@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');

/* ============================================================================
   PEBBLE SKIN  ·  option 3a
   ----------------------------------------------------------------------------
   Warm grey body, soft-rounded panels floating on diffuse shadows, capsules
   instead of rectangles, and a bright acid accent used only as punctuation —
   a badge, a dial's inner ring, the send button.

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

:root {
  --page: #c3bfb6;
  --surface-1: #f0ede7;
  --ink: #2b2924;
  /* THE TWO SECONDARY INKS WERE FITTED TO THE CARD AND READ ON THE PANELS.
     They were #6d695f and #96928a, which clear 4.7 and 2.7 on this skin's
     cream card (#f0ede7) — the surface anyone checks. But the Settings sheet
     and the assistant drawer are FROSTED: translucent cream over a page that
     is #c3bfb6, compositing to about #d4d0c9, a good deal darker than the
     card. The same two inks land at 3.6 and 2.0 there. Two of the app's
     paragraph styles live on them (.sub and the report cards' description),
     so the sheet's body copy was running at half the contrast body copy needs
     — reported as "not too contrasty", on the Settings dialog and on the
     assistant's report cards, in that order.
     Fitted to the DARKER of the two surfaces now, which is the one that has
     to hold: --ink-2 clears 4.69 on the Settings panel, 5.11 on the drawer
     and 6.17 on the card, so every paragraph on it is AA wherever it is
     drawn. --muted keeps its job — de-emphasis, not body copy: the ⓘ glyphs,
     placeholders and unit suffixes — and merely comes far enough down to be
     legible: 3.04 on the Settings panel, which is the 3:1 a non-text mark
     (the ⓘ glyphs are controls) has to clear, and 3.99 on the card — while
     staying a clear step lighter than the ink above it. What was on it and
     should not have been has moved to --ink-2 in theme.css instead. */
  --ink-2: #5a5750;
  --muted: #787469;
  --grid: rgba(43, 41, 36, 0.10);
  --baseline: rgba(43, 41, 36, 0.24);
  --border: rgba(43, 41, 36, 0.10);
  --series-1: #46433c;
  --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: #8d867a;
  --status-good: #2f7d4f;
  --status-warning: #b79338;
  --status-serious: #c07a4a;
  --status-critical: #bf5340;
  --wash: rgba(43, 41, 36, 0.055);
  --dock-bg: rgba(240, 237, 231, 0.56);
  --dock-border: rgba(43, 41, 36, 0.09);
  --panel-bg: rgba(240, 237, 231, 0.56);
  --panel-border: rgba(43, 41, 36, 0.09);
  --panel-shadow-side: -18px 0 50px rgba(43, 41, 36, 0.16);
  --panel-shadow-pop: 0 26px 60px rgba(43, 41, 36, 0.2);
  --scrim-bg: rgba(43, 41, 36, 0.13);

  --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: #c9a233;
  --pb-chart-gold-dark: #e0bd5c;
  --pb-chart-olive: #576b3f;
  --pb-chart-olive-dark: #a9c191;
  --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: #2b2924;
  /* 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, #2b2924 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);
  --pb-soft: rgba(43, 41, 36, 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 38px rgba(43, 41, 36, 0.13);
  --pb-shadow-sm: 0 6px 18px rgba(43, 41, 36, 0.12);
  /* 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. */
  /* About's label when it IS the selected pill. Light mode: the pill is dark
     ink, so the accent still reads on it. Dark mode overrides this below —
     there the pill is near-white and lime on it is illegible. */
  --pb-about-active: var(--pb-accent);
  /* …and the surface it sits on: the same wash the theme and currency pills
     wear, so it reads as a control rather than floating text. Note this is a
     pale surface, so the lime label sits at ~1.25:1 on it — chosen for the
     shape, not the contrast. Its edge is --border, the token behind the
     sheet's own head/tab rules and separators, so the pill belongs to the
     dialog's ruling instead of introducing a new weight. Dark mode leaves the
     pill unfilled (the page is already dark) and takes the heavier --baseline
     edge, since there the edge is all the pill has. */
  --pb-about-bg: var(--pb-soft);
  --pb-about-edge: var(--border);
  /* 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 this token. Same hue (89°),
     lifted and saturated to C 13.2, which is what the ladder's own slots then
     resolve to: #c9a545 and #d4b872 on the cream card, #d4b45e and #ad9655 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. The base sheet's default is var(--series-2) — every skin's own
     second chart colour — but Pebble's --series-2 is a SAGE (#5b8266, 34° from
     the citron), which is exactly the collision the third hue exists to avoid.
     So this skin names a cool one: a slate blue, the single cold note in a
     warm palette, and the one direction that survives protanopia and
     deuteranopia (both leave the blue-yellow axis standing, and the citron and
     the gold are both ON that axis). Quiet enough for the house — it reads as
     a working blue, not a primary. */
  --cat-accent-3: var(--pb-chart-olive);
  --pb-spot-glow: 0 0 36px -2px color-mix(in srgb, var(--spot-ring) 90%, 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.10);
  --baseline: rgba(243, 240, 233, 0.26);
  --border: rgba(243, 240, 233, 0.12);
  --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.56);
  --dock-border: rgba(243, 240, 233, 0.11);
  --panel-bg: rgba(65, 63, 58, 0.56);
  --panel-border: rgba(243, 240, 233, 0.11);
  --panel-shadow-side: -18px 0 50px rgba(0, 0, 0, 0.34);
  --panel-shadow-pop: 0 26px 60px rgba(0, 0, 0, 0.42);
  --scrim-bg: rgba(0, 0, 0, 0.29);
  /* 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-about-active: var(--surface-1);
  --pb-about-bg: transparent;
  --pb-about-edge: var(--baseline);
  --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 38px rgba(0, 0, 0, 0.3);
  --pb-shadow-sm: 0 6px 18px rgba(0, 0, 0, 0.28);
}
@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.10); --baseline: rgba(243,240,233,0.26);
    --border: rgba(243,240,233,0.12); --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.56); --dock-border: rgba(243,240,233,0.11);
    --panel-bg: rgba(65,63,58,0.56); --panel-border: rgba(243,240,233,0.11);
    --panel-shadow-side: -18px 0 50px rgba(0,0,0,0.34);
    --panel-shadow-pop: 0 26px 60px rgba(0,0,0,0.42); --scrim-bg: rgba(0,0,0,0.29);
    --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-about-active: var(--surface-1);
    --pb-about-bg: transparent; --pb-about-edge: var(--baseline);
    --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 38px rgba(0,0,0,0.3);
    --pb-shadow-sm: 0 6px 18px rgba(0,0,0,0.28);
  }
}

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;
}
.stack, .two-col, .hero-top, .grid-stats { 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;
}
/* 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); }
/* …and the Insights card, which is the third card that frames smaller ones —
   its pills sit beside .hero-mid's tiles on the same row, and at 24px against
   that card's 12px the two channels were visibly different widths. */
