/* ---------------------------------------------------------------------------
   /stock-info/ -- five-section stock information page

   Palette taken from the MarketPulse reference's resolved tokens (shadcn dark:
   background 0 0% 3.9%, border 0 0% 14.9%, muted-foreground 0 0% 63.9%) rather
   than guessed from a screenshot. Everything is scoped under .si-page except
   the one #navbar-template rule, which has to reach the shared header.

   Uses the Bootstrap 5 grid only incidentally; layout here is flex/grid.
--------------------------------------------------------------------------- */

.si-page {
  --si-bg:        #0a0a0a;
  --si-card:      #101012;
  --si-raised:    #17171a;
  --si-border:    #33333a;   /* was #262628 -- lifted for a more visible edge */
  /* --si-border: #262628; */
  --si-text:      #fafafa;
  --si-muted:     #a3a3a3;
  /* 5.6:1 on the card surface. Was #6f6f74, which measured 3.80:1 and failed
     WCAG AA (4.5:1) for the 11px labels that use it -- visibly faint. */
  --si-dim:       #8b8b92;

  --si-accent:    #38bdf8;

  /* Trade Ideas brand hues for direction (BRAND_GUIDELINES.md).
     Up   = a tint of Blue 500  #066699 -- the brand value itself measures only
            3.05:1 on this dark card, so #5FB3DD (8.13:1) carries the hue legibly.
     Down = Amber 500 #F19429 exactly, which already clears AA at 8.15:1.
     Blue/orange is also the colour-blind-safe pairing; red/green is not.
     To revert, swap these two lines for the commented originals below. */
  --si-up:        #34d399;   /* emerald, 9.89:1 on the card */
  --si-down:      #fb7185;   /* rose,    7.06:1 */
  /* Blue/orange, the colour-blind-safe pair these replaced. To switch back,
     swap these four lines and the four derived values below.
     --si-up:     #5fb3dd;   --si-up-tint:   rgba(95,179,221,0.15);
     --si-down:   #f19429;   --si-down-tint: rgba(241,148,41,0.15);
     --si-down-soft: #d29a5a;  --si-down-soft-tint: rgba(210,154,90,0.11); */
  /* Badge/pill fills. Tokens rather than literals so a direction-colour swap
     reaches them too -- they were hardcoded rgba() and silently kept the old
     hue when the tokens changed. */
  --si-up-tint:   rgba(52,211,153,0.15);
  --si-down-tint: rgba(251,113,133,0.15);
  /* Mid step of the rank ramp: 60% of the way from --si-muted to --si-down,
     so it reads as a weaker version of the down colour rather than a different
     hue. Recomputed when --si-down changed; 6.95:1. */
  --si-down-soft:      #d88591;
  --si-down-soft-tint: rgba(216,133,145,0.11);
  --si-warn:      #fbbf24;
  /* Trade Ideas amber, for chrome that is NOT a direction: the landing hero's
     eyebrow dot and the CTA button. These used --si-down, which was fine while
     down was amber and turns them rose the moment it is not. */
  --si-brand:     #f19429;

  --si-radius:    0.625rem;

  background: var(--si-bg);
  color: var(--si-text);
  font-family: 'Poppins', -apple-system, BlinkMacSystemFont, 'Segoe UI', Arial, sans-serif;
  font-size: 14px;
  line-height: 1.55;
  padding-bottom: 3.5rem;
}

.si-shell { max-width: 1400px; margin: 0 auto; padding: 0 1.5rem; }
.si-stack { display: flex; flex-direction: column; gap: 1rem; padding-top: 1rem; }

/* The shared site nav is transparent with white links by design
   (MainSite/css/styles.css:373 `.navbar{background:unset!important}`), so it
   relies on the page painting something dark behind it. This page's surface
   starts below the nav, so without this the white links land on the off-white
   body (--bodyBg #FBFBFD) and the header reads as blank. The ID outranks
   `.navbar`, and this sheet only loads on /stock-info/. */
#navbar-template { background: #0a0a0a !important; border-bottom: 1px solid #33333a; }  /* matches --si-border; literal because #navbar-template is outside .si-page */
#promotions-test { background: #0a0a0a; }

/* --- Header ------------------------------------------------------------- */
/* A card like the rest, not a full-bleed band. <header> is full-bleed, so any
   border on IT runs the whole viewport; __inner fills the shell's CONTENT box
   -- the same box .si-card occupies -- so all four edges line up.
   Stacked rows, so the quote sentence gets the FULL width and only wraps when
   the viewport genuinely forces it. An earlier two-column version put the
   metrics beside it and `margin-left:auto` on that column swallowed the free
   space, which stopped the sentence growing and wrapped it early. */
.si-header { background: var(--si-bg); padding: 1rem 0 0; }
.si-header__inner {
  display: flex;
  flex-direction: column;
  gap: 1rem;   /* was 0.625rem */
  background: var(--si-card);
  border: 1px solid var(--si-border);
  border-radius: var(--si-radius);
  padding: 1.25rem 1.375rem;
}

.si-header__top {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 0.75rem 1.5rem;
  flex-wrap: wrap;
}
.si-header__line { display: flex; align-items: center; gap: 0.5rem; flex-wrap: wrap; }
/* Source images are 128x128 with their own padding; contain keeps any that
   are not square from distorting. The rounded tile on --si-raised gives the
   white-background logos an edge so they do not float on the dark card. */
.si-logo {
  flex: 0 0 auto;
  width: 2rem;
  height: 2rem;
  object-fit: contain;
  border-radius: 0.375rem;
  background: var(--si-raised);
  padding: 0.125rem;
}
.si-ticker {
  margin: 0; font-size: 1.5rem; font-weight: 600;
  letter-spacing: -0.01em; color: var(--si-text);
}
.si-company { font-size: 0.8125rem; color: var(--si-muted); }

