/* Per-view layout. Each block here corresponds to one screen, in the order the
   navigation lists them. */

/* ============================================== Today - the front page == */

/* An editorial document, not an instrument. Three things follow, and they are
   the reason this block looks unlike the rest of this file:

   - **A column, centred.** Every other screen fills the window because it is a
     working surface. Prose does not: past about 1180px a reader's eye loses the
     start of the next line, so the page has a measure and sits in the middle of
     whatever space it is given.
   - **Sections are separated by space, then by a hairline.** The rule is almost
     invisible and does the work of a page break - it says "new movement" without
     boxing anything. Nothing on this page is in a frame unless the frame means
     something.
   - **The personality is rationed to two places.** The foil sheen fires on
     artwork under the pointer, and the foil gradient draws exactly one line: the
     divider in the anatomy panel where public data ends and ours begins. The
     Poke Ball mark is deliberately absent - it belongs to the header, the
     favicon and the empty states, and a landing page is precisely where a
     signature turns into wallpaper. */

.front {
  max-width: 1180px; margin: 0 auto;
  padding: 8px 34px 80px;
}
.front > section { padding: 62px 0; border-top: 1px solid var(--grid); }
.front > section:first-child { padding-top: 26px; border-top: none; }

.front-h1 {
  font-size: var(--fs-lead); font-weight: 600; letter-spacing: -0.5px;
  line-height: 1.22; margin: 0; max-width: 20ch;
}
.front-h2 {
  font-size: var(--fs-title); font-weight: 600; letter-spacing: -0.35px;
  margin: 0;
}
/* Prose sizing, and the only place on the site that uses it. The 13px body
   scale is right for a dense table and too small for four consecutive
   sentences a stranger has to be willing to read. */
.front-lede {
  color: var(--fg-dim); font-size: var(--fs-prose); line-height: 1.62;
  margin: 10px 0 0; max-width: 66ch;
}
.front-body {
  color: var(--fg-dim); font-size: var(--fs-prose); line-height: 1.68;
  margin: 14px 0 0; max-width: 68ch;
}
.front-note {
  color: var(--fg-muted); font-size: var(--fs-small); line-height: 1.62;
  margin: 18px 0 0;
}
.front-note b { color: var(--fg-dim); font-weight: 600; }
.front-head { min-width: 0; }
.front-head .front-lede { max-width: 70ch; }
.front-head-row {
  display: flex; align-items: flex-end; gap: var(--s4); flex-wrap: wrap;
}
.front-head-row .front-head { flex: 1; min-width: 280px; }
.front > section > .front-head,
.front > section > .front-head-row { margin-bottom: 30px; }

/* ------------------------------------------------------------ the opening -- */

.front-open { display: flex; flex-direction: column; gap: 46px; }
.open-grid {
  display: grid; gap: 48px; align-items: center;
  grid-template-columns: minmax(0, 1fr) minmax(0, auto);
}
.front-open-body { min-width: 0; }
.front-lead {
  font-size: var(--fs-hero); font-weight: 600; letter-spacing: -1.6px;
  line-height: 1.08; margin: 14px 0 0; max-width: 19ch;
  display: flex; flex-direction: column;
}
/* The first line is what the reader already believes and the second is the
   turn, so they are set at the same size and different weights of attention.
   Two <span>s rather than one sentence: a line break that matters should not
   depend on where the column happens to wrap. */
.lead-quiet { color: var(--fg-muted); }
.lead-loud { color: var(--fg); }
.front-open .lede-wide { max-width: 62ch; font-size: calc(var(--fs-prose) + 1.5px); }
.front-actions { display: flex; gap: var(--s3); margin-top: 26px; flex-wrap: wrap; }

/* One card, presented as an object rather than as a result. The slight tilt and
   the shadow are the whole trick: a card lying on a surface is what this hobby
   physically is, and two degrees is enough to say so without becoming a gimmick.
   It straightens under the pointer, which is the only motion on this screen
   that the reader causes directly. */
.open-card { display: block; flex: none; text-align: center; }
.open-card-plate {
  transform: rotate(-2.2deg);
  transition: transform var(--dur-slow) var(--ease);
  filter: drop-shadow(0 18px 34px rgba(0, 0, 0, 0.55));
}
.open-card:hover .open-card-plate { transform: rotate(0deg) translateY(-4px); }
.open-card .art { width: 268px; }
.open-card .art::before {
  content: ""; position: absolute; inset: 0; z-index: 1;
  background: var(--foil); opacity: 0; mix-blend-mode: soft-light;
  transform: translateX(-100%);
}
.open-card:hover .art::before { animation: sheen 700ms var(--ease) forwards; }
.open-card-cap { margin-top: 22px; max-width: 268px; }
.open-card-name {
  font-size: var(--fs-body); font-weight: 600; margin-top: 6px;
  line-height: 1.35;
}
.open-card-set {
  display: flex; align-items: center; justify-content: center; gap: 5px;
  color: var(--fg-muted); font-size: var(--fs-micro); margin-top: 3px;
  min-width: 0;
}
.open-card-set span {
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}

/* Scale is the cheapest credibility available, so the figures are given room
   and no box. Boxing them would make them look like four statistics on a
   dashboard; unboxed and widely spaced they read as a masthead. */
.proof-row {
  display: grid; gap: var(--s5) var(--s4);
  grid-template-columns: repeat(auto-fit, minmax(170px, 1fr));
  padding-top: 34px; border-top: 1px solid var(--grid);
}
.proof { min-width: 0; }
.proof-value {
  font-size: var(--fs-display); font-weight: 600; letter-spacing: -1.1px;
  font-variant-numeric: tabular-nums;
}
.proof-label {
  font-size: var(--fs-small); font-weight: 600; color: var(--fg-dim);
  margin-top: 2px;
}
.proof-note {
  font-size: var(--fs-micro); color: var(--fg-faint); margin-top: 3px;
  line-height: 1.45;
}

/* -------------------------------------------------------- the market brief -- */

.brief-dateline {
  display: flex; align-items: baseline; gap: var(--s3); flex-wrap: wrap;
  margin-bottom: 18px;
}
.brief-date { font-size: var(--fs-micro); color: var(--fg-faint); }
.brief-grid {
  display: grid; gap: 40px;
  grid-template-columns: minmax(0, 1.15fr) minmax(0, 1fr);
  align-items: start;
}
.brief-copy { min-width: 0; }
.brief-copy .front-body { max-width: 60ch; }
.brief-figure { min-width: 0; }
/* The market line is the illustration of this section, so it is given the full
   column width and no axes. Every figure on the page arrives already worded;
   a chart printing its own tick labels would be the browser formatting numbers
   again, one axis at a time. */
svg.market-ribbon { display: block; width: 100%; height: 196px; }
.brief-stats {
  display: grid; gap: var(--s4);
  grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));
  margin-top: 20px; padding-top: 20px; border-top: 1px solid var(--grid);
}
.brief-stat { min-width: 0; cursor: help; }
.brief-stat .cap {
  font-size: var(--fs-micro); color: var(--fg-muted); font-weight: 600;
}
.brief-stat .value {
  font-size: var(--fs-title); font-weight: 600; letter-spacing: -0.5px;
  font-variant-numeric: tabular-nums; margin-top: 2px;
}
.brief-stat .note {
  font-size: var(--fs-micro); color: var(--fg-faint); line-height: 1.45;
  margin-top: 2px;
}

/* ------------------------------------------------------- how we read a card -- */

.anatomy-grid {
  display: grid; gap: 32px;
  grid-template-columns: minmax(0, 320px) minmax(0, 1fr);
  align-items: start;
}
.anatomy-subject {
  padding: 20px; display: flex; flex-direction: column; gap: 14px;
  position: sticky; top: 8px;
}
.anatomy-art { display: block; align-self: center; }
.anatomy-art .art { width: 168px; }
/* The foil sweep, on the one piece of artwork this page shows large. It fires
   under the pointer only - a reward for looking, not an animation running at
   eighty tiles at once. Extended to My Collection's and Watchlist's card
   tiles (`.ctile`, `.wl-tile`) for the same reason `.finding` earns it: real
   card art shown at gallery size, one tile at a time under the pointer. */
.anatomy-art .art::before, .finding .art::before,
.ctile .art::before, .wl-tile .art::before {
  content: ""; position: absolute; inset: 0; z-index: 1;
  background: var(--foil); opacity: 0; mix-blend-mode: soft-light;
  transform: translateX(-100%);
}
.anatomy-art:hover .art::before, .finding:hover .art::before,
.ctile:hover .art::before, .wl-tile:hover .art::before {
  animation: sheen 560ms var(--ease) forwards;
}
@keyframes sheen {
  0% { opacity: 0; transform: translateX(-100%); }
  30% { opacity: 0.85; }
  100% { opacity: 0; transform: translateX(100%); }
}
.anatomy-id { text-align: center; min-width: 0; }
.anatomy-name { font-size: var(--fs-heading); font-weight: 600; line-height: 1.3; }
.anatomy-set {
  display: flex; align-items: center; justify-content: center; gap: 5px;
  color: var(--fg-muted); font-size: var(--fs-micro); margin-top: 4px;
  min-width: 0;
}
.anatomy-set span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

