/*
 * stock-lists.css — /stock-lists and /stock-lists/{slug}
 *
 * Loads after homepage.css and content-pages.css and borrows their tokens
 * (--bq-green, --bq-line-strong, --bq-mono, ...) rather than defining a
 * second palette. Everything here is prefixed .bq-sl- and cannot reach
 * another template.
 *
 * ---------------------------------------------------------------------
 * IT IS THE MOVERS PAGE, NOT A CONTENT PAGE
 *  Square corners, hairline borders, a tinted head bar and a 2px ink rule
 *  under the column headers — the same chrome .bq-panel and .bq-tm-panel
 *  already wear. These two page types are the same object at different
 *  scopes ("today's biggest movers" / "every bank"), and a reader moving
 *  between them should not feel they changed sites. Nothing here has a
 *  border-radius except the pill-shaped controls.
 *
 * COLUMN WIDTHS ARE NOT FROZEN, and that is the one deliberate departure
 *  from top-movers.css. That table has a fixed nine columns; this one has
 *  seven plus however many metric columns the reader has added through
 *  Edit Columns — a percentage set summing to 100 cannot be written for an
 *  unknown column count. So the table is auto-layout with min-widths on
 *  the fixed columns and a scrolling wrapper, and the metric columns share
 *  what is left.
 * ---------------------------------------------------------------------
 */

/* =====================================================================
   SECTION
   ===================================================================== */
/* STICKY GEOMETRY, in one place.

   The site header is position:fixed at 54px, so ANY sticky element with
   top:0 slides underneath it. Both header rows are offset from --sl-nav.

   --sl-ttl is set further down, next to the rows it governs: it is 0 at rest
   and 40px only while the header is stuck, which is what makes the title row
   a scroll-only band rather than a permanent second heading. */
.bq-sl-page {
    --sl-nav: 54px;     /* #bq-main-header height */
}

.bq-sl {
    /* .bq-plain-page .bq-main clears the fixed 54px header exactly, so this
       is the whole gap between the navy bar and the first card. Same 46px
       the movers pages use, for the same reason: a bordered white card
       30px under a solid navy bar reads as touching it. */
    padding: 46px 0 56px;
    background: #fbfcfd;
    border-bottom: 1px solid var(--bq-line);
    min-height: 60vh;
}

/* .bq-plain-page narrows .bq-container to 1120px for prose. This page is a
   wide table, and it wants the room the homepage dashboard gets. Widened
   here rather than by dropping .bq-plain-page from the body, because that
   class is also what pins the header solid. */
.bq-sl-page .bq-main .bq-sl .bq-container { max-width: 1500px; }

/* =====================================================================
   HEAD PANE
   ===================================================================== */
.bq-sl-head {
    background: var(--white);
    border: 1px solid var(--bq-line-strong);
    padding: 20px 22px 20px;
    margin-bottom: 16px;
}
.bq-sl-head__text { min-width: 0; }

.bq-sl-crumbs {
    display: flex; align-items: center; flex-wrap: wrap; gap: 7px;
    font-size: 12px; color: var(--gray-500); margin-bottom: 8px;
}
.bq-sl-crumbs a { color: var(--blue-primary); text-decoration: none; }
.bq-sl-crumbs a:hover { text-decoration: underline; }

/* The classification path. Each level is a link to its own list, so the
   taxonomy is navigable rather than decorative — which is also most of this
   page's internal linking. */
.bq-sl-eyebrow {
    display: flex; align-items: center; flex-wrap: wrap; gap: 6px;
    margin-bottom: 7px;
    font-size: 11px; font-weight: 700; letter-spacing: 1.1px; text-transform: uppercase;
    color: var(--blue-primary);
}
.bq-sl-eyebrow a { color: inherit; text-decoration: none; border-bottom: 1px solid transparent; }
.bq-sl-eyebrow a:hover { border-bottom-color: currentColor; }
.bq-sl-eyebrow__sep { color: var(--gray-500); }
/* .bq-sl-code is gone with the markup that used it — BQ-MICS codes are
   not printed on public pages. */

.bq-sl-head h1 {
    margin: 0;
    font-size: 28px; font-weight: 900; line-height: 1.15;
    letter-spacing: -.5px; color: var(--bq-ink);
}
.bq-sl-lede {
    margin: 9px 0 0; max-width: 74ch;
    font-size: 14.5px; line-height: 1.6; color: var(--gray-700);
}

/* =====================================================================
   PANEL
   ===================================================================== */
.bq-sl-panel {
    background: var(--white);
    border: 1px solid var(--bq-line-strong);
}

.bq-sl-error {
    margin: 0; padding: 28px 16px; text-align: center;
    font-size: 14px; color: var(--gray-500);
}

/* =====================================================================
   STATS STRIP
   -----------------------------------------------------------------
   Four figures a 200-row table does not answer at a glance. Equal grid
   columns rather than a flex row, so a nine-character market cap cannot
   push the labels out of alignment.
   ===================================================================== */
