
/* Primary navigation rail.
   Vertical on desktop: charts are wide and short, so height is the scarce axis
   on the homepage grid and width is comparatively cheap. Moving destinations
   off the top bar hands their vertical space back to the charts. */
.site-rail {
  position: fixed;
  top: var(--bar-height);
  left: 0;
  bottom: 0;
  z-index: 45;
  width: var(--rail-width);
  padding: 0.5rem 0.4rem;
  border-right: 1px solid var(--border);
  background: var(--chrome-bg);
  backdrop-filter: blur(8px);
  overflow-y: auto;
  box-sizing: border-box;
  /* Column so the toggle can sit at the foot of the rail. */
  display: flex;
  flex-direction: column;
  gap: 0.4rem;
  transition: width 0.16s ease, box-shadow 0.16s ease;
  /* Signals that empty rail space (not a link) is clickable — it toggles
     collapse/expand, same as the edge handle. */
  cursor: pointer;
}

/* Collapsed. The flag lives on <html> because --rail-width also drives
   .site-shell's left inset — the page, not just the nav, has to resize. An
   inline script in <head> sets it before first paint to avoid a flash. */
html[data-rail-collapsed="true"] {
  --rail-width: 3.1rem;
}

.site-rail__list {
  display: flex;
  flex-direction: column;
  gap: 0.1rem;
  margin: 0;
  padding: 0;
  list-style: none;
}

.site-rail__link {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  padding: 0.42rem 0.5rem;
  border-radius: 4px;
  color: var(--ink-mute);
  font-size: 0.78rem;
  line-height: 1.2;
  text-decoration: none;
  transition:
    color 0.15s ease,
    background-color 0.15s ease;
}

.site-rail__link:hover {
  color: var(--ink-soft);
  background: var(--surface-overlay);
}

.site-rail__link.is-active {
  color: var(--ink);
  background: color-mix(in srgb, var(--accent) 12%, transparent);
}

.site-rail__link:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: -2px;
}

.site-rail__icon {
  display: inline-flex;
  flex: none;
  /* Icons are decoration only — every item ships a visible label, because
     "Market bottom" and "Tech Pulse" are not distinguishable as glyphs. */
  color: currentColor;
}

.site-rail__label {
  min-width: 0;
}

/* Edge handle straddling the rail's right border.
   Positioned against the viewport rather than the nav, so it stays put while
   the destination list scrolls. The hit area is ~15px wide while the visible
   sliver is a hairline — a target this thin is otherwise fiddly to click. */
.site-rail__handle {
  position: fixed;
  top: var(--bar-height);
  bottom: 0;
  left: calc(var(--rail-width) - 9px);
  z-index: 46;
  width: 19px;
  padding: 0;
  border: 0;
  background: none;
  cursor: pointer;
  display: flex;
  /* Grip sits near the top, level with the first destination — the primary
     scan path. Dead-centre on a full-height rail is easy to miss. */
  align-items: flex-start;
  justify-content: center;
  padding-top: 0.78rem;
  -webkit-tap-highlight-color: transparent;
}

/* The sliver, drawn as a pseudo-element so the button's wider hit area stays
   invisible. Visible at rest rather than hover-only — a transparent edge gives
   no hint that anything is clickable. */
.site-rail__handle::before {
  content: "";
  position: absolute;
  top: 0;
  bottom: 0;
  left: 9px;
  width: 2px;
  background: var(--hairline);
  transition: background-color 0.15s ease;
}

.site-rail__handle:hover::before,
.site-rail__handle:focus-visible::before {
  background: var(--accent);
}

/* Round control seated on the seam. Fully opaque with its own surface and
   border so it reads as a button rather than as decoration on the divider. */
.site-rail__handle-grip {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  position: relative;
  width: 22px;
  height: 22px;
  border: 1px solid var(--hairline-strong);
  border-radius: 999px;
  background: var(--surface-overlay);
  box-shadow: 0 1px 4px rgb(0 0 0 / 0.45);
  color: var(--ink-soft);
  transition:
    color 0.15s ease,
    background-color 0.15s ease,
    border-color 0.15s ease,
    transform 0.18s ease;
}

.site-rail__handle:hover .site-rail__handle-grip,
.site-rail__handle:focus-visible .site-rail__handle-grip {
  color: var(--bg);
  background: var(--accent);
  border-color: var(--accent);
}

.site-rail__handle:focus-visible {
  outline: none;
}

.site-rail__handle:focus-visible .site-rail__handle-grip {
  outline: 2px solid var(--accent);
  outline-offset: 1px;
}

/* Collapsed: icons only. Labels stay in the DOM and are merely taken out of
   the visual flow, so screen readers still announce each destination — the
   glyphs alone would not distinguish "Market bottom" from "Tech Pulse". */
