/* ============================================================================
   BQ WATCHLIST — embeddable widget
   ----------------------------------------------------------------------------
   Self-sufficient but deferential. Every token below falls back through the
   host page's custom properties first:

       var(--bq-line, #e7edf2)

   so dropped into the homepage it picks up that page's hairlines, greens and
   reds and looks native in the panel grid; dropped anywhere else it still
   renders correctly on its own defaults. It loads no webfont — figures use
   whatever mono stack the host defines, falling back to the system one.

   Everything is scoped under .bq-wlw. Nothing here styles a bare element
   selector, because this markup lands inside pages with their own CSS.
   ============================================================================ */

.bq-wlw {
  --wlw-surface:  var(--white, #ffffff);
  --wlw-surface-2:var(--bq-surface-2, #fafbfc);
  --wlw-line:     var(--bq-line, #e7edf2);
  --wlw-line-2:   var(--bq-line-strong, #d5dee6);
  --wlw-text:     var(--bq-text, #0b1f2e);
  --wlw-text-2:   var(--gray-700, #475569);
  --wlw-text-3:   var(--gray-500, #94a3b8);
  --wlw-pos:      var(--bq-green, #15803d);
  --wlw-pos-soft: var(--bq-green-soft, rgba(21,128,61,.10));
  --wlw-neg:      var(--bq-red, #c5331f);
  --wlw-neg-soft: var(--bq-red-soft, rgba(197,51,31,.09));
  --wlw-accent:   var(--blue-primary, #0369a1);
  --wlw-accent-soft: rgba(3, 105, 161, .08);
  --wlw-mono:     var(--bq-mono, ui-monospace, SFMono-Regular, Menlo, Consolas, monospace);
  --wlw-radius:   6px;
  --wlw-t:        140ms cubic-bezier(.22,.61,.36,1);

  display: flex;
  flex-direction: column;
  min-width: 0;
  color: var(--wlw-text);
}
.bq-wlw *, .bq-wlw *::before, .bq-wlw *::after { box-sizing: border-box; }

/* Only when the host has NOT supplied its own panel chrome via the `class`
   arg. :where() keeps this at zero specificity so a host class always wins. */
.bq-wlw:where(:not([class*="bq-panel"])) {
  background: var(--wlw-surface);
  border: 1px solid var(--wlw-line-2);
  border-radius: 8px;
  overflow: hidden;
}

/* ── HEAD ─────────────────────────────────────────────────────────────────── */

/* Matches the host's own panel header (bq-pages .bq-panel__head): same 11/14
   padding, same tinted bar, same hairline — so the widget's header sits on the
   exact line as Indices and Advance/Decline beside it. */
.bq-wlw__head {
  display: flex; align-items: center; justify-content: space-between; gap: 10px;
  padding: 11px 14px;
  background: var(--bq-panel-head, transparent);
  border-bottom: 1px solid var(--wlw-line-2);
  flex-shrink: 0;
}
/* 12px / 700 / .9px tracking / uppercase — copied from .bq-panel__title so
   WATCHLIST reads identically to INDICES and ADVANCE / DECLINE. The markup
   still says "Watchlist" in mixed case; the caps are presentational, which
   keeps the accessible name and the page title readable. */
.bq-wlw__title {
  display: inline-flex; align-items: center; gap: 8px;
  font-size: 12px; font-weight: 700; letter-spacing: .9px;
  text-transform: uppercase;
  color: var(--bq-ink, var(--wlw-text));
}
.bq-wlw__dot { width: 7px; height: 7px; border-radius: 50%; background: var(--wlw-accent); flex-shrink: 0; }
.bq-wlw__count {
  font-family: var(--wlw-mono); font-size: 10.5px; font-weight: 700;
  color: var(--wlw-text-3); background: var(--wlw-surface-2);
  border: 1px solid var(--wlw-line); border-radius: 999px;
  padding: 1px 7px; font-variant-numeric: tabular-nums;
}
.bq-wlw__count:empty { display: none; }
.bq-wlw__meta { font-size: 10.5px; color: var(--wlw-text-3); font-variant-numeric: tabular-nums; }
.bq-wlw__tag {
  font-size: 9.5px; font-weight: 700; letter-spacing: .07em; text-transform: uppercase;
  color: var(--wlw-accent); background: var(--wlw-accent-soft);
  border: 1px solid var(--wlw-line-2); border-radius: 999px; padding: 2px 7px;
}

/* ── BODY / TABLE ─────────────────────────────────────────────────────────── */

/* overflow-x is pinned to hidden ON PURPOSE. Setting only overflow-y:auto makes
   the other axis compute to auto too (CSS overflow spec: a non-visible value on
   one axis promotes `visible` on the other to `auto`), which is where the stray
   horizontal scrollbar under the rows came from. The table below can no longer
   exceed its container, so nothing is being clipped away — this just stops the
   bar reappearing if a future column is added carelessly.

   display:flex is what lets the empty state stretch to fill a tall panel
   instead of sitting in a band at the top. */
.bq-wlw__body {
  flex: 1 1 auto; min-height: 0;
  overflow-y: auto; overflow-x: hidden;
  display: flex; flex-direction: column;
}

/* table-layout:fixed is the actual fix for the scrollbar: under auto layout a
   long company name sets a minimum width for its column and drags the whole
   table wider than the panel, and text-overflow never gets a chance to bite.
   Fixed layout takes the widths below as final, so the ellipsis works. */
.bq-wlw__table { width: 100%; border-collapse: collapse; table-layout: fixed; flex: 0 0 auto; }
.bq-wlw__table[hidden] { display: none; }

/* COLUMN GEOMETRY — widths are content + that column's own padding, worked out
   at the 12px mono the figures use (~7.25px per character):
   sym  "BRK.B"     5ch ≈ 36 + 18 padding = 54  -> 74  (room for 7ch)
   px   "12,345.67" 9ch ≈ 65 + 16 padding = 81  -> 82
   pct  "+123.45%"  8ch ≈ 58 +  9 padding = 67  -> 74
   act  22px button +  0 +  6 padding      = 28  -> 31
   Total 261 of ~348, leaving ~87 for the company name.

   pct and act are FROZEN at 74 and 31. Every figure here is right-aligned, so
   the price sits at (table width - pct - act - its own right padding):
   narrowing pct would shift the price even though pct is not its column. That
   is why widening `co` is paid for out of PRICE's width alone — trimming price
   pulls only its own LEFT edge inward, handing the space to the auto-width
   company column while price and Chg% stay exactly where they were.

   The headroom is deliberate — mono metrics differ per font stack, and the
   host page picks the font.
   These MUST be read together with the padding rules further down: a width that
   looks generous is still a crop once the cell's own padding is subtracted,
   which is exactly how Chg% ended up truncated. */
.bq-wlw__th--sym { width: 74px; }
.bq-wlw__th--px  { width: 82px; }
.bq-wlw__th--pct { width: 74px; }
.bq-wlw__th--act { width: 31px; }
/* Every cell clips rather than pushes. */
.bq-wlw__table th, .bq-wlw__table td { overflow: hidden; text-overflow: ellipsis; }

.bq-wlw__th {
  position: sticky; top: 0; z-index: 1;
  background: var(--wlw-surface);
  border-bottom: 1px solid var(--wlw-line);
  padding: 7px 12px;
  font-size: 9.5px; font-weight: 700; letter-spacing: .07em; text-transform: uppercase;
  color: var(--wlw-text-3); text-align: left; white-space: nowrap;
}
.bq-wlw__th--num { text-align: right; }
.bq-wlw__th.is-sortable { cursor: pointer; user-select: none; transition: color var(--wlw-t); }
.bq-wlw__th.is-sortable:hover { color: var(--wlw-text-2); }
.bq-wlw__th.is-sorted { color: var(--wlw-accent); }
/* The caret exists only once a column is sorted, so the header row stays quiet
   instead of carrying four permanent arrows. */
.bq-wlw__caret { display: inline-block; margin-left: 4px; }
.bq-wlw__th.is-sorted .bq-wlw__caret {
  width: 0; height: 0; vertical-align: middle;
  border-left: 3px solid transparent; border-right: 3px solid transparent;
}
.bq-wlw__th.is-sorted.is-asc  .bq-wlw__caret { border-bottom: 4px solid currentColor; }
.bq-wlw__th.is-sorted.is-desc .bq-wlw__caret { border-top: 4px solid currentColor; }

.bq-wlw__table tbody tr { transition: background var(--wlw-t); }
.bq-wlw__table tbody tr:hover { background: var(--wlw-surface-2); }
.bq-wlw__table tbody td {
  padding: 8px 12px;
  border-bottom: 1px solid var(--wlw-line);
  font-size: 12.5px;
  vertical-align: middle;
}
.bq-wlw__table tbody tr:last-child td { border-bottom: 0; }

.bq-wlw__sym a {
  font-family: var(--wlw-mono); font-size: 12px; font-weight: 700;
  color: var(--wlw-accent); text-decoration: none; letter-spacing: -.01em;
}
.bq-wlw__sym a:hover { text-decoration: underline; }
/* max-width is gone: it did nothing under table-layout:fixed except contradict
   the column width, which is the real constraint. The font-size lives with the
   padding overrides below — at this specificity it would lose to
   `.bq-wlw__table tbody td`. */
.bq-wlw__co {
  color: var(--wlw-text-3);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
/* On desktop the anchor is invisible as an anchor: the symbol next to it is
   the obvious click target, so this stays plain grey text and only picks up
   its link affordance on hover. */
.bq-wlw__co a { color: inherit; text-decoration: none; }
.bq-wlw__table tbody tr:hover .bq-wlw__co a { color: var(--wlw-accent); }
.bq-wlw__num {
  text-align: right; font-family: var(--wlw-mono); font-size: 12px;
  font-variant-numeric: tabular-nums; white-space: nowrap;
}
.bq-wlw .is-pos { color: var(--wlw-pos); }
.bq-wlw .is-neg { color: var(--wlw-neg); }
.bq-wlw .is-flat { color: var(--wlw-text-3); }

/* ── PER-COLUMN PADDING ───────────────────────────────────────────────────── */
/* These come AFTER `.bq-wlw__table tbody td { padding: 8px 12px }` and are
   written as `table td.x` on purpose. An earlier attempt used a bare `.x`,
   which is specificity (0,1,0) against that rule's (0,2,1) — so the shorthand
   won, every override was silently dead, and the 24px gap between % and the
   cross survived two rounds of "fixes". Element+2 classes beats it. */
/* Symbol keeps its outer margin but gives up the inner one — the gap it used
   to hold belongs to the company name. */
.bq-wlw__table th.bq-wlw__th--sym,
.bq-wlw__table td.bq-wlw__sym      { padding-left: 12px; padding-right: 6px; }
.bq-wlw__table th.bq-wlw__th--co,
.bq-wlw__table td.bq-wlw__co       { padding-left: 8px; padding-right: 6px; }
/* 12px to match the symbol beside it — the pair reads as one unit, and the
   smaller face fits about another character and a half of name. */
.bq-wlw__table td.bq-wlw__co       { font-size: 12px; }

/* padding-right stays 12px so the price figure does NOT move; only the left
   side is trimmed, which widens the company column's usable text area. */
.bq-wlw__table th.bq-wlw__th--px,
.bq-wlw__table td.bq-wlw__num--px  { padding-left: 4px; padding-right: 12px; }

/* 3px is the whole gap between the % figure and the cross. */
.bq-wlw__table th.bq-wlw__th--pct,
.bq-wlw__table td.bq-wlw__num--pct { padding-left: 6px; padding-right: 3px; }

.bq-wlw__table th.bq-wlw__th--act,
.bq-wlw__table td.bq-wlw__act      { padding-left: 0; padding-right: 6px; }

.bq-wlw__act { text-align: right; }
/* Hidden until the row is hovered — but always reachable by keyboard, and
   always visible on touch (see the coarse-pointer rule at the end). */
.bq-wlw__del {
  width: 22px; height: 22px; padding: 0; border: 0; background: none;
  border-radius: 4px; cursor: pointer; color: var(--wlw-text-3);
  display: inline-flex; align-items: center; justify-content: center;
  opacity: 0; transition: opacity var(--wlw-t), color var(--wlw-t), background var(--wlw-t);
}
.bq-wlw__del svg { width: 12px; height: 12px; }
.bq-wlw__table tbody tr:hover .bq-wlw__del,
.bq-wlw__del:focus-visible { opacity: 1; }
.bq-wlw__del:hover { color: var(--wlw-neg); background: var(--wlw-neg-soft); }

/* ── THE TICK FLASH ───────────────────────────────────────────────────────── */
/* Applied only to cells whose value actually changed on a poll. The one piece
   of motion in the widget, so movement always means "this number just moved". */
@keyframes bq-wlw-up {
  0%   { background-color: var(--wlw-pos-soft); }
  100% { background-color: transparent; }
}
@keyframes bq-wlw-down {
  0%   { background-color: var(--wlw-neg-soft); }
  100% { background-color: transparent; }
}
.bq-wlw__flash-up   { animation: bq-wlw-up 1100ms ease-out; }
.bq-wlw__flash-down { animation: bq-wlw-down 1100ms ease-out; }

/* ── STATES ───────────────────────────────────────────────────────────────── */

/* Fills the panel rather than sitting in a band at the top: flex:1 claims the
   leftover height and the content centres in it, so a tall sidebar does not end
   in a large blank area below the message. */
.bq-wlw__state {
  position: relative;
  flex: 1 1 auto;
  display: flex; flex-direction: column;
  align-items: center; justify-content: center;
  padding: 0 16px; text-align: center;
  min-height: 260px;
  overflow: hidden;
}
/* The error state has no ghost blocks to space it out, so it keeps the padding
   the empty state hands to its ghosts instead. */
.bq-wlw__state--err { padding: 26px 16px; }
.bq-wlw__state[hidden] { display: none; }

/* No background wash — the ghost rows ARE the texture. */
.bq-wlw__state-inner {
  position: relative; z-index: 1;
  max-width: 260px;
  flex: 0 0 auto;
  padding: 4px 0;
}
.bq-wlw__state-h { font-size: 13.5px; font-weight: 700; margin: 0; }
.bq-wlw__state-p { font-size: 11.5px; color: var(--wlw-text-3); margin: 5px 0 0; line-height: 1.5; }
.bq-wlw__state--err p { font-size: 12px; color: var(--wlw-neg); margin: 0 0 10px; }

.bq-wlw__state-icon {
  width: 40px; height: 40px; margin: 0 auto 12px;
  display: flex; align-items: center; justify-content: center;
  border-radius: 10px;
  color: var(--wlw-accent); background: var(--wlw-accent-soft);
  border: 1px solid var(--wlw-line-2);
}
.bq-wlw__state-icon svg { width: 20px; height: 20px; }

/* The ghost sketch — two blocks in normal flow, above and below the message.
   Each fades out as it approaches the message, so the rows are solid at the
   panel edges and gone by the time they reach the copy.

   The top block is deliberately the SHORTER of the two (0.8 vs 1.2): that is
   what puts the message above centre, with no margin hacks and no percentage
   padding resolving against the wrong axis. */
.bq-wlw__ghost {
  z-index: 0;
  align-self: stretch;
  display: flex; flex-direction: column;
  overflow: hidden;
  pointer-events: none;
  min-height: 0;
}
.bq-wlw__ghost--top {
  flex-grow: 0.8; flex-shrink: 1; flex-basis: 0;
  justify-content: flex-start;
  -webkit-mask-image: linear-gradient(to bottom, #000 0%, rgba(0,0,0,.45) 55%, transparent 100%);
          mask-image: linear-gradient(to bottom, #000 0%, rgba(0,0,0,.45) 55%, transparent 100%);
}
/* Mirrored, not re-authored. scaleY(-1) flips the rows AND their mask, so this
   block fades upward toward the message and reads as the reflection of the top
   one — which is the whole point of it being the same sketch inverted. */
.bq-wlw__ghost--bottom {
  flex-grow: 1.2; flex-shrink: 1; flex-basis: 0;
  justify-content: flex-start;
  transform: scaleY(-1);
  -webkit-mask-image: linear-gradient(to bottom, #000 0%, rgba(0,0,0,.45) 55%, transparent 100%);
          mask-image: linear-gradient(to bottom, #000 0%, rgba(0,0,0,.45) 55%, transparent 100%);
}
.bq-wlw__ghost-row {
  display: flex; align-items: center; gap: 10px;
  padding: 0 12px; height: 34px;
  border-bottom: 1px solid var(--wlw-line);
}
.bq-wlw__ghost-row > span { height: 7px; border-radius: 3px; background: var(--wlw-line); }
.bq-wlw__ghost-sym { width: 34px; }
.bq-wlw__ghost-co  { flex: 1; opacity: .6; }
.bq-wlw__ghost-num { width: 40px; opacity: .8; }
/* Staggered widths stop the sketch reading as a barcode. */
.bq-wlw__ghost-row:nth-child(2n) .bq-wlw__ghost-co { max-width: 62%; }
.bq-wlw__ghost-row:nth-child(3n) .bq-wlw__ghost-co { max-width: 44%; }
.bq-wlw__ghost-row:nth-child(2n) .bq-wlw__ghost-sym { width: 26px; }

.bq-wlw__chips-label {
  display: block; margin: 16px 0 7px;
  font-size: 9px; font-weight: 700; letter-spacing: .08em; text-transform: uppercase;
  color: var(--wlw-text-3);
}
.bq-wlw__chips { display: flex; flex-wrap: wrap; gap: 5px; justify-content: center; }
.bq-wlw__chip {
  display: inline-flex; align-items: center; gap: 4px;
  height: 25px; padding: 0 9px; cursor: pointer;
  font-family: var(--wlw-mono); font-size: 11px; font-weight: 600;
  color: var(--wlw-text-2); background: var(--wlw-surface-2);
  border: 1px solid var(--wlw-line-2); border-radius: 999px;
  transition: color var(--wlw-t), border-color var(--wlw-t), background var(--wlw-t);
}
.bq-wlw__chip:hover { color: var(--wlw-accent); border-color: var(--wlw-accent); background: var(--wlw-accent-soft); }
.bq-wlw__chip:disabled { opacity: .45; cursor: not-allowed; }
/* The "+" is UI, not a symbol — keep it out of the mono stack the ticker uses. */
.bq-wlw__chip-plus { font-family: inherit; font-weight: 700; opacity: .7; }

/* ── FOOT: add control / sign-in ──────────────────────────────────────────── */

.bq-wlw__foot { border-top: 1px solid var(--wlw-line); flex-shrink: 0; }

.bq-wlw__add, .bq-wlw__signin {
  display: flex; align-items: center; justify-content: center; gap: 6px;
  width: 100%; padding: 10px 14px; cursor: pointer;
  font-size: 11.5px; font-weight: 700; letter-spacing: .01em;
  color: var(--wlw-accent); background: none; border: 0;
  text-decoration: none;
  transition: background var(--wlw-t), color var(--wlw-t);
}
.bq-wlw__add:hover, .bq-wlw__signin:hover { background: var(--wlw-accent-soft); }
.bq-wlw__add svg, .bq-wlw__signin svg { width: 13px; height: 13px; flex-shrink: 0; }
.bq-wlw__add[hidden] { display: none; }

/* The composer. Three bands — title, field, actions — so it reads as a small
   piece of UI with a job, rather than the single naked input bar it was. */
.bq-wlw__addbox { padding: 10px; background: var(--wlw-surface-2); }
.bq-wlw__addbox[hidden] { display: none; }

.bq-wlw__addhead {
  display: flex; align-items: center; justify-content: space-between;
  margin-bottom: 7px;
}
.bq-wlw__addtitle {
  font-size: 10px; font-weight: 700; letter-spacing: .07em; text-transform: uppercase;
  color: var(--wlw-text-3);
}
.bq-wlw__addclose {
  width: 20px; height: 20px; padding: 0; border: 0; background: none; cursor: pointer;
  border-radius: 4px; color: var(--wlw-text-3);
  display: inline-flex; align-items: center; justify-content: center;
  transition: color var(--wlw-t), background var(--wlw-t);
}
.bq-wlw__addclose svg { width: 12px; height: 12px; }
.bq-wlw__addclose:hover { color: var(--wlw-text); background: var(--wlw-surface); }

/* Pills and the caret share one bordered box, so it reads as a single field
   that happens to contain chips — the pattern people know from mail clients. */
.bq-wlw__field {
  position: relative;
  display: flex; flex-wrap: wrap; align-items: center; gap: 4px;
  min-height: 34px; padding: 4px 6px; cursor: text;
  background: var(--wlw-surface);
  border: 1px solid var(--wlw-line-2); border-radius: var(--wlw-radius);
  transition: border-color var(--wlw-t), box-shadow var(--wlw-t);
}
.bq-wlw__field.is-focused {
  border-color: var(--wlw-accent);
  box-shadow: 0 0 0 3px var(--wlw-accent-soft);
}
/* Shake, not a colour swap: a rejected symbol needs to register without the
   field changing meaning. */
.bq-wlw__field.is-bad { border-color: var(--wlw-neg); animation: bq-wlw-shake 260ms; }
@keyframes bq-wlw-shake {
  0%, 100% { transform: translateX(0); }
  25% { transform: translateX(-3px); }
  75% { transform: translateX(3px); }
}

.bq-wlw__pills { display: contents; }
.bq-wlw__pill {
  display: inline-flex; align-items: center; gap: 3px;
  height: 22px; padding: 0 3px 0 7px;
  font-family: var(--wlw-mono); font-size: 11px; font-weight: 700;
  color: var(--wlw-accent); background: var(--wlw-accent-soft);
  border: 1px solid var(--wlw-line-2); border-radius: 4px;
  animation: bq-wlw-pop 140ms ease-out;
}
@keyframes bq-wlw-pop { from { transform: scale(.85); opacity: 0; } }
.bq-wlw__pill button {
  width: 15px; height: 15px; padding: 0; border: 0; background: none; cursor: pointer;
  color: inherit; opacity: .55; border-radius: 3px;
  display: inline-flex; align-items: center; justify-content: center;
}
.bq-wlw__pill button:hover { opacity: 1; background: rgba(0, 0, 0, .07); }
.bq-wlw__pill button svg { width: 9px; height: 9px; }

.bq-wlw__input {
  flex: 1; min-width: 80px; height: 24px; padding: 0 2px;
  font-size: 12px; font-family: inherit; color: var(--wlw-text);
  background: none; border: 0;
}
.bq-wlw__input::placeholder { color: var(--wlw-text-3); }
.bq-wlw__input:focus { outline: none; }

.bq-wlw__addfoot {
  display: flex; align-items: center; justify-content: space-between; gap: 8px;
  margin-top: 7px;
}
.bq-wlw__hint { font-size: 10.5px; color: var(--wlw-text-3); }
.bq-wlw__hint.is-bad { color: var(--wlw-neg); }

/* Opens UPWARD. The widget's natural home is the bottom of a sidebar column,
   where a downward list would fall outside the panel and be clipped by the
   body's overflow. */
.bq-wlw__ts {
  position: absolute; z-index: 60; bottom: calc(100% + 5px); left: 0; right: 0;
  max-height: 230px; overflow-y: auto;
  background: var(--wlw-surface);
  border: 1px solid var(--wlw-line-2); border-radius: 8px;
  box-shadow: 0 8px 26px rgba(15, 23, 42, .14), 0 2px 6px rgba(15, 23, 42, .06);
  display: none;
}
.bq-wlw__ts.is-open { display: block; }
.bq-wlw__ts-label {
  padding: 7px 10px 4px;
  font-size: 9px; font-weight: 700; letter-spacing: .07em; text-transform: uppercase;
  color: var(--wlw-text-3);
}
.bq-wlw__ts-item {
  display: flex; align-items: center; gap: 8px;
  padding: 7px 10px; cursor: pointer;
  border-left: 2px solid transparent;
}
.bq-wlw__ts-item:hover, .bq-wlw__ts-item.is-active {
  background: var(--wlw-accent-soft); border-left-color: var(--wlw-accent);
}
.bq-wlw__ts-sym {
  font-family: var(--wlw-mono); font-size: 11.5px; font-weight: 700;
  color: var(--wlw-text); min-width: 54px;
}
.bq-wlw__ts-name {
  font-size: 11.5px; color: var(--wlw-text-3); flex: 1; min-width: 0;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.bq-wlw__ts-msg { padding: 12px 10px; font-size: 11.5px; color: var(--wlw-text-3); text-align: center; }
.bq-wlw__ts-badge {
  font-size: 8.5px; font-weight: 700; letter-spacing: .05em; text-transform: uppercase;
  padding: 1px 5px; border-radius: 3px; flex-shrink: 0;
  color: var(--wlw-text-3); background: var(--wlw-surface-2); border: 1px solid var(--wlw-line);
}
.bq-wlw__ts-badge.is-etf { color: var(--wlw-accent); border-color: var(--wlw-accent); background: var(--wlw-accent-soft); }

.bq-wlw__btn {
  height: 30px; padding: 0 11px; cursor: pointer;
  font-size: 11.5px; font-weight: 700; font-family: inherit;
  border-radius: var(--wlw-radius); border: 1px solid transparent;
  transition: background var(--wlw-t), border-color var(--wlw-t), color var(--wlw-t);
  white-space: nowrap;
}
.bq-wlw__btn--primary { background: var(--wlw-accent); color: #fff; }
.bq-wlw__btn--primary:hover:not(:disabled) { filter: brightness(1.08); }
.bq-wlw__btn--ghost { background: none; color: var(--wlw-text-3); border-color: var(--wlw-line-2); }
.bq-wlw__btn--ghost:hover { color: var(--wlw-text); background: var(--wlw-surface-2); }
.bq-wlw__btn:disabled { opacity: .45; cursor: not-allowed; }

/* ── ROW TOOLTIP ──────────────────────────────────────────────────────────── */
/* Lives on <body>, not inside the widget. The body scroller clips on both axes
   (see the overflow note above), so a tooltip parented inside it would be cut
   off by the very panel edge it needs to escape. position:fixed off the row's
   bounding rect sidesteps that entirely.
   Not a `title` attribute: that cannot be styled, waits a second before
   appearing, and is invisible on touch. */
.bq-wlw-tip {
  position: fixed; z-index: 100000;
  max-width: 280px; padding: 7px 11px;
  pointer-events: none; opacity: 0;
  transform: translateY(3px);
  transition: opacity 120ms ease, transform 120ms ease;
  background: var(--white, #fff);
  border: 1px solid var(--bq-line-strong, #d5dee6);
  border-radius: 7px;
  box-shadow: 0 8px 24px rgba(15, 23, 42, .13), 0 2px 6px rgba(15, 23, 42, .07);
  font-family: inherit;
}
.bq-wlw-tip.is-open { opacity: 1; transform: translateY(0); }
.bq-wlw-tip__sym {
  display: block;
  font-family: var(--bq-mono, ui-monospace, SFMono-Regular, Menlo, Consolas, monospace);
  font-size: 11px; font-weight: 700; letter-spacing: -.01em;
  color: var(--blue-primary, #0369a1);
}
.bq-wlw-tip__name {
  display: block; margin-top: 1px;
  font-size: 12px; line-height: 1.35; color: var(--bq-text, #0b1f2e);
}

/* ── TOASTS ───────────────────────────────────────────────────────────────── */

.bq-wlw-toasts {
  position: fixed; bottom: 20px; right: 20px; z-index: 99999;
  display: flex; flex-direction: column; gap: 7px; pointer-events: none;
}
.bq-wlw-toast {
  padding: 9px 14px; min-width: 180px;
  font-size: 12.5px; font-weight: 600;
  background: #fff; color: #0b1f2e;
  border: 1px solid #d5dee6; border-left: 3px solid var(--wlw-accent, #0369a1);
  border-radius: 6px; box-shadow: 0 6px 20px rgba(15,23,42,.13);
  animation: bq-wlw-toast-in 180ms ease-out;
}
.bq-wlw-toast.is-ok  { border-left-color: #15803d; }
.bq-wlw-toast.is-err { border-left-color: #c5331f; }
.bq-wlw-toast.is-out { animation: bq-wlw-toast-out 160ms ease-in forwards; }
@keyframes bq-wlw-toast-in  { from { opacity: 0; transform: translateY(6px); } }
@keyframes bq-wlw-toast-out { to   { opacity: 0; transform: translateY(5px); } }

@media (prefers-reduced-motion: reduce) {
  .bq-wlw__flash-up, .bq-wlw__flash-down { animation-duration: 1ms; }
  .bq-wlw-toast { animation: none; }
}

/* ── TOUCH ────────────────────────────────────────────────────────────────── */
/* Keyed on the POINTER, not the viewport: a touchscreen laptop needs the bigger
   targets at 1400px just as much as a phone does, and a narrow desktop window
   does not. */
@media (hover: none), (pointer: coarse) {
  /* Nothing can hide behind a hover that will never happen. */
  .bq-wlw__del { opacity: 1; width: 30px; height: 30px; }
  .bq-wlw__del svg { width: 15px; height: 15px; }
  /* The action column has to grow with the button or it clips it again — the
     two numbers are a pair. */
  .bq-wlw__th--act { width: 40px; }

  .bq-wlw__pill { height: 26px; }
  .bq-wlw__pill button { width: 18px; height: 18px; }
  .bq-wlw__btn, .bq-wlw__field { min-height: 36px; }
  .bq-wlw__ts-item { padding: 10px 12px; }
  .bq-wlw__chip { height: 30px; padding: 0 12px; }

  /* iOS Safari zooms the whole page when a focused input is under 16px, which
     leaves the composer half off-screen and the layout re-scaled. 16px costs
     nothing here and prevents that jump entirely. */
  .bq-wlw__input { font-size: 16px; }
}

/* Below the homepage's stacking breakpoint the host panel stops being
   height-constrained (its flex:1 becomes flex:none), so the list would grow to
   however many symbols the user holds. Cap it here — the widget has to own
   this, since the rule that used to do it lived on markup that no longer
   exists. */
@media (max-width: 767px) {
  .bq-wlw__body { max-height: 360px; }
  /* A shorter panel needs a proportionally smaller lift, or the message ends
     up crowding the header. */
  .bq-wlw__state { min-height: 220px; }
  .bq-wlw__ghost-row { height: 30px; }
}

/* PHONE: three columns, not four.
   The symbol column is dropped and the company name carries the row instead —
   bold, in ink rather than grey, and linked to the same ticker page the symbol
   pointed at. A name is what a reader recognises at a glance on a small
   screen; a four-character ticker beside a truncated name is two half-columns
   competing for the same 40px. Price and Chg% are untouched. */
@media (max-width: 520px) {
  .bq-wlw__sym, .bq-wlw__th--sym { display: none; }
  .bq-wlw__co { color: var(--wlw-text); }
  .bq-wlw__co a { font-weight: 700; color: var(--wlw-accent); }
  /* The name column absorbs the width the symbol gave up. */
  .bq-wlw__table th.bq-wlw__th--co,
  .bq-wlw__table td.bq-wlw__co { padding-left: 12px; }
}