.surface-rows { display: flex; flex-direction: column; gap: 10px; }
.surface-row {
  display: grid; grid-template-columns: 1fr auto; gap: 2px var(--s3);
  align-items: baseline;
}
.surface-name { font-size: var(--fs-small); font-weight: 600; }
.surface-value {
  font-size: var(--fs-small); font-weight: 600;
  font-variant-numeric: tabular-nums;
}
.surface-line {
  grid-column: 1 / -1; font-size: var(--fs-micro); color: var(--fg-faint);
}
/* The one foil line in the product. It marks the boundary the whole section is
   about: above it is what anybody can look up, below it is what was measured
   here. A gradient used once, to mean one thing. */
.surface-divider {
  display: flex; align-items: center; gap: var(--s3);
  font-size: var(--fs-caption); color: var(--fg-faint);
  text-transform: uppercase; letter-spacing: 0.9px;
}
.surface-divider::before, .surface-divider::after {
  content: ""; height: 1px; flex: 1; background: var(--foil); opacity: 0.5;
}
.anatomy-verdict { display: flex; align-items: center; gap: var(--s3); }
.verdict-score {
  font-size: var(--fs-display); font-weight: 600; letter-spacing: -1.2px;
  line-height: 1; font-variant-numeric: tabular-nums;
}
.verdict-body { min-width: 0; }
.verdict-tier { font-size: var(--fs-small); font-weight: 600; }
.verdict-cap { font-size: var(--fs-micro); color: var(--fg-faint); }
.anatomy-open { justify-content: center; }

.layer-list {
  list-style: none; margin: 0; padding: 0;
  display: grid; gap: 2px; grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
}
.layer {
  padding: 14px 16px; border-radius: var(--r-md); min-width: 0;
  transition: background var(--dur-fast) var(--ease);
  cursor: help;
}
.layer:hover { background: var(--bg-panel); }
.layer-head {
  display: flex; justify-content: space-between; align-items: baseline;
  gap: var(--s2);
}
.layer-name { font-size: var(--fs-body); font-weight: 600; }
.layer-share { font-size: var(--fs-caption); color: var(--fg-faint); flex: none; }
.layer-line {
  font-size: var(--fs-micro); color: var(--fg-muted); line-height: 1.5;
  margin: 5px 0 10px;
}
.layer-meter { display: flex; align-items: center; gap: var(--s2); }
/* One meter shape for the whole page - the layer percentile and the signal
   strength are different quantities, and drawing them two different ways would
   invent a distinction the reader then has to decode. */
.meter-track {
  flex: 1; min-width: 0; height: 5px; border-radius: 3px;
  background: var(--bg-elevated); overflow: hidden;
}
.meter-track i {
  display: block; height: 100%; border-radius: 3px;
  transition: width var(--dur-slow) var(--ease-soft);
}
.meter-value {
  font-size: var(--fs-micro); font-weight: 600; color: var(--fg-dim);
  font-variant-numeric: tabular-nums; flex: none; min-width: 22px;
  text-align: right;
}
.layer-verdict { font-size: var(--fs-micro); margin-top: 7px; }

.anatomy-forecast {
  padding: 20px 24px; margin-top: 28px; max-width: 78ch;
  border-left: 2px solid var(--forecast);
}
.anatomy-forecast .overline { color: var(--forecast); }
.forecast-verdict {
  margin-top: 14px; padding-top: 14px; border-top: 1px solid var(--grid);
  cursor: help;
}
.fv-head {
  display: block; font-size: var(--fs-body); font-weight: 600;
  color: var(--forecast);
}
.fv-detail {
  display: block; font-size: var(--fs-small); color: var(--fg-muted);
  line-height: 1.6; margin-top: 4px;
}

/* ---------------------------------------------------------- what we measure -- */

.signal-grid {
  display: grid; gap: var(--s3);
  grid-template-columns: repeat(auto-fit, minmax(232px, 1fr));
}
.signal {
  padding: 16px 18px 18px; display: flex; flex-direction: column; gap: 0;
  min-width: 0; cursor: help;
}
.signal-top {
  display: flex; justify-content: space-between; align-items: baseline;
  gap: var(--s2);
}
.signal-name { font-size: var(--fs-body); font-weight: 600; }
.signal-share {
  font-size: var(--fs-micro); font-weight: 600; color: var(--fg-muted);
  font-variant-numeric: tabular-nums; flex: none;
}
.signal-line {
  font-size: var(--fs-micro); color: var(--fg-muted); line-height: 1.55;
  margin: 7px 0 14px; flex: 1;
}
.signal-measure { display: flex; flex-direction: column; gap: 7px; }
.signal-verdict {
  display: flex; justify-content: space-between; align-items: baseline;
  gap: var(--s2); font-size: var(--fs-micro); font-weight: 600;
}
.signal-hit { font-size: var(--fs-caption); color: var(--fg-faint); line-height: 1.45; }

/* --------------------------------------------------------- why believe it -- */

.pillar-grid {
  display: grid; gap: var(--s3);
  grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
}
.pillar { padding: 22px 24px 24px; min-width: 0; }
.pillar-figure {
  font-size: var(--fs-display); font-weight: 600; letter-spacing: -1.2px;
  line-height: 1; font-variant-numeric: tabular-nums;
}
.pillar-caption {
  font-size: var(--fs-micro); color: var(--fg-faint); margin-top: 5px;
  line-height: 1.45;
}
.pillar-title {
  font-size: var(--fs-heading); font-weight: 600; margin: 16px 0 0;
}
.pillar .front-body { font-size: var(--fs-small); margin-top: 8px; max-width: none; }

.limits { margin-top: var(--s5); padding-top: var(--s5); border-top: 1px solid var(--grid); }
.limits-title {
  display: flex; align-items: center; gap: 7px;
  font-size: var(--fs-small); font-weight: 600; color: var(--fg-dim);
}
.limits-title svg { color: var(--fg-muted); flex: none; }
.limits-grid {
  display: grid; gap: var(--s4) var(--s5); margin-top: var(--s4);
  grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
}
.limit { min-width: 0; }
.limit-name { font-size: var(--fs-small); font-weight: 600; color: var(--fg-dim); }
.limit-body {
  font-size: var(--fs-micro); color: var(--fg-muted); line-height: 1.55;
  margin-top: 3px;
}

/* -------------------------------------------------------- today's evidence -- */

.finding-grid {
  display: grid; gap: var(--s3);
  grid-template-columns: repeat(auto-fit, minmax(268px, 1fr));
}
.finding {
  padding: 18px; display: flex; flex-direction: column; gap: 12px;
  align-items: center; text-align: center; min-width: 0;
  transition: transform var(--dur-fast) var(--ease),
              background var(--dur-fast) var(--ease);
}
.finding:hover { background: var(--bg-elevated); transform: translateY(-3px); }
.finding-question {
  font-size: var(--fs-caption); font-weight: 600; color: var(--fg-muted);
  text-transform: uppercase; letter-spacing: 0.8px; align-self: flex-start;
}
.finding .art { width: 132px; }
.finding-body { width: 100%; min-width: 0; }
.finding-name { font-size: var(--fs-body); font-weight: 600; line-height: 1.32; }
.finding-set {
  display: flex; align-items: center; justify-content: center; gap: 5px;
  color: var(--fg-muted); font-size: var(--fs-micro); margin-top: 3px;
  min-width: 0;
}
.finding-set span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* What the score says is happening, above the rule that put the card here.
   Two different statements, so they are set as two different things. */
.finding-flag {
  font-size: var(--fs-micro); font-weight: 600; margin-top: 9px;
}
.finding-why {
  font-size: var(--fs-small); color: var(--fg-muted); line-height: 1.55;
  margin: 8px 0 0;
}
.finding-foot {
  display: flex; justify-content: center; align-items: baseline; gap: var(--s3);
  margin-top: 12px; padding-top: 12px; border-top: 1px solid var(--grid);
}
.finding-price { font-weight: 600; font-size: var(--fs-body); }
.finding-tier { font-size: var(--fs-micro); font-weight: 600; }

/* The shelf index. Replaced eight strips of artwork: it keeps what those were
   for - scrolling them taught the reader what the product can find - while
   giving each question its sentence and its count, which a strip never did. */