.insights-card { 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: 700; letter-spacing: -0.02em; text-transform: none; }
.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.85);
  --lg-sym: #3c3c42;
  --lg-shadow-face: inset 0 0 0 1.2px rgba(25, 25, 30, 0.28);
  --lg-ingot: linear-gradient(180deg, #b0b1ba, #8e8f99);
}
@media (prefers-color-scheme: dark) {
  :root[data-theme="system"] .lg {
    --lg-ink: rgba(25, 25, 30, 0.85);
    --lg-sym: #3c3c42;
    --lg-shadow-face: inset 0 0 0 1.2px rgba(25, 25, 30, 0.28);
    --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); }
.stat .value, .hero-mid .stat .value, .risk-grid > .card .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;
}
/* 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;
  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: clamp(24px, 3.2vw, 31px); line-height: 0.98; letter-spacing: -0.045em;
}
.stat.hero .value { font-size: clamp(17px, 1.5vw, 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, .composer-attach, .friend-chips .chip, .friend-months .chip {
  border-radius: 999px;
}
.seg { background: var(--pb-soft); border-radius: 999px; padding: 4px; }
.seg button { padding: 6px 14px; 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; }
/* 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 strategy presets (Settings → Strategy) 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,
.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,
.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,
.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; }
/* 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 -- */
table.data th {
  font-size: 10.5px; font-weight: 500; letter-spacing: 0.02em; 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 8px; }
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);
}

/* ------------------------------------------------------------ insights -- */
.insight {
  background: var(--pb-soft); border: none;
  /* Concentric with the card, not a capsule: the strip's card is --pb-r-card
     (30px) with a --card-inset (12px) frame, so the pill nests at their
     difference — theme.css derives it once as --r-tile (18px here). The old
     999px pill-shape put a fatter arc inside a slimmer one and the corner
     channel visibly pinched. */
  border-radius: var(--r-tile);
  padding: 8px 12px; font-size: 11.5px;
}
.insight.sev-good, .insight.sev-bad, .insight.sev-warn, .insight.sev-info,
.insight.ai {
  border-left: none; padding-left: 14px;
}
/* This skin trades the stripe for a DOT — same four meanings, said in the
   round shape the rest of the skin is made of.
   The dot is the PILL's own ::before rather than the icon slot it used to
   borrow. Borrowing it worked only as long as every mark was an emoji, which
   font-size: 0 could mask; the assistant's pills carry an SVG (SparksIcon),
   and an SVG has its own width and height and simply painted over the 8px dot
   it was sitting in. Drawn separately, the two marks sit side by side: the dot
   says how loud, the sparks say who wrote it. */
.insight::before {
  content: ''; width: 7px; height: 7px; border-radius: 50%;
  background: var(--muted); flex: none;
}
.insight.sev-good::before { background: var(--up); }
.insight.sev-bad::before { background: var(--down); }
.insight.sev-warn::before { background: var(--pb-accent); }
.insight.sev-info::before { background: var(--ink-2); }
/* The rule pills' emoji is dropped entirely (the dot has already said it);
   the assistant's mark stays, and is now the one thing that identifies an AI
   pill — the dashed outline it also used to wear is gone. */
