@import url('https://fonts.googleapis.com/css2?family=DM+Sans:opsz,wght@9..40,300;9..40,400;9..40,500;9..40,700&display=swap');

/* ============================================================================
   PEWTER SKIN  ·  option 3b  ·  pebble, in cool grey
   ----------------------------------------------------------------------------
   Pebble exactly — same geometry, same type, same shadows, same acid accent —
   with a COOL light palette in place of the warm one. Its page is #d9dbdf, the
   grey the logo was picked on (logo lab 2's card 5, and now the website's
   ground), so the app opens on the same colour the mark was designed against.

   ONLY the light `:root` block below differs from skins/pebble.css. The dark
   theme is byte-identical: the mark reads on dark already, and two skins whose
   dark themes drift apart is two skins to maintain rather than one palette
   swap. Diff the files before editing either — anything outside the first
   block belongs to both, and a fix here almost certainly belongs there too.

   The neutrals moved warm → cool as a set (page, card, the three inks and
   every rgba tint derived from the ink), because a single warm token left in a
   cool palette reads as a stain rather than as warmth. The hue-bearing tokens
   — the accent, the series ladder, up/down, the status colours — are pebble's
   untouched: they carry meaning, and meaning should not change with the paint.

   Contrast, measured against pebble's own (card / frosted panel):
     --ink    13.88 / 12.55   (pebble 12.43 / 10.30)
     --ink-2   6.84 /  6.19   (pebble  6.17 /  5.11)
     --muted   3.68 /  3.33   (pebble  3.99 /  3.31)
   The lighter page lifts the frosted panel — the surface that has to hold, per
   the note below — so every paragraph clears AA there as it does on pebble.

   Loaded after theme.css. Paint, type and edges only.
   ========================================================================== */

:root {
  --page: #d9dbdf;
  --surface-1: #f4f5f7;
  --ink: #24262b;
  /* THE TWO SECONDARY INKS ARE FITTED TO THE FROSTED PANEL, NOT THE CARD.
     Pebble learned this the hard way and the reasoning carries over intact:
     the Settings sheet and the assistant drawer are translucent surface over
     the page (#f4f5f7 at 0.56 over #d9dbdf, compositing to about #e8eaec), so
     they are DARKER than the card everyone checks — inks fitted to the card
     alone ran at half the contrast body copy needs, and were reported as "not
     too contrasty" on exactly those two surfaces.
     So both are fitted to the panel: --ink-2 clears 6.19 there and 6.84 on the
     card, which is AA wherever a paragraph is drawn. --muted keeps its job —
     de-emphasis, not body copy: ⓘ glyphs, placeholders, unit suffixes — and
     only has to stay legible: 3.33 on the panel, over the 3:1 a non-text mark
     must clear, while staying a clear step lighter than the ink above it. */
  --ink-2: #52555c;
  --muted: #7b7f87;
  --grid: rgba(36, 38, 43, 0.19);
  --baseline: rgba(36, 38, 43, 0.316);
  --border: rgba(36, 38, 43, 0.19);
  --series-1: #3d4046;
  --series-2: #5b8266;
  --series-3: #b79338;
  --series-5: #6f6a8f;
  --up: #2f7d4f;
  --down: #bf5340;
  /* Value-chart event markers, in the skin's own key. Deliberately NOT
     borrowed from the profit palette: a transfer is money moving, which is
     neither a gain nor a loss, so it takes the one hue this skin has kept
     free of meaning — a cool slate that no line, chip or status uses — while
     a correction wears a dark ochre, close enough to the warning family to
     read as "this is bookkeeping" and far enough from --down that a
     written-off position is never mistaken for a sale. Shape is what
     separates the three marker categories (round / diamond / crossed
     square); colour only has to stay legible on the sand card. */
  --marker-transfer: #4d6f91;
  --marker-correction: #8a6420;
  /* The coverage rule: where an account's trade record begins. Not an event,
     so it gets no hue of its own — a warm stone grey that reads as an
     annotation against the sand card and never competes with a series line.
     On the portfolio chart each rule takes its own account's colour; this is
     the legend swatch and the asset drawer's. */
  --marker-coverage: #868a92;
  --status-good: #2f7d4f;
  --status-warning: #b79338;
  --status-serious: #c07a4a;
  --status-critical: #bf5340;
  --wash: rgba(36, 38, 43, 0.055);
  --dock-bg: rgba(244, 245, 247, 0.604);
  --dock-border: rgba(36, 38, 43, 0.181);
  --panel-bg: rgba(244, 245, 247, 0.604);
  --panel-border: rgba(36, 38, 43, 0.181);
  --panel-shadow-side: -18px 0 60px rgba(36, 38, 43, 0.244);
  --panel-shadow-pop: 0 26px 72px rgba(36, 38, 43, 0.28);
  --scrim-bg: rgba(36, 38, 43, 0.217);

  --pb-sans: 'DM Sans', system-ui, sans-serif;
  --pb-accent: #dcff26;
  /* The CHART accent, deliberately not --pb-accent. The acid lime is this
     skin's signature and it is reserved for meaning — the portfolio's own
     line, the Diversification dial, the largest account on the value donut.
     A colour that means "this one" cannot also be slot 3 of a ladder handed
     out to whichever category happens to land there; a chart with a lime
     third series was pointing at nothing.
     A CITRON — the lime walked down toward the ink, so the ladder still runs
     black → olive → citron the way the signature does, without ever reaching
     the signature itself. Not a muted green: the accent slot has to sit where
     the tonal ladder is NOT, and a mid-lightness hue lands among the steps.
     Measured, against a floor of 15: Pebble's own sage (--series-2, #5b8266)
     scores adjacent 13.2 light / 11.4 dark, and the correlation matrix's gold
     (--series-3) bottoms out at 8.1 wherever it is put — the ladder has room
     for ONE chromatic slot because the other ten positions are a lightness
     ramp, and a second hue has to take a step's place, not join it.
     Two values, because the two cards want opposite things of the same hue:
     on the pale card the citron has to be dark enough to clear the pale steps,
     and on the dark card the ink is cream and a dark citron collapses into the
     mid steps (13.1). The dark half is the same hue lifted. */
  --pb-chart-accent: #b8cc22;
  /* …and the lime keeps the reserved jobs (theme.css --accent-signal): the
     portfolio's own line, the Diversification dial, the largest account on
     the value donut. Declared once — the dark blocks below inherit it, as
     they do --pb-accent itself. */
  --pb-chart-accent-dark: #d6e86e;
  /* The chart gold and the chart cool, each in its two lifts — declared here
     beside the accent they are dealt out with, so the three are read as one
     set. The dark blocks below re-point --cat-accent-2/-3 at the *-dark
     twins; these four are declared once, as --pb-chart-accent is. */
  --pb-chart-gold: #d69123;
  --pb-chart-gold-dark: #e6a83f;
  --pb-chart-olive: #2f6135;
  --pb-chart-olive-dark: #97cf89;
  --accent-signal: var(--pb-accent);
  /* The light that crosses a badge mark in the friend sheet. The base sheet's
     gold is a stranger here: on this page the one colour that reads as "the
     app's own light" is the acid, and a badge catching it is exactly the kind
     of punctuation it already does (the unread pill, the live-feed chip).
     Restated in BOTH dark blocks below — theme.css declares it at
     :root[data-theme="dark"], which would otherwise outrank this line. */
  --badge-glint: var(--pb-accent);
  --pb-accent-ink: #24262b;
  /* In LIGHT mode the charts do NOT take the accent: it was tried on the
     portfolio line and on the Macro card's Treasury spread and washed out
     against the pale card. --curve-line is therefore overridden only in the
     dark blocks below, where the accent has contrast to spare.

     The portfolio's line goes to pure black instead. It used to inherit
     theme.css's fallback of --series-1, a warm dark grey (#46433c), which put
     it ΔE 14.4 from the S&P benchmark and 14.3 from the Nasdaq — two of the
     lines it is meant to be read AGAINST, on the one chart where the whole
     point is telling your portfolio apart from its benchmarks. It is also the
     only colour on this card that is unambiguously "the subject".

     Black is not IN the ladder, though, and that is what took a second fix.
     Nothing stopped the deal from handing a benchmark the slot right BESIDE
     it: --cat-1 is the ink, #24262b here, and the US dollar line came out in
     it at ΔE 28.1 from the black — which clears every floor the pins checked
     and still reads, on cream, as two black lines. Reported exactly that way.
     The deal now retires whichever slot the subject line is nearest before it
     starts (Dashboard.helpers dealBenchSlots), which on this surface is that
     near-black one, so the seven benchmarks share the ten that are left and
     the nearest of them sits 45.3 away rather than 28.1.

     Black rather than var(--cat-1), which was the other way to say it and
     measures worse: pointing the line AT the darkest slot retires the same
     slot, but leaves the subject sitting inside the ladder's dark end, and
     every benchmark is then read against a near-black instead of a black —
     worst 17.5 against black's 45.3, on the same deal. The palette-following
     that would have bought (Brights drawing its own #0a0a0a) is not worth it
     when every palette's darkest slot is already a black to the eye.

     The fill is pinned back to --series-1 rather than following the line —
     theme.css derives --series-total-fill from --series-total, and a black
     wash under the curve reads as a shadow on cream. The line carries the
     identity; the wash stays the warm grey it always was. */
  --series-total: #000000;
  --series-total-fill: var(--series-1);
  /* The disc behind the 3D logo (see .lg-wrap::before). Full-strength accent
     in every theme — the masthead's one fixed mark. Dark mode does not dim it;
     instead the logo's own outlines are flipped back to ink further down, so
     the artwork keeps cutting against the lime. */
  --pb-lg-disc: var(--pb-accent);
  /* The grey fill every INNER surface wears — the hero card's sub-tiles (Cash,
     Total P/L, Portfolio fundamentals), the drawer's cards, the segmented
     tracks, the chips and every hover wash. Back to 0.055 on 16.09.2026:
     07.09.'s blanket `alpha = 1 - (1 - alpha) * 0.9` was fitted to the glass
     panels (0.56 → 0.604, a 8% step) and read as a near-tripling down here
     (0.055 → 0.1495), which turned an inner tile from a hair off the card
     (#e9eaec on #f4f5f7) into a flat mid grey (#d5d6d8). Josef asked for the
     lighter tone back, so THIS token and --wash keep their pre-07.09 values in
     every skin; the panels, borders, shadows and blurs keep the adjustment. */
  --pb-soft: rgba(36, 38, 43, 0.055);
  /* Report / tutorial card fill — see .chat-suggest below.
     The SAME wash the assistant's own reply bubbles take (.chat-msg.assistant),
     transparency and all, in both themes: everything stacked inside that panel
     is one material, and the cards are the top of the same column of bubbles.
     It went through an opaque --surface-1 and then two translucent creams on
     the way here, each fitted against the panel in isolation — a card lifted
     off the glass by its own measured step still read as a different substance
     from the bubble below it. Sameness beats separation here; the darker
     description ink (--ink-2, fitted to these frosted panels) is what carries
     legibility, not the fill. */
  --pb-suggest-bg: var(--pb-soft);
  /* The Events card's "new" marks — filled here, outlined on the dark
     card. See .evt-new below for why the two cards differ. */
  --pb-new-bg: var(--pb-accent);
  --pb-new-ink: var(--pb-accent-ink);
  --pb-new-edge: transparent;
  --pb-shadow: 0 16px 45.6px rgba(36, 38, 43, 0.217);
  --pb-shadow-sm: 0 6px 21.6px rgba(36, 38, 43, 0.208);
  /* The tutorial spotlight wears the accent: the walkthrough is the one place
     the skin points at a card, and the acid ring is unmistakable against the
     warm page. Luminance-wise lime sits close to the light surfaces, so the
     glow is carrying as much of the signal as the line — hence the wider,
     denser halo here than the base's. --spot-ring stays unresolved until the
     tile uses it, so this one pair of declarations covers dark mode too. */
  /* The segmented control's marker (chart mode, Sector tilt, What-if, and the
     two in Settings), and the label that rides on it. Light mode: the lifted
     white capsule on the soft grey track, ink label — the skin's default and
     unchanged. Dark mode overrides both below: --surface-1 is #413f3a there
     and the track is that very surface lightened by 7% (#4d4b46), so the
     capsule sat at 1.21:1 against it — measured in Chromium — and was all but
     invisible; 7.61:1 with the flip below. Dark takes the near-white
     ink instead — the same fill the range rows' active pill already wears —
     and the label flips to the surface colour to stay on top of it. */
  --pb-seg-marker: var(--surface-1);
  --pb-seg-marker-ink: var(--ink);
  --spot-ring: var(--pb-accent);
  /* The categorical chart ladder (theme.css --cat-*) is built from --ink,
     --surface-1 and three chromatic tokens, and this skin names all three.
     The base sheet would otherwise hand the accent --series-1, which Pebble
     has already muted to a warm grey — no pop at all. */
  --cat-accent: var(--pb-chart-accent);
  /* The chart GOLD, deliberately not --series-3. That one is also the
     correlation matrix's warm pole and the status-warning ink, so it is drawn
     to read as text on a cream card — muted (#b79338, OKLab C 11.6) and a
     little dark. On a stacked chart the same colour arrives as a tan: the
     ladder's gold slot measured #ab935d before this, and "make the brownish
     much more golden" is the note that produced a gold here; #d69123 is that
     gold pushed further, hue 89° -> 73° and C to 14.1 — an AMBER — after the
     Sept 2026 note that the dealt benchmark lines were still "too close
     together". The ladder's slots resolve it to #d5963c and #e0af71 on the
     cream card, #d9a145 and #b28845 on the dark one. Two values, because the
     dark card wants the lighter of the two the same way it does the accent. */
  --cat-accent-2: var(--pb-chart-gold);
  /* …and the chart's THIRD hue, the one that stops the ladder reading as a row
     of greens. It has been three things: the slate blue this comment once
     described (held every floor, and the CVD-safe direction — both
     dichromacies keep the blue-yellow axis), traded away for an OLIVE
     (#576b3f) in Aug 2026 because the house is warm and the blue read as a
     stranger, and then this deep FOREST (#2f6135) in Sept 2026, when the
     olive's dealt lines came back "too close together": at hue 129° it sat
     only 40° from the gold, and the ladder's three olive-mix slots were three
     murky greens of one hue. 148° and deeper doubles that hue gap and spreads
     the family — still a green, still warm-adjacent, deliberately NOT the
     blue: that trade was decided against the numbers once and is not
     relitigated here. Measured with the amber above: the four default
     benchmark lines' worst pair goes 12.9 -> 16.3 on the cream card, 8.5 ->
     11.8 on the dark one. */
  --cat-accent-3: var(--pb-chart-olive);
  --pb-spot-glow: 0 0 43.2px -2px color-mix(in srgb, var(--spot-ring) 91%, transparent);
  --pb-r-card: 30px;
  --pb-r-tile: 22px;
  /* The base sheet's handle on the card radius (theme.css --r-card). It reads
     it to derive one thing — the radius of a tile that a card FRAMES, as
     --r-card minus that frame (theme.css --r-tile) — so pointing it at Pebble's
     own card radius is all the concentric maths needs, at both the 30px scale
     here and the 24px one in the phone block at the foot of this file.
     --pb-r-tile above stays the radius of every tile that is NOT framed by its
     card: the Risk metrics, the drawer's stat tiles, a plain .grid-stats
     strip. Those sit under a heading in the card's text column and never reach
     a corner of it, so there is no channel to hold concentric and a flat 22px
     is simply the skin's tile shape. */
  --r-card: var(--pb-r-card);
}
:root[data-theme="dark"] {
  --page: #302e2b;
  --surface-1: #413f3a;
  --ink: #f3f0e9;
  /* TWO GREYS, AND BOTH OF THEM READABLE — the same correction the light half
     got, applied to the card this skin is actually dark on.
     They were #c3bfb5 and #918d85, fitted like their light twins against a
     surface that is not the one they mostly land on: #918d85 measures 4.09 on
     the page but 3.18 on a card and 2.93 on a report card, so the dimmer of
     the two greys was under the bar anywhere it was actually used. And the
     lighter one sat far enough down that the assistant's report cards had to
     be special-cased brighter to be comfortable — a special case is the tell
     that the token was wrong, not the card.
     The pair is now #dbd7cd and #b8b4aa: 7.32 and 5.08 on a card, 8.15 and
     5.66 on the drawer, 6.74 and 4.68 on a report card. Both clear AA on every
     surface in the skin, they keep a clear 1.44 step between them, and the
     assistant's override is deleted because --ink-2 IS what it was reaching
     for. Two greys is the whole scale, deliberately: --ink for a heading,
     --ink-2 for anything read as a sentence, --muted for de-emphasis. */
  --ink-2: #dbd7cd;
  --muted: #b8b4aa;
  --grid: rgba(243, 240, 233, 0.19);
  --baseline: rgba(243, 240, 233, 0.334);
  --border: rgba(243, 240, 233, 0.208);
  --series-1: #cfcabf;
  --series-2: #7fb08c;
  --series-3: #d3b05a;
  --series-5: #a49dc4;
  --up: #7ccf95;
  --down: #e58a72;
  /* Both marker hues lift on the dark stone card — see the light block. */
  --marker-transfer: #9dbcd8;
  --marker-correction: #dbab5e;
  --marker-coverage: #a9a294;
  --status-good: #7ccf95;
  --status-warning: #d3b05a;
  --status-serious: #dc9a6a;
  --status-critical: #e58a72;
  --wash: rgba(243, 240, 233, 0.06);
  --dock-bg: rgba(65, 63, 58, 0.604);
  --dock-border: rgba(243, 240, 233, 0.199);
  --panel-bg: rgba(65, 63, 58, 0.604);
  --panel-border: rgba(243, 240, 233, 0.199);
  --panel-shadow-side: -18px 0 60px rgba(0, 0, 0, 0.406);
  --panel-shadow-pop: 0 26px 72px rgba(0, 0, 0, 0.478);
  --scrim-bg: rgba(0, 0, 0, 0.361);
  /* On the dark page the accent has plenty of contrast, so the portfolio's
     line — and its wash — take it in every chart mode. In light mode both
     tokens stay untouched (see the note at the top): lime on the pale card
     washed out. */
  --series-total: var(--pb-accent);
  --series-total-fill: var(--pb-accent);
  --curve-line: var(--pb-accent);
  --badge-glint: var(--pb-accent);
  /* The three chart hues, in their dark-card lifts. --cat-7 and --cat-8 used
     to be restated here as well, because the base sheet walked the accent
     toward the INK and this card's ink is a near-white cream that the citron
     is already nearly as light as — the two came out a hair apart. The base
     recipe now washes every slot over a step BETWEEN ink and card instead, so
     it can reach the card-ward colours this override existed to supply, and
     the override is gone rather than retuned. */
  --cat-accent: var(--pb-chart-accent-dark);
  --cat-accent-2: var(--pb-chart-gold-dark);
  --cat-accent-3: var(--pb-chart-olive-dark);
  --pb-seg-marker: var(--ink);
  --pb-seg-marker-ink: var(--surface-1);
  /* --pb-suggest-bg needs no dark override any more: it IS --pb-soft in both
     themes now, and this line moves the wash under it. */
  --pb-soft: rgba(243, 240, 233, 0.07);
  --pb-new-bg: transparent; --pb-new-ink: var(--pb-accent);
  --pb-new-edge: currentColor;
  --pb-shadow: 0 16px 45.6px rgba(0, 0, 0, 0.37);
  --pb-shadow-sm: 0 6px 21.6px rgba(0, 0, 0, 0.352);
}
@media (prefers-color-scheme: dark) {
  :root[data-theme="system"] {
    --page: #302e2b; --surface-1: #413f3a; --ink: #f3f0e9; --ink-2: #dbd7cd;
    /* Two readable greys — see the [data-theme="dark"] block above. */
    --muted: #b8b4aa; --grid: rgba(243,240,233,0.19); --baseline: rgba(243,240,233,0.334);
    --border: rgba(243,240,233,0.208); --series-1: #cfcabf; --series-2: #7fb08c;
    --series-3: #d3b05a; --series-5: #a49dc4; --up: #7ccf95; --down: #e58a72;
    --marker-transfer: #9dbcd8; --marker-correction: #dbab5e;
    --marker-coverage: #a9a294;
    --status-good: #7ccf95; --status-warning: #d3b05a; --status-serious: #dc9a6a;
    --status-critical: #e58a72; --wash: rgba(243,240,233,0.06);
    --dock-bg: rgba(65,63,58,0.604); --dock-border: rgba(243,240,233,0.199);
    --panel-bg: rgba(65,63,58,0.604); --panel-border: rgba(243,240,233,0.199);
    --panel-shadow-side: -18px 0 60px rgba(0,0,0,0.406);
    --panel-shadow-pop: 0 26px 72px rgba(0,0,0,0.478); --scrim-bg: rgba(0,0,0,0.361);
    --series-total: var(--pb-accent); --series-total-fill: var(--pb-accent);
    --curve-line: var(--pb-accent); --badge-glint: var(--pb-accent);
    /* The three chart hues in their dark lifts — see the note above the
       [data-theme="dark"] block. */
    --cat-accent: var(--pb-chart-accent-dark);
    --cat-accent-2: var(--pb-chart-gold-dark);
    --cat-accent-3: var(--pb-chart-olive-dark);
    --pb-seg-marker: var(--ink); --pb-seg-marker-ink: var(--surface-1);
    --pb-soft: rgba(243,240,233,0.07);
    --pb-new-bg: transparent; --pb-new-ink: var(--pb-accent);
    --pb-new-edge: currentColor;
    --pb-shadow: 0 16px 45.6px rgba(0,0,0,0.37);
    --pb-shadow-sm: 0 6px 21.6px rgba(0,0,0,0.352);
  }
}