.question-grid {
  display: grid; gap: 2px;
  grid-template-columns: repeat(auto-fit, minmax(400px, 1fr));
}
.question {
  display: flex; align-items: center; gap: var(--s4);
  padding: 14px 18px; min-width: 0; background: transparent;
  transition: background var(--dur-fast) var(--ease);
}
.question:hover { background: var(--bg-panel); }
/* Three pieces of artwork overlapped, like cards held in a hand. Small enough
   to be a texture rather than a gallery. */
.question-spine { display: flex; flex: none; }
.question-spine .art { width: 46px; }
.question-spine > *:not(:first-child) { margin-left: -22px; }
.question-body { flex: 1; min-width: 0; }
.question-title { font-size: var(--fs-body); font-weight: 600; }
.question-sub {
  font-size: var(--fs-micro); color: var(--fg-muted); line-height: 1.5;
  margin: 3px 0 0;
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical;
  overflow: hidden;
}
.question-count {
  display: flex; align-items: baseline; gap: 5px; flex: none;
  color: var(--fg-muted);
}
.question-count .count {
  font-size: var(--fs-heading); font-weight: 600; color: var(--fg-dim);
  font-variant-numeric: tabular-nums;
}
.question-count .count-cap { font-size: var(--fs-caption); color: var(--fg-faint); }
.question-count svg { align-self: center; }
.question:hover .question-count { color: var(--accent); }

.front-forecast .front-h2 { color: var(--forecast); }

/* --------------------------------------------------------------- the close -- */

.check-grid {
  display: grid; gap: var(--s3);
  grid-template-columns: repeat(auto-fit, minmax(230px, 1fr));
}
.check {
  padding: 18px 20px 20px; border-radius: var(--r-lg); min-width: 0;
  border: 1px solid var(--grid);
  display: flex; flex-direction: column;
  transition: border-color var(--dur-fast) var(--ease),
              background var(--dur-fast) var(--ease);
}
.check:hover { border-color: var(--border); background: var(--bg-panel); }
.check-title { font-size: var(--fs-body); font-weight: 600; margin: 0; }
.check-body {
  font-size: var(--fs-small); color: var(--fg-muted); line-height: 1.6;
  margin: 8px 0 0; flex: 1;
}
.check-action {
  display: flex; align-items: center; gap: 4px; margin-top: 16px;
  font-size: var(--fs-micro); font-weight: 600; color: var(--accent);
}
.check:hover .check-action svg { transform: translateX(2px); }
.check-action svg { transition: transform var(--dur-fast) var(--ease); }

.front-foot {
  margin-top: 44px; padding-top: var(--s5); border-top: 1px solid var(--grid);
  max-width: 82ch; display: flex; flex-direction: column; gap: 12px;
}
.front-foot .front-note { margin: 0; }
.front-foot .disclaimer { color: var(--fg-faint); }
/* The public footer's links, set as the public footer sets them. */
.front-links { display: flex; flex-wrap: wrap; gap: var(--s1) var(--s4);
  font-size: var(--fs-small); }
.front-links a { color: var(--fg-muted); text-decoration: none; }
.front-links a:hover { color: var(--accent); }
@media (max-width: 640px) {
  .front-links { gap: 0 var(--s1); }
  .front-links a { display: inline-flex; align-items: center; min-height: 44px;
    padding: 0 6px; }
  .front-links a:first-child { margin-left: -6px; }
}

/* ================================================================ Browse == */

/* The research desk. A question owns the screen: its statement across the top
   of the list pane, its case in the report pane until a card is chosen, and its
   evidence - the cards - between them. The split pane is the point of the whole
   view: reading a full report without losing your place in the list is the one
   thing a price site cannot do. */

.browse {
  display: grid;
  grid-template-columns: minmax(360px, 40fr) minmax(560px, 60fr);
  height: 100%;
}
.browse-list {
  display: flex; flex-direction: column; min-width: 0;
  padding: 18px 14px 16px 20px;
  gap: var(--s3);
  min-height: 0;
  overflow: hidden;
}
/* A flex item's `min-width` defaults to `auto`, which means "never narrower
   than my own content". The result count is itself a flex row of phrases, so
   its min-content is the sum of all of them - and at phone width that one line
   silently made the whole pane 470px wide inside a 394px column, clipping the
   price off every row. Every child here is allowed to be narrow. */
.browse-list > * { min-width: 0; }
.browse-report {
  border-left: 1px solid var(--grid);
  min-width: 0; overflow: auto; position: relative;
}

/* --- the question, stated ------------------------------------------------- */

.desk-head { display: flex; flex-direction: column; gap: var(--s3); }
.desk-head > * { min-width: 0; }
.desk-head-top { display: flex; align-items: flex-start; gap: var(--s3); }
.desk-id { flex: 1; min-width: 0; display: flex; flex-direction: column;
  gap: 3px; }
.desk-title {
  margin: 0;
  font-size: var(--fs-title); font-weight: 650; letter-spacing: -0.4px;
  line-height: 1.15;
}
.desk-rule { margin: 0; color: var(--fg-muted); font-size: var(--fs-small);
  line-height: 1.5; max-width: 62ch; }
.desk-note { margin: 4px 0 0; color: var(--fg-muted); font-size: var(--fs-micro);
  line-height: 1.5; max-width: 62ch; }
.desk-id .overline.invested { color: var(--invest); }
/* The one control on this screen that opens onto everything else it can do,
   so it does not get to look like Filters' peer. A wash of the accent, not
   the accent itself: `.btn.primary` is reserved for committing something
   (Save, Sign in), and this button commits nothing - it only offers to show
   what else is here. */
.desk-switch { flex: none; display: inline-flex; align-items: center;
  gap: 6px; margin-top: 2px; font-weight: 600;
  background: var(--accent-wash); border-color: rgba(57, 135, 229, 0.4);
  color: var(--fg); }
