/* Mobile-first. No CDN, no webfont, no external asset of any kind.
   Spec section 9: a CDN chart library failed silently on mobile and blanked
   the entire page, so nothing here is loaded from a network we do not control.

   The colours are the owner's logo's own, sampled out of the file: the navy of
   its bars carries the top bar and the buttons, the teal it passes through
   marks the tab you are on, and its green is kept for the one thing the arrow
   means, which is money up.

   Light and dark are each their own set of choices, not an inversion of the
   other. The rule that governs both: nothing sits behind a number. Every
   surface that carries a figure is opaque and flat. */

:root {
  --ma20: #e8b100;
  --ma50: #2d9cff;
  --ma200: #e8559c;
  /* The sessions' own colours (14 October 2026): the rows' sun and moons,
     the live mark and the widget. On the dark wallet the blue and purple are
     a shade lighter, or they sink into it. */
  --session-pre: #f59e0b;
  --session-after: #2f80ed;
  --session-night: #7c5cff;
  --session-after-on-dark: #4a9bff;
  --session-night-on-dark: #9b85ff;
  --vs-line: #8b7cf6;
  /* Market mood's five bands in CNN's own colours (22 October 2026, CNN's
     gauge beside Investoo's: "I need colors matching"). */
  --mood-xfear: #ff5a1f;
  --mood-fear: #ff8c1a;
  --mood-neutral: #f7b131;
  --mood-greed: #a8b23a;
  --mood-xgreed: #5fae4a;
  /* The indices' lines on Market, Saham's colours (20 October 2026). */
  --idx-sp: #f2c94c;
  --idx-nq: #8b7cf6;
  --idx-rut: #4fb6c9;
  --idx-btc: #f7931a;
  color-scheme: light dark;

  /* Ground and surfaces, three steps, and all three flat. The reference is a
     research screen: nothing sits behind a number, and a card is told from the
     page by a real edge rather than by a shadow daylight washes out. */
  /* Investing.com's look (prototype, 12 October 2026): the light theme is
     inferred from its dark one, as no light screenshots exist. A white
     ground, very light grey tiles with no edge, near-black text. */
  --bg: #ffffff;
  --ground: #ffffff;
  --card: #f3f4f6;
  --raised: #e8eaee;
  --ink: #111318;
  --muted: #5d636c;
  --line: #e1e4e8;
  --hairline: rgba(13, 16, 22, 0.07);

  /* The page chrome: the bar at the top and the tabs at the bottom. The navy
     of the logo's own bars, read out of the image rather than matched by eye.
     It keeps its own tokens, because text on it needs different values from
     text on a white card and the page's --ink and --muted are unreadable
     there. */
  --chrome: #16181d;
  --chrome-ink: #ffffff;
  --chrome-muted: #a3a9b2;
  --chrome-line: rgba(255, 255, 255, 0.10);
  --chrome-raised: #2a2d33;

  /* Interaction, and nothing else: the primary button, the focus ring, a link.
     The same navy as the bar, so green is free to mean money up and nothing
     else.

     Three tokens because a fill, the text on that fill, and the same idea used
     as text on a page are three different contrast problems. */
  --accent: #16181d;
  --accent-ink: #ffffff;
  --accent-text: #1a5fd0;
  /* The teal the logo passes through on its way to the green. It marks the
     tab you are on and nothing else, so neither the navy nor the green has to
     do two jobs. */
  --marker: #186786;

  /* Money up, paired with --danger, which is money down. The logo's own green,
     darkened until it reads as text on white, and used for nothing else, so
     that green on this page means exactly one thing. */
  --gain: #2a8a3e;

  /* A state that is fine: inside the policy band, a live feed, a check that
     passed. The same green as a gain today, deliberately, and a separate name
     so that changing one cannot silently change the other. */
  --ok: #2a8a3e;

  /* Three levels of attention, and only the first is red. See .card.wrong,
     .card.warn and .card.note below. */
  /* Orange, the colour of Money on the move's waiting step (12 October 2026:
     "don't use brown use orange colour like the one you use when money is in
     move"). Text a shade deeper so a line stays readable on white; marks,
     bars and dots take the step's own orange. */
  --warn: #d46b08;
  --warn-fill: #f59e0b;
  --warn-bg: #fff4e5;
  --danger: #d63b30;
  --danger-bg: #fdecea;
  --note-bg: #eaf1fb;
  --note: #1f4d80;
  /* Behind the drawer and the pop-ups. */
  --scrim: rgba(13, 16, 22, 0.48);
  /* The floating tab bar: its pill, its edge, and the darker pill the tab
     you are on sits in. */
  --tabbar-bg: rgba(255, 255, 255, 0.94);
  --tabbar-line: rgba(13, 16, 22, 0.10);
  --tabbar-on: #eceef1;

  /* The six chart colours are NOT here. They are declared once, by
     app/services/charts.py, and written into every page as a style block.
     They used to be declared here as well, in different values, and the
     inline block overrode all six: the ring on the Dashboard was drawn from
     one list and the legend in the weekly email from the other. */

  --shadow: none;
  --radius: 12px;
  --radius-sm: 10px;

  --space: 1rem;
  --space-lg: 1.4rem;
}

@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    /* Investing.com's dark app, sampled from his screenshots: a near-black
       ground, tiles a step lighter with no edge, white text, cool grey. */
    --bg: #0d1016;
    --ground: #0d1016;
    --card: #191c21;
    --raised: #24282e;
    --ink: #f5f6f7;
    --muted: #9aa0a8;
    --line: #2c3037;
    --hairline: rgba(255, 255, 255, 0.07);

    /* The bar is the page's own ground, as Investing.com's header is. */
    --chrome: #0d1016;
    --chrome-ink: #ffffff;
    --chrome-muted: #9aa0a8;
    --chrome-line: rgba(255, 255, 255, 0.08);
    --chrome-raised: #24272d;

    /* A primary button is white with dark letters; a link stays blue. */
    --accent: #f5f6f7;
    --accent-ink: #0d1016;
    --accent-text: #5a9cf8;
    --marker: #6fc095;
    --gain: #6cc551;
    --ok: #6cc551;
    --warn: #f59e0b;
    --warn-fill: #f59e0b;
    --warn-bg: #2b2112;
    --danger: #ec5b4f;
    --danger-bg: #3a1f1d;
    --note-bg: #152030;
    --note: #8bbcf5;
    --scrim: rgba(0, 0, 0, 0.62);
    --tabbar-bg: rgba(44, 46, 52, 0.94);
    --tabbar-line: rgba(255, 255, 255, 0.10);
    --tabbar-on: #13161d;

    --shadow: none;
  }
}

:root[data-theme="dark"] {
  --bg: #0d1016; --ground: #0d1016; --card: #191c21; --raised: #24282e;
  --ink: #f5f6f7; --muted: #9aa0a8; --line: #2c3037;
  --hairline: rgba(255, 255, 255, 0.07);
  --chrome: #0d1016; --chrome-ink: #ffffff; --chrome-muted: #9aa0a8;
  --chrome-line: rgba(255, 255, 255, 0.08);
  --chrome-raised: #24272d;
  --accent: #f5f6f7; --accent-ink: #0d1016; --accent-text: #5a9cf8;
  --marker: #6fc095; --gain: #6cc551; --ok: #6cc551;
  --warn: #f59e0b; --warn-fill: #f59e0b; --warn-bg: #2b2112; --danger: #ec5b4f; --danger-bg: #3a1f1d;
  --note-bg: #152030; --note: #8bbcf5;
  --scrim: rgba(0, 0, 0, 0.62);
  --tabbar-bg: rgba(44, 46, 52, 0.94); --tabbar-line: rgba(255, 255, 255, 0.10); --tabbar-on: #13161d;
  --shadow: none;
}

* { box-sizing: border-box; }
body {
  /* A column, so a short page's ground fills the screen beneath it. */
  margin: 0; min-height: 100vh; display: flex; flex-direction: column;
  background: var(--ground); color: var(--ink);
  font: 15px/1.55 system-ui, -apple-system, "Segoe UI", Roboto,
        "Helvetica Neue", Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
}
/* A plain link in the one blue, rather than the browser's own two. */
a { color: var(--accent-text); }
/* One stacking context for the page furniture, so a dropdown opened inside a
   card cannot be drawn underneath the bar above it. */
.topbar, main, .demo-banner { position: relative; z-index: 1; }
[dir="rtl"] body { font-family: system-ui, "Segoe UI", Tahoma, sans-serif; }

/* One row on a phone now: the mark, the word, the theme and sign out. The
   eight section links below are hidden until there is room for them, because
   on a phone they live along the bottom instead, in _tabbar.html. */
.topbar {
  display: flex; flex-wrap: wrap; gap: .4rem 1rem; align-items: center;
  /* Room for the phone's clock, in the bar's own blue. Found by him on 2
     October 2026: on the home-screen app the iPhone frosts the top of the
     screen, and the frost sat on the riyal | $ pill and the refresh. The
     bar still scrolls away with the page ("No need to be pined"). */
  padding: calc(.5rem + env(safe-area-inset-top)) 1.25rem .45rem;
  background: var(--chrome);
  color: var(--chrome-ink);
  border-bottom: 1px solid var(--chrome-line);
}
/* The home-screen app: iOS 26 still frosts the top strip of the page under
   an opaque status bar, about 30 points (found by him on 8 October 2026,
   re-added: "it came back non solid bar"). The bar's own blue stands above
   the buttons there, so the frost lies on blue alone and every button sits
   clear of it; the page's root is that blue too, which is what iOS tints
   the status bar and the frost from. */
html { background: var(--chrome); }
@media (display-mode: standalone) {
  .topbar { padding-top: calc(2.25rem + env(safe-area-inset-top)); }
}
.brand {
  display: inline-flex; align-items: center; gap: 8px;
  font-weight: 700; letter-spacing: -.012em; text-decoration: none;
  color: var(--chrome-ink); margin-inline-end: auto;
}
/* The mark lies on the bar itself, orange into yellow, no tile ("Go f",
   13 October 2026). The same image the home screen shows, at a smaller size:
   see tools/make_icon.py. */
.mark {
  flex: 0 0 auto; display: block;
  width: 28px; height: 28px;
}
/* Every tab visible, no scrolling of any kind.
   This went through three wrong answers. Left to wrap with a flex:1 basis it
   built a 350px tower, one link per line. Made a sideways-scrolling strip, the
   last tabs were reachable only by dragging, and reaching Settings should not
   be a gesture. Then made bare text at .82rem with a 2.4px row gap, which is
   what the owner reported from his phone: "the tabs are not separated, they
   are adjacent to each other so much, borders between? IDK". He was right
   twice over. Nothing separated them, and each one was a 16px tall target
   where a thumb needs 44.

   So on a phone they are chips: a real target, a real edge, real space
   between. Eight of them fit in two rows. The desktop rule below turns them
   back into a plain row of text, because that is the one size at which bare
   links did work and he did not complain about the Mac. */
.topbar nav {
  display: none;
}
.topbar nav a {
  display: inline-flex; align-items: center; min-height: 44px;
  line-height: 1.2;
  /* The size is set HERE, on the link. `.topbar nav` carried a font-size for
     as long as this bar existed and it never once applied, because `.topbar a`
     below matches the link directly and inheritance loses to that. Every tab
     was .92rem while the stylesheet said .82rem. */
  font-size: .85rem;
}
.topbar a { color: var(--chrome-muted); text-decoration: none; font-size: .92rem; }
.topbar nav a:hover, .topbar nav a:focus-visible { color: var(--chrome-ink); }
.lang, .theme { font-size: .8rem; color: var(--chrome-muted); }
.theme {
  border: 1px solid var(--chrome-line); border-radius: var(--radius-sm);
  padding: .15rem .5rem; text-decoration: none;
}
.theme:hover { color: var(--chrome-ink); }
/* The sign-out button is a form button styled as a link, so it does not
   inherit the bar's colour the way the anchors do. */
.topbar .linklike { color: var(--chrome-muted); }
.topbar .linklike:hover { color: var(--chrome-ink); }
/* The top bar's round buttons: refresh (refresh.js) and, beside it, the
   riyal | dollar pill. Asked for on 2 October 2026, "the same location of
   every tab", from the picture he chose ("Pill"). */
.tb-refresh { margin: 0; display: inline-flex; }
/* On a phone a pull from the top refreshes, so the bar carries no ↻: asked
   for on 5 October 2026, "Yes without ↻". A computer has no pull and keeps
   it. The form stays, hidden, for the pull to post (refresh.js). */
@media (hover: none) and (pointer: coarse) { .tb-refresh { display: none; } }
.ccy-pill { margin: 0; display: inline-flex; gap: 2px; padding: 3px; border-radius: 999px;
  border: 0; background: var(--chrome-raised); }
.ccy-pill button { width: 30px; height: 28px; border-radius: 999px; border: 0; padding: 0; cursor: pointer;
  display: grid; place-items: center; background: none; color: var(--chrome-muted);
  font: 700 16px/1 system-ui, sans-serif; }