body { font-family: var(--pb-sans); font-size: 13px; font-weight: 400; -webkit-font-smoothing: antialiased; }
.app { --app-pad-t: 16px; --app-pad-x: 18px; --app-pad-b: 80px; padding: var(--app-pad-t) var(--app-pad-x) var(--app-pad-b); }

/* -------------------------------------------------------------- panels -- */
.card {
  background: var(--surface-1);
  border: none; border-radius: var(--pb-r-card);
  box-shadow: var(--pb-shadow);
  padding: 20px 24px;
  /* Beside the padding it names — see --card-pad-x in theme.css. */
  --card-pad-x: 24px;
}
/* The channel between cards, as the base sheet's ONE token rather than a list
   of containers — see --card-gap in theme.css. The list this replaced was
   written before .topline-row (the value chart + heatmap row, and Explore's
   Macro + heatmap row) and .social-cols existed, so those two kept theme.css's
   12/14px while every other card gap on the page was 16 — the difference
   Josef spotted on 26.08.2026. */
:root { --card-gap: 16px; }
.hero-mid > .card, .risk-grid > .card, .grid-stats > .card,
.stats-frame .grid-stats > .card, .drawer .card {
  background: var(--pb-soft); border: none;
  box-shadow: none; padding: 14px 16px;
  /* (The Risk tiles override this padding to 10px 12px — "Risk tiles" in the
     numbers section below, 25.09.2026.)
     Beside the padding it names — without this the token still said the
     outer card's 24 in here, and everything derived from it (a drawer
     chart's phone bleed, a nested table's pull-out) landed 8px wrong. */
  --card-pad-x: 16px;
}
/* A tile that sits loose inside a card — under a heading, never in one of the
   card's corners — takes the flat tile radius. The tiles that are FRAMED by
   their card (the hero card's three sub-tiles, a stats frame's strip) are the
   exception: their radius has to be the card's minus that frame or the channel
   opens up around the corners, so the base sheet derives it (theme.css
   --r-tile) and restating --pb-r-tile here would overwrite the derivation with
   a number that happens to agree at one breakpoint and not at the next. */
.risk-grid > .card, .grid-stats > .card, .drawer .card {
  border-radius: var(--pb-r-tile);
}
/* The padding is restated, not dropped, and restated as the base sheet's own
   token: this skin gives .card a 20px 24px padding, and a skin sheet loads
   after theme.css, so at equal specificity that padding lands on .hero-mid —
   which is a .card — and buries the frame width the grid's gap has to match.
   Naming the token instead of a number is what stops the two drifting apart
   again; the same applies to the stats frame below, which is the same idiom. */
.hero-mid {
  background: var(--surface-1); box-shadow: var(--pb-shadow);
  border-radius: var(--pb-r-card); padding: var(--card-inset);
}
.stats-frame { padding: var(--card-inset); }
.card h2, .acct-tile .acct-head .label { font-size: 14px; font-weight: 500; letter-spacing: -0.01em; color: var(--ink); text-transform: none; }
.card .sub { font-size: 11.5px; color: var(--muted); }
/* The strips above the Trades/Taxes cards — the disclaimer and the macro
   ribbon — introduce the panels below them, so they take the card surface
   instead of theme.css's ink wash, which painted them as a darker band across
   the page. Borderless like every other Pebble panel; the wash needed its
   1px edge, a light panel doesn't. Shadow is the small one, not --pb-shadow:
   these are one-line bars barely taller than that shadow's 16px drop, which
   would puddle out from under them — --pb-shadow-sm lifts them into the same
   family at strip scale. Radius stays the tile radius set further down; the
   card's 30px would round a 32px bar into a lozenge. */
.trades-disclaimer, .macro-ribbon {
  background: var(--surface-1); border: none; box-shadow: var(--pb-shadow-sm);
}
/* Desktop-only Taxes privacy footnote — a quiet muted line, not a panel. */
.taxes-privacy { font-size: 11px; color: var(--muted); }

/* -------------------------------------------------------------- header -- */
.brand { font-size: 14px; font-weight: 650; letter-spacing: -0.02em; text-transform: none; }  /* 650 + -0.02em is the shared wordmark spec — website/public/styles.css .brand carries the same, so the name reads identically on both */
.brand .accent { color: var(--ink-2); }
/* The masthead's accent is the disc BEHIND the 3D logo, not the wordmark: one
   lime pebble the transparent wireframe sits on.
   It is painted on .lg-wrap::before and NOT on .lg — .lg's filter chain ends
   in grayscale(1), which applies to that element's own background and to every
   descendant and pseudo-element of it, so the same disc drawn as .lg's
   background or .lg::before would render grey. Do not "simplify" it back onto
   .lg. The wrapper is outside the filtered subtree, so the lime survives.
   Geometry is in the logo's own 74×58 coordinate space times --lg-scale (set
   by theme.css, 0.56 desktop / 0.5 on phones): a 72px circle centred on the
   wrapper at local x = 36·s. .lg scales about its left/centre origin, hence
   the x from the wrapper's left edge.
   72, not the art's swept 77, and centred rather than lifted 5px to the art's
   optical centre — both because of the 12.08.2026 slimming pass. The bar is
   40.5px tall now and comes to rest at the very top of the viewport, so
   anything taller than the bar has its top SHAVED OFF by the window once the
   page scrolls: at 77 the disc measured 43.1 and lost 5px of its crown, a
   circle with a flat top. 72·0.56 = 40.3 fits inside the bar with 0.2px to
   spare, and dropping the lift is what centres it there. The price is that
   the coin now GRAZES the disc at the sway extremes instead of clearing it
   (checked frame by frame with the animations frozen — it touches, it does
   not break out). Both numbers are tied to the bar's height: re-measure them
   together, and never simply grow the disc back.
   Horizontally there is room to spare — at s=0.56 it spans −1.4…38.9px and
   .brand starts at 47.4. Absolutely positioned, so it reserves no space: the
   topbar, brand, tabs and controls measure identically with and without it. */
.lg-wrap::before {
  content: ''; position: absolute; pointer-events: none;
  /* Same paint step as .lg (both positioned, z-index auto/0) and earlier in
     tree order, so it always lands underneath the outlines and symbols. */
  z-index: 0;
  width: calc(72px * var(--lg-scale, 1)); height: calc(72px * var(--lg-scale, 1));
  border-radius: 50%;
  left: calc(36px * var(--lg-scale, 1)); top: 50%;
  transform: translate(-50%, -50%);
  background: var(--pb-lg-disc);
}
/* The disc reaches further right than the bare artwork did (it clears the
   wordmark by 0.4px), so the masthead needs the gap back: 5px between the
   pebble's edge and "Portfolio". Scoped to this skin — no disc, no crowding,
   in the others.
   The mark also RIDES UP by exactly half of what the disc grew (--lg-grow,
   theme.css), and that is what keeps "10% larger" from costing the bar any
   height. The disc used to sit centred on the wrapper with its foot 0.09px
   inside the bar's bottom edge and 8px of unused bar above it — grown, it
   would have hung ~2px below the bar and over the page. The lift spends the
   room that was going spare instead; the two margins cancel, so the flex
   line — and the bar — measure exactly as before. It falls to zero on its
   own wherever --lg-grow is 1 (phones), so nothing shifts there. */
.lg-wrap {
  margin-right: 5px;
  --lg-lift: calc(72px * var(--lg-box) * (var(--lg-grow) - 1) / 2);
  margin-top: calc(-1 * var(--lg-lift));
  margin-bottom: var(--lg-lift);
}
/* The gold bar is the artwork's only filled shape. On the lime disc its
   brushed silver was the one thing not drawn in ink, so it reads as ink too —
   a flat fill, no gradient, matching the outlines around it. */
.lg .ingot { background: var(--lg-ink); }
/* Dark mode keeps the full-strength disc, so the artwork flips back to INK.
   theme.css turns the logo's outlines and engraved symbols near-white for a
   dark page — correct with no disc behind them, unreadable on lime. Same
   selectors as theme.css's dark blocks; this sheet loads later, so it wins. */
