/* Winston V3 — ticker tape. Sticky band below the top-bar; full width
   across mobile + desktop. The grid in layout.css reserves a row for it
   so the band never overlaps content. */

.ticker-tape {
  /* Pin the band directly under the top-bar so it stays visible on scroll.
     top-bar is sticky at top:0 / z-index:100; the tape tucks beneath it at
     a lower z-index so content scrolls under both. */
  position: sticky;
  top: var(--top-bar-h);
  z-index: 90;
  background: var(--surface);
  border-bottom: 1px solid var(--border);
  overflow: hidden;
  min-height: 36px;
  display: flex;
  align-items: center;
  width: 100%;
  font-family: var(--font-mono, 'JetBrains Mono', ui-monospace, monospace);
  font-size: var(--type-sm);
  user-select: none;
}

.ticker-tape[hidden] { display: none; }

/* Marquee track. When the symbol list overflows the band, ticker-tape.js
   adds `.is-marquee` + a second aria-hidden run and the CSS animation
   translates the track left by exactly one run-width for a seamless loop.
   When the content fits, the track stays a single static run (no duplicate,
   no scroll) so a short list doesn't render side-by-side duplicates. */
.ticker-track {
  display: flex;
  flex-wrap: nowrap;
  width: max-content;
}

.ticker-track.is-marquee {
  animation: ticker-scroll 60s linear infinite;
}

.ticker-track.is-marquee:hover { animation-play-state: paused; }

.ticker-run {
  display: flex;
  flex: 0 0 auto;
  gap: var(--space-6);
  padding: 0 var(--space-6);
  align-items: center;
}

@keyframes ticker-scroll {
  from { transform: translateX(0); }
  to   { transform: translateX(-50%); }
}

/* The tape always auto-scrolls — the operator opted out of the previous
   prefers-reduced-motion swipe fallback, which replaced the marquee with a
   horizontal scrollbar (overflow-x: auto). We no longer special-case reduced
   motion: the marquee still only engages when the symbol list overflows the
   band (ticker-tape.js adds .is-marquee), it pauses on hover, and the band's
   own `overflow: hidden` clips the track so no scrollbar ever appears. */
.ticker-tape,
.ticker-track {
  /* Belt-and-suspenders: never paint a scrollbar even if some future overflow
     rule sneaks in. The marquee animation does the scrolling. */
  scrollbar-width: none;          /* Firefox */
}
.ticker-tape::-webkit-scrollbar,
.ticker-track::-webkit-scrollbar { display: none; }  /* WebKit/Blink */

.ticker-tile {
  display: inline-flex;
  align-items: baseline;
  gap: var(--space-2);
  white-space: nowrap;
  line-height: 1;
}

.ticker-sym {
  font-weight: 700;
  color: var(--ink-strong, var(--ink));
  letter-spacing: 0.02em;
}

.ticker-price {
  color: var(--ink);
  font-variant-numeric: tabular-nums;
}

.ticker-delta {
  font-variant-numeric: tabular-nums;
  font-weight: 600;
  display: inline-flex;
  align-items: baseline;
  gap: 2px;
}

.ticker-arrow {
  font-size: 0.85em;
  line-height: 1;
}

/* Sign-coupled color (NOT color-alone — arrow + sign character carry the
   signal too, matches V3's delta-pill discipline). */
.ticker-tile[data-sign="up"]   .ticker-delta { color: var(--pos, #117A3A); }
.ticker-tile[data-sign="down"] .ticker-delta { color: var(--neg, #C8201F); }
.ticker-tile[data-sign="flat"] .ticker-delta { color: var(--ink-muted); }

.ticker-tile[data-state="empty"] .ticker-price,
.ticker-tile[data-state="empty"] .ticker-delta {
  color: var(--ink-muted);
}

/* Empty + error states stretch to the full band width so the CTA / message
   centers correctly. */
.ticker-empty,
.ticker-error {
  width: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-3);
  padding: 0 var(--space-4);
  font-size: var(--type-sm);
}

.ticker-empty-text { color: var(--ink-muted); }

.ticker-empty-cta {
  /* #151 L1 — was var(--accent, var(--ink)); --accent isn't defined in
     tokens.css, so the CTA resolved to body ink and "Add symbols →" read as
     plain text. --ai is the defined V3 accent (the cobalt used for active
     sidebar items), so the link now reads as interactive. */
  color: var(--ai);
  font-weight: 600;
  text-decoration: none;
}

.ticker-empty-cta:hover,
.ticker-empty-cta:focus { text-decoration: underline; }

.ticker-error-text { color: var(--ink-muted); font-style: italic; }

/* #151 L2 — freshness indicator. When prices haven't refreshed within the
   stale threshold (polling stalled — Alpaca degraded, expired key, transient
   5xx), the tape keeps showing the last good prices but must acknowledge they
   may be behind. ticker-tape.js sets data-stale="1" and renders the pill. */
.ticker-tape[data-stale="1"] .ticker-track { opacity: 0.5; }

.ticker-stale {
  position: absolute;
  top: 50%;
  right: var(--space-3);
  transform: translateY(-50%);
  z-index: 1;
  display: inline-flex;
  align-items: center;
  gap: var(--space-1);
  padding: 2px var(--space-2);
  border-radius: var(--radius-sm, 4px);
  background: var(--surface);
  border: 1px solid var(--neg, #C8201F);
  color: var(--neg, #C8201F);
  font-size: var(--type-xs);
  font-weight: 700;
  letter-spacing: 0.02em;
  white-space: nowrap;
  cursor: help;
}
