/* Stocks index — Audit Ledger theme.
   Flat hairline cards, mono figures, ledger rank tags.
   No gradients, no gloss, no entrance animations. */

.stocks-page {
  background: var(--bg-main);
  min-height: 100vh;
}

/* ============ Hero ============ */
.stocks-hero {
  background: var(--bg-main);
  border-top: 1px solid var(--border);
  padding: 4.5rem 0 3.5rem;
  position: relative;
}

.stocks-hero::before {
  content: '';
  position: absolute;
  top: 3px;
  left: 0;
  right: 0;
  height: 1px;
  background: var(--border);
}

.stocks-hero .hero-title {
  margin: 0 0 1rem;
  font-size: clamp(2.2rem, 4vw, 3.5rem);
}

.stocks-hero .lead {
  margin: 0;
  color: var(--text);
  font-size: 1.05rem;
  line-height: 1.65;
  max-width: 58ch;
}

/* ============ Section headers (trending + top list) ============ */
.trending-header {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 1rem;
  margin-bottom: 1.75rem;
}

.trending-header h2 {
  margin: 0 0 0.35rem;
  font-family: var(--font-display);
  font-size: 1.9rem;
  font-weight: 600;
  letter-spacing: 0.01em;
  color: var(--text-bright);
}

.trending-header .lead {
  margin: 0;
  color: var(--text-muted);
  font-size: 1rem;
}

.trending-header .sentiment-period-badge {
  margin-top: 0.5rem;
  white-space: nowrap;
}

/* ============ Trending (last 14 days) ============ */
.stocks-trending {
  padding: 3.5rem 0 0;
}

.trending-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
  gap: 1rem;
}

.trending-card {
  display: grid;
  grid-template-columns: auto 1fr;
  align-items: center;
  gap: 0.85rem 1rem;
  min-width: 0;
  background: var(--bg-elevated);
  border: 1px solid var(--border);
  border-left: 3px solid var(--primary);
  border-radius: 3px;
  padding: 1.1rem 1.25rem;
  text-decoration: none;
  transition: border-color 0.2s ease;
}

.trending-card:hover {
  border-color: var(--text-muted);
  border-left-color: var(--primary);
}

.trending-rank {
  font-family: var(--font-mono);
  font-size: 0.8rem;
  font-weight: 600;
  letter-spacing: 0.08em;
  color: var(--text-muted);
  background: var(--bg-surface);
  border: 1px solid var(--border);
  border-radius: 2px;
  padding: 0.3rem 0.5rem;
  flex-shrink: 0;
}

.trending-card:first-child .trending-rank {
  color: var(--secondary);
  border-color: var(--secondary);
}

.trending-info {
  display: flex;
  flex-direction: column;
  gap: 0.15rem;
  min-width: 0;
  flex: 1;
}

.trending-ticker {
  font-family: var(--font-mono);
  font-size: 1.1rem;
  font-weight: 600;
  letter-spacing: 0.02em;
  color: var(--text-bright);
}