.si-tag {
  display: inline-flex; align-items: center; gap: 0.25rem;
  border: 1px solid var(--si-border); background: var(--si-raised);
  border-radius: 0.375rem; padding: 0.0625rem 0.375rem;
  font-size: 0.6875rem; font-weight: 500; color: var(--si-muted); white-space: nowrap;
}

/* Timestamp, quote basis, market status and lookup, one row. */
.si-header__meta {
  display: flex; align-items: center; justify-content: flex-end;
  flex-wrap: wrap; gap: 0.5rem 0.75rem;
  font-size: 0.6875rem; color: var(--si-dim);
}
.si-header__meta .si-lookup--inline { margin: 0; }
.si-stamp__time { white-space: nowrap; }
.si-stamp__status { display: inline-flex; align-items: center; gap: 0.375rem; white-space: nowrap; }
.si-chip {
  border-radius: 0.25rem; background: var(--si-raised); padding: 0 0.25rem;
  font-size: 0.625rem; font-weight: 500; color: var(--si-muted);
}
.si-dotstat {
  width: 0.375rem; height: 0.375rem; border-radius: 50%;
  background: var(--si-dim); display: inline-block;
}
.si-dotstat.is-open { background: var(--si-up); }

/* Two stacked lines: price + move, then the explanatory sentence.
   Was one flowing sentence across the full card width:
   .si-quote { display: flex; align-items: baseline; flex-wrap: wrap;
               gap: 0.25rem 0.5rem; font-size: 0.875rem; line-height: 1.5; } */
/* The quote and the headline metrics share a row. space-between plus a grow
   on the quote, not margin-left:auto on the metrics -- auto margins absorb the
   free space before flex-grow ever sees it, so the sentence would wrap early. */
.si-header__quote {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: 0.75rem 2rem;
  flex-wrap: wrap;
}
.si-quote {
  margin: 0;
  flex: 1 1 24rem;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 0.125rem;
  font-size: 0.875rem;
  line-height: 1.5;
}
.si-quote__main,
.si-quote__detail {
  display: flex;
  align-items: baseline;
  flex-wrap: wrap;
  gap: 0.25rem 0.5rem;
}
.si-price {
  font-size: 1.875rem; font-weight: 600; letter-spacing: -0.02em;
  color: var(--si-text); font-variant-numeric: tabular-nums;
}
/* The move now sits alone next to the price, so it carries a little more
   weight than body text. Inherited 0.875rem from .si-quote before. */
.si-quote__main .si-num { font-size: 1rem; }
/* Leads the sentence now, so it sits at sentence size. Was 0.9375rem. */
.si-quote__dir { font-size: 0.875rem; font-weight: 600; }
.si-quote__from { color: var(--si-muted); }

/* Bottom row of the header card: the compact ranges, full width. Plain block
   now that the metrics have moved up -- the grid inside needs the full width to
   divide, and a lone flex item would only be as wide as its content. Was:
   .si-header__bottom { display: flex; align-items: flex-end;
                        justify-content: space-between;
                        gap: 1rem 2rem; flex-wrap: wrap; } */
.si-header__bottom {
  display: block;
  /* Rule marks the real grouping boundary: identity and price above, the range
     readouts below. Inset from the card edge by the inner padding, so it reads
     as a divider within the card rather than a second card edge. */
  border-top: 1px solid var(--si-border);
  padding-top: 1rem;
}

/* Group heading for the range row. Deliberately quieter than .si-card__title --
   it labels a group inside the header card, it is not a card of its own -- but a
   step up from .si-miniband__label so it reads as the parent of those five. */
.si-bandlabel {
  margin: 0 0 0.4375rem;
  font-size: 0.6875rem;
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--si-dim);
}

/* A scaled-down Price ranges card -- same parts (label, both ends, track with
   marker, current value), roughly 75% the size. The full card is disabled in
   stock-info.html; these carry the detail now. */
/* Equal columns that each take a share of the row and reflow on their own:
   auto-fit drops the column count as the width shrinks, so the cards wrap by
   themselves instead of at a hand-picked breakpoint. The 8rem floor is measured,
   not guessed: two 9-character prices ($1,234.56) plus the padding need 114px,
   so 128px leaves slack and still keeps all five across down to ~768px -- the
   page's own mobile breakpoint -- then 4, 3, 2 and finally 1 on a phone.
   Was: .si-minibands { display: flex; gap: 0.5rem; flex-wrap: wrap; }
        .si-miniband  { min-width: 7.5rem; } */
.si-minibands {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(8rem, 1fr));
  gap: 1rem;   /* was 0.5rem */
}
.si-miniband {
  background: var(--si-raised);
  border: 1px solid var(--si-border);
  border-radius: 0.5rem;
  padding: 0.4375rem 0.5625rem 0.5rem;
  min-width: 0;
}
/* Label left, direction icon right. The margin moved from the label to this
   row so the icon does not sit on its own baseline. */
.si-miniband__head {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 0.375rem;
  margin-bottom: 0.375rem;
  min-height: 1.125rem;
}
.si-miniband__label {
  display: block;
  font-size: 0.5625rem;
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--si-dim);
  padding-top: 0.1875rem;
}
/* Tinted badge, scaled down from the base44 reference (28px / 14px icon) to
   suit a card that can be 128px wide. currentColor carries the hue into the
   glyph, so only the tint is set here. */
.si-miniband__ico {
  flex: 0 0 auto;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 1.125rem;
  height: 1.125rem;
  border-radius: 0.3125rem;
}
.si-miniband__ico--up   { background: var(--si-up-tint);   color: var(--si-up); }
.si-miniband__ico--down { background: var(--si-down-tint); color: var(--si-down); }
.si-miniband__ends {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 0.5rem;
  margin-bottom: 0.3125rem;
}
/* The range ends. Off --si-accent, which means "interactive" everywhere else
   on the page (links, Go, focus rings) and sits 2 degrees of hue from --si-up,
   so it read as a third blue beside the direction icon and change line.
   Was: color: var(--si-accent); */