:root[data-theme="dark"] .lg {
  --lg-ink: rgba(25, 25, 30, 0.865);
  --lg-sym: #3c3c42;
  --lg-shadow-face: inset 0 0 0 1.2px rgba(25, 25, 30, 0.352);
  --lg-ingot: linear-gradient(180deg, #b0b1ba, #8e8f99);
}
@media (prefers-color-scheme: dark) {
  :root[data-theme="system"] .lg {
    --lg-ink: rgba(25, 25, 30, 0.865);
    --lg-sym: #3c3c42;
    --lg-shadow-face: inset 0 0 0 1.2px rgba(25, 25, 30, 0.352);
    --lg-ingot: linear-gradient(180deg, #b0b1ba, #8e8f99);
  }
}
.tabs { gap: 3px; }
.tab {
  /* 8px of side padding, down from 15 → 11 → 8 over two passes, and the gap up
     from 2 to 3 with it.
     What is being narrowed is the distance between two WORDS, which is the
     pair of paddings plus the gap: 15+2+15 = 32 before any of this, 24 after
     the first pass, 19 now — another 20.8%, as asked. The strip runs 401 → 370
     and the labels themselves are still untouched.
     The gap goes UP by a pixel on purpose. Padding is what separates two
     labels while also being the pill's own margin, so cutting it alone starts
     to read as two words running together; a pixel of true gap buys the
     separation back while still costing four less than it saves. */
  border-radius: 999px; padding: 7px 8px; border-bottom: none;
  font-size: 11.5px; font-weight: 400; letter-spacing: 0; text-transform: none;
  color: var(--ink-2);
}
.tab:hover { background: var(--pb-soft); }
.tab.active { background: var(--ink); color: var(--surface-1); font-weight: 500; }
/* Once the strip is measured (theme.css) the pill IS the sliding indicator,
   so it grows to the full button and takes the capsule radius; the active
   label keeps its own flip to --surface-1 on the button. */
.tab-indicator { top: 0; height: auto; background: var(--ink); border-radius: 999px; }
/* ------------------------------------------------------------- numbers -- */
.stat .label { font-size: 11.5px; font-weight: 400; letter-spacing: 0; text-transform: none; color: var(--muted); }
/* The Risk tiles' figures left this rule on 25.09.2026 — see "Risk tiles" just
   below; every other value here (the hero, the Cash card, the diversification
   score) keeps its 24px. */
.stat .value, .hero-mid .stat .value, .divers-score .value {
  font-weight: 500; letter-spacing: -0.035em; font-variant-numeric: tabular-nums;
  font-size: 24px; line-height: 1.08; margin-top: 7px;
}
/* Risk tiles, packed tighter (Josef, 25.09.2026: "the Risk card's large
   numbers can be a bit smaller and maybe some of the cards can be packed bit
   more tightly so they become overall smaller and we can fit more on single
   line"). Measured before, beside the docked assistant at a 1400px window
   (an 894px grid): five 169px tiles to a row, 24px figures, 14px 16px
   padding, and Best / worst day's pair broken over two lines. Now: 20px
   figures (−1/6), 10px 12px padding, 5px above the figure, and the grid's
   narrowest track 150 → 136px (theme.css .risk-grid), which puts six on that
   row and all seven from a 1024px grid up. The gap between the tiles stays
   --card-inset: it is the card's one tile channel, the same number as the
   grid's side gaps (theme.css .risk-grid), and splitting it would open two.
   Split out of the shared padding and value rules above rather than added to
   them — those also size the hero, the Cash card and the drawers, which were
   not asked about. */
.risk-grid > .card { padding: 10px 12px; --card-pad-x: 12px; }
.risk-grid > .card .value {
  font-weight: 500; letter-spacing: -0.035em; font-variant-numeric: tabular-nums;
  font-size: 20px; line-height: 1.08; margin-top: 5px;
}
/* Best / worst day is the one tile holding two figures. At 20px a pair such as
   "+16.6% / −26.7%" is ~134px, wider than a 136px track's text box (112px), so
   it takes one notch down OF ITS OWN FIGURE — 16px, ~107px — and stays on one
   line wherever the grid lets six or seven tiles stand. Scoped to .value: the
   dates under it are a pair too, and they keep the 10.5px of every .sub2.
   It also outranks theme.css's phone notch (.stat .value .slash-pair, 0.72em
   under 560px) by sheet order — on a phone that is 16px instead of 14.4px,
   which still fits the two-to-a-row tile's 146px text box whole. */
.risk-grid .value .slash-pair { font-size: 0.8em; }
/* Price refresh mirrors the quiet column gear; keep its hover squircle in
   the default skin's soft field in both themes. */
.asof-refresh:hover { background: var(--pb-soft); }
/* Portfolio’s refresh follows the surrounding card’s inset corner arc. */
.asof-corner .asof-refresh { border-radius: max(0px, calc(var(--pb-r-card) - 8px)); }
/* Time travel (TimeTravel.tsx): the clock is the refresh button's twin, and
   while a past day is on screen it holds the hover field as its state. The
   date pill is this skin's active tab (.tab.active: --ink capsule, weight
   500), and the popover under the clock joins the floating family's 18px
   corner (.mpick-pop, .dpick-pop). */
.tt-open.active { background: var(--pb-soft); color: var(--ink); }
.tt-pill { font-weight: 500; }
.tt-pop { border-radius: 18px; }
.asof-note, .current-only { color: var(--muted); }
/* Compact position-chart key uses the same muted caption ink as the card. */
.position-chart-key { color: var(--muted); }
/* Keep complete marker labels together in the position heading’s wrapping row. */
.chart-head h2 > .marker-legend .marker-key { white-space: nowrap; }
/* The value tile is the hero of the column, so it gets the full card
   treatment — a light panel floating on a shadow — instead of the washed
   sub-tile look its small siblings above share. */
.hero-left .grid-stats > .acct-tile {
  flex-basis: 100%; border-radius: var(--pb-r-card); padding: 20px 22px; --acct-pad-top: 20px;
  background: var(--surface-1); box-shadow: var(--pb-shadow);
}
/* Capped at 31px, and the cap is MEASURED, not chosen: this card's column is
   held to 366px by the hero grid however wide the window gets, the ring beside
   the number takes 112 of it (the box the value donut and the Diversification
   dial share — see .acct-donut in theme.css, and RING in helpers.tsx; the
   painted ring inside it is 104 across) and the padding 44, so the total has
   202px. A 13-character total
   — "2 000 739 CZK", "4 626 904 CZK" — is 6.44px wide per px of type, so 31px
   is the largest that still shares the line with the ring; at the 42px this
   said before any of it, every such number wrapped onto a second line on any
   wide screen, which is what broke the card. Longer totals still wrap,
   deliberately, rather than pushing the ring out — they just no longer take
   the ring with them. The number keeps the theme's ink — the accent was tried
   here and read as washed-out lime on the light panel. */
.hero-left .grid-stats > .acct-tile .value {
  font-size: 29px; /* constant, not vw — no drift during a window resize; 29 is the fit cap for the 352px column (valueRing.test.ts) */ line-height: 0.98; letter-spacing: -0.045em;
}
/* constant, not vw — the figure must not drift during a window resize */
.stat.hero .value { font-size: 25px; }
.stat .delta {
  display: inline-flex; align-items: center; margin-top: 9px;
  background: var(--pb-soft); border-radius: 999px; padding: 5px 12px; font-size: 12px;
}
/* The capsule belongs to the ▲/▼ day change — it reads as a badge on the
   number. A sub-note is a caption, so it drops the wash (which doubled up on
   the tile's own wash into a darker inner pill) and the capsule padding, and
   goes back to the plain block the base sheet gives it: the Cash breakdown
   needs the full tile width for its hairline rule and right-aligned amounts.
   One rule covers the Taxes summary tiles and the Cash card. */
.stat .delta-sub {
  display: block; background: none; border-radius: 0; padding: 0;
}
/* The extended-hours note under the day-change capsule. It already sheds the
   wash and the padding through .delta-sub above; what it still needs is its
   own spacing — .stat .delta's 9px was measured for a badge hanging off the
   big number, and applied again here it left the two deltas floating apart
   instead of reading as figure + caption. Smaller than the capsule too: the
   badge is the headline, this is the footnote to it. */
.acct-tile .delta-xh { margin-top: 6px; font-size: 11px; }
/* The Taxes headline tiles are peers of the tab's other cards rather than
   sub-tiles inside one, so all four wear the same light panel — surface, card
   radius, card shadow — as the Portfolio value tile, instead of the wash
   .grid-stats > .card hands out. Padding sits between the sub-tile's and the
   full card's: the bigger radius wants room, four across haven't much. */
.grid-stats.tax-strip > .card {
  background: var(--surface-1); border-radius: var(--pb-r-card);
  box-shadow: var(--pb-shadow); padding: 16px 18px;
}

/* The tutorial spotlight (theme.css `.card-spot`). Its ring is an `outline`,
   so it already survives everything above; the glow is a shadow, and the rules
   above own `box-shadow` on every card here — the plain panel with
   --pb-shadow, the sub-tiles with `none`. So the glow is re-composed once per
   case: alongside the panel shadow where there is one, alone where the tile is
   deliberately flat. Panels keep their lift while they are spotlit rather than
   flattening for the length of the step. The glow is the accent (see
   --spot-ring), so a spotlit panel carries its own warm shadow and an acid
   halo at once — the two do not muddy, they sit at opposite ends of the
   tonal range. */
.card-spot { box-shadow: var(--pb-spot-glow); }
.card.card-spot,
.grid-stats.tax-strip > .card.card-spot { box-shadow: var(--pb-shadow), var(--pb-spot-glow); }
.hero-mid > .card.card-spot, .risk-grid > .card.card-spot,
.grid-stats > .card.card-spot, .stats-frame .grid-stats > .card.card-spot,
.drawer .card.card-spot { box-shadow: var(--pb-spot-glow); }

/* ------------------------------------------------------------ controls -- */
/* Everything interactive is a capsule. Bare `.chip` is the catch-all — without
   it, a chip in a container nobody had listed (the account menu's "Sign in /
   Create account") kept the base's square corners. The scoped variants below
   it are NOT redundant: theme.css styles several of them at (0,2,0)
   (.filter-row .chip, .pager .chip …), which outranks a bare .chip whatever
   the sheet order, so each of those still needs its own entry here. */
.chip, .acct-actions .chip, .filter-row .chip, .tag-legend .chip, .seg button, .bench-chip,
.preset-chip, .chat-asks .ask-chip, .tutorial-level, .pager .chip, .ctx-chip,
.rec-chip, .rec-wait, .rec-kind, .src-badge, .report-link, .tag, .action-chip,
.chip.tour-chip, .chip.first-run-link, .transfer-actions .chip,
.mlot-form .chip, .trades-recs .chip, .sellopt-drawer .chip, .lv-badge,
.evt, .rec, .whatif-go, .demo-btn, .btn-ghost, .oa-btn, .settings-save,
.tutorial-stop, .report-stub, .evt-season-btn, .annual-foot .annual-csv,
.settings-btn, .notes-fab, .pf-finder-box, .mpick-btn, .colpick-btn,
.reaction-chip, .friend-chips .chip, .friend-months .chip,
button.chip.card-retry {
  border-radius: 999px;
}
/* A notch tighter since 22.08.2026 — sized to read like the chips in the
   rows under it, not like a second tab bar. */
.seg { background: var(--pb-soft); border-radius: 999px; padding: 3px; }
.seg button { padding: 4px 10px; font-weight: 400; }
.seg button.active {
  background: var(--pb-seg-marker); color: var(--pb-seg-marker-ink);
  box-shadow: var(--pb-shadow-sm); font-weight: 500;
}
/* Once the group is measured (theme.css) the lifted capsule IS the sliding
   marker, so it takes the button's own radius, fill and lift; the active
   label keeps its colour and its 500 weight on the button. */
.seg-indicator { background: var(--pb-seg-marker); border-radius: 999px; box-shadow: var(--pb-shadow-sm); }
.filter-row .chip:hover { background: var(--pb-soft); }
.filter-row .chip.active { background: var(--ink); color: var(--surface-1); font-weight: 500; }
/* The range rows' marker is that same ink capsule, handed over from the chip
   the moment the row is measured; the label keeps its --surface-1 flip and
   its 500 weight on the chip. */
.range-indicator { background: var(--ink); border-radius: 999px; }
/* Pebble's inputs are capsules — taller than the base's 8px-radius boxes — so
   theme.css's 7px stack gap leaves the rows nearly touching (Settings →
   Assistant, where Provider/API key/Model sit three deep, is the worst of it).
   The rows are flex boxes whose height is the input's, so gap + margin IS the
   clear channel between two capsules — measured in-browser, not guessed.
   The extra room is scoped to ADJACENT FIELD ROWS: a blanket gap also pushed
   headings, their descriptions and the separators apart, which left every
   section looking unrelated to its own caption. */
.settings-panel { gap: 8px; }
.settings-panel .settings-row + .settings-row { margin-top: 4px; }
/* …but never inside a .settings-rowpair: there the two rows sit SIDE BY SIDE
   (Assistant tab — Model+Thinking, Provider+API key), and the stacking gap
   dropped the second half 4px below the first's centre line. */
.settings-panel .settings-rowpair > .settings-row + .settings-row { margin-top: 0; }
/* The compact account rows (AccountSettings AcctRow): the two-column layout is
   structural (theme.css); pebble only pins the section heading to its lighter,
   tighter idiom — the same treatment .card h2 gets above. */
.settings-panel h3 { font-weight: 500; letter-spacing: -0.01em; color: var(--ink); }
.acct-setting-actions .btn-ghost { white-space: nowrap; }
/* The unconfirmed-address notice at the head of the account panel
   (VerifyEmailNotice) wears GuestDataNotice's `card data-warn data-note`
   shell. On the Portfolio tab that shell is a page-level card and correctly
   takes this skin's full card geometry — the 24px inset, the ambient lift.
   Inside the Settings sheet it is one block among the account rows, and a
   shadowed 24px card there reads as a second sheet floating inside the first.
   So it drops back to the base sheet's own padding and to the flat tile
   radius the sheet's other inset blocks wear. */
.settings-panel .acct-verify {
  padding: 11px 12px; box-shadow: none; border-radius: var(--pb-r-tile);
}
/* The named groups of Other assets / Market-priced assets (AssetGroups.tsx):
   the drop ring a drag draws around a group takes the flat tile radius the
   sheet's inset blocks wear, and the group name — the account-name editor
   (.acct-name-btn, capsuled below) — this skin's lighter heading weight, the
   500 .card h2 and .settings-panel h3 take here. */
.settings-panel .ag-group { border-radius: var(--pb-r-tile); }
.settings-panel .ag-head .acct-name-btn.ag-name { font-weight: 500; }
/* The settings panels' chips (Alerts' "+ Add rule", Trades' "+ Add target",
   Strategy's "Use the … text / Keep mine" offer, which replaced its preset
   buttons on 24.09.2026) are .settings-panel .bench-chip,
   and theme.css pins that to a 7px squircle at (0,2,0) — the capsule list
   above is (0,1,0) and loses, so they were the one chip row in the app still
   wearing corners. Restated at matching specificity. */
.settings-panel .bench-chip { border-radius: 999px; padding: 5px 12px; }
/* Same trap for the account pair: theme.css pins .acct-menu/.acct-actions
   .chip to its 7px squircle at (0,2,0) — the lime "Sign in / Create account"
   in the popover was the one accent button still wearing corners. Restated
   at matching specificity, disabled state included (a radius is a shape,
   not an affordance). */
.acct-menu .chip, .acct-actions .chip { border-radius: 999px; }
/* The accent is the "go" colour, and the chat's two Send buttons join the
   group — the composer's and the edit-a-message form's, which is the same verb
   sending the same text to the same assistant. Unlike .settings-save they wear
   it unconditionally: Send is disabled whenever the composer is empty, which is
   most of the time you are looking at the chat, and a Send that only turns lime
   once you have typed reads as a different button rather than a ready one. The
   disabled state is carried by theme.css's dim instead (.chat-input .btn-ghost
   :disabled, the .demo-btn:disabled idiom). The edit form's Cancel is a bare
   .btn-ghost and stays the quiet outlined pill next to it. */
.whatif-go, .demo-btn, .settings-save:not(:disabled),
.chat-input .btn-ghost, .chat-edit-send,
/* (0,4,0), matching theme.css's own rule for it — at less the base's --series-1 fill wins. */
.chip.first-run-link.first-run-primary:not(:disabled),
.acct-menu .chip, .acct-actions .chip:not(:disabled) {
  background: var(--pb-accent); color: var(--pb-accent-ink); border-color: transparent;
  font-weight: 500; box-shadow: var(--pb-shadow-sm);
}
/* The demo button is the one accent pill that sits on a light card with a lime
   beacon glow behind it, so its edge dissolves into the halo — a hairline in
   the label's own ink gives it back a definite shape. Kept to this button:
   the other accent pills sit on plain surfaces and need no edge. */
.demo-btn { border: 1px solid var(--pb-accent-ink); }
/* The fill is RESTATED here, not just dimmed. The base's hover for these
   buttons is a translucent wash over a transparent ground — correct for an
   outlined button, and at (0,3,0) it beat the resting accent rule above,
   which is (0,2,0). So an accent pill lost its paint the moment the pointer
   touched it: the lime "Sign in / Create account" turned into a grey box,
   and the chat's Send did the same. Repeating the accent at hover-level
   specificity is what keeps the fill under the brightness. */
.acct-menu .chip:hover:not(:disabled), .acct-actions .chip:hover:not(:disabled),
.whatif-go:hover:not(:disabled), .demo-btn:hover:not(:disabled),
.settings-save:not(:disabled):hover, .chip.first-run-link.first-run-primary:not(:disabled):hover,
.chat-input .btn-ghost:not(:disabled):hover,
.chat-edit-send:not(:disabled):hover {
  background: var(--pb-accent); filter: brightness(0.96);
}
.holdings-filter, .settings-row input, .settings-row select, .strategy-text,
.whatif-form input, .whatif-form select, .oa-row input, .oa-row select,
.src-pending select,
.mlot-form input, .feedback-email, .ccy-combo input, .size-filter input,
.size-filter select, .corr-count, .chat-input textarea, .settings-field,
.license-token, .alerts-delivery select, .alerts-threshold {
  border-radius: 999px; border-color: transparent; background: var(--pb-soft); padding-left: 14px; padding-right: 14px;
}
/* Multi-line fields keep soft corners, not the full capsule: a 999px radius
   on a 3-row textarea clips the first characters of its middle lines. The
   licence-token paste box (desktop account sheet) is one of them. */
.strategy-text, .feedback-text, .chat-input textarea, .license-token { border-radius: 20px; }
/* ⚙ Settings → Data, the Other-assets / Market-priced rows in columns
   (theme.css .oa-grid, 25.09.2026): the two narrow columns — the currency
   select and the APY number — keep the capsule but not its 14px sides,
   which left "11" no room at all in a 45px pill. */
.oa-grid .oa-ccy { padding-left: 10px; padding-right: 4px; }
.oa-grid .oa-apy { padding-left: 9px; padding-right: 5px; }
/* The accent ring on focus, by element and not by name. This was a list of
   three selectors, so the Explore-tables spinners, the tax fields, the Skills
   editor and every field written since kept the browser's blue default —
   foreign paint in a warm grey design. Element selectors cannot miss one.
   A box-shadow rather than an outline: it follows the capsule radius, and it
   lands on the handful of fields whose base rule marks focus with a border
   tint instead of a ring (.oa-row, .ccy-combo, .mlot-form…), which keep that
   tint here on top of the acid ring.
   :focus-visible matches the base rule — a mouse click into a text field
   still rings it, a click on a checkbox or a slider does not. */
input:focus-visible, select:focus-visible, textarea:focus-visible {
  outline: none; box-shadow: 0 0 0 2px var(--pb-accent);
}
/* The ring is the ONLY focus mark. theme.css also darkens several fields'
   borders on focus (.feedback-text/-email, .ccy-combo input, .oa-row, and the
   finder box below), which under this skin draws a second outline just inside
   the lime one. Those rules are (0,2,0) — a class plus :focus — so plain
   `input:focus-visible` at (0,1,1) loses to them. The :root prefix is purely a
   specificity lever: it adds a pseudo-class, making this (0,2,1), which wins
   without naming a single field. The base keeps its tint for the unskinned
   look. */
:root input:focus-visible,
:root select:focus-visible,
:root textarea:focus-visible { border-color: transparent; }
/* The finder keeps the base's one exception: its borderless input hands the
   focus to the box around it, which is what reads as the field. */
.pf-finder-input:focus-visible { box-shadow: none; }
/* The accent ring is the whole focus signal here: theme.css also darkens the
   box's border on focus, which under this skin reads as a second, competing
   outline just inside the lime one. */
.pf-finder-box:focus-within {
  box-shadow: 0 0 0 2px var(--pb-accent), var(--pb-shadow-sm);
  border-color: transparent;
}
.holdings-filters { background: var(--pb-soft); border-radius: var(--pb-r-tile); padding: 12px 16px; }

/* -------------------------------------------------------------- tables -- */
/* The header label is a step under the body type it labels, and the column
   gutters are 4px a side — see the note on table.data in theme.css. The row
   PADDING stays 9px: this skin's tables breathe vertically, and it is the
   horizontal budget that was pushing a twenty-column table off-screen. */
table.data th {
  font-size: 9.5px; font-weight: 500; letter-spacing: 0.015em; text-transform: none;
  color: var(--muted); border-bottom: 1px solid var(--border); padding-bottom: 9px;
}
table.data td { border-bottom: 1px solid var(--border); padding: 9px 4px; }
table.data tbody tr.click:hover { background: var(--pb-soft); }
.cell-name .nm { font-weight: 500; }
.weighttrack, .rec-bar, .rangetrack, .drift-track, .tilt-track,
.progress-track, .segbar, .weightbar, .rec-bar-fill,
.drift-fill, .progress-fill, .segbar-pill, .mat-bar,
.tilt-you, .tilt-bench, .punch .cell, .corr-heat .cell {
  border-radius: 999px;
}
/* .segbar is NOT in this list: the breakdown rails carry no track at all (see
   theme.css). Every breakdown that uses one sums to 100%, so a fill behind the
   pills only ever shows in the hairline gaps between them — an outline round
   each segment rather than a rail they sit in. The others below really are
   tracks: their bars do not fill the row, so the rail is what shows the scale. */
.weighttrack, .rec-bar, .drift-track, .tilt-track { background: var(--pb-soft); }
/* The score dial's and the value donut's tracks are the same soft rail the
   bars ride on. Their ARCS are not listed here on purpose: the donut's carry
   per-account colors off the categorical ladder, and a rule would beat them
   exactly the way the one below beats the dial's stroke=. */
.dial-track, .acct-donut .donut-track { stroke: var(--pb-soft); }
/* The ring is the accent at every score — the number, the grade word beneath
   it and the per-dimension sub-scores still carry the good/warning/critical
   reading, so the arc itself does not need to. A presentation attribute (the
   component's stroke=) loses to any rule, which is how .dial-track is skinned
   too. */
.dial-arc { stroke: var(--pb-accent); }
.punch .cell, .corr-heat .cell { border-radius: 6px; }
/* The Events card's two "new" markers — the filing pill and the header count
   — flag what just arrived, which is exactly the accent's job here. The ring
   follows the text through currentColor, so both stay lime. */
/* The "NEW" flag on a filing and the "N new" count beside the Events heading.
   Two treatments, because the lime behaves oppositely on the two cards and the
   mark is not the thing that changes — the card under it is.
   LIGHT fills: the accent as TEXT inside a ring of the same colour is the one
   thing this lime cannot do on cream, about 1.3:1, and at 9px / 700 weight
   there is nothing to compensate with. So the accent becomes the surface with
   --pb-accent-ink on it (12.71:1) — the pairing every other lime control here
   uses, the Send button, the Start-tutorial pill, the fab.
   DARK keeps the outline. The same lime on the dark card is already the
   loudest thing in the row: filled, it stopped reading as a flag and started
   reading as a button, which is what Josef pushed back on. A hairline ring is
   enough when the card is doing the contrast for you. */
.evt-new, .evt-new-badge {
  background: var(--pb-new-bg); color: var(--pb-new-ink);
  border-color: var(--pb-new-edge);
}

/* The Allocation card's verdict lines and fact chips (AllocationCard): the
   dot carries the app's four severity colours, the warn one the
   skin's accent rather than the base's amber — and every clickable thing is
   a capsule on the soft wash, as the rest of the skin's controls are. */
.verdict.sev-warn .dot { background: var(--pb-accent); }
.verdict.sev-info .dot { background: var(--ink-2); }
.verdict { border-radius: 999px; }
.verdict:hover { background: var(--pb-soft); }
.alloc-chips .chip { border-radius: 999px; background: var(--pb-soft); }
.alloc-chips .chip:hover { background: var(--pb-soft); color: var(--ink); }
.dist.dist-hot, .dist-span2.dist-hot { border-radius: var(--r-tile); }
/* The digest's own tables sit on the skin's soft wash, the way every nested
   panel here does; the dialog itself takes the card corner with the rest of
   the overlay family further down this file. */
.alert-body .md-table-wrap {
  background: var(--pb-soft); border-radius: var(--pb-r-tile, 14px);
  padding: 4px 10px;
}

/* ----------------------------------------------------------- first run -- */
/* Beacons are pure punctuation — exactly what the accent is for here — so the
   theme's blue halo becomes lime. Same color-mix technique as theme.css: the
   mixes are with transparent, so the halo stays a soft fade rather than a
   flat ring and sits right on the warm page in light and dark alike. */
@keyframes pb-first-run-glow {
  0%, 100% {
    box-shadow: 0 0 0 0 color-mix(in srgb, var(--pb-accent) 59.5%, transparent),
                0 0 16.8px 2px color-mix(in srgb, var(--pb-accent) 41.5%, transparent);
  }
  50% {
    box-shadow: 0 0 0 8px color-mix(in srgb, var(--pb-accent) 19%, transparent),
                0 0 43.2px 12px color-mix(in srgb, var(--pb-accent) 64%, transparent);
  }
}
/* One pair of selectors, same as the base: every beacon in the app — the
   Get-started card's demo button, chips and drop area, the empty tile's, the
   ⚙ Settings → Data drop area — plus the current step's number. */
.beacon:not(:disabled),
.first-run-steps li.current .first-run-tick {
  animation: pb-first-run-glow 5s ease-in-out infinite;
}
/* Reduced motion: the base's held-still halo, in lime (repeated in full so
   the shorthand still wins over the animating rule above). */
@media (prefers-reduced-motion: reduce) {
  .beacon:not(:disabled),
  .first-run-steps li.current .first-run-tick {
    animation: none;
    box-shadow: 0 0 21.6px 4px color-mix(in srgb, var(--pb-accent) 50.5%, transparent);
  }
}
/* Step badges: the finished ✓ and the current number both ride the accent
   with dark ink on it — the "Take the tour" pill's pairing — never white. Steps
   still ahead keep the quiet base circle, so the order still reads. */
.first-run-steps li.done .first-run-tick,
.first-run-steps li.current .first-run-tick {
  background: var(--pb-accent); border-color: transparent; color: var(--pb-accent-ink);
}

/* ------------------------------------------------------------ overlays -- */
/* The frosted glass recipe is preserved; corners get very soft. */
/* --drawer-pad-t restates this rule's own top padding: the pinned ✕ cancels it
   to ride 10px below the panel's top edge in every skin (theme.css .drawer). */
.drawer {
  border-radius: var(--pb-r-card) 0 0 var(--pb-r-card); border-left: none;
  --drawer-pad-t: 26px; padding: var(--drawer-pad-t) 28px 48px;
}
/* Docked as a column of its own (theme.css `.drawer.docked`, drawerDock.ts)
   it is a floating rounded panel with a gutter all round — the SAME shape
   this skin gives the maximized assistant pane below (.chat-dock.max), and
   the same 14px it stands off the window edge, because the two are now
   neighbours in one rail and a flush panel beside a floating one would read
   as a mistake. The inset the base sheet computes for it (--drawer-inset:
   the assistant's reserved width plus the gutter) is what puts it left of
   the chat; the 14 here is the same distance the chat keeps from whatever is
   on ITS right, so the pair sits on one line. Four corners rather than the
   overlay's two: nothing is flush with the window any more. */
body.drawer-docked .drawer.docked {
  top: 14px; bottom: 14px; right: calc(var(--drawer-inset) + 14px);
  border-radius: var(--pb-r-card); border-left: none; box-shadow: var(--pb-shadow);
}
/* Phone: the drawer is a full-width sheet, and the 28px above — right for the
   floating desktop panel — read as wasted width there. 12px matches the gap
   between the stacked cards inside (theme.css's ≤560px .drawer rule says the
   same), so edge gap == inter-card gap. Longhands on purpose: only the sides
   change; top/bottom keep whatever the cascade already decided. */
@media (max-width: 560px) {
  .drawer { padding-left: 12px; padding-right: 12px; }
}
.settings-sheet, .feedback-sheet, .account-sheet, .ctx-modal, .alert-modal,
.vega-modal, .docs-fig-modal { border-radius: var(--pb-r-card); }
.mpick-pop, .colpick-pop, .acct-menu, .pf-finder-results, .tip, .combo-list,
.ccy-list, .whatif-hits, .sources-panel, .reaction-pop, .conn-acct-key-pop,
.tip-fast::after, [data-tip]::after { border-radius: 18px; }
/* The refresh card left that family on 12.08 — it is read like a card, not
   like something hanging off a control (see .refresh-pill in theme.css), so
   it takes this skin's card corner and card padding. Only the two the base
   sheet cannot know are restated here; the base sheet already reads --r-card
   and its own padding, and everything else about the card — the ground, the
   float's own shadow — stays as it is. */
.refresh-pill { border-radius: var(--pb-r-card); padding: 20px 24px; }
/* The phone pull-to-refresh gap wears the same readout while it works (see
   .ptr-gap.busy in theme.css — same label row, same track, same checklist),
   so it takes the same corner. Not the same padding: that panel is bounded by
   a gap the finger opened and every px of it is height the page has to give
   up, where the float above can afford to be generous. */
.ptr-gap.busy .ptr-gap-inner { border-radius: var(--pb-r-card); }
.assistant-fab { border-radius: 50%; }
.settings-head strong { font-size: 15px; font-weight: 500; letter-spacing: -0.01em; text-transform: none; }
.settings-tabs button { border-radius: 999px; border-bottom: none; font-size: 12px; padding: 7px 15px; }
.settings-tabs button.active { background: var(--ink); color: var(--surface-1); border-bottom-color: transparent; }
/* The header's About button (theme.css: quiet muted text, ink-on-wash when
   its panel shows) takes this skin's capsule corner, like every other small
   flat control here. */
.settings-about { border-radius: 999px; }
.drawer-head h1 { font-weight: 500; font-size: 24px; letter-spacing: -0.03em; }
/* The ⓘ after the name (theme.css .drawer-title), at the same 0.75 of this
   skin's 24px title. */
.drawer-title > .info { font-size: 18px; margin-left: 8px; }
/* The drawers' "About …" section (AssetDescription.tsx — a .card with an h2,
   the Recent news card's twin, so the skin's card and h2 rules already dress
   it). Its wait's title-high and text-high pulse lines take this skin's
   capsule ends, like its other thin bars — theme.css squares them to the
   base sheet's 4px. */
.asset-desc-wait .skeleton-block { border-radius: 999px; }
/* The drawer's ✕ and ↘ keep the base sheet's 7px squircle — the assistant
   pane's own head buttons (.chat-win) get no rule from this skin either, and
   the two strips stand side by side on one line (22.09.2026; this used to
   make them 50% discs, which is what set them apart). The strip's shared
   height is still --finder-h — this skin used to size the ✕ at 34 while the
   search pill it sat beside stayed 26. */

/* ----------------------------------------------------------- assistant -- */
/* The maximized dock becomes a floating rounded panel with a gutter. */
.chat-dock, .chat-dock.float { border-radius: var(--pb-r-card); }
.chat-dock.max {
  top: 14px; right: 14px; bottom: 14px; height: auto;
  border-radius: var(--pb-r-card); border-left: none; box-shadow: var(--pb-shadow);
}
/* The 14px this skin stands its maximized pane off the window edge widens
   the visible dashboard→assistant gap by the same amount; theme.css adds it
   to the column's LEFT padding while maximized, so both gaps read equal.
   Declared on :root, not .app: the overlay scrims are portaled to <body> and
   fade their dim out AT this edge (theme.css, the chat-maximized scrim
   block), and from .app they could not see it. .app inherits the same value,
   so its own gutter calc is unchanged. */
:root { --dock-float-inset: 14px; }
.chat-dock .chat-card { border: none; }
.chat-msg { border-radius: 20px; padding: 11px 15px; font-size: 12.5px; line-height: 1.55; }
.chat-msg.user { background: var(--ink); color: var(--surface-1); border-radius: 20px 20px 6px 20px; }
/* The links in your own bubble. Every chat link wears the app's link green
   and plain underline (theme.css, 24.09.2026), but this bubble is painted in
   the page's ink — near-black in the light theme, cream in the dark — so the
   page's --link would land on the very ground it was chosen against the
   negative of, and theme.css falls back to the bubble's ink. Here they keep
   the green: --link-on-ink, the other palette's link green, the one made for
   a ground of this lightness. The same selectors as theme.css's fallback,
   so the later sheet wins. The ticker chip keeps the bubble's ink: it is
   not a link. */
.chat-msg.user a,
.chat-msg.user .dash-link,
.chat-msg.user .docs-link { color: var(--link-on-ink); }
.chat-msg.assistant { background: var(--pb-soft); border-radius: 20px 20px 20px 6px; }
/* Proactive ✨ tips (ChatCard): the reply bubble above plus theme.css's green
   wash. The fold arrow and the hover Copy beside it sit INSIDE this skin's
   20px corner, centred on the first line (11px padding + half the 1.55 line
   box, less half the 19px button), and the text keeps clear of the arrow.
   A reply's Copy is a FLOAT (theme.css .chat-copy-msg), placed by margins:
   no top margin centres it on the first line like the arrow, and the right
   margin puts its edge 12px in (the arrow's own inset) on a reply, 40px in
   (one box left of the arrow) on a tip. */
.chat-msg.assistant.chat-tip { padding-right: 44px; }
.chat-msg.chat-tip .chat-tip-toggle { top: 11px; right: 12px; }
.chat-copy.chat-copy-msg { margin: 0 -3px 0 6px; }
.chat-msg.chat-tip .chat-copy.chat-copy-msg { margin-right: -4px; }
/* The report cards (brief / strategy check / buy advice) and the tutorial card
   take the SAME wash as the reply bubbles right above — one line up from here,
   .chat-msg.assistant, the same token and the same transparency. They are the
   top of the panel's single column of stacked things, and reading as one
   material is worth more than any amount of separation from the glass.
   The body copy is what had to change instead: on the frosted panel it used to
   run at 2.0 against this wash, which is why the fill was chased through an
   opaque cream and two translucent ones. The greys were refitted to the frosted
   panels since (--ink-2 in the token block), and the description now holds its
   contrast on the wash itself. */
.chat-suggest { background: var(--pb-suggest-bg); border: none; border-radius: var(--pb-r-tile); }
/* The 12/15 above was cut to 10/13 on 04.09.2026: the card holds ONE title
   row now (the description moved into its tooltip) and two cards share a line,
   so the generous inset of a three-line card was most of the tile's height and
   ate the width a half-width card needs for its title. The 22px on the right
   is the ⓘ's corner (theme.css .chat-suggest-info, right: 8px) plus its
   glyph — one notch tighter than the base 24 because this skin's tile radius
   already keeps the title off the corner. The tile radius is untouched. */
.chat-suggest-btn { border-radius: var(--pb-r-tile); padding: 10px 22px 10px 13px; }
/* …and the body copy takes the FULL ink here, not the secondary grey the same
   text wears on an opaque dashboard card. Measured on this wash over the
   frosted panel the grey holds 4.63, and the button's own hover wash pulls it
   to 4.23 — under AA exactly while you are pointing at the card. Full ink is
   8.5 at rest and 8.0 hovered, and it is the ink the assistant's replies use,
   which is the point: these cards are the top of that column. The hierarchy is
   carried by size and weight instead — 11.5 regular under a 13 medium title.
   Since 04.09.2026 the only card still PRINTING a description is the
   empty-portfolio gate card; the report cards say it in their tooltip. */
.chat-suggest-desc { color: var(--ink); }
.chat-suggest-title { font-size: 13px; font-weight: 500; }
.chat-suggest-title b { font-weight: 500; }
.chat-asks .ask-chip { background: none; border-color: var(--border); padding: 7px 13px; }
/* Ask AI (chat/AskAiButton.tsx) is that chip in miniature — the same unfilled
   capsule on the hairline (inside a frosted tip and on the bells' panel alike),
   the soft wash under the pointer. */
.ask-ai { background: none; border-color: var(--border); }
.ask-ai:hover { background: var(--pb-soft); color: var(--ink); }
/* The Learn card's two path tiles (theme.css .learn-tile — the course and the
   tour): Pebble separates with washes, not strokes — the hairline goes, the
   soft wash and the tile radius do the grouping, the same trade every other
   inset panel here makes. The tile body copy takes the full ink for the same
   reason .chat-suggest-desc does two rules up (measured on this wash over the
   frosted panel, the grey dips under AA on hover). The level picker inside is
   a plain .seg and already wears the capsule track + marker above; its track
   sits on a --pb-soft tile, so it goes one step darker to stay visible. */
.learn-tile {
  background: var(--pb-soft); border-color: transparent;
  border-radius: var(--pb-r-tile);
}
.learn-tile-desc { color: var(--ink); }
/* The head row's done-chips (theme.css .learn-chip — a finished walkthrough
   collapsed onto the Learn line, 04.09.2026): edgeless like every other chip
   on this wash, exactly as .chat-asks .ask-chip is three rules up — the fill
   goes, the border is the hairline, and the capsule comes from the .chip.tour-chip
   entry in the radius list. Open, it takes the soft tile fill this skin uses for
   a pressed control instead of the base's --wash, which is nearly invisible here. */
.chip.tour-chip.learn-chip { background: none; border-color: var(--border); padding: 4px 9px; }
.chip.tour-chip.learn-chip:hover:not(:disabled) { background: var(--pb-soft); color: var(--ink); }
.chip.tour-chip.learn-chip[aria-expanded="true"] { background: var(--pb-soft); color: var(--ink); }
.learn-tile .seg { background: color-mix(in srgb, var(--ink) 7%, transparent); }
/* …and its three options a notch tighter than the card-header .seg button
   above (6px 14px): the control lives inside a tile, not a card head, and at
   the sheet's width the three names plus the sliding capsule have to fit one
   row (the base sheet sets the same tighter padding; restated here because
   .seg button outranks it by sheet order). */
.learn-levels button { padding: 5px 10px; }
/* The composer keeps the chat bubbles' 20px squircle (set with the other
   multi-line fields above) rather than a capsule: it grows with what you type,
   and a pill's ends look wrong the moment it is two lines tall. The round
   attach button and attachment pills stay capsules. */
.chat-attach, .chat-att, .chat-att-file { border-radius: 999px; }
/* The ⇩ "download this conversation" menu. Edgeless and lifted, like every
   other floating thing this skin draws — the stroke goes, the small ambient
   shadow does the separating (--pb-shadow-sm is the one for panels this size;
   the full --pb-shadow belongs to the dock and the drawer). Its rows are
   capsules, the same shape the attach button and the attachment pills take
   one line up: a menu of two choices reads as two chips here, not as a list
   with square rows. The footnote keeps its hairline — it is a rule INSIDE the
   panel, which this skin does use — and only loses the sharp corner. */
.chat-export-menu {
  border-color: transparent; border-radius: var(--pb-r-tile); padding: 7px;
  box-shadow: var(--pb-shadow-sm);
}
.chat-export-menu button { border-radius: 999px; padding: 7px 12px; }
/* The minimized assistant — one class for both surfaces (desktop .dock-fab
   and the phone FAB) — is a solid accent lozenge instead of frosted glass;
   the wireframe bubble picks up the dark label ink through currentColor.
   Keeps the floating lift, the bob and the corner sparks' unread pulse
   untouched. */
.assistant-fab {
  background: var(--pb-accent); color: var(--pb-accent-ink);
  /* --pb-shadow is Pebble's own ambient lift, far and diffuse. The app's
     --arc-lift rides on top of it for the contact edge, the same hairline the
     value donut and the Diversification dial wear — this bubble is the third
     accent-filled shape on a pale page and has the same problem they do. */
  border-color: transparent; box-shadow: var(--arc-lift), var(--pb-shadow);
}
.assistant-fab:hover { border-color: transparent; filter: brightness(0.96); }
/* Status light: a dark ring rather than the page grey, so the green
   "connected" dot still cuts an edge against the lime. */
.assistant-fab .fab-dot { border-color: var(--pb-accent-ink); }
.tkr { border-radius: 999px; padding: 1px 7px; font-weight: 500; }
.md-code { border-radius: 6px; }
.md-pre, .vega-card, .tutorial-strip, .news-ai, .strategy, .whatif-delta,
.dropzone, .data-warn, .trades-disclaimer, .macro-ribbon,
.skeleton-block, .prompt-full, .docs-fig img { border-radius: var(--pb-r-tile); }
/* Settings → Data: "Remove all files" beside the drop area (25.09.2026).
   Stretched to the zone's height it is a block, not a one-line capsule — the
   .snap-broker-pick reasoning below — so it wears the zone's own tile radius
   and the two read as one pair. (The base sheet gives it the base zone's
   10px with a selector that already outranks the capsule list.) */
.src-drop-row .oa-btn.danger.src-remove-all { border-radius: var(--pb-r-tile, 14px); }
/* The Macro card's glance row — the number tiles and the Treasury-spread chart
   that sits among them — as one family. Edgeless like every other Pebble panel:
   the tiles' darker wash already separates them, so theme.css's 1px stroke on
   top of it is one line too many. The chart is styled by a descendant selector
   in the base (.regime-strip .curve-chart), which the single-class radius list
   above could never reach — it kept the base's 8px beside its 22px neighbours,
   so both tile kinds are named here and share one radius. */
.regime-tile, .regime-strip .curve-chart {
  border: none; border-radius: var(--pb-r-tile);
}

/* ── Explore heatmap ──────────────────────────────────────────────────────
   Same treatment as the Macro tiles right above it: no stroke — the sector
   box's soft wash already separates it from the card — and the pebble radius
   instead of the base 8px, so the two Explore cards' tiles are one family.
   The asset cells take .punch/.corr-heat's 6px: they ARE that element here,
   a small coloured square in a grid of them. */
.heat-sector {
  border: none; border-radius: var(--pb-r-tile); background: var(--pb-soft);
}
.heat-cell {
  border-radius: 6px;
  /* The cells tile edge to edge, so the gap between them is this border and
     nothing else — it has to be the card surface, not a line colour. */
  border-color: var(--surface-1);
}
/* Squircle, not a rectangle: the hover ring follows the cell's own radius. */
.heat-cell:hover { outline-color: var(--pb-accent); }
/* Sector navigation keeps the heatmap's squircle hover and the existing
   chip treatment; metric badges share the asset cells' rounded paint. */
.heat-sector-head:hover:not(:disabled) { background: var(--heat-neutral); border-radius: 6px; }
.heat-tip-value { border-radius: 4px; }
.heat-swatch { border: none; border-radius: 4px; }
.news-title { font-weight: 500; font-size: 14px; }
.lg { opacity: 0.82; filter: grayscale(1) brightness(1.05); }

@media (max-width: 560px) {
  /* Horizontal padding halves to 9px on a phone — the base sheet's own phone
   number, restated here because this skin publishes 18px unconditionally and
   would otherwise outrank it at every width ("make all the borders between a
   card's outer edge and the display's edge smaller on mobile so that we gain
   more space for card content", Josef 10.09.2026: measured 18px between the
   card edge and the screen edge at 393px). That SUPERSEDES the 22.08.2026
   decision to keep the desktop 18px across this boundary ("Keep the same
   edge/margin") — the edge now does step in when a window crosses 560px,
   which is the price of the content width. A card at 393px gains 18px:
   327px of content against 309. */
.app { --app-pad-b: 64px; --app-pad-x: 9px; padding: 12px var(--app-pad-x) var(--app-pad-b); }
  :root { --pb-r-card: 24px; --pb-r-tile: 18px; }
  .chat-dock.max { top: 8px; right: 8px; bottom: 8px; }
  /* theme.css's phone shrink for the value tile uses the same selector, so
     this later sheet outranks it — restate it at Pebble's scale, or the tile
     keeps desktop padding and type on a 360px screen. */
  .hero-left .grid-stats > .acct-tile { padding: 14px 16px; --acct-pad-top: 14px; }
  .hero-left .grid-stats > .acct-tile .value { font-size: clamp(22px, 6.5vw, 30px); }
}

/* Once the strip is measured (theme.css) the dark pill IS the settings
   tabs' sliding marker — same handover as .tabs above: full button box,
   capsule radius, ink fill; the active label keeps its own flip to
   --surface-1 on the button. */
.settings-tab-indicator {
  top: var(--marker-top, 0px); height: var(--marker-height, 100%);
  background: var(--ink); border-radius: 999px;
}
.settings-tabs.measured button.active { background: none; }

/* The Favourites card's list tabs are the same idea a third time: capsule
   buttons, and once the strip is measured the dark pill IS the marker. The
   controls beside them (+ ✎ ✕, and the row's ⊞) are round icon buttons
   rather than pills — they act on the strip, they are not options in it —
   and the name fields take this skin's input capsule. */
.fav-tab { border-radius: 999px; border-bottom: none; font-size: 12px; padding: 6px 14px; }
.fav-tab.active { background: var(--ink); color: var(--surface-1); border-bottom-color: transparent; }
.fav-tab-indicator {
  top: var(--marker-top, 0px); height: var(--marker-height, 100%);
  background: var(--ink); border-radius: 999px;
}
.fav-tabs.measured .fav-tab.active { background: none; }
/* The strip's controls are one family since 04.09.2026 — +, ✎, ✕ and the
   name field's ✓ share .fav-tab-btn — so the round icon-button ground is
   named once for the family. The two older classes stay in the list: they
   are still on the buttons (for what each MEANS), and a skin that only knew
   the family would leave any control that ever drops it undressed.
   ＋ Add asset above the table is a .btn-ghost and needs nothing here; its
   field and its dropdown take the input capsule and the popover corner this
   skin already gives .whatif-hits and the name fields. */
.fav-tab-btn, .fav-tab-add, .fav-tab-edit, .rowtag { border-radius: 999px; }
.egress-ip, .egress-copy { border-radius: 999px; padding-inline: 11px; }
.fav-tab-input, .listpick-new input, .fav-add-input, .acct-name-inline {
  border-radius: 999px; padding-inline: 11px;
}
/* The drag-and-drop rings need no restating — an outline follows the
   element's own border-radius, so the tab and + rings are already capsules
   here. The table-body drop zone alone takes the tile radius, so its ring
   sits on the same curve as the tiles this skin frames tables with. */
.fav-drop-zone { border-radius: var(--pb-r-tile); }
.listpick { border-radius: 18px; }
.listpick-row { border-radius: 999px; padding-inline: 8px; }

/* Social identity: the avatar is clipped to a circle wherever it appears
   (Pebble rounds everything; a square avatar chip would be the one hard corner
   on the bar). 15px is the icon-sized default the account sheet's rows use.
   On the topbar badge it is a FACE and has to be legible, so the picture IS
   the button: full-bleed, clipped by the capsule's 999px radius into a plain
   round avatar, with no ring of dead surface between photo and edge.
   The square footprint and the missing padding are theme.css's now (every
   icon-only .settings-btn is --finder-h wide as well as tall) — which is also
   what makes ⚙ Settings and the notes pill circles under this skin rather
   than capsules: the list at the top of this file already rounds them at
   999px, and 999px on a square box IS a circle. All this rule still owes the
   picture is `inherit`, so the photo takes the button's round corner instead
   of the base sheet's square one. */
.acct-avatar { display: block; width: 15px; height: 15px; border-radius: 50%; object-fit: cover; }
.acct-badge .acct-avatar { width: 100%; height: 100%; border-radius: inherit; }
/* ------------------------------------------------------------- social ---- */
/* The unread badge is punctuation — exactly what the acid accent is for
   (like the notes FAB's count and the send button). */
.tab-badge { background: var(--pb-accent); color: var(--pb-accent-ink); }
/* Composer + reactions keep the skin's soft-rounded language: the textarea
   is a rounded tile, the reaction pills sit on the soft wash and the active
   one takes the seg-marker treatment (ink pill, inverted label). */
.social-composer .composer-body { border-radius: var(--pb-r-tile, 14px); background: var(--pb-soft); border-color: transparent; }
.reaction-chip { background: var(--pb-soft); border-color: transparent; }
.reaction-chip:hover { border-color: var(--baseline); }
/* The collapsed rail's vertical Friends/Leaderboards buttons speak the same
   soft-capsule language as the reaction pills — wash fill, no hairline until
   hover puts the --baseline edge on. */
.rail-btn { background: var(--pb-soft); border-color: transparent; }
.rail-btn:hover { border-color: var(--baseline); }
/* The Social tab's draggable divider, in the same soft-capsule language: the
   base sheet paints its hover wash out of --series-1, which in this skin is a
   near-black grey and reads as a bar rather than as a highlight. --pb-soft is
   the wash every other hoverable surface here takes, and --baseline is the
   edge they take with it — so the grabbed line is the same ink as the border
   the rail buttons show on hover. The 1px resting hairline needs no override:
   it is --border, which this skin already redefines. */
.social-split:hover, body.social-splitting .social-split {
  background: var(--pb-soft);
}
.social-split:hover > i, .social-split:focus-visible > i,
body.social-splitting .social-split > i { background: var(--baseline); }
.reaction-chip.on {
  background: var(--pb-seg-marker); border-color: transparent;
  box-shadow: var(--pb-shadow-sm);
}
.reaction-chip.on .reaction-count { color: var(--pb-seg-marker-ink); }
/* The ☺ that opens the palette is a reaction pill too, so it already has the
   soft wash and the capsule. Open, it takes the same --baseline edge the pills
   take on hover: this skin paints the pills' own borders transparent, so the
   base sheet's --ink-2 edge would be the only hairline in the row. The
   POPOVER's lift is the skin's, not the base's flat black shadow, and its edge
   goes with it — pebble's floating surfaces are held up by shadow. */
.reaction-add[aria-expanded='true'] { border-color: var(--baseline); }
.reaction-pop {
  background: var(--surface-1); border-color: transparent;
  box-shadow: var(--pb-shadow); padding: 6px;
}
.reaction-opt { border-radius: 999px; }
.reaction-opt:hover { background: var(--pb-soft); }
.reaction-opt.on { background: var(--pb-seg-marker); box-shadow: var(--pb-shadow-sm); }
/* Written replies under a post (theme.css .post-comments): the same soft
   language one level quieter, because a thread is subordinate to the post it
   hangs under. The inset rail is the skin's own hairline colour rather than a
   border token; the reply box is the composer's rounded tile at a smaller
   radius, since it is a two-row box and not a card; and the reply avatars keep
   the round shape every avatar has in this skin. */
.pc-open { border-left-color: var(--baseline); }
.pc-input {
  background: var(--pb-soft); border-color: transparent;
  border-radius: var(--pb-r-tile, 14px);
}
.pc-row .post-avatar, .pc-row .avatar-preview { border-radius: 50%; }
.pc-toggle { border-radius: 999px; }
/* @mentions (theme.css "@mentions"): the picker's rows are capsules on the soft
   wash like every option in this skin (.reaction-opt), the selected one the
   seg-marker pill; the "mentions you" mark is punctuation and takes the acid
   accent exactly as the unread badge and the "N new posts" pill do, and a
   tagged card's leading-edge accent is the same colour. The chip inside a
   sentence keeps the base sheet's treatment — a byline you can click, not a
   capsule. */
.mention-list button { border-radius: 999px; }
.mention-list button:hover { background: var(--pb-soft); }
.mention-list [aria-selected="true"] button { background: var(--pb-seg-marker); color: var(--pb-seg-marker-ink); box-shadow: var(--pb-shadow-sm); }
.mention-avatar { border-color: transparent; }
.mention-flag { background: var(--pb-accent); color: var(--pb-accent-ink); }
.feed-item.mentions-me > .card, .feed-item.mentions-me > .event-row,
.pc-row.mentions-me .pc-said { box-shadow: inset 3px 0 0 var(--pb-accent); }
/* The live feed's "N new posts" pill. Same reasoning as the unread badge it
   answers: a count of things waiting for you is punctuation, so it wears the
   acid accent rather than the base's outlined-link treatment, and it takes the
   skin's lift so it reads as floating above the column it is stuck to. */
.feed-new {
  background: var(--pb-accent); color: var(--pb-accent-ink);
  border-color: transparent; box-shadow: var(--pb-shadow-sm);
}
.feed-new:hover { background: var(--pb-accent); filter: brightness(0.96); }
/* The notification bell (theme.css "Notifications"): the button speaks the
   rail buttons' soft-capsule language (wash fill, no hairline until hover);
   its count is the unread badge and takes the acid accent with it, as does
   the unread dot on a row and the ring the jump lands with. The popover is
   the reaction palette's float (shadow-held, no edge, this skin's 18px
   corner); the rows are the mention picker's capsule-on-wash. */
.notif-bell { border-radius: 999px; background: var(--pb-soft); border-color: transparent; }
.notif-bell:hover, .notif-bell[aria-expanded="true"] { border-color: var(--baseline); color: var(--ink); }
.notif-pop { border-color: transparent; box-shadow: var(--pb-shadow); border-radius: var(--pb-r-card); }
.notif-row { border-radius: var(--pb-r-tile, 14px); }
.notif-row:hover, .notif-row:focus-visible { background: var(--pb-soft); }
/* NO tint on an unread row (26.08.2026). It used to wear a 12% accent wash —
   Josef, of the Insights list: "the alerts here shouldn't have yellow
   background, just the yellow (lime) dot." The wash was doing the dot's job a
   second time and much louder: a panel of unread rows was a block of lime with
   sentences on it, and the hover wash had nothing left to say on top of it.
   The dot and the base sheet's 650 weight on .notif-line carry unread on their
   own; the accent stays a punctuation mark, which is what this skin uses it
   for everywhere else. Both notification lists lose it — the Insights bell's
   and the Social feed's — because they are one component family, deliberately
   (theme.css .notif-pop / .notif-row / .notif-dot), and 26.08.2026 had just
   finished telling them apart by their BUTTON's glyph rather than by anything
   inside the panel. */
.notif-dot { background: var(--pb-accent); }
/* The Insights bell's inert rows keep the shape and lose the wash — nothing
   happens when they are clicked, so nothing should light up under the
   pointer. (theme.css .notif-row--static.) */
.notif-row--static:hover { background: none; }
.feed-item.feed-flash > .card, .feed-item.feed-flash > .event-row { animation-name: feed-flash-pb; }
@keyframes feed-flash-pb {
  0%, 45% { box-shadow: 0 0 0 2px var(--pb-accent); }
  100% { box-shadow: 0 0 0 0 transparent; }
}
/* The sheet's top-only corner. 600px since 04.09.2026 — the base sheet
   posture moved off the Social tab's 860px column fold onto the app's own
   phone cutoff (theme.css .notif-pop), and a radius override at the old
   width would square off a desktop popover's bottom corners between 601
   and 860. */
@media (max-width: 600px) {
  .notif-pop { border-radius: var(--pb-r-card) var(--pb-r-card) 0 0; }
}
.presence-dot { box-shadow: 0 0 0 2px var(--surface-1); }
/* The friend's headline return (IRR p.a.) beside their name. Pebble's friend
   rows are a quiet list — avatar, handle, a grey stamp — so a bare coloured
   number floats loose in it. It gets the skin's soft wash and capsule shape,
   the same treatment the reaction pills and the "+2" badge chip take, which
   parks it as a compact tile against the handle. The .pos/.neg ink from the
   base carries the sign; only the container is restated here. */
.friend-pa {
  background: var(--pb-soft); border-radius: 999px;
  padding: 1px 8px; line-height: 1.55;
}
/* The "demo" mark beside a handle — this person's shared figures were
   computed over the built-in demo portfolio, so their return is not a track
   record. The base sheet builds it from the neutral hue by .conn-pill's
   recipe; here it only needs pebble's own two habits. The skin paints
   surfaces rather than outlining them, so the hairline goes and the fill
   carries the shape (the same ink mix the rank pill and the badge "+2" chip
   wear on this skin) — and the label is pulled further toward --ink, because
   pebble's cards are a frosted cream panel much darker than the base card the
   generic mix was fitted against, and a 55% muted label loses its contrast on
   one. Measured from the painted pixels, not from the CSS. */
.demo-chip {
  background: color-mix(in oklab, var(--ink) 8%, transparent);
  border-color: transparent;
  color: color-mix(in oklab, var(--muted) 35%, var(--ink) 65%);
}
/* Pictures are framed the same way wherever this skin puts one: the
   composer's thumbnails and a posted picture alike. (For an hour on 12.08 a
   posted picture ran the full width of its card and this rule named only the
   composer; Josef put the card's margins back — "the posted images should
   have the same card gaps like the other stuff" — so a post's picture is a
   framed picture again, and takes the frame.) */
.post-img, .composer-img img { border-radius: var(--pb-r-tile, 14px); }
/* The lightbox a posted picture opens into (theme.css .lightbox-scrim): its
   ✕ and arrows go round, as the drawer's pinned ✕ does in this skin, and the
   picture keeps the tile radius it had in the card. */
.lightbox-close, .lightbox-nav { border-radius: 50%; }
.lightbox-img { border-radius: var(--pb-r-tile, 14px); }
/* A GIF held still until it is clicked (theme.css .gif-wrap). The still frame
   and the playing picture both wear .post-img, so the tile radius above
   already applies to them — what this skin has to say is about the two marks
   ON the picture: the ⤢ goes round like the lightbox's own ✕ two lines up
   (it is the same kind of corner control on the same kind of dark ground),
   and the "▶︎ Play GIF" capsule takes the pill radius every capsule in this
   skin takes. Their dark translucent ground is deliberately NOT re-tinted:
   it sits on somebody else's picture, not on a card, so the skin's surfaces
   have no say in it — the same reason .lightbox-close keeps its own. */
.gif-max { border-radius: 50%; }
.gif-badge { border-radius: 999px; }
.fh-bar, .fh-bar i { border-radius: 999px; }
/* Badges. The trophy-case tiles are the skin's soft tiles — the pebble
   language throughout is a wash with no hairline, so the base's 1px border
   goes and --pb-soft carries the shape. A LOCKED tile has to stay legible as
   an outline (it is the "not yet" state, and a washed-out wash is just a
   hole), so it keeps a dashed baseline rule instead. The "+2" overflow chip
   joins the capsule list above by shape rather than by class, since it is a
   one-off. */
.badge-tile { background: var(--pb-soft); border-color: transparent; border-radius: var(--pb-r-tile, 14px); }
.badge-tile.locked { background: none; border-color: var(--baseline); }
.badge-more {
  border-radius: 999px; background: var(--pb-soft); padding: 1px 6px;
  line-height: 1.5;
}
/* The snapshot's read-only pills (months, risk, brokers). theme.css
   gives them their floor — see the note there; they are data, not controls,
   and bare `.chip` paints nothing. Here they join the wash-not-hairline
   language the trophy tiles and the composer already speak. Restated at the
   base sheet's (0,2,0) so it lands: the capsule catch-all at the top of this
   file is (0,1,0) and would lose to it whatever the sheet order. */
.friend-chips .chip, .friend-months .chip {
  background: var(--pb-soft); border-color: transparent;
}
/* …except the buy-plan pills, which ARE controls now — each one opens that
   ticker's detail drawer. They keep the soft wash (they are still a row of
   figures) and take the hover edge on the same terms .reaction-chip does in
   this skin: pebble paints pill borders transparent, so the base sheet's
   --ink-2 hairline would be the only hard line in the sheet. --baseline is
   the edge this skin shows when a pill is being pointed at. */
.friend-chips button.chip:hover, .friend-chips button.chip:focus-visible {
  border-color: var(--baseline);
}
/* A pressable holdings row (theme.css .friend-holding-open). The base sheet
   bleeds its hover tint out with a spread shadow so no column moves; pebble
   only swaps the tint for its own wash and rounds the corners to the pill
   radius the rest of the sheet's soft shapes use. */
.friend-holding-open:hover, .friend-holding-open:focus-visible {
  background: var(--pb-soft); box-shadow: 0 0 0 5px var(--pb-soft);
}
.friend-holding-open { border-radius: 7px; }
/* The friend dialog's avatar preview takes the tile radius its siblings use
   (.post-img, .composer-img img above) — it is a picture in a frame, and
   pebble frames pictures the same way everywhere. */
.avatar-big { border-radius: var(--pb-r-tile, 14px); }
/* The exits at the foot of the friend sheet. Pebble's language has no
   hairline rules between sections — the wash carries the separation — so the
   base's border-top goes and the row simply sits further down. */
.friend-leave { border-top: none; padding-top: 0; margin-top: 18px; }
/* The friend's headline return, when there ISN'T one — the greyed N/A pill
   (theme.css .friend-pa.unshared). It used to be drawn hollow, on the
   argument that this skin says "not there" with an outline (the locked
   trophy tiles do). In the friends list that reading did not hold: the pill
   sits in a column of filled capsules, and the one outlined row read as a
   different KIND of control rather than as the same figure withheld. So it
   keeps .friend-pa's wash and its slot untouched, and only the ink is
   different — muted instead of the .pos/.neg green or red. Grey is the whole
   message; the shape says nothing. */
/* ── Denser Social cards ────────────────────────────────────────────────────
   The base sheet halves .card's PADDING for the Social tab and the friend
   dialog (see the note there) off two tokens. This skin paints .card with its
   own, roomier padding — 20px 24px against the base sheet's 18px 20px — so the
   half has to be said in its numbers, or the tab would wear pebble's card with
   the base sheet's channel.
   Only the tokens are restated. The rule that spends them, and the title's
   step back out to the app's text margin, are the base sheet's and are
   skin-blind.
   Nothing about the CORNER is said here any more (it used to be: --pb-r-social
   and --pb-r-social-tile halved it, in this skin's vocabulary). Josef, 12.08:
   "the cards corner radius in the Social tab should be the same like in the
   other tabs of this app" — so a Social card takes --pb-r-card like every
   other card in the app, and its tiles --pb-r-tile. */
.social-tab, .friend-sheet, .card.social-cta {
  --social-pad-y: 10px;  /* half of this skin's 20px … */
  --social-pad-x: 12px;  /* … and of its 24px */
}
/* …and the friend dialog's header portrait reads THIS skin's corner. The base
   sheet tucks that picture into the sheet's own top-left arc by arithmetic on
   --friend-corner (see the note there), and can only default that token to the
   14px it paints the sheet at itself; pebble paints it at --pb-r-card, so the
   picture nests a good deal deeper here — and follows the phone step at the
   foot of this file for free, because the token is the live one, not a copy.
   The sheet's OWN outer corner, which is what the picture is tucked into —
   never a radius fitted to what the sheet CONTAINS. (It survived the Social
   corner's half-life above unchanged for that reason, and is unchanged again
   now that the half is gone: --pb-r-card both times.) */
.friend-sheet { --friend-corner: var(--pb-r-card); }

/* Crash fallback (theme.css `.crash-panel` / `.crash-stack`). The panel is a
   plain .card, so this skin's shadowed cream sheet, its 30px radius and its
   .card h2 / .sub treatment already dress it, and .oa-btn / .chip are in the
   capsule list at the top of this file. Only the code block needs saying:
   pebble's language is a soft wash with no hairline, exactly like the trophy
   tiles and the composer, so the base sheet's 1px border goes and --pb-soft
   carries the shape. Radius is the TILE radius — this block sits inside a
   card, and the card's 30px on a full-width panel reads as a bubble. */
.crash-stack {
  background: var(--pb-soft); border-color: transparent;
  border-radius: var(--pb-r-tile, 14px);
}

/* ------------------------------------------- the connect picker's marks -- */
/* Settings → Data, ConnectPicker: each platform button carries up to two
   marks saying how it can be brought in. The base sheet builds their labels
   by pulling each hue 45% toward --ink, which adapts to any palette but lands
   short on this one — pebble's greens and golds are already soft, and its
   panels are FROSTED cream (roughly #d4d0c9 composited), a good deal darker
   than the card the hues were fitted to. The same trap the --ink-2 note at
   the top of this file describes, and the same answer: inks fitted to the
   surface that actually has to hold them. These clear 4.9 / 5.7 / 4.9 on the
   Settings panel, so a 9.5px label on them is AA wherever the sheet is drawn.
   The washes stay as the base mixes them — transparent tints of the pure hue,
   which is what keeps the three marks telling themselves apart at a glance.

   Light only: the skin's dark palette lifts the very same hues (--up #7ccf95,
   --series-5 #a49dc4, --series-3 #d3b05a) and the base formula already lands
   them well clear of a #302e2b page, so the dark blocks below hand the marks
   back to it rather than fitting a second set of constants nobody would
   remember to keep in step.

   (A stray comment TERMINATOR after the first paragraph once closed this
   comment four lines early, which made the whole `:root` block below an
   invalid rule — dropped wholesale by the parser, --pb-pill-* left undefined,
   and every mark in this skin's light mode falling back to the surrounding
   ink. The marks have to be right here of all places: the connected-accounts
   list wears the same chips as the picker, and colourless is how they both
   looked.

   The note that recorded that fix then reintroduced it, on 20.08.2026, by
   quoting the terminator in backticks: CSS comments have no escape and no
   quoting, so an asterisk-slash inside one ends it wherever it appears. Both
   skins had shipped that way and light mode had lost the three pills again —
   found while screenshotting something else, confirmed in Chromium (--ink
   resolved, --pb-pill-api empty). Hence the words rather than the characters,
   and skinComments.test.ts, which fails on any comment in skins/ that ends
   anywhere but where its author meant it to.) */
:root {
  --pb-pill-api: #1f5c39;
  --pb-pill-snaptrade: #4a4571;
  --pb-pill-csv: #6b5010;
}
:root[data-theme="dark"] {
  --pb-pill-api: color-mix(in oklab, var(--up) 55%, var(--ink) 45%);
  --pb-pill-snaptrade: color-mix(in oklab, var(--series-5) 55%, var(--ink) 45%);
  --pb-pill-csv: color-mix(in oklab, var(--series-3) 55%, var(--ink) 45%);
}
@media (prefers-color-scheme: dark) {
  :root[data-theme="system"] {
    --pb-pill-api: color-mix(in oklab, var(--up) 55%, var(--ink) 45%);
    --pb-pill-snaptrade: color-mix(in oklab, var(--series-5) 55%, var(--ink) 45%);
    --pb-pill-csv: color-mix(in oklab, var(--series-3) 55%, var(--ink) 45%);
  }
}
.conn-pill-api { color: var(--pb-pill-api); }
.conn-pill-snaptrade { color: var(--pb-pill-snaptrade); }
.conn-pill-csv { color: var(--pb-pill-csv); }
/* The choice buttons are .oa-btn, so the capsule list at the top of this file
   has already rounded them to 999px. That reads right on a one-line button
   and wrong on this one — name over marks is a two-line BLOCK, and pebble
   gives blocks the tile radius (.crash-stack, .dropzone, the regime tiles). */
.snap-broker-pick { border-radius: var(--pb-r-tile, 14px); padding: 7px 11px; }
/* Pebble's buttons invert on hover; the base flips the marks to white with
   them. Nothing to add there — only the disabled state needs saying, because
   a greyed-out entry (a connection a guest cannot start) should read as
   unavailable rather than as a differently coloured option. */
.snap-broker-pick:disabled .conn-pill { filter: grayscale(0.7); }
/* And the mark with them: a full-colour logo beside a greyed-out name reads
   as an offer that is still live. */
.snap-broker-pick:disabled .conn-logo { filter: grayscale(0.7); opacity: 0.775; }
/* The plate is a small block, and this skin rounds small blocks harder than
   the base sheet does — the same squircle the reaction chips and the assistant
   suggestions wear, scaled to 22px. */
.conn-logo { border-radius: 8px; }
/* The asset marks take the same squircle, scaled — this skin rounds small
   blocks harder than the base sheet does. */
.asset-logo { border-radius: calc(var(--alogo) / 2.6); }
/* The key fragment in a connected-accounts row, right beside those marks:
   which key this connection runs on, and the control that reveals it whole.
   The base sheet marks it as pressable with a hairline on hover — the one
   thing this skin never does. Pebble says "pressable" with a soft wash and a
   capsule (the reaction chips, the badge "+2", the friend's return pill all
   do), so the border goes and --pb-soft carries the shape. Resting state stays
   paint-free: it is metadata until the pointer is on it, and a row of
   permanently washed capsules would out-shout the platform name beside it.
   OPEN, it keeps the wash — that is what ties the panel hanging below the row
   to the one fragment it belongs to.
   NOT in the capsule catch-all at the top of this file, because that list is
   .oa-btn and friends — outlined controls — and this is neither. */
.conn-acct-key { border-radius: 999px; padding: 1px 9px; }
button.conn-acct-key:hover:not(:disabled),
button.conn-acct-key[aria-expanded='true'],
button.conn-acct-key:focus-visible {
  background: var(--pb-soft); border-color: transparent; color: var(--ink);
}
/* An account's editable name (the Files table's Account cell, a connected
   account's name) is the same kind of thing as the fragment above —
   metadata that is pressable — so it says so the same way: a capsule and
   the --pb-soft wash under the pointer, paint-free at rest. The margin keeps
   the text on the column's edge as the base sheet's does, for this skin's
   wider capsule padding. */
.acct-name-btn { border-radius: 999px; padding: 1px 9px; margin: -2px -10px; }
.conn-acct-account .acct-name-btn { margin: -2px 0 -2px -10px; }
.acct-name-btn:hover:not(:disabled), .acct-name-btn:focus-visible {
  background: var(--pb-soft); border-color: transparent; color: var(--ink);
}
/* Keyboard focus (Enter commits and hands focus back to the name) wears the
   acid ring every tab stop inside a table row wears here (.star, tr.click) —
   not the browser's blue. */
.acct-name-btn:focus-visible { outline: 2px solid var(--pb-accent); outline-offset: 1px; }
/* The Copy inside the reveal is an .oa-btn — already a capsule with this
   skin's padding, which was fitted to full-size buttons and is the tallest
   thing in a small popover. Trimmed to the panel's scale; the panel's own
   corner comes from the overlay family near the top of this file. */
.conn-acct-key-copy { padding: 3px 11px; font-size: 11px; }
/* --------------------------------------------------------- leaderboards --- */
/* The standing chips and the board rows are new surfaces, and pebble paints
   surfaces rather than outlining them: the base sheet's var(--wash) is right
   for the chip on a card, but the highlighted "you" row sits ON a card and
   needs to be a shade the card is not, hence the mix rather than the flat
   wash. Radii come from the skin's own tile scale so they belong to the same
   family as the badge tiles right above them in a friend's profile. */
.rank-pill {
  background: color-mix(in oklab, var(--ink) 8%, transparent);
  border-radius: 999px; font-weight: 600;
}
.lb-row { border-radius: var(--pb-r-tile, 14px); }
.lb-me { background: color-mix(in oklab, var(--ink) 6%, transparent); }

/* ------------------------------------------ avatar hover preview ---------- */
/* Every avatar in the app enlarges on hover now, not just the friend dialog's
   header — the account rows and every Social chip share one trigger and one
   panel (components/AvatarPreview.tsx). The one exception is the topbar
   account badge: a navigation control, not a face, so it keeps its plain
   title tooltip and never opens a picture over the page. Pebble already owns
   the two surfaces that reach: the panel is a .tip, rounded 18px with the
   other floating glass at the top of this file, and the picture inside it
   takes the tile radius (.avatar-big, above in the social block).

   What is left is the trigger. Pebble makes every avatar a circle, so a
   trigger sized inline in an account row must be a circle too — and the
   inert one (the friends-list chip, an <img> because its row is already a
   button) has to keep .post-avatar's round shape rather than fall into the
   tile family with the pictures. */
.acct-avatar.avatar-preview { border-radius: 50%; }
.post-avatar.avatar-preview, .post-avatar.avatar-peek { border-radius: 50%; }

/* ── the phone's bottom control panel (theme.css .mobile-bar, ≤600px) ──────
   The controls left the header on 17.08.2026 and now sit in a fixed panel at
   the bottom of the window: tab strip on the upper row, then search, notes,
   Feedback and the assistant. Two things there are this sheet's business.
   1. The page's own bottom padding. The ≤560 block above restates .app's
      padding wholesale, which would put the last card back under the panel —
      so it is restated here, after it, from the panel's measured height.
   2. The tabs' padding. 7px 8px is this skin's roomy desktop rhythm; six
      labels plus that air came to 362px against a 357px row and clipped
      "Social" at the edge. 4px of side padding brings the strip to ~319 and
      buys the vertical back as a thumb-sized target. */
@media (max-width: 600px) {
  .app {
    /* This skin's own ≤560 rule pads the column 12px, not theme.css's 14 — so
       the TOKEN has to say 12 as well, or everything derived from it is 2px
       out. The planted header's veil is the one that showed it: its strip
       ended 4px above the bar's own bottom edge. */
    --app-pad-t: 12px;
    --app-pad-b: calc(var(--mobile-bar-h, 96px) + 20px);
    padding-bottom: var(--app-pad-b);
  }
  /* 3px and a 1px gap, not 8px and 3: the strip shares its row with the
     assistant's key now, so the six labels have ~297px rather than the 357
     they had — measured, and 4px of padding overflowed it by 22. The type is
     untouched; what gives is the air around it. */
  .mobile-bar .tabs { gap: 1px; }
  /* 2px, not 3: the assistant key beside these labels went 56 -> 64 on
     03.09.2026 and its column is `auto`, so it took 8px out of this strip —
     which had 2.2px of slack. Six labels x two sides gives 12px back, so all
     six still stand unclipped (6.2px spare at 393px, measured). What sits
     between two labels is this padding twice, the base rule's 1px margins
     twice, and the strip's own 1px gap: 7px, was 9px. */
  .mobile-bar .tab { padding: 9px 2px; }
}

/* ⚙ Settings → Admin (theme.css .adm-*): the operator's Accounts table. Only
   the two boxes need this skin's language — the filter field is a rounded tile
   like every other input here, and the scroller keeps the tile radius so its
   corners do not cut square inside a rounded panel. */
.adm-find {
  background: var(--pb-soft); border-color: transparent;
  border-radius: 999px; padding: 6px 12px;
}
.adm-scroll { border-radius: var(--pb-r-tile, 14px); }
/* The Usage tiles below the accounts table nest inside the panel like the
   hero's stat tiles: the tile radius, a soft wash, no outline. */
.adm-tiles > .card.adm-tile {
  border-radius: var(--pb-r-tile, 14px); background: var(--pb-soft);
  border-color: transparent; box-shadow: none;
}

/* Fair value card: the models' bars ride the same soft rail and pill
   geometry as every other track in this skin (.weighttrack, .rec-bar,
   .drift-track above). The FILL keeps the base sheet's --series-1, which
   this skin redefines for both themes — the lime stays reserved for the
   primary action, and six lime bars would spend it on a data table. */
.fv-bar, .fv-bar-fill { border-radius: 999px; }
.fv-bar { background: var(--pb-soft); }
.fv-price-mark { background: var(--ink); opacity: 0.55; }
.fv-weighted { letter-spacing: -0.01em; }

/* Simple view (04.09.2026): the phone bar's switch is a .notes-fab, so it has
   the capsule already; the on-state takes the skin's soft wash under the
   accent glyph, as the settings gear's pressed state does. */
.simple-fab.on, .mobile-bar .simple-fab.on { background: var(--pb-soft); border-radius: 999px; }

/* Historical strategy uses the same flat controls and quiet dividers as DCA. */
.trade-backtest .backtest-controls select,
.trade-backtest .backtest-controls input { border-radius: 10px; }
.trade-backtest .backtest-details { border-color: var(--border); }
.trade-backtest .backtest-metrics strong { font-variant-numeric: tabular-nums; }
/* `fit-content`, which on a scroller is min(max-content, available): the strip
   is as wide as its four names and no wider, and it pans when the card cannot
   hold them. No flex-wrap here any more, and no 2×2 grid below 480px — both
   made a second row, which is exactly what Josef asked to be rid of on
   10.09.2026 ("it should fit on a single line on mobile"). The one row is the
   base sheet's business now: .simulation-strategies joins .tabs/.fav-tabs in
   theme.css's pan block and tightens its buttons to 7px there. */
.simulation-strategies.seg { width: fit-content; }

/* Keyboard focus on the non-button controls that became tab stops on
   04.09.2026 (polish audit rows 11 and UIT-13): the clickable table rows
   (Holdings, Dividends, Events, Explore) and the ★ / ⊞ marks inside them.
   The same acid ring the fields above wear — one token, one focus signal —
   drawn as an outline because a table row cannot carry a box-shadow, inset
   so it never widens the table. :focus-visible, so a mouse click on a row
   (which does focus it) draws nothing. */
tr.click:focus-visible { outline: 2px solid var(--pb-accent); outline-offset: -2px; }
.star:focus-visible, .rowtag:focus-visible {
  outline: 2px solid var(--pb-accent); outline-offset: 1px; border-radius: 8px;
}
/* …and the candidate tables' Asset cell, which became a control of its own on
   22.09.2026 (the ticker/name opens the asset, the rest of the row expands
   the why-breakdown). Same ring as the ★ above — it is the same kind of
   thing: a tab stop INSIDE a clickable row. */
.recs-table .rec-asset-link:focus-visible {
  outline: 2px solid var(--pb-accent); outline-offset: 1px; border-radius: 8px;
}

/* The ? shortcut sheet's key caps: this skin's soft fill and its rounder
   corner, no hairline — the same flat capsule the chips wear here. */
.shortcut-sheet kbd { background: var(--pb-soft); border-color: transparent; border-radius: 8px; }

/* Settings finder, docs chapter link and the swipe hint (04.09.2026): the
   finder field is a .holdings-filter and so already wears the skin's input
   rule above; the popover borrows .whatif-hits. Only the link's ink and the
   hint's tone need naming here. */
.docs-chapter { color: var(--muted); }
.docs-chapter:hover { color: var(--ink); }
.settings-swipe-hint { color: var(--muted); }

/* Trade plan hand-offs (04.09.2026): the per-row "Simulate" chip and the
   "Copy plan" / "Copy link" chips are the same hairline capsule as the
   trades-recs chips above — the plan card is a plain .card, so they name
   themselves here rather than falling through to the browser button. */
.plan-sim, .plan-copy { background: none; border: 1px solid var(--border); border-radius: 999px; }
.plan-sim:hover, .plan-copy:hover { background: var(--pb-soft); }
/* The plan's column labels (15.09.2026) are the candidate tables' header type,
   so they take this skin's version of it — the same rule as `table.data th`
   above: sentence case, lighter, tighter tracking. Without this the plan card
   would be the only uppercase header on the Trades tab in the default skin. */
.plan-head-row { font-size: 9.5px; font-weight: 500; letter-spacing: 0.015em; text-transform: none; color: var(--muted); }

/* ── Assistant discoverability (polish 04.09.2026) ────────────────────────── */
/* Hover Copy on replies and code blocks: a capsule like every other small
   control here, on the bubble's own wash — and a tip's fold arrow beside it
   is the same capsule (its narrower padding is theme.css's). */
.chat-copy, .chat-tip-toggle { border-radius: 999px; background: var(--surface-1); border-color: var(--border); padding: 3px 8px; }
/* Hovered: the bubble's --pb-soft tint pre-mixed onto the capsule's opaque
   surface. --pb-soft itself is translucent, and over a reply the words
   showed straight through the hovered chip (Josef, 25.09.2026). */
.chat-copy:hover, .chat-tip-toggle:hover {
  background: color-mix(in srgb, var(--ink) 8%, var(--surface-1)); color: var(--ink);
}
/* The live ask chip keeps the capsule; the tint says "yours". */
.chat-asks .ask-chip.ask-live { background: var(--pb-soft); border-color: var(--border); }
/* The composer's verb list shares .whatif-hits' popover surface (above);
   the highlighted row takes the same soft wash a hovered row does. */
.chat-verbs button.sel, .chat-verbs button:hover { background: var(--pb-soft); }

/* ── Polish batch 5 / D1 (04.09.2026) ───────────────────────────────────── */
/* The Super Investors roster filter is a .holdings-filter and so already
   wears the skin's input treatment (the rule above that names the finder
   field); only its width is set here so it fills the fold's row. */
.super-roster .super-filter { width: 100%; }
/* The star cell's grab hand, restated so a skin that later restyles the
   `.click` rows' cursor keeps the drag hint on the cell. */
.star-cell { cursor: grab; }

/* External agents reuse the Settings/Skills geometry in both Pewter themes.
   The agent dialog itself is a .ctx-modal and takes the sheet family's corner
   and glass above (--pb-r-card) — no override here, so it matches the Settings
   sheet it opens over. */
.agent-proposal { border-radius:var(--radius, 16px); }
.agent-pro { background:var(--surface); color:var(--muted); }

/* Markets mirrors the Favourites heading and sliding list strip. */
.markets-head { display: flex; align-items: center; gap: 16px; min-width: 0; margin-bottom: 8px; padding-right: 40px; }
.markets-head h2 { flex: 0 0 auto; margin: 0; padding-right: 0; }
.markets-head .market-tabs { flex: 0 1 auto; min-width: 0; max-width: 100%; }
.index-asof { overflow-wrap: anywhere; }
.index-asof a { color: inherit; }
@media (max-width: 600px) {
  .markets-head { flex-wrap: wrap; gap: 8px; }
  .markets-head .market-tabs { flex-basis: 100%; }
}
/* Group portfolio borrows FriendPortfolioView's flat card geometry. */
.group-portfolio { color:var(--ink); }
.group-portfolio .group-table tr:hover { background:color-mix(in srgb, var(--ink) 4%, transparent); }
.group-portfolio .group-bar-track { background:color-mix(in srgb, var(--ink) 9%, transparent); }
.group-launchers .btn-ghost { border:0; box-shadow:none; }

/* Card-local group actions borrow the compact flat Browse control. */
.social-card-heading .group-launcher { border:0; background:var(--pb-soft); box-shadow:none; border-radius:12px; }
.social-card-heading h2 { margin:0; }
.group-sheet .group-portfolio { padding:20px 24px; }

/* Connection guide borrows Settings controls and flat chat Copy buttons. */
.agent-setup .agent-setup-copy { border:0; box-shadow:none; background:var(--pb-soft); color:var(--ink); padding:6px 12px; }
.agent-setup-code .agent-json { background:var(--pb-soft); border-radius:var(--r-card); }

/* Match the existing soft proposal cards and flat settings actions. */
.agent-chat-approvals .agent-proposal { border:0; background:var(--pb-soft); border-radius:var(--r-card); }
.agent-chat-approvals .agent-buttons button, .agent-connection-permission button { box-shadow:none; border:0; }
.agent-chat-approvals .settings-row select { background:var(--panel); color:var(--text); border:0; box-shadow:none; border-radius:12px; }
.agent-approval-details > summary { color:var(--muted); border-radius:var(--r-pill); padding:.15rem .35rem; }
.agent-approval-details > summary:hover, .agent-approval-details > summary:focus-visible { background:var(--pb-soft); color:var(--text); }

.agent-result-notice { background:var(--surface-1); color:var(--ink); border-radius:var(--r-card); }
.agent-result-notice .btn-ghost { border:0; box-shadow:none; background:var(--pb-soft); border-radius:999px; }

/* External agents dialog: connection cards take the approval cards' soft wash.
   The compact subpanel uses the same card and flat action vocabulary. */
.agent-settings .agent-grant, .agent-connections .agent-grant { border:0; background:var(--pb-soft); border-radius:var(--r-card); }
/* Two class names, not one: theme.css's `.settings-row > span` (0,1,1) already
   colours this element, so a bare `.agent-connection-when` (0,1,0) never won. */
.agent-connections .agent-connection-when { color:var(--muted); }
.agent-scopes .tag { background:var(--surface); color:var(--muted); }
.agent-grant-tools { background:var(--surface); color:var(--muted); }
.agent-grant-tools.stale { color:var(--status-warning); }

/* MCP chat bubbles mirror Assistant messages and ActivityEntry disclosures. */
.chat-msg.chat-agent-activity { padding:0; }
.chat-agent-activity .agent-activity-entry { margin:0; border:0; background:transparent; }

/* Grouped assistant/MCP actions keep one bubble, with compact rows inside. */
.chat-msg.chat-action-group { padding:0; }
.chat-action-group .chat-agent-activity .agent-activity-entry { margin:0; border:0; background:transparent; }

/* The long-run collapse button (15.09.2026) is a floating control on the
   skin's own surface: flat, borderless, the soft wash Pewter gives its round
   buttons (.settings-btn, .notes-fab), with the shadow that lifts it off the
   rows it floats over. */
.chat-actions-collapse {
  border: 0; background: var(--pb-soft); color: var(--pb-accent-ink);
  box-shadow: 0 6px 18px rgba(0, 0, 0, 0.18);
}
.chat-actions-collapse:hover { border-color: transparent; filter: brightness(0.96); color: var(--pb-accent-ink); }

/* The External agents quick view groups its opener and four compact rows. */
.external-agents-panel { background:var(--surface-1); border:0; border-radius:var(--r-card); }
.agent-connections .agent-grant { border-radius:12px; }
.agent-connection .agent-connection-revoke { border:0; box-shadow:none; background:var(--surface-1); }

/* Measurement annotations reuse the default skin's chart/text surfaces. */
.chart-ruler g rect { fill: var(--surface-1); rx: 6px; }
.chart-head-right > .info { color: var(--muted); }
/* Same squircle chips as rating drivers, with a muted decision line. */
.rec-chip.rec-decision { border-radius: 7px; white-space: normal; }
.rec-decision.rec-excluded, .rec-inputs, .plan-decision { color: var(--muted); }
.planner-settings .settings-row > .planner-unit { width: auto; }
/* Trade plan's inner rows: this skin used to widen the planner-rule and
   "Buy candidates from" labels to 170px on its own, which put them 80px right
   of the plan's own rows in the panel above — half of the misalignment Josef
   pointed at on 15.09.2026. The whole section now reads one label column
   (--plan-label-w, theme.css), measured in THIS skin's metrics: 140px holds
   "Maximum per company" (137px) on one line here, so there is nothing left
   for the skin to correct. */
@media (max-width: 700px) {
  .settings-panel .trade-source-row > span:first-child { width: auto; }
}

/* Compact drawer chart headings retain the skin's muted caption styling. */
.chart-head > .chart-heading-inline { align-items: baseline; gap: 2px 12px; }
.chart-heading-inline > .sub { margin: 0; }
/* Compact last-used stamps follow the muted Settings caption palette. */
.agent-connection-stamp > span { color:var(--muted); }
/* The dialog card's key prefix wears the skin's soft chip surface, like the
   scope .tag pills beside it, rather than the base sheet's --wash. */
.agent-grant-key { background:var(--pb-soft); color:var(--muted); }
/* Keep the floating collapse chip legible over candidate rows. */
.recs-toggle > .chip { background:var(--surface-1); }

/* --------------------------------------------------- date picker (from) -- */
/* The chart card's in-app date field and calendar (components/DatePick.tsx,
   22.09.2026). It replaced an `<input type="date">` whose popup was the
   browser's own — blue highlight, blue links, system font — so this skin now
   has a grid to dress. Everything here is this skin's existing answer for the
   element the base sheet already mirrors: the closed box is a field, so it is
   a capsule on --pb-soft with no hairline (the .settings-row input family
   above); the float takes the 18px corner every popover here wears
   (.mpick-pop, .combo-list); a day cell is a .filter-row .chip, so hover is
   --pb-soft and the selected day is this skin's ink capsule. */
.dpick-box {
  border-radius: 999px; border-color: transparent;
  background: var(--pb-soft); padding-left: 12px; padding-right: 4px;
}
/* The ring belongs to the BOX, not to the borderless text node inside it —
   the same exception .pf-finder-input takes above, and for the same reason:
   the box is what reads as the field. */
.dpick-input:focus-visible { box-shadow: none; }
.dpick-box:focus-within { box-shadow: 0 0 0 2px var(--pb-accent); border-color: transparent; }
.dpick-pop { border-radius: 18px; }
.dpick-nav, .dpick-cal, .dpick-act, .dpick-title { border-radius: 999px; }
.tt-ticks .tt-today { border-radius: 999px; }
.tt-ticks .tt-today:hover { background: var(--pb-soft); }
.dpick-nav:hover:not(:disabled), .dpick-act:hover, .dpick-title:hover { background: var(--pb-soft); }
/* A near-square cell under a 999px radius IS the circle every calendar draws
   its days in — the capsule rule of this skin landing where it always does. */
.dpick-day { border-radius: 999px; }
.dpick-day:hover:not(:disabled) { background: var(--pb-soft); }
.dpick-day.active { background: var(--ink); color: var(--surface-1); font-weight: 500; }
.dpick-day.active.dpick-today::after { background: var(--surface-1); }

/* Investing category editor mirrors the account-name inline editor. */
.holding-category-cell { display:inline-flex; flex-direction:column; align-items:flex-start; gap:4px; }
.holding-category-cell form { display:flex; align-items:center; gap:6px; }
.holding-category-cell input { width:170px; padding:5px 8px; border-radius:10px; color:var(--ink); background:var(--surface); border:1px solid var(--baseline); }
.holding-category-edit { border:0; background:transparent; color:var(--ink-2); font:inherit; padding:5px 8px; border-radius:10px; text-align:left; cursor:pointer; }
.holding-category-edit:hover { background:var(--hover); }
.asset-pie-category-label { font-family:inherit; }

/* Same flat checkbox as the chart-footer controls. */
.pie-sector-toggle { display:inline-flex; align-items:center; gap:6px; white-space:nowrap; font-size:12px; }
/* Category is a secondary pill below each hand-added asset's main fields. */
.oa-grid > .oa-category, .ma-grid > .oa-category { font-size: 12px; }