.desk-switch:hover { background: rgba(57, 135, 229, 0.26);
  border-color: rgba(57, 135, 229, 0.6); color: #fff; }
.desk-switch svg { transform: rotate(90deg); }

/* The budget behind "What can you buy today?" - shown in the exact slot
   every other question's static rule occupies, wearing a control instead of
   a sentence. Kept out of `.desk-rule` deliberately: the number changes on
   every drag and a sentence spliced around a moving figure reads as noise,
   where a number that is simply, plainly large reads as the point. */
.budget-control { display: flex; align-items: baseline; flex-wrap: wrap;
  gap: 2px var(--s2); margin-top: 2px; }
.budget-label { font-size: var(--fs-micro); color: var(--fg-faint);
  text-transform: uppercase; letter-spacing: 0.5px; font-weight: 600;
  align-self: center; }
.budget-dollar { font-family: var(--mono); font-size: 40px; font-weight: 650;
  color: var(--invest); line-height: 1; }
.figure-num {
  font-family: var(--mono); font-variant-numeric: tabular-nums;
  font-size: 40px; font-weight: 650; color: var(--invest); line-height: 1;
  cursor: ew-resize; user-select: none; padding: 2px 4px;
  border-radius: var(--r-sm); margin: -2px -4px;
  transition: background var(--dur-fast) var(--ease);
}
.figure-num:hover, .figure-num:focus-visible { background: var(--invest-wash); outline: none; }
.figure-num.dragging { background: var(--invest-wash-strong); }
.figure-num-edit {
  font-family: var(--mono); font-variant-numeric: tabular-nums;
  font-size: 40px; font-weight: 650; color: var(--invest);
  background: var(--invest-wash-strong); border: none; outline: none;
  border-radius: var(--r-sm); width: 4.4ch; padding: 2px 4px; margin: -2px -4px;
}
.figure-hint { flex-basis: 100%; font-size: var(--fs-caption);
  color: var(--fg-faint); }

.browse-controls { display: flex; gap: var(--s2); align-items: center; }
.browse-controls .grow { position: relative; }
.filter-button-wrap { position: relative; }

.browse-meta { display: flex; align-items: center; gap: var(--s2);
  min-height: 20px; }
.browse-count { display: flex; align-items: center; flex-wrap: wrap;
  gap: 2px var(--s3); color: var(--fg-muted); font-size: var(--fs-small);
  min-width: 0; }
.count-part { white-space: nowrap; }
.count-part b { color: var(--fg); font-weight: 600; }
/* The one figure on this line that changes how the rest should be read. */
.count-part.count-rarely_traded b { color: var(--warn); }

/* No negative margin. The rows are inset by their own padding instead: a
   negative margin here makes the list wider than the pane that clips it, and
   the price column on the right silently disappears. */
.results { flex: 1; min-height: 0; overflow-y: auto; overflow-x: hidden; }

/* --- results -------------------------------------------------------------- */

/* A result is a card and its evidence: artwork big enough to recognise, the
   identity, the specific reason to be careful if there is one, the figure that
   answers the question this list is inside, and the price. The interest score
   is deliberately not here - the top of a percentile ranking is flat, and a
   figure that reads the same on every row is not information. It is one row
   away in the tooltip and one click away in the report. */
.result {
  display: flex; gap: 14px; align-items: center;
  width: 100%; text-align: left;
  padding: 8px 14px; margin: 3px 0;
  background: transparent; border: 1px solid transparent;
  border-radius: var(--r-md);
  cursor: pointer;
  color: inherit;
}
.result:hover { background: rgba(255, 255, 255, 0.05); }
/* Selection is an inset rounded plate rather than a full-bleed slab. A blue
   rectangle spanning the viewport is how a file manager indicates selection; a
   rounded card that lifts out of the list is how a designed application does. */
.result[aria-selected="true"] {
  background: rgba(57, 135, 229, 0.15);
  border-color: rgba(57, 135, 229, 0.43);
}
.result .art { width: 62px; }
.result-body { flex: 1; min-width: 0; display: flex; flex-direction: column;
  gap: 3px; }
.result-name {
  display: flex; align-items: center; gap: 6px;
  font-size: var(--fs-body); font-weight: 600;
}
/* Two lines before it is cut, not one: at laptop and phone widths a single
   line held about seven characters, and "Charizard ex (Spe..." five times
   over is a list nobody can choose from. */
.result-name span { overflow: hidden; display: -webkit-box;
  -webkit-box-orient: vertical; -webkit-line-clamp: 2; line-clamp: 2;
  line-height: 1.3; overflow-wrap: anywhere; }
.result-name svg { width: 13px; height: 13px; flex: none; color: var(--warn); }
.result-meta-line {
  display: flex; align-items: center; gap: 5px;
  color: var(--fg-muted); font-size: var(--fs-micro);
  overflow: hidden;
}
.result-meta-line span { overflow: hidden; text-overflow: ellipsis;
  white-space: nowrap; }
/* The specific finding, quietly. A pill on 82% of rows was a texture; a dot
   and four words in the row's own type reads once per card and never shouts. */
.result-trust { display: flex; align-items: center; gap: 6px;
  font-size: var(--fs-micro); }
.result-trust .trust-dot { width: 6px; height: 6px; border-radius: 50%;
  background: currentColor; flex: none; }

/* The middle column: what this card contributes to the question. The value
   leads at body size because it is the figure the list is ordered by - the
   evidence, not an annotation. */
.result-evidence { flex: none; width: 118px; text-align: right;
  display: flex; flex-direction: column; gap: 1px; align-items: flex-end; }
.result-evidence .ev-value { font-size: var(--fs-body); font-weight: 600;
  font-family: var(--mono); font-variant-numeric: tabular-nums; }
.result-evidence .ev-label { color: var(--fg-faint);
  font-size: var(--fs-caption); overflow: hidden; text-overflow: ellipsis;
  white-space: nowrap; max-width: 118px; }

/* Wide enough for the forecast line ("22% chance to beat the market") to sit
   in two balanced lines under the price rather than four ragged ones. */
.result-figures { text-align: right; flex: none; width: 100px; display: flex;
  flex-direction: column; gap: 2px; align-items: flex-end; }
.result-figures .price { font-weight: 600; font-size: var(--fs-body); }
.result-figures .fc { font-size: var(--fs-caption); font-weight: 600;
  line-height: 1.25; text-wrap: balance; }

/* Where the list pane is narrow - beside the report on a laptop, or a phone -
   the evidence moves under the card's name instead of taking a column of its
   own, which is what left the name about seven characters. The row becomes a
   small grid: artwork, then name over evidence, then price. Between the two
   the list has the whole pane and keeps its three columns. */
@media (min-width: 1025px) and (max-width: 1300px), (max-width: 760px) {
  /* The empty first and last rows take the artwork's extra height, so the
     name and its evidence sit together in the middle of the row. */
  .result { display: grid; grid-template-columns: auto minmax(0, 1fr) auto;
    grid-template-rows: 1fr auto auto 1fr;
    grid-template-areas: "art . fig" "art body fig" "art ev fig" "art . fig";
    column-gap: 12px; row-gap: 0; }
  .result-evidence { margin-top: 3px; }
  .result > .art { grid-area: art; align-self: center; }
  .result-body { grid-area: body; }
  .result-evidence { grid-area: ev; width: auto; flex-direction: row;
    align-items: baseline; justify-content: flex-start; gap: 6px;
    text-align: left; min-width: 0; }
  .result-evidence:empty { display: none; }
  .result-evidence .ev-value { font-size: var(--fs-small); }
  .result-evidence .ev-label { max-width: none; min-width: 0; }
  .result-figures { grid-area: fig; align-self: center; }
}

.load-more { width: 100%; margin: var(--s3) 0; }

/* --- the question's case (the report pane, before a card is chosen) -------- */

/* This pane is 60% of the screen, and before a card is chosen it used to spend
   all of it on the words "Pick a card". It now argues for the question the
   reader is inside - the same width discipline as the card report it swaps out
   with, because both are prose. */
.brief-pane {
  max-width: 640px; margin: 0 auto; padding: 46px 34px 40px;
  display: flex; flex-direction: column; gap: var(--s4);
}
.brief-title { margin: 0; font-size: var(--fs-display); font-weight: 650;
  letter-spacing: -0.6px; line-height: 1.12; }
.brief-rule { margin: 0; color: var(--fg-dim); font-size: var(--fs-prose);
  line-height: 1.6; }
.brief-why { margin: 0; color: var(--fg-dim); font-size: var(--fs-prose);
  line-height: 1.65; }
.brief-block { display: flex; flex-direction: column; gap: 6px;
  padding-top: var(--s4); border-top: 1px solid var(--grid); }
.brief-block p { margin: 0; color: var(--fg-dim); font-size: var(--fs-small);
  line-height: 1.6; }
.brief-h { margin: 0; display: flex; align-items: center; gap: 6px;
  color: var(--fg-muted); font-size: var(--fs-micro); font-weight: 600;
  letter-spacing: 0.5px; text-transform: uppercase; }
.brief-metric { display: flex; align-items: baseline; gap: 8px;
  margin-top: 2px; cursor: help; }
.brief-metric-name { font-weight: 600; font-size: var(--fs-body); }
.brief-metric-note { color: var(--fg-faint); font-size: var(--fs-caption); }
.measured-row { display: flex; align-items: baseline; gap: var(--s3); }
.measured-verdict { font-size: var(--fs-heading); font-weight: 600; }
.measured-ic { display: flex; align-items: baseline; gap: 5px;
  color: var(--fg-muted); font-size: var(--fs-small); }
.measured-cap { font-size: var(--fs-caption); color: var(--fg-faint); }
.brief-caveat .brief-h { color: var(--warn); }
.brief-prompt { margin: 0; padding-top: var(--s4);
  border-top: 1px solid var(--grid);
  color: var(--fg-muted); font-size: var(--fs-small); line-height: 1.6; }

/* --- the question picker --------------------------------------------------- */

/* The same object as the front page's desk index: three faces, the question,
   the honest size of its answer. A reader arriving from Today has already used
   this control once. */
.dialog.questions { width: min(760px, 94vw); padding: var(--s5) var(--s5) var(--s6);
  gap: var(--s4); overflow-y: auto; }
.q-picker { display: flex; flex-direction: column; gap: var(--s5); }
.q-picker-head { display: flex; flex-direction: column; gap: 4px; }
.q-picker-title { margin: 0; font-size: var(--fs-title); font-weight: 650;
  letter-spacing: -0.4px; }
.q-picker-lede { margin: 0; color: var(--fg-muted); font-size: var(--fs-small);
  line-height: 1.55; max-width: 66ch; }
.q-group { display: flex; flex-direction: column; gap: 4px; }
.q-group-title { margin: 0; font-size: var(--fs-heading); font-weight: 600; }
.q-group-note { margin: 0 0 6px; color: var(--fg-muted);
  font-size: var(--fs-micro); line-height: 1.5; max-width: 70ch; }
.q-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 8px; }
.q-entry {
  display: flex; align-items: center; gap: var(--s3); text-align: left;
  padding: 10px 12px;
  background: var(--bg-sunken); border: 1px solid transparent;
  border-radius: var(--r-md); color: inherit; cursor: pointer;
}
.q-entry:hover { background: var(--bg-panel);
  border-color: rgba(246, 242, 236, 0.08); }
.q-entry[aria-pressed="true"] { border-color: rgba(57, 135, 229, 0.5);
  background: var(--accent-wash); }
/* The signature tile: the same button, the same grid, the same click
   handler as every other question - only the paint changes. Reserved for
   "What can you buy today?" alone; reusing this treatment on a second tile
   is exactly the mistake that turns a signature into wallpaper. */