html[data-rail-collapsed="true"] .site-rail__label {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

html[data-rail-collapsed="true"] .site-rail__link {
  justify-content: center;
  gap: 0;
}

html[data-rail-collapsed="true"] .site-rail__handle-grip {
  transform: rotate(180deg);
}

@media (prefers-reduced-motion: reduce) {
  .site-rail {
    transition: none;
  }

  .site-rail__handle-grip {
    transition: opacity 0.15s ease, color 0.15s ease;
  }
}

/* Below the rail breakpoint the rail lies down into a scrolling strip beneath
   the bar, which is close to how the old wrapped nav row behaved. */
@media (max-width: 720px) {
  :root {
    --rail-width: 0rem;
    --rail-strip-height: 2.4rem;
  }

  .site-rail {
    top: var(--bar-height);
    bottom: auto;
    right: 0;
    width: auto;
    height: var(--rail-strip-height);
    padding: 0 0.5rem;
    border-right: 0;
    border-bottom: 1px solid var(--border);
    overflow-x: auto;
    overflow-y: hidden;
    scrollbar-width: none;
  }

  .site-rail::-webkit-scrollbar {
    display: none;
  }

  .site-rail__list {
    flex-direction: row;
    align-items: center;
    height: 100%;
    gap: 0.15rem;
  }

  .site-rail__link {
    white-space: nowrap;
  }

  .site-rail__icon {
    display: none;
  }

  /* The strip is already compact and has no width to reclaim, so collapsing is
     meaningless here. Hide the control and undo the collapsed state, in case
     the flag was stored on a wider screen. */
  .site-rail__handle {
    display: none;
  }

  html[data-rail-collapsed="true"] .site-rail__label {
    position: static;
    width: auto;
    height: auto;
    margin: 0;
    overflow: visible;
    clip-path: none;
  }

  html[data-rail-collapsed="true"] .site-rail__link {
    justify-content: flex-start;
  }
}

/* flex-grow: 0 (rather than the old 1) keeps this from expanding to fill
   the row itself — centering comes from .site-bar__start/__end (see
   indicator_and_scout.css) claiming equal space on either side, not from
   this element growing. Overridden back to a full-width row at 640px. */
.stock-search {
  position: relative;
  flex: 0 1 16rem;
  min-width: 8.5rem;
  max-width: 16rem;
}

.stock-search__input {
  width: 100%;
  margin: 0;
  padding: 0.28rem 2.9rem 0.28rem 0.65rem;
  border: 1px solid var(--border);
  border-radius: 8px;
  background: var(--panel-inset);
  color: var(--text);
  font: inherit;
  font-size: 0.78rem;
  line-height: 1.3;
}

.stock-search__input::placeholder {
  color: var(--muted);
}

.stock-search__input:focus {
  outline: none;
  border-color: color-mix(in srgb, var(--accent) 55%, var(--border));
  box-shadow: 0 0 0 2px color-mix(in srgb, var(--accent) 22%, transparent);
}

/* Hints that tapping Shift alone jumps focus here (see stock_search_controller.js).
   Fades out once the box is actually in use so it never fights live results. */
.stock-search__hint {
  position: absolute;
  top: 50%;
  right: 0.45rem;
  transform: translateY(-50%);
  margin: 0;
  padding: 0.1rem 0.4rem;
  border: 1px solid var(--border);
  border-radius: 5px;
  background: var(--panel-raised);
  color: var(--muted);
  font-family: var(--mono);
  font-size: 0.62rem;
  font-weight: 500;
  line-height: 1.3;
  pointer-events: none;
}

.stock-search__input:focus ~ .stock-search__hint,
.stock-search__input:not(:placeholder-shown) ~ .stock-search__hint {
  display: none;
}

.stock-search__results {
  position: absolute;
  top: calc(100% + 0.3rem);
  left: 0;
  right: 0;
  z-index: 50;
  margin: 0;
  padding: 0.25rem;
  list-style: none;
  border: 1px solid var(--border);
  border-radius: 10px;
  background: var(--panel-raised);
  box-shadow: 0 12px 28px rgba(0, 0, 0, 0.35);
  max-height: min(20rem, 60vh);
  overflow-y: auto;
}

.stock-search__item {
  display: grid;
  grid-template-columns: auto 1fr;
  grid-template-rows: auto auto;
  column-gap: 0.55rem;
  row-gap: 0.05rem;
  width: 100%;
  margin: 0;
  padding: 0.4rem 0.5rem;
  border: 0;
  border-radius: 7px;
  background: transparent;
  color: inherit;
  font: inherit;
  text-align: left;
  cursor: pointer;
}

.stock-search__item:hover,
.stock-search__item.is-active {
  background: color-mix(in srgb, var(--accent) 14%, transparent);
}

.stock-search__symbol {
  grid-row: 1 / span 2;
  align-self: center;
  font-family: var(--mono);
  font-size: 0.78rem;
  font-weight: 500;
  color: var(--accent);
}

.stock-search__name {
  font-size: 0.78rem;
  color: var(--text);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.stock-search__meta {
  font-size: 0.68rem;
  color: var(--muted);
}

.stock-search__empty {
  padding: 0.55rem 0.65rem;
  font-size: 0.78rem;
  color: var(--muted);
}

.site-bar__ai-item {
  position: relative;
}

.site-bar__ai-toggle {
  margin: 0;
  padding: 0;
  border: 0;
  background: transparent;
  color: var(--muted);
  font: inherit;
  font-size: 0.8rem;
  cursor: pointer;
}

.site-bar__ai-toggle:hover,
.site-bar__ai-toggle[aria-expanded="true"] {
  color: var(--accent);
}

/* The persistent rail (indicator_and_scout.css) replaces this entry point
   at 1080px+; below that it's still the only way to reach the drawer. */
@media (min-width: 1080px) {
  .site-bar__ai-toggle {
    display: none;
  }
}

.page-footer {
  margin-top: clamp(2.5rem, 6vw, 4rem);
  border-top: 1px solid var(--border);
  background: var(--chrome-bg);
}

.page-footer__inner {
  max-width: var(--shell-max);
  margin: 0 auto;
  padding: 2.25rem 1rem 1rem;
  box-sizing: border-box;
}

/* Identity on the left, link directory filling the rest. The identity column
   is fixed so the directory columns stay aligned across breakpoints. */
.page-footer__top {
  display: grid;
  grid-template-columns: minmax(0, 15rem) minmax(0, 1fr);
  gap: 2rem 3.5rem;
  padding-bottom: 2rem;
}

.page-footer__identity {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 0.7rem;
}

.page-footer__brand {
  color: var(--ink);
  font-family: var(--mono);
  font-size: 0.95rem;
  font-weight: 500;
  letter-spacing: 0.14em;
  text-decoration: none;
}

.page-footer__brand:hover {
  color: var(--accent);
}

.page-footer__tagline {
  margin: 0;
  /* Capped in ch so the line length stays readable, not tied to the column. */
  max-width: 32ch;
  color: var(--ink-mute);
  font-size: 0.82rem;
  line-height: 1.45;
}

.page-footer__social {
  display: flex;
  gap: 0.4rem;
  margin: 0.15rem 0 0;
  padding: 0;
  list-style: none;
}

.page-footer__social-link {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 2rem;
  height: 2rem;
  border: 1px solid var(--hairline);
  border-radius: 4px;
  color: var(--ink-mute);
  text-decoration: none;
  transition:
    color 0.15s ease,
    border-color 0.15s ease,
    background-color 0.15s ease;
}

.page-footer__social-link:hover {
  color: var(--ink);
  border-color: var(--hairline-strong);
  background: var(--surface-overlay);
}

/* Rendered while a social account has no URL yet — visible but inert. */
.page-footer__social-link--stub {
  color: var(--ink-faint);
  border-color: var(--hairline-ghost);
  border-style: dashed;
  cursor: default;
}

.page-footer__eyebrow {
  margin: 0 0 1.1rem;
  color: var(--muted);
  font-family: var(--mono);
  font-size: 0.72rem;
  letter-spacing: 0.04em;
  text-transform: uppercase;
}

.page-footer__groups {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 1.5rem 2rem;
}

.page-footer__label {
  margin: 0 0 0.55rem;
  color: var(--text);
  font-size: 0.78rem;
  font-weight: 600;
}

.page-footer__links {
  display: grid;
  gap: 0.35rem;
  list-style: none;
  margin: 0;
  padding: 0;
}

.page-footer__links a {
  color: var(--muted);
  font-size: 0.88rem;
  text-decoration: none;
}

.page-footer__links a:hover {
  color: var(--accent);
}

.page-footer__bar {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 0.5rem 1.5rem;
  padding-top: 1rem;
  border-top: 1px solid var(--hairline-ghost);
}

.page-footer__legal {
  margin: 0;
  color: var(--ink-faint);
  font-size: 0.76rem;
  line-height: 1.4;
}

@media (max-width: 1080px) {
  .page-footer__top {
    grid-template-columns: 1fr;
    gap: 1.75rem;
  }
}

@media (max-width: 720px) {
  .page-footer__groups {
    grid-template-columns: 1fr;
    gap: 1.25rem;
  }

  .page-footer__bar {
    justify-content: flex-start;
  }
}

.reports-page {
  /* Wider than a single report so the generate form and example list can sit side by side. */
  width: min(100% - 2rem, 1120px);
  margin: 0 auto;
  padding: clamp(1.5rem, 4vw, 2.75rem) 0 3rem;
}

.pricing-page {
  width: min(100% - 2rem, 920px);
  margin: 0 auto;
  padding: 0.85rem 0 2rem;
}

.report-page {
  width: min(100% - 2rem, 880px);
  margin: 0 auto;
  padding: clamp(2.5rem, 7vw, 5.5rem) 0 4rem;
}

.stock-page {
  /* Charts want width; prose sections below keep their own readable max. */
  width: min(100% - 1.25rem, var(--shell-max));
  margin: 0 auto;
  padding: 0.4rem 0 2rem;
}