.bq-sl-stats {
    display: grid; grid-template-columns: repeat(4, 1fr);
    background: #fcfdfe;
    border-bottom: 1px solid var(--bq-line-strong);
}
.bq-sl-stat { padding: 11px 16px 12px; border-left: 1px solid var(--bq-line); min-width: 0; }
.bq-sl-stat:first-child { border-left: none; }
.bq-sl-stat__label {
    display: block; margin-bottom: 3px;
    font-size: 9.5px; font-weight: 700; letter-spacing: .9px; text-transform: uppercase;
    color: var(--gray-500); white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.bq-sl-stat__val {
    display: block;
    font-family: var(--bq-mono); font-variant-numeric: tabular-nums;
    font-size: 16px; font-weight: 700; color: var(--bq-ink);
    white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.bq-sl-stat__val.is-up   { color: var(--bq-green); }
.bq-sl-stat__val.is-down { color: var(--bq-red); }

/* =====================================================================
   TOOLBAR
   ===================================================================== */
.bq-sl-bar {
    display: flex; align-items: center; justify-content: space-between;
    gap: 12px; flex-wrap: wrap;
    padding: 10px 14px;
    background: var(--bq-panel-head);
    border-bottom: 1px solid var(--bq-line-strong);
}
.bq-sl-bar__left, .bq-sl-bar__right { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }

/* THE INDEX PAGE'S FILTER ONLY.
   The leaf page had one and lost it: a table that is already one industry,
   sorted by size, does not need a box that filters it down to one row —
   someone who knows the ticker uses the site search. The index, with 264
   lists across 11 sectors, is the case a filter is actually for. */
.bq-sl-search {
    display: inline-flex; align-items: center; gap: 7px;
    padding: 0 10px; height: 32px;
    background: var(--white);
    border: 1px solid var(--bq-line-strong);
    transition: border-color .14s ease, box-shadow .14s ease;
}
.bq-sl-search:focus-within { border-color: var(--blue-primary); box-shadow: 0 0 0 3px rgba(3,105,161,.08); }
.bq-sl-search svg { width: 14px; height: 14px; color: var(--gray-500); flex-shrink: 0; }
.bq-sl-search input {
    border: 0; outline: 0; background: none;
    font-family: inherit; font-size: 13px; color: var(--bq-ink);
    width: 230px; min-width: 0;
}
.bq-sl-search input::placeholder { color: var(--gray-500); }
/* Chrome's own clear button sits on a different baseline in a 32px box. */
.bq-sl-search input::-webkit-search-cancel-button { -webkit-appearance: none; appearance: none; }

.bq-sl-toggle {
    display: inline-flex; align-items: center; gap: 7px;
    font-size: 12.5px; color: var(--gray-700); cursor: pointer; user-select: none;
}
.bq-sl-toggle input { margin: 0; accent-color: var(--blue-primary); }
.bq-sl-toggle__n {
    font-family: var(--bq-mono); font-size: 10.5px; font-weight: 700;
    color: var(--gray-500); background: var(--white);
    border: 1px solid var(--bq-line-strong); padding: 1px 6px;
}

.bq-sl-btn {
    display: inline-flex; align-items: center; gap: 6px;
    height: 32px; padding: 0 12px;
    font-family: inherit; font-size: 12px; font-weight: 700;
    letter-spacing: .3px; color: var(--blue-primary);
    background: var(--white);
    border: 1px solid var(--bq-line-strong);
    cursor: pointer;
    transition: border-color .14s ease, background .14s ease, color .14s ease;
}
.bq-sl-btn svg { width: 13px; height: 13px; }
.bq-sl-btn:hover { border-color: var(--blue-primary); background: #f5faff; }
.bq-sl-btn:focus-visible { outline: 2px solid var(--blue-primary); outline-offset: 1px; }
.bq-sl-btn.is-busy { opacity: .6; pointer-events: none; }

/* =====================================================================
   TABLE
   ===================================================================== */
/* THE WRAPPER MUST NOT BE A SCROLL CONTAINER, or the sticky header dies.
   -----------------------------------------------------------------
   This cost an hour, so it is written down. `position: sticky` resolves
   against the nearest SCROLLPORT ancestor, not the viewport. The moment this
   wrapper carried `overflow-x: auto` it became that scrollport — and because
   the wrapper is exactly as tall as the table and scrolls away with the page,
   the header stuck to a box that was itself leaving the screen. Measured: the
   title row sat at -443px while the page claimed it was `position: sticky;
   top: 54px`. Removing the overflow put it back at exactly 54px.

   `overflow-x: auto; overflow-y: visible` does not rescue it either: per the
   overflow spec a non-visible value on one axis promotes `visible` on the
   other to `auto`, so the box is a scroll container either way.

   So the wrapper only becomes a scroll container when it actually has to be:

     · Default — no overflow. At 1500px the eleven-column table fits with
       room to spare (measured: 0px of overflow), so the scroll container was
       buying nothing and costing the header.

     · .is-wide — set BY PHP when the reader's Edit Columns choice pushes the
       table past what fits. That is a server-side count, not a JS measurement,
       so there is no resize observer and no layout thrash. Those readers trade
       the sticky header for a table that fits the screen, which is the right
       way round: a header is worth less than being able to see the columns you
       just chose.

     · Below 900px — always, because a phone cannot fit this table at any
       column count and a page-level horizontal scrollbar is the worse bug.
   ----------------------------------------------------------------- */
/* NOT A SCROLL CONTAINER — the same arrangement /top-gainers uses, and the
   reason that page never had any of this.
   -----------------------------------------------------------------
   Every symptom on this page came from making it one. A wrapper with
   `overflow-x: auto` is a scrollport on BOTH axes (per the overflow spec a
   non-visible value on one axis promotes the other), which killed the sticky
   header outright: `top` measured from the wrapper, so the header rendered
   54px down inside its own tbody, covering rows two and three.

   And it did not contain the damage either. MEASURED on a 430px device,
   hiding <main> collapsed documentElement.scrollWidth from 662 to 430 and
   #bq-main-header with it — the scrolling table was holding the INITIAL
   CONTAINING BLOCK open at 662, and Chrome sizes `position: fixed` against
   that block and never narrows it again. So the fixed header rendered 662px
   wide on a 430px screen and put its own hamburger at x=638, off the side of
   the phone, and the drawer opened 232px off-screen with it. The table broke
   the site header from three levels down without ever visibly overflowing
   anything of its own.

   The movers table is incapable of this, because it is incapable of
   overflowing: table-layout:fixed, every column a percentage, the set summing
   to 100 at every breakpoint. This table now works the same way — it always
   exactly fills its wrapper, the wrapper never scrolls, the page never
   overflows, and the header is plain `position: sticky` against the page like
   every other table on the site.

   .is-wide stays for the one case that genuinely cannot fit: a signed-in
   reader who adds more than six columns through Edit Columns. They trade the
   sticky header for their columns, which is the right way round. */
.bq-sl-tablewrap { -webkit-overflow-scrolling: touch; }
.bq-sl-tablewrap.is-wide { overflow-x: auto; }

.bq-sl-table {
    width: 100%;
    border-collapse: collapse;
    /* Fixed layout is what makes the percentages binding and the table
       incapable of exceeding its wrapper. It also forces the widths onto
       <colgroup>: under fixed layout the geometry comes from the first row,
       and the first row here is the title band — one cell with a colspan — so
       widths written on th are silently discarded. That exact trap had made
       every column on /top-gainers equal-width before it was found. */
    table-layout: fixed;
    font-size: 13px;
}

/* ── THE STICKY HEADER ──
   Two real <tr>s in the table's own <thead>, each held with position:sticky
   at its own offset. Nothing is cloned and no width is ever synced in JS —
   which is the whole point: when a signed-in reader adds four columns through
   Edit Columns, the sticky header has four more columns at exactly the right
   widths, because it IS the header. See the note in the template.

   ONE LIGHT SURFACE ACROSS BOTH ROWS. The first version put the title row on
   navy, which read as a separate object dropped on top of the table rather
   than as its header, and was the only dark band on an otherwise light page.
   Both rows now share one tint and one bottom rule, so the stuck header reads
   as a single object with a heading line and a label line inside it.

   z-index: the title row sits ABOVE the column row, because the column row
   slides up under it as the page scrolls.

   background is not optional on a sticky th. With border-collapse:collapse a
   transparent header lets the rows show straight through it. */
.bq-sl-table thead th {
    position: sticky;
    top: calc(var(--sl-nav) + var(--sl-ttl));
    z-index: 2;
    padding: 8px 12px;
    background: var(--bq-panel-head, #f4f8fb);
    border-bottom: 2px solid var(--bq-line-strong);
    font-size: 10px; font-weight: 700; letter-spacing: .9px; text-transform: uppercase;
    color: var(--gray-500); text-align: left; white-space: nowrap;
}
.bq-sl-table thead th.bq-sl__num { text-align: right; }

/* The unit chip that used to sit in each numeric heading is gone: the suffix
   now rides on every value (bq_listicle_in_unit in bq-pages.php), because a
   heading scrolls away and a sorted or copied row has to carry its own
   magnitude. The rule stays only so a cached template still renders the chip
   as nothing rather than as unstyled text. */
.bq-sl__unit { display: none; }

/* ── Row one: revealed only when stuck ──
   Collapsed to nothing at rest. It says nothing the H1 two inches above it is
   not already saying, and a permanent second title bar is clutter; stuck, it
   is the only thing on screen naming the table being read. Same behaviour as
   the global layout's ticker bar.

   The height lives on an inner div rather than the th, because a th with
   height:0 and overflow:hidden is not reliable across engines — table cells
   negotiate their own height with the row. A div inside one does not. */
.bq-sl-table thead .bq-sl-thead-title th {
    top: var(--sl-nav);
    z-index: 3;
    padding: 0 14px;
    background: var(--bq-panel-head, #f4f8fb);
    border-bottom: 0;
}
.bq-sl-tt__inner {
    display: flex; align-items: center;
    height: 0; overflow: hidden;
    opacity: 0;
    transition: height .18s ease, opacity .14s ease;
}
.bq-sl-table.is-stuck .bq-sl-tt__inner { height: var(--sl-ttl); opacity: 1; }

.bq-sl-tt__name {
    font-size: 12.5px; font-weight: 700; letter-spacing: -.1px;
    text-transform: none; color: var(--bq-ink);
    white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.bq-sl-tt__meta {
    margin-left: 12px; flex-shrink: 0;
    font-size: 11px; font-weight: 400; letter-spacing: .2px;
    text-transform: none; color: var(--gray-500);
}
.bq-sl-tt__sep { margin: 0 7px; opacity: .55; }

/* --sl-ttl is 0 until the header is stuck, so the column row sits flush under
   the navbar at rest and drops by exactly the title row's height when it
   appears. One variable drives the collapse and the offset together, which is
   what stops the two disagreeing mid-transition. */
.bq-sl-page { --sl-ttl: 0px; }
.bq-sl-page:has(.bq-sl-table.is-stuck) { --sl-ttl: 40px; }

/* :has() is not universal. Without it the title row simply never expands and
   the column row stays flush under the navbar — the page loses a nicety, not
   a feature, which is the right way for this to degrade. */
@supports not selector(:has(*)) {
    .bq-sl-table.is-stuck .bq-sl-tt__inner { height: 0; opacity: 0; }
}

/* The sentinel is gone with the IntersectionObserver that watched it — see
   initStuck() in stock-lists.js for why that approach was abandoned. The rule
   stays only so a cached template still renders it as nothing. */
.bq-sl-sentinel { display: none; }

/* ROW GEOMETRY.
   This rule went missing in a refactor of the header block above — it sat
   between the two and was swallowed when the block was replaced wholesale.
   The symptom was rows with no padding at all, which is why the table looked
   broken while the header looked fine: the header carries its own padding,
   the body does not inherit any.

   7px matches .bq-tm-table on the movers pages, which is the table this one
   is a sibling of. */
.bq-sl-table td {
    padding: 7px 12px;
    border-bottom: 1px solid var(--bq-line);
    white-space: nowrap;
    vertical-align: middle;
}
.bq-sl-table tbody tr { transition: background-color .12s; }
.bq-sl-table tbody tr:hover { background: var(--bq-row-hover); }
.bq-sl-table tbody tr:last-child td { border-bottom: none; }

/* Minimums only — see the note at the top of this file for why the widths
   are not a frozen percentage set. Company is the one column allowed to
   take the slack and ellipse. */
/* ── COLUMN GEOMETRY: ON <col>, IN PERCENT ──
   Percent so the set always sums to 100 and the table exactly fills its
   wrapper at every width; on <col> because fixed layout reads widths there
   and, here, nowhere else (see .bq-sl-table above).

   The extras carry no width deliberately: there can be any number of them,
   and under fixed layout a column with no declared width takes an equal share
   of whatever the declared ones leave. One rule therefore covers zero extras
   and six without arithmetic anywhere. */
.bq-sl-table col.bq-sl__c-sym  { width: 8%;  }
.bq-sl-table col.bq-sl__c-co   { width: 18%; }
.bq-sl-table col.bq-sl__c-mcap { width: 10%; }
.bq-sl-table col.bq-sl__c-px   { width: 9%;  }
.bq-sl-table col.bq-sl__c-pct  { width: 9%;  }
.bq-sl-table col.bq-sl__c-y1   { width: 9%;  }
.bq-sl-table col.bq-sl__c-why  { width: 4%;  }
/* The extras DO get a width, unlike the first draft which left them to share
   the leftover. Sharing sounded elegant and was wrong: the seven fixed columns
   came to 88%, so four Edit Columns metrics divided the remaining 12% into
   44px each — too narrow for "6,088.00 Mn". At 8% each the fixed set plus four
   extras lands on 99%, plus six on 115% (columns then shrink proportionally,
   which is the correct degradation), and with no extras at all the undeclared
   33% is shared out and every column simply gets wider. */
.bq-sl-table col.bq-sl__c-extra { width: 8%; }
.bq-sl__c-why  { width: 38px; }

.bq-sl__sym a {
    font-family: var(--bq-mono); font-weight: 700; letter-spacing: .3px;
    color: var(--blue-primary); text-decoration: none;
}
.bq-sl__sym a:hover { color: var(--blue-darkest); text-decoration: underline; }

.bq-sl__co {
    max-width: 320px; overflow: hidden; text-overflow: ellipsis;
}
.bq-sl__co a { color: var(--gray-700); text-decoration: none; }
.bq-sl__co a:hover { color: var(--blue-primary); }

.bq-sl__num { text-align: right; font-family: var(--bq-mono); font-variant-numeric: tabular-nums; }
.bq-sl__mcap { color: var(--bq-ink); font-weight: 700; }
.bq-sl__px, .bq-sl__extra { color: var(--gray-700); }
.bq-sl__pct.is-up,   .bq-sl__y1.is-up   { color: var(--bq-green); }
.bq-sl__pct.is-down, .bq-sl__y1.is-down { color: var(--bq-red); }
/* 1Y is context beside today's move, so it is set a notch quieter — the eye
   should land on Chg% first. */
.bq-sl__y1 { font-size: 12.5px; opacity: .92; }

/* The secondary marker. A tag rather than a whole-row tint: a tinted row
   reads as a warning, and a company appearing here on its secondary
   classification is not an error — it is the classification working. */
.bq-sl-tag {
    display: inline-block; margin-left: 5px; vertical-align: 1px;
    font-family: var(--font-sans); font-size: 9px; font-weight: 700;
    letter-spacing: .4px; text-transform: uppercase;
    color: #b45309; background: #fff7ed;
    border: 1px solid #fed7aa; padding: 0 4px;
    cursor: help;
}

/* ── The reasoning trigger + its tooltip ──
   The reasoning used to open a full-width row beneath the company, which
   pushed every row below it down the page and made the table jump under the
   cursor. It is a tooltip now: it appears over the table and costs the layout
   nothing.

   THE TOOLTIP ITSELF IS A CHILD OF <body>, not of this cell — the table wrapper
   is overflow-x:auto and clips anything absolutely positioned inside it, which
   is precisely where a tooltip on the last column needs to escape to. See the
   block comment in assets/js/stock-lists.js. */
.bq-sl__why { text-align: right; }
.bq-sl-why-btn {
    width: 22px; height: 22px; padding: 0; border: 0; background: none;
    color: var(--gray-500); cursor: pointer; border-radius: 3px;
    display: inline-flex; align-items: center; justify-content: center;
    opacity: .4;
    transition: opacity .14s ease, color .14s ease, background .14s ease;
}
.bq-sl-why-btn svg { width: 14px; height: 14px; }
.bq-sl-table tbody tr:hover .bq-sl-why-btn { opacity: 1; }
.bq-sl-why-btn:hover, .bq-sl-why-btn.is-open { opacity: 1; color: var(--blue-primary); background: #eff6ff; }
.bq-sl-why-btn:focus-visible { opacity: 1; outline: 2px solid var(--blue-primary); outline-offset: 1px; }

/* The reason string lives here, in the document, read by crawlers and copied
   into the tooltip on demand. Visually hidden rather than display:none so it
   stays in the accessibility tree as the button's own description. */
.bq-sl-why__text {
    position: absolute; width: 1px; height: 1px;
    padding: 0; margin: -1px; overflow: hidden;
    clip: rect(0, 0, 0, 0); white-space: nowrap; border: 0;
}

.bq-sl-tip {
    position: fixed; z-index: 900;
    width: 340px; max-width: calc(100vw - 24px);
    padding: 12px 14px 13px;
    background: var(--bq-ink, #0b1f2e);
    color: #e8eef4;
    box-shadow: 0 10px 30px rgba(3, 18, 30, .28), 0 2px 6px rgba(3, 18, 30, .18);
    /* Not interactive: it must never sit between the cursor and the button it
       is describing, or hovering it would fight the mouseout that closes it. */
    pointer-events: none;
    animation: bq-sl-tip-in .12s ease-out;
}
.bq-sl-tip[hidden] { display: none; }
@keyframes bq-sl-tip-in { from { opacity: 0; transform: translateY(3px); } }

.bq-sl-tip__head {
    display: flex; align-items: baseline; gap: 9px;
    margin-bottom: 7px; padding-bottom: 7px;
    border-bottom: 1px solid rgba(255,255,255,.13);
}
.bq-sl-tip__sym {
    font-family: var(--bq-mono); font-size: 12.5px; font-weight: 700;
    letter-spacing: .3px; color: #7cc0f0;
}
.bq-sl-tip__rel {
    font-size: 9.5px; font-weight: 700; letter-spacing: .8px; text-transform: uppercase;
    color: rgba(255,255,255,.5);
}
.bq-sl-tip__body {
    margin: 0;
    font-size: 12.5px; line-height: 1.62; color: #dbe5ee;
}

/* The byline. Quiet enough that it never competes with the sentence above it,
   present enough that anyone screenshotting a description carries the source
   with it. */
.bq-sl-tip__src {
    display: block; margin-top: 9px; padding-top: 8px;
    border-top: 1px solid rgba(255,255,255,.12);
    font-size: 10px; font-weight: 600; letter-spacing: .04em;
    color: rgba(255,255,255,.42);
}

/* Drawn as a rotated square rather than a border triangle, so one element
   serves both placements — JS just flips .is-below. */
.bq-sl-tip__arrow {
    position: absolute; bottom: -5px;
    width: 10px; height: 10px; margin-left: -5px;
    background: var(--bq-ink, #0b1f2e);
    transform: rotate(45deg);
}
.bq-sl-tip.is-below .bq-sl-tip__arrow { bottom: auto; top: -5px; }

@media (prefers-reduced-motion: reduce) {
    .bq-sl-tip { animation: none; }
}

/* ── Sort control ──
   Every figure column carries one, so the affordance stays quiet: the caret
   appears only on the column actually sorted. */
.bq-sl__th--sort { cursor: pointer; user-select: none; transition: color .12s; }
.bq-sl__th--sort:hover { color: var(--blue-primary); }
.bq-sl__th--sort:focus-visible { outline: 2px solid var(--blue-primary); outline-offset: -2px; }
.bq-sl__th--sort.is-sorted { color: var(--blue-primary); }
.bq-sl__caret { display: inline-block; width: 0; height: 0; margin-left: 5px; vertical-align: middle; opacity: 0; transition: opacity .12s; }
.bq-sl__th--sort.is-desc .bq-sl__caret { opacity: 1; border-top: 4px solid currentColor; border-left: 4px solid transparent; border-right: 4px solid transparent; }
.bq-sl__th--sort.is-asc  .bq-sl__caret { opacity: 1; border-bottom: 4px solid currentColor; border-left: 4px solid transparent; border-right: 4px solid transparent; }

.bq-sl-empty { margin: 0; padding: 34px 14px; text-align: center; color: var(--gray-500); font-size: 14px; }

/* A LEGEND, not a paragraph.
   What was here was five sentences of classification theory set as body copy
   under a 200-row table. Nobody read it, and the one thing in it a reader
   actually needed — what the "2nd" chip means — was in the middle of the
   third sentence. Three items, each on its own line at a phone width and
   inline with separators above it, so each fact is findable rather than
   merely present. */
.bq-sl-legend {
    display: flex; flex-wrap: wrap; align-items: center;
    gap: 8px 22px;
    margin: 0; padding: 11px 14px 12px;
    list-style: none;
    border-top: 1px solid var(--bq-line);
    background: #fcfdfe;
    font-size: 12px; line-height: 1.5; color: var(--gray-500);
}
.bq-sl-legend li { display: flex; align-items: center; gap: 7px; position: relative; }
.bq-sl-legend li + li::before {
    content: ""; position: absolute; left: -12px; top: 50%;
    width: 3px; height: 3px; margin-top: -1px;
    border-radius: 50%; background: var(--bq-line-strong);
}
.bq-sl-legend .bq-sl-tag { cursor: default; margin-left: 0; vertical-align: baseline; }

/* =====================================================================
   RELATED
   ===================================================================== */
.bq-sl-related { margin-top: 20px; }
.bq-sl-related__h {
    margin: 0 0 12px;
    font-size: 13px; font-weight: 700; letter-spacing: .9px; text-transform: uppercase;
    color: var(--gray-500);
}
.bq-sl-related__grid {
    display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 10px;
}
.bq-sl-related__card {
    display: flex; align-items: baseline; justify-content: space-between; gap: 10px;
    padding: 12px 14px;
    background: var(--white);
    border: 1px solid var(--bq-line-strong);
    text-decoration: none;
    transition: border-color .14s ease, box-shadow .14s ease;
}
.bq-sl-related__card:hover { border-color: var(--blue-primary); box-shadow: 0 2px 8px rgba(0,42,69,.07); }
.bq-sl-related__name { font-size: 13.5px; font-weight: 700; color: var(--bq-ink); min-width: 0; }
.bq-sl-related__card:hover .bq-sl-related__name { color: var(--blue-primary); }
.bq-sl-related__n {
    font-family: var(--bq-mono); font-size: 11px; color: var(--gray-500);
    white-space: nowrap; flex-shrink: 0;
}
.bq-sl-related__all {
    display: inline-block; margin-top: 12px;
    font-size: 12.5px; font-weight: 700; color: var(--blue-primary); text-decoration: none;
}
.bq-sl-related__all::after { content: " \2192"; }
.bq-sl-related__all:hover { text-decoration: underline; }

/* =====================================================================
   FAQ  +  BQ-MICS   —  the closing band
   -----------------------------------------------------------------
   Two halves doing two different jobs, which is why they are side by
   side rather than stacked:

     LEFT  answers questions about THIS list, and is the source of the
           page's FAQPage markup.
     RIGHT is the only place on the page that talks about BQ-MICS, and
           its job is NOT to teach the methodology — it is to send the
           reader to /industry-classification, where the methodology
           lives, and to state that the taxonomy is ours.

   The methodology paragraph that used to sit under the table is gone.
   Five sentences of classification theory set as grey body copy under a
   200-row table is a paragraph nobody finishes, and it was competing
   with the page's own data for attention while converting no one.
   ===================================================================== */
.bq-sl-foot {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 16px;
    margin-top: 20px;
    align-items: start;
}

.bq-sl-faq {
    background: var(--white);
    border: 1px solid var(--bq-line-strong);
    padding: 18px 20px 8px;
}
.bq-sl-faq__h {
    margin: 0 0 6px;
    font-size: 13px; font-weight: 700; letter-spacing: .9px; text-transform: uppercase;
    color: var(--gray-500);
}
.bq-sl-faq__item { border-top: 1px solid var(--bq-line); }
.bq-sl-faq__item summary {
    list-style: none; cursor: pointer;
    padding: 13px 26px 13px 0; position: relative;
    font-size: 14px; font-weight: 700; color: var(--bq-ink);
    transition: color .14s;
}
.bq-sl-faq__item summary::-webkit-details-marker { display: none; }
.bq-sl-faq__item summary:hover { color: var(--blue-primary); }
.bq-sl-faq__item summary:focus-visible { outline: 2px solid var(--blue-primary); outline-offset: 2px; }
.bq-sl-faq__item summary::after {
    content: ""; position: absolute; right: 4px; top: 50%;
    width: 7px; height: 7px; margin-top: -5px;
    border-right: 2px solid var(--gray-500); border-bottom: 2px solid var(--gray-500);
    transform: rotate(45deg); transition: transform .16s ease;
}
.bq-sl-faq__item[open] summary::after { transform: rotate(-135deg); margin-top: -2px; }
.bq-sl-faq__item p {
    margin: 0 0 15px; padding-right: 26px;
    font-size: 13.5px; line-height: 1.65; color: var(--gray-700);
}

/* ── BQ-MICS ──
   A LIGHT card, matching the FAQ beside it. The first version was navy, which
   made the heaviest object on the page a marketing panel sitting under the
   data it was describing — and this page has no other dark surface for it to
   belong to. The accent is a rail and a button, not a ground. */
.bq-sl-mics {
    position: relative; overflow: hidden;
    padding: 22px 24px 24px;
    background: var(--white);
    border: 1px solid var(--bq-line-strong);
    border-top: 3px solid var(--blue-primary);
}
.bq-sl-mics__eyebrow {
    display: block; margin-bottom: 9px;
    font-size: 10px; font-weight: 700; letter-spacing: 1.4px; text-transform: uppercase;
    color: var(--blue-primary);
}
.bq-sl-mics__h {
    margin: 0 0 10px;
    font-size: 19px; font-weight: 700; line-height: 1.25; letter-spacing: -.3px;
    color: var(--bq-ink);
}
/* NO max-width. The 48ch cap was copied from the prose pages, where a
   measure that tight is right because the column is 1,120px wide. Here the
   card is half of a 1,500px grid — about 740px — so 48ch stopped the
   paragraph at roughly half of it and left the other half empty, which is
   what made the box look unfinished. The card's own padding is the measure
   now, and it narrows with the card at every breakpoint. */
.bq-sl-mics__p {
    margin: 0 0 18px;
    font-size: 14px; line-height: 1.7; color: var(--gray-700);
}

.bq-sl-mics__stats {
    display: flex; gap: 0;
    margin-bottom: 20px; padding: 14px 0;
    border-top: 1px solid var(--bq-line);
    border-bottom: 1px solid var(--bq-line);
}
/* The three figures spread across the card rather than bunching at its left
   edge — same reason as the paragraph above. flex:1 makes them share the
   width whatever the card is. */
.bq-sl-mics__stats > div {
    flex: 1; min-width: 0;
    padding-right: 20px;
    border-right: 1px solid var(--bq-line);
}
.bq-sl-mics__stats > div:last-child { padding-right: 0; border-right: none; }
.bq-sl-mics__num {
    display: block;
    font-family: var(--bq-mono); font-size: 21px; font-weight: 700; line-height: 1.1;
    color: var(--bq-ink); font-variant-numeric: tabular-nums;
}
.bq-sl-mics__lbl {
    display: block; margin-top: 4px;
    font-size: 10px; font-weight: 700; letter-spacing: .8px; text-transform: uppercase;
    color: var(--gray-500);
}

/* The one thing this panel exists to be clicked, and now the only saturated
   colour on the card. */
.bq-sl-mics__cta {
    display: inline-block;
    padding: 10px 20px;
    background: var(--blue-primary); color: var(--white);
    font-size: 13px; font-weight: 700; letter-spacing: .2px;
    text-decoration: none;
    transition: background .14s ease, transform .14s ease;
}
.bq-sl-mics__cta::after { content: " \2192"; }
.bq-sl-mics__cta:hover { background: var(--blue-darkest); transform: translateX(2px); }
.bq-sl-mics__cta:focus-visible { outline: 2px solid var(--blue-primary); outline-offset: 2px; }

.bq-sl-mics__legal {
    margin: 18px 0 0;
    font-size: 12px; line-height: 1.65; color: var(--gray-500);
}
.bq-sl-mics__legal a { color: var(--blue-primary); text-decoration: underline; text-underline-offset: 2px; }
.bq-sl-mics__legal a:hover { color: var(--blue-darkest); }

/* =====================================================================
   INDEX PAGE
   ===================================================================== */
.bq-sl-index-body { padding: 44px 0 64px; background: var(--white); }

.bq-sl-idxbar {
    display: flex; align-items: center; justify-content: space-between;
    gap: 14px; flex-wrap: wrap;
    padding-bottom: 18px; margin-bottom: 30px;
    border-bottom: 2px solid var(--blue-darkest);
}
.bq-sl-search--wide input { width: 320px; }
.bq-sl-idxbar__count {
    font-family: var(--bq-mono); font-size: 12px; color: var(--gray-500);
    font-variant-numeric: tabular-nums;
}

.bq-sl-sector { margin-bottom: 34px; }
.bq-sl-sector[hidden] { display: none; }
.bq-sl-sector__head {
    display: flex; align-items: baseline; gap: 12px;
    padding-bottom: 9px; margin-bottom: 13px;
    border-bottom: 1px solid var(--bq-line-strong);
}
.bq-sl-sector__head h2 {
    margin: 0; font-size: 17px; font-weight: 700; letter-spacing: -.2px; color: var(--bq-ink);
}
.bq-sl-sector__head h2 a { color: inherit; text-decoration: none; }
.bq-sl-sector__head h2 a:hover { color: var(--blue-primary); }
.bq-sl-sector__n { font-size: 11.5px; color: var(--gray-500); font-variant-numeric: tabular-nums; }

/* Chips rather than a grid of cards. Two hundred lists as cards is a page
   nobody scrolls to the bottom of; as chips it is scannable in one pass,
   and the count beside each name is the only thing anyone compares them
   on. */
.bq-sl-chips { display: flex; flex-wrap: wrap; gap: 8px; }
.bq-sl-chip {
    display: inline-flex; align-items: baseline; gap: 8px;
    padding: 7px 12px;
    background: var(--white);
    border: 1px solid var(--bq-line-strong);
    text-decoration: none;
    transition: border-color .14s ease, background .14s ease;
}
.bq-sl-chip[hidden] { display: none; }
.bq-sl-chip:hover { border-color: var(--blue-primary); background: #f5faff; }
.bq-sl-chip__name { font-size: 13.5px; color: var(--bq-ink); }
.bq-sl-chip:hover .bq-sl-chip__name { color: var(--blue-primary); }
.bq-sl-chip__n {
    font-family: var(--bq-mono); font-size: 11px; color: var(--gray-500);
    font-variant-numeric: tabular-nums;
}

/* Visually hidden, still read aloud. */
.bq-sl-page .screen-reader-text {
    position: absolute; width: 1px; height: 1px;
    padding: 0; margin: -1px; overflow: hidden;
    clip: rect(0, 0, 0, 0); white-space: nowrap; border: 0;
}

/* =====================================================================
   RESPONSIVE
   ===================================================================== */
@media (max-width: 1100px) {
    .bq-sl-related__grid { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}

@media (max-width: 960px) {
    /* The closing band stacks: FAQ first, because a reader who got this far
       is asking about the list, not about us. */
    .bq-sl-foot { grid-template-columns: 1fr; }
}

@media (max-width: 900px) {
    /* Two stats a row rather than four squeezed columns. The labels break
       first — "Combined market cap" in a 90px column ellipses, and a
       truncated label is worse than a taller strip. */
    .bq-sl-stats { grid-template-columns: 1fr 1fr; }
    .bq-sl-stat:nth-child(3) { border-left: none; }
    .bq-sl-stat:nth-child(n+3) { border-top: 1px solid var(--bq-line); }
    .bq-sl-related__grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

@media (max-width: 680px) {
    .bq-sl { padding: 30px 0 40px; }
    .bq-sl-head { padding: 16px 14px 15px; margin-bottom: 10px; }
    .bq-sl-head h1 { font-size: 22px; }
    .bq-sl-lede { font-size: 13.5px; }

    /* The toolbar stacks; both buttons share the row. */
    .bq-sl-bar { flex-direction: column; align-items: stretch; gap: 8px; }
    .bq-sl-bar__left:empty { display: none; }
    .bq-sl-bar__right { justify-content: stretch; }
    .bq-sl-btn { flex: 1; justify-content: center; }

    /* The title bar drops its meta line before it drops the name — which
       list you are in matters more than how many companies are in it. */
    .bq-sl-tt__meta { display: none; }

    /* 1Y goes first, then the reader's own metric columns, then Price. Today's
       move is what someone opened a list on a phone to see; a column set
       chosen at a desk is not what they came here for; and these lists are
       ranked by market cap, so Mkt Cap outranks Price for the last slot.

       HIDING A COLUMN MEANS HIDING ITS <col> TOO. Under fixed layout
       `display: none` on a cell does not remove the column — it keeps its
       share of the width and draws nothing in it. That is precisely how
       /top-gainers ended up with four visible columns crammed into 188px of a
       375px screen while half the row sat blank. The <col> is named separately
       from the cells because un-hiding them takes two different values: a cell
       returns to `table-cell`, a column to `table-column`. */
    .bq-sl__y1,    .bq-sl-table thead th.bq-sl__c-y1,
    .bq-sl-table col.bq-sl__c-y1 { display: none; }
    .bq-sl__extra, .bq-sl-table thead th.bq-sl__c-extra,
    .bq-sl-table col.bq-sl__c-extra { display: none; }
    .bq-sl__px,    .bq-sl-table thead th.bq-sl__c-px,
    .bq-sl-table col.bq-sl__c-px { display: none; }

    /* The four that remain, plus the reason chip, summing to 100. */
    .bq-sl-table col.bq-sl__c-sym  { width: 20%; }
    .bq-sl-table col.bq-sl__c-co   { width: 38%; }
    .bq-sl-table col.bq-sl__c-mcap { width: 20%; }
    .bq-sl-table col.bq-sl__c-pct  { width: 15%; }
    .bq-sl-table col.bq-sl__c-why  { width: 7%;  }
    .bq-sl-table { font-size: 12.5px; }
    .bq-sl-table thead th, .bq-sl-table td { padding: 8px 10px; }
    .bq-sl-table thead .bq-sl-thead-title th { padding: 0 12px; }
    .bq-sl__co { max-width: 180px; }

    /* Touch has no hover, so the trigger is always visible. */
    .bq-sl-why-btn { opacity: .8; }

    .bq-sl-related__grid { grid-template-columns: 1fr; }
    .bq-sl-faq { padding: 16px 14px 6px; }
    .bq-sl-mics { padding: 20px 18px 22px; }
    .bq-sl-mics__h { font-size: 18px; }
    .bq-sl-mics__stats > div { padding-right: 18px; margin-right: 18px; }
    .bq-sl-mics__cta { display: block; text-align: center; }

    .bq-sl-index-body { padding: 30px 0 44px; }
    .bq-sl-sector__head h2 { font-size: 16px; }
}

@media (max-width: 520px) {
    /* Edge to edge, same as the movers table at this width: with a mono
       numeric table there is no width left to spend on a 24px gutter. */
    .bq-sl-page .bq-main .bq-sl .bq-container { padding: 0 12px; }
    .bq-sl-panel, .bq-sl-head, .bq-sl-faq, .bq-sl-mics {
        margin-left: -12px; margin-right: -12px;
        border-left: none; border-right: none;
    }
    .bq-sl-table thead th, .bq-sl-table td { padding: 8px; }

    /* The legend goes to one item per line — three facts wrapping into each
       other with dot separators is the unreadable thing this replaced. */
    .bq-sl-legend { flex-direction: column; align-items: flex-start; gap: 6px; }
    .bq-sl-legend li + li::before { display: none; }

    .bq-sl-tip { width: auto; left: 12px !important; right: 12px; }
    /* Centred under a card that now spans the screen, the arrow would point
       at the wrong column. Hide it rather than lie about the source. */
    .bq-sl-tip__arrow { display: none; }
}

/* Coarse pointers get the trigger permanently, at every width — a touch
   device with a wide viewport hovers no more than a phone does. */
@media (hover: none), (pointer: coarse) {
    .bq-sl-why-btn { opacity: .8; }
}


/* =====================================================================
   SCROLL TO TOP
   -----------------------------------------------------------------
   These pages run to 500 rows plus an FAQ, so the way back up is a real
   journey. Hidden until there is something to scroll back from — a
   permanent button floating over a short page is chrome advertising a
   problem the reader does not have.

   Fixed, bottom-right, clear of the table's own horizontal scrollbar.
   ===================================================================== */
.bq-sl-top {
    position: fixed; right: 24px; bottom: 28px; z-index: 800;
    width: 42px; height: 42px; padding: 0;
    display: flex; align-items: center; justify-content: center;
    background: var(--white);
    color: var(--blue-primary);
    border: 1px solid var(--bq-line-strong);
    box-shadow: 0 4px 14px rgba(0, 42, 69, .12);
    cursor: pointer;

    /* Fades AND lifts into place, and is pointer-events:none while hidden so
       an invisible button can never swallow a click meant for the page. */
    opacity: 0; transform: translateY(8px); pointer-events: none;
    transition: opacity .2s ease, transform .2s ease, background .14s ease, border-color .14s ease;
}
.bq-sl-top.is-on { opacity: 1; transform: translateY(0); pointer-events: auto; }
.bq-sl-top:hover { background: #f5faff; border-color: var(--blue-primary); }
.bq-sl-top:focus-visible { outline: 2px solid var(--blue-primary); outline-offset: 2px; }
.bq-sl-top svg { width: 17px; height: 17px; }

@media (max-width: 680px) {
    .bq-sl-top { right: 14px; bottom: 18px; width: 38px; height: 38px; }
}
@media (prefers-reduced-motion: reduce) {
    .bq-sl-top { transition: opacity .2s ease; transform: none; }
}