.insight .ic { display: none; }
/* An assistant pill therefore carries TWO marks, and they go in ONE column,
   sparks above and dot below, rather than side by side: these pills wrap to
   three lines in a card a third of the hero wide, and two marks in a row take
   that width off every one of them. Stacked, the pair is as wide as the widest
   mark. The dot rides the icon (::after) instead of the pill (::before) so it
   stays centred under the sparks whatever the pill's height. */
.insight.ai::before { display: none; }
.insight.ai .ic { display: inline-flex; position: relative; padding-bottom: 11px; }
.insight.ai .ic::after {
  content: ''; position: absolute; left: 50%; bottom: 0; margin-left: -3.5px;
  width: 7px; height: 7px; border-radius: 50%; background: var(--muted);
}
.insight.ai.sev-good .ic::after { background: var(--up); }
.insight.ai.sev-bad .ic::after { background: var(--down); }
.insight.ai.sev-warn .ic::after { background: var(--pb-accent); }
.insight.ai.sev-info .ic::after { background: var(--ink-2); }
/* Delivered alerts (Settings → Alerts): like the AI pills, the mark IS the
   identity — the bell says "this was delivered to you" the way the sparks
   say "the assistant wrote this" — so it survives the emoji cull above and
   replaces the severity dot (an alert is not an observation with a level). */
.insight.alert-pill::before { display: none; }
.insight.alert-pill .ic { display: inline-flex; }
/* The opened pill: theme.css marks it with a border tint, but pills here
   have no border — an inset accent ring says "this one is unfolded". */
.insight.alert-pill.open { box-shadow: inset 0 0 0 1.5px var(--pb-accent); }
/* The unfolded digest under the strip nests in the same soft wash and tile
   radius the pills use. */
.alert-detail { background: var(--pb-soft); border-radius: var(--r-tile); }

/* ----------------------------------------------------------- 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) 55%, transparent),
                0 0 14px 2px color-mix(in srgb, var(--pb-accent) 35%, transparent);
  }
  50% {
    box-shadow: 0 0 0 8px color-mix(in srgb, var(--pb-accent) 10%, transparent),
                0 0 36px 12px color-mix(in srgb, var(--pb-accent) 60%, 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 18px 4px color-mix(in srgb, var(--pb-accent) 45%, transparent);
  }
}
/* Step badges: the finished ✓ and the current number both ride the accent
   with dark ink on it — the "Start tutorial" 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;
}
.settings-sheet, .feedback-sheet, .account-sheet, .ctx-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; }
.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; }
/* About sits apart at the right end of the strip, so it takes the accent as
   its text colour — no fill, just ink. The .active pair is spelled out so it
   outranks the rule above whatever the order: selected, About keeps the dark
   ink pill and wears the lime on top of it. */
.settings-tabs button.tab-about { color: var(--pb-accent); }
/* Selected, About is the standard dark pill again — spelled out at (0,3,1) so
   the resting fill above cannot swallow the .active rule, which is exactly
   what it did until this line existed (measured: dark mode's active label went
   to 1.0:1 against a transparent background). */
.settings-tabs button.tab-about.active {
  background: var(--ink); border-color: transparent; color: var(--pb-about-active);
}
/* …and a ring to find it by: lime on the light sheet has almost no tonal
   contrast, so the label alone barely registers at the strip's right end.
   The outline is ink, not accent, for exactly that reason. Selected, the dark
   fill supplies the shape and the ring would double it. */
.settings-tabs button.tab-about {
  background: var(--pb-about-bg); border: 1px solid var(--pb-about-edge);
}
.settings-tabs button.tab-about.active { border-color: transparent; }
.drawer-head h1 { font-weight: 500; font-size: 24px; letter-spacing: -0.03em; }
/* Round, and the strip's shared height — this skin used to size the ✕ at 34
   while the search pill it sits beside stayed 26, and the mismatch is exactly
   what you see when the two are next to each other. --finder-h moves both. */
.drawer > .close { border-radius: 50%; }

/* ----------------------------------------------------------- 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. */
.app { --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; }
.chat-msg.assistant { background: var(--pb-soft); border-radius: 20px 20px 20px 6px; }
/* 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); }
.chat-suggest-btn { border-radius: var(--pb-r-tile); padding: 12px 26px 12px 15px; }
/* …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. */
.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; }
/* 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 ✨ unread mark 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); }
/* 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);
}
.news-title { font-weight: 500; font-size: 14px; }
.lg { opacity: 0.8; filter: grayscale(1) brightness(1.05); }

@media (max-width: 560px) {
  .app { --app-pad-b: 64px; padding: 12px 12px 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; }
  .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 (lime for About) on the button. Resting About keeps its
   outlined capsule — the marker only ever sits under the ACTIVE tab. */
.settings-tab-indicator {
  top: var(--marker-top, 0px); height: var(--marker-height, 100%);
  background: var(--ink); border-radius: 999px;
}
.settings-tabs.measured button.active,
.settings-tabs.measured button.tab-about.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; }
.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 { 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); }
.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); }
/* 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); }
.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); }
.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.

   (That stray `*/` after the first paragraph used to close the 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.) */
: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); }
/* 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);
}
/* 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%; }
