/* ── Section label ─────────────────────────────────────── */
.sec-lbl {
    font-size: 10px; font-weight: 800; text-transform: uppercase;
    letter-spacing: .9px; color: var(--tx3);
    border-bottom: 1px solid var(--bd);
    padding-bottom: 10px; margin-bottom: var(--ta-sec-gap);
    display: flex; align-items: center; gap: 8px;
}
.live-pill { margin-left: auto; font-size: 10px; font-weight: 800; background: var(--red-fill); color: #fff; padding: 2px 9px; border-radius: 10px; }

/* ── Page heading ──────────────────────────────────────── */
.home-hdr { padding: var(--ta-hdr-pad) 0; }
.home-h1  { font-size: 25px; font-weight: 900; letter-spacing: -.6px; color: var(--tx); line-height: 1.2; }
.home-h1 span { color: var(--blue); }
/* Bottom margin zeroed: it is a <p>, so the reset's 1rem sat inside .home-hdr's
   own bottom padding and made the homepage's header-to-section gap 40 not 24. */
.home-sub { font-size: 13px; color: var(--tx2); margin: 7px 0 0; max-width: 660px; }

/* ════════════════════════════════════════════════════════
   SECTION 1 — TOP NEWS HERO
════════════════════════════════════════════════════════ */
/* Columns and gutters both come from .row .col-* */
/* No top padding: .home-hdr above already ends on the shared section gap. */
.news-hero { padding: 0 0 var(--ta-sec-gap); }

.feat-card {
    background: var(--bg); border: 1px solid var(--bd);
    border-radius: var(--r); overflow: hidden;
    box-shadow: var(--sh-sm); cursor: pointer;
    transition: box-shadow .15s;
    display: flex; flex-direction: column;
}
.feat-card:hover { box-shadow: var(--sh-md); }
.feat-img { width: 100%; height: 240px; object-fit: cover; display: block; background: var(--bg2); }
.feat-body { padding: 20px; flex: 1; display: flex; flex-direction: column; gap: 8px; }
.feat-cat  { font-size: 10px; font-weight: 800; text-transform: uppercase; letter-spacing: .4px; color: var(--blue); }
.feat-hl   { font-size: 22px; font-weight: 800; line-height: 1.25; color: var(--tx); }
.feat-excerpt { font-size: 13.5px; color: var(--tx2); line-height: 1.6; flex: 1; }
.feat-meta { display: flex; align-items: center; gap: 8px; font-size: 11.5px; color: var(--tx3); margin-top: auto; padding-top: 10px; border-top: 1px solid var(--bd); }
.feat-meta .tag-up { color: var(--green-ink); font-weight: 700; }
.feat-meta .tag-dn { color: var(--red-ink);   font-weight: 700; }

.sec-card {
    background: var(--bg); border: 1px solid var(--bd);
    border-radius: var(--r); overflow: hidden; height: 100%;
    box-shadow: var(--sh-sm); cursor: pointer;
    transition: box-shadow .15s;
    display: flex; flex-direction: column;
}
.sec-card:hover { box-shadow: var(--sh-md); }
.sec-img { width: 100%; height: 145px; object-fit: cover; display: block; background: var(--bg2); }
.sec-body { padding: 14px; flex: 1; display: flex; flex-direction: column; gap: 5px; }
.sec-cat  { font-size: 10px; font-weight: 800; text-transform: uppercase; letter-spacing: .4px; color: var(--blue); }
.sec-hl   { font-size: 14px; font-weight: 700; line-height: 1.35; color: var(--tx); }
.sec-meta { font-size: 11px; color: var(--tx3); margin-top: auto; display: flex; gap: 6px; }
.sec-meta .tag-up { color: var(--green-ink); font-weight: 700; }
.sec-meta .tag-dn { color: var(--red-ink);   font-weight: 700; }

/* ════════════════════════════════════════════════════════
   SECTION 2 — 3-COLUMN BODY
════════════════════════════════════════════════════════ */
/* Columns and gutters both come from .row .col-lg-* */

.j-card {
    background: var(--bg); border: 1px solid var(--bd);
    border-radius: var(--r); padding: 15px; margin-bottom: var(--ta-sec-gap);
    box-shadow: var(--sh-sm); cursor: pointer;
    transition: box-shadow .15s, transform .15s;
}
.j-card:last-child { margin-bottom: 0; }
.j-card:hover { box-shadow: var(--sh-md); transform: translateY(-1px); }
.j-profile { display: flex; align-items: center; gap: 10px; margin-bottom: 11px; }
.j-avatar {
    width: 40px; height: 40px; border-radius: 50%; flex-shrink: 0;
    background: var(--blue-lt); color: var(--blue-ink);
    font-size: 14px; font-weight: 800;
    display: flex; align-items: center; justify-content: center;
    border: 2px solid var(--bd);
}
.j-name { font-size: 13px; font-weight: 700; }
.j-role { font-size: 11px; color: var(--tx3); }
.j-tag  { display: inline-block; font-size: 10px; font-weight: 700; padding: 2px 8px; border-radius: 20px; background: var(--blue-lt); color: var(--blue-ink); margin-top: 3px; }
.j-hl   { font-size: 13px; font-weight: 600; line-height: 1.4; margin-bottom: 10px; }
.tldr   { background: var(--bg3); border-left: 2px solid var(--blue); border-radius: 6px; padding: 9px 12px; }
.tldr-lbl  { font-size: 9px; font-weight: 800; text-transform: uppercase; letter-spacing: .8px; color: var(--blue-ink); margin-bottom: 5px; }
.tldr-list { list-style: none; padding: 0; display: flex; flex-direction: column; gap: 4px; }
.tldr-list li { font-size: 11.5px; color: var(--tx2); display: flex; gap: 6px; }
.tldr-list li::before { content: '•'; color: var(--blue); font-weight: 800; }

/* ── Left-column panels ────────────────────────────────────
   Reuse .widget / .w-ttl from the sidebar rather than restyling a second
   panel: same border, radius, padding and shadow. Only the sidebar's
   height:100% has to go, because these stack instead of filling a cell.
   Must be .widget.j-panel: .widget is declared later in this sheet, so a
   bare .j-panel loses the tie on equal specificity and the panel stretched
   to the full column height. */
.widget.j-panel { height: auto; margin-top: var(--ta-sec-gap); }
.j-panel-foot {
    display: block; margin-top: 12px; padding-top: 11px;
    border-top: 1px solid var(--bd);
    font-size: 11px; font-weight: 700; color: var(--blue-ink);
    text-decoration: underline; text-underline-offset: 2px;
}

/* Broker spotlight */
.bs-row { display: flex; align-items: center; gap: 9px; padding: 8px 0; border-bottom: 1px solid var(--bd); text-decoration: none; color: inherit; }
.bs-row:last-of-type { border-bottom: none; }
.bs-row:hover .bs-name { color: var(--blue); }
.bs-logo { width: 26px; height: 26px; flex-shrink: 0; object-fit: contain; border-radius: 4px; background: var(--bg2); }
/* A mark drawn in white for a dark site header disappears on --bg2, so those
   bring their own dark backing. --ta-plate-ink, not --bg2: a logo's own ink does
   not change when the reader switches theme, so this plate must not either. It
   is also the exact colour the register pages and the admin contact sheet use —
   judging a logo against one shade and shipping it on another is how the
   white-on-white bug got missed in the first place. */
.bs-logo.is-light-ink { background: var(--ta-plate-ink); }
/* Initials fallback, matching the register's ink-on-paper mark. */
.bs-mark {
    width: 26px; height: 26px; flex-shrink: 0; border-radius: 4px;
    background: var(--bg3); color: var(--tx2);
    font-size: 10px; font-weight: 800;
    display: flex; align-items: center; justify-content: center;
}
.bs-body { flex: 1; min-width: 0; }
.bs-name { font-size: 12.5px; font-weight: 700; color: var(--tx); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.bs-regs { font-size: 10px; color: var(--tx3); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.bs-score { font-size: 10px; font-weight: 700; color: var(--gold-ink); white-space: nowrap; flex-shrink: 0; }

/* Desk roster. Two-up only in the 6-wide column it lives in: as a single
   list across ~660px each row is a name at one edge and a call count at the
   other, which reads as blank in its own right. */
.dr-grid { display: grid; grid-template-columns: 1fr; }
@media (min-width: 992px) {
    .dr-grid { grid-template-columns: 1fr 1fr; column-gap: var(--ta-sec-gap); }
    /* Hairlines belong between rows, so the two bottom cells drop theirs. */
    .dr-grid .dr-row:nth-last-child(-n+2) { border-bottom: none; }
}
.dr-row { display: flex; align-items: center; gap: 9px; padding: 8px 0; border-bottom: 1px solid var(--bd); text-decoration: none; color: inherit; }
.dr-row:last-of-type { border-bottom: none; }
.dr-row:hover .dr-name { color: var(--blue); }
.dr-avatar {
    width: 30px; height: 30px; border-radius: 50%; flex-shrink: 0;
    background: var(--blue-lt); color: var(--blue-ink);
    font-size: 11px; font-weight: 800;
    display: flex; align-items: center; justify-content: center;
}
.dr-body { flex: 1; min-width: 0; }
.dr-name { font-size: 12.5px; font-weight: 700; color: var(--tx); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.dr-beat { font-size: 10px; color: var(--tx3); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.dr-calls { font-size: 10px; font-weight: 700; color: var(--tx2); white-space: nowrap; flex-shrink: 0; }
.dr-total { font-size: 11px; color: var(--tx2); line-height: 1.5; margin: 11px 0 0; }

.news-strip {
    display: flex; background: var(--bg); border: 1px solid var(--bd);
    border-radius: var(--r); overflow: hidden; margin-bottom: var(--ta-sec-gap);
    box-shadow: var(--sh-sm); cursor: pointer; transition: box-shadow .15s;
}
.news-strip:last-child { margin-bottom: 0; }
.news-strip:hover { box-shadow: var(--sh-md); }
/* Same idea as the sidebar: at desktop this column takes the full row height
   and its strips share whatever is left over, so it ends flush with the other
   two instead of leaving a gap. The strips absorb it rather than the roster
   card, which would otherwise be one card carrying all the slack — worst at
   992px, where the journalist cards in column 1 wrap tallest. .ns-img covers
   and .ns-meta is bottom-pinned, so a taller strip just shows more image. */
@media (min-width: 992px) {
    .stories-col { display: flex; flex-direction: column; }
    .stories-col .news-strip { flex: 1 1 auto; }
    /* Column 1 gets the same treatment, or it is the one column with no way to
       absorb the row's slack and the Regulated Brokers panel stops short of the
       other two. The journalist cards take it rather than the panel, so the
       leftover is split three ways instead of pooling under one list. */
    .factory-col { display: flex; flex-direction: column; }
    .factory-col .j-card { flex: 1 1 auto; }
}
.ns-img { width: 130px; flex-shrink: 0; object-fit: cover; display: block; background: var(--bg2); min-height: 105px; }
.ns-body { padding: 13px; flex: 1; display: flex; flex-direction: column; gap: 4px; }
.ns-cat  { font-size: 10px; font-weight: 800; text-transform: uppercase; letter-spacing: .4px; color: var(--blue); }
.ns-hl   { font-size: 14px; font-weight: 700; line-height: 1.35; color: var(--tx); }
.ns-exc  { font-size: 12px; color: var(--tx2); line-height: 1.5; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }
.ns-meta { display: flex; align-items: center; gap: 6px; font-size: 11px; color: var(--tx3); margin-top: auto; }

/* Sidebar widgets — the shared .row gutter supplies the spacing */
/* The sidebar carries the least content of the three columns, so at desktop
   it is given the full column height and its wrapped flex lines stretch to
   fill it (align-content defaults to stretch). The slack is shared out
   across the four widgets instead of pooling as one gap above the next
   section. Below lg the columns stack, so there is no slack to share. */
@media (min-width: 992px) {
    .sidebar-wrap { display: flex; }
    /* min-width:0 because a flex item defaults to min-width:auto, i.e. it refuses
       to shrink below its min-content. At exactly 992px the column is 240px but
       the widgets measure ~305, so the sidebar hung 54px off the right edge.
       Pre-existing; the 24px gutter only made it 59. */
    .sidebar-wrap > .sidebar-col { flex: 1; min-width: 0; }
}
.widget { background: var(--bg); border: 1px solid var(--bd); border-radius: var(--r); padding: 16px; height: 100%; box-shadow: var(--sh-sm); overflow: hidden; }
.w-ttl { font-size: 12px; font-weight: 800; text-transform: uppercase; letter-spacing: .5px; color: var(--tx); margin-bottom: var(--ta-sec-gap); display: flex; align-items: center; gap: 7px; }
.w-ttl i { color: var(--blue); font-size: 14px; }

.fg-wrap { display: flex; flex-direction: column; align-items: center; }
.fg-svg  { width: 100%; max-width: 225px; }
/* These two are the resting colour, shown while "Loading…" is on screen and
   whenever the sentiment API fails. It was a hard-coded #22C55E at 2.3:1 —
   fetchFearGreed already defaults to var(--green-ink), so the CSS was the
   only place still carrying an unreadable green. */
.fg-val  { font-size: 36px; font-weight: 900; text-align: center; font-variant-numeric: tabular-nums; color: var(--green-ink); }
.fg-mood { font-size: 13px; font-weight: 700; text-align: center; color: var(--green-ink); }
.fg-scale { display: flex; justify-content: space-between; font-size: 10px; font-weight: 600; color: var(--tx3); width: 100%; max-width: 225px; margin-top: 7px; }

#news-ta-wrap { margin: 0 -16px -16px; overflow: hidden; }

/* TA dropdown — Bootstrap supplies the chevron and the dark-mode swap */
.ta-select { font-size: 12.5px; font-weight: 600; margin-bottom: 10px; }

/* One block per asset class, hairline-separated. The classes close at different
   times, so each carries its own date line rather than sharing one. */
.mv-group + .mv-group { margin-top: 13px; padding-top: 11px; border-top: 1px solid var(--bd); }
/* Pulls the first heading up under .w-ttl, which is what .mv-date used to do
   before the groups existed. */
.mv-group:first-child { margin-top: -6px; }
.mv-grp-hd { font-size: 10px; font-weight: 800; letter-spacing: .05em; text-transform: uppercase; color: var(--tx2); }

/* Where the figures come from. Stamped rather than implied, and it carries one
   of three labels: a completed "Close of {date}"; "Intraday · {time} ET" for a
   snapshot taken while that market was still trading; or "24h · as of {time} ET"
   for a class with no closing bell at all. "Live" was never a claim we could
   keep — the fetch runs on each market's own schedule, not continuously. */
.mv-date { font-size: 10px; color: var(--tx3); margin: 1px 0 7px; }
.mover { display: flex; align-items: center; padding: 7px 0; border-bottom: 1px solid var(--bd); }
.mover:last-child { border-bottom: none; }
/* Sizes to content with a floor, rather than a fixed width: the crypto pairs
   are "SOL/USD" and a hard 50px let them overrun the instrument name. */
.mv-sym { font-size: 13px; font-weight: 800; flex: 0 0 auto; min-width: 50px; padding-right: 8px; white-space: nowrap; }
/* Truncates: the sidebar is ~300px and some instrument names are long. */
.mv-nm  { font-size: 11px; color: var(--tx3); flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.mv-px  { font-size: 12px; font-weight: 600; font-variant-numeric: tabular-nums; width: 64px; text-align: right; }
.mv-chg { font-size: 11.5px; font-weight: 800; width: 64px; text-align: right; font-variant-numeric: tabular-nums; }
/* These two had no colour rule at all while the widget was hard-coded, so
   every change value rendered as body text. The arrow carries direction
   too, so the sign is never the only cue (SC 1.4.1). */
.mv-chg.up { color: var(--green-ink); }
.mv-chg.dn { color: var(--red-ink); }
.mv-empty { font-size: 11.5px; color: var(--tx3); }

/* ════════════════════════════════════════════════════════
   SECTION 3 — AI + CHART (bottom)
════════════════════════════════════════════════════════ */
/* Columns and gutters both come from .row .col-lg-* */
.bottom-panel { padding: var(--ta-sec-gap) 0 0; }
/* The only .sec-lbl on the site that is a grid column in its own right, so the
   row's own gutter-y already puts the section gap under it. Its margin would
   land on top of that and the label sat twice as far from the cards as every
   other label on the page. */
.bottom-panel > .col-12 > .sec-lbl { margin-bottom: 0; }

.pulse-card {
    background: var(--bg); border: 1px solid var(--bd);
    border-top: 3px solid var(--blue);
    border-radius: var(--r); padding: 20px; height: 100%;
    box-shadow: var(--sh-sm);
    display: flex; flex-direction: column; gap: 14px;
}
.pulse-hdr { display: flex; align-items: center; gap: 10px; }
.pulse-icon { width: 34px; height: 34px; flex-shrink: 0; background: var(--blue-lt); border-radius: 8px; display: flex; align-items: center; justify-content: center; color: var(--blue); font-size: 17px; }
.pulse-ttl { font-size: 11px; font-weight: 800; text-transform: uppercase; letter-spacing: .7px; color: var(--blue); }
.pulse-sub { font-size: 11px; color: var(--tx3); }
/* An anchor since 2026-08-04 (it links to the symbol hub), so it has to unset
   the link colour and underline the card would otherwise inherit. */
.pulse-asset { display: flex; align-items: center; justify-content: space-between; background: var(--bg2); border: 1px solid var(--bd); border-radius: 8px; padding: 12px; color: inherit; text-decoration: none; transition: border-color .15s; }
.pulse-asset:hover { border-color: var(--blue); }
/* Which session the price above belongs to. Sits directly under the figure and
   carries the same wording as the matching Top Movers block. */
.pulse-stamp { font-size: 10px; color: var(--tx3); margin: -8px 0 0; }
.pa-label { font-size: 10px; color: var(--tx3); margin-bottom: 2px; }
.pa-name  { font-size: 15px; font-weight: 800; }
.pa-price { font-size: 22px; font-weight: 900; font-variant-numeric: tabular-nums; }
.chg-badge { font-size: 11.5px; font-weight: 700; padding: 3px 9px; border-radius: 4px; display: inline-block; }
.chg-badge.up { color: var(--green-ink); background: var(--green-lt); }
.chg-badge.dn { color: var(--red-ink);   background: var(--red-lt);   }
.ai-box { background: var(--blue-lt); border-left: 3px solid var(--blue); border-radius: 6px; padding: 12px; }
.ai-box-lbl { font-size: 9px; font-weight: 800; text-transform: uppercase; letter-spacing: .7px; color: var(--blue-ink); margin-bottom: 5px; }
.ai-box-txt { font-size: 12.5px; color: var(--tx); line-height: 1.5; }
.ai-box-src { font-size: 10px; color: var(--blue-ink); margin-top: 6px; }
.pulse-bullets { list-style: none; padding: 0; display: flex; flex-direction: column; gap: 6px; }
.pulse-bullets li { display: flex; gap: 7px; font-size: 12px; color: var(--tx2); }
.pulse-bullets li::before { content: '→'; color: var(--blue); font-weight: 800; flex-shrink: 0; }
.pulse-footer { display: flex; gap: 8px; margin-top: auto; }
/* An <a> to the article since 2026-08-04, hence text-align and the reset
   underline; it used to be a <button> with no handler at all. */
.btn-analysis { flex: 1; padding: 8px; background: var(--blue-fill); color: #fff; border: none; border-radius: 6px; font-size: 12px; font-weight: 700; cursor: pointer; font-family: inherit; text-align: center; text-decoration: none; transition: opacity .15s; }
.btn-analysis:hover { opacity: .88; color: #fff; }

.tv-wrap { border: 1px solid var(--bd); border-radius: var(--r); overflow: hidden; box-shadow: var(--sh-sm); min-height: 420px; height: 100%; }

/* Markets at a Glance */
.mktsnap { background: var(--bg); border: 1px solid var(--bd); border-radius: var(--r); padding: 16px; box-shadow: var(--sh-sm); display: flex; flex-direction: column; }
.mktsnap-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; flex: 1; align-content: start; }
.mkt-tile { background: var(--bg2); border: 1px solid var(--bd); border-radius: 8px; padding: 10px 12px; display: flex; flex-direction: column; gap: 3px; }
.mkt-tile-name { font-size: 10px; font-weight: 700; color: var(--tx3); text-transform: uppercase; letter-spacing: .4px; }
.mkt-tile-px   { font-size: 15px; font-weight: 800; font-variant-numeric: tabular-nums; color: var(--tx); }
.mkt-tile-chg  { font-size: 11px; font-weight: 700; }
.mkt-tile-bar  { height: 3px; border-radius: 2px; margin-top: 4px; background: var(--bd); overflow: hidden; }
.mkt-tile-fill { height: 100%; border-radius: 2px; }
.mkt-tile-fill.g { background: var(--green); }
.mkt-tile-fill.r { background: var(--red); }
.mkt-update { font-size: 10px; color: var(--tx3); margin-top: 10px; display: flex; align-items: center; gap: 4px; }
.pulse-dot { width: 6px; height: 6px; border-radius: 50%; background: var(--green); animation: blink 1.5s ease-in-out infinite; }

/* Latest News — matches the featured card's height once they sit side by side */
.latest-news {
    background: var(--bg); border: 1px solid var(--bd);
    border-radius: var(--r); padding: 14px; height: 320px;
    box-shadow: var(--sh-sm);
    display: flex; flex-direction: column; overflow: hidden;
}
@media (min-width: 992px) {
    .feat-card, .latest-news { height: 440px; }
}
.ln-scroll { overflow-y: auto; flex: 1; min-height: 0; }
.ln-scroll::-webkit-scrollbar { width: 3px; }
.ln-scroll::-webkit-scrollbar-track { background: transparent; }
.ln-scroll::-webkit-scrollbar-thumb { background: var(--bd); border-radius: 2px; }
.ln-item { display: flex; align-items: flex-start; gap: 8px; padding: 8px 2px; border-bottom: 1px solid var(--bd); }
.ln-item:last-child { border-bottom: none; }
.ln-dot { width: 7px; height: 7px; border-radius: 50%; flex-shrink: 0; margin-top: 5px; }
.ln-dot.mkts { background: var(--blue); }
.ln-dot.tech { background: #8B5CF6; }
.ln-dot.cryp { background: var(--amber); }
.ln-dot.macr { background: var(--green); }
.ln-dot.enrg { background: #F97316; }
.ln-dot.bank { background: #06B6D4; }
.ln-hl   { font-size: 12px; font-weight: 600; color: var(--tx); line-height: 1.4; flex: 1; }
.ln-time { font-size: 10px; color: var(--tx3); white-space: nowrap; margin-top: 2px; }

/* Latest Analysis Section */
.la-section { padding: var(--ta-sec-gap) 0 0; }
.la-card {
    background: var(--bg); border: 1px solid var(--bd); border-radius: var(--r);
    overflow: hidden; box-shadow: var(--sh-sm); text-decoration: none; color: inherit;
    display: flex; flex-direction: column; height: 100%; transition: box-shadow .15s, transform .15s;
}
.la-card:hover { box-shadow: var(--sh-md); transform: translateY(-2px); }
.la-card-img { width: 100%; height: 160px; object-fit: cover; display: block; background: var(--bg2); }
.la-card-body { padding: 14px; display: flex; flex-direction: column; gap: 6px; flex: 1; }
.la-card-cat { font-size: 10px; font-weight: 800; text-transform: uppercase; letter-spacing: .4px; color: var(--blue); }
.la-card-title { font-size: 13px; font-weight: 700; line-height: 1.35; color: var(--tx); }
.la-card-excerpt { font-size: 12px; color: var(--tx2); line-height: 1.5; flex: 1; }
.la-card-meta { font-size: 11px; color: var(--tx3); display: flex; align-items: center; gap: 6px; margin-top: 4px; }

/* Layout responsiveness comes from the Bootstrap grid; only sizing is left here */
@media (max-width: 767px) {
    .feat-img    { height: 200px; }
    .latest-news { height: 260px; }
    .ta-select   { font-size: 12px; }
}
