/* Auvra web.

   Two surfaces, on purpose. The public pages are white paper: someone arriving from a link
   should read, not be impressed. The dashboard is a dark instrument panel, because it is the
   thing you sit in front of, and because the numbers on it are the only bright objects there.

   The dashboard follows the house shape used across these apps: the number first and large at
   a light weight, its label underneath in small uppercase monospace, plates that are a lighter
   tone of the ground with no line around them and no shadow under them, and exactly one
   coloured plate per screen carrying that screen's subject. The greys are neutral -- the same
   near-black the marketing site stands on -- so the one blue plate is the only blue thing.

   Shared design tokens come from /assets/tokens.css (copied from design/tokens.css at build);
   the literal values below are fallbacks for the same numbers. */

/* Two typefaces, self-hosted, same origin, 112KB in total.

   Lausanne is the voice: a Swiss grotesk with enough character in the a, g and t that a page
   of it is not anonymous, and a real 300 so a large number can be light instead of shouted.
   Berkeley Mono carries every number, label and identifier -- it is drawn on a pixel grid,
   which is the same grid the bars and meters on this page are built from.

   Only 300/400/500 exist and font-synthesis is off, so every weight in this sheet is one of
   those three on purpose rather than a browser-faked 650. */
@font-face { font-family: Lausanne; src: url(/assets/fonts/lausanne-300.woff2) format("woff2"); font-weight: 300; font-display: swap; }
@font-face { font-family: Lausanne; src: url(/assets/fonts/lausanne-400.woff2) format("woff2"); font-weight: 400; font-display: swap; }
@font-face { font-family: Lausanne; src: url(/assets/fonts/lausanne-500.woff2) format("woff2"); font-weight: 500; font-display: swap; }
@font-face { font-family: "Berkeley Mono"; src: url(/assets/fonts/berkeley-mono-400.woff2) format("woff2"); font-weight: 400; font-display: swap; }