.si-miniband__end {
  font-size: 0.6875rem;
  font-weight: 600;
  color: var(--si-text);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}
.si-miniband__track {
  position: relative;
  display: block;
  height: 0.25rem;
  border-radius: 999px;
  background: rgba(139,139,146,0.22);
}
.si-miniband__marker {
  position: absolute;
  top: 50%;
  left: 0;
  width: 0.625rem;
  height: 0.625rem;
  margin-left: -0.3125rem;
  transform: translateY(-50%);
  border-radius: 50%;
  /* Neutral on purpose. The marker's POSITION is its meaning -- where the price
     sits in this period's range. It used to be tinted by the day's direction,
     which said nothing about the year on the year card, and now that each card
     shows its own change the two would openly disagree (a year up 31% under an
     orange marker because today is down). The change line carries direction.
     Was: background: var(--si-up);
          .si-header__bottom.is-down .si-miniband__marker { background: var(--si-down); } */
  background: var(--si-text);
  border: 2px solid var(--si-raised);
  box-shadow: 0 0 0 1px rgba(255,255,255,0.18);
}
/* The open is a price in the same range, so it rides the same track as a tick
   rather than taking a row of its own. Taller than the 4px rail so it reads as
   a mark; the current marker is later in the DOM and paints over it if they
   coincide. */
.si-miniband__open {
  position: absolute;
  top: 50%;
  left: 0;
  width: 2px;
  height: 0.5625rem;
  margin-left: -1px;
  transform: translateY(-50%);
  border-radius: 1px;
  background: var(--si-muted);
}

/* open .......... now */
/* The pair needs 166px of card to sit on one line; below that it wraps to two
   rows rather than forcing the whole grid to wider columns. Centred, not
   space-between: the two values are not tied to the ends of the bar above. */
.si-miniband__foot {
  margin-top: 0.4375rem;
  display: flex;
  align-items: baseline;
  justify-content: center;
  flex-wrap: wrap;
  gap: 0.125rem 0.625rem;
  font-size: 0.6875rem;
}
.si-miniband__foot-i {
  white-space: nowrap;
  font-variant-numeric: tabular-nums;
  color: var(--si-muted);
}
.si-miniband__k {
  color: var(--si-dim);
  font-size: 0.5625rem;
  text-transform: uppercase;
  letter-spacing: 0.06em;
}
.si-miniband__cur { font-weight: 600; color: var(--si-text); }
/* Centred when there is no open to pair it with (Today, intraday). */
.si-miniband__cur--solo { font-size: 0.75rem; }

/* Change from the period open. This is the one value in the card that IS
   directional, so it is the one that earns the up/down colour. */
.si-miniband__chg {
  margin-top: 0.1875rem;
  text-align: center;
  font-size: 0.6875rem;
  font-weight: 600;
}


/* Metrics on their own rows, right-justified beside the quote. */
.si-headstats { margin: 0; display: grid; gap: 0.1875rem; justify-items: end; }
.si-headstats > div { display: flex; align-items: baseline; gap: 0.75rem; }
.si-headstats dt { margin: 0; font-size: 0.75rem; color: var(--si-dim); }
.si-headstats dd {
  margin: 0; font-size: 0.8125rem; font-weight: 600;
  color: var(--si-text); font-variant-numeric: tabular-nums;
  min-width: 5rem; text-align: right;
}