.q-group-invest { margin-bottom: -6px; }
.q-group-invest .q-grid { grid-template-columns: 1fr; }
.q-entry-invest {
  background: linear-gradient(155deg, var(--invest-wash), var(--bg-sunken) 65%);
  border-color: rgba(201, 152, 90, 0.35);
}
.q-entry-invest:hover {
  background: linear-gradient(155deg, var(--invest-wash-strong), var(--bg-panel) 65%);
  border-color: rgba(201, 152, 90, 0.6);
}
.q-entry-invest svg { color: var(--invest); flex: none; }
.q-spine { display: flex; flex: none; }
.q-spine .art { width: 34px; }
.q-spine > *:not(:first-child) { margin-left: -17px; }
.q-body { flex: 1; min-width: 0; }
.q-title { font-size: var(--fs-body); font-weight: 600; }
.q-sub { margin: 1px 0 0; color: var(--fg-muted); font-size: var(--fs-caption);
  line-height: 1.45;
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical;
  overflow: hidden; }
.q-count { flex: none; text-align: right; }
.q-count .count { display: block; font-weight: 650;
  font-variant-numeric: tabular-nums; }
.q-count .count-cap { font-size: var(--fs-caption); color: var(--fg-faint); }
.q-saved-list { display: flex; flex-direction: column; gap: 4px; }
.q-saved { display: flex; align-items: center; gap: 8px; text-align: left;
  padding: 8px 12px; background: var(--bg-sunken); border: 1px solid transparent;
  border-radius: var(--r-md); color: inherit; cursor: pointer;
  font-size: var(--fs-body); font-weight: 600; }
.q-saved:hover { background: var(--bg-panel);
  border-color: rgba(246, 242, 236, 0.08); }
.q-saved svg { color: var(--warn); flex: none; }
.q-saved-invite { display: flex; flex-direction: column; gap: 8px;
  align-items: flex-start; }

/* Naming a saved question - in the product, not in a `window.prompt()`. */
.dialog.name-view-dialog { width: min(420px, 92vw); top: 16vh;
  padding: var(--s5); }
.name-view { display: flex; flex-direction: column; gap: var(--s3); }
.name-view h2 { margin: 0; }
.name-view .hint { margin: 0; }
.name-actions { justify-content: flex-end; }

/* Filters live in a popover wide enough to show them properly rather than a
   238px rail that is resident whether or not anyone is filtering. What is
   *currently* filtering shows as removable chips above the results, so the
   state is visible even though the controls are not. */
.filter-panel { width: min(700px, calc(100vw - 40px)); }
.filter-grid {
  display: grid; grid-template-columns: 238px 1fr; gap: 26px;
  margin-top: var(--s3);
}
.filter-col { display: flex; flex-direction: column; gap: 6px; }
.filter-head {
  color: var(--fg-muted); font-size: var(--fs-micro); font-weight: 600;
  letter-spacing: 0.6px; padding: 10px 0 2px;
}
.check-list {
  background: var(--bg-sunken); border-radius: var(--r-md);
  padding: 4px; overflow-y: auto;
}
.check-list label { padding: 5px 8px; border-radius: 6px; }
.check-list label:hover { background: rgba(246, 242, 236, 0.05); }
.filter-pair { display: grid; grid-template-columns: 1fr 1fr; gap: 14px; }

/* ============================================================ card report = */

/* The report is prose beside a card image, and prose has a measure. Capped and
   centred, it stays readable however wide the window is dragged. */
.report { max-width: 900px; margin: 0 auto; padding: 22px 26px 34px; }

/* Three and a half screens is a long way to read without being told, at any
   point, which card you are reading about. */
/* It takes no room in the flow: a fixed height, cancelled by the same negative
   bottom margin, so the hero starts at the top of the report and the bar lays
   over it only once it is shown. Invisible but in the flow, it held an 81px
   blank band above every report. One line of name and meta, ellipsised, is
   what keeps the height fixed. */
.report-sticky {
  --sticky-h: 56px;
  position: sticky; top: 0; z-index: 5;
  display: flex; align-items: center; gap: var(--s3);
  box-sizing: border-box; height: var(--sticky-h);
  padding: 6px 26px;
  background: var(--bg-panel);
  border-bottom: 1px solid var(--grid);
  margin: 0 -26px calc(-1 * var(--sticky-h));
  opacity: 0;
  visibility: hidden;
  transition: opacity var(--dur-fast) var(--ease-soft),
              visibility 0s linear var(--dur-fast);
  pointer-events: none;
}
.report-sticky.on { opacity: 1; visibility: visible; pointer-events: auto;
  transition: opacity var(--dur-fast) var(--ease-soft); }
.report-sticky .art { width: 30px; flex: none; }
.report-sticky .grow { min-width: 0; }
.report-sticky .name, .report-sticky .meta { overflow: hidden;
  text-overflow: ellipsis; white-space: nowrap; }
.report-sticky .name { font-weight: 600; }
.report-sticky .meta { color: var(--fg-muted); font-size: var(--fs-micro); }
.report-sticky .price { font-size: var(--fs-heading); font-weight: 600; }

.report-hero { display: flex; gap: 22px; }
.report-hero .art { width: 200px; }
.report-hero-body { flex: 1; min-width: 0; display: flex;
  flex-direction: column; gap: 7px; }
.report-headline { display: flex; align-items: flex-start; gap: 22px;
  margin-top: 6px; }
.report-price { flex: 1; min-width: 0; }
.report-price .cap { color: var(--fg-muted); font-size: 11.5px;
  font-weight: 600; }
.report-price .note { color: var(--fg-muted); font-size: 11.5px;
  line-height: 1.45; }
.report-actions { display: flex; gap: 7px; margin-top: auto; padding-top: 14px; }

/* The interest score as a filled arc plus the number and its tier word. A
   meter rather than a bare figure: 0-100 has hard ends, and a fill against a
   track shows position within the range at a glance. The word beside it is not
   decoration - it is what stops the number being meaningless on first sight. */
.dial { width: 84px; flex: none; text-align: center; }
.dial svg { width: 84px; height: 84px; display: block; }
.dial .arc { transition: stroke-dashoffset 520ms cubic-bezier(0.22, 1, 0.36, 1); }
.dial .tier { font-size: var(--fs-small); font-weight: 600; margin-top: 2px; }

.report-badges { display: flex; flex-wrap: wrap; gap: 6px; margin-top: var(--s4); }

/* The caveat box. Shown only when earned - a permanent disclaimer gets tuned
   out, one that appears for a reason gets read. */
.warning-box {
  color: var(--fg-dim); background: var(--bg-sunken);
  border: 1px solid currentColor; border-left: 3px solid currentColor;
  border-radius: var(--r-sm);
  padding: 11px 13px; font-size: 12.5px; line-height: 1.55;
  margin-top: var(--s4);
}
.warning-box b { color: currentColor; }

.outlook-range { padding: 12px 14px; }
.outlook-range .cap { color: var(--fg-muted); font-size: 11.5px;
  font-weight: 600; }
.outlook-range .main { font-size: var(--fs-display); font-weight: 600;
  letter-spacing: -0.8px; }
.outlook-range .note { color: var(--fg-muted); font-size: 11.5px; }
.outlook-tiles { display: grid; grid-template-columns: repeat(3, 1fr);
  gap: 10px; }
.outlook-tile { padding: 10px 12px; }
.outlook-tile .cap { color: var(--fg-muted); font-size: 11px;
  font-weight: 600; }
.outlook-tile .value { font-size: 20px; font-weight: 700; }
.outlook-tile .note { color: var(--fg-muted); font-size: 10.5px;
  line-height: 1.4; }

/* One question, its answer, and the reasoning - reasoning folded away. The core
   unit of the card report and the direct expression of "the application should
   answer questions, not display numbers". */
.answers { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 10px; }
.answer { padding: 14px 16px; }
.answer-top { display: flex; align-items: flex-start; gap: var(--s2); }
.answer-verdict { flex: 1; font-size: var(--fs-heading); font-weight: 600;
  line-height: 1.35; }
.answer-detail { color: var(--fg-dim); font-size: var(--fs-small);
  line-height: 1.6; margin-top: 6px; }
.answer-evidence { display: flex; gap: 18px; margin-top: 8px; }
.answer-evidence .k { color: var(--fg-faint); font-size: var(--fs-caption); }
.answer-evidence .v { font-family: var(--mono); color: var(--fg-dim); }

.breakdown { display: flex; flex-direction: column; }
.breakdown-head, .breakdown-row {
  display: grid;
  grid-template-columns: 132px 46px minmax(90px, 0.32fr) 1fr;
  align-items: center; gap: 8px;
}
.breakdown-head { color: var(--fg-muted); font-size: 9.5px; font-weight: 600;
  letter-spacing: 0.5px; padding-bottom: 4px; }
.breakdown-head .r, .breakdown-row .name, .breakdown-row .share {
  text-align: right; }
