/* Shared data-card styling for chat, previews, and public snapshots. */
  .kilby-card { margin-top: 8px; padding: 12px; border: 1px solid rgba(var(--kilby-tint),0.06); border-radius: 12px; background: var(--kilby-surface, rgba(22,22,22,0.55)); backdrop-filter: blur(8px); -webkit-backdrop-filter: blur(8px); color: var(--kilby-white); font-size: 13px; }
  .kilby-card-label { font-size: 10px; color: var(--kilby-secondary); text-transform: uppercase; letter-spacing: 0.06em; margin-bottom: 6px; }
  /* The company header — which company am I looking at — is a TITLE, not a
     label. It was using .kilby-card-label, the same 10px dim style as a row key
     like "Volume", so the most important line on the card was also the quietest.
     Android already renders it titleSmall / Bold / #E0E0E0; this matches that,
     so the two surfaces stop disagreeing. Separate class, so every other card's
     label is untouched. */
  .kilby-card-title { font-size: 14px; color: var(--kilby-white); font-weight: 700; text-transform: uppercase; letter-spacing: 0.02em; margin-bottom: 6px; line-height: 1.25; }
  .kilby-card-divider { border: none; border-top: 1px solid var(--kilby-border); margin: 8px 0; }
  .kilby-card-row { display: flex; justify-content: space-between; gap: 8px; padding: 3px 0; font-size: 12px; }
  .kilby-card-key { color: var(--kilby-secondary); }
  .kilby-card-val { color: var(--kilby-white); font-weight: 500; text-align: right; }
  .kilby-card-val.pos { color: var(--kilby-green); }
  .kilby-card-val.neg { color: var(--kilby-red); }
  .kilby-estimate-table { display: flex; flex-direction: column; gap: 4px; margin-top: 2px; }
  .kilby-estimate-header, .kilby-estimate-row { display: grid; grid-template-columns: minmax(0, 1.35fr) minmax(0, 1fr) minmax(0, 0.8fr); gap: 10px; font-size: 12px; align-items: baseline; }
  .kilby-estimate-header { color: var(--kilby-secondary); font-size: 11px; text-transform: uppercase; letter-spacing: 0.04em; }
  .kilby-estimate-header span:nth-child(2), .kilby-estimate-header span:nth-child(3) { text-align: right; }
  .kilby-estimate-period { color: var(--kilby-secondary); }
  .kilby-estimate-val { color: var(--kilby-white); font-weight: 500; text-align: right; font-variant-numeric: tabular-nums; }
  .stock-price { font-size: 22px; font-weight: 700; color: var(--kilby-white); letter-spacing: -0.02em; line-height: 1; }
  .stock-meta { font-size: 12px; color: var(--kilby-secondary); margin-top: 2px; }
  .fred-sparkline { font-family: monospace; font-size: 15px; letter-spacing: -0.04em; color: var(--kilby-link); margin: 6px 0 2px; overflow: hidden; white-space: nowrap; }
  .pulse-article { padding: 7px 0; }
  .pulse-article + .pulse-article { border-top: 1px solid var(--kilby-border); }
  .pulse-article-title { color: var(--kilby-white); font-weight: 500; font-size: 13px; line-height: 1.35; }
  .pulse-article-byline { color: var(--kilby-secondary); font-size: 11px; margin-top: 2px; }
  .pulse-article-summary { color: var(--kilby-secondary); font-size: 12px; margin-top: 3px; line-height: 1.4; }
  .pulse-article-link { color: var(--kilby-link); font-size: 11px; text-decoration: none; display: inline-block; margin-top: 3px; }
  .pulse-article-link:hover { text-decoration: underline; }
  .code-entry { padding: 7px 0; }
  .code-entry + .code-entry { border-top: 1px solid var(--kilby-border); }
  .code-entry-header { display: flex; align-items: baseline; gap: 8px; flex-wrap: wrap; }
  .code-tag { font-family: monospace; font-size: 12px; color: var(--kilby-link); font-weight: 700; background: rgba(147,197,253,0.08); border-radius: 4px; padding: 1px 5px; }
  .code-reason { color: var(--kilby-white); font-size: 12px; font-weight: 500; }
  .code-desc { color: var(--kilby-secondary); font-size: 11px; margin-top: 3px; line-height: 1.4; }
  .code-detail-row { display: flex; gap: 6px; font-size: 11px; margin-top: 3px; flex-wrap: wrap; }
  .code-detail-key { color: var(--kilby-secondary); }
  .code-detail-val { color: var(--kilby-secondary); }
  .kilby-card-source { font-size: 10px; color: var(--kilby-secondary); margin-top: 8px; }

  /* ── Comp table (/comp AAPL MSFT) ──────────────────────────────────────────
     A comp table exists to be read ACROSS. Stacking one company per block would
     be readable and useless — you could no longer compare. So the metric column
     is STICKY and the companies scroll underneath it, and the scroll lives
     INSIDE the card so the chat itself never moves sideways. */
  .comp-scroll { overflow-x: auto; margin: 0 -12px; padding: 0 12px; -webkit-overflow-scrolling: touch; }
  .comp { border-collapse: collapse; width: max-content; min-width: 100%; font-size: 12px; font-variant-numeric: tabular-nums; }
  /* ⚠️ THE CLASS IS DOUBLED ON PURPOSE — DO NOT "TIDY" IT TO ONE.
     `.msg.bot th` above is Kilby's markdown-table style and outranks a single
     `.comp th`. It was silently winning: it forced UPPERCASE, 11px #bbb, a 2px
     bottom rule and its own alignment onto every header in this card, so the
     tickers were capitalised, every row label carried a line under it and the
     header did not sit on the same rule as its own figures. Doubling the class
     outranks it without depending on the card
     sitting inside a .msg.bot wrapper. The resets below undo each property it
     sets, so nothing is left leaking through. */
  .comp.comp th, .comp.comp td {
    padding: 5px 0; white-space: nowrap;
    /* Left-justified. Ticker, company name and every figure beneath them share
       one left rule, so a column reads as a single block. */
    text-align: left;
    text-transform: none; letter-spacing: normal;
    border-bottom: none; font-size: 12px;
  }
  /* Column gutter. Selected by NOT being the metric column rather than by
     adjacency: `td + td` silently skips the FIRST company's value cells,
     because those follow the metric <th> and not another <td> — while
     `th + th` does match that company's header. The first column's heading
     then sits 18px inside its own figures. */
  .comp.comp th:not(.metric), .comp.comp td:not(.metric) { padding-left: 18px; }
  /* Opaque background, not the card's translucent one: the columns scroll
     underneath this and would otherwise show through it. */
  .comp.comp th.metric, .comp.comp td.metric { position: sticky; left: 0; z-index: 2; text-align: left; color: var(--kilby-secondary); font-weight: 400; padding-right: 14px; background: var(--kilby-panel); box-shadow: 1px 0 0 var(--kilby-panel); }
  .comp.comp thead th { padding-bottom: 10px; vertical-align: bottom; }
  /* Ticker and company name are deliberately CLOSE in size. On a comp table the
     company name is not decoration — it is how you tell four columns apart at a
     glance — so it reads as part of the same block, not a caption beneath it. */
  .comp.comp .tick { display: block; color: var(--kilby-white); font-weight: 700; font-size: 13px; letter-spacing: .01em; line-height: 1.15; }
  /* The name is capped and WRAPS rather than widening the column. Legal
     suffixes are already stripped server-side; this catches what is left, so a
     genuinely long name costs two lines of header instead of pushing the table
     off the side of the card. Values keep nowrap — they must never break. */
  .comp.comp .co { display: block; color: var(--kilby-secondary); font-size: 12px; font-weight: 500; margin-top: 3px; line-height: 1.2; max-width: 104px; white-space: normal; }
  .comp.comp thead th.metric { font-size: 11px; text-transform: uppercase; letter-spacing: 0.04em; color: var(--kilby-secondary); vertical-align: bottom; }
  .comp.comp td.v { color: var(--kilby-white); font-weight: 500; }
  /* An absent figure is a dimmed em dash. Never zero, never "N/A" — a company
     that is not earning has no meaningful P/E, and that is a fact about the
     company rather than a gap in the data. */
  .comp.comp td.v.dim { color: var(--kilby-secondary); font-weight: 400; }
  /* Fifteen rows in one block is a wall of numbers. Three groups, separated by
     a hairline and nothing else — the captions came off 16 Aug (his call): the
     row names already say what the group was labelling. */
  .comp.comp tr.group td, .comp.comp tr.group th { padding-top: 12px; border-top: 1px solid var(--kilby-border); }
  .comp-hint { font-size: 10px; color: var(--kilby-secondary); margin-top: 6px; }


  /* ── Financial statements (/NVDA inc · bal · cf) ────────────────────────────
     Modelled on TEK2day Finance's own income statement card — a title, a
     QUARTERLY section, an ANNUAL section, each a table headed "Metric" with
     period-end dates as columns, then a source line. His instruction, 21 Aug
     2026: use that card as the model and change the colours.

     Kilby's blue replaces TEK2day's section colour, as it did on the macro
     card, and negatives take Kilby's existing red rather than a new one. */
  .fin-card { padding: 16px; }

  .fin-head { margin-bottom: 12px; }
  .fin-h1 { color: var(--kilby-white); font-size: 16px; font-weight: 700; line-height: 1.2; }
  .fin-h2 { color: var(--kilby-faint); font-size: 11px; margin-top: 2px; }
  /* The scale, stated once and beside the statement it applies to — his call,
     22 Aug 2026. Dimmer than the statement name so it reads as a qualifier
     rather than part of the title. */
  .fin-unit { margin-left: 8px; color: var(--kilby-faint); letter-spacing: 0.02em; }

  .fin-section + .fin-section { margin-top: 16px; }
  .fin-section-title { color: var(--kilby-link); font-size: 11px; font-weight: 700; text-transform: uppercase; letter-spacing: 0.08em; margin-bottom: 6px; }
  .fin-section-empty { color: var(--kilby-secondary); font-size: 12px; padding: 4px 0 2px; }

  /* Eight period columns beside a metric name will outrun a phone. The scroll
     lives INSIDE the card so the chat itself never moves sideways — the same
     rule the comp and macro tables follow. */
  .fin-scroll { overflow-x: auto; -webkit-overflow-scrolling: touch; }
  .fin { border-collapse: collapse; width: 100%; font-size: 12px; font-variant-numeric: tabular-nums; }

  /* ⚠️ THE CLASS IS DOUBLED ON PURPOSE, same as .comp.comp and .macro.macro —
     `.msg.bot th` is Kilby's markdown-table style and outranks a single
     `.fin th`, forcing uppercase 11px #bbb and a border this card does not
     want. Do not "tidy" this to one class. */
  .fin.fin th, .fin.fin td {
    border: 0; background: none; text-transform: none; letter-spacing: normal;
    padding: 6px 0; text-align: right; vertical-align: top; white-space: nowrap;
  }
  .fin.fin th:not(.metric), .fin.fin td:not(.metric) { padding-left: 16px; }
  /* ⚠️ THE DATE IS THE COLUMN HEADING, so it is sized to be read rather than
     tucked away — his call, 22 Aug 2026. It is also the ONLY thing in the
     heading: the fiscal quarter label is deliberately absent, because TEK2day's
     storage key is not the issuer's fiscal label and printing "2026-Q2" would
     assert a quarter nobody told us. */
  .fin.fin thead th {
    font-size: 12px; letter-spacing: 0.01em; color: var(--kilby-white); font-weight: 700;
    padding-bottom: 8px; border-bottom: 1px solid rgba(var(--kilby-tint),0.09);
  }
  .fin.fin thead th.metric { text-align: left; }

  /* Line-item names wrap; figures never do. A long label must not push the
     table past the card and clip the right-hand periods. */
  .fin.fin th.metric, .fin.fin td.metric {
    text-align: left; font-weight: 500; color: var(--kilby-white); padding-right: 14px;
    white-space: normal; width: 34%;
  }
  .fin.fin tbody tr + tr th.metric, .fin.fin tbody tr + tr td { border-top: 1px solid rgba(var(--kilby-tint),0.05); }
  .fin.fin tbody td { color: var(--kilby-white); font-weight: 600; }

  /* A line the company did not report is a dimmed em dash — never zero. Not
     reporting a line is a fact about the company, not a gap in the data. */
  .fin.fin tbody td.dim { color: var(--kilby-secondary); font-weight: 400; }
  /* Kilby's existing red, so a loss here reads the same as a loss anywhere else
     in the product. */
  .fin.fin tbody td.neg { color: var(--kilby-red); }

  .fin-empty { font-size: 12px; color: var(--kilby-secondary); line-height: 1.5; }

  /* Amber, not red: the figures are true and useful, merely older than they
     should be. Red would say "wrong", which they are not. */
  .fin-stale { color: var(--kilby-amber); margin-bottom: 4px; }
  .fin-footer { font-size: 10px; color: var(--kilby-faint); margin-top: 12px; padding-top: 8px; border-top: 1px solid rgba(var(--kilby-tint),0.05); line-height: 1.5; }

  @media (max-width: 899px) {
    .fin { width: max-content; min-width: 100%; }
    /* The metric column holds its ground while the periods scroll under it. */
    .fin.fin th.metric, .fin.fin td.metric {
      position: sticky; left: 0; z-index: 2; background: var(--kilby-panel);
      box-shadow: 1px 0 0 rgba(255,255,255,0.05); width: auto; min-width: 148px;
    }
  }

  /* ── Macro dashboard (/macro) ──────────────────────────────────────────────
     His ruling, 21 Aug 2026: "You should make it look like TEK2day Finance
     macro dashboard, but change the colors." So the LAYOUT is deliberately
     TEK2day's — a header with as-of and contract metadata on the right, then
     six boxed panels two across, each with its own title, an INDICATOR column
     and a source line at its foot.

     ⚠️ WHAT CHANGES IS THE PALETTE. TEK2day's section titles are orange; Kilby's
     accent is blue (#2563eb, lightened to #60a5fa so it reads as a heading on a
     dark panel rather than disappearing into it). Type is Kilby's sans rather
     than TEK2day's monospace, with tabular figures so columns still line up. */
  .macro-card { padding: 16px; }

  .macro-head { display: flex; align-items: flex-start; justify-content: space-between; gap: 16px; margin-bottom: 14px; }
  .macro-h1 { color: var(--kilby-white); font-size: 16px; font-weight: 700; line-height: 1.2; }
  .macro-meta { text-align: right; color: var(--kilby-faint); font-size: 10px; letter-spacing: 0.04em; line-height: 1.6; white-space: nowrap; }

  /* Two panels across on desktop — source order produces TEK2day's own pairing
     (Market|Rates, Money|Inflation, Growth|Labor) without hard-coding which
     panel goes where, so a section added upstream lands correctly on its own.
     Stacked below 900px, which is the format he asked for on mobile. */
  .macro-grid { display: grid; grid-template-columns: 1fr; gap: 14px; }
  @media (min-width: 900px) {
    .macro-grid { grid-template-columns: 1fr 1fr; }
  }

  .macro-panel {
    min-width: 0; padding: 12px 14px 10px;
    border: 1px solid rgba(var(--kilby-tint),0.07); border-radius: 10px;
    background: rgba(var(--kilby-tint),0.02);
  }
  /* The one place the palette swap is visible: TEK2day's orange becomes Kilby's
     blue. Everything else about the panel is TEK2day's arrangement. */
  .macro-panel-title { color: var(--kilby-link); font-size: 11px; font-weight: 700; text-transform: uppercase; letter-spacing: 0.08em; margin-bottom: 8px; }

  .macro-scroll { overflow-x: auto; -webkit-overflow-scrolling: touch; }
  .macro { border-collapse: collapse; width: 100%; font-size: 12px; font-variant-numeric: tabular-nums; }

  /* ⚠️ THE CLASS IS DOUBLED ON PURPOSE, same as .comp.comp — `.msg.bot th` is
     Kilby's markdown-table style and outranks a single `.macro th`, forcing
     uppercase 11px #bbb and a border this card does not want. Do not "tidy"
     this to one class. */
  .macro.macro th, .macro.macro td {
    border: 0; background: none; text-transform: none; letter-spacing: normal;
    padding: 6px 0; text-align: right; vertical-align: top; white-space: nowrap;
  }
  .macro.macro th:not(.metric), .macro.macro td:not(.metric) { padding-left: 12px; }
  .macro.macro thead th {
    font-size: 9px; text-transform: uppercase; letter-spacing: 0.06em;
    color: var(--kilby-faint); font-weight: 600; padding-bottom: 8px;
    border-bottom: 1px solid rgba(var(--kilby-tint),0.07);
  }
  .macro.macro thead th.metric { text-align: left; }

  /* Long names — "Nonfarm Payrolls – Reported Monthly Change" — wrap rather than
     forcing the table past its panel and clipping the values on the right. Only
     labels wrap; figures stay on one line. */
  .macro.macro th.metric, .macro.macro td.metric {
    text-align: left; font-weight: 400; padding-right: 12px;
    white-space: normal; width: 44%;
  }
  .macro.macro tbody tr + tr th.metric, .macro.macro tbody tr + tr td { border-top: 1px solid rgba(var(--kilby-tint),0.05); }

  .macro-label { display: block; color: var(--kilby-white); font-weight: 600; font-size: 12px; line-height: 1.25; }
  /* The series behind the row — FEDFUNDS, ^GSPC, BC_10YEAR. TEK2day shows it the
     same way: it is how a reader checks WHICH series they are looking at. */
  .macro-code { display: block; color: var(--kilby-faint); font-size: 9.5px; margin-top: 2px; letter-spacing: .02em; }

  .macro-value { display: block; color: var(--kilby-white); font-weight: 700; font-size: 13px; line-height: 1.2; }
  /* An absent figure is a dimmed em dash — never zero, never the string "N/A".
     The dash is written by the renderer; this only dims it. */
  .macro-value.dim { color: var(--kilby-secondary); font-weight: 400; }
  .macro-date { display: block; color: var(--kilby-faint); font-size: 9.5px; margin-top: 2px; min-height: 11px; }

  .macro-panel-source { color: var(--kilby-faint); font-size: 9.5px; text-align: right; margin-top: 8px; padding-top: 6px; border-top: 1px solid rgba(var(--kilby-tint),0.05); }

  .macro-empty { font-size: 12px; color: var(--kilby-secondary); line-height: 1.5; }

  /* A stale dashboard must announce itself. Amber rather than red: the data is
     true and useful, it is simply older than it should be — red would say
     "wrong", which it is not. */
  .macro-stale { color: var(--kilby-amber); margin-bottom: 4px; }
  .macro-footer { font-size: 10px; color: var(--kilby-faint); margin-top: 12px; line-height: 1.5; }

  /* Below 900px the panels stack and a table can outgrow the screen, so the
     indicator column holds its ground and the values scroll under it. Here the
     solid background is doing real work rather than drawing a band for no
     reason — a band on desktop was the first thing he called out. */
  @media (max-width: 899px) {
    .macro { width: max-content; min-width: 100%; }
    .macro.macro th.metric, .macro.macro td.metric {
      position: sticky; left: 0; z-index: 2; background: var(--kilby-panel);
      box-shadow: 1px 0 0 rgba(255,255,255,0.05);
    }
    .macro-head { flex-direction: column; gap: 8px; }
    .macro-meta { text-align: left; }
  }