/* --- Lookup ------------------------------------------------------------- */
.si-lookup { margin: 0 0 1.5rem; }
.si-lookup--inline { margin: 0; flex: 0 0 auto; }
.si-lookup__label {
  display: block; font-size: 0.6875rem; font-weight: 500; letter-spacing: 0.08em;
  text-transform: uppercase; color: var(--si-accent); margin-bottom: 0.5rem;
}
.si-lookup__row { display: flex; gap: 0.5rem; max-width: 26rem; }
.si-lookup--inline { display: flex; gap: 0.375rem; }
.si-lookup__input {
  flex: 1 1 auto; min-width: 0; width: 7rem;
  background: var(--si-raised);
  border: 1px solid var(--si-border);
  border-radius: 0.5rem;
  color: var(--si-text);
  padding: 0.4375rem 0.6875rem;
  font-size: 0.8125rem;
  text-transform: uppercase;
}
.si-lookup__row .si-lookup__input { width: auto; padding: 0.625rem 0.875rem; font-size: 0.9375rem; }
.si-lookup__input::placeholder { color: var(--si-dim); }
.si-lookup__input:focus { outline: 2px solid var(--si-accent); outline-offset: 1px; border-color: transparent; }
.si-lookup__btn {
  flex: 0 0 auto; border: 0; cursor: pointer;
  background: var(--si-accent); color: #05121b;
  border-radius: 0.5rem; padding: 0.4375rem 0.875rem;
  font-size: 0.75rem; font-weight: 600;
}
.si-lookup__row .si-lookup__btn { padding: 0.625rem 1.125rem; font-size: 0.8125rem; }
.si-lookup__btn:hover { background: #7dd3fc; }

/* --- Symbol autocomplete ------------------------------------------------ */
/* The field is the positioning context for the popup; the row stays flex so
   the button keeps sitting beside it. */
.si-lookup__field { position: relative; flex: 1 1 auto; min-width: 0; }
/* border-box explicitly: the input carries 14px of padding plus a border, so
   width:100% would otherwise overflow the wrapper and slide under the button.
   Bootstrap's reset happens to set this globally on the real page, but this
   component should not depend on another stylesheet to lay out correctly. */
.si-lookup__field .si-lookup__input { width: 100%; box-sizing: border-box; }

.si-ac {
  position: absolute;
  z-index: 40;
  top: calc(100% + 0.25rem);
  left: 0;
  right: 0;
  margin: 0;
  padding: 0.25rem;
  list-style: none;
  max-height: 17rem;
  overflow-y: auto;
  background: var(--si-card);
  border: 1px solid var(--si-border);
  border-radius: 0.5rem;
  box-shadow: 0 12px 32px -12px rgba(0,0,0,0.85);
}
.si-ac__item {
  display: flex;
  align-items: baseline;
  gap: 0.5rem;
  padding: 0.375rem 0.5rem;
  border-radius: 0.375rem;
  cursor: pointer;
  font-size: 0.8125rem;
  line-height: 1.35;
}
.si-ac__item.is-active { background: var(--si-raised); }
.si-ac__sym {
  flex: 0 0 auto;
  min-width: 3.75rem;
  font-weight: 600;
  color: var(--si-text);
  font-variant-numeric: tabular-nums;
}
.si-ac__co {
  flex: 1 1 auto;
  min-width: 0;
  color: var(--si-muted);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.si-ac__ex {
  flex: 0 0 auto;
  font-size: 0.625rem;
  font-weight: 600;
  letter-spacing: 0.06em;
  color: var(--si-dim);
}
/* The matched run. Accent is the interactive colour and this list IS the
   interactive element, so it is the right one here. */
.si-ac__hit { color: var(--si-accent); font-weight: 700; }

/* The header form is narrow; let its popup out to a readable width without
   stretching the input itself. */
.si-lookup--inline .si-ac { min-width: 20rem; left: auto; right: 0; }

@media (max-width: 47.99rem) {
  .si-lookup--inline .si-ac { min-width: 0; left: 0; right: 0; }
  .si-ac { max-height: 14rem; }
}

/* --- Cards -------------------------------------------------------------- */
.si-card {
  background: var(--si-card);
  border: 1px solid var(--si-border);
  border-radius: var(--si-radius);
  padding: 1.25rem 1.375rem 1.375rem;
}
.si-card__head {
  display: flex; align-items: flex-start; justify-content: space-between;
  gap: 1rem; margin-bottom: 1rem;
}
.si-card__title { margin: 0; font-size: 0.9375rem; font-weight: 600; color: var(--si-text); }
.si-card__sub { margin: 0.125rem 0 0; font-size: 0.75rem; color: var(--si-dim); }

.si-group {
  margin: 1.25rem 0 0.625rem;
  font-size: 0.625rem; font-weight: 600; letter-spacing: 0.09em;
  text-transform: uppercase; color: var(--si-dim);
}
.si-group:first-of-type { margin-top: 0; }

.si-split { display: grid; gap: 1rem; grid-template-columns: 1fr; }
@media (min-width: 62rem) {
  .si-split { grid-template-columns: 1.35fr 1fr; }
  .si-split--wide { grid-template-columns: 1fr 1.15fr; }
}

/* --- Numbers ------------------------------------------------------------ */
.si-num { font-variant-numeric: tabular-nums; font-weight: 600; white-space: nowrap; }
.si-num--up { color: var(--si-up); }
.si-num--down { color: var(--si-down); }
.si-num--neutral { color: var(--si-muted); }
.si-num--warn { color: var(--si-down-soft); }   /* was var(--si-warn) */

.si-label {
  display: block; font-size: 0.6875rem; color: var(--si-dim);
  letter-spacing: 0.02em; margin-bottom: 0.1875rem;
}
.si-val { display: block; font-size: 0.9375rem; font-weight: 600; color: var(--si-text); font-variant-numeric: tabular-nums; }
.si-sub { display: block; font-size: 0.6875rem; color: var(--si-dim); margin-top: 0.125rem; }
.si-muted { color: var(--si-dim); font-size: 0.8125rem; }

/* --- Chart -------------------------------------------------------------- */
/* Card head: title + range change on the left (two lines), range buttons
   right. The symbol, "closing prices" and the timezone were all already in the
   page header, so that subtitle is gone; the active button and the "/ 6M"
   suffix replace the old "Selected range (6M)" label. */
.si-chart__change {
  margin: 0.25rem 0 0;
  display: flex;
  align-items: baseline;
  gap: 0.375rem;
  font-size: 0.9375rem;
}
.si-chart__rangename { font-size: 0.8125rem; color: var(--si-dim); }
.si-rangebtns {
  flex: 0 0 auto;
  display: flex; gap: 0.125rem; padding: 0.1875rem;
  border-radius: 0.5rem; border: 1px solid var(--si-border); background: var(--si-raised);
}
.si-rangebtn {
  border: 0; background: none; color: var(--si-muted); cursor: pointer;
  font: 600 0.6875rem/1.4 inherit; padding: 0.25rem 0.625rem; border-radius: 0.375rem;
  transition: background 0.12s ease, color 0.12s ease;
}
.si-rangebtn:hover { background: rgba(255,255,255,0.06); color: var(--si-text); }
.si-rangebtn.is-active { background: var(--si-text); color: #0a0a0a; }
.si-rangebtn:focus-visible { outline: 2px solid var(--si-accent); outline-offset: 1px; }

/* Height must come from CSS, never from the viewBox. fitToBox() writes the
   measured box INTO the viewBox, so if the box were sized FROM the viewBox the
   two would feed each other (1200x293 -> 380x154 -> 1200x486 on a resize
   round-trip).
   aspect-ratio keeps the chart width-proportional -- the behaviour that made it
   look right at desktop -- while staying CSS-determined, so there is no loop.
   640/140 is the authored ratio; min-height floors it on narrow screens. */
.si-chart__wrap {
  position: relative;
  aspect-ratio: 640 / 140;
  min-height: 7.65rem;
  display: flex;
}
.si-chart { width: 100%; height: 100%; display: block; overflow: visible; }
.si-chart:focus-visible { outline: 2px solid var(--si-accent); outline-offset: 2px; }
.si-grid { stroke: rgba(255,255,255,0.06); stroke-width: 1; }
/* Literal pixels: stock-info.js re-points the viewBox at the element's real
   size on load, so this is no longer multiplied by a viewBox scale factor.
   It previously rendered at ~18px on a desktop width despite saying 8.5. */
.si-axis { fill: var(--si-dim); font-size: 11px; font-family: inherit; }
.si-chart-empty { margin: auto; color: var(--si-dim); font-size: 0.8125rem; }

/* Belt and braces: the UA `[hidden]{display:none}` does reach SVG children in
   current browsers, but stating it means a browser that does not would hide the
   hover furniture rather than stranding it at x=0. The script toggles the
   ATTRIBUTE, never the .hidden property -- SVGElement does not implement it. */
.si-chart [hidden] { display: none; }
/* Neutral rather than accent-blue: with --si-up now blue, a blue crosshair sat
   at 1.24:1 against an up-line and effectively disappeared on it. White reads
   over both the blue up-line and the orange down-line. */
.si-band-hl { fill: rgba(250,250,250,0.07); pointer-events: none; }
.si-cross { stroke: rgba(250,250,250,0.70); stroke-width: 1; shape-rendering: crispEdges; pointer-events: none; }
.si-halo { fill: rgba(250,250,250,0.22); pointer-events: none; }
.si-dot { fill: var(--si-text); stroke: #0a0a0a; stroke-width: 2; pointer-events: none; }
/* .si-band-hl { fill: rgba(56,189,248,0.10); } */
/* .si-cross { stroke: rgba(56,189,248,0.85); } */
/* .si-halo { fill: rgba(56,189,248,0.25); } */
/* .si-dot { fill: var(--si-accent); stroke: #0a0a0a; stroke-width: 2; } */

.si-tip {
  position: absolute; z-index: 2; pointer-events: none;
  display: flex; flex-direction: column; gap: 0.0625rem;
  padding: 0.375rem 0.5625rem; border-radius: 0.5rem;
  border: 1px solid var(--si-border); background: rgba(10,10,10,0.96);
  box-shadow: 0 8px 24px -10px rgba(0,0,0,0.9); white-space: nowrap;
}
.si-tip__date { font-size: 0.625rem; color: var(--si-dim); }
.si-tip__price { font-size: 0.875rem; font-weight: 600; color: var(--si-text); font-variant-numeric: tabular-nums; }

/* --- Metric rows -------------------------------------------------------- */
.si-pairs { display: grid; gap: 0.875rem 1.5rem; grid-template-columns: repeat(auto-fit, minmax(8rem, 1fr)); }

/* --- Price range bands -------------------------------------------------- */
/* Each band is its own card: label, the two ends flanking the track, and the
   current value centred beneath. Five across on desktop, wrapping down. */
.si-bands {
  display: grid;
  gap: 0.75rem;
  grid-template-columns: repeat(auto-fit, minmax(10.5rem, 1fr));
}
.si-band {
  background: var(--si-raised);
  border: 1px solid var(--si-border);
  border-radius: 0.625rem;
  padding: 0.75rem 0.875rem 0.875rem;
}
.si-band__label {
  display: block;
  font-size: 0.625rem;
  font-weight: 600;
  letter-spacing: 0.09em;
  text-transform: uppercase;
  color: var(--si-dim);
  margin-bottom: 0.625rem;
}
.si-band__ends {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 0.5rem;
  margin-bottom: 0.4375rem;
}
/* Matches .si-miniband__end. Was: color: var(--si-accent); */
.si-band__end {
  font-size: 0.8125rem;
  font-weight: 600;
  color: var(--si-text);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}
.si-band__track {
  position: relative;
  height: 0.375rem;
  border-radius: 999px;
  /* Neutral rail. The bar answers "where in the range", which is positional,
     not directional -- and blue/orange already mean up/down everywhere else on
     this page, so a fixed low-to-high gradient in those hues put a stock near
     its 52-week HIGH on the orange (down) end. It also never changed with the
     value, so it encoded nothing. Position carries the meaning; the marker
     carries the direction. Previous versions kept below. */
  background: rgba(139,139,146,0.22);
  /* brand direction gradient:
  background: linear-gradient(to right,
      rgba(95,179,221,0.45), rgba(139,139,146,0.22), rgba(241,148,41,0.45)); */
  /* MarketPulse original (same flaw in green/red -- near the high renders red):
  background: linear-gradient(to right,
      rgba(16,185,129,0.30), rgba(245,158,11,0.30), rgba(225,29,72,0.30)); */
}
.si-band__marker {
  position: absolute;
  top: 50%;
  left: 0;
  width: 0.875rem;
  height: 0.875rem;
  margin-left: -0.4375rem;
  transform: translateY(-50%);
  border-radius: 50%;
  /* Tinted by the day's direction so it agrees with the header and the rest of
     the page, instead of introducing a third colour language. */
  background: var(--si-up);
  border: 2px solid var(--si-raised);
  box-shadow: 0 0 0 1px rgba(255,255,255,0.18);
}
.si-band--down .si-band__marker { background: var(--si-down); }
.si-band__cur {
  margin-top: 0.625rem;
  text-align: center;
  font-size: 0.9375rem;
  font-weight: 600;
  color: var(--si-text);
  font-variant-numeric: tabular-nums;
}

/* --- Tabs --------------------------------------------------------------- */
.si-tabs {
  display: flex; gap: 0.25rem; padding: 0.25rem;
  background: var(--si-raised); border: 1px solid var(--si-border);
  border-radius: 0.5rem; margin-bottom: 1rem;
}
.si-tab {
  flex: 1 1 0; border: 0; background: none; cursor: pointer;
  color: var(--si-muted); font: 500 0.8125rem/1.6 inherit;
  padding: 0.375rem 0.5rem; border-radius: 0.375rem;
  transition: background 0.12s ease, color 0.12s ease;
}
.si-tab:hover { color: var(--si-text); }
.si-tab.is-active { background: var(--si-card); color: var(--si-text); font-weight: 600; }
.si-tab:focus-visible { outline: 2px solid var(--si-accent); outline-offset: 1px; }

.si-rows { margin: 0; display: grid; gap: 0; }
.si-rows > div {
  display: flex; align-items: center; justify-content: space-between; gap: 1rem;
  padding: 0.5625rem 0; border-bottom: 1px solid rgba(255,255,255,0.05);
}
.si-rows > div:last-child { border-bottom: 0; }
.si-rows dt { margin: 0; font-size: 0.8125rem; color: var(--si-muted); }
.si-rows dd { margin: 0; font-size: 0.8125rem; font-weight: 600; color: var(--si-text); font-variant-numeric: tabular-nums; }

/* Overview commentary: ticky's sentence-style observations rather than
   label/value rows, so each line reads as a statement about the stock. */
.si-commentary {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  gap: 0.0625rem;
}
.si-commentary li {
  padding: 0.5625rem 0;
  border-bottom: 1px solid rgba(255,255,255,0.05);
  font-size: 0.8125rem;
  line-height: 1.5;
  color: var(--si-muted);
}
.si-commentary li:last-child { border-bottom: 0; }
.si-commentary b { font-weight: 600; }

.si-note {
  margin: 1rem 0 0; padding: 0.75rem 0.875rem;
  border: 1px solid var(--si-border); border-radius: 0.5rem;
  background: var(--si-raised); font-size: 0.8125rem; color: var(--si-muted);
}

.si-alert {
  display: grid; gap: 0.125rem 0.75rem; padding: 0.625rem 0;
  grid-template-columns: 1fr auto; border-bottom: 1px solid rgba(255,255,255,0.05);
}
.si-alert:last-child { border-bottom: 0; }
.si-alert__type { font-size: 0.8125rem; font-weight: 600; color: var(--si-accent); }
.si-alert__time { font-size: 0.6875rem; color: var(--si-dim); text-align: right; white-space: nowrap; }
.si-alert__desc { grid-column: 1 / -1; font-size: 0.75rem; color: var(--si-muted); }

/* --- Company & peers ---------------------------------------------------- */
.si-desc {
  margin: 1rem 0 0; font-size: 0.8125rem; color: var(--si-muted);
  display: -webkit-box; -webkit-line-clamp: 3; -webkit-box-orient: vertical; overflow: hidden;
}
.si-desc.is-open { -webkit-line-clamp: unset; overflow: visible; }
.si-more {
  margin-top: 0.375rem; border: 0; background: none; cursor: pointer;
  color: var(--si-accent); font: 500 0.75rem/1.5 inherit; padding: 0;
}
.si-more:hover { text-decoration: underline; }

.si-tw { overflow-x: auto; }
.si-table { width: 100%; border-collapse: collapse; font-size: 0.8125rem; }
.si-table th {
  text-align: left; font-size: 0.625rem; font-weight: 500; letter-spacing: 0.08em;
  text-transform: uppercase; color: var(--si-dim);
  padding: 0 0.75rem 0.5rem 0; border-bottom: 1px solid var(--si-border); white-space: nowrap;
}
.si-table td { padding: 0.5625rem 0.75rem 0.5625rem 0; border-bottom: 1px solid rgba(255,255,255,0.05); color: var(--si-muted); }
.si-table tr:last-child td { border-bottom: 0; }
.si-table .si-r { text-align: right; padding-right: 0; font-variant-numeric: tabular-nums; }
.si-peer { color: var(--si-text); font-weight: 600; text-decoration: none; }
/* :focus as well as :hover -- the global a:hover, a:focus { color: #111 }
   in core/css/main.css catches both, so a keyboard user tabbing through the
   peer table would otherwise land on invisible text. */
.si-peer:hover,
.si-peer:focus { color: var(--si-accent); text-decoration: underline; }
.si-peer__name { color: var(--si-muted); }

/* --- Pills / empty / footer -------------------------------------------- */
.si-pill {
  display: inline-block; padding: 0.125rem 0.5rem; border-radius: 0.3125rem;
  font-size: 0.75rem; font-weight: 600; white-space: nowrap;
}
/* Rank ramp, in order: one axis running blue -> grey -> weak amber -> amber,
   with intensity carrying the steps between the ends.
   It used to jump hue instead: "Not So Good" was --si-warn #fbbf24 and "Poor"
   --si-down #f19429, 11 degrees apart, so two adjacent steps of a single
   ordinal scale were effectively the same colour -- and identical under
   colour blindness. Ordinal data wants one hue varying in strength.
   Was: .si-pill--warn { background: rgba(251,191,36,0.15); color: var(--si-warn); }
        .si-pill--neutral { background: rgba(163,163,163,0.15); ... } */
.si-pill--up      { background: var(--si-up-tint);        color: var(--si-up); }
.si-pill--neutral { background: rgba(163,163,163,0.12);   color: var(--si-muted); }
.si-pill--warn    { background: var(--si-down-soft-tint); color: var(--si-down-soft); }
.si-pill--down    { background: var(--si-down-tint);      color: var(--si-down); }
/* Pre-rebrand direction colours, kept for reference:
   .si-pill--up { background: rgba(52,211,153,0.15); color: var(--si-up); }
   .si-pill--down { background: rgba(251,113,133,0.15); color: var(--si-down); } */

/* --- Landing hero (no symbol in the path) ------------------------------- */
/* Sized to its content, not to 100vh: the form is the point of this page and
   has to be in the first frame. The canvas sits behind, the wash keeps the
   type legible over whatever the animation is doing underneath. */
.si-hero {
  position: relative;
  overflow: hidden;
  min-height: 30rem;
  display: flex;
  align-items: center;
  border-bottom: 1px solid var(--si-border);
}
.si-hero__viz,
.si-hero__wash {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  pointer-events: none;
}
/* Weighted to the left, where the copy is: the labels drift across the whole
   canvas and would otherwise cross the headline. Solid behind the text,
   clearing by the time it reaches the reticle. */
.si-hero__wash {
  background:
    linear-gradient(to right, rgba(10,10,10,0.96) 0%, rgba(10,10,10,0.93) 32%,
                    rgba(10,10,10,0.62) 47%, rgba(10,10,10,0.18) 62%, rgba(10,10,10,0) 76%),
    linear-gradient(to bottom, rgba(10,10,10,0.55), rgba(10,10,10,0) 28%, rgba(10,10,10,0.75));
}
@media (max-width: 53.75rem) {
  /* Reticle is centred at this width, so the wash covers evenly instead. */
  .si-hero__wash {
    background:
      radial-gradient(70% 60% at 50% 50%, rgba(10,10,10,0.88) 0%, rgba(10,10,10,0.6) 55%, rgba(10,10,10,0.35) 100%),
      linear-gradient(to bottom, rgba(10,10,10,0.55), rgba(10,10,10,0) 28%, rgba(10,10,10,0.75));
  }
}
.si-hero__inner { position: relative; width: 100%; padding-block: 4rem; }
.si-hero__title {
  font-size: clamp(2rem, 5.5vw, 3.25rem);
  font-weight: 700;
  letter-spacing: -0.03em;
  line-height: 1.05;
  margin: 0 0 0.75rem;
  color: var(--si-text);
  text-wrap: balance;
}
.si-hero__text {
  font-size: 1rem;
  line-height: 1.6;
  color: var(--si-muted);
  margin: 0 0 1.75rem;
  max-width: 30rem;
}
.si-lookup--hero { margin: 0; max-width: 26rem; }
/* Past the daily free-lookup limit (stock-info-gate.php): the way back to the
   signup modal after it has been closed. */
.si-gate__actions { display: flex; flex-wrap: wrap; gap: 0.75rem; margin: 0 0 1.75rem; }

/* Eyebrow badge on the landing hero, carried over from the prototype. The dot
   breathes on the same 1.6s loop; it is the one piece of motion that survives
   reduced-motion being switched off, so it is switched off there too.
   Named .si-eyebrow, NOT .si-pill: that class already belongs to the rank badge
   further up this file, and reusing it silently overrode all four rank steps
   (later source order, equal specificity) so they all rendered muted grey. */
.si-eyebrow {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  border: 1px solid var(--si-border);
  background: rgba(23,23,26,0.6);
  border-radius: 999px;
  padding: 0.3125rem 0.75rem;
  margin-bottom: 1.25rem;
  font-size: 0.6875rem;
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--si-muted);
  backdrop-filter: blur(8px);
}
.si-eyebrow__dot {
  width: 0.375rem;
  height: 0.375rem;
  border-radius: 50%;
  background: var(--si-brand);
  box-shadow: 0 0 10px var(--si-brand);
  animation: si-pulse-dot 1.6s ease-in-out infinite;
}
@keyframes si-pulse-dot {
  0%, 100% { opacity: 1; transform: scale(1); }
  50%      { opacity: 0.55; transform: scale(0.85); }
}

/* Inc. 5000 proof line under the lookup. The SVG is white-filled, so it only
   works on this dark hero. */
.si-proof {
  display: flex;
  align-items: center;
  gap: 1rem;
  margin-top: 2rem;
  max-width: 30rem;
}
.si-proof__badge { flex: none; width: 5rem; height: auto; }
.si-proof__text {
  margin: 0;
  font-size: 0.8125rem;
  line-height: 1.5;
  color: var(--si-muted);
}
.si-proof__text strong { color: var(--si-text); }

/* --- Landing: "What's on a Stock Info page" ----------------------------- */
/* H2 size is the site-wide section H2 (SITE-1421); set it nowhere else. */
.si-depth,
.si-faq { padding: 4rem 0 0; }
/* Full-bleed rule between the FAQ and the closing CTA. .si-faq sits outside
   any .si-shell, so its border spans the viewport; the CTA's own top padding
   supplies the space below it. */
.si-faq {
  padding-bottom: 3.5rem;
  border-bottom: 1px solid var(--si-border);
}
/* Same full-width .si-shell as the hero, so the copy starts on the hero's left
   edge; the reading measure is capped on the children instead of the shell,
   which would centre the column. */
.si-depth .si-shell > *,
.si-faq .si-shell > * { max-width: 52rem; }
/* Scoped under .si-depth: the kicker is a <p>, and .si-depth p below would
   otherwise outrank a bare class and turn it muted grey. */
.si-depth .si-kicker {
  margin: 0 0 0.65rem;
  font-size: 0.75rem;
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--si-brand);
}
.si-depth__intro { margin-bottom: 2rem; }
.si-depth .si-depth__lede {
  margin: 0;
  max-width: 42rem;
  font-size: 1.05rem;
  line-height: 1.65;
  color: var(--si-muted);
}
.si-depth article {
  padding: 1.75rem 0;
  border-top: 1px solid var(--si-border);
}
.si-depth h2,
.si-faq h2 {
  font-size: clamp(1.5rem, 3vw, 2.125rem);
  font-weight: 500;
  letter-spacing: -0.02em;
  line-height: 1.15;
  margin: 0 0 0.75rem;
  color: var(--si-text);
}
.si-depth p {
  margin: 0 0 0.75rem;
  font-size: 0.9375rem;
  line-height: 1.65;
  color: var(--si-muted);
}
.si-depth p:last-child { margin-bottom: 0; }
/* Restated on hover/focus: core/css/main.css turns every a:hover near-black. */
.si-depth a,
.si-depth a:hover,
.si-depth a:focus { color: var(--si-brand); text-underline-offset: 2px; }

/* --- Landing FAQ -------------------------------------------------------- */
/* Card-per-question accordion, matching the compare pages' .faq. */
.si-faq h2 { margin-bottom: 1.25rem; }
.si-faq details {
  /* The compare pages' navy --card / --border, not this page's neutral
     --si-card, so the cards match theirs exactly. */
  background: #121826;
  border: 1px solid #1e2636;
  border-radius: 14px;
  padding: 1rem 1.25rem;
  margin-bottom: 0.625rem;
}
.si-faq summary {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 0.75rem;
  cursor: pointer;
  list-style: none;
  font-size: 14px;
  font-weight: 600;
  color: var(--si-text);
}
.si-faq summary::-webkit-details-marker { display: none; }
.si-faq summary::after {
  content: "+";
  flex-shrink: 0;
  font-size: 18px;
  font-weight: 700;
  color: var(--si-brand);
}
.si-faq details[open] summary::after { content: "\2212"; }
.si-faq summary:focus-visible { outline: 2px solid var(--si-accent); outline-offset: 2px; }
.si-faq details p {
  margin: 0.625rem 0 0;
  font-size: 13px;
  line-height: 1.5;
  color: var(--si-muted);
}
/* Restated on hover/focus: core/css/main.css turns every a:hover near-black. */
.si-faq details a,
.si-faq details a:hover,
.si-faq details a:focus {
  color: #4ec9b0;
  text-decoration: underline;
  text-underline-offset: 2px;
}

/* --- Closing CTA -------------------------------------------------------- */
/* Two call sites: under the landing hero, and at the foot of a symbol page
   above the disclaimer. */
.si-cta { text-align: center; padding: 3.5rem 0 5rem; }
/* On a symbol page it follows a run of cards inside .si-stack, so it needs a
   rule to separate it -- on the landing page the hero above already ends in
   one. Bottom padding drops too: the disclaimer and .si-page's own
   padding-bottom follow it there, where on the landing page it ends the page. */
.si-stack .si-cta {
  border-top: 1px solid var(--si-border);
  margin-top: 1rem;
  padding: 3rem 0 1.5rem;
}
.si-cta__title {
  font-size: clamp(1.75rem, 4vw, 2.625rem);
  font-weight: 700;
  letter-spacing: -0.03em;
  line-height: 1.1;
  margin: 0 0 0.75rem;
  color: var(--si-text);
  text-wrap: balance;
}
.si-cta__text {
  color: var(--si-muted);
  margin: 0 auto 1.375rem;
  max-width: 34rem;
  font-size: 0.9375rem;
  line-height: 1.6;
}
.si-cta__actions {
  display: flex;
  gap: 0.75rem;
  justify-content: center;
  flex-wrap: wrap;
}

/* Squared off with a soft corner rather than the prototype's pill, matching
   .si-lookup__btn directly above it -- two button shapes on one page reads as
   two different systems. The primary carries the brand amber; the glow on
   hover is the same idea as the hero canvas, which is why it is a coloured
   box-shadow rather than a generic lift.
   Was: border-radius: 999px; */
.si-btn {
  display: inline-flex;
  align-items: center;
  gap: 0.4375rem;
  border-radius: 0.5rem;
  border: 1px solid transparent;
  padding: 0.875rem 1.75rem;
  font: 600 0.9375rem/1 inherit;
  text-decoration: none;
  white-space: nowrap;
  cursor: pointer;
  transition: background 0.15s ease, border-color 0.15s ease,
              color 0.15s ease, box-shadow 0.2s ease, transform 0.12s ease;
}
.si-btn:active { transform: translateY(1px); }
.si-btn:focus-visible { outline: 2px solid var(--si-accent); outline-offset: 2px; }
.si-btn--primary {
  background: var(--si-brand);
  border-color: var(--si-brand);
  color: #0b0e14;
  font-weight: 700;
}
.si-btn--primary:hover,
.si-btn--primary:focus {
  background: #ffa645;
  border-color: #ffa645;
  box-shadow: 0 0 28px rgba(241,148,41,0.35);
  color: #0b0e14;   /* restated for the same reason as the secondary */
}
.si-btn--secondary {
  background: transparent;
  border-color: var(--si-border);
  color: var(--si-text);
}
/* Colour must be restated on hover AND focus. core/css/main.css:121 sets a
   site-wide `a:hover, a:focus { color: #111 }`, which outranks the base
   .si-btn--secondary rule at those states -- so without this the label went
   near-black on a near-black ground and disappeared, for pointer and keyboard
   alike. */
.si-btn--secondary:hover,
.si-btn--secondary:focus {
  border-color: var(--si-dim);
  background: rgba(255,255,255,0.03);
  color: var(--si-text);
}

/* .si-empty was the bare "no data for this symbol" block. Both no-data
   states now render the full hero instead, so these are unused -- kept
   commented rather than deleted in case the minimal version is wanted back.
.si-empty { padding: 3rem 0; max-width: 34rem; }
.si-empty__title { font-size: 1.75rem; font-weight: 600; margin: 0 0 0.5rem; color: var(--si-text); }
.si-empty__text { font-size: 0.9375rem; color: var(--si-muted); margin: 0; }
*/

.si-disclaimer { margin: 0.5rem 0 0; font-size: 0.6875rem; line-height: 1.6; color: var(--si-dim); }

@media (max-width: 47.99rem) {
  .si-chart__wrap { min-height: 6.75rem; }
  .si-shell { padding: 0 1rem; }
  .si-header__inner { gap: 0.875rem; }
  .si-header__meta { justify-content: flex-start; }
  .si-headstats { justify-items: start; }
  .si-price { font-size: 1.5rem; }
  .si-card { padding: 1rem 1.125rem 1.125rem; }
}

@media (prefers-reduced-motion: reduce) {
  .si-rangebtn, .si-tab { transition: none; }
  /* The canvas never starts (the script checks the same query), so hide the
     element and let the wash carry the hero on its own. */
  .si-hero__viz { display: none; }
  .si-eyebrow__dot { animation: none; }
  .si-btn { transition: none; }
  .si-btn--primary:hover { box-shadow: none; }
}