.breakdown-row { height: 30px; font-size: var(--fs-small); }
.breakdown-row .name { color: var(--fg-dim); overflow: hidden;
  text-overflow: ellipsis; white-space: nowrap; }
.breakdown-row .share { color: var(--fg-muted); }
.breakdown-row .phrase { color: var(--fg-dim); display: flex;
  align-items: center; gap: 8px; min-width: 0; }
.breakdown-row .phrase .ptext { overflow: hidden; text-overflow: ellipsis;
  white-space: nowrap; min-width: 0; }
.breakdown-row .phrase.none { color: var(--fg-muted); }
/* How well this one ingredient has actually measured, named quietly beside
   the sentence it backs up rather than as a second row of statistics - the
   same "a dot and a few words" restraint `.result-trust` uses in Browse. */
.breakdown-row .measured-dot { display: flex; align-items: center; gap: 4px;
  flex: none; font-size: var(--fs-micro); }
.breakdown-row .measured-dot i { width: 6px; height: 6px; border-radius: 50%;
  background: currentColor; }
.bar-track { position: relative; height: 10px; }
.bar-track::before {
  content: ""; position: absolute; left: 50%; top: -10px; bottom: -10px;
  width: 1px; background: var(--border);
}
.bar-track i { position: absolute; top: 0; height: 10px; border-radius: 4px; }

.metrics-table { width: 100%; border-collapse: collapse; font-size: var(--fs-small); }
.metrics-table td { padding: 5px 10px; border-bottom: 1px solid var(--grid); }
.metrics-table td:first-child { color: var(--fg-dim); white-space: nowrap; }
.metrics-table td.v { font-family: var(--mono); text-align: right;
  white-space: nowrap; }
.metrics-table td:last-child { color: var(--fg-muted); }

/* The forecast panel. It used to share a two-column row with Investment
   Outlook's star table; that panel left the card report (its ratings are the
   same for every card - see `web/horizon_outlook.py`), so Forecast now spans
   the row on its own. Still a flex column so its "Learn more" footer anchors
   to the bottom of the panel rather than trailing whatever precedes it. */
.oc-panel { padding: 18px 20px; display: flex; flex-direction: column; }
.oc-panel > section { display: flex; flex-direction: column; flex: 1; }
.oc-foot { margin-top: auto; }

/* A one-word eyebrow naming what kind of claim the panel below it makes - a
   prediction - in Forecast's own colour (`--forecast`, also the chart's
   cone), so the panel and the cone read as the same model. */
.oc-kicker { font-size: 10px; font-weight: 700; letter-spacing: 0.6px;
  text-transform: uppercase; }
.oc-kicker.forecast { color: var(--forecast); }
.oc-kicker + .section-header { margin-top: 2px; }

/* "Learn more": a short visible line with the fuller research caveat folded
   away behind one toggle (`report.js::learnMore`). */
.ho-note { color: var(--fg-faint); font-size: var(--fs-micro); line-height: 1.55; }
.ho-learn { margin-top: 2px; display: flex; flex-direction: column; gap: 6px; }
.ho-learn-toggle { padding: 3px 0; font-size: var(--fs-caption);
  color: var(--fg-muted); background: none; border: none; }
.ho-learn-toggle:hover { color: var(--fg-dim); background: none; }

.tabs { display: flex; gap: 3px; border-bottom: 1px solid var(--grid);
  margin-bottom: var(--s3); }
.tab {
  background: transparent; border: none; border-radius: var(--r-md) var(--r-md) 0 0;
  padding: 8px 15px; color: var(--fg-muted); font-size: var(--fs-small);
  cursor: pointer;
}
.tab:hover { color: var(--fg-dim); background: rgba(246, 242, 236, 0.05); }
.tab[aria-selected="true"] { color: var(--fg); font-weight: 600;
  background: rgba(246, 242, 236, 0.09); }

.note-item {
  background: var(--bg-panel);
  border: 1px solid rgba(246, 242, 236, 0.055);
  border-radius: var(--r-md);
  padding: 12px 15px;
  color: var(--fg-dim);
  font-size: var(--fs-small);
  line-height: 1.6;
  display: flex; gap: var(--s3); align-items: flex-start;
}
.note-item .grow { min-width: 0; white-space: pre-wrap; word-break: break-word; }
.note-when { color: var(--fg-muted); font-size: var(--fs-micro);
  margin-bottom: 4px; }

.form-row { display: grid; grid-template-columns: 160px 1fr; gap: var(--s3);
  align-items: center; }

/* ================================================================= chart == */

.chart { width: 100%; }
.chart svg { width: 100%; display: block; touch-action: pan-y; }
.chart-bar { display: flex; align-items: center; gap: 6px;
  margin-bottom: var(--s2); flex-wrap: wrap; }
.chart-bar select { width: auto; }
.chart-readout { color: var(--fg-muted); font-size: var(--fs-small);
  min-height: 18px; }
.chart .grid-line { stroke: var(--grid); stroke-width: 1; }
.chart .axis-text { fill: var(--fg-muted); font-size: 10px;
  font-family: var(--sans); }
.chart .price-line { fill: none; stroke: var(--accent); stroke-width: 2;
  stroke-linejoin: round; }
.chart .ask-band { fill: rgba(57, 135, 229, 0.15); }
.chart .cone-80 { fill: rgba(147, 112, 219, 0.1); }
.chart .cone-50 { fill: rgba(147, 112, 219, 0.17); }
.chart .cone-line { fill: none; stroke: var(--forecast); stroke-width: 2;
  stroke-dasharray: 5 4; }
.chart .crosshair { stroke: var(--fg-muted); stroke-width: 1;
  stroke-dasharray: 3 3; }
.chart .cursor-dot { fill: var(--accent); stroke: var(--bg-panel);
  stroke-width: 2; }
.chart .base-line { stroke: var(--fg-muted); stroke-width: 1;
  stroke-dasharray: 2 3; }

.chart-legend { display: flex; flex-wrap: wrap; gap: var(--s3);
  font-size: var(--fs-micro); color: var(--fg-dim); margin-top: 6px; }
.chart-legend i { display: inline-block; width: 10px; height: 2px;
  vertical-align: middle; margin-right: 5px; background: currentColor; }

/* ===================================================== Watchlist & Collection = */
/* Shared by both: a person's cards, however they hold them. */

.stat-tiles { display: grid; grid-template-columns: repeat(3, minmax(0, 200px));
  gap: 10px; }
.stat-tile { padding: 12px 14px; }
.stat-tile .cap { color: var(--fg-muted); font-size: var(--fs-micro);
  font-weight: 600; }
.stat-tile .value { font-size: var(--fs-title); font-weight: 600;
  letter-spacing: -0.4px; }
.stat-tile .note { color: var(--fg-muted); font-size: var(--fs-micro); }

.thumb-cell { width: 46px; }
.thumb-cell .art { width: 34px; }

/* ----------------------------------------------------------- Collection --- */

.owned-row { padding: 12px 14px; display: flex; flex-direction: column;
  gap: 10px; }
.owned-row .name { font-weight: 600; }
.owned-fields { display: flex; flex-wrap: wrap; gap: var(--s4); }
.owned-fields .form-row { grid-template-columns: auto auto; gap: 6px; }
.owned-fields .form-row.grow { flex: 1 1 220px; grid-template-columns: auto 1fr; }
.owned-fields input, .owned-fields select {
  background: var(--bg-sunken); border: 1px solid var(--hairline);
  border-radius: var(--r-sm); color: var(--fg); padding: 5px 8px;
  font-size: var(--fs-small);
}

.add-card { padding: 12px 14px; }
.add-card-results:empty { display: none; }
.add-card-results { display: flex; flex-direction: column; gap: 2px;
  margin-top: 8px; }
.add-card-results .palette-item { border-radius: var(--r-sm); }

.standout-row { padding: 12px 14px; display: flex; align-items: center;
  gap: var(--s3); }
.standout-row .name { font-weight: 600; }
.standout-row .count { color: var(--fg-muted); font-size: var(--fs-small);
  white-space: nowrap; }

/* A plain magnitude bar - composition has no sign, so this is one filled
   track rather than the diverging pos/neg pair the score breakdown uses.
   Reused by Portfolio Intelligence's diversification read below. */
.composition-bar { height: 4px; border-radius: 2px;
  background: rgba(246, 242, 236, 0.08); overflow: hidden; margin-top: 4px; }
.composition-bar i { display: block; height: 100%; background: var(--accent);
  border-radius: 2px; }