:root {
 color-scheme: light;
 --raise: #ececee;
 --brand: var(--appshare-brand, #101114); --brand-ink: var(--appshare-button-text, #ffffff); --link: var(--appshare-link, #101114);
 --inset: var(--appshare-inset, 20px); --radius: var(--appshare-radius, 16px); --row-radius: var(--appshare-row-radius, 18px);
 --ink: #111112; --muted: #6f7076; --canvas: #fafafa;
 /* No line anywhere. A plate is told from the paper by tone; a field is told from its plate the
    same way. --line stays defined so nothing that still reads it draws a stroke. */
 --surface: #ffffff; --subtle: #f2f2f3; --line: transparent; --plate: #f4f4f5;
 --green: #0f6b45; --green-bg: #eef8f2; --amber: #8a5a08; --amber-bg: #fdf5e6; --red: #b3261e; --red-bg: #fdf0ef;
 --hero: var(--appshare-hero, linear-gradient(135deg, #4A5CD8, #5468E0));
 --shadow: 0 1px 2px rgba(16, 17, 20, .04), 0 6px 16px -8px rgba(74, 92, 216, .14);
 --shadow-lift: 0 2px 4px rgba(16, 17, 20, .05), 0 16px 32px -12px rgba(74, 92, 216, .26);
 --chart-from: var(--appshare-brand, #7892FF); --chart-to: #A9B8FF;
 --chart-best-from: var(--appshare-brand-deep, #5468E0); --chart-best-to: #8CA0FF;
 --meter-track: rgba(74, 92, 216, .12);
 --nav-width: 248px;
 --mono: "Berkeley Mono", ui-monospace, SFMono-Regular, Menlo, monospace;
 font-family: Lausanne, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
 font-synthesis: none; text-rendering: optimizeLegibility; -webkit-font-smoothing: antialiased;
}
* { box-sizing: border-box; }
html { scroll-behavior: smooth; }
body { margin: 0; background: var(--canvas); color: var(--ink); font-size: 15px; line-height: 1.6; }
/* Overscroll past the end of a dark dashboard used to show white paper underneath it. */
body:has(.dashboard) { background: #0D0D0F; }
a { color: var(--link); text-decoration: none; }
a:hover { text-decoration: underline; }
button, input, select { font: inherit; color: inherit; }
button, a, input, select, summary { -webkit-tap-highlight-color: transparent; }
button { cursor: pointer; }
button:disabled { cursor: not-allowed; }
[hidden] { display: none !important; }
:focus-visible { outline: 2px solid var(--link); outline-offset: 3px; }
main:focus, section:focus { outline: none; }
.icon { width: 20px; height: 20px; flex: 0 0 auto; vertical-align: middle; }
.icon.inline { width: 14px; height: 14px; }
h1, h2, h3, p, pre { margin: 0; }
h1, h2, h3 { letter-spacing: -.03em; line-height: 1.18; font-weight: 500; }
h1 { font-size: clamp(27px, 2.7vw, 36px); font-weight: 400; letter-spacing: -.04em; }
h2 { font-size: 19px; font-weight: 500; letter-spacing: -.025em; }
h3 { font-size: 15px; letter-spacing: -.02em; }
p { color: var(--muted); }
small { font-size: 12px; color: var(--muted); }
time { font-variant-numeric: tabular-nums; white-space: nowrap; }
code, .mono { font-family: var(--mono); font-size: .92em; overflow-wrap: anywhere; font-variant-numeric: tabular-nums; }
.muted { color: var(--muted); }
.micro { font-size: 12px; color: var(--muted); margin-top: 12px; }
.center { text-align: center; }
.sr-only { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0,0,0,0); white-space: nowrap; border: 0; }
.skip-link { position: fixed; top: -100px; left: 20px; z-index: 100; padding: 12px 20px; background: var(--surface); border: 2px solid var(--link); border-radius: 12px; }
.skip-link:focus { top: 16px; }
/* The mark is the app icon itself: white tiles on the brand tile, the same in both themes. */
.brand { display: inline-flex; align-items: center; gap: 11px; font-size: 20px; letter-spacing: -.03em; font-weight: 500; color: var(--ink); }
.brand:hover { text-decoration: none; }
.brand-mark { width: 30px; height: 30px; flex: 0 0 auto; display: block; }
.brand-tile { fill: #678DFC; }

/* Buttons, pills, notices, empty states */
.button { display: inline-flex; align-items: center; justify-content: center; gap: 8px; min-height: 44px; padding: 10px 20px; border-radius: 12px; border: 0; font-size: 14px; line-height: 1.3; font-weight: 500; transition: background 150ms ease; }
.button:hover { text-decoration: none; }
.button.primary { background: var(--brand); color: var(--brand-ink); }
.button.secondary { background: var(--subtle); color: var(--ink); }
.button.secondary:hover { background: var(--raise); }
.button.ghost { background: transparent; color: var(--muted); }
.button.danger { background: var(--red); color: #fff; }
.button.danger-secondary { background: var(--red-bg); color: var(--red); }
.button.small { min-height: 38px; padding: 8px 14px; font-size: 13px; }
/* Fading the whole button to 46% left white label text on a washed-out ink fill, and
   "Review claim" was barely legible. A disabled button gets its own quiet fill instead.
   Placed after the variants so it wins on specificity as well as order. */
.button:disabled, .button[aria-disabled="true"] {
  background: var(--subtle); color: var(--muted); box-shadow: none;
}
.button .icon { width: 17px; height: 17px; }
.full { width: 100%; }
.icon-button { display: inline-flex; align-items: center; justify-content: center; width: 40px; height: 40px; border-radius: 50%; border: 0; background: transparent; color: var(--muted); transition: background 150ms ease, color 150ms ease; }
.icon-button:hover { color: var(--ink); background: var(--subtle); text-decoration: none; }
.icon-button[aria-pressed="true"] { color: var(--link); background: var(--subtle); }
.actions { display: flex; flex-wrap: wrap; align-items: center; gap: 12px; margin: 16px 0 0; }
.actions.center { justify-content: center; }
.eyebrow { font-family: var(--mono); font-size: 11px; letter-spacing: .1em; font-weight: 400; color: var(--muted); text-transform: uppercase; }
.pill { display: inline-flex; align-items: center; gap: 6px; padding: 4px 10px; background: var(--subtle); color: var(--link); border-radius: 99px; font-family: var(--mono); font-size: 11px; line-height: 1.4; font-weight: 400; letter-spacing: .04em; text-transform: uppercase; white-space: nowrap; }
.pill.success { background: var(--green-bg); color: var(--green); }
.pill.warning { background: var(--amber-bg); color: var(--amber); }
.pill.danger { background: var(--red-bg); color: var(--red); }
.pill.neutral { background: var(--subtle); color: var(--muted); }
.card { background: var(--surface); border: 0; border-radius: var(--radius); padding: 24px 26px; box-shadow: none; min-width: 0; }
.panel { margin: 0 0 20px; }
.section-heading { display: flex; align-items: center; justify-content: space-between; gap: 16px; margin-bottom: 18px; }
.section-heading h2 { font-size: 17px; }
.text-link { font-size: 13px; font-weight: 500; white-space: nowrap; }
.divider { height: 0; margin: 24px 0; }
.notice { display: flex; align-items: flex-start; gap: 12px; padding: 16px 18px; margin: 0 0 16px; border: 0; background: var(--subtle); border-radius: 14px; font-size: 13px; }
.notice strong { font-size: 13px; font-weight: 500; }
.notice p { margin-top: 4px; }
.notice.warning { background: var(--amber-bg); color: var(--amber); }
.notice.warning p { color: inherit; }
.notice-dot { width: 7px; height: 7px; flex: 0 0 auto; border-radius: 50%; background: currentColor; margin-top: 7px; }
.empty-state { text-align: center; padding: 36px 20px; }
.empty-state h3 { font-size: 17px; margin-bottom: 8px; }
.empty-state p { max-width: 420px; margin: 0 auto; font-size: 14px; }
.empty-state .actions { margin-top: 16px; justify-content: center; }
.page-heading { display: flex; align-items: flex-end; justify-content: space-between; gap: 20px; margin: 0 0 30px; }
.page-heading .eyebrow { margin-bottom: 8px; display: block; }
.page-subtitle { font-size: 14px; margin-top: 8px; max-width: 680px; }

/* ---------------------------------------------------------------------------
   The dashboard, on its own ground.

   Everything below is scoped to `.dashboard`, so the public pages keep the light
   values above untouched. Most of the restyling is done by replacing the tokens:
   the components already read them. */
.dashboard {
 color-scheme: dark;
 --ink: #F2F2F3; --muted: #8A8A91; --canvas: #0D0D0F;
 /* Four neutral tones and nothing else. A plate is separated from the ground by being lighter
    than it, not by having a line drawn round it; a row inside a plate lifts again. Strokes
    are what make a dark interface look like a wireframe of itself, and a blue cast in the
    greys is what makes every card look like a weaker copy of the one blue plate. */
 --surface: #161618; --subtle: #1E1E21; --raise: #26262A; --line: transparent;
 --link: #A6B6FF; --brand: #678DFC; --brand-ink: #0D0D0F;
 --green: #62D9A0; --green-bg: rgba(98, 217, 160, .13);
 --amber: #E7B979; --amber-bg: rgba(231, 185, 121, .14);
 --red: #FF8E85; --red-bg: rgba(255, 142, 133, .14);
 --hero: linear-gradient(135deg, #4C5FE0 0%, #6C84FF 58%, #8AA0FF 100%);
 --chart-from: #93A7FF; --chart-to: #5A6FE6;
 --chart-best-from: #B8C6FF; --chart-best-to: #6C84FF;
 --meter-track: rgba(255, 255, 255, .085); --px-track: rgba(255, 255, 255, .065);
 --shadow: none; --shadow-lift: none;
 background: var(--canvas); color: var(--ink);
 display: grid; grid-template-columns: var(--nav-width) minmax(0, 1fr); min-height: 100vh;
}
.dash-nav { position: sticky; top: 0; height: 100vh; display: flex; flex-direction: column; gap: 6px; padding: 28px 18px 18px; background: var(--canvas); overflow-y: auto; }
.dash-nav > .brand { margin: 0 12px 30px; color: var(--ink); }
.dash-nav nav { display: flex; flex-direction: column; gap: 3px; }
.nav-item { display: flex; align-items: center; gap: 12px; color: var(--muted); font-size: 14px; font-weight: 400; padding: 11px 14px; border-radius: 11px; min-height: 44px; white-space: nowrap; transition: background 150ms ease, color 150ms ease; }
.nav-item .icon { width: 18px; height: 18px; opacity: .75; }
.nav-item.selected { background: var(--surface); color: var(--ink); }
.nav-item.selected .icon { opacity: 1; color: var(--link); }
.nav-item:hover { background: var(--surface); color: var(--ink); text-decoration: none; }
/* The account sits in its own bordered card at the foot of the rail, so the rail reads as
   navigation with an identity under it rather than as a list with one odd row at the end. */
.dash-user { margin-top: auto; display: flex; align-items: center; gap: 4px; padding: 6px 6px 6px 8px; border-radius: 14px; background: var(--surface); }
.dash-profile { display: flex; align-items: center; gap: 10px; color: var(--ink); min-width: 0; flex: 1; padding: 4px; border-radius: 10px; }
.dash-profile:hover { background: var(--raise); text-decoration: none; }
.dash-profile-text { min-width: 0; }
.dash-profile-text strong, .dash-profile-text small { display: block; font-size: 12px; font-weight: 400; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.avatar { display: inline-flex; align-items: center; justify-content: center; width: 32px; height: 32px; background: var(--brand); color: #fff; border-radius: 50%; flex: 0 0 auto; font-size: 14px; font-weight: 500; }
.dash-body { min-width: 0; display: flex; flex-direction: column; background: var(--canvas); }
.dash-topline { display: flex; align-items: center; justify-content: space-between; gap: 12px; padding: 22px 48px 0; font-size: 12px; color: var(--muted); }
/* A status chip with a live dot, rather than a sentence floating on the rule. */
.dash-refreshed { display: inline-flex; align-items: center; gap: 8px; padding: 6px 13px 6px 11px; border-radius: 99px; background: var(--surface); font-family: var(--mono); font-size: 11px; letter-spacing: .03em; }
.dash-refreshed::before { content: ""; width: 6px; height: 6px; border-radius: 50%; background: var(--green); flex: 0 0 auto; }
.topbar-actions { display: flex; gap: 4px; }
.dash-main { padding: 26px 48px 12px; max-width: 1280px; width: 100%; margin: 0 auto; flex: 1; }
.dash-foot { max-width: 1280px; width: 100%; margin: 0 auto; padding: 16px 48px 36px; display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 10px 16px; color: var(--muted); font-size: 12px; }
.dash-foot > span { display: inline-flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.dash-foot .icon { width: 15px; height: 15px; }
/* A plate is a solid tone, unoutlined. Nothing happens on hover: a panel is not a button. */
.dashboard .card { border-radius: 18px; }
/* The mark of an eligible app on a small tile at the head of its row. */
.app-mark { display: inline-flex; align-items: center; justify-content: center; width: 32px; height: 32px; border-radius: 9px; background: var(--subtle); flex: 0 0 auto; }
.app-mark img { width: 18px; height: 18px; display: block; }
.app-mark.letter { font-family: var(--mono); font-size: 12px; color: var(--muted); }
.cell-app { display: flex; align-items: center; gap: 12px; min-width: 0; }
.cell-app > span { min-width: 0; }
.cell-app strong { font-weight: 400; }

/* Stats, grids, tables */
.stat-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 16px; margin: 0 0 24px; }
.stat-grid.three { grid-template-columns: repeat(3, minmax(0, 1fr)); }
.stat-grid.four { grid-template-columns: repeat(4, minmax(0, 1fr)); }
/* The house shape: the number first, large and light, with its name underneath in small
   uppercase monospace. The markup stays label-then-number so a screen reader hears
   "Available credit, $20.58" rather than the number on its own; only the drawing is swapped. */
.stat-card { padding: 22px 24px 20px; display: flex; flex-direction: column; justify-content: flex-start; }
.stat-card strong { order: 1; font-size: 34px; font-weight: 300; letter-spacing: -.04em; display: block; font-variant-numeric: tabular-nums; line-height: 1.05; }
.stat-card p { order: 2; font-family: var(--mono); font-size: 11px; margin: 11px 0 0; letter-spacing: .08em; text-transform: uppercase; font-weight: 400; color: var(--muted); }
.stat-card small { order: 3; display: block; margin-top: 14px; font-size: 12px; }
/* The page's subject. One per screen -- see statCard() in ui/layout.ts. The light on it is a
   soft radial fade, not a circle: a flat disc at 13% white drew a visible hard edge across the
   card, which looked like a rendering fault rather than a highlight. */
.stat-card.hero { background: var(--hero); color: #fff; position: relative; overflow: hidden; }
.stat-card.hero::after { content: ""; position: absolute; inset: 0; pointer-events: none; background:
 radial-gradient(160% 130% at 90% -34%, rgba(255, 255, 255, .3), rgba(255, 255, 255, 0) 60%); }
.stat-card.hero > * { position: relative; }
.stat-card.hero p { color: rgba(255, 255, 255, .8); }
.stat-card.hero small { color: rgba(255, 255, 255, .86); }
.stat-card.hero strong { font-size: 40px; }
.stat-card.hero a, .stat-card.hero .on-hero { color: #fff; font-weight: 400; text-decoration: underline; text-underline-offset: 3px; text-decoration-color: rgba(255, 255, 255, .5); }
.overview-grid { display: grid; grid-template-columns: 1.35fr 1fr; gap: 20px; align-items: stretch; }
.overview-grid .panel { margin: 0 0 20px; }
.account-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 20px; align-items: start; }
/* The three readings under the week chart. */
.week-figures { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 12px; margin-top: 22px; }
.figure { padding: 14px 16px 13px; background: var(--subtle); border-radius: 12px; min-width: 0; }
.figure strong { display: block; font-size: 22px; font-weight: 300; letter-spacing: -.03em; font-variant-numeric: tabular-nums; line-height: 1.1; }
.figure span { display: block; font-family: var(--mono); font-size: 10px; letter-spacing: .08em; text-transform: uppercase; color: var(--muted); margin-top: 8px; }
.figure small { display: block; margin-top: 3px; font-size: 12px; }
/* Rows folded under one line. */
.fold { margin-top: 12px; }
.fold summary { display: flex; align-items: center; gap: 8px; cursor: pointer; list-style: none; padding: 12px 14px; border-radius: 10px; background: var(--subtle); color: var(--muted); font-size: 13px; }
.fold summary::-webkit-details-marker { display: none; }
.fold summary .icon { transition: transform 150ms ease; }
.fold[open] summary .icon { transform: rotate(90deg); }
.fold .table-wrap { margin-top: 6px; }
.account-grid .panel { margin: 0; }
.table-wrap { overflow-x: auto; margin: 0 -8px; padding: 0 8px; }
table { width: 100%; border-collapse: collapse; font-size: 14px; }
/* No rules between rows. A monospaced, right-aligned number column already lines the table up,
   and the row height separates one reading from the next better than a hairline does. */
th, td { padding: 13px 10px; text-align: left; border-bottom: 0; vertical-align: middle; }
.dashboard th, .dashboard td { padding: 12px 12px; }
.dashboard thead th { padding-bottom: 6px; }
.dashboard tbody tr:hover > *:first-child { border-radius: 10px 0 0 10px; }
.dashboard tbody tr:hover > *:last-child { border-radius: 0 10px 10px 0; }
thead th { font-family: var(--mono); font-size: 10.5px; text-transform: uppercase; letter-spacing: .08em; color: var(--muted); font-weight: 400; white-space: nowrap; padding-bottom: 10px; }
tbody tr { transition: background 120ms ease; }
.dashboard tbody tr:hover > * { background: var(--subtle); }
tbody th[scope="row"] { font-weight: 400; color: var(--ink); }
tbody th small, tbody td small { display: block; margin-top: 2px; }
.num { text-align: right; font-variant-numeric: tabular-nums; white-space: nowrap; }
/* A shortened hash or address in a table is already short enough to fit; letting it break
   mid-value split "0x5d5688…b80025" across two lines and read as two numbers. */
td .mono, td > a.mono { white-space: nowrap; overflow-wrap: normal; }
.empty-row td { padding: 0; }
.inline-form { display: inline-flex; flex-direction: column; align-items: flex-end; gap: 4px; }
.toolbar { display: flex; flex-wrap: wrap; align-items: flex-end; gap: 12px; margin: 0 0 16px; }
.toolbar-spacer { flex: 1; }
.toolbar p { margin: 0 0 10px; font-size: 13px; }
.toolbar .button { margin-bottom: 2px; }

/* Forms and row groups */
/* A field is a tone one step off its plate: white on the grey auth card, a lifted grey inside a
   dark panel. Never an outline. */
input:not([type="checkbox"]), select { min-height: 44px; border: 0; background: var(--surface); padding: 10px 12px; border-radius: 11px; max-width: 100%; font-size: 14px; width: 100%; }
.dashboard input:not([type="checkbox"]), .dashboard select, .dashboard textarea { background: var(--subtle); color: var(--ink); }
.dashboard .notice { background: var(--subtle); }
/* A field that is right or wrong says so by tone, and by the sentence under it. */
.dashboard .wallet-input.good { background: rgba(98, 217, 160, .1); }
.dashboard .wallet-input.bad { background: rgba(231, 185, 121, .1); }
.dashboard input::placeholder, .dashboard textarea::placeholder { color: rgba(255, 255, 255, .34); }
input[type="checkbox"] { width: 22px; height: 22px; accent-color: var(--link); flex: 0 0 auto; cursor: pointer; margin: 0; }
.field { display: flex; flex-direction: column; gap: 6px; margin: 0; font-size: 13px; font-weight: 400; }
.field > span:first-child { color: var(--muted); font-family: var(--mono); font-size: 10.5px; letter-spacing: .08em; text-transform: uppercase; }
.field.inline { width: auto; }
.field.inline input, .field.inline select { width: auto; min-width: 150px; }
.field-hint { font-size: 12px; color: var(--muted); font-family: inherit; letter-spacing: normal; text-transform: none; }
.stack { display: flex; flex-direction: column; gap: 14px; margin-top: 16px; }
.stack .button { align-self: flex-start; }
.form-error, #dialog-error { color: var(--red); font-size: 13px; }
.form-error:empty, #dialog-error:empty { display: none; }
.challenge { white-space: pre-wrap; padding: 12px; background: var(--subtle); border-radius: 10px; margin: 0; }

/* Reward wallet. The address is the subject of the panel, so it gets the one coloured plate
   on the page, at a size meant for reading a group of four at a time rather than for fitting
   in a table cell. The phone apps carry the same card. */
.wallet-hero { position: relative; overflow: hidden; background: var(--hero); color: #fff; border-radius: var(--appshare-hero-radius, 20px); padding: 20px 22px; }
.wallet-hero::after { content: ""; position: absolute; inset: 0; pointer-events: none; background:
 radial-gradient(160% 130% at 90% -34%, rgba(255, 255, 255, .28), rgba(255, 255, 255, 0) 60%); }
.wallet-hero > * { position: relative; }
/* The base `p { color: var(--muted) }` outranks the colour inherited from the card, so every
   paragraph on the plate states its own. Without this the address rendered grey on purple. */
.wallet-hero p { color: #fff; }
.wallet-hero-top { display: flex; align-items: flex-start; justify-content: space-between; gap: 12px; }
.wallet-hero .eyebrow { color: rgba(255,255,255,.8); margin: 0; }
.wallet-address { font-family: var(--mono); font-size: 17px; font-weight: 400; line-height: 1.6; letter-spacing: .01em; margin: 16px 0 0; overflow-wrap: anywhere; -webkit-user-select: all; user-select: all; }
.wallet-none { font-size: 25px; font-weight: 300; letter-spacing: -.03em; margin: 16px 0 0; }
.wallet-hero .wallet-note { font-size: 13px; color: rgba(255,255,255,.88); margin: 8px 0 0; max-width: 46ch; }
.wallet-hero .actions { margin-top: 12px; }
.wallet-copy { display: inline-flex; align-items: center; gap: 8px; min-height: 36px; padding: 6px 13px 6px 11px; border: 0; border-radius: 99px; background: rgba(255,255,255,.18); color: #fff; font-size: 13px; font-weight: 400; }
.wallet-copy:hover { background: rgba(255,255,255,.24); }
.wallet-hero-stats { display: flex; gap: 30px; margin-top: 24px; }
.wallet-hero-stats span { display: block; font-family: var(--mono); font-size: 10.5px; letter-spacing: .08em; text-transform: uppercase; color: rgba(255,255,255,.72); }
.wallet-hero-stats strong { display: block; font-size: 15px; font-weight: 400; margin-top: 4px; }
.pill.on-hero { background: rgba(255,255,255,.2); color: #fff; }
.wallet-explain { font-size: 13px; margin: 16px 0 0; }
.wallet-subhead { font-family: var(--mono); font-size: 10.5px; font-weight: 400; letter-spacing: .08em; text-transform: uppercase; color: var(--muted); margin: 22px 0 0; }
textarea { font: inherit; color: inherit; width: 100%; max-width: 100%; border: 0; background: var(--surface); padding: 10px 12px; border-radius: 11px; font-size: 14px; resize: vertical; }
.wallet-input { line-height: 1.6; min-height: 72px; }
.field-hint.good { color: var(--green); }
.field-hint.bad { color: var(--amber); }
/* Inside a plate a group lifts one more step, and its rows are told apart by height alone. */
.row-group { background: var(--subtle); border: 0; border-radius: var(--row-radius); overflow: hidden; margin: 0 0 12px; padding: 6px 0; }
.dashboard .detail-line { min-height: 46px; }
.row-group > * { border-bottom: 0; margin: 0; }
.detail-line { display: flex; align-items: center; justify-content: space-between; gap: 14px; padding: 0 16px; min-height: 48px; font-size: 14px; }
.detail-line > span { color: var(--muted); display: inline-flex; align-items: center; gap: 10px; }
.detail-line strong { font-weight: 400; color: var(--ink); font-variant-numeric: tabular-nums; text-align: right; min-width: 0; overflow-wrap: anywhere; }
.detail-line strong.mono { font-size: 12px; }
.detail-line select { width: auto; min-height: 36px; padding: 6px 10px; margin: 6px 0; }
.detail-line input[type="checkbox"] { margin-left: auto; }
.detail-row { display: flex; justify-content: space-between; gap: 24px; padding: 12px 0; border-bottom: 0; font-size: 13px; }
dl { margin: 0; }
dt { color: var(--muted); min-width: 120px; }
dd { text-align: right; margin: 0; overflow-wrap: anywhere; font-weight: 400; color: var(--ink); }
dl.row-group .detail-row { padding: 12px 16px; margin: 0; }
.toggle-row { display: flex; align-items: center; justify-content: space-between; gap: 20px; padding: 6px 0; }
.toggle-row strong, .toggle-row small { display: block; }
.toggle-row strong { font-size: 14px; font-weight: 500; }
.toggle-row small { font-size: 12px; margin-top: 4px; }
.segmented { display: flex; background: var(--subtle); border-radius: 999px; padding: 3px; margin: 18px 0 16px; }
.segmented button { flex: 1; min-height: 38px; border: 0; border-radius: 999px; background: transparent; color: var(--muted); font-weight: 400; font-size: 14px; }
.segmented button[aria-selected="true"] { background: var(--surface); color: var(--ink); }
.auth-form { display: flex; flex-direction: column; gap: 12px; }
.auth-page { display: flex; justify-content: center; padding: 24px 0 40px; }
.auth-card { width: min(440px, 100%); padding: 30px; background: var(--plate); }
.auth-card .lead { font-size: 14px; margin-top: 8px; }
.auth-card .notice { margin-top: 16px; }
.auth-card .auth-guest { margin-top: 10px; font-size: 13px; }

/* Chart and claim status */
.activity-chart { display: block; width: 100%; margin-top: 16px; }
.activity-chart svg { display: block; width: 100%; height: 158px; overflow: visible; }
.activity-chart text { fill: var(--muted); font-family: var(--mono); font-size: 9.5px; letter-spacing: .04em; text-transform: uppercase; }
.activity-chart .chart-value { font-size: 10.5px; letter-spacing: 0; fill: var(--muted); font-variant-numeric: tabular-nums; }
/* The busiest day is the one number in the readout worth finding at a glance. */
.activity-chart .chart-value.best { fill: var(--ink); }
/* One cell of a day's column. Unlit cells stay drawn: an empty slot is how far the day could
   have gone, which is half of what a level meter says. */
.px { fill: var(--px-track, var(--meter-track)); }
.px.on { fill: url(#px-on); }
/* The busiest day of the seven, so the shape of the week has a reference point. */
.px.on.best { fill: url(#px-best); }

/* Proportion bars, cut into twenty cells. See meter() in ui/layout.ts -- decorative here and
   stated in words to a screen reader, so nothing depends on being able to count blocks.

   The cells are a mask over the whole track rather than twenty elements, so a table of these
   costs one span per row instead of twenty. The mask pitch is a percentage, so the cell count
   holds at any width, and meter() rounds the fill to a whole number of them. */
.meter { display: block; height: 7px; margin-top: 9px; background: var(--meter-track);
 -webkit-mask-image: repeating-linear-gradient(90deg, #000 0 calc(5% - 2px), transparent calc(5% - 2px) 5%);
 mask-image: repeating-linear-gradient(90deg, #000 0 calc(5% - 2px), transparent calc(5% - 2px) 5%); }
.meter-fill { display: block; height: 100%; background: linear-gradient(90deg, var(--chart-to), var(--chart-from)); }
td.num .meter { margin-left: auto; max-width: 128px; }

/* Ranked list: name, level, and the two numbers the level stands for. */
.rank-list { display: grid; gap: 1px; margin-top: 18px; }
.rank { display: grid; grid-template-columns: 32px minmax(120px, 1.1fr) minmax(90px, 2fr) 80px 74px; align-items: center; gap: 14px 16px; padding: 9px 14px; border-radius: 12px; transition: background 120ms ease; }
.rank:hover .app-mark, .dashboard tbody tr:hover .app-mark { background: var(--raise); }
.rank:hover { background: var(--subtle); }
.rank-name { display: flex; flex-direction: column; gap: 3px; font-size: 14px; min-width: 0; }
.rank-name small { font-family: var(--mono); font-size: 10px; letter-spacing: .05em; text-transform: uppercase; }
.rank .meter { margin: 0; }
.rank-value { font-family: var(--mono); font-size: 12.5px; text-align: right; font-variant-numeric: tabular-nums; color: var(--muted); }
.rank-value.credit { color: var(--ink); }
.claim-status { display: flex; align-items: center; gap: 14px; margin: 0 0 16px; }
.claim-status-icon { display: flex; align-items: center; justify-content: center; width: 52px; height: 52px; border-radius: 16px; background: var(--subtle); color: var(--link); }
.claim-status-icon.complete { background: var(--green-bg); color: var(--green); }
.claim-status-icon.failed { background: var(--red-bg); color: var(--red); }
.claim-status-icon > .icon { width: 26px; height: 26px; }

/* Public pages */
.public-header { display: flex; align-items: center; justify-content: space-between; gap: 16px; max-width: 1120px; padding: 22px var(--inset); margin: auto; }
.public-header nav { display: flex; gap: 24px; font-size: 13px; }
.public-header nav a { color: var(--muted); }
.public-main { max-width: 1120px; margin: auto; padding: 16px var(--inset) 60px; min-height: calc(100vh - 220px); }
.lead { font-size: 17px; line-height: 1.65; max-width: 620px; }
.quiet { font-size: 12px; margin-top: 14px; }
.public-footer { display: flex; flex-wrap: wrap; align-items: center; gap: 20px; max-width: 1120px; padding: 34px var(--inset); margin: auto; font-size: 12px; color: var(--muted); }
.public-footer .brand { font-size: 18px; }
.public-footer > div { display: flex; gap: 20px; margin-left: auto; flex-wrap: wrap; }
.explanation-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 20px; margin-bottom: 20px; }
.explanation-grid h2 { font-size: 19px; margin: 0 0 10px; }
.explanation-grid p { font-size: 14px; }
.step-number { display: inline-flex; color: var(--link); background: var(--subtle); border-radius: 10px; padding: 5px 10px; font-family: var(--mono); font-size: 11px; font-weight: 400; margin-bottom: 16px; }
.app-columns { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 20px; }
.app-columns h3 { margin-bottom: 6px; }
.app-columns p { font-size: 14px; }
.center-action { text-align: center; margin: 30px 0; }
.help-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 14px; align-items: start; margin-bottom: 20px; }
.faq { padding: 18px 20px; background: var(--plate); }
.faq summary { display: flex; justify-content: space-between; gap: 15px; cursor: pointer; font-weight: 500; font-size: 14px; list-style: none; min-height: 28px; align-items: center; }
.faq summary::-webkit-details-marker { display: none; }
.faq[open] summary .icon { transform: rotate(90deg); }
.faq p { font-size: 13px; margin-top: 10px; }
.reading { max-width: 760px; }
.prose h2 { margin: 24px 0 10px; font-size: 19px; }
.prose h2:first-child { margin-top: 0; }
.prose p { margin-bottom: 16px; }
.prose .button { margin-top: 8px; }

/* Dialog, loading, live region */
.app-dialog { width: min(520px, calc(100vw - 32px)); max-height: calc(100dvh - 48px); border: 0; border-radius: var(--radius); background: var(--surface); color: var(--ink); padding: 28px; box-shadow: none; }
.app-dialog::backdrop { background: rgba(8,8,9,.6); backdrop-filter: blur(3px); }
.dialog-close { position: absolute; right: 12px; top: 12px; }
.dialog-heading { padding: 6px 30px 14px 0; }
.dialog-heading h2 { font-size: 24px; font-weight: 400; letter-spacing: -.03em; margin-bottom: 6px; }
.dialog-heading p { font-size: 13px; }
.dialog-actions { display: grid; gap: 10px; margin-top: 20px; }
.loading-state { text-align: center; min-height: 60vh; display: flex; align-items: center; justify-content: center; flex-direction: column; gap: 16px; padding: 40px; }
.loader { width: 32px; height: 32px; border: 3px solid var(--subtle); border-top-color: var(--brand); border-radius: 50%; animation: rotate 800ms linear infinite; }
.live-status { position: fixed; bottom: 24px; left: 50%; transform: translateX(-50%); background: #26262A; color: #F2F2F3; border: 0; border-radius: 12px; padding: 12px 18px; box-shadow: none; font-size: 13px; z-index: 10; max-width: calc(100vw - 40px); pointer-events: none; }
.live-status:empty { display: none; }
.noscript { padding: 30px; }
@keyframes rotate { to { transform: rotate(360deg); } }

/* Responsive */
@media (max-width: 1100px) {
 .stat-grid.four { grid-template-columns: repeat(2, minmax(0, 1fr)); }
 .overview-grid, .account-grid { grid-template-columns: 1fr; }
 .dash-main, .dash-topline { padding-left: 28px; padding-right: 28px; }
 .dash-foot { padding-left: 28px; padding-right: 28px; }
 .week-figures { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}
@media (max-width: 900px) {
 .dashboard { display: block; }
 .dash-nav { position: sticky; top: 0; z-index: 8; height: auto; display: grid; grid-template-columns: auto 1fr auto; align-items: center; gap: 6px 12px; padding: 10px var(--inset) 8px; overflow: visible; }
 .dash-nav > .brand { grid-row: 1; grid-column: 1; margin: 0; font-size: 19px; }
 /* Five sections need about 560px and a phone has 375, so the row scrolls. Its scrollbar is
    hidden, which left Portfolio and Account off the right edge with nothing to say they were
    there. The last section is faded rather than cut, so the row reads as continuing. The fade
    lifts once the row is scrolled to its end -- see syncNavFade in main.js. */
 .dash-nav nav { grid-row: 2; grid-column: 1 / -1; flex-direction: row; overflow-x: auto; gap: 2px; margin: 0 calc(var(--inset) * -1); padding: 2px var(--inset); scrollbar-width: none; scroll-snap-type: x proximity; -webkit-mask-image: linear-gradient(to right, #000 calc(100% - 42px), transparent); mask-image: linear-gradient(to right, #000 calc(100% - 42px), transparent); }
 .dash-nav nav[data-scrolled="end"] { -webkit-mask-image: none; mask-image: none; }
 .dash-nav nav::-webkit-scrollbar { display: none; }
 .nav-item { scroll-snap-align: start; }
 .nav-item { flex: 0 0 auto; padding: 8px 12px; min-height: 38px; font-size: 13px; gap: 8px; }
 .nav-item .icon { width: 17px; height: 17px; }
 .dash-user { grid-row: 1; grid-column: 2 / 4; justify-self: end; margin: 0; padding: 3px; }
 .dash-profile-text { display: none; }
 .feature-grid, .explanation-grid, .help-grid, .app-columns { grid-template-columns: 1fr; }
 .calm-banner { flex-direction: column; align-items: flex-start; padding: 24px; }
 .public-header nav { display: none; }
 .page-heading { flex-direction: column; align-items: flex-start; gap: 12px; }
}
@media (max-width: 600px) {
 .dash-main, .dash-topline, .dash-foot { padding-left: 16px; padding-right: 16px; }
 .dash-main { padding-top: 22px; }
 .card { padding: 18px; border-radius: 16px; }
 .stat-grid, .stat-grid.three, .stat-grid.four { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 10px; }
 .stat-card { padding: 16px 16px 14px; }
 .stat-card strong, .stat-card.hero strong { font-size: 23px; }
 .week-figures { gap: 8px; }
 .figure strong { font-size: 18px; }
 .rank { grid-template-columns: 32px minmax(0, 1fr) 70px 64px; }
 .rank .meter { display: none; }
 .stat-card p { font-size: 10px; margin-top: 8px; }
 .stat-card small { margin-top: 10px; padding-top: 10px; }
 .toolbar .field.inline { flex: 1 1 130px; }
 .toolbar .field.inline input { width: 100%; min-width: 0; }
 .toolbar-spacer { display: none; }
 .toolbar p { flex-basis: 100%; }
 th, td { padding: 11px 8px; font-size: 13px; }
 .dash-foot { flex-direction: column; align-items: flex-start; }
 .live-status { bottom: 16px; font-size: 12px; }
 .public-main { padding-bottom: 40px; }
 .app-dialog { padding: 24px 20px; }
}
@media (max-width: 340px) {
 .stat-grid, .stat-grid.three, .stat-grid.four { grid-template-columns: 1fr; }
}
@media (prefers-reduced-motion: reduce) {
 html { scroll-behavior: auto; }
 *, *::before, *::after { animation-duration: .01ms !important; animation-iteration-count: 1 !important; transition-duration: .01ms !important; }
}
@media (forced-colors: active) {
 .button, .card, .pill, .nav-item, .brand-mark, .row-group { border: 1px solid CanvasText; }
 .px.on { fill: CanvasText; }
}
@media print {
 .dash-nav, .dash-topline, .dash-foot, .public-header, .public-footer, .button, .toolbar { display: none !important; }
 .dashboard { display: block; background: white; color: black; }
 .dash-main { padding: 0; }
 .card { break-inside: avoid; box-shadow: none; }
 body { background: white; color: black; }
}

/* Reward stocks: a company balance is a count first ("90 stocks") with its value beside it. */
.rank.wide { grid-template-columns: 32px minmax(120px, 1.1fr) minmax(90px, 2fr) 108px 84px; }
.rank-note { font-size: 12px; color: var(--muted); }
.rank-note.ready { color: var(--green); }
.rank-value small { display: block; margin-top: 2px; color: var(--muted); }
.today-progress { display: grid; grid-template-columns: auto minmax(120px, 320px); align-items: center; gap: 8px 16px; margin: 4px 0 18px; font-size: 13px; color: var(--muted); }
.today-progress .meter { margin: 0; }
td .earned { font-weight: 500; white-space: nowrap; }
td .earned.none { font-weight: 400; color: var(--muted); }
td .stock-count { white-space: nowrap; }
@media (max-width: 600px) {
 .rank.wide { grid-template-columns: 32px minmax(0, 1fr) 84px 60px; }
 .today-progress { grid-template-columns: 1fr; }
}

/* meter() widths, one class per twentieth (inline style attributes are blocked by the CSP). */
.meter-fill.w5 { width: 5%; }
.meter-fill.w10 { width: 10%; }
.meter-fill.w15 { width: 15%; }
.meter-fill.w20 { width: 20%; }
.meter-fill.w25 { width: 25%; }
.meter-fill.w30 { width: 30%; }
.meter-fill.w35 { width: 35%; }
.meter-fill.w40 { width: 40%; }
.meter-fill.w45 { width: 45%; }
.meter-fill.w50 { width: 50%; }
.meter-fill.w55 { width: 55%; }
.meter-fill.w60 { width: 60%; }
.meter-fill.w65 { width: 65%; }
.meter-fill.w70 { width: 70%; }
.meter-fill.w75 { width: 75%; }
.meter-fill.w80 { width: 80%; }
.meter-fill.w85 { width: 85%; }
.meter-fill.w90 { width: 90%; }
.meter-fill.w95 { width: 95%; }
.meter-fill.w100 { width: 100%; }