.trending-name {
  color: var(--text-muted);
  font-size: 0.8rem;
  line-height: 1.4;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.trending-meta {
  grid-column: 1 / -1;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.75rem;
  border-top: 1px solid var(--border-light);
  padding-top: 0.85rem;
}

.trending-count {
  font-family: var(--font-mono);
  font-variant-numeric: tabular-nums;
  font-size: 0.72rem;
  font-weight: 600;
  color: var(--success);
  background: rgba(93, 169, 122, 0.12);
  border: 1px solid rgba(93, 169, 122, 0.35);
  border-radius: 2px;
  padding: 0.25rem 0.55rem;
}

.trending-price {
  font-family: var(--font-mono);
  font-variant-numeric: tabular-nums;
  font-size: 0.85rem;
  font-weight: 600;
  color: var(--text-bright);
}

/* ============ Top stocks grid ============ */
.stocks-list {
  padding: 3.5rem 0 1.5rem;
}

.stock-cards {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
  gap: 1.5rem;
}

.stock-card {
  display: flex;
  flex-direction: column;
  min-width: 0;
  background: var(--bg-elevated);
  border: 1px solid var(--border);
  border-radius: 3px;
  padding: 1.75rem 1.5rem 1.5rem;
  transition: border-color 0.2s ease;
}

.stock-card:hover {
  border-color: var(--text-muted);
}

.stock-card-head {
  display: flex;
  align-items: center;
  gap: 1rem;
  margin-bottom: 1.25rem;
  padding-bottom: 1.1rem;
  border-bottom: 1px solid var(--border-light);
}

/* Ledger entry number — gold for the top entry, no medals */
.stock-rank {
  font-family: var(--font-mono);
  font-size: 0.85rem;
  font-weight: 600;
  letter-spacing: 0.08em;
  color: var(--text-muted);
  background: var(--bg-surface);
  border: 1px solid var(--border);
  border-radius: 2px;
  padding: 0.3rem 0.55rem;
  flex-shrink: 0;
}

.stock-rank::before {
  content: '№ ';
  color: var(--text-dim);
}

.stock-rank.is-top {
  color: var(--secondary);
  border-color: var(--secondary);
}

.stock-info {
  min-width: 0;
}

.stock-info h3 {
  margin: 0 0 0.2rem;
  font-family: var(--font-mono);
  font-size: 1.25rem;
  font-weight: 600;
  letter-spacing: 0.02em;
  color: var(--text-bright);
}

.stock-info .sub {
  margin: 0;
  color: var(--text-muted);
  font-size: 0.875rem;
  line-height: 1.4;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.stock-metrics {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 0.5rem;
  margin: 0 0 1.5rem;
}

.stock-metrics > div {
  display: flex;
  flex-direction: column;
  padding: 0.85rem 0.5rem;
  text-align: center;
  background: var(--bg-surface);
  border: 1px solid var(--border);
  border-radius: 2px;
}

.stock-metrics dt {
  font-family: var(--font-mono);
  font-size: 0.62rem;
  font-weight: 600;
  color: var(--text-muted);
  text-transform: uppercase;
  letter-spacing: 0.08em;
  margin-bottom: 0.45rem;
}

.stock-metrics dd {
  margin: auto 0 0;
  font-family: var(--font-mono);
  font-variant-numeric: tabular-nums;
  font-size: 1.05rem;
  font-weight: 600;
  color: var(--text-bright);
  line-height: 1.2;
}

.stock-metrics dd.profit-positive {
  color: var(--success);
}

.stock-metrics dd.profit-negative {
  color: var(--danger);
}

.trending-header .stocks-sort-form {
  margin-top: 0.5rem;
  flex-shrink: 0;
}

.stock-card-actions {
  margin-top: auto;
  display: flex;
}

.stock-card-actions .btn {
  flex: 1;
}

/* ============ Empty state (shared with asset show tabs) ============ */
.empty-state {
  text-align: center;
  padding: 4rem 2rem;
  background: var(--bg-surface);
  border: 1px solid var(--border);
  border-radius: 3px;
}

.empty-message {
  font-size: 1.25rem;
  font-weight: 600;
  color: var(--text-bright);
  margin-bottom: 0.5rem;
}

.empty-hint {
  color: var(--text-muted);
  margin: 0;
}

@media (max-width: 768px) {
  .stocks-hero {
    padding: 3.25rem 0 2.5rem;
  }

  .stocks-list {
    padding: 2.5rem 0 1rem;
  }

  .stocks-trending {
    padding: 2.5rem 0 0;
  }

  .trending-header {
    flex-direction: column;
    align-items: flex-start;
    margin-bottom: 1.25rem;
  }

  .trending-header h2 {
    font-size: 1.5rem;
  }

  .trending-header .sentiment-period-badge {
    margin-top: 0;
  }

  .trending-grid {
    grid-template-columns: 1fr;
  }

  .stock-cards {
    grid-template-columns: 1fr;
    gap: 1rem;
  }
}

@media (max-width: 480px) {
  .stock-card {
    padding: 1.5rem 1.25rem 1.25rem;
  }

  .stock-metrics {
    grid-template-columns: 1fr;
    gap: 0.4rem;
  }

  .stock-metrics > div {
    flex-direction: row;
    align-items: baseline;
    justify-content: space-between;
    gap: 1rem;
    text-align: left;
    padding: 0.7rem 0.9rem;
  }

  .stock-metrics dt {
    margin-bottom: 0;
  }

  .stock-metrics dd {
    margin: 0;
  }
}

/* ============ Stock search — flat ledger lookup ============ */
.stock-search-section {
  margin-top: 2rem;
  padding: 3.5rem 0 4.5rem;
  border-top: 1px solid var(--border);
}

.stock-search-section h2 {
  margin: 0 0 0.5rem;
  font-family: var(--font-display);
  font-size: 1.9rem;
  font-weight: 600;
  letter-spacing: 0.01em;
  color: var(--text-bright);
}

.stock-search-section .lead {
  margin: 0 0 1.75rem;
  color: var(--text-muted);
  font-size: 1rem;
}

.stock-search-container {
  position: relative;
  max-width: 600px;
}

.stock-search-input {
  width: 100%;
  padding: 0.9rem 1.1rem;
  font-family: var(--font-mono);
  font-size: 0.95rem;
  border: 1px solid var(--border);
  border-radius: 2px;
  background: var(--bg-surface);
  color: var(--text-bright);
  outline: none;
  transition: border-color 0.15s ease, box-shadow 0.15s ease;
}

.stock-search-input:focus {
  border-color: var(--primary);
  box-shadow: 0 0 0 2px var(--ring);
}

.stock-search-input::placeholder {
  color: var(--text-dim);
}

/* Autocomplete results */
.autocomplete-results {
  position: absolute;
  top: calc(100% + 4px);
  left: 0;
  right: 0;
  background: var(--bg-elevated);
  border: 1px solid var(--border);
  border-radius: 2px;
  box-shadow: 0 16px 32px rgba(0, 0, 0, 0.4);
  max-height: 400px;
  overflow-y: auto;
  opacity: 0;
  visibility: hidden;
  transition: opacity 0.15s ease, visibility 0.15s ease;
  z-index: 100;
}

.autocomplete-results.show {
  opacity: 1;
  visibility: visible;
}

.autocomplete-item {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 1rem;
  padding: 0.85rem 1.1rem;
  cursor: pointer;
  border-bottom: 1px solid var(--border-light);
  transition: background 0.15s ease;
}

.autocomplete-item:last-child {
  border-bottom: none;
}

.autocomplete-item:hover,
.autocomplete-item.selected {
  background: var(--bg-highlight);
  box-shadow: inset 2px 0 0 var(--primary);
}

.autocomplete-ticker {
  font-family: var(--font-mono);
  font-size: 0.95rem;
  font-weight: 600;
  color: var(--text-bright);
  min-width: 80px;
}

.autocomplete-details {
  display: flex;
  align-items: center;
  justify-content: flex-end;
  gap: 0.75rem;
  flex: 1;
  min-width: 0;
}

.autocomplete-name {
  font-size: 0.85rem;
  color: var(--text-muted);
  text-align: right;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.autocomplete-exchange {
  font-family: var(--font-mono);
  font-size: 0.68rem;
  font-weight: 600;
  color: var(--text-muted);
  background: var(--bg-surface);
  border: 1px solid var(--border);
  border-radius: 2px;
  padding: 0.2rem 0.5rem;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  flex-shrink: 0;
}

/* Scrollbar styling */
.autocomplete-results::-webkit-scrollbar {
  width: 8px;
}

.autocomplete-results::-webkit-scrollbar-track {
  background: var(--bg-surface);
}

.autocomplete-results::-webkit-scrollbar-thumb {
  background: var(--border);
}

.autocomplete-results::-webkit-scrollbar-thumb:hover {
  background: var(--text-muted);
}

@media (max-width: 768px) {
  .stock-search-section {
    margin-top: 1.5rem;
    padding: 2.5rem 0 3.5rem;
  }

  .stock-search-section h2 {
    font-size: 1.5rem;
  }

  .autocomplete-item {
    flex-direction: column;
    align-items: flex-start;
    gap: 0.4rem;
  }

  .autocomplete-details {
    justify-content: flex-start;
  }

  .autocomplete-name {
    text-align: left;
  }
}

/* ===========================================================================
   Asset page (/stocks/:symbol) — the destination surface.

   An asset's record read as instrumentation: what the market says it costs,
   what calling it has actually returned, and which channels that number is
   made of. The callers are the spine — each row is one channel's whole record
   on this ticker, and opening it drops to the receipts behind the average.
   Construction follows the board on /top-influencer and the tape on the
   influencer profile: flat surfaces, hairlines instead of gaps, mono figures
   carrying every comparable number.
   =========================================================================== */

/* ============ Masthead ============ */
.asset-masthead {
  padding: 3rem 0 1.75rem;
}

.asset-identity {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  align-items: end;
  gap: 1.25rem 2rem;
  margin-bottom: 1.75rem;
}

.asset-identity-text {
  min-width: 0;
}

/* The ticker is the page's identity and its most comparable token at once, so
   it is set in the figure face rather than the display face — a reader
   scanning from a tape row to this heading matches the same letterforms. */
.asset-ticker {
  margin: 0 0 0.5rem;
  font-family: var(--font-mono);
  font-size: clamp(2.4rem, 5.5vw, 3.75rem);
  font-weight: 600;
  line-height: 1;
  letter-spacing: 0.01em;
  color: var(--text-bright);
  overflow-wrap: anywhere;
}

.asset-subtitle {
  display: flex;
  align-items: baseline;
  flex-wrap: wrap;
  gap: 0.6rem;
  margin: 0;
  min-width: 0;
}

.asset-name {
  font-size: 1rem;
  color: var(--text);
  overflow-wrap: anywhere;
}

.asset-exchange {
  padding: 0.15rem 0.4rem;
  border: 1px solid var(--border);
  border-radius: 2px;
  font-family: var(--font-mono);
  font-size: 0.62rem;
  font-weight: 500;
  text-transform: uppercase;
  letter-spacing: 0.11em;
  color: var(--text-muted);
  white-space: nowrap;
}

/* The market's own number, held apart from the record: this is what the asset
   costs, not what the calls on it returned. */
.asset-quote {
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: 0.3rem;
  text-align: right;
}

.asset-quote-label,
.asset-quote-stamp {
  font-family: var(--font-mono);
  font-size: 0.66rem;
  font-weight: 500;
  text-transform: uppercase;
  letter-spacing: 0.13em;
  color: var(--text-muted);
}

.asset-quote-figure {
  font-family: var(--font-mono);
  font-variant-numeric: tabular-nums;
  font-size: 1.6rem;
  font-weight: 600;
  line-height: 1.1;
  color: var(--text-bright);
  white-space: nowrap;
}

.asset-quote-currency {
  color: var(--text-muted);
  margin-right: 0.1em;
}

/* ============ Scoreboard strip ============ */
.asset-board {
  display: grid;
  grid-template-columns: 1.4fr repeat(4, 1fr);
  margin: 0;
  border-top: 1px solid var(--border);
  border-bottom: 1px solid var(--border);
}

.asset-cell {
  padding: 1.1rem 1.25rem;
  border-left: 1px solid var(--border);
  min-width: 0;
}
.asset-cell:first-child {
  padding-left: 0;
  border-left: 0;
}

.asset-cell dt {
  font-family: var(--font-mono);
  font-size: 0.66rem;
  font-weight: 500;
  text-transform: uppercase;
  letter-spacing: 0.13em;
  color: var(--text-muted);
}

.asset-cell dd {
  margin: 0.5rem 0 0;
  font-family: var(--font-mono);
  font-variant-numeric: tabular-nums;
  font-size: 1.35rem;
  font-weight: 600;
  color: var(--text-bright);
  white-space: nowrap;
}

/* The average return across every scored call is the figure this page exists
   to report; every other cell is the evidence standing behind it. */
.asset-cell dd.asset-figure {
  font-size: clamp(2rem, 3.2vw, 2.6rem);
  line-height: 1.1;
  /* pt and fr write the decimal as a comma, and a monospace comma sits in a
     full advance — at display size the separator reads as its own token. */
  letter-spacing: -0.03em;
}
.asset-figure.positive { color: var(--success); }
.asset-figure.negative { color: var(--danger); }

/* A measurement, not a progress decoration: 3px, square, and capped short
   enough that it never reads as a page-wide bar. */
.asset-ratio {
  display: block;
  width: 100%;
  max-width: 160px;
  height: 3px;
  margin-top: 0.55rem;
  background: var(--danger-dark);
  overflow: hidden;
}
.asset-ratio-fill {
  display: block;
  height: 100%;
  background: var(--success);
  transform-origin: left center;
  animation: asset-ratio-draw 0.55s cubic-bezier(0.16, 1, 0.3, 1) both;
}
/* Buy against sell is a direction the callers chose, not a result the market
   delivered, so this pair stays out of the gain/loss vocabulary entirely. */
.asset-ratio--neutral { background: var(--bg-highlight); }
.asset-ratio--neutral .asset-ratio-fill { background: var(--info); }

@keyframes asset-ratio-draw {
  from { transform: scaleX(0); }
  to   { transform: scaleX(1); }
}

.asset-stance {
  display: flex;
  align-items: baseline;
  flex-wrap: wrap;
  gap: 0 0.9rem;
}
.asset-stance-part {
  display: inline-flex;
  align-items: baseline;
  gap: 0.3rem;
}
.asset-stance-tag {
  font-size: 0.6rem;
  font-weight: 500;
  text-transform: uppercase;
  letter-spacing: 0.11em;
  color: var(--text-muted);
}

/* The measurement basis, stated once, in the figure face that carries it. */
.asset-basis {
  margin: 1.1rem 0 0;
  font-family: var(--font-mono);
  font-variant-numeric: tabular-nums;
  font-size: 0.72rem;
  font-weight: 500;
  text-transform: uppercase;
  letter-spacing: 0.1em;
  color: var(--text-muted);
}
.asset-basis--empty {
  text-transform: none;
  letter-spacing: 0.02em;
  font-size: 0.85rem;
}

/* ============ The callers ============ */
.voices-section {
  background: var(--bg-main);
  border-top: 1px solid var(--border);
  padding: 2.75rem 0 0;
}

.voices {
  /* The last track holds the disclosure label at its longest translation
     ("Voir les recos") without crowding the return beside it. */
  --voices-cols: 3.25rem minmax(7rem, 1.35fr) 6.5rem minmax(4rem, 1fr) 4.5rem 6.5rem 8rem;
  border: 1px solid var(--border);
  background: var(--bg-elevated);
}

.voices-head,
.voice-row {
  display: grid;
  grid-template-columns: var(--voices-cols);
  align-items: center;
  gap: 0 1rem;
  padding: 0.8rem 1.1rem;
}

.voices-head {
  border-bottom: 1px solid var(--border);
  background: var(--bg-darker);
  font-family: var(--font-mono);
  font-size: 0.68rem;
  font-weight: 500;
  text-transform: uppercase;
  letter-spacing: 0.1em;
  color: var(--text);
}
.voices-col--right { text-align: right; }

.voices-rows {
  margin: 0;
  padding: 0;
  list-style: none;
}
.voices-entry { display: block; }
.voices-entry + .voices-entry { border-top: 1px solid var(--border-light); }

/* The row is the disclosure control, so the whole width is the hit area and
   the native marker gives way to the caret in the last cell. */
.voice-row {
  cursor: pointer;
  list-style: none;
  transition: background 0.15s ease;
}
.voice-row::-webkit-details-marker { display: none; }
.voice-row::marker { content: ""; }
.voice-row:hover { background: var(--bg-highlight); }
.voice-row:focus-visible {
  outline: none;
  background: var(--bg-highlight);
  box-shadow: inset 0 0 0 2px var(--primary);
}

.voice-rank {
  font-family: var(--font-mono);
  font-variant-numeric: tabular-nums;
  font-size: 0.82rem;
  font-weight: 600;
  letter-spacing: 0.08em;
  color: var(--text-muted);
}
/* Signal amber is the system's top-rank marker — it distinguishes without
   claiming direction. */
.voice-row--leader .voice-rank { color: var(--secondary); }

.voice-channel {
  display: flex;
  align-items: center;
  gap: 0.7rem;
  min-width: 0;
}
.voice-avatar {
  flex-shrink: 0;
  width: 28px;
  height: 28px;
  border-radius: 50%;
  overflow: hidden;
  background: var(--bg-highlight);
  border: 1px solid var(--border);
}
.voice-avatar img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
}
.voice-name {
  min-width: 0;
  font-size: 0.95rem;
  font-weight: 600;
  color: var(--text-bright);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.voice-stance {
  display: flex;
  flex-wrap: nowrap;
  gap: 0.3rem;
}
.voice-stance-tag {
  padding: 0.15rem 0.4rem;
  border: 1px solid var(--border);
  border-radius: 2px;
  font-family: var(--font-mono);
  font-size: 0.62rem;
  font-weight: 500;
  text-transform: uppercase;
  letter-spacing: 0.1em;
  color: var(--text);
  white-space: nowrap;
}
.voice-stance-tag--sell { border-style: dashed; }

/* Anchored at zero, not at the left edge: a tape of callers on one asset runs
   both ways, and a magnitude-only bar would give the best caller on a losing
   asset the shortest mark. Each half of the track is the full scale, read
   against the largest move on this tape. */
.voice-bar {
  position: relative;
  display: block;
  width: 100%;
  height: 3px;
  background: var(--bg-highlight);
}
.voice-bar::before {
  content: "";
  position: absolute;
  left: 50%;
  top: -3px;
  bottom: -3px;
  width: 1px;
  background: var(--text-dim);
}
.voice-bar-fill {
  position: absolute;
  top: 0;
  height: 100%;
  animation: asset-ratio-draw 0.55s cubic-bezier(0.16, 1, 0.3, 1) both;
}
.voice-bar-fill.positive {
  left: 50%;
  transform-origin: left center;
  background: var(--success);
}
.voice-bar-fill.negative {
  right: 50%;
  transform-origin: right center;
  background: var(--danger);
}

.voice-count {
  font-family: var(--font-mono);
  font-variant-numeric: tabular-nums;
  font-size: 0.82rem;
  color: var(--text);
  text-align: right;
  white-space: nowrap;
}

.voice-move {
  font-family: var(--font-mono);
  font-variant-numeric: tabular-nums;
  font-size: 1.05rem;
  font-weight: 600;
  text-align: right;
  white-space: nowrap;
}
.voice-move.positive { color: var(--success); }
.voice-move.negative { color: var(--danger); }

.voice-cell-label { display: none; }

.voice-toggle {
  display: inline-flex;
  align-items: center;
  justify-content: flex-end;
  gap: 0.4rem;
  font-family: var(--font-mono);
  font-size: 0.62rem;
  font-weight: 500;
  text-transform: uppercase;
  letter-spacing: 0.1em;
  color: var(--text-muted);
  white-space: nowrap;
}
.voice-row:hover .voice-toggle { color: var(--text-bright); }
.voice-caret {
  flex-shrink: 0;
  transition: transform 0.2s cubic-bezier(0.16, 1, 0.3, 1);
}
.voice[open] .voice-caret { transform: rotate(180deg); }

/* Opened, the row drops onto the backplate — darker reads as further back,
   which is where the supporting evidence belongs. */
/* The right inset clears the toggle column so a call's return lands in the
   same column as the row average it explains. */
.voice-panel {
  padding: 0.35rem 10.1rem 1.1rem 1.1rem;
  background: var(--bg-darker);
  border-top: 1px solid var(--border-light);
}
.voice[open] > .voice-panel {
  animation: voice-reveal 0.32s cubic-bezier(0.16, 1, 0.3, 1) both;
}

@keyframes voice-reveal {
  from { opacity: 0; transform: translateY(-5px); }
  to   { opacity: 1; transform: none; }
}

.voice-calls {
  margin: 0;
  padding: 0;
  list-style: none;
}
.voice-call {
  padding: 0.55rem 0 0.6rem;
  border-bottom: 1px solid var(--border-light);
}
.voice-call:last-child { border-bottom: 0; }

.voice-call-row {
  display: grid;
  grid-template-columns: 6.5rem 4.5rem minmax(0, 1fr) 6rem;
  align-items: center;
  gap: 0 1rem;
  padding: 0.35rem 0.55rem;
  margin: 0 -0.55rem;
  color: inherit;
  text-decoration: none;
  transition: background 0.15s ease;
}
.voice-call-row:hover { background: var(--bg-highlight); }
.voice-call-row:focus-visible {
  outline: none;
  background: var(--bg-highlight);
  box-shadow: inset 0 0 0 2px var(--primary);
}

.voice-call-date {
  font-family: var(--font-mono);
  font-variant-numeric: tabular-nums;
  font-size: 0.72rem;
  color: var(--text-muted);
  white-space: nowrap;
}

/* Entry beside current, in that order — the return in the last column is the
   difference between them, and the receipt is right there. */
.voice-call-prices {
  display: flex;
  align-items: baseline;
  gap: 0.5rem;
  min-width: 0;
  font-family: var(--font-mono);
  font-variant-numeric: tabular-nums;
  font-size: 0.8rem;
  color: var(--text);
  white-space: nowrap;
  overflow: hidden;
}
.voice-call-arrow { color: var(--text-dim); }
/* Entry and current are the receipt behind the return, so each says which
   one it is rather than relying on reading order. */
.voice-call-prices .voice-cell-label {
  display: inline;
  margin-right: 0.35rem;
  font-size: 0.62rem;
  text-transform: uppercase;
  letter-spacing: 0.1em;
  color: var(--text-muted);
}

.voice-call-move {
  font-family: var(--font-mono);
  font-variant-numeric: tabular-nums;
  font-size: 0.9rem;
  font-weight: 600;
  text-align: right;
  white-space: nowrap;
}
.voice-call-move.positive { color: var(--success); }
.voice-call-move.negative { color: var(--danger); }

/* The words the call was actually made in. Prose, so the body face carries it
   and the measure stays short. */
.voice-call-quote {
  margin: 0.5rem 0 0;
  padding-left: 0.85rem;
  border-left: 1px solid var(--border);
  max-width: 62ch;
  font-size: 0.88rem;
  line-height: 1.55;
  color: var(--text);
}
.voice-call-quote::before { content: "\201C"; }
.voice-call-quote::after  { content: "\201D"; }

.voice-channel-link {
  display: inline-block;
  margin-top: 0.9rem;
  font-family: var(--font-mono);
  font-size: 0.66rem;
  font-weight: 500;
  text-transform: uppercase;
  letter-spacing: 0.11em;
  color: var(--primary);
  text-decoration: none;
  border-bottom: 1px solid transparent;
  transition: color 0.15s ease, border-color 0.15s ease;
}
.voice-channel-link:hover {
  color: var(--text-bright);
  border-bottom-color: var(--primary);
}
.voice-channel-link:focus-visible {
  outline: none;
  border-radius: 2px;
  box-shadow: 0 0 0 3px var(--ring);
}

/* ============ Community chat ============ */
.chat-section {
  background: var(--bg-main);
  border-top: 1px solid var(--border);
  padding: 3rem 0 4rem;
  margin-top: 3rem;
}

.chat-live-badge {
  padding: 0.35rem 0.65rem;
  border: 1px solid var(--border);
  border-radius: 2px;
  font-family: var(--font-mono);
  font-size: 0.62rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.12em;
  color: var(--text-muted);
  white-space: nowrap;
}

.chat-messages {
  max-height: 480px;
  overflow-y: auto;
  border: 1px solid var(--border);
  background: var(--bg-elevated);
}

.chat-empty {
  padding: 2.5rem 1.25rem;
  text-align: center;
  color: var(--text-muted);
  font-size: 0.9rem;
}
.chat-empty p { margin: 0; }
/* The prompt is only true while the thread is empty. */
.chat-messages:has(.chat-message) .chat-empty { display: none; }

.chat-message {
  display: flex;
  gap: 0.8rem;
  padding: 0.9rem 1.1rem;
}
.chat-message + .chat-message { border-top: 1px solid var(--border-light); }

.chat-message-avatar {
  flex-shrink: 0;
  display: grid;
  place-items: center;
  width: 32px;
  height: 32px;
  border-radius: 50%;
  overflow: hidden;
  background: var(--bg-highlight);
  border: 1px solid var(--border);
  font-family: var(--font-mono);
  font-size: 0.8rem;
  font-weight: 600;
  color: var(--text-muted);
}
.chat-message-avatar img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.chat-message-content { min-width: 0; }

.chat-message-meta {
  display: flex;
  align-items: baseline;
  gap: 0.6rem;
  margin-bottom: 0.25rem;
}
.chat-message-author {
  font-size: 0.85rem;
  font-weight: 600;
  color: var(--text-bright);
}
.chat-message-time {
  font-family: var(--font-mono);
  font-variant-numeric: tabular-nums;
  font-size: 0.66rem;
  letter-spacing: 0.06em;
  color: var(--text-dim);
  white-space: nowrap;
}
.chat-message-body {
  margin: 0;
  font-size: 0.92rem;
  line-height: 1.55;
  color: var(--text);
  overflow-wrap: anywhere;
}

.chat-form { margin-top: 1rem; }
.chat-form-row {
  display: flex;
  align-items: stretch;
  gap: 0.6rem;
}
.chat-form textarea {
  flex: 1;
  min-height: 46px;
  padding: 0.75rem 0.9rem;
  border: 1px solid var(--border);
  border-radius: 2px;
  background: var(--bg-surface);
  color: var(--text);
  font-family: inherit;
  font-size: 0.95rem;
  line-height: 1.5;
  resize: vertical;
}
.chat-form textarea:focus {
  outline: none;
  border-color: var(--primary);
  box-shadow: 0 0 0 3px var(--ring);
}
.chat-form textarea::placeholder { color: var(--text-muted); }

.chat-form-error {
  margin: 0 0 0.6rem;
  font-size: 0.85rem;
  color: var(--danger);
}

.chat-send-btn { flex-shrink: 0; }

.chat-sign-in { margin-top: 1rem; }

@media (prefers-reduced-motion: reduce) {
  .asset-ratio-fill,
  .voice-bar-fill,
  .voice[open] > .voice-panel { animation: none; }
  .voice-caret { transition: none; }
}

/* ============ Responsive ============ */
@media (max-width: 1024px) {
  .voices {
    --voices-cols: 2.75rem minmax(6rem, 1.3fr) 6rem minmax(3rem, 1fr) 3.75rem 5.75rem 1.5rem;
  }
  .voice-toggle-text { display: none; }
  .voice-panel { padding-right: 4.6rem; }
}

@media (max-width: 900px) {
  .asset-board {
    grid-template-columns: 1fr 1fr;
  }
  /* The lead figure keeps its own row so the return never shares a baseline
     with a count it dwarfs. */
  .asset-cell--lead {
    grid-column: 1 / -1;
    border-bottom: 1px solid var(--border);
  }
  .asset-cell:nth-child(2),
  .asset-cell:nth-child(4) {
    padding-left: 0;
    border-left: 0;
  }
  .asset-cell:nth-child(4),
  .asset-cell:nth-child(5) {
    border-top: 1px solid var(--border);
  }
}

/* One caller reflows to three lines: who and how much on the first, the bar
   spanning beneath, then the direction, the call count, and the disclosure.
   Column headers give way to inline labels so no bare count loses its name. */
@media (max-width: 768px) {
  .asset-masthead { padding: 2rem 0 1.5rem; }
  .asset-identity {
    grid-template-columns: minmax(0, 1fr);
    gap: 1rem;
    margin-bottom: 1.5rem;
  }
  .asset-quote {
    align-items: flex-start;
    text-align: left;
  }

  .voices-section { padding: 2.25rem 0 0; }
  .voices-head { display: none; }
  /* Four fixed tracks rather than three: the direction tags need room to sit
     beside the call count without either one riding over the other, and fixed
     widths keep every row's columns landing on the same verticals. */
  .voice-row {
    grid-template-columns: 2.25rem minmax(0, 1fr) 4.5rem 1.5rem;
    grid-template-areas:
      "rank   channel move  move"
      "bar    bar     bar   bar"
      "stance stance  count toggle";
    gap: 0.65rem 0.75rem;
    padding: 0.95rem 1rem;
  }
  .voice-rank   { grid-area: rank; }
  .voice-channel { grid-area: channel; }
  .voice-move   { grid-area: move; }
  .voice-bar    { grid-area: bar; }
  .voice-stance { grid-area: stance; }
  .voice-count  { grid-area: count; text-align: left; }
  .voice-toggle { grid-area: toggle; }
  .voice-count .voice-cell-label {
    display: inline;
    margin-right: 0.4rem;
    font-size: 0.62rem;
    text-transform: uppercase;
    letter-spacing: 0.1em;
    color: var(--text-muted);
  }

  .voice-panel { padding: 0.35rem 1rem 1rem; }
  /* The narrow prices cell has no room for both labels and both figures; the
     arrow between them carries the reading order instead. */
  .voice-call-prices .voice-cell-label { display: none; }
  .voice-call-row {
    grid-template-columns: minmax(0, 1fr) auto;
    grid-template-areas:
      "date   move"
      "action prices";
    gap: 0.4rem 0.75rem;
  }
  .voice-call-date   { grid-area: date; }
  .voice-call-move   { grid-area: move; }
  .voice-call-row .voice-stance-tag {
    grid-area: action;
    justify-self: start;
  }
  .voice-call-prices {
    grid-area: prices;
    justify-content: flex-end;
  }

  .chat-section {
    padding: 2.5rem 0 3rem;
    margin-top: 2.25rem;
  }
  .chat-messages { max-height: 400px; }
  .chat-form-row { flex-direction: column; }
  .chat-send-btn { width: 100%; }
}

@media (max-width: 480px) {
  .asset-cell { padding: 0.9rem 1rem; }
  .asset-cell dd { font-size: 1.15rem; }
  .asset-quote-figure { font-size: 1.35rem; }
  .voice-name { font-size: 0.88rem; }
  .voice-call-prices { font-size: 0.74rem; }
}