/* ------------------------------------------------- the binder gallery ---- */
/* My Collection and Watchlist share this: cards shown at gallery size,
   grouped where grouping means something (by set for a collection, not at
   all for a watchlist), each tile opening in place rather than sending the
   reader to another page to edit four fields. The foil sheen on `.ctile`/
   `.wl-tile` hover is the same mechanism `.finding` uses on Today - see the
   comment above `.anatomy-art .art::before` - extended here because this is
   the other place real card art is shown at gallery size, one tile at a
   time under the pointer. */

.binder-head { display: flex; gap: var(--s4); flex-wrap: wrap; margin-bottom: var(--s5); }
.health-card { display: flex; align-items: center; gap: var(--s4);
  padding: 14px 20px; flex: 1 1 320px; min-width: 280px; }
.health-card .dial { flex: none; }
.health-card p { font-size: var(--fs-small); color: var(--fg-muted);
  max-width: 42ch; margin-top: 3px; }
.health-card a { color: var(--accent); }
.binder-tally { flex: 1 1 280px; display: flex; align-items: center;
  gap: var(--s5); padding: 0 var(--s4); flex-wrap: wrap; }
.binder-tally .stat { display: flex; flex-direction: column; gap: 2px; }
.binder-tally .stat b { font-size: var(--fs-title); font-weight: 650;
  font-variant-numeric: tabular-nums; }
.binder-tally .stat span { font-size: var(--fs-micro); color: var(--fg-muted); }

.set-group { margin-top: var(--s6); }
.set-group:first-of-type { margin-top: 0; }
.set-group-head { display: flex; align-items: baseline; gap: 10px;
  margin-bottom: 12px; padding-bottom: 8px; border-bottom: 1px dashed var(--border); }
.set-group-head h3 { font-size: var(--fs-heading); font-weight: 650; }
.set-group-head .set-meta { font-size: var(--fs-micro); color: var(--fg-faint); }

.card-grid { display: grid;
  grid-template-columns: repeat(auto-fill, minmax(160px, 1fr)); gap: var(--s3); }

.ctile { padding: 14px; text-align: center; position: relative;
  transition: transform var(--dur-base) var(--ease), background var(--dur-base) var(--ease); }
.ctile[tabindex] { cursor: pointer; }
.ctile[tabindex]:hover { background: var(--bg-elevated); transform: translateY(-3px); }
.ctile[tabindex]:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.ctile[data-open="true"] { grid-column: 1 / -1; cursor: default; transform: none; }
.ctile[data-open="true"]:hover { background: var(--bg-panel); }
.ctile .art { width: 128px; margin: 0 auto 10px; }
.ctile .c-name { font-size: var(--fs-body); font-weight: 650; }
.ctile .c-meta { font-size: var(--fs-micro); color: var(--fg-faint); margin-top: 2px; }
.ctile .cond-row { display: flex; align-items: center; justify-content: center;
  gap: 5px; margin-top: 6px; font-size: var(--fs-micro); color: var(--fg-muted); }
.ctile .cond-dot { width: 8px; height: 8px; border-radius: 50%; flex: none; }
.ctile .money-row { display: flex; justify-content: center; gap: 6px;
  align-items: baseline; margin-top: 8px; font-size: var(--fs-small);
  font-variant-numeric: tabular-nums; }
.ctile .money-row .then { color: var(--fg-faint); }
.ctile .money-row .now { font-weight: 650; }
.ctile .evidence-chip { display: inline-block; margin-top: 8px;
  font-size: var(--fs-micro); padding: 3px 9px; border-radius: var(--r-pill);
  color: var(--fg-dim); background: rgba(246, 242, 236, 0.06);
  max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ctile .evidence-chip.flag { background: color-mix(in srgb, currentColor 13%, transparent);
  border: 1px solid currentColor; white-space: normal; }

.ctile-drawer { display: grid; grid-template-columns: 170px 1fr; gap: var(--s5);
  margin-top: 16px; padding-top: 16px; border-top: 1px solid var(--border);
  text-align: left; }
.ctile-drawer .art { width: 100%; max-width: 170px; margin: 0; }
@media (max-width: 640px) { .ctile-drawer { grid-template-columns: 1fr; } }
.drawer-fields { display: flex; flex-wrap: wrap; gap: var(--s4); }
.drawer-money { display: flex; gap: var(--s5); flex-wrap: wrap; margin-top: 2px; }
.drawer-money .stat b { display: block; font-size: var(--fs-heading);
  font-variant-numeric: tabular-nums; }
.drawer-money .stat span { font-size: var(--fs-micro); color: var(--fg-muted); }
.journal { margin-top: var(--s4); }
.journal h4 { font-size: var(--fs-small); font-weight: 650; color: var(--fg-dim); }
.journal .note-item { margin-top: 8px; }
.journal textarea { width: 100%; min-height: 52px; margin-top: 8px;
  background: var(--bg-sunken); border: 1px solid var(--hairline);
  border-radius: var(--r-sm); color: var(--fg); padding: 8px 10px;
  font-family: var(--sans); font-size: var(--fs-small); resize: vertical; }

/* ---------------------------------------------------- Watchlist gallery -- */

.wl-grid { display: grid;
  grid-template-columns: repeat(auto-fill, minmax(268px, 1fr)); gap: var(--s3); }
.wl-tile { padding: 16px; cursor: pointer; }
.wl-tile:hover { background: var(--bg-elevated); }
.wl-tile:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.wl-tile[data-open="true"] { grid-column: 1 / -1; cursor: default; }
.wl-tile[data-open="true"]:hover { background: var(--bg-panel); }
.wl-tile-head { display: flex; gap: var(--s4); align-items: flex-start; }
.wl-tile .art { width: 74px; flex: none; margin: 0; }
.wl-tile .grow { min-width: 0; }
.wl-tile .c-name { font-size: var(--fs-body); font-weight: 650; }
.wl-tile .c-meta { font-size: var(--fs-micro); color: var(--fg-faint); margin-top: 1px; }
.stars { display: flex; gap: 2px; margin-top: 7px; }
.stars svg { width: 12px; height: 12px; }
.wl-thesis { font-size: var(--fs-small); color: var(--fg-dim); font-style: italic;
  margin-top: 8px; line-height: 1.5; }
.wl-figures { display: flex; gap: var(--s4); margin-top: 9px;
  font-size: var(--fs-small); font-variant-numeric: tabular-nums; }
.wl-figures div span { display: block; font-size: var(--fs-caption);
  color: var(--fg-faint); font-variant-numeric: initial; }
.evidence-check { margin-top: 9px; padding: 8px 10px; border-radius: var(--r-sm);
  font-size: var(--fs-micro); line-height: 1.55; background: var(--bg-sunken);
  border: 1px solid var(--hairline); }
.evidence-check .tag { display: block; font-weight: 700; font-size: var(--fs-caption);
  text-transform: uppercase; letter-spacing: 0.04em; margin-bottom: 3px; }

/* ==================================================== Portfolio Intelligence = */
/* Five questions, two columns on a wide screen. Nothing here invents a new
   visual language - `.panel.tile`, `.composition-bar`, `.badge` and `.art`
   all already exist; this section is mostly about giving them a layout that
   reads as an analyst's page rather than a form. */

.pi-grid { display: grid; grid-template-columns: 1.1fr 0.9fr; gap: var(--s4); }
@media (max-width: 860px) { .pi-grid { grid-template-columns: 1fr; } }
.pi-col { display: flex; flex-direction: column; gap: var(--s4); }
.pi-panel { padding: 20px 22px; }
.pi-panel h4 { font-size: var(--fs-heading); font-weight: 650; }
.pi-panel .sub { font-size: var(--fs-micro); color: var(--fg-muted); margin-top: 3px; }
.pi-panel .empty-note { font-size: var(--fs-small); color: var(--fg-muted);
  margin-top: 10px; }

.conc-row { margin-top: 16px; }
.conc-row:first-of-type { margin-top: 14px; }
.conc-row .lbl { display: flex; justify-content: space-between; gap: var(--s3);
  font-size: var(--fs-small); margin-bottom: 5px; }
.conc-row .lbl b { font-variant-numeric: tabular-nums; color: var(--fg-dim);
  font-weight: 650; }

.rollup-row { display: flex; gap: 10px; margin-top: 14px; flex-wrap: wrap; }
.rollup-pill { flex: 1 1 110px; padding: 10px 12px; border-radius: var(--r-md);
  background: var(--bg-sunken); border: 1px solid var(--hairline); text-align: center; }
.rollup-pill b { display: block; font-size: var(--fs-title);
  font-variant-numeric: tabular-nums; }
.rollup-pill span { font-size: var(--fs-caption); color: var(--fg-muted); }

.dist-bar { display: flex; height: 9px; border-radius: 5px; overflow: hidden;
  margin-top: 12px; background: var(--bg-sunken); }
.dist-bar div { height: 100%; }

.finding-line { display: flex; gap: 11px; align-items: flex-start;
  padding: 11px 0; border-top: 1px solid var(--hairline); cursor: pointer;
  background: none; border-left: none; border-right: none; border-bottom: none;
  width: 100%; text-align: left; color: inherit; }
button.finding-line { font: inherit; }
.finding-line:first-of-type { border-top: none; padding-top: 2px; }
.finding-line:hover .ftext b { color: var(--accent); }
.finding-line .art { width: 36px; flex: none; margin: 0; }
.finding-line .ftext { font-size: var(--fs-small); color: var(--fg-dim); line-height: 1.5; }
.finding-line .ftext b { color: var(--fg); }

.conviction-row { display: flex; gap: 11px; align-items: flex-start;
  padding: 12px 0; border-top: 1px solid var(--hairline); }
.conviction-row:first-of-type { border-top: none; padding-top: 2px; }
.conviction-row .art { width: 40px; flex: none; margin: 0; }
.conviction-row .grow { min-width: 0; }
.conviction-row .c-name { font-weight: 650; font-size: var(--fs-small); }
.conviction-row .c-thesis { font-size: var(--fs-micro); color: var(--fg-muted);
  font-style: italic; margin-top: 2px; }

/* ================================================================ Compare = */

.compare-strip { display: flex; gap: 10px; flex-wrap: wrap; }
.compare-card { width: 78px; text-align: center; }
.compare-card .art { width: 58px; margin: 0 auto; }
.compare-card .label { font-size: var(--fs-micro); font-weight: 600;
  margin-top: 4px; overflow: hidden; text-overflow: ellipsis;
  white-space: nowrap; }

.compare-table { width: 100%; border-collapse: collapse; font-size: var(--fs-small); }
.compare-table th {
  text-align: left; color: var(--fg-muted); font-size: var(--fs-micro);
  font-weight: 600; padding: 8px 10px; border-bottom: 1px solid var(--border);
}
.compare-table th.card-head { text-align: right; }
.compare-table td { padding: 6px 10px; border-bottom: 1px solid var(--grid);
  text-align: right; white-space: nowrap; }
.compare-table td.metric-label { text-align: left; color: var(--fg-dim); }
.compare-table td.left { text-align: left; }

/* ================================================================== Notes = */

.composer { padding: 14px 16px; }
.composer textarea { min-height: 84px; background: var(--bg-sunken);
  border: 1px solid var(--hairline); }
.composer-foot { display: flex; align-items: flex-end; gap: 10px;
  margin-top: 10px; }

/* ================================================================ palette = */

.palette { top: 100px; width: min(720px, 92vw); }
.palette-input { margin: 12px; }
.palette-list { flex: 1; overflow: auto; padding: 0 12px; min-height: 120px; }
.palette-item {
  display: flex; align-items: center; gap: var(--s3);
  width: 100%; text-align: left;
  padding: 9px 12px; border-radius: var(--r-sm);
  background: transparent; border: none; color: inherit; cursor: pointer;
  font-size: var(--fs-small);
}
.palette-item:hover { background: var(--bg-hover); }
.palette-item[aria-selected="true"] { background: var(--bg-select); }
.palette-item .art { width: 26px; }
.palette-item .grow { min-width: 0; }
.palette-item .p-name { font-weight: 600; overflow: hidden;
  text-overflow: ellipsis; white-space: nowrap; }
.palette-item .p-meta { color: var(--fg-muted); font-size: var(--fs-micro);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.palette-item .p-right { text-align: right; flex: none; }
.palette-foot { padding: 10px 16px 12px; border-top: 1px solid var(--grid);
  color: var(--fg-muted); font-size: var(--fs-micro); }

/* =================================================================== help = */

.help-tabs { display: flex; gap: 3px; padding: 12px 16px 0; flex-wrap: wrap;
  border-bottom: 1px solid var(--grid); }
.help-body { overflow: auto; padding: 18px 24px 24px; color: var(--fg-dim);
  line-height: 1.6; font-size: var(--fs-body); }
.help-body h2 { font-size: var(--fs-heading); color: var(--fg); margin: 0 0 6px; }
.help-body h3 { font-size: var(--fs-body); color: var(--fg); margin: 18px 0 0; }
.help-body p { margin: 8px 0; }
.help-body ul { margin: 8px 0; padding-left: 20px; }
.help-body li { margin: 5px 0; }
.help-body hr { border: none; border-top: 1px solid var(--grid); margin: 14px 0; }
.help-body table.keys td { padding: 6px 22px 6px 0; }
.help-body table.keys td.key { font-family: var(--mono); color: var(--fg);
  white-space: nowrap; }
.help-foot { padding: 10px 16px 12px; border-top: 1px solid var(--grid);
  display: flex; justify-content: flex-end; }

/* ================================================================ loading = */

/* =================================================================== admin = */

.log-row { padding: 10px 14px; display: flex; flex-direction: column;
  gap: 3px; }
.log-row > div:last-child { font-size: var(--fs-small); }

#view-admin input[type="checkbox"] { accent-color: var(--accent); width: 15px;
  height: 15px; }
#view-admin input[type="text"] {
  background: var(--bg-sunken); border: 1px solid var(--hairline);
  border-radius: var(--r-sm); color: var(--fg); padding: 7px 10px;
  font-size: var(--fs-small); width: 100%;
}