.ccy-pill button.on { background: #ffffff; color: var(--chrome); }
.riyal { width: 14px; height: 15px; fill: currentColor; display: block; }
.tb-btn {
  width: 34px; height: 34px; border-radius: 50%; padding: 0; cursor: pointer;
  display: inline-grid; place-items: center;
  border: 0; background: var(--chrome-raised); color: var(--chrome-ink);
}
.tb-btn svg { width: 18px; height: 18px; fill: none; stroke: currentColor;
  stroke-width: 2.2; stroke-linecap: round; stroke-linejoin: round; }
.tb-btn.is-busy svg { animation: tb-spin .8s linear infinite; }
@keyframes tb-spin { to { transform: rotate(360deg); } }
@media (prefers-reduced-motion: reduce) { .tb-btn.is-busy svg { animation-duration: 2.4s; } }
.refresh-toast {
  position: fixed; top: calc(4.2rem + env(safe-area-inset-top)); left: 50%; transform: translateX(-50%); z-index: 50; margin: 0;
  background: #111827; color: #fff; font-size: .85rem; font-weight: 600;
  padding: .45rem .9rem; border-radius: 999px; box-shadow: 0 6px 18px rgba(0, 0, 0, .25);
  white-space: nowrap;
}
/* A trade's line (trade_said.py) is longer than "Prices updated": held
   inside the phone's width, and wrapping there rather than running off it. */
.said-toast {
  white-space: normal; text-align: center; font-size: .8rem;
  width: max-content; max-width: calc(100vw - 2rem); box-sizing: border-box; border-radius: 1rem;
}

main {
  padding: var(--space-lg) 1.25rem 4rem; max-width: 68rem;
  margin: 0 auto; width: 100%; box-sizing: border-box; flex: 1 0 auto;
}

/* Small and firm. A page title on a screen of figures names the page and then
   gets out of the way: the largest thing on it should be a number, not a word.
   This was 2.6rem at weight 300, which is a consumer application's idea of a
   heading, and on a phone it pushed the first figure below the fold. */
h1 {
  font-size: 1.75rem; font-weight: 700;
  letter-spacing: -.02em; margin: .2rem 0 1.1rem; line-height: 1.15;
}
/* A section label, not a sentence. Small, spaced and set in capitals, which is
   how a screen of this kind marks the top of a block of figures and how the
   weekly email has always marked its cards. */
h2 {
  font-size: 1.22rem; font-weight: 700; letter-spacing: -.012em;
  text-transform: none; margin: 0 0 .7rem; line-height: 1.2;
}

.card {
  /* A real edge rather than a soft one. A hairline plus a shadow made a card
     float; a card on this kind of screen is a panel, and a panel has a border. */
  background: var(--card);
  border: 1px solid transparent;
  border-radius: var(--radius);
  padding: 1.1rem 1.05rem;
  margin-bottom: 1rem;
  box-shadow: var(--shadow);
}
/* Three levels of attention, and they are not interchangeable.

   Every caution in this application used to be the same amber card, so a price
   the application cannot vouch for looked exactly like a preview of a policy
   rule about idle cash. Nothing could shout, because everything was already
   shouting at one volume.

     .card.wrong   a figure on this screen cannot be trusted. Red. Rare.
     .card.warn    true, and you should do something about it.
     .card.note    true, and there is nothing to do.

   The inside edge carries the level as well as the tint, so the three are told
   apart at a glance and on a screen where the tint is washed out by daylight. */
.card.wrong { background: var(--danger-bg); border-color: var(--danger); }
.card.wrong h2 { color: var(--danger); }
.card.warn { background: var(--warn-bg); border-color: var(--warn); }
.card.warn h2 { color: var(--warn); }
.card.note { background: var(--note-bg); border-color: var(--note); }
.card.note h2 { color: var(--note); }
.card.wrong, .card.warn, .card.note { border-inline-start-width: 4px; }
.section-error { border-style: dashed; color: var(--muted); }

.muted { color: var(--muted); font-size: .9rem; }
.muted-row td { opacity: .55; }
.warn-inline { color: var(--warn); font-size: .9rem; }
.error { color: var(--danger); font-size: .85rem; display: block; font-weight: 600; }

.pairs { display: grid; grid-template-columns: 1fr auto; gap: .35rem .75rem; margin: 0; }
.pairs dt { color: var(--muted); }
.pairs dd { margin: 0; text-align: end; font-variant-numeric: tabular-nums; }

/* Wide content scrolls inside its own container. The page body never scrolls
   horizontally on a phone. There used to be two classes doing this, .scroll and
   .scroll-x, differing only in that one had the padding that made it work. Two
   names for one thing is how a screen ends up half-fixed. See .scroll-x below;
   this is the only definition. */
table { border-collapse: collapse; width: 100%; font-size: .85rem; }
th, td { text-align: start; padding: .55rem .5rem; border-bottom: 1px solid var(--hairline); vertical-align: top; }
th { color: var(--muted); font-weight: 600; white-space: nowrap; }
.num, td.num { text-align: end; font-variant-numeric: tabular-nums; white-space: nowrap; }

label { display: block; margin-bottom: .85rem; font-size: .9rem; color: var(--muted); }
label.check { display: flex; gap: .5rem; align-items: center; }
input, select, textarea {
  display: block; width: 100%; margin-top: .25rem; padding: .5rem .55rem;
  font: inherit; color: var(--ink); background: var(--raised);
  border: 1px solid transparent; border-radius: var(--radius-sm);
}
label.check input { width: auto; margin: 0; }
small { display: block; margin-top: .3rem; color: var(--muted); font-size: .8rem; }
fieldset { border: 1px solid var(--line); border-radius: var(--radius); padding: .75rem; margin: 0 0 1rem; }
legend { font-size: .85rem; color: var(--muted); padding: 0 .35rem; }

.actions { display: flex; gap: .5rem; align-items: center; margin-top: .5rem; }
/* One radius for everything that is pressed. A <button> was 8px here and 10px
   further down, so a real button and a link styled as one sat side by side on
   the same row with different corners. */
button, .btn {
  display: inline-block; padding: .62rem 1.05rem; border: 0; border-radius: var(--radius-sm);
  background: var(--accent); color: var(--accent-ink); font: inherit;
  font-size: .9rem; font-weight: 700; letter-spacing: .005em;
  text-decoration: none; cursor: pointer;
  transition: opacity .15s ease, transform .15s ease;
}
.btn.secondary { background: var(--raised); color: var(--ink); border: 1px solid transparent; }
button.danger { background: var(--danger); }
.danger-form { margin-top: 1.5rem; }

.tag {
  display: inline-block; padding: .12rem .45rem; border-radius: 6px; font-size: .75rem;
  background: var(--note-bg); color: var(--note); white-space: nowrap;
}
.tag.danger { background: transparent; color: var(--danger); border: 1px solid var(--danger); }
/* Buy green and Sell red, on one line with edit. A soft tint with coloured
   letters, from the picture he chose on 1 October 2026 ("Soft tint"), after
   the solid boxes read "so bright". The theme's own green and red, so each
   theme keeps its readable pair; the tint is that colour faint. */
.act-buy, .tl-tag.buy { background: color-mix(in srgb, var(--gain) 20%, transparent); color: var(--gain); }
.act-sell, .tl-tag.sell { background: color-mix(in srgb, var(--danger) 20%, transparent); color: var(--danger); }
td.row-actions { white-space: nowrap; }
/* Buy and Sell at the top of Positions, the same green and red as each
   row's (1 October 2026). */
.trade-top { display: flex; gap: .6rem; margin: .2rem 0 .6rem; }
.trade-top a.act {
  flex: 1; text-align: center; padding: .85rem 0; border-radius: 10px;
  font-weight: 700; font-size: 1.15rem; text-decoration: none;
}
.trade-top a.act-buy, td.row-actions a.act-buy { color: var(--gain); }
.trade-top a.act-sell, td.row-actions a.act-sell { color: var(--danger); }
.pick-search {
  width: 100%; box-sizing: border-box; padding: .65rem .8rem; margin: .2rem 0 .4rem;
  border-radius: 10px; border: 1px solid var(--line); background: var(--card);
  color: var(--ink); font: inherit;
}
.pick-list { list-style: none; margin: 0; padding: 0; max-height: 55vh; overflow-y: auto; }
.pick-list a {
  display: flex; justify-content: space-between; align-items: baseline; gap: .6rem;
  padding: .65rem .2rem; border-top: 1px solid var(--line); color: var(--ink); text-decoration: none;
}
.pick-list small { color: var(--muted); }
td.row-actions a.act {
  display: inline-block; padding: .15rem .55rem; border-radius: 6px;
  font-weight: 600; font-size: .82rem; text-decoration: none;
}
td.row-actions a.act-sell { margin-right: .35rem; }
/* The ticker and its › on one line, now nothing else widens the column. */


tfoot td { border-top: 2px solid var(--line); font-weight: 600; }

.actions form { margin: 0; }
/* Its own rule rather than an override of the one above, and not
   button.secondary-btn either: the download link on Settings is an <a>, and a
   rule keyed to the element would leave it looking like a primary button. */
.secondary-btn {
  display: inline-block; padding: .62rem 1.05rem; border-radius: var(--radius-sm);
  background: var(--raised); color: var(--ink);
  border: 1px solid transparent; font: inherit;
  font-size: .9rem; font-weight: 700; letter-spacing: .005em;
  text-decoration: none; cursor: pointer;
  transition: opacity .15s ease, transform .15s ease;
}

.trigger { border-top: 1px solid var(--line); padding-top: .6rem; margin-top: .6rem; }
.trigger p { margin: .2rem 0; }

/* Inline SVG only. Nothing on this page loads from a network. */
.spark { display: inline-block; vertical-align: middle; width: 96px; height: 24px; }
.spark-up { color: var(--gain); }
.spark-down { color: var(--danger); }
.nowrap { white-space: nowrap; }

.allocbar { display: block; width: 100%; height: 10px; border-radius: 5px; overflow: hidden; }
.bar-track { fill: var(--line); }
.bar-target { fill: var(--ink); }
.bar-ok .bar-fill { fill: var(--ok); }
.bar-over .bar-fill { fill: var(--warn-fill); }
.bar-under .bar-fill { fill: var(--note); }

.alloc { margin-bottom: .9rem; }
.alloc-head { display: flex; justify-content: space-between; gap: .5rem; font-size: .9rem; }
.alloc p { margin: .25rem 0 0; }

.waterfall { list-style: none; counter-reset: step; margin: 0; padding: 0; }
.waterfall li {
  counter-increment: step; border-top: 1px solid var(--line);
  padding: .75rem 0 .75rem 2rem; position: relative;
}
.waterfall li:first-child { border-top: 0; }
.waterfall li::before {
  content: counter(step); position: absolute; inset-inline-start: 0; top: .8rem;
  width: 1.4rem; height: 1.4rem; border-radius: 50%; background: var(--accent);
  color: var(--accent-ink); font-size: .8rem; display: grid; place-items: center;
}
.waterfall li.done::before { background: var(--muted); }
.waterfall p { margin: .2rem 0 0; }
.step-head { display: flex; justify-content: space-between; gap: .5rem; }

.inline-form { display: flex; gap: .5rem; align-items: flex-end; flex-wrap: wrap; }
.inline-form label { flex: 1; min-width: 10rem; margin: 0; }

.signout { margin: 0; }
button.linklike {
  background: none; border: 0; padding: 0; color: var(--accent-text);
  font: inherit; font-size: .85rem; cursor: pointer;
}

/* --- dashboard headline ------------------------------------------------ */
.hero {
  display: grid; gap: 1.1rem;
  padding: 1.25rem 1.3rem;
}
.hero-label {
  margin: 0; color: var(--muted); font-size: .86rem;
  text-transform: none; letter-spacing: 0; font-weight: 500;
}
/* The headline when too much of the portfolio is unpriced to state a figure.
   Muted, not alarming: nothing is wrong with the data, a price is simply
   absent, and a red border would say the opposite. */
.hero.unpriced .hero-number { font-size: 1.6rem; letter-spacing: 0; }
.hero.unpriced { border-style: dashed; }
.hero-number {
  /* The one number on the page allowed to be large, and now the only large
     thing on it. Set in the weight a quote screen uses: at 300 it read as a
     decorative figure rather than as the answer the page exists to give. */
  margin: .2rem 0 .45rem;
  font-size: clamp(1.9rem, 6vw, 2.5rem); font-weight: 700;
  font-variant-numeric: tabular-nums; letter-spacing: -.02em;
  line-height: 1.1;
}
.hero-unit { font-size: .9rem; font-weight: 400; color: var(--muted); }
.hero-main p:last-child { margin: 0; }
.hero-side { display: grid; grid-template-columns: 1fr auto; gap: .3rem .75rem; margin: 0;
  padding-top: 1rem; border-top: 1px solid var(--line); }
.hero-side dt { color: var(--muted); font-size: .85rem; }
.hero-side dd { margin: 0; text-align: end; font-variant-numeric: tabular-nums; font-size: .85rem; }
.up { color: var(--gain); }
.down { color: var(--danger); }

/* --- period selector --------------------------------------------------- */
.card-head { display: flex; flex-wrap: wrap; gap: .5rem; align-items: baseline;
  justify-content: space-between; margin-bottom: .75rem; }
.card-head h2 { margin: 0; }
.periods { display: flex; flex-wrap: wrap; gap: .25rem; }
.periods a {
  padding: .35rem .8rem; border-radius: 999px; font-size: .85rem;
  text-decoration: none; color: var(--ink); border: 1px solid transparent;
}
.periods a.on { color: var(--ink); border-color: transparent;
                background: var(--raised); font-weight: 700; }
.trend { margin-top: .75rem; color: var(--gain); }
.trend .spark { width: 100%; height: 72px; }

/* --- allocation ring + legend ------------------------------------------
   The legend is not decoration. Three light-mode hues sit under 3:1 against
   the surface, so every segment carries a visible label and its own numbers. */
.alloc-split { display: grid; gap: 1.25rem; align-items: center; }
.alloc-ring { display: grid; place-items: center; }
.donut { max-width: 168px; height: auto; transform: rotate(-90deg); }
.alloc-legend { list-style: none; margin: 0; padding: 0; }
.alloc-legend li {
  display: grid; grid-template-columns: auto 1fr auto; gap: .6rem;
  align-items: start; padding: .55rem 0; border-top: 1px solid var(--line);
}
.alloc-legend li:first-child { border-top: 0; }
.swatch { width: 10px; height: 10px; border-radius: 3px; margin-top: .35rem; }
.swatch.s1 { background: var(--series-1); }
.swatch.s2 { background: var(--series-2); }
.swatch.s3 { background: var(--series-3); }
.swatch.s4 { background: var(--series-4); }
.swatch.s5 { background: var(--series-5); }
.swatch.s6 { background: var(--series-6); }
.alloc-name { font-size: .9rem; }
.alloc-name .muted { display: block; font-size: .78rem; }
.alloc-figs { font-size: .9rem; white-space: nowrap; }

/* --- news (news.py): the Dashboard's card and the News page -------------- */
.news-h { display: flex; justify-content: space-between; align-items: baseline; gap: .5rem; }
.news-h a { font-size: .85rem; text-transform: none; letter-spacing: 0; font-weight: 600; }
.news-list { list-style: none; margin: 0; padding: 0; }
.news-list li { border-top: 1px solid var(--hairline); }
.news-list li:first-child { border-top: 0; }
.news-row { display: flex; gap: .7rem; padding: .8rem 0; color: var(--ink);
            text-decoration: none; align-items: flex-start; }
.news-row > span { display: flex; flex-direction: column; line-height: 1.35; min-width: 0; }
.news-row small { color: var(--muted); font-size: .8rem; margin-top: .15rem; }
.news-t { display: -webkit-box; -webkit-line-clamp: 3; -webkit-box-orient: vertical;
          overflow: hidden; }
.news-t b { display: block; }
.news-dot { width: .55rem; height: .55rem; border-radius: 50%; margin-top: .45rem; flex: none;
            background: var(--muted); }
.news-dot.l1 { background: var(--danger); }
.news-dot.l2 { background: var(--warn-fill); }
.news-ic { flex: none; display: grid; place-items: center; width: 1.9rem; height: 1.9rem; margin-top: .05rem;
  border-radius: .55rem; background: var(--raised); color: var(--muted); }
.news-ic svg { width: 1.1rem; height: 1.1rem; fill: none; stroke: currentColor; stroke-width: 1.7;
  stroke-linecap: round; stroke-linejoin: round; }
.news-kind { font-weight: 600; color: var(--ink); }
.news-group { font-size: .9rem; letter-spacing: 0; text-transform: none; font-weight: 600;
              color: var(--muted); margin: 1.1rem 0 .2rem; }
.news-group:first-child { margin-top: 0; }
/* The head line: a ticker or a market date on the left, its move, verdict or
   date on the right (picture approved 30 September 2026). */
.news-row > span { flex: 1; }
.news-top { display: flex; justify-content: space-between; align-items: baseline; gap: .5rem; }
.news-top b { display: inline; }
.news-fig { font-weight: 700; font-variant-numeric: tabular-nums; white-space: nowrap; }
.news-fig.up { color: var(--gain); }
.news-fig.down { color: var(--danger); }
details.news-more { border-top: 1px solid var(--hairline); }
details.news-more > summary { display: flex; justify-content: space-between; gap: .5rem;
  padding: .65rem 0; cursor: pointer; font-weight: 600; list-style: none; }
details.news-more > summary::-webkit-details-marker { display: none; }
details.news-more > summary small { color: var(--muted); font-weight: 600; }
details.news-more[open] > summary small { display: none; }
/* Each section its own card, its name and count on top (1 October 2026):
   small grey capitals between lines did not say where a section began. */
.news-sec + .news-sec { margin-top: 1rem; }
.sec-h { display: flex; align-items: center; gap: .5rem; margin: 0 0 .35rem;
         padding-bottom: .3rem; border-bottom: 0; }
.sec-h h2 { margin: 0; font-size: 1.22rem; font-weight: 700; color: var(--ink);
            letter-spacing: -.012em; text-transform: none; display: flex; align-items: center; gap: .55rem; }
/* A News section's icon, its kind (27 October 2026). */
.sec-ic { display: inline-grid; place-items: center; width: 1.9rem; height: 1.9rem; border-radius: .6rem;
  background: var(--raised); flex: none; }
.sec-ic svg { width: 1.05rem; height: 1.05rem; fill: none; stroke: currentColor; stroke-width: 1.8;
  stroke-linecap: round; stroke-linejoin: round; }
.sec-ic.g-dates { color: var(--vs-line); }
.sec-ic.g-act { color: var(--warn-fill); }
.sec-ic.g-results { color: var(--accent-text); }
.sec-ic.g-holdings { color: var(--gain); }
.sec-ic.g-market { color: var(--muted); }
.sec-h span { margin-inline-start: auto; font-size: .8rem; font-weight: 700; color: var(--muted);
              background: var(--raised); border-radius: 6px; padding: .1rem .5rem; }
.sec-note { margin: .45rem 0 .1rem; font-size: .82rem; }
/* The last results, opened from a line on Earnings, as two charts sharing
   their columns (charts.results_charts, 1 October 2026). */
.earn-sheet .sheet-panel { max-height: 88vh; }
.ec { display: block; margin: .2rem 0 .1rem; }
.ec-rung { stroke: var(--line); stroke-width: 1; }
.ec-zero { stroke: var(--muted); stroke-width: 1.2; }
.ec-tick { font-size: 10.5px; fill: var(--muted); text-anchor: end; font-variant-numeric: tabular-nums; }
.ec-date { font-size: 10.5px; fill: var(--muted); text-anchor: middle; }
.ec-exp { fill: none; stroke: var(--muted); stroke-width: 1.6; }
.ec-act.beat { fill: var(--gain); }
.ec-act.missed { fill: var(--danger); }
.ec-act.met { fill: var(--muted); }
.ec-bar.up { fill: var(--gain); }
.ec-bar.down { fill: var(--danger); }
.ec-future { fill: var(--raised); }
.ec-gap { font-size: 12px; fill: var(--muted); text-anchor: middle; }
.ec-cross { stroke: var(--ink); stroke-dasharray: 3 3; opacity: .6; }
.ec-hit { fill: transparent; cursor: pointer; }
.ec-h { display: flex; justify-content: space-between; align-items: baseline; gap: .5rem;
        margin: .8rem 0 0; font-weight: 700; font-size: .92rem; }
.ec-h small { font-weight: 500; color: var(--muted); font-size: .75rem; white-space: nowrap; }
.ec-key i { display: inline-block; width: 9px; height: 9px; border-radius: 50%;
            margin: 0 .2rem 0 .45rem; vertical-align: -1px; }
.ec-key .k-exp { border: 1.5px solid var(--muted); }
.ec-key .k-beat { background: var(--gain); }
.ec-key .k-miss { background: var(--danger); }
.ec-chips { display: flex; flex-wrap: wrap; gap: .5rem; margin: .4rem 0 .2rem; }
.ec-chips span { background: var(--raised); border-radius: 6px; padding: .2rem .6rem;
                 font-size: .82rem; font-weight: 600; }
.ec-read { background: var(--raised); border-radius: 10px; padding: .6rem 0;
           font-size: .85rem; font-weight: 600; margin: .4rem 0; }
.ec-read .er-r { border-bottom: 0; padding-top: 0; padding-bottom: 0; font-weight: 400; }

@media (min-width: 44rem) {
  .hero { grid-template-columns: 1.3fr 1fr; align-items: start; }
  .hero-side { padding-top: 0; border-top: 0;
    border-inline-start: 1px solid var(--line); padding-inline-start: 1.25rem; }
  .alloc-split { grid-template-columns: 200px 1fr; }
}

.demo-banner {
  margin: 0; padding: .6rem 1rem; text-align: center; font-size: .82rem;
  font-weight: 600; letter-spacing: .02em;
  background: var(--warn-bg); color: var(--warn);
  border-bottom: 1px solid var(--warn);
}

/* Plan against self-directed. Two rows, same measure on both, so the reader
   compares like with like rather than a percentage against a total. */
/* Any table too wide for the screen scrolls in its own box rather than
   dragging the page with it.

   The shadows are the point. A scroll box with no visible scrollbar, which is
   every one of them on a Mac and most on a phone, gives the reader no way to
   know there are more columns to the right. These are pure CSS: the two
   gradients pinned with background-attachment: local slide away as the box
   scrolls, so a shadow appears on the side that still has content and vanishes
   at the end of it. Nothing to load and nothing to run. */
.scroll-x {
  overflow-x: auto; -webkit-overflow-scrolling: touch;
  margin: .5rem -.35rem 1rem; padding: 0 .35rem;
  background:
    linear-gradient(to right, var(--card) 40%, transparent),
    linear-gradient(to left, var(--card) 40%, transparent) 100% 0,
    radial-gradient(farthest-side at 0 50%, rgba(20, 20, 26, .16), transparent),
    radial-gradient(farthest-side at 100% 50%, rgba(20, 20, 26, .16), transparent) 100% 0;
  background-repeat: no-repeat;
  background-size: 42px 100%, 42px 100%, 15px 100%, 15px 100%;
  background-attachment: local, local, scroll, scroll;
}
.compare { width: 100%; border-collapse: collapse; margin: 0; }
/* Wide only where it can scroll sideways. On its own, 30rem ran NEOM's plan
   table and Saham's own record off a phone (found by him, 1 October 2026). */
.scroll-x .compare { min-width: 30rem; }
.compare th { text-align: start; font-weight: 600; padding: .45rem .5rem; }
.compare thead th { color: var(--muted); font-size: .8rem; font-weight: 500; }
.compare td { padding: .45rem .5rem; font-variant-numeric: tabular-nums; }
.compare tbody tr + tr { border-top: 1px solid var(--line); }


/* ---------------------------------------------------------------- polish

   Numbers are tabular everywhere they are compared, which is set where each of
   those rules is declared. It was also set a second time here, along with a
   second border-collapse on table and a second colour for .up and .down. A
   property set twice for one selector is how a screen ends up half-fixed: the
   later copy wins, and an edit to the earlier one changes nothing while
   looking applied. tests/test_one_rule_one_place.py now fails the build on
   one. */
thead th {
  font-weight: 500; font-size: .8rem; color: var(--muted);
  text-transform: none; letter-spacing: 0;
}
tbody tr + tr { border-top: 1px solid var(--hairline); }

/* A row lights under the pointer, so the eye keeps its place across twelve
   columns. Only where there is a real pointer: on a touch screen :hover sticks
   to the last row tapped and reads as a selection nobody made. */
@media (hover: hover) {
  tbody tr:hover { background: var(--raised); }
}

button:active, .secondary-btn:active, .btn:active { transform: translateY(1px); }

a:focus-visible, button:focus-visible, input:focus-visible, select:focus-visible {
  outline: 2px solid var(--accent-text); outline-offset: 2px;
}

/* Anyone who has asked for less movement gets none, including the field,
   which renders a single still frame and stops. */
@media (prefers-reduced-motion: reduce) {
  * { animation-duration: .01ms !important; transition-duration: .01ms !important; }
}

@media (min-width: 48rem) {
  /* Wide enough for one row: identity, nav, account. */
  .topbar { flex-wrap: nowrap; gap: 1.1rem; }
  .topbar nav {
    /* Shown here and nowhere else. It still WRAPS: eight links beside the
       mark and the account controls do not fit a narrow laptop window, and a
       row that cannot wrap pushes the whole page sideways instead, which is
       exactly what it used to do on the phone. */
    display: flex; flex-wrap: wrap;
    order: 0; flex: 1 1 auto; overflow: visible; margin: 0; padding: 0;
    column-gap: .95rem; row-gap: .15rem;
  }
  /* Chips are a phone answer to a phone problem. At this width there is room
     for the links to be links. */
  .topbar nav a {
    min-height: 0; padding: .1rem 0;
    border: 0; background: none; border-radius: 0;
    /* Back up. The narrow size exists to fit a phone and there is nothing to
       fit here. */
    font-size: .85rem;
  }
  .brand { margin-inline-end: 0; }
  main { padding: 1.9rem 2rem 4rem; }
  .card { padding: 1.15rem 1.25rem; }
  .hero { padding: 1.5rem 1.6rem; }
}

/* Which build this page is. Quiet, and the only way to tell a stale cache
   from a failed deploy without a developer present. */
.build {
  font-size: .7rem; color: var(--muted); opacity: .55;
  font-variant-numeric: tabular-nums; letter-spacing: .04em;
  margin-top: .35rem;
}

/* Why the number is or is not moving. Quiet, and directly under it, because
   a still figure with no explanation reads as a broken application. */
/* One rule, because the margin-top set beside the hero was cancelled by
   this shorthand and had no effect at all. */
.asof { margin: .1rem 0 1.25rem; font-size: .85rem; line-height: 1.5; }
.asof .why { display: block; color: var(--muted); font-size: .8rem; margin-top: .15rem; }

/* A figure that has just changed, marked briefly so the movement is noticed
   rather than discovered. Suppressed for anyone who asked for less motion. */
.just-changed { animation: settle 1.1s ease-out; }
@keyframes settle {
  0%   { background: color-mix(in srgb, var(--accent-text) 20%, transparent); }
  100% { background: transparent; }
}
@media (prefers-reduced-motion: reduce) { .just-changed { animation: none; } }
/* A figure a new price moved, laid onto the page in place (live.js), flashes
   green up or red down for a moment, as Investing.com's rows do. Asked for on
   5 October 2026, "Go" to the picture. A fade of colour, not a movement, so
   it stays for a phone asking for less motion. */
.flash-up { animation: flash-up 1s ease-out; }
.flash-down { animation: flash-down 1s ease-out; }
@keyframes flash-up { from { background-color: color-mix(in srgb, var(--gain) 26%, transparent); } }
@keyframes flash-down { from { background-color: color-mix(in srgb, var(--danger) 26%, transparent); } }

.asof.is-live .why::before { content: "\2022 "; color: var(--ok); }
.asof.is-stalled .why { color: var(--warn); }

/* Extended-hours prices. Marked, because a thin-market print in the same
   typeface as a close is a worse number that looks better. */
.asof .thin { color: var(--warn); }

/* The long view. Capital is a line because every movement is dated; value is
   marks until enough days are measured to justify joining them. */
.journey {
  display: block; max-width: 100%; overflow: visible;
  /* A press was selecting the chart as text: iOS put its own Copy and Look Up
     bar over the card, with the blue selection handles across the lines, and
     the reading never appeared. A chart is a picture, so it is not selectable
     and offers no callout. touch-action leaves the page its vertical scroll
     and claims only the horizontal gesture. */
  touch-action: pan-y;
  user-select: none; -webkit-user-select: none;
  -webkit-touch-callout: none;
}
.journey-axis { stroke: var(--muted); stroke-width: 1.2; }
.journey-capital {
  fill: none; stroke: var(--muted); stroke-width: 2;
  stroke-linejoin: round; stroke-linecap: round;
}
/* Total P/L against his capital (30 September 2026): green above the line,
   red below, the gap itself the thing drawn. */
.journey-value-line { fill: none; stroke-width: 2; stroke-linejoin: round; stroke-linecap: round; }
.journey-value-line.up { stroke: var(--gain); }
.journey-value-line.down { stroke: var(--danger); }
.journey-fill { stroke: none; opacity: .14; }
.journey-fill.up { fill: var(--gain); }
.journey-fill.down { fill: var(--danger); }
.journey-value-mark { stroke: var(--card); stroke-width: 2; }
.journey-value-mark.up, .journey-end.up { fill: var(--gain); }
.journey-value-mark.down, .journey-end.down { fill: var(--danger); }
.journey-end { stroke: var(--card); stroke-width: 2.5; }
.journey-note { font-size: 10.5px; fill: var(--ink); text-anchor: middle; }
.journey-note-dot { fill: var(--ink); stroke: var(--card); stroke-width: 2; }
.journey-key { font-size: 10.5px; font-weight: 500; }
.journey-key-capital { fill: var(--muted); }
.journey-key-value { fill: var(--series-1); }
.journey-date { font-size: 11px; fill: var(--muted); }
.journey-date-end { text-anchor: end; }

/* The vertical scale, added on 14 September 2026. Faint on purpose: it is
   there so a line can be placed without touching the chart, and a grid dark
   enough to compete with the lines makes the chart harder to read, not
   easier. */
.journey-rung { stroke: var(--hairline); stroke-width: 1; }
.journey-tick { font-size: 11px; fill: var(--muted); text-anchor: end; font-variant-numeric: tabular-nums; }

/* The reading at a date, on press and drag. Dotted, because a solid line here
   reads as a third series. touch-action keeps a vertical scroll working: the
   chart claims the horizontal gesture and leaves the page the vertical one. */
/* Hit testing, made deterministic. One transparent rectangle takes every
   pointer event and nothing else in the drawing takes any, so a touch between
   two lines lands on the chart rather than on nothing at all. */
.journey-hit { fill: transparent; pointer-events: all; }
.journey path, .journey circle, .journey line, .journey text,
.journey rect:not(.journey-hit) { pointer-events: none; }

/* While a reading is on screen the chart owns the gesture, so the scroller
   cannot claim a drag and cancel the pointer mid-read. The page keeps its
   scroll everywhere else, and tapping off the chart hands this back. */
.journey.is-reading { touch-action: none; }

/* Hidden by class rather than by the hidden attribute, which SVG children do
   not reliably honour. */
.journey .is-off { display: none; }

/* The date ticks along the bottom, so a point in the middle of the window has
   a date under it and not only the two ends. */
.journey-tick-mark { stroke: var(--hairline); stroke-width: 1; }
.journey-cross-v, .journey-cross-h {
  stroke: var(--ink); stroke-width: 1; stroke-dasharray: 3 3; opacity: .55;
}
.journey-cross-dot { fill: var(--ink); stroke: var(--card); stroke-width: 2; }
.journey-cross-box, .journey-cross-datebox { fill: var(--ink); }
.journey-cross-amount, .journey-cross-date {
  font-size: 12px; font-weight: 600; fill: var(--card);
  font-variant-numeric: tabular-nums;
}
/* The figure the chart draws, large enough to read at a phone's width; what
   it is made of beneath it, smaller (30 September 2026). */
.journey-cross-lead { font-size: 14px; font-weight: 700; }
.journey-cross-part { font-size: 12px; font-weight: 500; }



/* Money in against value now, one pair of bars per account. The two bars are
   deliberately different weights rather than different hues: the question is
   which is longer, and a reader with any colour vision answers it from length
   alone. Colour only carries the sign of the difference, which is also
   written out with its own + or -. */
.bars { display: block; max-width: 100%; overflow: visible; }
.bar-capital { fill: var(--muted); opacity: 0.45; }
.bar-value { fill: var(--series-1); }
.bar-name { font-size: 12px; font-weight: 600; fill: var(--ink); }
.bar-delta { font-size: 11px; font-weight: 500; fill: var(--muted); }
.bar-delta.up { fill: var(--gain); }
.bar-delta.down { fill: var(--danger); }
.bar-figure { font-size: 11px; fill: var(--muted); }


/* The trade screen. A buy and a sell are opposite acts and the eye should not
   have to read the word to tell them apart, so they carry the same two colours
   the gain and loss figures already use everywhere else in the application. */
.deal { display: flex; gap: .4rem; }
.deal a {
  flex: 1; text-align: center; text-decoration: none;
  padding: .34rem .5rem; border-radius: 8px;
  font-size: .82rem; font-weight: 600; letter-spacing: .01em;
  border: 1px solid currentColor;
}
.deal .buy { color: var(--gain); }
.deal .sell { color: var(--danger); }
.deal a:hover, .deal a:focus-visible {
  background: color-mix(in srgb, currentColor 14%, transparent);
}

.holding {
  display: flex; align-items: center; gap: 1rem;
  padding: .6rem 0; border-bottom: 1px solid var(--hairline);
}
.holding:last-child { border-bottom: 0; }
.holding .who { flex: 1 1 auto; min-width: 0; }
.holding .who strong { display: block; }
.holding .amount { text-align: end; white-space: nowrap; font-variant-numeric: tabular-nums; }
.holding .deal { flex: 0 0 auto; width: 9.5rem; }

/* The phone. Until now the only rule in this file written for one was the
   three lines below about .holding: everything else was designed at a Mac and
   left to squeeze. */
@media (max-width: 560px) {
  .holding { flex-wrap: wrap; gap: .35rem .75rem; }
  .holding .who { flex: 1 1 60%; }
  .holding .deal { flex: 1 1 100%; width: auto; }

  /* Room back. A 1.35rem card inside 1.25rem of page leaves 340px of a 390px
     screen for the figures, which is what the reader came for. */
  main { padding: 1.25rem .8rem 3rem; }
  .card { padding: 1rem .85rem; border-radius: 12px; }
  .card + .card { margin-bottom: .8rem; }

  /* THE FIRST COLUMN STAYS. Nine columns of Positions and twelve of
     Performance cannot be made to fit, and pretending otherwise by shrinking
     the type only makes them unreadable as well as wide. What breaks a wide
     table on a phone is not the dragging, it is losing sight of WHICH ROW you
     are dragging: four columns in, every line is anonymous numbers.

     So the ticker, or the account name, is pinned and the rest slides under
     it. Every table in the application gets this, because every one of them
     names its row in the first column. */
  .scroll-x table th:first-child,
  .scroll-x table td:first-child {
    position: sticky; inset-inline-start: 0; z-index: 1;
    background: var(--card);
    box-shadow: 1px 0 0 var(--hairline);
  }
  /* No padding to the left of the pinned column: the columns sliding under
     it showed through that strip, a letter's edge beside every ticker
     (30 September 2026). Margin and padding cancelled out, so nothing moves. */
  .scroll-x { margin-inline: 0; padding-inline: 0; }
  .scroll-x table { font-size: .88rem; }
  .scroll-x th, .scroll-x td { padding-inline: .45rem; }

  /* Anything tapped is at least a thumb across. These were 30px. */
  .periods a, .view-toggle a { min-height: 40px; display: inline-flex; align-items: center; }
}


/* Ticker search results, hanging from the box itself (symbols.js wraps it),
   never from the label, whose help line pushed them a paragraph down. */
.symbol-box { position: relative; display: block; }
.symbol-hits {
  position: absolute; z-index: 30; inset-inline: 0; top: 100%;
  margin: .2rem 0 0; padding: .25rem; list-style: none;
  max-height: 16rem; overflow-y: auto;
  background: var(--card); border: 1px solid var(--line); border-radius: 10px;
  box-shadow: 0 12px 32px rgb(0 0 0 / .28);
}
.symbol-hits li {
  display: flex; gap: .55rem; align-items: baseline;
  padding: .4rem .55rem; border-radius: 7px; cursor: pointer;
}
.symbol-hits li strong { flex: 0 0 auto; font-size: .9rem; }
.symbol-hits li span {
  flex: 1 1 auto; color: var(--muted); font-size: .8rem;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.symbol-hits li.held span { color: var(--ink); }
.symbol-hits li:hover, .symbol-hits li.on {
  background: color-mix(in srgb, var(--accent-text) 16%, transparent);
}


/* The headline percentage. Deliberately quieter than the riyal figure above
   it: the absolute number is what was made or lost, the percentage is only
   the scale it happened on, and the capital it sits on is named so the
   reader never has to guess what the denominator was. */
.hero-pct { margin: -2px 0 0; font-size: 14px; font-weight: 700;
            font-variant-numeric: tabular-nums; }
.hero-pct .muted { font-weight: 400; font-size: 12px; }


/* A button that has to look like the small, reversible thing it is, next to
   rows of figures. Full button styling here would give deleting a ledger row
   more visual weight than saving one, which is the wrong way round. */
.link-button {
  background: none; border: 0; padding: 0; font: inherit; font-size: 12px;
  cursor: pointer; text-decoration: underline; color: var(--muted);
}
.link-button.danger { color: var(--danger); }
.link-button:hover { text-decoration: none; }


/* The step that turns a plan into a ledger entry. Deliberately quiet: it is a
   link to a form, not the act of recording, and it must not look like a button
   that has already done something. */
.step-action { margin: 6px 0 0; display: flex; gap: 10px; align-items: baseline; flex-wrap: wrap; }
.step-action .muted { font-size: 12px; }
.button-link {
  display: inline-block; padding: 4px 12px; border: 1px solid var(--line);
  border-radius: var(--radius-sm); font-size: 13px; font-weight: 600; text-decoration: none;
  color: var(--ink); background: var(--raised);
}
.button-link:hover { border-color: var(--ink); }
.note-inline { background: var(--note-bg); color: var(--note); padding: 8px 12px;
               border-radius: 8px; font-size: 13px; margin: 0 0 12px; }
ul.tight { margin: 6px 0 0; padding-left: 18px; font-size: 13px; }
ul.tight li { margin: 2px 0; }


/* Two ways of arranging one list. Deliberately not tabs: tabs imply separate
   pages with separate content, which is exactly the mistake being undone here. */
.view-toggle { display: flex; gap: 10px; align-items: baseline; flex-wrap: wrap;
               margin: 0 0 var(--space); font-size: 13px; }
.view-toggle a { text-decoration: none; color: var(--ink); padding: 3px 12px;
                 border: 1px solid transparent; border-radius: 999px; }
.view-toggle a.is-on { color: var(--ink); border-color: transparent; font-weight: 700; background: var(--raised); }
.view-toggle .muted { font-size: 12px; }


/* The sections inside one group. A row of links rather than tabs with borders:
   they are steps in one question, not separate places, and the first is always
   the one you came to read.

   These used to be the loudest thing on the screen: solid cards with borders,
   sitting under a top nav that was bare grey text. The hierarchy read upside
   down, the smaller level looking like the real navigation. The top nav is now
   the stronger of the two and these are quieter to match, while staying a
   44px target, which they always were.

   The em dash between name and hint is deliberately not used anywhere in this
   application. The hint sits on its own line instead. */
.subnav {
  display: flex; gap: 2px; flex-wrap: wrap; margin: 0 0 var(--space-lg);
  border-bottom: 1px solid var(--line);
}
.subnav a {
  display: flex; flex-direction: column; justify-content: center; gap: 1px;
  min-height: 44px; text-decoration: none;
  padding: 6px 12px; border-radius: var(--radius-sm) var(--radius-sm) 0 0;
  border: 1px solid transparent; color: var(--muted); background: none;
}
.subnav a strong { font-size: 12.5px; font-weight: 500; color: var(--muted); }
.subnav a span { font-size: 11px; }
.subnav a:hover { background: var(--raised); }
.subnav a.is-on { background: none; box-shadow: inset 0 -3px 0 var(--ink); }

/* On a phone these are chips, not tabs.
   Reported from the phone: "see how the 2 options above look off". They were.
   A hint of six or seven words makes each item nearly a screen wide, so the
   two stacked, the underline under the first ran the whole width and read as a
   rule, and the strip's own bottom border drew a second line under both. Two
   navigation items looked like two headings with a divider between them.

   So the hint goes at this width and the labels sit side by side. Nothing is
   lost that the label does not already say: "Update from a snapshot" is the
   hint. The wide screen below keeps both. */
@media (max-width: 47.99rem) {
  .subnav { border-bottom: 1px solid var(--line); gap: 18px; margin-bottom: var(--space-lg); }
  .subnav a {
    flex: 0 1 auto; min-height: 44px; padding: 0 2px;
    border-radius: 0; border-color: transparent;
  }
  .subnav a span { display: none; }
  .subnav a strong { font-size: 16px; }
  .subnav a.is-on {
    background: none; border-color: transparent; box-shadow: inset 0 -3px 0 var(--ink);
  }
  .subnav a.is-on strong { color: var(--ink); }
}
.subnav a.is-on strong { color: var(--ink); font-weight: 700; }
/* The tab you are on: the bar's own ink, underlined in the brand's green.
   One rule, because this strip only exists on a wide screen now; the phone's
   current tab is marked in .tabbar below.

   It used to be bare --ink on the bar, which is the page's near-black text
   measured against a coloured bar: 1.63:1 on the old blue. The one tab you
   could not read was the one you were on. */
.topbar nav a.is-on {
  color: var(--chrome-ink); font-weight: 700;
  box-shadow: inset 0 -3px 0 var(--chrome-ink);
}


/* --- the phone's navigation ---------------------------------------------
   Four sections along the bottom, where a thumb already is, and the other
   four behind one button. Eight as chips in the bar above took two rows and
   151px of an 844px screen before a single figure appeared.

   Which four is decided in app/web/nav.py and drawn by _tabbar.html. This
   file only says what they look like. */
/* Investing.com's floating pill (prototype, 12 October 2026): inset from
   the sides and the bottom, its own surface and a hairline edge, drawn by
   ::before so a fixed drawer inside the bar keeps the screen as its frame.
   The padding under it stays the home line's own height. */
.tabbar {
  position: fixed; inset-inline: 0; bottom: max(0px, calc(12px - env(safe-area-inset-bottom))); z-index: 40;
  display: flex; align-items: stretch;
  background: none; border-top: 0;
  padding: 0 17px env(safe-area-inset-bottom);
}
/* An open pop-up inside <main> covers the floating bar, as Investing.com's
   sheets do: the bar steps under main, whose own layer the sheet is in. */
html:has(main details.sheet[open]) .tabbar { z-index: 0; }
.tabbar::before {
  content: ""; position: absolute; z-index: -1; top: 0;
  inset-inline: 12px; bottom: max(0px, calc(env(safe-area-inset-bottom) - 14px));
  border-radius: 34px; background: var(--tabbar-bg); border: 1px solid var(--tabbar-line);
  box-shadow: 0 8px 28px rgba(0, 0, 0, .28);
  -webkit-backdrop-filter: blur(14px); backdrop-filter: blur(14px);
}
.tabbar > a, .tabbar summary {
  flex: 1 1 0; min-width: 0; min-height: 58px;
  margin: 5px 0 calc(5px - min(14px, env(safe-area-inset-bottom)));
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 3px; text-decoration: none; color: var(--ink);
  font-size: 10.5px; font-weight: 500; cursor: pointer;
  list-style: none; border-radius: 28px;
}
.tabbar summary::-webkit-details-marker { display: none; }
.tabbar svg {
  width: 23px; height: 23px; fill: none; stroke: currentColor;
  stroke-width: 1.9; stroke-linecap: round; stroke-linejoin: round;
}
.tabbar > a span, .tabbar summary span {
  max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
/* Colour AND weight. On a bar this small, weight alone is not findable, and
   colour alone fails for a reader who cannot tell these two apart. */
.tabbar > a.is-on { color: var(--accent-text); font-weight: 700; background: var(--tabbar-on); }
/* The bar is fixed over the page, so the page needs that much room under it,
   or its last card sits behind the bar and cannot be read. */
@media (max-width: 47.99rem) {
  main { padding-bottom: calc(68px + 2.5rem + env(safe-area-inset-bottom)); }
}
@media (min-width: 48rem) { .tabbar { display: none; } }

/* The drawer. A <details>, so it opens with JavaScript turned off;
   static/drawer.js only adds Escape and a tap outside. */
.tabbar .drawer { flex: 1 1 0; min-width: 0; display: flex; }
.tabbar .drawer[open] > summary,
/* A page that lives behind More lights More: nine pages lit nothing in the
   bar, found in the review of 23 September 2026. */
.tabbar .drawer:has(a.is-on) > summary { color: var(--accent-text); font-weight: 700; background: var(--tabbar-on); }
.drawer-scrim {
  position: fixed; inset: 0; z-index: 41; background: var(--scrim);
}
.drawer-sheet {
  position: fixed; z-index: 42; top: 0; bottom: 0; inset-inline-end: 0;
  width: min(17rem, 82vw);
  display: flex; flex-direction: column;
  background: var(--card); border-inline-start: 0;
  box-shadow: -8px 0 28px rgba(0, 0, 0, .32);
  overflow-y: auto;
  padding-top: env(safe-area-inset-top);
  padding-bottom: env(safe-area-inset-bottom);
}
.drawer-head {
  margin: 0; padding: 20px 16px 12px;
  font-size: 1.22rem; font-weight: 700; letter-spacing: -.012em;
  text-transform: none; color: var(--ink);
  border-bottom: 0;
}
.drawer-sheet a {
  min-height: 56px; padding: 8px 16px;
  display: flex; flex-direction: column; justify-content: center; gap: 2px;
  text-decoration: none; color: var(--ink);
  border-bottom: 0;
}
.drawer-sheet a strong { font-size: .92rem; font-weight: 600; }
.drawer-sheet a span { font-size: .72rem; color: var(--muted); }
.drawer-sheet a.is-on { background: var(--raised); }
.drawer-sheet a.is-on strong { color: var(--accent-text); }


/* The reasoning behind a figure, folded away. See templates/_why.html. */
.why-drop { display: inline-block; vertical-align: baseline; position: relative; }
/* The i and the space before it never part (_why.html); its panel wraps. */
.why-glue { white-space: nowrap; }
.why-glue::before { content: "\00a0"; }
.why-glue .why-body { white-space: normal; }
.why-drop > summary {
  list-style: none; cursor: pointer; display: inline-flex;
  align-items: center; justify-content: center;
  width: 17px; height: 17px; border-radius: 50%;
  border: 1px solid var(--line); color: var(--muted);
  font-size: 11px; font-style: italic; font-weight: 700; line-height: 1;
  /* 24px of touch target from a 17px dot, without moving the text beside it. */
  outline-offset: 3px;
}
.why-drop > summary::-webkit-details-marker { display: none; }
.why-drop > summary::after {
  content: ""; position: absolute; inset: -4px auto -4px -4px; width: 25px;
}
.why-drop > summary:hover { border-color: var(--ink); color: var(--ink); }
.why-drop[open] > summary { border-color: var(--ink); color: var(--ink); }
.why-body {
  position: absolute; z-index: 20; inset-inline-start: 0; top: calc(100% + 6px);
  width: min(38ch, 78vw); padding: 10px 13px;
  background: var(--raised); border: 1px solid transparent;
  border-radius: 12px; box-shadow: 0 10px 30px rgba(0, 0, 0, .3);
  font-size: 12.5px; line-height: 1.5; color: var(--muted); font-weight: 400;
  text-align: start; white-space: normal;
}
.why-body p { margin: 0 0 7px; }
.why-body p:last-child { margin-bottom: 0; }
.why-body strong { color: var(--ink); }

/* Opening on hover is done in why.js, not here: a closed <details> hides its
   own content through the user-agent stylesheet, and CSS that tries to
   override that works in some engines and not others. */


/* Where a holding's price comes from. Four states, and the fourth was the
   missing one: a mutual fund does not have a price now, it has one NAV per
   dealing day. Said on every row, because a portfolio with a fifth of its
   value typed in by hand looks exactly like a live one. */
.cadence { font-size: 10.5px; letter-spacing: .04em; text-transform: uppercase;
           padding: 1px 6px; border-radius: 4px; border: 1px solid var(--line);
           color: var(--muted); white-space: nowrap; }
.cadence-live { color: var(--ok); border-color: currentColor; }
.cadence-manual { border-style: dashed; }
.cadence-unpriced { color: var(--danger); border-color: currentColor; }
/* Carries a date rather than a word, so it is wider than the others and must
   be allowed to wrap out of the uppercase treatment the one-word tags use. */
.cadence-nav { text-transform: none; letter-spacing: 0; font-variant-numeric: tabular-nums; }
/* The age is only shown where nothing will update it. A live price being
   ninety seconds old is not information; a hand-typed one being 24 days old is. */
.cadence-age { font-size: 10.5px; color: var(--muted); }
.cadence-age.is-old { color: var(--warn); font-weight: 700; }


/* Three dials, read side by side. The arc is where you are, the notch is the
   target today's glidepath sets. No composite score sits behind them. */
.health { display: flex; gap: var(--space); flex-wrap: wrap; align-items: flex-start; }
.health-one { text-align: center; flex: 1 1 132px; min-width: 132px; }
.health-one h3 { font-size: 12px; font-weight: 600; color: var(--muted); margin: 0 0 2px; }
.health-drift { font-size: 11.5px; color: var(--muted); }
.health-drift.is-out { color: var(--warn); font-weight: 700; }
.gauge { display: block; margin: 0 auto; max-width: 100%; height: auto; }
.gauge-track { fill: none; stroke: var(--line); stroke-width: 8; stroke-linecap: round; }
.gauge-arc { fill: none; stroke-width: 8; stroke-linecap: round; }
.gauge-arc.gauge-in { stroke: var(--ok); }
.gauge-arc.gauge-out { stroke: var(--warn-fill); }
.gauge-target { stroke: var(--ink); stroke-width: 2; }
.gauge-value { text-anchor: middle; font-size: 15px; font-weight: 700; fill: var(--ink); }
.gauge-target-text { text-anchor: middle; font-size: 8px; fill: var(--muted); }
.checks { display: flex; align-items: baseline; gap: 8px; flex-wrap: wrap; }
.checks b { font-size: 22px; font-weight: 800; }
.checks b.is-clear { color: var(--ok); }
.checks b.is-broken { color: var(--warn); }


/* What selling made, period by period. One axis, so a loss hangs below zero
   rather than being drawn as a positive bar in another colour. */
.realised-bars { display: block; max-width: 100%; height: auto; }
.bars-zero { stroke: var(--hairline); stroke-width: 1; }
.rb-up { fill: var(--gain); }
.rb-down { fill: var(--danger); }
.rb-figure { text-anchor: middle; font-size: 11px; font-weight: 700; }
.rb-label { text-anchor: middle; font-size: 10px; fill: var(--muted); }
.rb-warn { text-anchor: middle; font-size: 8.5px; fill: var(--warn); }
.grain-toggle { display: flex; gap: 6px; flex-wrap: wrap; margin: 0 0 var(--space); }
.grain-toggle a { text-decoration: none; font-size: 12.5px; color: var(--muted);
                  padding: 3px 12px; border: 1px solid var(--line);
                  border-radius: var(--radius-sm); }
.grain-toggle a.is-on { color: var(--ink); border-color: var(--ink); font-weight: 600; }


/* The twelve funds on Settings. A list of blocks rather than a table, because
   the table version put the gap, the source, the price and the dealing day off
   the right-hand edge of a phone: every column that does the checking, on the
   screen whose only job is to let it be checked. Blocks stack, so nothing has
   to be scrolled sideways to be read. */
.fundlist { list-style: none; padding: 0; margin: 12px 0 0; }
.fundrow { border: 1px solid var(--line); border-radius: 8px;
           padding: 10px 12px; margin-bottom: 8px; }
.fundrow-head { display: flex; flex-wrap: wrap; gap: 8px;
                align-items: baseline; justify-content: space-between; }
.fundrow-tags { display: flex; flex-wrap: wrap; gap: 4px; }
.fundrow-name { margin-top: 2px; }
.fundrow-ids { font-size: 12px; margin-top: 2px;
               font-variant-numeric: tabular-nums; word-break: break-word; }
/* Label and value side by side and wrapping, rather than a grid with a fixed
   first column: "vs your statement" is long and must not squeeze the number. */
.fundrow-facts { display: grid; grid-template-columns: auto 1fr;
                 gap: 2px 10px; margin: 8px 0 0; }
.fundrow-facts dt { color: var(--muted); font-size: 12px; }
.fundrow-facts dd { margin: 0; font-variant-numeric: tabular-nums; }
.fundrow-error { font-size: 12px; margin-top: 8px; word-break: break-word; }
/* A fund nothing has reached yet is not an error, and must not be painted as
   one: four of these have always been hand-priced and that is the honest
   state for them, not a failure. */
.fundrow.state-broken { border-color: var(--warn); }
@media (min-width: 700px) {
  .fundrow-facts { grid-template-columns: auto 1fr auto 1fr auto 1fr; }
}

/* The screening headline. Large enough to answer "do I read this" from across
   the room, which is the whole reason it exists. Asked for as a score out of a
   hundred; built as a verdict and a count, because a total lets a good mark
   cancel a disqualifying one. */
.screen-headline { font-size: 1.6rem; margin: 0 0 .2rem; }
.screen-subhead { margin: 0 0 .6rem; font-size: 1rem; }

/* --- totals, parts and memos -------------------------------------------
   Every list of figures on this application used one row style for three
   different kinds of row, and the owner found it: a total, the parts that make
   it, and a figure belonging to no sum at all were indistinguishable. Worse,
   two parts on the dashboard added to a total that appeared only in the prose
   above them, so the eye attached them to the total that WAS visible, which was
   the wrong one.

   Three styles, used on every tab, with the structural rules in the tests:

   .led-total  a total that HEADS its parts. Splitting a known number up.
   .led-sum    a total that CLOSES its parts, with a rule above it. Adding up to
               an answer. The two directions are genuinely different questions
               and marking which is which is most of the clarity.
   .led-part   a component. Indented and muted, so it cannot read as a peer.
   .led-memo   a figure in no sum: an alternative measure, a rate, an input. Set
               apart, because inside a group it reads as an addend.            */

.pairs dt.led-total, .pairs dd.led-total,
.hero-side dt.led-total, .hero-side dd.led-total { font-weight: 600; color: var(--ink); }

.pairs dt.led-sum, .pairs dd.led-sum,
.hero-side dt.led-sum, .hero-side dd.led-sum {
  font-weight: 600; color: var(--ink);
  border-top: 1px solid var(--line); padding-top: .4rem; margin-top: .15rem;
}

.pairs dt.led-part, .hero-side dt.led-part { padding-inline-start: 1.1rem; }

/* A memo is pushed away from the group above it. Both cells move together or
   the row breaks in half, which on a phone is worse than no gap at all. */
.pairs dt.led-memo, .pairs dd.led-memo,
.hero-side dt.led-memo, .hero-side dd.led-memo {
  margin-top: .7rem; opacity: .85;
}
/* The label leans, the figure does not: an italic number is harder to read and
   these are the two halves of one row. */
.pairs dt.led-memo, .hero-side dt.led-memo { font-style: italic; }

/* The note under the hero breakdown. Sits inside the hero's own column so it
   wraps against the figures rather than the page. */
.hero-note { font-size: .8rem; margin: .7rem 0 0; }

/* The riyal amounts under a gauge. Deliberately quieter than the percentage:
   the percentage answers whether he is off target, this answers by how much,
   and he asked for it small. */
.health-money { margin: .15rem 0 0; font-size: .78rem; color: var(--muted);
  font-variant-numeric: tabular-nums; }

/* The index counterfactual. A full line, unlike the measured value, because
   every point on it is a real deposit priced at a real close. Drawn beneath the
   capital line in weight so it reads as a reference rather than a claim. */
/* In the second series colour, not the first. Both lines on this chart were
   drawn in the same green: --series-1 and the old --accent held the same
   value, so a comparison whose entire point is two lines was two lines of one
   colour, told apart by weight alone. */
.journey-index { fill: none; stroke: var(--series-2); stroke-width: 1.6;
  stroke-linejoin: round; opacity: .75; }
.journey-key-index { fill: var(--series-2); }

/* An account's whole result, above its holdings on the Positions page. Bigger
   than a row and smaller than a hero: it is the first thing read in the group
   and the rows under it are the detail. */
.group-result { margin: -4px 0 12px; font-size: 15px; }
.group-result strong { font-variant-numeric: tabular-nums; }
.group-result > .muted { display: block; font-size: 12px; font-weight: 400; }

/* The x on a warning that can be put away. Top right of its card, small
   enough not to compete with the warning and large enough to hit on a phone. */
.card-dismiss { float: inline-end; margin: -4px -4px 0 8px; }
.card-dismiss button {
  background: none; border: 0; color: var(--muted); cursor: pointer;
  font-size: 22px; line-height: 1; padding: 4px 8px; min-width: 32px;
}
.card-dismiss button:hover { color: var(--ink); }


/* --- the wallet ---------------------------------------------------------
   One card carrying the whole portfolio: what it is worth, what it has made,
   what it did today, with the accounts themselves a press inside it. Asked
   for on 22 September 2026 against his broker's own card, which puts the day
   and the result side by side rather than a screen apart. */
.wallet-today {
  display: grid; grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: .1rem 1.2rem; margin: .95rem 0 .2rem;
}
.wallet-today dt {
  grid-row: 1; margin: 0; color: var(--muted); font-size: .82rem;
  text-transform: none; letter-spacing: 0; font-weight: 500;
}
.wallet-today dd {
  grid-row: 2; margin: 0; font-size: 1.02rem; font-weight: 600;
  font-variant-numeric: tabular-nums; white-space: nowrap;
}
.wallet-today dd .unit { font-size: .78rem; font-weight: 400; color: var(--muted); }
.wallet-today dt:nth-of-type(1), .wallet-today dd:nth-of-type(1) { grid-column: 1; }
.wallet-today dt:nth-of-type(2), .wallet-today dd:nth-of-type(2) { grid-column: 2; }
.wallet-today dd.muted { font-size: .82rem; font-weight: 400; }
.wallet-pct { font-size: .82rem; font-weight: 600; }

/* A fold on a card, which had no styling at all and rendered as a bare
   browser triangle. The accounts and the breakdown both use it, so they open
   the same way. Full width inside the hero's two columns: side by side they
   read as two halves of one thing, which they are not. */
/* min-width: 0, or the table inside pushes the whole grid wider than the
   phone and the figures in the column beside it leave the screen. A grid item
   is auto-sized to its content unless told otherwise, and .scroll-x cannot
   scroll what it was never allowed to clip. */
.hero > details.fold { grid-column: 1 / -1; min-width: 0; }
.hero > * { min-width: 0; }
details.fold { border-top: 1px solid var(--hairline); padding-top: .7rem; }
details.fold > summary {
  cursor: pointer; list-style: none; display: flex; align-items: center;
  gap: .45rem; font-size: .92rem; font-weight: 700; color: var(--ink);
  padding: .15rem 0; outline-offset: 3px;
}
details.fold > summary::-webkit-details-marker { display: none; }
details.fold > summary::before {
  content: ""; width: 7px; height: 7px; flex: 0 0 auto;
  border-inline-end: 2px solid currentColor; border-block-end: 2px solid currentColor;
  transform: rotate(45deg) translate(-1px, -1px);
  transition: transform .15s ease;
}
details.fold[open] > summary::before { transform: rotate(-135deg) translate(-2px, -2px); }
details.fold > summary:hover { color: var(--ink); }
details.fold details.fold { border-top: 0; padding-top: .3rem; }
.wallet-accounts { list-style: none; margin: .5rem 0 0; padding: 0; }
.wallet-accounts > li { padding: .65rem 0; border-top: 1px solid var(--hairline); }
.wallet-accounts > li:first-child { border-top: 0; }
.wa-head { display: flex; justify-content: space-between; align-items: baseline; gap: .6rem; }
.wa-worth { font-variant-numeric: tabular-nums; font-weight: 600; white-space: nowrap; }
.wa-worth .unit { font-size: .78rem; font-weight: 400; color: var(--muted); }
.wa-figs { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: .05rem .9rem; margin: .35rem 0 0; }
.wa-figs dt { grid-row: 1; color: var(--muted); font-size: .8rem;
  text-transform: none; letter-spacing: 0; }
.wa-figs dd { grid-row: 2; margin: 0; font-size: .92rem; font-weight: 600;
  font-variant-numeric: tabular-nums; }
.wa-figs dt:nth-of-type(1), .wa-figs dd:nth-of-type(1) { grid-column: 1; }
.wa-figs dt:nth-of-type(2), .wa-figs dd:nth-of-type(2) { grid-column: 2; }
.wa-figs dd.muted { font-size: .78rem; font-weight: 400; }
.wa-pct { font-size: .78rem; font-weight: 600; }
.wa-note { margin: .35rem 0 0; font-size: .75rem; }
.wa-base { display: block; font-size: .72rem; font-weight: 400; }


/* --- the wallet panel ---------------------------------------------------
   Asked for on 22 September 2026: make it look like the card he reads every
   day in Saham, because that is the one he is used to. So the figures he opens
   on sit on a filled green panel in white, and the supporting ledger and the
   two folds sit below it on the card's own surface, the way his broker puts
   the numbers on colour and the detail underneath.

   Green is the gain colour this application already uses, not a second green:
   a card whose panel and whose rising figures disagreed about which green
   means up would be two names for one thing. */
.wallet {
  /* Investing.com's look (prototype, 12 October 2026): a dark card in both
     themes, lit from its top corner by Investing's green, which is now the
     accent rather than the slab. */
  --panel:
    radial-gradient(130% 85% at 100% 0%, rgba(108, 197, 81, .30) 0%, rgba(108, 197, 81, 0) 60%),
    radial-gradient(90% 70% at 0% 100%, rgba(108, 197, 81, .10) 0%, rgba(108, 197, 81, 0) 70%),
    linear-gradient(165deg, #20252c 0%, #14171c 100%);
  --panel-ink: #ffffff;
  --panel-muted: #b4bac2;
  --panel-line: rgba(255, 255, 255, .10);
  /* On the dark card a rise reads in Investing's green and a fall in a
     light red. */
  --panel-up: #7ad35f;
  --panel-down: #ff8a80;
  --panel-gain-gold: #ffc4b8;    /* the light gold a loss was drawn in until then */
  /* Bright red, back from five reds pictured on his records on 2 October
     2026: "The last red in the bottom". Unrealised P/L's own red and a fifth
     darker had both been tried that day and were hard to see on the green. */
  --panel-loss-red: #ff6b6b;
  /* The profit target's own violet (19 October 2026, "Purple"): orange on
     the card is money ready to move, so the target is told apart from it. */
  --panel-goal: #b49cff;
  padding-top: 0;
  overflow: hidden;
  /* One column at every width. The panel bleeds to the card's edges, and a
     bleeding panel occupying one half of a two-column grid reads as a stripe
     down the side rather than as a wallet. */
  grid-template-columns: 1fr;
  gap: .9rem;
}
.wallet > .hero-main {
  background: var(--panel); color: var(--panel-ink);
  /* Tightened on 15 October 2026: "I believe there are spaces that
     couldn't be squeezed". */
  margin: 0 -1.05rem; padding: .8rem 1.15rem .95rem;
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, .06), inset 0 -2px 0 rgba(108, 197, 81, .55);
}
.wallet > .hero-main .hero-label,
.wallet > .hero-main .muted,
.wallet > .hero-main .hero-unit,
.wallet > .hero-main .unit,
.wallet > .hero-main .wallet-today dt { color: var(--panel-muted); }
.wallet > .hero-main .hero-number,
.wallet > .hero-main .hero-pct,
.wallet > .hero-main .wallet-today dd { color: var(--panel-ink); }
.wallet > .hero-main .up { color: var(--panel-up); }
.wallet > .hero-main .down { color: var(--panel-down); }
/* Total P/L: light gold above his capital, bright red below. Chosen by him
   on 1 October 2026 ("Bright red"), then, pointing at the colour a loss had
   been drawn in: "Make this color for when it's gain". */
.wallet > .hero-main .wallet-total-pl .fig.up,
.wallet > .hero-main .wallet-total-pl .fig.up .wallet-pct { color: var(--panel-gain-gold); }
.wallet > .hero-main .wallet-total-pl .fig.down,
.wallet > .hero-main .wallet-total-pl .fig.down .wallet-pct { color: var(--panel-loss-red); }
.wallet > .hero-main .wallet-today { border-top: 1px solid var(--panel-line); padding-top: .8rem; }
.wallet > .hero-main strong { color: inherit; }
/* The i keeps working on colour: its ring and letter are drawn from the text
   colour around it, which is now white. */
.wallet > .hero-main .why-drop > summary { border-color: var(--panel-line); color: var(--panel-muted); }
.wallet > .hero-main .why-drop > summary:hover,
.wallet > .hero-main .why-drop[open] > summary { border-color: var(--panel-ink); color: var(--panel-ink); }
.wallet > .hero-side { padding-top: 0; border-top: 0; }
/* The ledger and the folds keep the card's own surface, so the panel is the
   thing that is coloured and not the whole card. */
.wallet > details.fold { border-top: 1px solid var(--hairline); padding-top: .7rem; }

@media (min-width: 44rem) {
  /* Overrides the .hero rule above, which puts the ledger in a second column.
     The panel is full width at every size. */
  .wallet { grid-template-columns: 1fr; }
  .wallet > .hero-side { border-inline-start: 0; padding-inline-start: 0; }
}

@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .wallet {
    --panel:
      radial-gradient(130% 85% at 100% 0%, rgba(108, 197, 81, .26) 0%, rgba(108, 197, 81, 0) 60%),
      radial-gradient(90% 70% at 0% 100%, rgba(108, 197, 81, .08) 0%, rgba(108, 197, 81, 0) 70%),
      linear-gradient(165deg, #232830 0%, #191c21 100%);
  }
}
:root[data-theme="dark"] .wallet {
  --panel:
    radial-gradient(130% 85% at 100% 0%, rgba(108, 197, 81, .26) 0%, rgba(108, 197, 81, 0) 60%),
    radial-gradient(90% 70% at 0% 100%, rgba(108, 197, 81, .08) 0%, rgba(108, 197, 81, 0) 70%),
    linear-gradient(165deg, #232830 0%, #191c21 100%);
}
/* The headline on the panel is white when it is a gain, not green on green:
   the panel already carries that. A loss stays red, because the one thing the
   colour has to survive is telling him which way the figure went. */
.wallet > .hero-main .hero-number.up,
.wallet > .hero-main .hero-pct .up { color: var(--panel-ink); }
/* The percentage under the amount, not beside it: at phone width the two ran
   off the right edge of the panel together. */
.wallet-today .wallet-pct { display: block; font-size: .8rem; }


/* --- page to page, without the blank flash --------------------------------
   Asked for on 22 September 2026: "seamless ... between tabs". Once a tab
   arrived in a tenth of a second, what was left was the moment between two
   pages, which a phone paints white. A cross-document view transition keeps
   the old page on screen until the new one is ready and swaps them in 80 ms.
   The bar at the bottom and the bar at the top are named so they stay put
   rather than fading with everything else: they are the same bars on both
   pages, and a bar that blinks on every tap reads as a page that reloaded.

   A phone that does not support this ignores all of it and changes page the
   way it always did. Anyone who has asked their phone for less motion gets
   none. */
@view-transition { navigation: auto; }
.tabbar { view-transition-name: tabbar; }
.topbar { view-transition-name: topbar; }
::view-transition-old(root),
::view-transition-new(root) { animation-duration: 80ms; }
@media (prefers-reduced-motion: reduce) {
  @view-transition { navigation: none; }
}

/* Positions: a heading that sorts the rows by its column, like the arrows on
   Saham's holdings list. Faint arrows on every sortable heading say it can be
   tapped; the one in use shows which way round, in the accent colour. */
.sort-by {
  background: none; border: 0; padding: 2px 0; margin: 0; font: inherit;
  color: inherit; cursor: pointer; white-space: nowrap; min-height: 28px;
}
.sort-by::after { content: " \2195"; opacity: .45; font-size: .9em; }
.sort-by.is-desc, .sort-by.is-asc { color: var(--accent); }
.sort-by.is-desc::after { content: " \2193"; opacity: 1; }
.sort-by.is-asc::after { content: " \2191"; opacity: 1; }
th .sort-by + br + .sort-by { font-weight: 500; font-size: .92em; }

/* The live mark, beside a platform on Positions and on the Dashboard's
   wallet. Green naming the session when every price is as current as the
   market allows; red counting the ones that are not. The dot pulses only
   while a session is running, because a pulse is a claim that things move. */
.feed {
  display: inline-flex; align-items: center; gap: .35em; vertical-align: middle;
  font-size: 10.5px; font-weight: 700; letter-spacing: .04em; text-transform: uppercase;
  padding: 3px 9px; border-radius: 6px; border: 1px solid transparent;
  background: color-mix(in srgb, currentColor 16%, transparent);
  white-space: nowrap;
}
.feed.is-current { color: var(--ok); }
.feed.is-pre { color: var(--session-pre); }
.feed.is-after { color: var(--session-after); }
.feed.is-night { color: var(--session-night); }
.feed.is-closed { color: var(--muted); }
.feed.is-behind { color: var(--danger); }
.feed-dot { width: 7px; height: 7px; border-radius: 50%; background: currentColor; }
svg.feed-icon { width: 11px; height: 11px; fill: currentColor; }
.feed.is-current.is-trading .feed-icon { animation: feed-pulse 2s ease-in-out infinite; }
@keyframes feed-pulse { 50% { opacity: .3; } }
@media (prefers-reduced-motion: reduce) {
  .feed.is-current.is-trading .feed-icon { animation: none; }
}
strong.not-updated { color: var(--danger); }
/* 🛒 buying power and 🔒 or 💸 profit under Cash (15 October 2026): two
   small chips, one tap to the split by account. */
.bp > summary.bp-chips, .wallet-chips > p.bp-chips { display: flex; justify-content: flex-end;
  flex-wrap: wrap; gap: .3rem; margin: .45rem 0 0; }
.bp-chip { display: inline-block; padding: .14rem .45rem; border-radius: 999px; font-size: .74rem;
  font-weight: 700; white-space: nowrap; text-decoration: none; font-variant-numeric: tabular-nums; }
.bp-buy { background: color-mix(in srgb, var(--gain) 16%, transparent); color: var(--gain); }
.bp-lock { background: color-mix(in srgb, var(--muted) 16%, transparent); color: var(--muted); }
.bp-out, a.bp-out:hover { background: color-mix(in srgb, var(--warn-fill) 18%, transparent);
  color: var(--warn); }
.wallet > .hero-main .bp-chips .bp-buy { background: rgba(122, 211, 95, .16); color: var(--panel-up); }
.wallet > .hero-main .bp-chips .bp-lock { background: rgba(255, 255, 255, .08); color: var(--panel-muted); }
.wallet > .hero-main .bp-chips .bp-out { color: var(--warn-fill); }
.bp-rows li { display: flex; justify-content: space-between; align-items: center; gap: .6rem;
  padding: .65rem 0; border-bottom: 1px solid var(--hairline); }
.bp-rows li:last-child { border-bottom: 0; }
.bp-pair { display: inline-flex; gap: .3rem; }
.bp-riyal svg.riyal { display: inline-block; width: .72em; height: .72em; fill: currentColor; vertical-align: -.02em;
  margin-inline-end: .12em; }
.bp-line { display: flex; flex-wrap: wrap; gap: .35rem; margin: .1rem 0 .6rem; }
/* trade.js hides the line on a sale and the warning until an order passes the
   buying power; their own display would otherwise show them (18 October 2026). */
.bp-line[hidden], .bp-line .bp-chip[hidden] { display: none; }
.bp-short { background: color-mix(in srgb, var(--danger) 16%, transparent); color: var(--danger); }
.btn-small.bp-max { float: inline-end; margin: 0; background: color-mix(in srgb, var(--gain) 16%, transparent); color: var(--gain); font-weight: 600; }
.btn-small.bp-max[hidden], .bp-left[hidden] { display: none; }
.bp-left { display: block; font-size: .74rem; color: var(--muted); margin-top: .25rem; }
/* The month's profit target under Cash (19 October 2026): made against a
   share of the pot's ceiling, amount and %; violet while short, green met:
   "I just don't want to confuse it with something else and it's under the
   available cash" (19 October 2026, then "Purple"). */
.pt > summary.pt-line { display: flex; justify-content: flex-end; margin-top: .2rem; list-style: none; cursor: pointer; }
.pt > summary.pt-line::-webkit-details-marker { display: none; }
.pt-chip {
  --pt-fill: 0%;
  display: inline-flex; align-items: center; gap: .25rem; padding: .14rem .5rem; border-radius: 999px;
  font-size: .74rem; font-weight: 700; white-space: nowrap; font-variant-numeric: tabular-nums;
  background: color-mix(in srgb, var(--vs-line) 16%, transparent); color: var(--vs-line); }
.pt-chip.met { background: color-mix(in srgb, var(--gain) 16%, transparent); color: var(--gain); }
/* The chip is its own bar: the target, and how much of it is filled (27
   October 2026: "you could show what target and percentage of it filled and
   fill that shape with percentage I achieved"). */
.wallet > .hero-main .pt-chip { color: #ece6ff; background: linear-gradient(90deg,
  color-mix(in srgb, var(--panel-goal) 62%, transparent) var(--pt-fill, 0%),
  color-mix(in srgb, var(--panel-goal) 16%, transparent) var(--pt-fill, 0%)); }
.wallet > .hero-main .pt-chip.met { background: rgba(122, 211, 95, .5); color: #f2fff0; }
.pt-chip svg.ic { width: 1em; height: 1em; }
/* Over What selling has made since 30 October 2026: the same filled bar. */
#selling-card .pt > summary.pt-line { justify-content: flex-start; margin: .1rem 0 .45rem; }
#selling-card .pt-chip { background: linear-gradient(90deg,
  color-mix(in srgb, var(--vs-line) 45%, transparent) var(--pt-fill, 0%),
  color-mix(in srgb, var(--vs-line) 14%, transparent) var(--pt-fill, 0%)); }
#selling-card .pt-chip.met { background: color-mix(in srgb, var(--gain) 22%, transparent); }
/* Under Cash, three tiles left to right (30 October 2026): In TBIL, Profit,
   To trade; dark grey while empty, each its colour once it holds money. */
.ms { margin-top: .5rem; }
.ms > summary.ms-row { display: grid; grid-template-columns: repeat(3, 1fr); gap: .35rem; list-style: none; cursor: pointer; }
.ms > summary.ms-row::-webkit-details-marker { display: none; }
.ms-t { display: flex; flex-direction: column; align-items: center; justify-content: center; min-width: 0;
  padding: .18rem .3rem; border-radius: 8px; line-height: 1.15; text-align: center;
  background: rgba(255, 255, 255, .05); color: #a3a9b1; }
.ms-t small { font-size: .62rem; white-space: nowrap; display: inline-flex; align-items: center; gap: .2rem; opacity: .85; }
.ms-t small svg.ic { width: 11px; height: 11px; }
.ms-t b { font-size: .8rem; font-weight: 600; white-space: nowrap; font-variant-numeric: tabular-nums; }
.ms-t em { font-style: normal; font-size: .58rem; white-space: nowrap; opacity: .8; }
.ms-t.ms-bill.on { background: rgba(90, 156, 248, .16); color: #5a9cf8; }
.ms-t.ms-profit.on { background: rgba(245, 158, 11, .15); color: var(--warn-fill); }
.ms-t.ms-trade.on { background: rgba(122, 211, 95, .16); color: var(--panel-up); box-shadow: inset 0 0 0 1px rgba(122, 211, 95, .4); }
.ms .sheet-panel { text-align: start; }
.ms-h { display: flex; align-items: center; gap: .35rem; font-size: .8rem; margin: .7rem 0 .15rem; }
.ms-h svg.ic { width: 14px; height: 14px; }
.ms-h.ms-bill { color: var(--accent-text); }
.ms-h.ms-profit { color: var(--warn); }
.ms-h.ms-trade { color: var(--gain); }
.ms-rows { list-style: none; margin: 0; padding: 0; }
.ms-rows li { border-bottom: 1px solid var(--line); font-size: .84rem; }
.ms-rows li.muted { padding: .45rem 0; color: var(--muted); }
.ms-rows a { display: flex; align-items: center; gap: .5rem; padding: .42rem 0; color: inherit; text-decoration: none; }
.ms-nm { display: flex; align-items: center; gap: .45rem; flex: 1; min-width: 0; }
.ms-nm small, .ms-amt small { display: block; font-size: .7rem; color: var(--muted); }
.ms-amt { text-align: end; white-space: nowrap; font-variant-numeric: tabular-nums; }
.ms-amt b { font-weight: 600; }
.ms-rows li.ms-act { display: flex; justify-content: flex-end; }
.ms-rows li.ms-act a { padding: .1rem .55rem; margin: .3rem 0 .4rem; border-radius: 999px; font-size: .76rem; font-weight: 600;
  background: color-mix(in srgb, var(--accent-text) 14%, transparent); color: var(--accent-text); gap: .25rem; }
.ms-rows li.ms-act svg.ic { width: 13px; height: 13px; }
.pt .sheet-panel { text-align: start; }
.pp-pill.pt-now { background: color-mix(in srgb, var(--accent-text) 14%, transparent); color: var(--accent-text); }
.pt-bar { position: relative; height: 12px; border-radius: 999px; background: var(--raised); margin: .7rem 0 .25rem; overflow: hidden; }
.pt-bar i { position: absolute; inset: 0 auto 0 0; border-radius: 999px; background: var(--accent-text); }
.pt-bar.met i { background: var(--gain); }
.pt-scale { display: flex; justify-content: space-between; margin-bottom: .6rem; font-size: .72rem; color: var(--muted); }
.pt-months { display: grid; grid-template-columns: repeat(6, 1fr); gap: .4rem; align-items: end; height: 8.1rem; margin: .5rem 0 .2rem; }
.pt-months em { position: absolute; left: 50%; transform: translateX(-50%); font-style: normal;
  font-size: .68rem; font-weight: 700; color: var(--ink); font-variant-numeric: tabular-nums; white-space: nowrap; }
.pt-months em.down { color: var(--danger); }
.pt-year { display: flex; justify-content: space-between; align-items: baseline; margin: .9rem 0 0;
  font-size: .82rem; color: var(--muted); }
.pt-year span { font-size: .82rem; }
.pt-year strong { font-size: 1rem; color: var(--ink); font-variant-numeric: tabular-nums; }
.pt-months div { position: relative; display: flex; flex-direction: column; justify-content: flex-end; align-items: center; height: 100%; gap: .2rem; }
.pt-months span { width: 72%; border-radius: 4px 4px 0 0; background: var(--gain); }
.pt-months span.miss { background: var(--warn-fill); }
.pt-months span.now { background: var(--accent-text); }
.pt-months b { position: absolute; left: 6%; right: 6%; border-top: 2px dashed var(--ink); }
.pt-months small { font-size: .7rem; color: var(--muted); }
.pt-key { font-size: .72rem; color: var(--muted); margin: .1rem 0 .6rem; }
/* When News was last read, under its title (19 October 2026). */
.news-updated { margin: -.4rem 0 .7rem; font-size: .78rem; }
/* An account's name in the cash pop-up stays on one line ("Saham App"). */
.bp-rows li > span:first-child { white-space: nowrap; }

/* Withdraw's From, an account a pill, on one line however long its name;
   the date box held inside its column (iOS gives it a width of its own). */
.mv-choice legend { padding: 0; }
.mv-choice.mv-from { gap: .4rem; }
/* Nothing in a pop-up is wider than the phone (19 October 2026, the
   Withdraw panel slid half off his screen: "this shall not happen again with
   any future features"). An iPhone gives a date box a width of its own, wider
   than its column, and a panel that could scroll sideways scrolled to it. So
   every date, select and box may shrink to its column, and no panel scrolls
   sideways; tests/test_nothing_runs_off_a_phone.py opens every pop-up. */
input[type=date], input[type=time], input[type=datetime-local] { min-width: 0; max-width: 100%;
  -webkit-appearance: none; appearance: none; text-align: left; }
input[type=date]::-webkit-date-and-time-value { text-align: left; }
input:not([type=checkbox]):not([type=radio]), select, textarea { min-width: 0; max-width: 100%; }
/* Performance, 19 October 2026 ("Go" to the pictures): Compare in Result,
   the calendar and Where it came from as pop-ups from two tiles under it,
   and an account's holdings as pills, one at a time. */
.pf-cmp { align-items: center; margin: .7rem 0 0; flex-wrap: nowrap; }
.pf-cmp > span { font-size: .8rem; color: var(--muted); margin-right: .2rem; white-space: nowrap; }
.pf-cmp a { white-space: nowrap; }
.pf-cmp a.vs.on { color: var(--vs-line); background: color-mix(in srgb, var(--vs-line) 16%, transparent); }
.pf-links { display: grid; grid-template-columns: 1fr 1fr; gap: .6rem; margin-top: .9rem; }
.pf-links a { display: block; min-width: 0; background: var(--raised); border-radius: 14px;
  padding: .7rem .85rem; color: var(--ink); text-decoration: none; }
.pf-links span { display: block; font-size: .8rem; color: var(--muted); white-space: nowrap; }
.pf-links strong { display: block; margin-top: .15rem; font-size: .98rem; white-space: nowrap;
  overflow: hidden; text-overflow: ellipsis; font-variant-numeric: tabular-nums; }
.pf-links strong.up { color: var(--gain); } .pf-links strong.down { color: var(--danger); }
.pf-links small { display: block; font-size: .76rem; color: var(--muted); }
.perf-pop .sheet-panel { max-height: 86vh; }
.perf-pop #calendar h2, .perf-pop #where-from h2 { margin-top: 0; }
.pf-hold { margin: 0 0 .8rem; }
.pf-tiles { display: grid; grid-template-columns: 1fr 1fr; gap: .5rem; margin: .5rem 0 .8rem; }
.pf-tiles > div { background: var(--raised); border-radius: 12px; padding: .55rem .7rem; min-width: 0; }
.pf-tiles small { display: block; font-size: .74rem; color: var(--muted); }
.pf-tiles b { font-variant-numeric: tabular-nums; }
.pf-tiles b.up { color: var(--gain); } .pf-tiles b.down { color: var(--danger); }
/* Each account's own logo beside its name (19 October 2026), a small
   rounded tile on the text's line. */
.acct-logo { display: inline-block; vertical-align: -.28em; border-radius: 22%; margin-right: .45em;
  flex: none; }
.acct-name, a.acct-open { white-space: nowrap; }
.mv-choice.mv-from label { flex: 1 1 0; }
.mv-choice.mv-from span { display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: .3rem; padding: .55rem .25rem; border-radius: 14px; font-size: .76rem; line-height: 1.15;
  white-space: normal; text-align: center; }
.mv-from .acct-logo { margin: 0; }
/* An account named anywhere wears its logo (27 October 2026), kept on one
   line with its name: the |account filter. */
.acct-n { white-space: nowrap; }
.acct-n .acct-logo { margin-right: .3em; }
/* Undo last step on Money on the move (20 October 2026: "Create undo
   option"): small and quiet under an order, never the main button. */
.sheet-panel .mv-undo { margin: .5rem 0 0; text-align: right; }
.sheet-panel .mv-undo button { width: auto; min-height: 0; height: auto; margin: 0;
  padding: .32rem .8rem; border-radius: 999px; font-size: .8rem; font-weight: 600;
  background: none; color: var(--muted); border: 1px solid var(--line); box-shadow: none; }
.sheet-panel .mv-undo-no { margin: .4rem 0 0; text-align: right; font-size: .75rem; color: var(--muted); }

/* Market (20 October 2026): the mood on the Dashboard's market line, its
   pop-up, and the page with the S&P 500's heat map. */
.mood-chip { display: inline-flex; align-items: center; gap: .2rem; margin-left: auto;
  padding: .05rem .5rem; border-radius: 999px; font-weight: 700; color: var(--muted);
  background: var(--raised); }
/* A mood's band, wherever a mood is printed: the chip, the word, the
   tiles, the parts, the trend (market_mood.band). */
.m-xfear { color: var(--mood-xfear); }
.m-fear { color: var(--mood-fear); }
.m-neutral { color: var(--mood-neutral); }
.m-greed { color: var(--mood-greed); }
.m-xgreed { color: var(--mood-xgreed); }
.mood-chip[class*="m-"] { background: color-mix(in srgb, currentColor 16%, transparent); }
.mood-chip .ic { width: 14px; height: 14px; }
a.mood-chip, a.mood-chip:hover { text-decoration: none; }
/* At the wallet's top left, the live mark and the eye pushed right. */
.wallet-top .mood-chip { margin-left: 0; margin-right: auto; }
.mood-sub { font-size: .8rem; color: var(--muted); margin: 0 0 .25rem; }
.mood-head { text-align: center; }
.mood-gauge { display: block; margin: 0 auto; max-width: 100%; height: auto; }
.mood-needle { stroke: var(--ink); stroke-width: 3; stroke-linecap: round; }
.mood-hub { fill: var(--ink); }
.mood-n { fill: var(--ink); font-weight: 700; }
.mood-word { font-size: 1.25rem; font-weight: 700; margin: -.2rem 0 .7rem; }

.mood-then { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: .35rem; }
.mood-then div { background: var(--raised); border-radius: 12px; padding: .45rem .2rem; text-align: center; }
.mood-then small { display: block; font-size: .66rem; color: var(--muted); }
.mood-then b { display: block; font-size: 1.15rem; margin: .1rem 0; }
.mood-then i { font-style: normal; font-size: .66rem; color: var(--muted); }
.mood-after { font-size: .78rem; color: var(--muted); margin: .7rem 0 0; }
.breadth { margin: .8rem 0 .2rem; }
.breadth-n { display: flex; justify-content: space-between; gap: .5rem; font-size: .82rem; font-weight: 600; margin-bottom: .3rem; }
.breadth-n span { display: inline-flex; align-items: center; gap: .2rem; color: var(--muted); }
.breadth-n .up { color: var(--gain); } .breadth-n .down { color: var(--danger); }
.breadth-n .ic { width: 14px; height: 14px; }
.breadth-bar { display: flex; height: 8px; border-radius: 999px; overflow: hidden; background: var(--raised); }
.breadth-bar .b-up { background: var(--gain); } .breadth-bar .b-down { background: var(--danger); }
.breadth-bar .b-flat { background: var(--mood-neutral); }
.mood-card .periods { margin: .9rem 0 .4rem; }
.mood-trend { display: block; width: 100%; height: auto; }
.mood-line { fill: none; stroke: currentColor; stroke-width: 1.8; stroke-linejoin: round; }
.mood-dot { fill: currentColor; }
/* The pop-up's trend, read as CNN's page reads it: the score large, the
   points since the day before and the day beside it, the word a pill. */
.mood-pop { margin: .8rem 0 .2rem; }
.mood-read { display: flex; align-items: center; gap: .6rem; margin-bottom: .2rem; }
.mood-read > b { font-size: 2.4rem; font-weight: 700; line-height: 1; font-variant-numeric: tabular-nums; min-width: 2.6ch; }
.mood-read-mid { display: flex; flex-direction: column; font-size: .85rem; }
.mood-read-mid small { color: var(--muted); font-size: .8rem; }
.mood-read-mid .up { color: var(--gain); } .mood-read-mid .down { color: var(--danger); }
.mood-pill { margin-left: auto; font-style: normal; font-weight: 600; font-size: .85rem;
  border-radius: 999px; padding: .2rem .7rem; white-space: nowrap; }
.mood-pill.m-xfear { background: var(--mood-xfear); } .mood-pill.m-fear { background: var(--mood-fear); }
.mood-pill.m-neutral { background: var(--mood-neutral); } .mood-pill.m-greed { background: var(--mood-greed); }
.mood-pill.m-xgreed { background: var(--mood-xgreed); }
.mood-pill[class*="m-"] { color: #111; }
/* The header carries the reading, so the chart keeps only its line and dot. */
.mood-pop .journey-cross-box, .mood-pop .journey-cross-amount,
.mood-pop .journey-cross-datebox, .mood-pop .journey-cross-date, .mood-pop .journey-cross-h { display: none; }
.mood-tick { fill: var(--muted); font-size: 9px; }
.mood-parts { list-style: none; margin: 0; padding: 0; font-size: .9rem; }
.mood-parts li { display: flex; justify-content: space-between; gap: .6rem; padding: .45rem 0; border-top: 1px solid var(--line); }
.mood-parts li:first-child { border-top: 0; }
.mood-parts small { display: block; font-size: .72rem; color: var(--muted); }
.heat-pills { margin: .7rem 0 .5rem; }
.breadth-of { font-size: .72rem; color: var(--muted); margin: .3rem 0 0; }
.idx-row { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: .4rem; margin-bottom: .5rem; }
.idx { text-decoration: none; color: inherit; min-width: 0; }
.idx-n { display: flex; align-items: center; gap: .3rem; font-size: .8rem; color: var(--muted); }
.idx-n i { width: 3px; height: .8rem; border-radius: 2px; }
.idx b { display: block; font-size: 1.05rem; margin: .1rem 0; font-variant-numeric: tabular-nums; }
.idx small { display: block; font-size: .72rem; white-space: nowrap; }
.idx small.up { color: var(--gain); } .idx small.down { color: var(--danger); }
.idx-chart { display: block; width: 100%; height: auto; }
.idx-line { fill: none; stroke-width: 1.6; }
.idx-zero { stroke: var(--line); stroke-dasharray: 3 3; }
.heat { display: block; width: 100%; height: auto; border-radius: 10px; }
.heat rect { shape-rendering: crispEdges; }
.heat-t { fill: #fff; text-anchor: middle; font-weight: 600; }
.heat-g { fill: var(--ink); font-size: 11px; }
.heat-band { fill: var(--card); }
.heat-edge { fill: none; stroke: var(--card); stroke-width: 2.5; }
.heat-disc { fill: #fff; }
.heat-key { display: flex; gap: 2px; margin: .5rem 0 .2rem; font-size: .66rem; text-align: center; }
.heat-key span { flex: 1; padding: .15rem 0 .25rem; color: #fff; border-radius: 2px; }
.heat-src { font-size: .72rem; margin: .3rem 0 0; }

/* Every figure on the card opens what it is made of by account, in place
   (15 October 2026); its page is the pop-up's last line. */
.wallet-total .hero-label, .wallet-total .hero-number { display: block; }
.wallet-total-pl > details > summary { display: inline-flex; align-items: baseline; gap: .1rem .45rem;
  flex-wrap: wrap; justify-content: flex-end; }
.split-panel { text-align: start; }
.split-panel .sheet-rows li { display: flex; justify-content: space-between; gap: 1rem; padding: .65rem 0;
  border-bottom: 1px solid var(--hairline); font-size: 1rem; }
.split-panel .sheet-rows li:last-child { border-bottom: 0; }
.split-more { margin: .8rem 0 0; text-align: end; }
.split-more a { font-weight: 600; text-decoration: none; }
.bp-line .bp-chip { font-size: .8rem; }
.bp-rows li > span:nth-child(2) { display: flex; flex-wrap: wrap; justify-content: flex-end; gap: .3rem; }
/* A chip that is a link in the pop-up stays a chip, not a sheet row. */
.bp-rows li a.bp-chip { display: inline-block; padding: .14rem .45rem; border-bottom: 0;
  font-size: .74rem; font-weight: 700; }
.bp-rows li a.bp-lock, .bp-rows li a.bp-lock:hover { color: var(--muted); }
/* The card tightened the same day ("I believe there are spaces that
   couldn't be squeezed"): less room above the live mark, none spare above
   Latest move, and Unrealised P/L's › on its own figure's line. */
.wallet > .wallet-pl { margin-top: -.25rem; padding: 0 0 .85rem; }
/* The › travels with the percentage, so it never sits on a line alone;
   a figure too wide for one line puts both under it. */
.wallet-pl summary { line-height: 1.25; }
.wallet-pl dt { margin-bottom: .1rem; }
.bp .sheet-panel { text-align: start; }
.wallet > .hero-main .feed.is-current { color: var(--panel-up); border-color: transparent; }
.wallet > .hero-main .feed.is-pre { color: var(--session-pre); }
.wallet > .hero-main .feed.is-after { color: var(--session-after-on-dark); }
.wallet > .hero-main .feed.is-night { color: var(--session-night-on-dark); }
.wallet > .hero-main .feed.is-closed { color: #9aa0a8; }
.wallet > .hero-main .feed.is-behind { color: var(--panel-down); }
/* A swipe between tabs (swipe.js): the page follows the finger and the next
   tab's own page comes in beside it, fixed under the top bar and above the
   bar at the bottom, until the lift finishes the slide or springs it back.
   Sideways drags on the page are the finger's; vertical ones scroll as ever,
   and a table that scrolls sideways keeps its own. */
main { touch-action: pan-y pinch-zoom; }
main.swipe-peek { position: fixed; left: 0; right: 0; bottom: 0; margin: 0 auto; z-index: 30;
  overflow: hidden; background: var(--bg); pointer-events: none; will-change: transform; }
/* A sideways swipe is swipe.js's. Without this, Chrome also reads it as
   "go back a page", and the two fight over one finger. */
html, body { overscroll-behavior-x: none; overflow-x: clip; }

.group-day, .group-day.up, .group-day.down { margin: .15rem 0 .5rem; font-size: .9rem;
  color: var(--muted); }
.group-day.up strong { color: var(--gain); }
.group-day.down strong { color: var(--danger); }
/* The card is the green panel alone since 23 September 2026, so the card's
   own padding under it would show as a strip of the other colour. */
.wallet { padding-bottom: 0; }
/* A row whose price is not current names the day it is from, in red. The
   only thing a row says about its price since 23 September 2026. */
.price-day { display: inline; color: var(--danger); font-size: .78rem; font-weight: 600; white-space: nowrap; }

/* The wallet as Saham lays its card out (23 September 2026). Right and left
   are his: the total on the right with its line to the left, the cash under
   it on the right, the market value on the left; beneath the panel, the
   unrealised figure on the right and the day on the left. */
.wallet-top { display: flex; flex-wrap: wrap; justify-content: flex-end; align-items: center; gap: .45rem .6rem; }
.wallet-eye {
  background: none; border: 0; padding: 4px; margin: 0; cursor: pointer;
  color: var(--panel-muted); min-height: 32px; min-width: 32px;
}
.wallet-eye svg { width: 22px; height: 22px; fill: none; stroke: currentColor; stroke-width: 1.8; }
.wallet-worth { display: flex; align-items: flex-end; justify-content: space-between; gap: .8rem;
  margin-top: .4rem; }
.wallet-total { text-align: end; min-width: 0; }
.wallet-total .hero-label { margin: 0; }
.wallet-total .hero-number { margin: .1rem 0 0; }
.hero-number small { display: inline; margin: 0; color: inherit; font-size: .5em; font-weight: 700; }
.wallet-spark .spark { width: 120px; height: 44px; }
.wallet > .hero-main .wallet-spark polyline { stroke: var(--panel-ink); }
.wallet > .hero-main .wallet-spark .muted { color: var(--panel-muted); font-size: .75rem; }
.wallet-split, .wallet-pl {
  display: grid; grid-template-columns: 1fr 1fr; gap: .8rem; margin: .9rem 0 0;
}
.wallet-split { border-top: 1px solid var(--panel-line); padding-top: .8rem; }
.wallet-split dt, .wallet-pl dt { font-size: .85rem; color: var(--muted); }
.wallet > .hero-main .wallet-split dt { color: var(--panel-muted); }
.wallet-split dd, .wallet-pl dd { margin: .2rem 0 0; font-size: 1.12rem; font-weight: 700;
  font-variant-numeric: tabular-nums; }
.wallet-split .at-end, .wallet-pl .at-end { text-align: end; }
.wallet-pl { padding: .9rem 0 1rem; }
.wallet-pl .wallet-pct { font-size: .8rem; font-weight: 600; margin-inline-start: .3rem; }
dd.wallet-note { font-size: .72rem; font-weight: 400; color: var(--muted); }
.wallet > .hero-main dd.wallet-note { color: var(--panel-muted); }
.sheet-panel .wallet-note { font-size: .8rem; color: var(--muted); margin: .6rem 0 0; }
/* The eye: the card's figures blurred, never removed, so the layout does not
   jump when they come back. */
html.hide-figures .wallet .fig { filter: blur(9px); }
.wallet-total .hero-number, .wallet-split dd.fig { white-space: nowrap; }
.wallet-pl .nowrap { white-space: nowrap; }
.wallet-spark { flex: 0 1 120px; min-width: 0; overflow: hidden; }
.wallet-pl dd.fig { font-size: 1rem; }
/* The count beside the live mark, small: most prices are current, and the
   mark says so; this says how many are not. */
.feed-wrap { display: inline-flex; align-items: center; gap: .35rem; vertical-align: middle;
  white-space: nowrap; }
.feed-behind { color: var(--danger); font-size: .72rem; font-weight: 600;
  text-transform: none; letter-spacing: 0; }
.wallet > .hero-main .feed-behind { color: var(--panel-down); }
/* Total P/L, under All assets on the green card (23 September 2026). */
.wallet-total-pl { display: flex; justify-content: flex-end; align-items: baseline;
  flex-wrap: wrap; gap: .1rem .45rem; margin-top: .35rem; font-size: .95rem; }
.wallet-total-pl-label { color: var(--panel-muted); font-size: .8rem; }
.wallet-total-pl .fig { white-space: nowrap; font-variant-numeric: tabular-nums; }
.wallet > .hero-main .wallet-total-pl .wallet-pct { font-size: .8rem; font-weight: 600; }

/* Tapping the Dashboard (23 September 2026): every figure on the card opens
   what it is made of. A tappable figure keeps its own colour; the small ›
   after its label is the only sign, as on Saham's card. */
.wallet-tap, .wallet-tap:hover { color: inherit; text-decoration: none; }
.wallet-tap { display: block; }
.wallet-top .wallet-tap { display: inline-flex; }
.wallet-total-pl > a { display: inline-flex; align-items: baseline; gap: .1rem .45rem; flex-wrap: wrap;
  justify-content: flex-end; }
a.card-link, a.card-link:hover { color: inherit; text-decoration: none; }
a.results-tap, a.results-tap:hover { color: inherit; text-decoration: none; }

/* The slide-up panels under the card. A <details>, so they open with the
   script off; drawer.js adds closing on the backdrop and Escape. */
details.sheet > summary { cursor: pointer; list-style: none; }
details.sheet > summary::-webkit-details-marker { display: none; }
.sheet-scrim { position: fixed; inset: 0; z-index: 41; background: var(--scrim); }
.sheet-panel {
  position: fixed; z-index: 42; left: 0; right: 0; bottom: 0;
  background: var(--card); color: var(--ink); border-radius: 22px 22px 0 0;
  padding: 1rem 1.1rem calc(1.2rem + 58px + env(safe-area-inset-bottom));
  box-shadow: 0 -10px 36px rgba(0, 0, 0, .35); max-height: 70vh; overflow-y: auto;
  overflow-x: hidden;
}
.sheet-head { margin: 0 0 .7rem; font-size: 1.22rem; font-weight: 700; letter-spacing: -.012em;
  text-transform: none; color: var(--ink); }
.sheet-rows { list-style: none; margin: 0; padding: 0; }
.sheet-rows li a, .sheet-rows li .part-row { display: flex; justify-content: space-between; gap: 1rem; padding: .7rem 0;
  border-bottom: 1px solid var(--hairline); color: inherit; text-decoration: none; font-weight: 400;
  font-size: 1rem; }
.sheet-rows li:last-child a, .sheet-rows li:last-child .part-row { border-bottom: 0; }
.sheet-rows li a > span:nth-child(2), .sheet-rows li .part-row > span:nth-child(2) { margin-inline-start: auto; text-align: end; }

/* The status line (_status.html): every note on the main tabs since
   23 September 2026. No box and no tint, so it never reads as a section
   between sections; a dot and the text's colour and weight carry the level,
   and a tap opens the detail. */
.status-line { margin: .3rem 0; font-size: .85rem; }
.status-line > summary { list-style: none; cursor: pointer; display: flex; align-items: baseline;
  gap: .45rem; font-weight: 600; }
.status-line > summary::-webkit-details-marker { display: none; }
.status-dot { flex: 0 0 8px; width: 8px; height: 8px; border-radius: 50%;
  background: currentColor; transform: translateY(-1px); }
.status-more { opacity: .7; }
/* What a line is about (marks.py, 14 October 2026), in place of the dot;
   the words keep their colour for how urgent it is. */
.status-mark { flex: 0 0 1.5rem; height: 1.5rem; display: grid; place-items: center; border-radius: .45rem;
  background: var(--raised); color: var(--muted); font-size: .9rem; line-height: 1; }
.status-line.wrong > summary { color: var(--danger); }
.status-line.warn > summary { color: var(--warn); }
.status-line.note > summary { color: var(--muted); font-weight: 500; }
.status-body { margin: .35rem 0 .6rem 1.2rem; color: var(--ink); font-weight: 400; }
.status-body p { margin: .3rem 0; }
/* Inside the green card. */
.wallet > .hero-main .status-line.wrong > summary { color: var(--panel-down); }
.wallet > .hero-main .status-line.warn > summary { color: #ffe08a; }
.wallet > .hero-main .status-line.note > summary { color: var(--panel-muted); }
.wallet > .hero-main .status-body { color: var(--panel-ink); }
.wallet > .hero-main .status-body ul { padding-inline-start: 1rem; }
.wallet > .hero-main .status-body a,
.wallet > .hero-main .status-body .link-button { color: var(--panel-ink); text-decoration: underline; }
.wallet > .hero-main .status-body .muted { color: var(--panel-muted); }
/* A status line that is a link rather than a fold: a new dividend opens its
   own confirm screen. Same look as .status-line > summary. */
.status-link { display: flex; align-items: baseline; gap: .45rem; margin: .3rem 0;
  font-size: .85rem; font-weight: 600; text-decoration: none; }
.status-link.warn { color: var(--warn); }
.status-link.note { color: var(--muted); }
.wallet > .hero-main .status-link.warn { color: #ffe08a; }
.status-link:hover { text-decoration: none; }
fieldset.choices { border: 0; padding: 0; margin: .8rem 0; }
fieldset.choices legend { font-weight: 600; margin-bottom: .3rem; }
fieldset.choices label.indent { margin-inline-start: 1.6rem; }
/* The slim lines above the Dashboard's card (_card_notes.html). */
.card-notes { margin: 0 0 .6rem; }
/* One line each, however long its words: asked for on 15 October 2026,
   "the dashboard line is long and I want you moving forward making it one
   line max". The words are written to fit a phone; the ellipsis is only the
   backstop, and the tap still opens the whole of it. */
.card-notes .status-link > span:not(.status-mark):not(.status-more),
.card-notes .status-link > a,
.card-notes .status-line > summary .status-text {
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis; min-width: 0; }
.card-notes .status-line > summary, .card-notes .status-link { align-items: center; }
/* Empty while prices arrive; live.js writes "not updating" into it if they stop. */
.card-notes .live-note { margin: 0 0 .2rem; font-size: .8rem; color: var(--warn); }
.card-notes .live-note:empty { display: none; }
.card-note-asof { font-size: .8rem; color: var(--muted); display: flex; align-items: center;
  gap: .35rem; margin: 0 0 .2rem; }

/* Performance, rebuilt 24 September 2026 from the approved picture. */
.perf-big { margin: .2rem 0 0; font-size: 2.1rem; font-weight: 700; font-variant-numeric: tabular-nums; }
.perf-big span { font-size: 1rem; font-weight: 500; }
.perf-sub { margin: .15rem 0 0; font-size: .9rem; }
#result .periods { margin: .8rem 0 .5rem; }
#where-from .part { display: grid; grid-template-columns: 1fr auto; gap: .25rem .6rem; align-items: center;
  padding: .55rem 0; border-bottom: 1px solid var(--line); color: var(--ink); text-decoration: none; }
#where-from .part-note { display: block; font-size: .75rem; font-weight: 400; margin-top: .1rem; }
#where-from .part-fig { font-weight: 600; text-align: right; font-variant-numeric: tabular-nums; }
.part-bar { grid-column: 1 / -1; position: relative; height: 6px; border-radius: 999px; background: var(--raised); }
.part-bar i { position: absolute; top: 0; height: 6px; border-radius: 999px; }
.part-bar i.up { background: var(--gain); }
.part-bar i.down { background: var(--danger); }
.part-total { display: flex; justify-content: space-between; margin: .4rem 0 0; padding-top: .6rem;
  border-top: 2px solid var(--line); font-weight: 700; font-variant-numeric: tabular-nums; }
details.acct { border-bottom: 1px solid var(--line); }
details.acct > summary { display: flex; justify-content: space-between; align-items: baseline; gap: .6rem;
  padding: .65rem 0; cursor: pointer; list-style: none; font-variant-numeric: tabular-nums; }
details.acct > summary::-webkit-details-marker { display: none; }
details.acct > summary:focus, details.acct > summary:active { background: none; outline: none; }
details.acct > summary { -webkit-tap-highlight-color: transparent; }
details.acct > summary .acct-name { font-weight: 600; }
details.acct > summary .acct-name::after { content: " ›"; color: var(--muted); }
details.acct[open] > summary .acct-name::after { content: " ⌄"; }
.acct-open { background: var(--raised); border-radius: 12px; padding: .7rem .8rem; margin: 0 0 .7rem; font-size: .9rem; }
.acct-open p { margin: .2rem 0 .5rem; }
#market table.vs { width: 100%; }
#market table.vs td { padding: .5rem 0; border-bottom: 1px solid var(--line); }
#market table.vs tr:last-child td { border-bottom: 0; }
#market table.vs td.num { text-align: right; font-weight: 600; }
/* On Performance the chart takes its own proportions, not a fixed 260px box
   that left a phone-width chart floating in empty space. */
#result .journey, details.acct .journey { height: auto; }

/* Activity > Fees: a bar per quarter, the figure at the end. */
.fee-q { display: grid; grid-template-columns: 4.6rem 1fr 7.4rem; gap: .6rem; align-items: center;
  padding: .35rem 0; font-size: .92rem; }
.fee-q .num { text-align: right; font-variant-numeric: tabular-nums; white-space: nowrap; }
.fee-bar { position: relative; height: 10px; border-radius: 5px; background: var(--raised); }
.fee-bar i { position: absolute; left: 0; top: 0; bottom: 0; border-radius: 5px; background: var(--danger); opacity: .85; }
.fee-q.gap .fee-bar { background: repeating-linear-gradient(45deg, var(--raised) 0 6px, transparent 6px 12px); }
.fee-q.gap .num { color: var(--muted); }
table.fee-rows { width: 100%; border-collapse: collapse; }
table.fee-rows td { padding: .45rem 0; border-bottom: 1px solid var(--line); }
table.fee-rows td.num { text-align: right; font-variant-numeric: tabular-nums; }

/* From Claude: one proposal per line, ticked unless he unticks it. */
label.proposal { display: grid; grid-template-columns: auto 1fr; gap: .6rem; align-items: start;
  padding: .55rem 0; border-bottom: 1px solid var(--line); font-weight: 400; }
label.proposal:last-of-type { border-bottom: 0; }
label.proposal small { display: block; margin-top: .15rem; }
code.key { word-break: break-all; font-size: .85rem; }

/* Positions: the account's delisted shares, folded under its holdings. */
details.delisted { margin: .7rem 0 0; }
details.delisted > summary { display: flex; align-items: baseline; gap: .45rem; cursor: pointer;
  list-style: none; color: var(--muted); font-size: .86rem; font-weight: 600; }
details.delisted > summary::-webkit-details-marker { display: none; }
details.delisted > summary .status-dot { background: var(--muted); }
details.delisted table { margin-top: .3rem; }
/* A one-time notice: the line opens what it is about, the x closes it for good. */
.status-link.one-time a { color: inherit; text-decoration: none; flex: 1; }
.status-link.one-time .close-notice { color: inherit; font-size: 1.1rem; line-height: 1; padding: 0 .2rem; }

/* Settings, as the picture approved on 24 September 2026: four groups, one
   line each, and each line opens what it holds. */
.set-group { color: var(--muted); font-size: .9rem; font-weight: 600;
  margin: 1.3rem 0 .45rem .2rem; }
.set-card { padding: .35rem 1.1rem; }
.set-row, .set-line { border-bottom: 1px solid var(--line); }
.set-card > :last-child, .set-card form:last-child > :last-child { border-bottom: 0; }
.set-row > summary, .set-line { display: flex; justify-content: space-between;
  align-items: center; gap: .8rem; padding: .72rem 0; font-size: .93rem;
  list-style: none; }
.set-row > summary { cursor: pointer; }
.set-row > summary::-webkit-details-marker { display: none; }
.set-row > summary .set-v::after { content: "›"; color: var(--muted); margin-inline-start: .35rem;
  display: inline-block; transition: transform .15s; }
.set-row[open] > summary .set-v::after { transform: rotate(90deg); }
.set-k { color: var(--ink); min-width: 0; flex: 1; }
.set-k small { display: block; color: var(--muted); font-size: .78rem; margin-top: .15rem; }
.set-k small.amber, .set-hint.amber { color: var(--warn); }
.set-v { color: var(--muted); text-align: end; white-space: nowrap; display: inline-flex;
  align-items: center; gap: .5rem; flex: none; }
.set-clip { max-width: 11rem; overflow: hidden; text-overflow: ellipsis; }
.set-big { font-size: 1.35rem; font-weight: 700; color: var(--ink); }
.set-hint { font-size: .86rem; margin: 0; }
.set-dot { display: inline-block; width: 8px; height: 8px; border-radius: 50%;
  margin-inline-end: .4rem; vertical-align: middle; }
.set-dot.green { background: var(--gain); }
.set-dot.amber { background: var(--warn-fill); }
.set-body { padding: 0 0 .9rem; }
/* Settings > Speed and size: three figures, then his three limits side by side. */
.speed-table { width: 100%; border-collapse: collapse; margin: 0 0 .6rem; font-size: .9rem; }
.speed-table td { padding: .3rem 0; border-bottom: 1px solid var(--line); }
.speed-table td + td { text-align: end; padding-inline-start: .6rem; }
.speed-limits { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: .45rem; }
.speed-limits > label { display: flex; flex-direction: column; justify-content: flex-end;
  font-size: .82rem; }
.speed-limits > label input { margin-top: .25rem; width: 100%; min-width: 0; }
.set-press { width: 100%; background: none; border: 0; color: inherit; font: inherit;
  text-align: start; cursor: pointer; }
.set-press .set-k { color: var(--gain); }
.set-k small select.set-inline { display: inline; width: auto; min-height: 0; margin: 0;
  background: none; border: 0; color: var(--muted); font: inherit; padding: 0;
  text-decoration: underline dotted; -webkit-appearance: none; appearance: none;
  field-sizing: content; }
.set-saved { color: var(--gain); font-size: .88rem; margin: 0 0 .4rem; }
.set-build { font-size: .75rem; text-align: center; margin: 1.5rem 0 0; }
.switch { position: relative; display: inline-block; width: 38px; height: 22px; flex: none; }
.switch input { position: absolute; opacity: 0; width: 100%; height: 100%; margin: 0; cursor: pointer; }
.switch i { position: absolute; inset: 0; border-radius: 11px; background: var(--line);
  transition: background .15s; pointer-events: none; }
.switch i::after { content: ""; position: absolute; left: 3px; top: 3px; width: 16px; height: 16px;
  border-radius: 50%; background: #fff; transition: transform .15s; }
.switch input:checked + i { background: var(--gain); }
.switch input:checked + i::after { transform: translateX(16px); }
.switch input:focus-visible + i { outline: 2px solid var(--gain); outline-offset: 2px; }

/* Add position: what Yahoo says the ticker is (profile.js). */
.found { border-inline-start: 3px solid var(--gain); padding: .45rem .7rem; margin: -.3rem 0 .9rem;
  font-size: .85rem; border-radius: 0 8px 8px 0; background: color-mix(in srgb, var(--gain) 8%, transparent); }
.found small { display: block; color: var(--muted); font-size: .76rem; margin-top: .15rem; }
.found.bad { border-inline-start-color: var(--danger); background: color-mix(in srgb, var(--danger) 10%, transparent); }
.found.bad strong { color: var(--danger); }
.auto { color: var(--gain); font-size: .72rem; font-weight: 600; text-transform: uppercase;
  letter-spacing: .04em; margin-inline-start: .4rem; }
/* Performance > Result: your capital, and which side of it you are. */
.capital-line { margin: .55rem 0 .3rem; padding: .6rem .75rem; border-radius: 10px;
  font-size: .95rem; color: var(--ink);
  background: color-mix(in srgb, var(--gain) 9%, transparent); }
.capital-line.down { background: color-mix(in srgb, var(--danger) 9%, transparent); }
.capital-line strong { color: var(--gain); }
.capital-line.down strong { color: var(--danger); }
/* Under the fee boxes on a purchase: the price a sale must beat (fees.js). */
.break-even { margin: -.4rem 0 1rem; font-size: .92rem; color: var(--ink); }
.break-even b { font-weight: 700; }
.break-even.warn { color: var(--warn); }

/* What to do next: plan against now, on the allocation ring (charts.donut). */
.rings { display: flex; justify-content: space-around; flex-wrap: wrap; }
.rings .donut { max-width: 150px; }
.donut .hatch-bg { fill: var(--card); }
.donut .hatch-line { stroke: var(--danger); stroke-width: 1.2; }
.donut-title { fill: var(--ink); font-size: 4.6px; font-weight: 700; text-anchor: middle; }
.donut-sub { fill: var(--muted); font-size: 3px; text-anchor: middle; }
.swatch.banned { background: repeating-linear-gradient(45deg, var(--danger) 0 2px, transparent 2px 5px); }
.plan-split .swatch { display: inline-block; margin: 0 .45rem 0 0; vertical-align: -1px; }
.plan-steps small { display: block; color: var(--muted); font-size: .78rem; margin-top: .12rem; }
.step-n { display: inline-flex; width: 20px; height: 20px; border-radius: 50%; background: var(--gain);
  color: #fff; font-size: .72rem; align-items: center; justify-content: center; margin-inline-end: .5rem; }


/* A ticker's trades, under Yours in its company pop-up (company.html). */
.history-head { display: flex; justify-content: space-between; align-items: baseline; }
.history-head h2 { margin: 0; }
.history-close { color: var(--muted); font-size: 1.2rem; text-decoration: none; }
.history-sub { margin: .15rem 0 .7rem; font-size: .82rem; }
/* The holding's next results, opening them on News > Earnings (2 October 2026). */
.next-results { display: flex; align-items: center; gap: .6rem; margin: -.2rem 0 .8rem;
  padding: .6rem .8rem; border: 1px solid var(--line); border-radius: 12px;
  background: var(--card); color: var(--ink); text-decoration: none; line-height: 1.3; }
.next-results > span:first-of-type { flex: 1; }
.next-results small { display: block; font-size: .8rem; }
.next-results .news-dot { flex: none; margin-top: 0; }
/* A holding's chart at the top of its trade history (ticker_chart,
   1 October 2026). */
.ticker-chart { margin: 0 0 .7rem; position: relative; }
/* A finger on the chart reads it (drawer.js, 3 October 2026): the chart owns
   the finger, a dashed line and a dot follow it, and the strip lies over the
   period switch while it reads. */
.tc-pane, .tick-pane { position: relative; overflow: hidden; }
/* The iPhone's tick (drawer.js): an unseen switch twice the chart's width,
   its middle over the chart's middle until a finger moves it. */
.tc-tick { position: absolute; top: 0; left: -50%; width: 200%; height: 100%; margin: 0; opacity: .01;
  touch-action: none; -webkit-tap-highlight-color: transparent; }
/* Only the iPhone needs the switch drawn for it to tick; elsewhere it is
   drawn as nothing, or a large faint checkbox shows through the chart once
   pressed. */
.tc-tick { -webkit-appearance: none; appearance: none; background: none; border: 0; }
@supports (-webkit-touch-callout: none) {
  .tc-tick { -webkit-appearance: auto; appearance: auto; }
}
/* On a page rather than a pop-up, the page keeps its vertical scroll: the
   Performance charts (charts.tickable, 3 October 2026). */
.tc-tick.tc-tick-scroll { touch-action: pan-y; }
.tc-svg[data-read] { touch-action: none; -webkit-user-select: none; user-select: none;
  -webkit-touch-callout: none; }
.tc-cross, .tc-dot { display: none; }
.tc-svg.is-reading .tc-cross { display: inline; stroke: var(--ink); stroke-width: 1;
  stroke-dasharray: 3 3; opacity: .7; }
.tc-svg.is-reading .tc-dot { display: inline; fill: var(--card); stroke: var(--ink); stroke-width: 2;
  transform-box: fill-box; transform-origin: center; }
.tc-svg.is-fading .tc-cross, .tc-svg.is-fading .tc-dot { opacity: 0; transition: opacity .25s; }
.tc-dot.tick { animation: tc-tick .18s ease-out; }
@keyframes tc-tick { 50% { transform: scale(1.45); } }
.tc-reading { display: none; position: absolute; top: 0; left: 0; right: 0; z-index: 2; min-height: 44px;
  box-sizing: border-box; padding: .35rem .6rem; border-radius: 10px; background: var(--raised);
  flex-wrap: wrap; gap: .1rem .7rem; align-items: center; justify-content: space-between;
  font-size: .85rem; line-height: 1.3; }
.tc-reading.on { display: flex; }
/* A results day's panel (company_report.html, 12 October 2026): its
   quarter, then pulled up, every report; the actual large and coloured, the
   forecast small beneath. */
.rp-q { margin: .2rem 0 .5rem; display: flex; flex-wrap: wrap; gap: .1rem .5rem; align-items: baseline; }
.rp-t, .rp-list { width: 100%; border-collapse: collapse; font-size: .9rem; }
.rp-t th, .rp-list th { color: var(--muted); font-weight: 600; font-size: .78rem; text-align: right;
  padding: .35rem .3rem; border-bottom: 1px solid var(--line); }
.rp-t td, .rp-list td { text-align: right; padding: .55rem .3rem; border-bottom: 1px solid var(--hairline);
  font-variant-numeric: tabular-nums; vertical-align: top; }
.rp-t th:first-child, .rp-t td:first-child, .rp-list th:first-child, .rp-list td:first-child { text-align: left; }
.rp-t td:first-child { color: var(--muted); }
.rp-list td b, .rp-list td small { display: block; }
.rp-list td small { color: var(--muted); font-size: .78rem; }
.rp-list tr.on td { background: var(--raised); }
.rp td.up b { color: var(--gain); }
.rp td.down b { color: var(--danger); }
.rp-more { display: block; margin: .7rem auto .2rem; background: none; border: 0; color: var(--accent-text);
  font-weight: 600; }
.rp .rp-all, .rp.is-full .rp-one { display: none; }
.rp.is-full .rp-all { display: block; }
.rp-key { font-size: .78rem; margin: .4rem 0 0; }
.er { margin-top: 1rem; }
.er-r { display: grid; grid-template-columns: 5.4rem minmax(0, 1fr) minmax(0, .9fr) minmax(0, .9fr);
        gap: 0 .6rem; padding: .5rem .4rem;
        border-bottom: 1px solid var(--hairline); font-size: .8rem; line-height: 1.45;
        font-variant-numeric: tabular-nums; }
.er-r > div { display: flex; flex-direction: column; min-width: 0; }
.er-r span, .er-r b, .er-r small { display: block; margin: 0; line-height: 1.45; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.er-w b { font-weight: 400; }
.er-w small { color: var(--muted); font-size: 1em; line-height: inherit; }
.er-l { color: var(--muted); }
.er-a, .er-f { text-align: right; }
.er-a span { font-weight: 500; }
.er-a .up { color: var(--gain); }
.er-a .down { color: var(--danger); }
@media (max-width: 380px) { .er-r { font-size: .76rem; grid-template-columns: 5.1rem minmax(0, 1fr) minmax(0, .9fr) minmax(0, .9fr); gap: 0 .45rem; padding-left: .3rem; padding-right: .3rem; } }
.er-r.next { background: var(--raised); border-radius: 8px; border-bottom-color: transparent; }
.er-hd { font-size: .74rem; font-weight: 500; color: var(--muted); padding-top: 0; }
.er-hd > div:nth-child(3), .er-hd > div:nth-child(4) { text-align: right; }
.er-more summary { display: block; margin-top: .8rem; padding: .6rem 0; text-align: center; list-style: none;
  border: 1px solid var(--hairline); border-radius: 10px; cursor: pointer; font-weight: 500; font-size: .84rem; }
.er-more summary::-webkit-details-marker { display: none; }
.er-more[open] summary { display: none; }
/* A trade's bubble, over its ▲ or ▼ (drawer.js, 12 October 2026). */
.tc-bubble { display: none; position: absolute; z-index: 3; max-width: 230px; pointer-events: none;
  padding: .4rem .6rem; border-radius: 10px; background: var(--raised); border: 1px solid var(--line);
  box-shadow: 0 6px 18px rgba(0, 0, 0, .25); font-size: .78rem; line-height: 1.35; }
.tc-bubble.on { display: block; }
.tc-bubble.fading { opacity: 0; transition: opacity .25s; }
.tc-bubble b { font-weight: 700; }
.tc-bubble span { color: var(--muted); }
.tc-bubble em { display: block; font-style: normal; font-weight: 700; }
.tc-bubble em.up { color: var(--gain); }
.tc-bubble em.down { color: var(--danger); }
.tc-reading.fading { opacity: 0; transition: opacity .25s; }
.tc-reading b { font-weight: 700; }
.tc-reading .up { color: var(--gain); }
.tc-reading .down { color: var(--danger); }
@media (prefers-reduced-motion: reduce) { .tc-dot.tick { animation: none; } }
.tc-periods { display: flex; gap: .4rem; margin-bottom: .35rem; }
.tc-period {
  flex: 1; min-height: 44px; padding: .3rem .2rem; border-radius: 12px;
  border: 1px solid transparent; background: transparent; color: var(--ink);
  font: inherit; font-size: .82rem; line-height: 1.25; cursor: pointer;
}
.tc-period b { display: block; font-size: .95rem; }
.tc-period b.up { color: var(--gain); }
.tc-period b.down { color: var(--danger); }
.tc-period.on { border-color: transparent; color: var(--ink); background: var(--raised); font-weight: 700; }
.tc-svg { display: block; }
.tc-grid { stroke: var(--line); stroke-width: 1; }
.tc-axis { font-size: 10.5px; fill: var(--muted); }
.tc-line { fill: none; stroke: var(--ink); stroke-width: 1.8; stroke-linejoin: round; }
/* The tick under Buy, Sell and Record (_haptic.html, 12 October 2026): an
   unseen switch over the button, on a phone with scripts only. */
[data-haptic] { position: relative; }
.haptic { display: none; }
@media (pointer: coarse) {
  html.has-haptic .haptic { display: block; position: absolute; inset: 0; z-index: 1; width: 100%; height: 100%;
    margin: 0; padding: 0; opacity: .01; pointer-events: auto; cursor: pointer; -webkit-tap-highlight-color: transparent;
    -webkit-appearance: none; appearance: none; background: none; border: 0; }
}
/* Only the iPhone needs the switch drawn for it to tick, as .tc-tick. */
@supports (-webkit-touch-callout: none) {
  html.has-haptic .haptic { -webkit-appearance: auto; appearance: auto; }
}
/* Candles (chart_style.py, 12 October 2026): green where a day closed at or
   above its open, red below, as Investing.com draws them. */
.tc-candle line { stroke-width: 1; }
.tc-candle.up rect, .tc-candle.up line { fill: var(--gain); stroke: var(--gain); }
.tc-candle.down rect, .tc-candle.down line { fill: var(--danger); stroke: var(--danger); }
.tc-candle rect { stroke-width: .4; }
/* His trades over candles, as Saham marks them (13 October 2026): a green B
   under the day's low, a red S over its high, on a thin stem. */
.tc-badge line { stroke-width: 1; }
.tc-badge rect { stroke-width: 1; }
.tc-badge text { font-size: 8.5px; font-weight: 800; fill: #fff; }
.tc-badge.buy line, .tc-badge.buy rect { stroke: var(--gain); }
.tc-badge.sell line, .tc-badge.sell rect { stroke: var(--danger); }
.tc-badge.buy rect { fill: var(--gain); }
.tc-badge.sell rect { fill: var(--danger); }
.tc-badge.other rect { fill: var(--card); }
.tc-badge.buy.other text { fill: var(--gain); }
.tc-badge.sell.other text { fill: var(--danger); }
.tc-avg { stroke: var(--warn); stroke-width: 1.4; stroke-dasharray: 4 3; }
.tc-prev { stroke: var(--muted); stroke-width: 1; stroke-dasharray: 1 3; opacity: .8; }
.tc-avg-label { font-size: 10px; font-weight: 700; fill: var(--warn); }
/* A halo in the card's colour, so a label over the line stays readable. */
.tc-avg-label, .tc-now-label { paint-order: stroke; stroke: var(--card); stroke-width: 3px; stroke-linejoin: round; }
.tc-buy { fill: var(--gain); stroke: var(--card); stroke-width: 1; }
.tc-sell { fill: var(--danger); stroke: var(--card); stroke-width: 1; }
.tc-now { fill: var(--ink); }
.tc-now-label { font-size: 10px; font-weight: 700; fill: var(--ink); }
.tc-key { font-size: .78rem; margin: .1rem 0 0; }
a.trend-link { display: inline-block; color: inherit; }
.history-sum { display: grid; grid-template-columns: 1fr 1fr; gap: .5rem; margin-bottom: .6rem; }
.history-sum div { background: var(--raised); border-radius: 10px; padding: .5rem .65rem; }
.history-sum small { display: block; color: var(--muted); font-size: .72rem; }
.history-sum b { font-size: 1rem; }
.history-note { font-size: .78rem; margin: 0 0 .4rem; }
.history-rows { list-style: none; margin: 0; padding: 0; }
.history-rows li { display: grid; grid-template-columns: 5.2rem 1fr auto; column-gap: .5rem;
  padding: .55rem 0; border-bottom: 1px solid var(--line); font-size: .86rem; }
.history-rows .d { color: var(--muted); grid-row: span 2; font-size: .8rem; }
.history-rows .a { font-weight: 600; }
.history-rows li.sold .a { color: var(--warn); }
.history-rows .r { text-align: end; white-space: nowrap; }
.history-rows .f { grid-column: 2 / span 2; color: var(--muted); font-size: .74rem; }
.history-log { display: block; text-align: center; margin-top: .8rem; font-weight: 600; }
.btn-small { font-size: .78rem; padding: .15rem .5rem; border: 1px solid var(--line);
  border-radius: 6px; text-decoration: none; margin-inline-start: .3rem; }

/* Add position, as the approved picture of 25 September 2026 draws it. */
.two-up { display: grid; grid-template-columns: 1fr 1fr; gap: .6rem; }
.holding-details { margin: -.3rem 0 1rem; }
.holding-details > summary { list-style: none; cursor: pointer; display: flex;
  justify-content: space-between; color: var(--muted); font-size: .84rem; padding: .3rem 0; }
.holding-details > summary::-webkit-details-marker { display: none; }
.holding-details > summary span { color: var(--accent-text); font-weight: 600; }
.holding-details[open] > summary { margin-bottom: .6rem; }
.found:has(.found-change) { position: relative; padding-inline-end: 4.5rem; }
.found .found-change { position: absolute; top: .45rem; inset-inline-end: .7rem;
  font-weight: 600; color: var(--accent-text); text-decoration: none; }
.switch-line { padding: .6rem 0; border-top: 1px solid var(--line); margin-bottom: .4rem; }
.form-hint { display: block; color: var(--muted); font-size: .78rem; margin: -.4rem 0 .9rem; }
/* The three fee boxes side by side on Add position, as the picture drew them. */
.holding-form .fee-boxes { display: grid; grid-template-columns: repeat(3, 1fr); gap: .45rem; }
.holding-form .fee-boxes > legend { grid-column: 1 / -1; }
.holding-form .fee-boxes > label { display: flex; flex-direction: column; justify-content: flex-end;
  font-size: .72rem; margin-bottom: 0; }
.holding-form .fee-boxes > label input { margin-top: .25rem; }
.holding-form .fee-boxes[hidden] { display: none; }

/* Buy or sell on a holding, as the approved picture of 25 September 2026
   draws it: Buy and Sell as two buttons, what the trade does under the fees. */
.segmented { display: grid; grid-template-columns: 1fr 1fr; border: 1px solid var(--line);
  border-radius: 10px; overflow: hidden; margin-bottom: 1rem; }
.segmented label { margin: 0; }
.segmented input { position: absolute; opacity: 0; pointer-events: none; width: 1px; height: 1px; margin: 0; }
.segmented span { display: block; text-align: center; padding: .55rem; font-weight: 600;
  color: var(--muted); cursor: pointer; }
.segmented input:checked + span { background: var(--accent-text); color: var(--bg); }
.segmented input:focus-visible + span { outline: 2px solid var(--accent-text); outline-offset: -3px; }
.trade-form .sell-all { float: inline-end; margin: 0; background: none; color: var(--accent-text);
  cursor: pointer; font-weight: 600; }
.trade-form .sell-all[hidden] { display: none; }
.trade-result { margin: -.4rem 0 .8rem; font-size: .92rem; }
.trade-result b { font-weight: 700; }
.trade-result[hidden] { display: none; }

/* Break-even Watch (29 September 2026): a small green mark beside a losing
   ticker, only at 90% or better, opening the plan in a panel. */
details.even-mark { margin: 0; }
.even-badge { display: inline-block; padding: .05rem .4rem; border-radius: 999px; text-decoration: none;
  font-size: .75rem; font-weight: 700; color: var(--gain); cursor: pointer;
  background: color-mix(in srgb, var(--gain) 14%, transparent); }
.even-mark .sheet-panel p { margin: .35rem 0; white-space: normal; }

/* A dividend as the broker's notice states it, then the tax, then what
   reaches the cash (dividend_record.html). */
.dividend-notice { width: 100%; margin: .6rem 0; }

/* Where it came from: each line opens its accounts in a pop-up, the
   Dashboard's details.sheet (29 September 2026). */
#where-from details.part-sheet > summary.part { cursor: pointer; }
#where-from .sheet-rows .sheet-sub { display: flex; justify-content: space-between;
  padding: .3rem 0 .3rem 1rem; font-size: .85rem; color: var(--muted); }

/* Sign in: the logo, the name under it, the passkey under that (29 September
   2026). Centred in the first screen, like a banking app's own. */
.signin { display: flex; flex-direction: column; align-items: center; text-align: center;
          padding: 3.5rem 0 1rem; gap: .9rem; max-width: 22rem; margin: 0 auto; }
.signin-mark { width: 88px; height: 88px; border-radius: 20px;
               box-shadow: 0 2px 12px rgba(0, 0, 0, .25); }
.signin-name { margin: 0 0 .8rem; font-size: 1.9rem; letter-spacing: -.01em; }
.signin-key { width: 100%; padding: .85rem 1rem; font-size: 1.05rem; }
.signin .fold { width: 100%; text-align: start; }
.signin p { margin: 0; }

/* The Trade log, rebuilt on 1 October 2026: search, All / Bought / Sold,
   two lines a trade, a month at a time. */
.tl-tools { margin: .3rem 0 .6rem; }
.tl-search {
  width: 100%; box-sizing: border-box; padding: .7rem .9rem; border-radius: 12px;
  border: 1px solid transparent; background: var(--raised); color: var(--ink); font: inherit;
}
.tl-chips { display: flex; flex-wrap: wrap; gap: .4rem; margin-bottom: .2rem; }
.tl-chips a {
  padding: .35rem .85rem; border-radius: 99px; border: 1px solid transparent;
  font-size: .9rem; color: var(--ink); text-decoration: none;
}
.tl-chips a.on { background: var(--raised); color: var(--ink); border-color: transparent; font-weight: 700; }
.tl-list { list-style: none; margin: 0; padding: 0; }
.tl-month {
  font-size: .9rem; letter-spacing: 0; text-transform: none; color: var(--muted);
  padding: .8rem 0 .3rem; font-weight: 700;
}
.tl-month span { font-weight: 400; }
.tl-row { border-top: 1px solid var(--hairline); }
.tl-row summary {
  list-style: none; display: flex; justify-content: space-between; gap: .6rem;
  padding: .55rem 0; cursor: pointer;
}
.tl-row summary::-webkit-details-marker { display: none; }
.tl-l { display: flex; flex-wrap: wrap; align-items: baseline; gap: .35rem; min-width: 0; }
.tl-l small { flex-basis: 100%; color: var(--muted); font-size: .82rem; }
.tl-r { display: flex; flex-direction: column; text-align: right; }
.tl-r b { white-space: nowrap; }
.tl-r b.up { color: var(--gain); }
.tl-r b.down { color: var(--danger); }
.tl-r .tl-unknown { color: var(--muted); font-weight: 400; font-size: .85rem; }
.tl-r small { color: var(--muted); font-size: .78rem; white-space: nowrap; }
.tl-tag { font-size: .7rem; font-weight: 700; padding: .1rem .45rem; border-radius: 6px; }
.tl-why { margin: 0 0 .4rem; font-size: .85rem; }
.tl-acts { display: flex; gap: .5rem; align-items: center; padding: 0 0 .6rem; }
.tl-acts .inline-form { margin: 0; }
.tl-erase { color: var(--danger); border-color: var(--danger); background: transparent; }
.tl-more { display: block; text-align: center; padding: .6rem 0 .2rem; font-size: .9rem; }
.tl-none { padding: .8rem 0; }
.tl-log summary { list-style: none; cursor: pointer; }
.tl-log summary::-webkit-details-marker { display: none; }
.tl-log[open] summary { margin-bottom: .6rem; }
.tl-check { font-size: .85rem; color: var(--gain); margin: .2rem .2rem 1rem; }

/* A ticker, wherever it is printed, opens its company pop-up (_ticker.html,
   2 October 2026): one look on every screen. */
a.tk { color: var(--ink); font-weight: 700; white-space: nowrap; text-decoration: underline;
  text-decoration-thickness: 1px; text-underline-offset: 3px;
  text-decoration-color: color-mix(in srgb, var(--muted) 45%, transparent); }
a.tk.not-updated { color: var(--danger); }
.visually-hidden { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }

/* A News line: the ticker its own link above the line's link, which covers
   the row (2 October 2026). */
.news-row { position: relative; }
.news-go { display: flex; flex-direction: column; color: var(--ink); text-decoration: none; }
/* Where it came from on the left; its date and time small at the lower
   right, on its own (27 October 2026: "Make it small in the lower right
   corner for example so I know the date and time clearly not mixed with
   news"). */
/* Every line's date and time at its top right, orange and small (27
   October 2026: "Stick to one maybe up right and orange color", then "Make
   date and time small font not like title"). */
.news-top .news-name { min-width: 0; }
.news-top .news-when { flex: none; margin-left: auto; white-space: nowrap; color: var(--warn);
  font-size: .75rem; font-weight: 500; }
.news-go::after { content: ""; position: absolute; inset: 0; }
.news-top .tk { position: relative; z-index: 1; }

/* The company pop-up (company.html), as the picture approved on 2 October
   2026 draws it: a handle, the ticker large and its price, a segmented
   period switch, the chart, then Yours, Results and Analysts as rows. */
.company-sheet .sheet-panel { max-height: 90vh; }
.company-sheet .sheet-panel, .results-sheet .sheet-panel { border-radius: 22px 22px 0 0; padding-top: .55rem; }
.results-sheet .sheet-scrim { z-index: 43; }
.results-sheet .sheet-panel { z-index: 44; max-height: 86vh; }
.co-grab { display: block; width: 38px; height: 4px; border-radius: 2px; background: var(--line);
  margin: 0 auto .75rem; padding: 8px 30px; background-clip: content-box; box-sizing: content-box; }
.co-loading { min-height: 40vh; }
.co-loading b { font-size: 1.45rem; font-weight: 800; }
/* While the pop-up is asked for: a bar that moves, so an open sheet is never
   mistaken for an empty one (3 October 2026). */
.co-wait { display: block; height: 3px; margin-top: .9rem; border-radius: 2px; overflow: hidden;
  background: color-mix(in srgb, var(--muted) 18%, transparent); position: relative; }
.co-wait::after { content: ""; position: absolute; inset: 0; width: 35%; border-radius: 2px;
  background: var(--accent, var(--gain)); animation: co-wait 1s ease-in-out infinite; }
.co-filling { margin: 0 0 .5rem; }
@keyframes co-wait { from { transform: translateX(-100%); } to { transform: translateX(290%); } }
@media (prefers-reduced-motion: reduce) { .co-wait::after { animation: none; width: 100%; opacity: .4; } }
.co-head { display: flex; justify-content: space-between; align-items: flex-start; gap: .8rem; }
.co-t { margin: 0; font-size: 1.75rem; font-weight: 700; letter-spacing: -.02em; line-height: 1.1;
  color: var(--ink); text-transform: none; }
.co-n { margin: .15rem 0 0; color: var(--muted); font-size: .82rem; }
.co-p { margin: 0; text-align: end; font-weight: 700; font-size: 1.3rem; line-height: 1.2; white-space: nowrap; }
.co-p small { display: block; font-weight: 600; font-size: .82rem; }
.co-chip { display: inline-block; font-size: .72rem; font-weight: 700; border-radius: 6px;
  padding: .12rem .5rem; background: var(--raised); color: var(--muted); margin-top: .35rem; }
.co-seg { display: flex; flex: 1 1 auto; min-width: 0; gap: .25rem; background: none; border-radius: 0; padding: 0; }
/* The period switch, and at its right the icon that turns the chart into
   candles or back to a line (12 October 2026, chart_style.py). */
.tc-move { margin: .1rem 0 .2rem; font-size: .92rem; color: var(--muted); }
.tc-move b { font-size: 1.02rem; font-variant-numeric: tabular-nums; }
.tc-top { display: flex; align-items: center; gap: .2rem; margin: .8rem 0 .35rem; }
.tc-style { flex: none; margin: 0; }
.tc-style button { display: grid; place-items: center; width: 36px; height: 36px; padding: 0; margin: 0;
  border: 0; border-radius: 999px; background: var(--raised); color: var(--ink); cursor: pointer; }
.tc-style svg { width: 19px; height: 19px; fill: none; stroke: currentColor; stroke-width: 1.7;
  stroke-linecap: round; stroke-linejoin: round; }
/* The icon shows what a press turns it into; the chart shows what is chosen. */
.ticker-chart .tc-ico-line, .ticker-chart.is-candles .tc-ico-candles,
.ticker-chart .tc-as-candles, .ticker-chart.is-candles .tc-as-line:not(.tc-only),
.ticker-chart .tc-src-candles, .ticker-chart.is-candles .tc-src-line { display: none; }
.ticker-chart.is-candles .tc-ico-line, .ticker-chart.is-candles .tc-src-candles { display: inline; }
.ticker-chart.is-candles svg.tc-as-candles { display: block; }
.co-seg .tc-period { flex: 1 1 auto; min-height: 36px; border: 0; border-radius: 999px; background: none;
  color: var(--ink); font-weight: 500; font-size: .9rem; padding: .25rem .4rem; line-height: 1.15;
  white-space: nowrap; }  /* "Since 28 Jul" on one line: it wrapped at a phone's width */
/* Beside the line-or-candles icon, "Since 30 Oct 2025" and Year still fit on
   a phone narrower than his (13 October 2026: Year went under the icon). */
@media (max-width: 420px) {
  .co-seg { gap: 0; }
  .co-seg .tc-period { font-size: .84rem; padding: .25rem .32rem; }
}
@media (max-width: 380px) {
  .co-seg .tc-period { font-size: .76rem; padding: .25rem .24rem; }
  .tc-style button { width: 32px; height: 32px; }
}
.co-seg .tc-period.on { background: var(--raised); color: var(--ink); box-shadow: none; font-weight: 700; }
.tc-fill { stroke: none; }
.tc-fill.above { fill: var(--gain); fill-opacity: .22; }
.tc-fill.below { fill: var(--danger); fill-opacity: .22; }
path.tc-avg { fill: none; }
.company .tc-key { display: flex; flex-wrap: wrap; gap: .15rem .8rem; font-size: .74rem; color: var(--muted); margin: .15rem 0 0; }
.tc-key b { font-weight: 400; }
.co-sec { margin-top: .95rem; }
.co-h { margin: 0 0 .45rem; font-size: 1.22rem; font-weight: 700; letter-spacing: -.012em; color: var(--ink);
  text-transform: none; }
.co-row { display: flex; justify-content: space-between; align-items: center; gap: .6rem; padding: .65rem 0;
  min-height: 44px; box-sizing: border-box;
  border-top: 0; color: var(--ink); text-decoration: none; font-size: 1rem; }
.co-row b { font-weight: 700; white-space: nowrap; }
.co-row > span:last-child { text-align: end; }
a.co-link { border-top: 0; padding: .35rem 0; }
.co-hist > summary { list-style: none; cursor: pointer; }
.co-hist > summary::-webkit-details-marker { display: none; }
.co-hist .history-rows { margin-top: .2rem; }
/* The analysts' target under the year's range: the figure and its distance
   from now on the left, how many and whose on the right. */
.co-target { display: flex; justify-content: space-between; align-items: baseline; gap: .6rem;
  margin: .35rem 0 0; font-size: .82rem; }
.co-target .up { color: var(--gain); }
.co-target .down { color: var(--danger); }
.co-target .muted { font-size: .72rem; white-space: nowrap; }
.co-btns { display: flex; gap: .5rem; margin-top: 1.1rem; }
.co-btn { flex: 1; text-align: center; font-weight: 700; border-radius: 10px; padding: .85rem 0; font-size: 1.05rem;
  background: var(--raised); color: var(--ink); text-decoration: none; }
.earn-panel .co-grab { margin-bottom: .6rem; }

/* Search, over every tab (search.html, history.js), as the picture approved
   on 2 October 2026 draws it: the box and Cancel, then his holdings, then
   every US company. Under the panels, so a company opens over it. */
.search-overlay { position: fixed; inset: 0; z-index: 40; background: var(--bg); overflow-y: auto;
  padding: calc(1rem + env(safe-area-inset-top)) 1rem 5rem; box-sizing: border-box; }
html.search-open body { overflow: hidden; }
.search-bar { display: flex; gap: .7rem; align-items: center; margin: 0; }
.search-box { flex: 1; min-width: 0; box-sizing: border-box; padding: .7rem .9rem; border-radius: 12px;
  border: 1px solid transparent; background: var(--raised); color: var(--ink); font: inherit; font-size: 1rem; }
.search-cancel { color: var(--muted); text-decoration: none; font-size: .95rem; }
.search-h { margin: 1.1rem 0 .3rem; font-size: 1.22rem; font-weight: 700; color: var(--ink); text-transform: none; letter-spacing: -.012em; }
.search-list { list-style: none; margin: 0; padding: 0; }
.search-list a { display: flex; justify-content: space-between; align-items: center; gap: .6rem; padding: .75rem 0;
  border-top: 1px solid var(--hairline); color: var(--ink); text-decoration: none; }
.search-list a > span:first-child { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.search-tag { flex: none; font-size: .78rem; background: var(--raised); color: var(--ink); border-radius: 6px;
  padding: .15rem .55rem; white-space: nowrap; }
.search-none { margin-top: 1rem; }
.co-btn.act-buy { background: color-mix(in srgb, var(--gain) 20%, transparent); color: var(--gain); }
.co-btn.act-sell { background: color-mix(in srgb, var(--danger) 20%, transparent); color: var(--danger); }
/* Buy and Sell at the foot of Yours, a pair an account (15 October 2026). */
.co-trade { align-items: center; margin-top: .6rem; }
.co-trade .co-btn { padding: .6rem 0; font-size: .98rem; }
.co-acct { flex: 0 0 4.2rem; font-size: .85rem; color: var(--muted); font-weight: 600; }
/* The ◎ plan's trades, one tap to the form filled in (15 October 2026). */
.even-mark a.even-go { display: block; text-align: center; font-weight: 700; border-radius: 10px;
  padding: .7rem .5rem; margin: .45rem 0; text-decoration: none; }

/* The stock score in the company pop-up (company.html, stock_score.py), as
   the picture approved on 2 October 2026 draws it: a ring filled to the score
   with its letter, the score and where it places the company, six grade
   tiles three a row, and the record line, worded as the warning it is. */
.sc-head { display: flex; align-items: center; gap: .9rem; }
.sc-ring {
  --sc-fill: 0%;
  --sc-tone: var(--gain);
  position: relative; flex: none; width: 58px; height: 58px; border-radius: 50%; display: grid; place-items: center;
  background: conic-gradient(var(--sc-tone) 0 var(--sc-fill), var(--raised) var(--sc-fill) 100%); }
.sc-ring::before { content: ""; position: absolute; inset: 6px; border-radius: 50%; background: var(--card); }
.sc-ring b { position: relative; font-size: 1.5rem; font-weight: 800; color: var(--ink); }
.sc-ring.sc-c { --sc-tone: var(--warn); }
.sc-ring.sc-d { --sc-tone: var(--danger); }
.sc-n { margin: 0; font-size: .95rem; }
.sc-n b { font-size: 1.15rem; font-weight: 800; }
.sc-place { margin: .1rem 0 0; font-size: .85rem; }
/* About a company: two lines, then six statistics (18 October 2026). */
.co-about .ab-line { margin: 0; font-size: .9rem; line-height: 1.4; color: var(--ink); }
.co-about .ab-where { margin: .2rem 0 0; font-size: .78rem; }
/* Three tiles a row, then two: six columns, a wide tile taking three. */
.ab-grid { display: grid; grid-template-columns: repeat(6, minmax(0, 1fr)); gap: .4rem; margin-top: .7rem; }
.ab-g { grid-column: span 2; }
.ab-g.ab-wide { grid-column: span 3; }
.ab-g b.warn { color: var(--warn); }
.ab-g { min-width: 0; background: var(--raised); border-radius: 12px; padding: .5rem .5rem .45rem; }
.ab-g small { display: block; font-size: .68rem; color: var(--muted); white-space: nowrap;
  overflow: hidden; text-overflow: ellipsis; }
.ab-g b { display: block; margin: .08rem 0; font-size: 1rem; font-weight: 700;
  font-variant-numeric: tabular-nums; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.co-about .ab-h { display: flex; align-items: baseline; justify-content: space-between; }
.co-about .ab-h small { font-size: .72rem; font-weight: 500; }
.sc-grid { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: .4rem; margin-top: .7rem; }
.sc-g { min-width: 0; background: var(--raised); border-radius: 12px; padding: .5rem .45rem; }
.sc-g b { font-size: 1rem; font-weight: 800; margin-inline-end: .25rem; }
.sc-g span { font-size: .72rem; font-weight: 700; }
.sc-g small { display: block; margin-top: .05rem; font-size: .7rem; color: var(--muted);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.sc-g .gA { color: var(--gain); }
.sc-g .gB { color: color-mix(in srgb, var(--gain) 75%, var(--ink)); }
.sc-g .gC { color: var(--warn); }
.sc-g .gD, .sc-g .gF { color: var(--danger); }
.sc-g .gx { color: var(--muted); }
.sc-rec { margin: .55rem 0 0; font-size: .78rem; }
/* Positions' Target column (8 October 2026): the analysts' figure, told apart
   from Price now by being plain grey with no currency, behind a dashed line;
   only its upside carries a colour. */
.tg { border-left: 1px dashed var(--line); }
.tg .tg-v { color: var(--muted); font-weight: 500; }
.tg .tg-v.up { color: var(--gain); }
.tg .tg-v.down { color: var(--danger); }
.tg .tg-n { display: block; color: var(--muted); font-size: .6rem; font-weight: 400; white-space: nowrap;
  margin-top: .05rem; }
/* The extras of 2 October 2026, judged by Claude on his delegation.
   The year's range of closes: a thin bar under a price, the dot today. */
.yr { display: block; width: 4.5rem; max-width: 100%; margin: .2rem 0 0 auto; }
.yr-ends-on { width: auto; }
.yr-bar { display: block; position: relative; height: 3px; border-radius: 2px; background: var(--line); }
.yr-bar i { position: absolute; top: -2px; width: 7px; height: 7px; margin-left: -3.5px; border-radius: 50%;
  background: var(--ink); }
.yr-ends-on { margin: .45rem 0 0; }
.yr-ends { display: flex; justify-content: space-between; gap: .5rem; font-size: .72rem; color: var(--muted);
  margin-top: .3rem; }
/* The trade after the close, small beneath the official close. */
.ext-price { display: block; font-size: .74rem; color: var(--muted); font-weight: 600; white-space: nowrap; }
/* The moon (after hours) or sun (pre-market) line: the trade plain, its
   move since the close in its colour, as Investing.com draws it. */
.ext-line { white-space: nowrap; font-size: .86em; color: var(--ink); font-weight: 400; }
.ext-price .ext-line { font-size: 1em; font-weight: 600; }
.ext-line .up { color: var(--gain); }
.ext-line .down { color: var(--danger); }
.ext-line .muted { color: var(--muted); font-size: inherit; }
.ext-icon { width: 1em; height: 1em; vertical-align: -.14em; margin-right: .2em; }
.ext-moon { fill: var(--session-after); }
.ext-sun { fill: var(--session-pre); }
.ext-night { fill: var(--session-night); }
/* How the market moved today, one slim line above the Dashboard's card. */
.mkt-strip { display: flex; flex-wrap: wrap; gap: .1rem .9rem; margin: 0 0 .5rem; font-size: .8rem; color: var(--muted); }
.mkt-strip b { font-weight: 700; }
.mkt-strip a { color: inherit; text-decoration: none; }
a.mkt-strip { text-decoration: none; }
.mood-idx { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: .35rem; margin: .7rem 0 .3rem; }
.mood-idx a { display: flex; flex-direction: column; align-items: center; padding: .4rem 0;
  border-radius: 12px; background: var(--raised); color: inherit; text-decoration: none; }
.mood-idx span { font-size: .75rem; color: var(--muted); white-space: nowrap; }
.mood-idx b { font-size: .95rem; }
.mood-idx b.up { color: var(--gain); } .mood-idx b.down { color: var(--danger); }

/* The design changes of 2 October 2026, judged by Claude on his delegation.
   Ready-made views of the Positions table, a chip per question. */
.view-chips { display: flex; gap: 1.2rem; overflow-x: auto; margin: 0 0 .9rem; padding: 0;
  background: none; border-radius: 0; scrollbar-width: none; border-bottom: 1px solid var(--line); }
.view-chips::-webkit-scrollbar { display: none; }
.view-chips a { flex: 0 0 auto; text-align: center; padding: .55rem .1rem .65rem; border-radius: 0;
  color: var(--muted); font-size: 1rem; font-weight: 500; text-decoration: none; white-space: nowrap; }
.view-chips a.is-on { background: none; color: var(--ink); font-weight: 700; box-shadow: inset 0 -3px 0 var(--ink); }
/* A stock pop-up's sub-tabs under its price, All first (22 October 2026):
   words with a line under the chosen one, as Positions' views; a pane shows
   in each tab its data-tab names. */
.co-tabs { display: flex; gap: 1.1rem; overflow-x: auto; margin: .7rem 0 .2rem; scrollbar-width: none;
  border-bottom: 1px solid var(--line); }
.co-tabs::-webkit-scrollbar { display: none; }
.co-tabs label { flex: 0 0 auto; cursor: pointer; }
.co-tabs input { position: absolute; width: 1px; height: 1px; margin: 0; opacity: 0; pointer-events: none; }
.co-tabs span { display: block; padding: .5rem .05rem .6rem; color: var(--muted); font-size: .95rem;
  font-weight: 500; white-space: nowrap; }
.co-tabs input:checked + span { color: var(--ink); font-weight: 700; box-shadow: inset 0 -3px 0 var(--ink); }
.co-tabs input:focus-visible + span { outline: 2px solid var(--accent); outline-offset: 2px; }
.co-earn { display: none; }
.company:has(.co-tab[value="earnings"]:checked) .co-earn { display: block; }
.company:has(.co-tab[value="yours"]:checked) .co-pane:not([data-tab~="yours"]),
.company:has(.co-tab[value="info"]:checked) .co-pane:not([data-tab~="info"]),
.company:has(.co-tab[value="earnings"]:checked) .co-pane:not([data-tab~="earnings"]),
.company:has(.co-tab[value="score"]:checked) .co-pane:not([data-tab~="score"]),
.company:has(.co-tab[value="radar"]:checked) .co-pane:not([data-tab~="radar"]),
.company:has(.co-tab[value="news"]:checked) .co-pane:not([data-tab~="news"]) { display: none; }
.co-earn .co-grab, .co-earn .sheet-head { display: none; }
/* Results (E) and payout (D) days on the company chart. */
.tc-ev { font-size: 9px; font-weight: 800; paint-order: stroke; stroke: var(--card); stroke-width: 3px; }
.tc-ev.e { fill: var(--accent-text); }
.tc-ev.d { fill: var(--gain); }
.tc-ev-dot.e { fill: var(--accent-text); }
.tc-ev-dot.d { fill: var(--gain); }
/* Another account's trades, hollow: they did not move the average drawn. */
.tc-buy.other { fill: var(--card); stroke: var(--gain); stroke-width: 1.4; }
.tc-sell.other { fill: var(--card); stroke: var(--danger); stroke-width: 1.4; }
.tc-k-other { color: var(--muted); }
/* Pull down to refresh: a small spinner under the top bar. */
.pull-spin { position: fixed; left: 50%; z-index: 30; width: 30px; height: 30px; margin-top: 6px;
  border-radius: 50%; background: var(--card); box-shadow: 0 1px 4px rgba(0, 0, 0, .18);
  transform: translate3d(-50%, 0, 0); pointer-events: none; display: grid; place-items: center; }
.pull-spin i { width: 14px; height: 14px; border-radius: 50%; border: 2px solid var(--line);
  border-top-color: var(--accent-text); }
.pull-spin.is-ready i { border-color: var(--accent-text); border-top-color: var(--line); }
.pull-spin.is-busy i { animation: pull-turn .8s linear infinite; }
@keyframes pull-turn { to { transform: rotate(360deg); } }
@media (prefers-reduced-motion: reduce) { .pull-spin.is-busy i { animation: none; } }
/* One account's part of a page, from Where it came from. */
.acct-only { margin: -.4rem 0 .8rem; }
.acct-only a { color: var(--accent-text); text-decoration: none; font-weight: 600; }

/* Motion, as a phone app moves (3 October 2026, "make it like phone apps
   movements to make usability easier"). One curve for everything that
   slides, iOS's own sheet curve. A panel slides up as it opens and down as
   it closes (drawer.js closes a copy, so the panel itself is shut at once);
   the More list slides in from its side; search fades in. A panel the live
   redraw opens again (live.js, .is-shown) does not slide in a second time.
   The page behind an open panel stays still. Asking the phone for less
   motion keeps a fade and drops the slides. */
:root {
  --motion-curve: cubic-bezier(.32, .72, 0, 1);
}
html { overscroll-behavior-y: none; }
.sheet-panel, .drawer-sheet { overscroll-behavior: none; }
.sheet-scrim, .drawer-scrim { touch-action: none; }
.company-sheet .sheet-panel { min-height: min(80vh, 720px); }
.results-sheet .sheet-panel { min-height: min(70vh, 640px); }
@keyframes motion-up { from { transform: translate3d(0, 100%, 0); } }
@keyframes motion-from-end { from { transform: translate3d(100%, 0, 0); } }
@keyframes motion-from-start { from { transform: translate3d(-100%, 0, 0); } }
@keyframes motion-fade { from { opacity: 0; } }
details.sheet[open] > .sheet-panel { animation: motion-up .38s var(--motion-curve); }
details.sheet[open] > .sheet-scrim { animation: motion-fade .3s var(--motion-curve); }
details.sheet.is-shown > .sheet-panel, details.sheet.is-shown > .sheet-scrim { animation: none; }
.tabbar .drawer[open] > .drawer-sheet { animation: motion-from-end .3s var(--motion-curve); }
[dir="rtl"] .tabbar .drawer[open] > .drawer-sheet { animation-name: motion-from-start; }
.tabbar .drawer[open] > .drawer-scrim { animation: motion-fade .25s var(--motion-curve); }
.search-overlay { animation: motion-fade .2s ease-out; }
.motion-ghost { pointer-events: none; }
@media (prefers-reduced-motion: reduce) {
  details.sheet[open] > .sheet-panel,
  .tabbar .drawer[open] > .drawer-sheet { animation: motion-fade .15s linear; }
  .search-overlay { animation: none; }
}

/* Change, on a recorded dividend (Activity > Dividends, 6 October 2026):
   the row opens it; each choice's extra boxes and its line show once
   chosen. */
tr.row-tap { cursor: pointer; }
.row-go { color: var(--muted); margin-left: .2rem; }
.pill-now { font-size: .72rem; padding: .05rem .45rem; border: 1px solid var(--line);
  border-radius: 99px; color: var(--muted); margin-left: .35rem; white-space: nowrap; }
.div-change .chg-more, .div-change .chg-effect { display: none; }
.div-change .chg-opt:has(input[name="what"]:checked) .chg-more,
.div-change .chg-opt:has(input[name="what"]:checked) .chg-effect { display: block; }
.div-change .chg-effect { margin: .1rem 0 .4rem 1.8rem; font-size: .88rem; color: var(--ink); }

/* A steady fund's carried price (read.price_map): "est." as the press that
   opens its reason, in place of the circled i (6 October 2026). */
.why-drop.est-drop > summary { width: auto; height: auto; border-radius: 99px;
  padding: .05rem .42rem; font-size: .7rem; font-style: normal; font-weight: 600; }
.why-drop.est-drop > summary::after { width: auto; inset: -6px; }

/* The bell (bell.py): beside search, a red count of unread; its list a
   sheet like every pop-up (6 October 2026). */
.tb-bell { position: relative; }
.bell-count { position: absolute; top: -5px; right: -5px; min-width: 17px; height: 17px;
  padding: 0 4px; border-radius: 99px; background: #ff6b6b; color: #fff; font-size: .66rem;
  font-weight: 700; line-height: 17px; text-align: center; }
.bell-day { margin: .9rem 0 .2rem; font-size: .9rem; font-weight: 600; letter-spacing: 0; text-transform: none;
  color: var(--muted); }
.bell-item { display: flex; gap: .7rem; align-items: flex-start; padding: .7rem 0;
  border-top: 1px solid var(--hairline); color: var(--ink); text-decoration: none; }
.bell-ic { flex: none; width: 28px; height: 28px; border-radius: 50%; display: flex; align-items: center;
  justify-content: center; background: var(--raised); font-size: .8rem; font-weight: 700; }
.bell-up { color: var(--gain); background: color-mix(in srgb, var(--gain) 16%, transparent); }
.bell-down { color: var(--danger); background: color-mix(in srgb, var(--danger) 16%, transparent); }
.bell-txt { flex: 1; min-width: 0; }
.bell-txt b { display: block; font-weight: 600; }
.bell-txt small { display: block; color: var(--muted); font-size: .8rem; }
.bell-t { flex: none; color: var(--muted); font-size: .75rem; }
.bell-item.is-unread .bell-txt b::before { content: ""; display: inline-block; width: 7px; height: 7px;
  border-radius: 50%; background: var(--accent-text); margin-right: 6px; vertical-align: 1px; }
/* Six categories (Radar's since 18 October 2026), a colour each, on the bell's icons and the chips of All
   notifications (bell.CATEGORIES, 12 October 2026). Price moves keep their
   own green up and red down. Read ones fade in the bell, unread lead. */
.bell-c-even .bell-ic { color: var(--marker); background: color-mix(in srgb, var(--marker) 16%, transparent); }
.bell-c-limits .bell-ic { color: var(--warn); background: color-mix(in srgb, var(--warn-fill) 18%, transparent); }
.bell-c-news .bell-ic { color: #7c5cff; background: color-mix(in srgb, #7c5cff 16%, transparent); }
.bell-c-money .bell-ic { color: var(--gain); background: color-mix(in srgb, var(--gain) 16%, transparent); }
.bell-c-radar .bell-ic { color: var(--accent-text); background: color-mix(in srgb, var(--accent-text) 14%, transparent); }
.bell-dot { display: inline-block; width: 8px; height: 8px; border-radius: 50%; margin-right: 5px;
  vertical-align: 1px; background: var(--accent-text); }
.bell-dot.bell-c-even { background: var(--marker); }
.bell-dot.bell-c-limits { background: var(--warn-fill); }
.bell-dot.bell-c-news { background: #7c5cff; }
.bell-dot.bell-c-money { background: var(--gain); }
.bell-dot.bell-c-radar { background: var(--accent-text); }
.bell-sheet .bell-item:not(.is-unread) { opacity: .6; }
.bell-all { display: block; padding: .8rem 0 .2rem; border-top: 1px solid var(--line);
  font-weight: 600; color: var(--accent-text); text-decoration: none; }
.bell-chips { flex-wrap: wrap; margin-bottom: .6rem; }
/* Each notification's Phone, Bell or Off on Settings. */
.alert-group { margin: 1rem 0 .1rem; font-size: .9rem; font-weight: 600; letter-spacing: 0; text-transform: none;
  color: var(--muted); }
.alert-line { display: flex; align-items: center; justify-content: space-between; gap: .6rem;
  padding: .55rem 0; border-top: 1px solid var(--line); }
.alert-line .set-k small { display: block; }
.seg { display: inline-flex; flex: none; border: 1px solid transparent; border-radius: 99px; padding: 2px;
  background: var(--raised); }
.seg label, .alert-steps label { margin: 0; cursor: pointer; }
.seg input, .alert-steps input { position: absolute; opacity: 0; width: 1px; height: 1px; }
.seg span { display: block; font-size: .74rem; padding: 4px 9px; border-radius: 99px; color: var(--muted); }
.seg input:checked + span { background: var(--card); color: var(--ink); font-weight: 700;
  box-shadow: 0 1px 2px rgba(0,0,0,.25); }
.seg input:checked + .seg-phone { color: var(--gain); }
.seg input:focus-visible + span, .alert-steps input:focus-visible + span { outline: 2px solid var(--accent-text); }
.alert-steps { display: flex; gap: .35rem; margin-top: .35rem; }
.alert-steps span { display: block; font-size: .74rem; padding: 2px 9px; border: 1px solid var(--line);
  border-radius: 99px; color: var(--muted); }
.alert-steps input:checked + span { border-color: var(--ink); color: var(--ink); font-weight: 600; }

/* Each part of the company pop-up in its own card, its name on top, on the
   page's ground: asked for on 6 October 2026, "I feel no separation between
   information which makes me confused", and "Go" to the picture. */
.company-sheet .sheet-panel { background: var(--bg); }
.company .ticker-chart, .company .co-sec { background: var(--card); border: 1px solid transparent;
  border-radius: 12px; padding: .9rem .9rem; box-shadow: none; }
.company .co-sec { margin-top: .9rem; }
.company .co-sec > .co-h + .co-row, .company .co-sec > .co-h + details > .co-row { border-top: 0; }
.company a.co-link { padding: .1rem 0; }
.company a.co-link > span { white-space: nowrap; }
.company a.co-link > span:first-child { min-width: 0; overflow: hidden; text-overflow: ellipsis; }
/* Inside its card the score's six tiles keep the room a hint needs on one
   line at a phone's width (tests/test_stock_score.py). */
.company .co-sec { padding-inline: .65rem; }
.company .co-sec .sc-grid { gap: .3rem; }
.company .co-sec .sc-g { padding-inline: .25rem; }

/* The score's grade in the pop-up's header, between the ticker and the
   price (6 October 2026); a tap scrolls to its tiles (drawer.js). */
.co-head > div:first-child { min-width: 0; }
.co-badge { display: flex; flex-direction: column; align-items: center; gap: .15rem; color: var(--ink);
  text-decoration: none; padding-top: .1rem; }
.co-badge small { font-size: .72rem; color: var(--muted); line-height: 1; }
.co-badge small b { color: var(--ink); font-size: .85rem; }
.sc-ring.sc-mini { width: 40px; height: 40px; }
/* The ticker's row stays at the top while the pop-up scrolls, so the stock
   is never forgotten (27 October 2026: "when I scroll down in stock page the
   first row that is above the target freeze"). Edge to edge on the panel's
   ground, over the cards sliding under it. */
.company-sheet .co-head { position: sticky; top: -.55rem; z-index: 5; margin: 0 -1.1rem;
  padding: .55rem 1.1rem .5rem; background: var(--bg); }
.sc-ring.sc-mini::before { inset: 4px; }
.sc-ring.sc-mini b { font-size: 1.05rem; }
.co-score .sc-place { margin: 0 0 .1rem; }

/* Money on the move (money_moves.py, 9 October 2026): four arrows, green
   done, orange the step it waits on, gray to come. */
.mv-card .mv-head { display: flex; justify-content: space-between; align-items: baseline; }
.mv-card .mv-head h2 { margin: 0 0 .4rem; }
.mv-card .mv-head small { color: var(--muted); font-size: .8rem; }
/* The history of finished orders (11 October 2026): a dot a step with its day. */
.mv-card .mv-hist { display: block; text-align: right; margin-top: .5rem; font-size: .85rem; font-weight: 600; }
.mh-panel .mh-month { font-size: .9rem; font-weight: 700; letter-spacing: 0; text-transform: none;
  color: var(--muted); margin: .9rem 0 .2rem; }
.mh { padding: .75rem 0; border-top: 1px solid var(--line); }
.mh-month + .mh { border-top: 0; }
.mh-top { display: flex; justify-content: space-between; gap: .6rem; align-items: baseline; }
.mh-t { font-weight: 700; color: var(--ink); }
.mh-a { font-weight: 700; white-space: nowrap; }
.mh-what { font-size: .8rem; color: var(--muted); margin: .1rem 0 .35rem; }
.mh ol { list-style: none; margin: 0; padding: 0 0 0 .2rem; }
.mh li { position: relative; padding: 0 0 .45rem 1.3rem; font-size: .85rem; color: var(--ink);
  display: flex; justify-content: space-between; gap: .5rem; }
.mh li:last-child { padding-bottom: 0; }
.mh li::before { content: ""; position: absolute; left: 0; top: .32rem; width: .6rem; height: .6rem;
  border-radius: 50%; background: var(--gain); }
.mh li:not(:last-child)::after { content: ""; position: absolute; left: .26rem; top: .95rem; bottom: -.05rem;
  width: 2px; background: var(--line); }
.mh li span:last-child { color: var(--muted); white-space: nowrap; }
.mh li.end b { color: var(--gain); }
.mh li.fee::before { background: var(--warn-fill); }
.mh li.fee b { color: var(--warn); }
.mv-order { display: block; text-decoration: none; color: inherit; padding: .6rem 0;
  border-top: 1px solid var(--hairline); }
.mv-order:first-of-type { border-top: 0; }
.mv-top { display: flex; justify-content: space-between; gap: .6rem; font-size: .92rem;
  margin-bottom: .4rem; }
.mv-top b { color: var(--ink); }
.mv-top span { color: var(--muted); font-size: .82rem; white-space: nowrap; }
.chev { display: flex; gap: 2px; }
.chev i { flex: 1; font-style: normal; font-size: .68rem; font-weight: 600; text-align: center;
  padding: .38rem .2rem .38rem .7rem; color: #fff; white-space: nowrap; overflow: hidden;
  text-overflow: ellipsis;
  clip-path: polygon(0 0, calc(100% - 9px) 0, 100% 50%, calc(100% - 9px) 100%, 0 100%, 9px 50%); }
.chev i:first-child { padding-left: .4rem;
  clip-path: polygon(0 0, calc(100% - 9px) 0, 100% 50%, calc(100% - 9px) 100%, 0 100%); }
.chev .done { background: var(--gain); }
.chev .now { background: var(--warn-fill); }
.chev .next { background: var(--raised); color: var(--muted); }
.mv-sub { display: block; font-size: .78rem; color: var(--muted); margin-top: .35rem; }
.mv-late .mv-sub { color: var(--warn); }
.mv-row { display: flex; gap: .6rem; }
.mv-row > label { flex: 1; min-width: 0; }
.mv-what { font-size: .8rem; color: var(--muted); margin: .1rem 0 .8rem; }
.mv-choice { border: 0; padding: 0; margin: 0 0 .8rem; }
.mv-choice legend { font-size: .9rem; color: var(--muted); margin-bottom: .35rem; }
.mv-choice { display: flex; flex-wrap: wrap; gap: .5rem; }
.mv-choice legend { flex-basis: 100%; }
.mv-choice label { flex: 1; margin: 0; }
/* A choice drawn as a pill keeps its real button unseen, 1px, so it is
   never as wide as the panel and past its edge (the Withdraw panel's
   pills, 19 October 2026). */
.mv-choice input { position: absolute; opacity: 0; pointer-events: none; width: 1px; height: 1px; margin: 0; }
.mv-choice span { display: block; text-align: center; padding: .6rem .4rem; border: 0; background: var(--raised);
  border-radius: 999px; font-size: .875rem; font-weight: 600; color: var(--muted); }
.mv-choice input:checked + span { background: var(--pp-up); color: var(--gain); }
.mv-form .mv-send, .mv-form .mv-keep, .mv-form .mv-fee, .mv-form .mv-buy { display: none; }
.mv-form:has(input[value="send"]:checked) .mv-send { display: flex; }
.mv-form:has(input[value="send"]:checked) p.mv-send,
.mv-form:has(input[value="keep"]:checked) .mv-keep,
.mv-form:has(input[value="fee"]:checked) .mv-fee { display: block; }
.mv-form:has(input[value="bought"]:checked) .mv-buy { display: block; }
.mv-form button[type="submit"] { width: 100%; }
.mv-gap { font-size: .8rem; color: var(--muted); margin: -.5rem 0 .8rem; }
/* Profit set aside in riyals at Saham (9 October 2026, "I like b"): the
   choice only for Saham, its boxes only when chosen. */
.mv-form .mv-aside-only, .mv-form .mv-sar { display: none; }
/* To: Riyal wallet only from Saham App, Bank from any account; the amount
   names the account's currency (19 October 2026, no sentences). */
.mv-form:not(:has(input[name="from_platform"][value="saham"]:checked)) .mv-to-aside { display: none; }
.mv-form:not(:has(input[name="from_platform"][value="saham"]:checked)) .mv-usd { display: none; }
.mv-form:not(:has(input[name="from_platform"][value="saham"]:checked)) .mv-sar { display: inline; }
.mv-form:not(:has(input[name="from_platform"][value="saham"]:checked)) .mv-to-out span {
  background: var(--pp-up); color: var(--gain); }
.mv-form:has(input[name="from_platform"][value="saham"]:checked):has(input[name="how"][value="aside"]:checked) .mv-aside-only { display: block; }
.mv-cost { font-size: .8rem; color: var(--muted); margin: .2rem 0 .8rem; }
.mv-cost b { color: var(--warn); }
.mv-aside { display: flex; justify-content: space-between; align-items: center; gap: .6rem; }
.mv-aside b { color: var(--ink); font-size: .92rem; }
.mv-aside .btn { white-space: nowrap; }
/* A dividend's confirm screen (15 October 2026): pills, and what a choice
   needs shown only under it. Units not known yet hides the Units box. */
.dv-form .dv-buy, .dv-form .dv-counted { display: none; }
.dv-form:has(input[name="what"][value="buy"]:checked) .dv-buy { display: block; }
.dv-form:has(input[name="what"][value="counted"]:checked) .dv-counted { display: block; }
.dv-form:has(input[name="units_later"]:checked) .dv-units { display: none; }
.dv-form .dv-later { display: flex; gap: .5rem; align-items: center; font-size: .9rem; margin: 0 0 .8rem; }
.dv-form .dv-later input { width: auto; margin: 0; }
.dv-choice label { flex: 1 1 30%; }
/* The plan card, in order (10 October 2026): a numbered step a line, its bar
   and when it gets there. One meaning a colour: blue on its way, green on plan
   or done (✓), amber over this month's step (!). */
.pg-h { display: flex; justify-content: space-between; align-items: baseline; gap: .5rem; }
.pg-h small { font-size: .72rem; color: var(--muted); font-weight: 400; letter-spacing: 0; text-transform: none; }
.pg { display: block; padding: .8rem 0; border-top: 0; text-decoration: none; color: inherit; }
.card > h2 + .pg { border-top: 0; }
.pg-top { display: flex; align-items: center; gap: .55rem; }
.pg-n { flex: none; width: 22px; height: 22px; border-radius: 50%; display: grid; place-items: center;
  font-size: .72rem; font-weight: 700; border: 1.5px solid var(--muted); color: var(--muted); }
.pg-done .pg-n { background: var(--gain); border-color: var(--gain); color: var(--card); }
.pg-on .pg-n { border-color: var(--gain); color: var(--gain); }
.pg-over .pg-n { border-color: var(--warn); color: var(--warn); }
.pg-name { flex: 1; font-weight: 600; color: var(--ink); font-size: .98rem; }
.pg-fig { font-size: .84rem; color: var(--muted); white-space: nowrap; }
.pg-go { color: var(--muted); }
.pg-bar { display: block; position: relative; height: 6px; border-radius: 999px; background: var(--raised);
  margin: .45rem 0 .3rem 30px; }
.pg-bar i { position: absolute; top: 0; bottom: 0; left: 0; border-radius: 999px; background: var(--accent-text); }
.pg-done .pg-bar i, .pg-on .pg-bar i { background: var(--gain); }
.pg-over .pg-bar i { background: var(--warn-fill); }
.pg-line { display: block; margin-left: 30px; font-size: .8rem; color: var(--muted); }
.pg-line em { font-style: normal; font-weight: 600; color: var(--gain); }
.pg-over .pg-line em { color: var(--warn); }
.pg-line b { color: var(--ink); font-weight: 600; }
/* The share to take out over a ceiling, red; the room under it, green. */
.pg-line b.pg-out { color: var(--danger); }
.pg-line b.pg-room { color: var(--gain); }
/* The card's key: each mark as the rows draw it, with its meaning. */
.pg-key { display: flex; flex-wrap: wrap; gap: .35rem .9rem; margin: .6rem 0 0; font-size: .74rem; color: var(--muted); }
.pg-key > span { display: inline-flex; align-items: center; gap: .3rem; }
.pg-key .pg-n { width: 16px; height: 16px; font-size: .6rem; font-style: normal; border-width: 1.5px; }
.pg-key .pg-on-k .pg-n { border-color: var(--gain); color: var(--gain); }
.pg-key .pg-over-k .pg-n { border-color: var(--warn); color: var(--warn); }
.pg-key .pg-done-k .pg-n { background: var(--gain); border-color: var(--gain); color: var(--card); }
.pg-foot { display: flex; flex-wrap: wrap; gap: .3rem 1rem; font-size: .74rem; color: var(--muted); margin: .5rem 0 0; }
.pg-foot span { flex: 1 1 100%; }
/* Crypto's holdings in its panel, each with its change so far (10 October 2026). */
.ch { margin: .2rem 0 .6rem; }
.ch-row { display: grid; grid-template-columns: 1fr auto auto; gap: .7rem; align-items: baseline;
  padding: .4rem 0; border-bottom: 1px solid var(--hairline); font-size: .86rem; }
.ch-t small { color: var(--muted); font-size: .74rem; }
.ch-v { color: var(--muted); font-variant-numeric: tabular-nums; }
.ch-g { text-align: right; font-weight: 600; font-variant-numeric: tabular-nums; min-width: 7.5rem; }
.ch-g.up { color: var(--gain); } .ch-g.down { color: var(--danger); }
/* The pot's and crypto's step-down, a bar a month (10 October 2026). */
.sb-line { font-size: .8rem; margin: .2rem 0 .4rem; }
.sb-row { display: grid; grid-template-columns: 4.2rem 1fr 4.8rem; align-items: center; gap: .5rem;
  margin: .3rem 0; font-size: .8rem; }
.sb-m { color: var(--muted); white-space: nowrap; }
.sb-n { text-align: right; color: var(--ink); font-variant-numeric: tabular-nums; white-space: nowrap; }
.sb-t { position: relative; height: 12px; }
.sb-t i { position: absolute; left: 0; top: 0; bottom: 0; border-radius: 3px; background: var(--hairline);
  border: 1px solid var(--line); box-sizing: border-box; }
.sb-t b { position: absolute; left: 0; top: 2px; bottom: 2px; border-radius: 2px; background: var(--gain); }
.sb-over .sb-t b { background: var(--warn-fill); }
.sb-over .sb-n { color: var(--warn); }
.sb-now .sb-m, .sb-now .sb-n { color: var(--ink); font-weight: 700; }
.sb-final .sb-t i { background: var(--accent-text); border-color: var(--accent-text); }
.sb-final .sb-n { font-weight: 700; }
.pp-table { width: 100%; border-collapse: collapse; font-size: .88rem; margin: .4rem 0 .6rem; }
.pp-table td { padding: .4rem .2rem; border-bottom: 1px solid var(--hairline); color: var(--ink); }
.pp-table td.num { text-align: right; }
.pp-table small { display: block; color: var(--muted); font-size: .74rem; }
.pp-table small.is-over { color: var(--warn); font-weight: 600; }
.gt-tabs { display: flex; gap: 4px; flex-wrap: wrap; margin: .2rem 0 .6rem; }
.gt-tabs input { position: absolute; opacity: 0; pointer-events: none; width: 1px; height: 1px; margin: 0; }
.gt-tabs label { border: 1px solid var(--line); border-radius: 8px; padding: .4rem .6rem;
  font-size: .8rem; color: var(--ink); margin: 0; }
.gt-tabs input:checked + label { border-color: var(--ink); font-weight: 600; }
.gt-pane { display: none; }
.pp:has(#gt-core:checked) .gt-pane-core,
.pp:has(#gt-satellite:checked) .gt-pane-satellite,
.pp:has(#gt-crypto:checked) .gt-pane-crypto { display: block; }
.pp-key { font-size: .74rem; margin: .2rem 0; }
/* A month's NEOM plan units to approve (plan_units.py, 9 October 2026). */
.pu-sum { font-size: .84rem; color: var(--muted); margin: .1rem 0 .7rem; }
.pu-sum b { color: var(--ink); }
.pu { width: 100%; border-collapse: collapse; font-size: .86rem; }
.pu th { font-size: .72rem; color: var(--muted); font-weight: 600; text-align: left;
  padding: .2rem .3rem; border-bottom: 1px solid var(--line); white-space: nowrap; }
.pu th.num, .pu td.num { text-align: right; }
.pu td { padding: .28rem .3rem; border-bottom: 1px solid var(--hairline); color: var(--ink); }
.pu td:first-child { white-space: nowrap; }
.pu td small { display: block; color: var(--muted); font-size: .7rem; }
.pu input { width: 4.6rem; text-align: right; padding: .3rem .4rem; }
.pu-note { font-size: .78rem; color: var(--muted); margin: .6rem 0 .8rem; }
#plan-units button[type="submit"] { width: 100%; }
.mv-gap b, .mv-split b { color: var(--warn); }
.mv-cash-head { display: flex; justify-content: space-between; align-items: center; gap: .6rem; }
.mv-cash-head h2 { margin: 0; }
.mv-cash-btns { display: flex; gap: .4rem; flex-wrap: wrap; justify-content: flex-end; }

/* Toward your plan (next_steps.toward, 9 October 2026): now as a bar, the
   plan as a black mark. */
.dr-row { padding: .55rem 0; border-top: 1px solid var(--hairline); }
.dr-row:first-of-type { border-top: 0; }
.dr-top { display: flex; justify-content: space-between; gap: .6rem; font-size: .9rem; }
.dr-top b { color: var(--ink); }
.dr-top span { color: var(--muted); font-size: .8rem; white-space: nowrap; }
.dr-track { position: relative; height: 6px; border-radius: 999px; background: var(--raised);
  margin: .35rem 0 .2rem; }
.dr-now { position: absolute; top: 0; bottom: 0; left: 0; border-radius: 999px; background: var(--warn-fill); }
.dr-now.dr-banned { background: var(--danger); }
.dr-now.dr-core, .dr-now.dr-safety { background: var(--gain); }
/* The pot and crypto under this month's ceiling are on plan: green, as on the
   Dashboard's card (16 October 2026); over it they stay orange. */
.dr-now.dr-on, .dr-now.dr-done { background: var(--gain); }
.dr-say-on, .dr-say-done { color: var(--gain); }
.dr-say-over { color: var(--warn); }
.dr-goal { position: absolute; top: -4px; bottom: -4px; width: 3px; background: var(--ink);
  border-radius: 2px; }
.dr-sub { font-size: .76rem; color: var(--muted); }
.mv-plan { display: block; background: color-mix(in srgb, var(--accent-text) 12%, transparent);
  border: 1px solid transparent; border-radius: .875rem; padding: .7rem .875rem; margin: 0 0 1rem;
  font-size: .86rem; color: var(--ink); }
.mv-plan b { display: block; font-size: .9375rem; color: var(--accent-text); }
.mv-plan small { display: block; color: var(--muted); margin-top: .2rem; font-size: .78rem; }

/* A paragraph that carries an i is a div, because a <details> inside a <p>
   closes the paragraph and drops the i onto a line of its own: "remove i
   inbetween ... keep it next to what it related to" (14 October 2026). It
   keeps a paragraph's margins, at no weight, so its own class still decides. */
:where(div.p) { margin-block: 1em; }

/* The phone widget's script, shown once to copy (widget_key.html). */
.widget-script { width: 100%; box-sizing: border-box; font: 11px/1.4 ui-monospace, SFMono-Regular, Menlo, monospace; }
.widget-steps { padding-inline-start: 1.2rem; }
.widget-steps li { margin: 0 0 .6rem; }

/* One account at a time under "platform" (14 October 2026): grey pills, the
   chosen one filled, as Week, Month, Year are; a row that scrolls if it must. */
.acct-tabs { display: flex; gap: 5px; overflow-x: auto; scrollbar-width: none; margin: 0 0 var(--space); }
.acct-tabs::-webkit-scrollbar { display: none; }
.acct-tabs a { flex: 0 0 auto; padding: 3px 9px; min-height: 32px; display: inline-flex; align-items: center;
  border-radius: 999px; background: var(--raised); color: var(--muted); font-size: 13px; font-weight: 600;
  text-decoration: none; white-space: nowrap; }
.acct-tabs a.is-on { background: var(--ink); color: var(--card); }
/* The P/L calendar and You against the market (14 October 2026): a month
   or a day a tile, tinted by which way it went. */
.cal-top { display: flex; align-items: center; justify-content: space-between; gap: .5rem; }
.cal-top h2 { margin: 0; }
.cal-total { display: flex; align-items: baseline; justify-content: space-between; gap: .5rem;
  margin: .6rem 0 .5rem; font-variant-numeric: tabular-nums; }
.cal-step { display: inline-flex; align-items: baseline; gap: .55rem; }
.cal-step a { text-decoration: none; font-size: 1.15rem; padding: 0 .2rem; }
.cal { width: 100%; border-collapse: separate; border-spacing: 4px; table-layout: fixed; }
.cal th { font-size: .7rem; font-weight: 500; color: var(--muted); text-align: center; padding: 0; }
.cal td { padding: 0; border: 0; }
.cal-cell > a, .cal-cell > div { display: flex; flex-direction: column; align-items: center; gap: 1px;
  border-radius: 8px; padding: .4rem .1rem; text-decoration: none; color: inherit;
  background: var(--ground); font-variant-numeric: tabular-nums; line-height: 1.2; }
.cal-cell b { color: var(--ink); font-weight: 600; font-size: .8rem; }
.cal-cell span { font-size: .74rem; white-space: nowrap; }
.cal-days .cal-cell > a, .cal-days .cal-cell > div { padding: .3rem 0; }
.cal-days .cal-cell span { font-size: .6rem; letter-spacing: -.02em; }
.cal-cell.up > a, .cal-cell.up > div { background: color-mix(in srgb, var(--gain) 14%, transparent); color: var(--gain); }
.cal-cell.down > a, .cal-cell.down > div { background: var(--danger-bg); color: var(--danger); }
.cal-cell.is-empty b { color: var(--muted); font-weight: 400; }
.cal-rebuilt { font-style: normal; color: var(--muted); font-size: .7rem; margin-left: 1px; }
.cal-key { margin: .3rem 0 0; font-size: .75rem; }
/* A tile split by account (15 October 2026): the pop-up a tap opens. */
.cal-sheet .part-note { display: block; font-size: .75rem; font-weight: 400; margin-top: .1rem; }
.cal-sheet .cal-rest { display: flex; justify-content: space-between; gap: 1rem; padding: .7rem 0;
  border-bottom: 1px solid var(--hairline); color: var(--muted); }
.vs-key { display: flex; justify-content: space-between; margin: .3rem 0 0; font-size: .85rem; }
/* The index's line and its dot in purple, apart from his red and green:
   "Make it purple" (14 October 2026), as the picture he approved drew it. */
.vs-index { color: var(--vs-line); }
.versus .journey-index { stroke: var(--vs-line); stroke-width: 1.8; }

/* "Prices not updated" (_stale_prices.html, 15 October 2026): a row a
   holding, its day in red, and beneath it Ask again or today's price. */
a.price-day { text-decoration: none; }
.stale-rows { list-style: none; margin: 0; padding: 0; }
.stale-rows li { padding: .65rem 0; border-bottom: 1px solid var(--hairline); }
.stale-rows li:last-child { border-bottom: 0; }
.stale-top { display: flex; justify-content: space-between; align-items: baseline; gap: 1rem; }
.stale-form { display: flex; align-items: center; gap: .5rem; margin: .45rem 0 0; }
.stale-form input[inputmode] { width: 8rem; font-size: 16px; }

/* The pop-ups of 16 October 2026: an account, the day's movers, his
   capital, a stock's news. "I like the idea but design I feel is so basic and
   cheap ... the sizes and everything should be relooked", then "Go" to the
   pictures: one large figure, digits of one width, its percentage a tinted
   pill, the rest on tiles and rows a size below. Every colour is a token. */
.pp {
  --pp-up: color-mix(in srgb, var(--gain) 15%, transparent);
  --pp-down: color-mix(in srgb, var(--danger) 15%, transparent);
  --pp-go: color-mix(in srgb, var(--warn-fill) 16%, transparent);
}
.pp .num, .pp-big, .pp-tile b, .pp-row .pp-amt { font-variant-numeric: tabular-nums; }
.pp-head { display: flex; align-items: center; gap: .75rem; margin: 0 0 .9rem; }
.pp-av { width: 2.5rem; height: 2.5rem; border-radius: .75rem; background: var(--raised);
  display: grid; place-items: center; font-weight: 600; font-size: 1rem; flex: none; }
.pp-title { font-size: 1.125rem; font-weight: 600; letter-spacing: -.01em; margin: 0; line-height: 1.2; }
.pp-sub { font-size: .8125rem; font-weight: 500; color: var(--muted); margin: .15rem 0 0; }
.pp-fig { display: flex; align-items: baseline; flex-wrap: wrap; gap: .5rem; margin: .15rem 0 .25rem; }
.pp-big { font-size: 2.125rem; font-weight: 600; letter-spacing: -.025em; line-height: 1.05; }
.pp-unit { font-size: .9375rem; font-weight: 500; color: var(--muted); }
.pp-pill { display: inline-flex; align-items: center; gap: .2rem; font-size: .8125rem; font-weight: 600;
  line-height: 1; padding: .32rem .5rem; border-radius: 999px; white-space: nowrap;
  background: var(--raised); color: var(--muted); font-variant-numeric: tabular-nums; }
.pp-pill.up { background: var(--pp-up); color: var(--gain); }
.pp-pill.down { background: var(--pp-down); color: var(--danger); }
.pp-big.up, .pp-tile b.up, .pp-amt.up, .pp-mv .up { color: var(--gain); }
.pp-big.down, .pp-tile b.down, .pp-amt.down, .pp-mv .down { color: var(--danger); }
.pp-tiles { display: grid; grid-template-columns: 1fr 1fr; gap: .625rem; margin: 1rem 0 0; }
.pp-tile { background: var(--raised); border-radius: 1rem; padding: .8rem .875rem .75rem; min-height: 5.75rem;
  display: flex; flex-direction: column; justify-content: space-between; color: inherit; text-decoration: none; }
.pp-tile > span:first-child { display: flex; justify-content: space-between; font-size: .78rem;
  font-weight: 500; color: var(--muted); }
.pp-tile b { font-size: 1.1875rem; font-weight: 600; letter-spacing: -.015em; margin: .45rem 0 .35rem; line-height: 1.15; }
.pp-of { font-size: .75rem; color: var(--muted); white-space: nowrap; }
.pp-btns { display: grid; grid-template-columns: repeat(3, 1fr); gap: .5rem; margin: 1rem 0 0; }
.pp-btn { height: 2.875rem; border-radius: .875rem; background: var(--raised); display: grid; place-items: center;
  font-weight: 600; font-size: .9rem; color: var(--ink); text-decoration: none; }
.pp-btn.go { background: var(--pp-go); color: var(--warn-fill); }
.pp-sec { display: flex; justify-content: space-between; align-items: baseline; font-size: .9375rem;
  font-weight: 600; margin: 1.35rem 0 .5rem; }
.pp-sec small { font-size: .78rem; font-weight: 500; color: var(--muted); }
.pp-rows { list-style: none; margin: .5rem 0 0; padding: 0; }
.pp-row, .pp-rows > li > a { display: flex; align-items: center; gap: .75rem; padding: .7rem 0;
  color: inherit; text-decoration: none; }
.pp-rows > li + li { border-top: 1px solid var(--hairline); }
.pp-nm { flex: 1; min-width: 0; font-size: .9375rem; font-weight: 500; }
.pp-nm small { display: block; font-size: .78rem; font-weight: 500; color: var(--muted); margin-top: .1rem; }
.pp-amt { font-size: .9375rem; font-weight: 600; text-align: right; white-space: nowrap; }
.pp-chev { color: var(--muted); opacity: .6; }
.pp-dot { width: .625rem; height: .625rem; border-radius: 3px; flex: none; }
.pp-bar { display: flex; gap: 2px; height: .5rem; border-radius: 4px; overflow: hidden; margin: .9rem 0 .4rem; }
.pp-movers { display: grid; grid-template-columns: 1fr 1fr; gap: 0 .75rem; margin-top: .9rem; }
.pp-mv-h { margin: 0 0 .2rem; font-size: .72rem; color: var(--muted); white-space: nowrap; }
.pp-mv { display: grid; grid-template-columns: max-content minmax(0, 1fr) 3.45rem; column-gap: .25rem;
  align-items: baseline; padding: .3rem 0; border-top: 1px solid var(--hairline); color: inherit;
  text-decoration: none; font-size: .76rem; font-variant-numeric: tabular-nums; }
.pp-mv:first-of-type { border-top: 0; }
.pp-tk { font-weight: 700; }
.pp-mv span { text-align: right; font-weight: 600; white-space: nowrap; }
.pp-news { list-style: none; margin: 0; padding: 0; }
.pp-news li + li { border-top: 1px solid var(--hairline); }
.pp-news a { display: flex; align-items: flex-start; gap: .75rem; padding: .75rem 0; color: inherit; text-decoration: none; }
.pp-src { width: 2.125rem; height: 2.125rem; border-radius: .625rem; display: grid; place-items: center;
  flex: none; background: var(--raised); color: var(--muted); font-weight: 700; font-size: .68rem; }
.pp-src.sec { background: var(--pp-down); color: var(--danger); }
.pp-news b { font-size: .9375rem; font-weight: 600; line-height: 1.35; display: -webkit-box;
  -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }
.pp-news b.down { color: var(--danger); }
.pp-news a > span { flex: 1; min-width: 0; }
.pp-news a > .pp-src { flex: none; }
.pp-news-top { display: flex; align-items: baseline; gap: .5rem; }
.pp-news-top b { flex: 1; min-width: 0; }
.pp-news-top .news-when { flex: none; margin-left: auto; white-space: nowrap; color: var(--warn);
  font-size: .75rem; font-weight: 500; line-height: 1.35; }
.pp-news small { display: flex; flex-wrap: wrap; gap: .5rem; align-items: center; font-size: .78rem;
  font-weight: 500; color: var(--muted); margin-top: .3rem; }
/* An account's name on Positions opens it at a glance. */
a.acct-open, a.capital-open { color: inherit; text-decoration: none; }
a.capital-open > span { color: var(--muted); }
a.acct-open span { color: var(--muted); font-weight: 400; }
.pp-more > summary { list-style: none; height: 2.875rem; border-radius: .875rem; background: var(--raised);
  display: grid; place-items: center; font-weight: 600; font-size: .9rem; margin: .6rem 0 0; cursor: pointer; }
.pp-more > summary::-webkit-details-marker { display: none; }
.pp-more[open] > summary { display: none; }

/* Every pop-up in the look of 16 October 2026 (.pp): the round of 17
   October, "Go" to standardising. Generic sheets take it from their own
   classes, so a pop-up added later has it without asking. */
details.sheet > .sheet-panel {
  --pp-up: color-mix(in srgb, var(--gain) 15%, transparent);
  --pp-down: color-mix(in srgb, var(--danger) 15%, transparent);
  --pp-go: color-mix(in srgb, var(--warn-fill) 16%, transparent);
}
details.sheet .sheet-head { font-size: 1.125rem; font-weight: 600; letter-spacing: -.01em; margin: 0; line-height: 1.25; }
details.sheet .sheet-said { font-size: .8125rem; font-weight: 500; color: var(--muted); margin: .15rem 0 .85rem; }
details.sheet .part-sheet-total, #where-from .part-sheet-total { font-size: .9375rem; color: var(--muted); margin: .1rem 0 .9rem; }
details.sheet .part-sheet-total strong { font-size: 2.125rem; font-weight: 600; letter-spacing: -.025em;
  font-variant-numeric: tabular-nums; margin-inline-end: .35rem; }
details.sheet .part-sheet-total.up strong { color: var(--gain); }
details.sheet .part-sheet-total.down strong { color: var(--danger); }
details.sheet .sheet-rows li > a, details.sheet .sheet-rows li > .part-row,
details.sheet .split-panel .sheet-rows li { padding: .8rem 0; align-items: center; font-size: .9375rem;
  font-weight: 500; border-bottom: 1px solid var(--hairline); }
details.sheet .sheet-rows strong { font-weight: 600; font-variant-numeric: tabular-nums; }
details.sheet .sheet-rows small { display: block; font-size: .78rem; font-weight: 500; }
details.sheet .sheet-rows .sheet-sub a { display: inline; padding: 0; border: 0; font-size: inherit; }
details.sheet .sheet-rows .sheet-sub { font-size: .8125rem; color: var(--muted); padding: .3rem 0 .3rem 1rem;
  display: flex; justify-content: space-between; font-variant-numeric: tabular-nums; }
details.sheet .pp-pill { margin-inline-start: .45rem; }
details.sheet .split-more { text-align: center; margin: 1rem 0 0; }
details.sheet .split-more a { display: grid; place-items: center; height: 2.875rem; border-radius: .875rem;
  background: var(--raised); color: var(--ink); font-weight: 600; font-size: .9rem; text-decoration: none; }
/* Money on the move's steps: a bar of four, its word under each. */
.mv-sheet .chev { gap: 4px; margin: .4rem 0 1.1rem; }
.mv-sheet .chev i { clip-path: none; padding: 1.05rem 0 0; background: none; color: var(--muted);
  position: relative; font-size: .72rem; font-weight: 600; }
.mv-sheet .chev i::before { content: ""; position: absolute; top: 0; left: 0; right: 0; height: .4rem;
  border-radius: 999px; background: var(--raised); }
.mv-sheet .chev .done::before { background: var(--gain); }
.mv-sheet .chev .now::before { background: var(--warn-fill); }
.mv-sheet .chev .done { color: var(--gain); }
.mv-sheet .chev .now { color: var(--warn-fill); }
.mv-form label { font-size: .78rem; font-weight: 500; color: var(--muted); }
.mv-form input[inputmode], .mv-form input[type=date], .mv-form select { display: block; width: 100%;
  margin-top: .3rem; height: 2.875rem; padding: 0 .85rem; border: 0; border-radius: .75rem;
  background: var(--raised); color: var(--ink); font-size: 16px; font-weight: 600;
  font-variant-numeric: tabular-nums; }
.mv-form .mv-row { gap: .625rem; margin-bottom: .85rem; }
.mv-form button[type=submit] { width: 100%; height: 3rem; border-radius: .875rem; font-size: 1rem;
  font-weight: 600; margin-top: .4rem; }

/* A holding's score beside its ticker on Positions (17 October 2026): the
   stock page's ring, small, its letter alone, its letter centred on the ring's middle ("make
   letter centralized in the circle not shifted top of the circle"): the
   letter's box trimmed to the capital's own height, so no space above or
   below it moves it off centre. */
.tk-line { white-space: nowrap; }
.sc-tag { display: inline-flex; vertical-align: middle; margin-inline-start: .25rem; text-decoration: none; }
.sc-dot { --sc-fill: 0%; --sc-tone: var(--gain); position: relative; width: 16px; height: 16px; border-radius: 50%;
  display: flex; align-items: center; justify-content: center;
  background: conic-gradient(var(--sc-tone) 0 var(--sc-fill), color-mix(in srgb, var(--sc-tone) 18%, transparent) var(--sc-fill) 100%); }
.sc-dot::before { content: ""; position: absolute; inset: 2px; border-radius: 50%; background: var(--card); }
.sc-dot b { position: relative; display: block; font-size: .56rem; font-weight: 700; line-height: 1;
  color: var(--sc-tone); text-box: trim-both cap alphabetic; }
.sc-dot.sc-c { --sc-tone: var(--warn-fill); }
.sc-dot.sc-d { --sc-tone: var(--danger); }

/* Every icon on a screen in lines (icons.py, 17 October 2026: "I want all
   icons of the app follow same this style"): strokes in the text's colour;
   a line's mark sits on a grey tile, as News' do. */
svg.ic { width: 1em; height: 1em; fill: none; stroke: currentColor; stroke-width: 1.8;
  stroke-linecap: round; stroke-linejoin: round; vertical-align: -.14em; flex: none; }
.bp-chip svg.ic, .pp-pill svg.ic, .even-badge svg.ic, .bp-line svg.ic { margin-inline-end: .25em; }
.bell-ic svg.ic { width: 15px; height: 15px; }

/* The 20-, 50- and 200-day averages over a price chart in Saham's colours,
   and his average now, dotted across; their key is one line above the chart,
   each by its colour and figure (17 October 2026). */
.tc-ma { fill: none; stroke-width: 1.2; stroke-linejoin: round; opacity: .9; }
.tc-ma.ma20 { stroke: var(--ma20); }
.tc-ma.ma50 { stroke: var(--ma50); }
.tc-ma.ma200 { stroke: var(--ma200); }
.tc-avg-now { stroke: var(--warn); stroke-width: 1.2; stroke-dasharray: 1.5 3; stroke-linecap: round; }
.tc-legend { display: flex; gap: .7rem; margin: .1rem 0 .15rem; font-size: .74rem; font-weight: 600;
  font-variant-numeric: tabular-nums; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.tc-legend .ma20 { color: var(--ma20); }
.tc-legend .ma50 { color: var(--ma50); }
.tc-legend .ma200 { color: var(--ma200); }
.tc-legend .tc-lg-avg { color: var(--warn); }
.tc-legend .tc-k-other { color: var(--muted); font-weight: 500; }

/* Radar (radar.py, 17 October 2026): a card under the wallet with two
   lanes, Swing and Long hold, and a section under a stock's chart. A
   reason tested and kept is ticked green, a tested warning orange, what is
   on trial grey and says so. */
.rd .rd-h { display: flex; align-items: center; gap: .45rem; margin: 0 0 .5rem; }
.rd .rd-h svg.ic { width: 1.15em; height: 1.15em; }
.rd-badge { margin-inline-start: auto; font-size: .66rem; font-weight: 600; letter-spacing: .03em;
  text-transform: uppercase; color: var(--muted); background: var(--raised); border-radius: 99px; padding: .15rem .5rem; }
.rd-lanes { display: flex; gap: .4rem; margin: 0 0 .25rem; }
.rd-lanes input { position: absolute; width: 1px; height: 1px; margin: 0; opacity: 0; pointer-events: none; }
.rd-lanes label { flex: 1; text-align: center; padding: .4rem .3rem; border-radius: 10px; background: var(--raised);
  font-size: .86rem; font-weight: 600; color: var(--muted); cursor: pointer; }
.rd-lanes label small { display: block; font-size: .66rem; font-weight: 500; }
.rd-lanes input:checked + label { background: var(--ink); color: var(--card); }
.rd .rd-pane-long { display: none; }
.rd:has(#rd-long:checked) .rd-pane-long { display: block; }
.rd:has(#rd-long:checked) .rd-pane-swing { display: none; }
.rd-list { list-style: none; margin: 0; padding: 0; }
.rd-row { display: grid; grid-template-columns: auto 1fr auto; gap: .1rem .55rem; align-items: center;
  padding: .5rem 0; border-top: 1px solid var(--hairline); }
.rd-row .tk { font-weight: 700; }
.rd-px { font-variant-numeric: tabular-nums; font-size: .9rem; }
.rd-why { grid-column: 1 / -1; display: flex; flex-wrap: wrap; gap: .15rem .55rem; font-size: .78rem; color: var(--muted); }
.rd-w { display: inline-flex; align-items: center; gap: .2rem; }
.rd-w i { font-style: normal; font-size: .66rem; font-weight: 600; border: 1px solid var(--line); border-radius: 4px; padding: 0 .25rem; }
.rd-tested { color: var(--gain); }
.rd-warn { color: var(--warn); }
.rd-call { justify-self: start; font-size: .72rem; font-weight: 600; border-radius: 99px; padding: .16rem .55rem; white-space: nowrap; }
.rd-call.good { background: color-mix(in srgb, var(--gain) 14%, transparent); color: var(--gain); }
.rd-call.exit { background: color-mix(in srgb, var(--accent-text) 13%, transparent); color: var(--accent-text); }
.rd-call.warn { background: color-mix(in srgb, var(--warn-fill) 18%, transparent); color: var(--warn); }
.rd-none { margin: .4rem 0; font-size: .84rem; color: var(--muted); }
.rd-care { display: flex; align-items: center; gap: .35rem; padding: .55rem 0 .2rem; border-top: 1px solid var(--hairline);
  font-size: .86rem; font-weight: 500; color: var(--warn); text-decoration: none; }
.rd-care span:last-child { margin-inline-start: auto; }
.rd-rec { margin: .4rem 0 0; font-size: .74rem; color: var(--muted); }
.rd-sub { margin: .3rem 0 0; font-size: .72rem; color: var(--muted); }
.rd-lane-row { display: flex; align-items: center; gap: .55rem; margin: .45rem 0 .1rem; }
.rd-lane-n { font-size: .74rem; font-weight: 700; color: var(--muted); min-width: 4.6rem; }
.rd-quiet { font-size: .8rem; color: var(--muted); }
.rd-zone { margin: .5rem 0 .4rem; }
.rd-bar { position: relative; height: 10px; border-radius: 6px; background: var(--raised); margin: .35rem 0 .45rem; }
.rd-bar .rd-buy, .rd-bar .rd-sell { position: absolute; top: 0; bottom: 0; border-radius: 6px; }
.rd-bar .rd-buy { background: color-mix(in srgb, var(--gain) 40%, transparent); }
.rd-bar .rd-sell { background: color-mix(in srgb, var(--accent-text) 35%, transparent); }
.rd-bar .rd-now { position: absolute; top: -5px; width: 3px; height: 20px; margin-inline-start: -1.5px; background: var(--ink); border-radius: 2px; }
.rd-bar .rd-be { position: absolute; top: -4px; height: 18px; border-inline-start: 2px dashed var(--warn); }
.rd-zone-leg { display: flex; justify-content: space-between; gap: .5rem; font-size: .76rem; font-variant-numeric: tabular-nums; }
.rd-zone-leg small { display: block; color: var(--muted); font-size: .68rem; }
.rd-zone-leg > span:last-child { text-align: end; }
.rd-be-t { color: var(--warn); align-self: center; }
.rd-rs { list-style: none; margin: .45rem 0 0; padding: 0; }
.rd-rs li { display: flex; gap: .5rem; align-items: baseline; padding: .3rem 0; border-top: 1px solid var(--hairline); font-size: .84rem; }
.rd-rs li i { font-style: normal; font-size: .7rem; font-weight: 600; min-width: 3.9rem; display: inline-flex; align-items: center; gap: .15rem; }
.rd-rs li span { color: var(--ink); }
.rd-rs li small { margin-inline-start: auto; color: var(--muted); font-size: .72rem; white-space: nowrap; }
.rd-rs li.rd-trial i, .rd-rs li.rd-trial small { color: var(--muted); }

/* Radar's tab (18 October 2026), opened from the radar in the top bar. */
.rd-title { display: flex; align-items: center; gap: .5rem; }
.rd-title svg.ic { width: 1em; height: 1em; }
.rd-title .rd-badge { font-size: .62rem; }
.rd-page .rd-lanes { margin: .7rem 0 .8rem; }
.rd-page .card { margin-bottom: .8rem; }
.rd-sec { display: flex; align-items: center; gap: .45rem; margin: 0 0 .2rem; font-size: 1rem; }
.rd-n { font-size: .72rem; font-weight: 600; color: var(--muted); background: var(--raised); border-radius: 99px; padding: .05rem .45rem; }
.rd-more > summary { list-style: none; cursor: pointer; padding: .55rem 0 .1rem; border-top: 1px solid var(--hairline);
  font-size: .86rem; font-weight: 600; color: var(--accent-text); }
.rd-more > summary::-webkit-details-marker { display: none; }
.rd-more[open] > summary { display: none; }
.tb-radar { position: relative; }
/* The night's new calls since Radar was last opened, in Radar's blue so it
   is not read as the bell's unread red (18 October 2026). */
.tb-radar .rd-count { background: var(--accent-text); }
.tb-radar svg.ic { width: 20px; height: 20px; }
.tb-radar.is-on { color: var(--chrome-ink); background: rgba(255, 255, 255, .12); }
/* Settings' Theme: three links drawn as the other segments. */
.seg-links a { text-decoration: none; border-bottom: 0; }
.seg-links a.on span { background: var(--card); color: var(--ink); font-weight: 700; box-shadow: 0 1px 2px rgba(0,0,0,.25); }

/* The percentage under P/L on Positions: read, not sorted (18 October 2026). */
.th-sub { font-weight: 500; color: var(--muted); }

/* The radar's island (radar_brief.js, 18 October 2026): a round bubble
   drops out of the radar in the top bar, opens outward into the night's
   brief, and closes back into a point. The bubble is the island itself,
   clipped to a circle at its top right, under the radar. Under every pop-up
   (their backdrop is 41), and gone at the first touch anywhere else. */
.rd-island { position: fixed; z-index: 40; top: calc(env(safe-area-inset-top, 0px) + 3.6rem); left: 10px; right: 10px;
  max-width: 460px; margin-left: auto; display: flex; gap: .7rem; align-items: center;
  padding: .75rem .9rem .75rem .75rem; border-radius: 26px; background: #0b0c0f; color: #fff; text-decoration: none;
  box-shadow: 0 10px 30px rgba(0, 0, 0, .45), 0 0 0 1px rgba(255, 255, 255, .06);
  clip-path: circle(150% at calc(100% - 26px) 26px);
  transition: clip-path .6s cubic-bezier(.32, .72, 0, 1), transform .45s cubic-bezier(.34, 1.4, .64, 1), opacity .3s; }
.rd-island[hidden] { display: none; }
.rd-island > * { transition: opacity .25s .2s; }
.rd-island.is-burst { clip-path: circle(21px at calc(100% - 26px) 26px); transform: translateY(-30px);
  background: radial-gradient(circle at calc(100% - 26px) 26px, #5a9cf8 0 5px, rgba(90, 156, 248, .25) 6px 13px, #0b0c0f 14px); }
.rd-island.is-burst > * { opacity: 0; transition: none; }
.rd-island.is-closing { clip-path: circle(0 at calc(100% - 26px) 26px); transform: translateY(-30px); opacity: 0;
  transition: clip-path .4s cubic-bezier(.32, .72, 0, 1), transform .4s, opacity .4s .1s; }
.rd-island.is-closing > * { opacity: 0; transition: opacity .12s; }
.rd-i-ic { flex: none; position: relative; display: flex; align-items: center; justify-content: center;
  width: 38px; height: 38px; border-radius: 50%; color: #5a9cf8; background: rgba(90, 156, 248, .18); }
.rd-i-ic::after { content: ""; position: absolute; inset: -4px; border-radius: 50%; border: 2px solid rgba(90, 156, 248, .45); }
.rd-i-ic svg.ic { width: 22px; height: 22px; }
.rd-i-txt { min-width: 0; }
.rd-i-txt b { display: block; font-size: .95rem; }
.rd-i-txt small { display: block; margin-top: .1rem; font-size: .78rem; color: #aab1bd; line-height: 1.3;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.rd-i-txt small.rd-i-exit { color: #ffb066; }
.rd-i-go { margin-inline-start: auto; flex: none; padding: .5rem .75rem; border-radius: 99px;
  background: #1a5fd0; color: #fff; font-size: .82rem; font-weight: 700; }
@media (display-mode: standalone) { .rd-island { top: calc(env(safe-area-inset-top, 0px) + 5.85rem); } }
@media (prefers-reduced-motion: reduce) {
  .rd-island, .rd-island.is-burst, .rd-island.is-closing { transform: none; clip-path: none; }
}

/* Radar on a holding's Buy and Sell form: the line of the side chosen. */
.rd-form { display: flex; gap: .5rem; align-items: flex-start; border-radius: 12px; padding: .55rem .7rem;
  margin: .2rem 0 .6rem; font-size: .84rem; background: color-mix(in srgb, var(--accent-text) 9%, transparent); }
.rd-form svg.ic { width: 1.1em; height: 1.1em; flex: none; margin-top: .1em; color: var(--accent-text); }
.rd-form b { color: var(--accent-text); }
.rd-form small { display: block; color: var(--muted); font-size: .74rem; margin-top: .15rem; }
.rd-form.is-careful { background: color-mix(in srgb, var(--warn-fill) 13%, transparent); }
.rd-form.is-careful b, .rd-form.is-careful svg.ic { color: var(--warn); }
.trade-form:has(input[name="action"][value="buy"]:checked) .rd-form-sell,
.trade-form:has(input[name="action"][value="sell"]:checked) .rd-form-buy { display: none; }

/* Never under 16px on a phone. Found by him on 8 October 2026, typing the
   shares to sell: "Sometimes the screen on the phone gets on side when I
   enter bought shares numbers I have to re zoom out and in to adjust it".
   An iPhone zooms into any box whose text is under 16px when it is tapped,
   and leaves the page zoomed and shifted afterwards; the boxes took their
   label's .9rem (14.4px), the search boxes 15px, Settings' day picker
   12.5px. Important, the one place it is used: a box's own smaller rule,
   added later, must not take it back under. At 16px it never zooms, and
   pinch-zoom stays his. */
@media (max-width: 760px), (pointer: coarse) {
  input, select, textarea { font-size: 16px !important; }
}

/* The market line's four on one chart (22 October 2026, index_trends.py):
   a pill a period, Week and Month's grey pills, and a row an index. */
.idx-periods { display: flex; gap: .35rem; margin: .2rem 0 .5rem; overflow-x: auto; scrollbar-width: none; }
.idx-periods::-webkit-scrollbar { display: none; }
.idx-periods label { flex: 0 0 auto; cursor: pointer; }
.idx-periods input { position: absolute; width: 1px; height: 1px; margin: 0; opacity: 0; pointer-events: none; }
.idx-periods span { display: block; padding: .3rem .7rem; border-radius: 999px; color: var(--muted);
  font-size: .85rem; font-weight: 600; }
.idx-periods input:checked + span { background: var(--raised); color: var(--ink); }
.idx-pane { display: none; }
.idx-sheet:has(input[value="1d"]:checked) .idx-pane[data-p="1d"],
.idx-sheet:has(input[value="5d"]:checked) .idx-pane[data-p="5d"],
.idx-sheet:has(input[value="1m"]:checked) .idx-pane[data-p="1m"],
.idx-sheet:has(input[value="6m"]:checked) .idx-pane[data-p="6m"],
.idx-sheet:has(input[value="ytd"]:checked) .idx-pane[data-p="ytd"],
.idx-sheet:has(input[value="1y"]:checked) .idx-pane[data-p="1y"],
.idx-sheet:has(input[value="5y"]:checked) .idx-pane[data-p="5y"] { display: block; }
.idx-list a { display: flex; align-items: center; gap: .6rem; padding: .55rem 0; border-top: 1px solid var(--line);
  color: inherit; text-decoration: none; }
.idx-list a:first-child { border-top: 0; }
.idx-list .idx-n { flex: 1; }
.idx-list b { min-width: 5.5rem; text-align: right; }
.idx-list .up { color: var(--gain); }
.idx-list .down { color: var(--danger); }

/* Positions' table in the earnings table's type (22 October 2026, "making
   numbers fonts like the table of earnings to fit more data than what my
   positions page currently do"): smaller, figures at medium weight, the
   currency once in its heading, so Target fits beside the price. */
.scroll-x table.hold-t { font-size: .8rem; line-height: 1.4; }
.hold-t th { font-size: .72rem; font-weight: 500; vertical-align: bottom; }
/* Every heading on one bottom line, a one-line heading level with the
   second line of the two-line ones (27 October 2026: "the colomn titles
   are not organized ... need to be aligned"). */
.hold-t th .th-plain { font-weight: 500; }
.hold-t strong { font-weight: 500; }
.scroll-x .hold-t th, .scroll-x .hold-t td { padding-inline: .35rem; }
.hold-t .tk-line a { font-size: .86rem; font-weight: 600; }
.hold-t .price-day { font-size: .72rem; }

/* News > Calendar (26 October 2026): his holdings' results, a tile a day.
   A confirmed day filled in the link blue, an estimated one outlined, a
   report already out green or red; the day's pop-up lists each. */
.ecal-top { display: flex; align-items: center; justify-content: space-between; gap: .5rem; margin: 0 0 .4rem; }
.ecal-top h2 { margin: 0; font-size: 1.22rem; font-weight: 700; }
.ecal-step { display: inline-flex; align-items: center; white-space: nowrap; }
.ecal-step b { font-size: .86rem; font-weight: 600; }
.ecal-step a { text-decoration: none; font-size: 1.25rem; line-height: 1; padding: .1rem .45rem; }
.ecal-now { margin: -.15rem 0 .35rem; font-size: .8rem; text-align: end; }
.ecal { border-collapse: separate; border-spacing: 3px; table-layout: fixed; margin: 0 -3px; width: calc(100% + 6px); }
.ecal th { font-size: .68rem; font-weight: 500; color: var(--muted); text-align: center; padding: 0 0 .15rem; border: 0; }
.ecal td { padding: 0; border: 0; vertical-align: top; }
.ed { display: flex; flex-direction: column; gap: 2px; min-height: 4.5rem; padding: .22rem .12rem .25rem;
  border-radius: 9px; background: var(--raised); color: var(--ink); text-decoration: none; overflow: hidden; }
.ed b { font-size: .74rem; font-weight: 600; color: var(--muted); padding-inline-start: .14rem; white-space: nowrap; }
.ed b small { font-size: .58rem; font-weight: 600; text-transform: uppercase; letter-spacing: .02em; }
.ed.has b { color: var(--ink); }
.ed.past { opacity: .55; }
.ed.past.has { opacity: .8; }
.ed.today { box-shadow: inset 0 0 0 1.6px var(--accent-text); }
.ed.today b { color: var(--accent-text); }
a.ed:active { filter: brightness(.94); }
.ecc { display: block; font-size: .62rem; font-weight: 700; letter-spacing: -.02em; text-align: center;
  border-radius: 5px; padding: 1px 0; line-height: 1.3; white-space: nowrap; overflow: hidden; text-overflow: clip; }
.c-conf { background: color-mix(in srgb, var(--accent-text) 16%, transparent); color: var(--accent-text); }
.c-est { box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--muted) 60%, transparent); color: var(--ink); }
.c-beat { background: color-mix(in srgb, var(--gain) 16%, transparent); color: var(--gain); }
.c-miss { background: var(--danger-bg); color: var(--danger); }
.c-met { background: var(--line); color: var(--muted); }
.c-mkt { background: color-mix(in srgb, var(--vs-line) 18%, transparent); color: var(--vs-line); }
/* When a report comes, at a glance (3 November 2026): before the open the
   pre-market's orange, after the close the after-hours blue, the rows' own
   session colours; an estimated day only outlined. */
.c-pre { background: color-mix(in srgb, var(--session-pre) 20%, transparent); color: var(--warn); }
.c-after { background: color-mix(in srgb, var(--session-after) 20%, transparent); color: var(--session-after); }
.c-tba { background: var(--line); color: var(--ink); }
.ecc.c-est { background: transparent; box-shadow: inset 0 0 0 1.2px currentColor; }
.ecc.c-tba.c-est { color: var(--muted); }
.ed .c-mkt { letter-spacing: -.03em; }
.ecd-mk { display: flex; flex-direction: column; gap: 1px; min-width: 0; }
.ecd-mk b { font-weight: 700; color: var(--vs-line); }
.ecd-mk small { font-size: .74rem; color: var(--muted); }
.ecd-mkt .ecd-fig { flex: 0 0 auto; max-width: 45%; }
.ec-more { font-size: .62rem; font-weight: 600; color: var(--muted); text-align: center; }
.ecal-key { display: flex; flex-wrap: wrap; gap: .3rem .85rem; margin: .5rem 0 0; font-size: .74rem; color: var(--muted); }
.ecal-key span { display: inline-flex; align-items: center; gap: .3rem; }
.ecal-key i.ecc { display: inline-block; width: 1.3rem; height: .7rem; padding: 0; }
.ecal-rest { list-style: none; margin: 0; padding: 0; }
.ecal-rest a { display: flex; justify-content: space-between; gap: 1rem; padding: .6rem 0;
  border-bottom: 1px solid var(--hairline); color: var(--ink); text-decoration: none; font-weight: 400; }
.ecal-rest li:last-child a { border-bottom: 0; }
.ecal-rest a span { color: var(--muted); font-size: .88rem; text-align: end; }
.ecd-when { margin: .8rem 0 .1rem; font-size: .78rem; font-weight: 700; color: var(--muted); }
.ecd-row { display: flex; align-items: center; gap: .6rem; padding: .62rem 0; border-bottom: 1px solid var(--hairline);
  color: var(--ink); text-decoration: none; font-weight: 400; }
.ecd-row b { min-width: 3.4rem; font-weight: 700; }
.ecd-tag { font-size: .72rem; font-weight: 600; border-radius: 6px; padding: 1px 6px; white-space: nowrap; }
.ecd-fig { margin-inline-start: auto; text-align: end; font-size: .88rem; color: var(--muted); }
.ecd-fig small { display: block; font-size: .74rem; }
.ecd-fig small.up { color: var(--gain); }
.ecd-fig small.down { color: var(--danger); }
.ecd-row i { font-style: normal; color: var(--muted); }
/* News has five tabs: on a phone they slide sideways rather than wrap. */
@media (max-width: 47.99rem) {
  .subnav[aria-label="News sections"] { flex-wrap: nowrap; overflow-x: auto; scrollbar-width: none; gap: 14px; }
  .subnav[aria-label="News sections"]::-webkit-scrollbar { display: none; }
  .subnav[aria-label="News sections"] a { flex: 0 0 auto; }
}

/* How many holdings an account had (holdings_count.py, 28 October 2026):
   the count beside its name opens it. */
a.hc-open { color: var(--muted); text-decoration: underline dotted; text-underline-offset: 3px; }
/* An account's heading on Positions: the account, its session, then the
   count, one row that wraps whole, never one piece lying over another
   (29 October 2026). */
.card > h2.group-h { display: flex; flex-wrap: wrap; align-items: center; gap: .4rem .55rem; }
.card > h2.group-h > a.acct-open { margin: 0; padding: .4rem .7rem; border-radius: 10px; }
.card > h2.group-h > .feed-wrap { display: inline-flex; align-items: center; gap: .35rem; }
.hc-chart { width: 100%; height: auto; display: block; margin-top: .6rem; overflow: visible; }
.hc-line { fill: none; stroke: var(--accent-text); stroke-width: 2; stroke-linejoin: round; }
.hc-area { fill: var(--accent-text); fill-opacity: .1; stroke: none; }
.hc-dot { fill: var(--accent-text); }
.hc-tick { font-size: 10px; fill: var(--muted); }

/* Price alerts (price_alerts.py, 28 October 2026): Saham's bell with a +
   beside a stock's name, its form stacked over the stock, and More > Price
   alerts. */
.co-tline { display: flex; align-items: center; }
.co-alert { display: inline-grid; place-items: center; position: relative; width: 30px; height: 30px;
  margin-left: .35rem; vertical-align: middle; color: var(--muted); }
.co-alert .ic { width: 22px; height: 22px; }
.co-alert.has { color: var(--warn); }
.co-alert i { position: absolute; top: -2px; right: -5px; min-width: 16px; height: 16px; padding: 0 3px;
  border-radius: 8px; background: var(--warn-fill); color: #fff; font: 600 10px/16px system-ui, sans-serif;
  font-style: normal; text-align: center; }
.pa-h { display: flex; justify-content: space-between; align-items: flex-start;
  border-bottom: 1px solid var(--hairline); padding-bottom: .55rem; }
.pa-x { color: var(--muted); font-size: 1.5rem; line-height: 1; text-decoration: none; padding: .1rem .3rem; }
.pa-now { margin: .7rem 0 0; display: flex; align-items: baseline; gap: .4rem; }
.pa-now b { display: inline; font-size: 1.6rem; font-variant-numeric: tabular-nums; }
.pa-now small { color: var(--muted); }
.pa-l { font-size: .82rem; color: var(--muted); font-weight: 600; margin: .95rem 0 .4rem; }
.pa-pills { display: grid; grid-template-columns: repeat(3, 1fr); gap: .45rem; }
.pa-pills label { position: relative; }
.pa-pills input { position: absolute; opacity: 0; width: 1px; height: 1px; }
.pa-pills span { display: block; border: 1px solid var(--hairline); border-radius: 10px; padding: .6rem 0;
  text-align: center; font-size: .92rem; }
.pa-pills input:checked + span { border-color: var(--gain); color: var(--gain); font-weight: 600;
  background: color-mix(in srgb, var(--gain) 8%, transparent); }
.pa-pills input:focus-visible + span { outline: 2px solid var(--accent-text); }
.pa-in { display: flex; align-items: baseline; gap: .5rem; border-bottom: 1.5px solid var(--hairline); }
.pa-in input { flex: 1; min-width: 0; border: 0; background: transparent; font-size: 1.7rem; font-weight: 700;
  color: var(--ink); padding: .2rem 0; font-variant-numeric: tabular-nums; }
.pa-in input:focus { outline: none; }
.pa-from { font-size: .85rem; font-weight: 600; white-space: nowrap; }
.pa-range { width: 100%; margin: .8rem 0 .1rem; accent-color: var(--gain); }
.pa-ends { display: flex; justify-content: space-between; font-size: .75rem; color: var(--muted); }
.pa-chips { display: flex; gap: .4rem; margin-top: .55rem; }
.pa-chips button { flex: 1; border: 0; border-radius: 999px; background: var(--raised); color: var(--ink);
  padding: .4rem 0; font-size: .82rem; }
.pa-select, .pa-note { width: 100%; border: 0; border-radius: 10px; background: var(--raised); color: var(--ink);
  padding: .7rem .8rem; font-size: .95rem; }
.pa-btn { display: block; width: 100%; margin-top: 1.1rem; border: 0; border-radius: 12px; background: var(--gain);
  color: #fff; font-weight: 600; font-size: 1rem; padding: .8rem; }
.pa-link { display: block; text-align: center; margin-top: .8rem; font-size: .9rem; }
.pa-card h2 { display: flex; justify-content: space-between; }
.pa-row { display: grid; grid-template-columns: 3.6rem 1fr auto; gap: .6rem; align-items: start;
  padding: .7rem 0; border-top: 1px solid var(--hairline); }
.pa-card h2 + .pa-row { border-top: 0; }
.pa-row .tk { font-weight: 700; }
.pa-row .w b { font-weight: 600; } .pa-row .w small { display: block; color: var(--muted); font-size: .78rem; }
.pa-row .pa-noted { font-style: italic; }
.pa-row.is-off .w { opacity: .55; }
.pa-row .act { display: flex; gap: .9rem; margin-top: .3rem; font-size: .82rem; }
.pa-row .act form { display: inline; } .pa-row .act .del { color: var(--danger); }
.pa-told { color: var(--gain); }
.pa-sw { width: 42px; height: 24px; border: 0; border-radius: 12px; background: var(--gain); position: relative; padding: 0; }
.pa-sw::after { content: ""; position: absolute; top: 3px; right: 3px; width: 18px; height: 18px; border-radius: 50%; background: #fff; }
.pa-sw.off { background: var(--raised); } .pa-sw.off::after { right: auto; left: 3px; }

/* Radar on a stock's page as one bar and three boxes (28 October 2026). */
.rd1-top { display: flex; align-items: center; gap: .35rem; margin-bottom: 1.15rem; }
.rd1-top .rd-h { margin: 0; font-size: .95rem; }
.rd1-p { font-size: .72rem; font-weight: 600; border-radius: 999px; padding: .1rem .45rem; white-space: nowrap; }
.rd1-p.good { background: color-mix(in srgb, var(--gain) 14%, transparent); color: var(--gain); }
.rd1-p.warn { background: color-mix(in srgb, var(--warn-fill) 18%, transparent); color: var(--warn); }
.rd1-p.exit { background: color-mix(in srgb, var(--danger) 14%, transparent); color: var(--danger); }
.rd1-ic { margin-inline-start: auto; display: inline-flex; align-items: center; gap: .2rem; font-size: .75rem;
  font-weight: 600; border-radius: 999px; padding: .15rem .45rem; background: var(--bg); color: var(--muted); text-decoration: none; }
.rd1-ic.warn { color: var(--warn); }
.rd1-ic svg { width: 13px; height: 13px; }
.rd1-bar { position: relative; height: 10px; border-radius: 5px; background: var(--raised); margin: 0 0 .1rem; }
.rd1-bar > span { position: absolute; top: 0; bottom: 0; border-radius: 5px; }
.rd1-long { background: color-mix(in srgb, var(--vs-line) 32%, transparent); }
.rd1-buy { background: color-mix(in srgb, var(--gain) 60%, transparent); }
.rd1-sell { background: color-mix(in srgb, var(--accent-text) 65%, transparent); }
.rd1-bar > .rd1-m { top: -5px; bottom: -5px; width: 2px; border-radius: 1px; }
.rd1-now { background: var(--ink); }
.rd1-be { background: var(--warn-fill); }
.rd1-m i { position: absolute; bottom: calc(100% + 1px); left: 50%; transform: translateX(-50%); font-style: normal;
  font-size: .66rem; white-space: nowrap; color: var(--muted); }
.rd1-now i { color: var(--ink); font-weight: 600; }
.rd1-be i { color: var(--warn); }
.rd1-g { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: .3rem; margin-top: .55rem; }
.rd1-c { background: var(--bg); border-radius: 10px; padding: .4rem .4rem .35rem; }
.rd1-c small { display: flex; align-items: center; gap: .3rem; font-size: .68rem; color: var(--muted); margin-bottom: .1rem; white-space: nowrap; }
.rd1-c small b { width: 8px; height: 8px; border-radius: 2px; flex: none; }
.rd1-c p { display: flex; justify-content: space-between; align-items: baseline; gap: .2rem; white-space: nowrap; margin: 0; font-size: .76rem; line-height: 1.5; font-variant-numeric: tabular-nums; }
.rd1-c p span { color: var(--muted); font-size: .6rem; }
.rd1-h { font-size: .75rem; font-weight: 600; color: var(--muted); margin: .7rem 0 .1rem; }
.rd1-rows li small { white-space: normal; text-align: end; }
.company-sheet .rd1-sheet > .sheet-panel { height: auto; min-height: 0; max-height: 80vh; }
.rd1-rows li > span { white-space: nowrap; }
.rd1-p { min-width: 0; overflow: hidden; text-overflow: ellipsis; }
@media (max-width: 410px) { .rd1-top .rd-h > span { display: none; } }
/* Each edge on one line, in the box's width: the price, how far from
   today's, how often (28 October 2026: "play with font size so it fits"). */
.rd1-c p b { font-weight: 500; }
.rd1-c p em { font-style: normal; font-size: .64rem; margin-inline-end: auto; }
.rd1-c p em.up { color: var(--gain); }
.rd1-c p em.down { color: var(--danger); }
.rd1-m.at-end i { left: auto; right: -2px; transform: none; }
.rd1-m.at-start i { left: -2px; transform: none; }
.rd1-g.wide .rd1-c p { font-size: .7rem; gap: .12rem; }
.rd1-g.wide .rd1-c p em { font-size: .58rem; }
.rd1-g.wide .rd1-c p span { font-size: .55rem; }
.rd1-g.wider .rd1-c p { font-size: .64rem; }
.rd1-g.wider .rd1-c p em, .rd1-g.wider .rd1-c p span { font-size: .52rem; }
html.keyboard-up details.sheet[open] > .sheet-panel { padding-bottom: .9rem; border-radius: 22px 22px 0 0; }

/* Radar's Compare (28 October 2026). */
.cmp-h { font-size: .95rem; margin: 0 0 .5rem; display: flex; align-items: center; gap: .35rem; }
.cmp-h small { margin-inline-start: auto; font-weight: 400; font-size: .7rem; color: var(--muted); }
.cmp-in { display: flex; flex-wrap: wrap; gap: .3rem; align-items: center; background: var(--bg); border-radius: 12px; padding: .35rem; margin: 0; }
.cmp-chip { font-size: .8rem; font-weight: 600; background: var(--raised); color: var(--ink); border-radius: 999px; padding: .15rem .5rem; text-decoration: none; }
.cmp-chip i { font-style: normal; color: var(--muted); margin-inline-start: .3rem; font-weight: 400; }
.cmp-in .cmp-add { flex: 1; min-width: 3.5rem; width: auto; border: 0; background: none; padding: .2rem .3rem; margin: 0; min-height: 0; text-transform: uppercase; }
.cmp-in button { width: auto; min-height: 0; margin: 0; background: var(--ink); color: var(--bg); border: 0; border-radius: 999px; padding: .3rem .8rem; font-size: .8rem; font-weight: 600; }
.cmp-sub { white-space: nowrap; display: flex; justify-content: space-between; gap: .5rem; font-size: .7rem; color: var(--muted); margin: .55rem .1rem .3rem; }
.cr { background: var(--bg); border-radius: 12px; padding: .5rem .6rem; margin-top: .4rem; }
.cr-1 { white-space: nowrap; display: flex; align-items: center; gap: .4rem; }
.cr-n { width: 20px; height: 20px; border-radius: 50%; background: var(--ink); color: var(--bg); font-size: .72rem; font-weight: 700; display: grid; place-items: center; flex: none; }
.cr-t { font-weight: 700; font-size: .9rem; }
.cr-tr { font-size: .7rem; color: var(--muted); }
.cr-px { font-size: .75rem; color: var(--muted); margin-inline-start: auto; font-variant-numeric: tabular-nums; }
.cr-odds { display: flex; gap: .3rem; }
.cr-odds span { font-size: .75rem; font-weight: 600; border-radius: 999px; padding: .08rem .4rem; font-variant-numeric: tabular-nums; }
.cr-odds .u { background: color-mix(in srgb, var(--gain) 14%, transparent); color: var(--gain); }
.cr-odds .d { background: color-mix(in srgb, var(--danger) 13%, transparent); color: var(--danger); }
.cr-g { white-space: nowrap; display: grid; grid-template-columns: 4rem 1fr 1fr 1fr; gap: .1rem .3rem; margin-top: .4rem; font-size: .72rem; font-variant-numeric: tabular-nums; align-items: baseline; }
.cr-g .h { color: var(--muted); font-size: .66rem; }
.cr-g .k { color: var(--muted); overflow: hidden; text-overflow: ellipsis; }
.cr-g .up, .cr-z em.up { color: var(--gain); }
.cr-g .down, .cr-z em.down { color: var(--danger); }
.cr-z { display: flex; justify-content: space-between; font-size: .72rem; margin-top: .35rem; padding-top: .35rem; border-top: 1px solid var(--hairline); font-variant-numeric: tabular-nums; }
.cr-z span { white-space: nowrap; }
.cr-z em { font-style: normal; font-size: .66rem; }
.cr-z i { font-style: normal; color: var(--muted); font-size: .62rem; }
.cr-none { font-size: .72rem; color: var(--muted); margin: .3rem 0 0; }
.cmp-in .cmp-add::placeholder { text-transform: none; }
.cmp-rec { font-size: .68rem; color: var(--muted); margin: .5rem .1rem 0; }
.rd-review-line { display: flex; align-items: center; gap: .45rem; text-decoration: none; color: var(--ink);
  font-size: .9rem; font-weight: 600; padding: .8rem 1rem; }
.rd-review-line svg { width: 16px; height: 16px; color: var(--warn); }
.rd-review-line .rd-go { margin-inline-start: auto; color: var(--muted); }
/* Radar's meters (28 October 2026). */
.rd:has(#rd-how:checked) .rd-pane-swing, .rd:has(#rd-how:checked) .rd-pane-long { display: none; }
.rd .rd-pane-how { display: none; }
.rd:has(#rd-how:checked) .rd-pane-how { display: block; }
.mt-sec .rd-sec { display: flex; align-items: baseline; gap: .4rem; }
.mt-note { margin-inline-start: auto; font-size: .7rem; font-weight: 400; color: var(--muted); }
.mt-grid { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: .4rem; }
.mt { display: flex; flex-direction: column; align-items: center; background: var(--bg); border-radius: 12px;
  padding: .45rem .25rem .4rem; text-decoration: none; color: var(--ink); min-width: 0; }
.mt-gw { height: 46px; display: flex; align-items: flex-end; }
.mt-g { width: 84px; height: 47px; }
.mt-g path { fill: none; stroke-width: 10; }
.mt-red { stroke: var(--danger); }
.mt-amber { stroke: var(--warn-fill); }
.mt-green { stroke: var(--gain); }
.mt-needle { stroke: var(--ink); stroke-width: 3; stroke-linecap: round; }
.mt-hub { fill: var(--ink); }
.mt b { font-size: 1rem; font-variant-numeric: tabular-nums; line-height: 1.15; margin-top: .1rem; }
.mt-n { font-size: .72rem; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; max-width: 100%; }
.mt-n i { font-style: normal; margin-inline-start: .15rem; }
.mt-n i.up { color: var(--gain); }
.mt-n i.down { color: var(--danger); }
.mt small { font-size: .62rem; color: var(--muted); white-space: nowrap; }
.mt-chart { width: 100%; height: auto; margin: .3rem 0 .2rem; }
.mt-line { fill: none; stroke: var(--gain); stroke-width: 2.2; }
.mt-level { stroke: var(--muted); stroke-dasharray: 4 4; }
.mt-tick { font-size: 10px; fill: var(--muted); }
.mt-rows li small { white-space: nowrap; }
.mt-log { list-style: none; margin: 0; padding: 0; }
.mt-log li { padding: .55rem 0; border-top: 1px solid var(--hairline); font-size: .82rem; }
.mt-log li:first-child { border-top: 0; padding-top: .2rem; }
.mt-log li > div:first-child { display: flex; gap: .5rem; align-items: baseline; }
.mt-day { margin-inline-start: auto; font-size: .7rem; color: var(--warn); white-space: nowrap; }
.mt-log small { display: block; color: var(--muted); font-size: .72rem; margin-top: .15rem; }
.mt-state { display: flex; align-items: center; gap: .5rem; margin-top: .3rem; }
.mt-chip { font-size: .68rem; font-weight: 600; border-radius: 999px; padding: .08rem .45rem; background: var(--raised); color: var(--muted); }
.mt-chip.good { background: color-mix(in srgb, var(--gain) 14%, transparent); color: var(--gain); }
.mt-chip.warn { background: color-mix(in srgb, var(--warn-fill) 18%, transparent); color: var(--warn); }
.mt-state form { margin: 0 0 0 auto; }
.mt-state .mt-undo { width: auto; min-height: 0; margin: 0; padding: .2rem .7rem; font-size: .75rem; font-weight: 600;
  border-radius: 999px; background: none; border: 1px solid var(--hairline); color: var(--accent-text); }
.mt-log-undone b, .mt-log-put_back b { color: var(--muted); }

/* Withdraw, from and to (3 November 2026, "Go for the first"): From and To
   as tiles, logo over name; the amount in riyals or dollars. */
.mv-wd .mv-choice { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: .35rem; }
.mv-wd .mv-choice.mv-to { grid-template-columns: repeat(auto-fit, minmax(3.6rem, 1fr)); }
.mv-wd .mv-choice legend { grid-column: 1 / -1; }
.mv-wd .mv-choice label { min-width: 0; }
.mv-wd .mv-choice span { display: flex; flex-direction: column; align-items: center; justify-content: center; gap: .25rem;
  padding: .5rem .15rem .45rem; font-size: .72rem; line-height: 1.15; border-radius: 12px; min-height: 3.6rem;
  border: 1.5px solid transparent; overflow: hidden; text-overflow: ellipsis; }
.mv-wd .mv-choice span small { font-size: .64rem; color: var(--muted); white-space: nowrap; }
.mv-wd .mv-choice input:checked + span { background: color-mix(in srgb, var(--accent-text) 12%, var(--raised));
  color: var(--ink); border-color: var(--accent-text); font-weight: 600; }
.mv-wd .acct-logo { margin: 0; }
.mv-wd .mv-ic { display: grid; place-items: center; width: 24px; height: 24px; border-radius: 6px; background: var(--line); }
.mv-wd .mv-ic svg.ic { width: 15px; height: 15px; }
.mv-wd:has(input[name="from_platform"]:not([value="saham"]):checked) .mv-to-aside,
.mv-wd:has(input[name="from_platform"][value="saham"]:checked) .mv-to-saham,
.mv-wd:has(input[name="from_platform"][value="wallet"]:checked) .mv-to-saham,
.mv-wd:has(input[name="from_platform"][value="awaed"]:checked) .mv-to-awaed,
.mv-wd:has(input[name="from_platform"][value="alrajhi"]:checked) .mv-to-alrajhi { display: none; }
.mv-wd .mv-amt-l { margin-bottom: .3rem; }
.mv-wd .mv-amt { display: flex; gap: .4rem; align-items: stretch; }
.mv-wd .mv-amt > input { flex: 1; min-width: 0; font-size: 1.05rem; font-weight: 600; }
.mv-seg { display: flex; border-radius: 10px; background: var(--raised); padding: 3px; flex: none; }
.mv-seg label { margin: 0; position: relative; }
.mv-seg input { position: absolute; opacity: 0; width: 1px; height: 1px; margin: 0; pointer-events: none; }
.mv-seg span { display: grid; place-items: center; height: 100%; padding: 0 .6rem; font-size: .8rem; font-weight: 600;
  border-radius: 8px; color: var(--muted); }
.mv-seg input:checked + span { background: var(--bg); color: var(--ink); box-shadow: 0 1px 2px rgba(0,0,0,.25); }
.mv-wd:has(input[name="to"][value="aside"]:checked) .mv-seg { display: none; }
.mv-wd:has(input[name="to"][value="aside"]:checked) .mv-aside-only { display: block; }
.mv-conv { display: flex; justify-content: space-between; gap: .5rem; font-size: .76rem; color: var(--muted); margin: .35rem 0 .8rem; }
.mv-conv a { font-weight: 600; white-space: nowrap; }
.mv-route { display: flex; align-items: center; flex-wrap: wrap; gap: .3rem; font-size: .78rem; background: var(--raised);
  border-radius: 10px; padding: .55rem .65rem; margin: .2rem 0 .9rem; }
.mv-route:empty { display: none; }
.mv-route b { font-weight: 600; }
.mv-route i { font-style: normal; color: var(--muted); }

.mt-checked { margin: .2rem 0 .4rem; font-size: .8rem; }
.mt-checked > span { display: flex; justify-content: space-between; gap: .5rem; }
.mt-checked b { font-weight: 600; }
.mt-checked small { display: block; color: var(--muted); font-size: .74rem; margin-top: .1rem; }

/* Picks ranked by (3 November 2026): learned against the rule. */
.mt-vs { display: grid; grid-template-columns: 1fr 1fr; gap: .4rem; margin: .3rem 0 .2rem; }
.mt-vs div { background: var(--raised); border-radius: 12px; padding: .45rem .6rem; text-align: center; border: 1.5px solid transparent; }
.mt-vs div.on { border-color: var(--accent-text); }
.mt-vs b { display: block; font-size: 1.25rem; font-weight: 600; font-variant-numeric: tabular-nums; }
.mt-vs small { color: var(--muted); font-size: .72rem; }
.mt-said { font-size: .74rem; color: var(--muted); margin: .2rem 0 .3rem; }
.mt-rule { stroke: var(--muted); stroke-dasharray: 4 3; }
.mt-key { display: flex; align-items: center; gap: .35rem; font-size: .7rem; color: var(--muted); margin: .2rem 0 0; }
.mt-key i { display: inline-block; width: 14px; height: 2px; background: var(--gain); margin-left: .4rem; }
.mt-key i:first-child { margin-left: 0; }
.mt-key i.k-rule { background: var(--muted); }
.mt-key i.k-coin { background: var(--line); }
