/* ============================================================
   Layout — shell grid, header, sidebar, news bar (Sprint 11)
   ============================================================ */
.app { display: grid; grid-template-rows: var(--h-header) 1fr var(--h-newsbar);
  height: 100vh; width: 100vw; overflow: hidden; }

/* ---------------- Header ---------------- */
.header { grid-row: 1; display: flex; align-items: center; gap: 18px; padding: 0 16px;
  background: var(--bg-header); border-bottom: 1px solid var(--line); overflow: hidden; }
.brand { display: flex; align-items: center; gap: 10px; flex-shrink: 0; }
.brand__logo { width: 34px; height: 34px; display: grid; place-items: center;
  background: linear-gradient(135deg, #0f2a22, #0a1a16); border: 1px solid #143a30; border-radius: 9px; color: var(--up); }
.brand__name { font-size: 15px; font-weight: 800; letter-spacing: .02em; line-height: 1.05; }
.brand__name b { color: var(--up); font-weight: 800; }
.brand__sub { font-size: 9px; letter-spacing: .22em; color: var(--text-2); font-weight: 600; }

.live-pill { display: inline-flex; align-items: center; gap: 5px; font-size: 10px; font-weight: 800;
  letter-spacing: .05em; padding: 3px 9px; border-radius: 20px; flex-shrink: 0; }
.live-pill.is-live { color: var(--up); background: var(--up-soft); border: 1px solid var(--up-line); }
.live-pill.is-sim { color: var(--accent); background: var(--accent-soft); border: 1px solid rgba(245,166,35,.35); }
.live-pill .dot { width: 6px; height: 6px; border-radius: 50%; background: currentColor; animation: pulse 2s infinite; }
@keyframes pulse { 0%,100% { opacity: 1; } 50% { opacity: .35; } }
.hclock { font-family: var(--font-mono); font-size: 12px; color: var(--text-1); flex-shrink: 0; }

/* Header index strip.
   Was `overflow:hidden` with a fixed 22px gap, so on a 1080p window the 6th
   tile (SENSEX/VIX) was sliced down the middle — "SENS 77,0" with the rest
   clipped. A half-rendered price is worse than no price: it looks like data.
   Now the strip shrinks its gap first, then scrolls, and each tile is
   flex-shrink:0 so a value is never cut mid-number. */
.hindices { display: flex; align-items: center; gap: clamp(9px, 1.1vw, 22px);
  margin-left: 6px; min-width: 0; flex: 0 1 auto;
  overflow-x: auto; overflow-y: hidden; scrollbar-width: none; }
.hindices::-webkit-scrollbar { display: none; }
.hidx { display: flex; flex-direction: column; gap: 1px; white-space: nowrap; flex-shrink: 0; }
.hidx__name { font-size: 9.5px; letter-spacing: .04em; color: var(--text-2); font-weight: 600; }
.hidx__row { display: flex; align-items: baseline; gap: 7px; }
.hidx__val { font-family: var(--font-mono); font-size: 13px; font-weight: 600; color: var(--text-0); }
.hidx__chg { font-family: var(--font-mono); font-size: 11px; font-weight: 500; }

.hspacer { flex: 1 1 auto; }
.hmarket { display: flex; flex-direction: column; align-items: center; gap: 2px; flex-shrink: 0; }
.hmarket__label { font-size: 9px; letter-spacing: .12em; color: var(--text-2); font-weight: 700; }
.hmarket__badge { font-size: 10px; font-weight: 800; letter-spacing: .04em; padding: 2px 10px; border-radius: 5px; }
.hmarket__badge.open { color: var(--up); background: var(--up-soft); border: 1px solid var(--up-line); }
.hmarket__badge.closed { color: var(--down); background: var(--down-soft); border: 1px solid var(--down-line); }
.hmarket__badge.pre { color: var(--accent); background: var(--accent-soft); border: 1px solid rgba(245,166,35,.35); }

.hactions { display: flex; align-items: center; gap: 10px; flex-shrink: 0; }
.hicon { width: 32px; height: 32px; display: grid; place-items: center; border-radius: 8px; color: var(--text-1); position: relative; }
.hicon:hover { background: var(--bg-hover); color: var(--text-0); }
.hicon .badge { position: absolute; top: 1px; right: 1px; min-width: 15px; height: 15px; padding: 0 3px;
  background: var(--down); color: #fff; font-size: 9px; font-weight: 700; border-radius: 8px; display: grid; place-items: center; }
.huser { display: flex; align-items: center; gap: 8px; padding-left: 8px; border-left: 1px solid var(--line); }
.huser__ava { width: 28px; height: 28px; border-radius: 50%; background: linear-gradient(135deg, var(--teal), #0e7c74);
  display: grid; place-items: center; color: #06201d; font-weight: 800; font-size: 12px; }
.huser__name { font-size: 12px; font-weight: 700; letter-spacing: .02em; }
.tag-pro { font-size: 8.5px; font-weight: 800; letter-spacing: .06em; color: var(--accent);
  background: var(--accent-soft); border: 1px solid rgba(245,166,35,.35); border-radius: 4px; padding: 1px 4px; }

/* ---------------- Body: sidebar + main ---------------- */
.body { grid-row: 2; display: grid; grid-template-columns: var(--w-sidebar) 1fr; overflow: hidden; }
.sidebar { display: flex; flex-direction: column; background: var(--bg-header); border-right: 1px solid var(--line);
  overflow-y: auto; overflow-x: hidden; }
.nav { padding: 10px 10px 6px; display: flex; flex-direction: column; gap: 2px; flex: 1; }
.navitem { display: flex; align-items: center; gap: 11px; padding: 8px 11px; border-radius: 8px; color: var(--text-1);
  font-size: 13px; font-weight: 500; position: relative; }
.navitem:hover { background: var(--bg-hover); color: var(--text-0); }
.navitem.active { background: var(--teal-soft); color: #7ff0e4; font-weight: 600; }
.navitem.active::before { content: ""; position: absolute; left: 0; top: 7px; bottom: 7px; width: 3px;
  background: var(--teal); border-radius: 0 3px 3px 0; }
.navitem svg { width: 17px; height: 17px; flex-shrink: 0; }
.navitem .nlabel { flex: 1; white-space: nowrap; }
.nbadge { font-size: 9px; font-weight: 800; letter-spacing: .04em; padding: 1px 6px; border-radius: 10px; }
.nbadge.new { color: var(--up); background: var(--up-soft); }
.nbadge.count { color: #fff; background: var(--down); }
.nbadge.ai { color: #c4b5fd; background: var(--purple-soft); }

.datastatus { margin: 6px 12px 14px; padding: 11px 12px; background: var(--bg-1); border: 1px solid var(--line); border-radius: 9px; }
.datastatus__title { font-size: 9px; letter-spacing: .12em; color: var(--text-2); font-weight: 700; margin-bottom: 6px; }
.datastatus__state { display: flex; align-items: center; gap: 6px; font-size: 12px; font-weight: 700; color: var(--up); }
.datastatus__state .dot { width: 7px; height: 7px; border-radius: 50%; background: var(--up); }
.datastatus.sim .datastatus__state { color: var(--accent); }
.datastatus.sim .datastatus__state .dot { background: var(--accent); }
.datastatus__meta { font-size: 10.5px; color: var(--text-2); margin-top: 5px; line-height: 1.5; }
.datastatus__rt { display: flex; align-items: center; justify-content: space-between; margin-top: 4px; }
.sigbars { display: inline-flex; align-items: flex-end; gap: 2px; height: 13px; }
.sigbars i { width: 3px; background: var(--up); border-radius: 1px; display: inline-block; }
.sigbars i:nth-child(1){height:4px}.sigbars i:nth-child(2){height:7px}.sigbars i:nth-child(3){height:10px}.sigbars i:nth-child(4){height:13px}

/* ---------------- Main ---------------- */
.main { overflow-y: auto; overflow-x: hidden; padding: 13px; }
.view { display: flex; flex-direction: column; gap: 13px; }

/* ---------------- News bar ---------------- */
.newsbar { grid-row: 3; display: flex; align-items: center; gap: 14px; padding: 0 14px;
  background: var(--bg-header); border-top: 1px solid var(--line); overflow: hidden; }
.newsbar__tag { display: flex; align-items: center; gap: 6px; font-size: 10px; font-weight: 800; letter-spacing: .08em;
  color: var(--text-1); flex-shrink: 0; }
.newsbar__tag .dot { width: 6px; height: 6px; border-radius: 50%; background: var(--down); }
.newsticker { flex: 1; overflow: hidden; white-space: nowrap; }
.newsticker__track { display: inline-block; padding-left: 100%;
  /* Duration is set from JS as --news-secs, scaled to the content's actual
     width so the PACE stays constant (~55px/s) however many headlines load.
     A fixed 36s raced unreadably once ~20 real headlines replaced the old
     placeholder (user report). */
  animation: news var(--news-secs, 120s) linear infinite; }
.newsticker__track:hover { animation-play-state: paused; }
@keyframes news { to { transform: translateX(-100%); } }
.newsitem { display: inline-flex; align-items: baseline; gap: 8px; margin-right: 34px; font-size: 12px; }
.newsitem time { font-family: var(--font-mono); color: var(--text-2); font-size: 11px; }
.newsbar__brokers { display: flex; align-items: center; gap: 14px; flex-shrink: 0; font-size: 11px; font-weight: 700; }
.broker-chip { display: inline-flex; align-items: center; gap: 5px; color: var(--text-1); }
.broker-chip.live { color: var(--up); }
.broker-chip .dot { width: 6px; height: 6px; border-radius: 50%; background: currentColor; }

/* News items are links now (real feed): keep the ticker look, add affordance. */
a.newsitem { color: var(--text-1, #dfe7ef); text-decoration: none; }
a.newsitem b { color: var(--teal, #23c6a4); font-weight: 700; font-size: 11px;
  text-transform: uppercase; letter-spacing: .3px; }
a.newsitem:hover span { text-decoration: underline; }

/* NET connection chip — colour by state. */
.netchip[data-state="ok"] .dot { background: var(--up); }
.netchip[data-state="warn"] .dot { background: var(--accent); }
.netchip[data-state="off"] .dot { background: var(--down); }

/* Speed-test popover, anchored above the chip in the news bar. */
.netpop { position: fixed; z-index: 9999; width: 270px; background: var(--bg-1);
  border: 1px solid var(--line-strong); border-radius: 10px; padding: 12px;
  box-shadow: var(--shadow); display: flex; flex-direction: column; gap: 10px; }
.netpop__head { font-size: 10px; font-weight: 800; letter-spacing: .08em;
  color: var(--text-2); }
.netpop__body { font-size: 11px; line-height: 1.45; }
.netpop__row { display: flex; justify-content: space-between; padding: 3px 0;
  font-family: var(--font-mono); font-size: 12px; }