.dialog.admin-confirm { width: min(380px, 92vw); padding: 20px; gap: 14px; }

.boot {
  position: fixed; inset: 0; z-index: 200;
  display: grid; place-items: center; gap: var(--s4);
  align-content: center;
  background: var(--bg-app);
  text-align: center;
}
.boot svg { width: 54px; height: 54px; color: var(--accent);
  animation: spin 2.4s linear infinite; }
@keyframes spin { to { transform: rotate(360deg); } }
.boot .name { font-size: var(--fs-title); font-weight: 600;
  letter-spacing: -0.4px; }
.boot .progress-text { color: var(--fg-muted); font-size: var(--fs-small); }
.boot.hidden { display: none; }

/* ============================================================= responsive = */

@media (max-width: 1180px) {
  .answers { grid-template-columns: minmax(0, 1fr); }
}

/* The front page is built out of `auto-fit` grids, so almost all of it reflows
   without a breakpoint. These three are the exceptions - two-column layouts
   whose columns are *different things* rather than repetitions of one thing,
   which auto-fit cannot collapse for you. */
@media (max-width: 940px) {
  .open-grid { grid-template-columns: minmax(0, 1fr); gap: var(--s5); }
  .open-card { justify-self: center; }
  .brief-grid { grid-template-columns: minmax(0, 1fr); gap: var(--s5); }
  .anatomy-grid { grid-template-columns: minmax(0, 1fr); }
  /* Sticky is a wide-window affordance: the subject stays beside its layers
     while they scroll. Stacked, it would pin the card over its own evidence. */
  .anatomy-subject { position: static; }
}

/* On a wide window the list and the report sit side by side, so a control that
   takes you "back to the list" has nothing to do. */
.browse-report .back-to-list { display: none; }

@media (max-width: 1024px) {
  /* The report becomes a page of its own rather than a squeezed column. Below
     about 680px of pane the answer text starts to crop rather than wrap, and a
     cropped paragraph is worse than a second tap. */
  .browse { grid-template-columns: minmax(0, 1fr); }
  .browse-report { border-left: none; border-top: 1px solid var(--grid);
    display: none; }
  .browse.showing-report .browse-list { display: none; }
  .browse.showing-report .browse-report { display: block; }
  .browse-report .back-to-list { display: inline-flex; align-items: center;
    gap: 4px; margin-bottom: var(--s2); }
}

@media (max-width: 760px) {
  .browse-list { padding: 14px 10px 12px; }
  .result { padding: 6px 8px; gap: 10px; }
  .result .art { width: 48px; }
  .result { column-gap: 10px; }
  .result-figures { width: 92px; }
  .desk-head-top { flex-direction: column; align-items: flex-start; }
  .q-grid { grid-template-columns: minmax(0, 1fr); }
  .brief-pane { padding: 26px 18px 30px; }
  .front { padding: 4px 18px 56px; }
  .front > section { padding: 44px 0; }
  /* A measure set in `ch` is a measure the phone cannot honour. */
  .front-lead, .front-lede, .front-body, .front-h1 { max-width: none; }
  .question-grid { grid-template-columns: minmax(0, 1fr); }
  .report-hero { flex-direction: column; }
  .report-hero .art { width: 150px; }
  .outlook-tiles { grid-template-columns: minmax(0, 1fr); }
  .filter-grid { grid-template-columns: minmax(0, 1fr); gap: var(--s4); }
  .stat-tiles { grid-template-columns: minmax(0, 1fr); }
  .breakdown-head, .breakdown-row {
    grid-template-columns: 96px 40px minmax(60px, 1fr);
  }
  .breakdown-head .phrase-head, .breakdown-row .phrase { display: none; }
}
