/* ChartPanel — only the rules styles.css does not already paint.
 *
 * The heading is styles.css `.panel-title`, the note line is `.muted.small`,
 * the canvas host is `.chart` plus a height class (`.chart-sm|md|lg|xl`), and
 * the empty state reuses `.empty-note`. This file adds the panel stack and
 * the note spacing. Every colour, type size, spacing and radius comes from
 * tokens.css custom properties — no colour literal of any form lives here
 * (transparent, currentColor and inherit are allowed).
 */

.chart-panel {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  min-width: 0;
}

.chart-panel-note {
  margin-bottom: var(--space-1);
}

/* Dual-grid builders (Compare's "Price + volume"). The planned phone height
 * for two stacked grids is --chart-h-dual (380px), not --chart-h-xl (300px).
 * Pass heightClass: "chart-dual" to mount() to pick it up — the Compare view
 * switches over in wave 2; nothing else changes here. */
.chart-dual {
  height: var(--chart-h-dual);
}

/* Phone legend (MOBILE_PLAN.md §2.6). Inserted above the canvas only in the
 * compact layout and removed again on the way back to desktop, so a desktop
 * panel's child order is unchanged. One `button[aria-pressed]` per series: a
 * swatch whose colour is set at runtime via `--swatch` (from the option's
 * itemStyle.color) plus the symbol text, with a 44 px hit area. */
.chart-legend {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-1) var(--space-2);
  min-width: 0;
}

.chart-legend-item {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  min-height: var(--hit-min);
  min-width: var(--hit-min);
  padding: var(--space-2);
  border: 0;
  border-radius: var(--radius);
  background: none;
  color: var(--text-soft);
  font: inherit;
  font-size: var(--fs-label);
  cursor: pointer;
}

.chart-legend-item[aria-pressed="false"] {
  color: var(--text-muted);
  opacity: 0.55;
}

.chart-legend-swatch {
  width: var(--space-3);
  height: var(--space-3);
  flex: none;
  border-radius: var(--radius-sm);
  background: var(--swatch, transparent);
}

.chart-legend-name {
  white-space: nowrap;
}

/* ---- T120 TradingView chart overlay (the shared "tap a ticker" panel) ----
 *
 * Two hosts share one body: components/sheet.js (size "full") on phones and a
 * NON-MODAL side panel (aside.tvp-side) at 768 px and up. The desktop host is
 * deliberately not components/modal.js — a modal dialog runs showModal(), which
 * makes the rest of the page inert, and an inert page can never deliver the
 * second tap that switches this panel. The side panel is a plain fixed aside:
 * no dialog, no backdrop, the page behind it stays live and the content rows
 * below the top bar shift left (body.tvp-side-open .main > :not(.topbar)) by
 * the panel's own width so no ticker column is ever covered. What lives here
 * is the two hosts' geometry, the body stack, the Open in TradingView link's
 * 44 px target and the chart host. Every
 * colour, type size, spacing and radius comes from tokens.css — no colour
 * literal of any form (transparent, currentColor and inherit are allowed).
 */

/* Desktop host: fixed to the right, ~40% of the width (min 420, max 720),
   full height below the top bar. `--tvp-side-top` is the measured top bar
   height, set on the element at open time; 0 when it cannot be measured. The
   aside is the column flex container: the head row and the body's chrome
   (title, name, link) take their own height and the chart host takes the
   rest — the two overrides further down are what make that chain work. */
.tvp-side {
  position: fixed;
  top: var(--tvp-side-top, 0px);
  right: 0;
  height: calc(100dvh - var(--tvp-side-top, 0px));
  width: clamp(420px, 40vw, 720px);
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
  padding: var(--space-4);
  background: var(--panel);
  border-left: 1px solid var(--panel-border);
  overflow: auto;
  z-index: 4; /* under the sticky top bar (z-index 5) */
}

/* The page content below the top bar makes room by exactly the panel's
   width — the same clamp, so the two can never drift apart and leave a
   ticker column underneath. Two deliberate differences from padding the
   whole of `.main`:

   - `:not(.topbar)` keeps the sticky top bar out of the inset. Narrowing
     `.main` narrowed the bar with it, so at 1440 the bar wrapped from one
     row to two (about 44 px to 90 px), the whole page jumped down when the
     panel opened and snapped back when it closed, and the shortened bar
     left an empty strip of page background to its right, above the panel.
     With the bar left alone its width and height are the same in both
     states — no jump — and it spans the full width, so the panel's top
     meets it with no gap and no strip.
   - the inset is a margin, not padding: each row keeps its own
     `padding-inline`, so the content keeps the 16 px gap to the panel's
     left edge instead of butting against it. */
body.tvp-side-open .main > :not(.topbar) {
  margin-right: clamp(420px, 40vw, 720px);
}

.tvp-side-head {
  display: flex;
  align-items: center;
  justify-content: flex-end;
  gap: var(--space-2);
  min-height: 0;
}

.tvp-side-close {
  appearance: none;
  -webkit-appearance: none;
  border: 0;
  background: none;
  margin: 0;
  padding: 0;
  color: var(--muted);
  font: inherit;
  font-size: var(--fs-title);
  line-height: 1;
  cursor: pointer;
  min-width: var(--hit-min);
  min-height: var(--hit-min);
  border-radius: var(--radius);
}

.tvp-side-close:hover {
  color: var(--ink);
}

.tvp-side-close:focus-visible {
  outline: 2px solid var(--focus-ring);
  outline-offset: 2px;
}

.tvp-body {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  min-width: 0;
}

.tvp-title {
  margin: 0;
  font-size: var(--fs-title);
  font-weight: var(--fw-semibold);
  color: var(--ink);
}

.tvp-name {
  margin: 0;
}

/* The one way out of the panel: a user navigation, 44 px tall. */
.tvp-link {
  display: inline-flex;
  align-items: center;
  align-self: flex-start;
  min-height: var(--hit-min);
  padding: var(--space-1) 0;
  color: var(--accent);
  font-size: var(--fs-small);
  font-weight: var(--fw-semibold);
  text-decoration: none;
}

.tvp-link:hover {
  text-decoration: underline;
}

.tvp-link:focus-visible {
  outline: 2px solid var(--focus-ring);
  outline-offset: 2px;
}

.tvp-unavailable {
  margin: 0;
  color: var(--muted);
  font-size: var(--fs-small);
}

/* The widget host: the TradingView iframe fills it (autosize). On a phone it
   is a viewport-relative block; inside the full-height side panel it just
   takes whatever height is left. */
.tvp-chart {
  width: 100%;
  min-width: 0;
  height: clamp(16rem, 58dvh, 44rem);
  min-height: 16rem;
  border: 1px solid var(--panel-border);
  border-radius: var(--radius);
}

/* Inside the full-height side panel the height is the panel's, not the
   viewport's, so the base rule's clamp is dropped and the chart host takes
   whatever the chrome leaves. The chain has two links and both are needed:
   `.tvp-body` must flex inside `.tvp-side` (with min-height: 0 so it can
   shrink instead of pushing the panel taller), and `.tvp-chart` must flex
   inside `.tvp-body`. With only the second one the body stayed as tall as
   its own content, the chart had nothing to grow into and stopped at the
   base rule's 16 rem floor — about half of an 810 px panel was empty. The
   injected widget follows with autosize, i.e. 100% of this host. */
.tvp-side .tvp-body {
  flex: 1 1 auto;
  min-height: 0;
}

.tvp-side .tvp-chart {
  height: auto;
  min-height: 0;
  flex: 1 1 auto;
}

/* The per-row chart trigger (chartButton()): a SMALL inline icon. It must not
   grow a dense desktop row — the Dashboard Movers rows are 33 px on
   origin/main and a min-height here took them to 47. The >=44 px target is
   painted rather than laid out: a transparent ::after under (pointer: coarse)
   / phones, the same pattern as the ⓘ in views/holdings.css, so the box (and
   the row) keep their size while the thumb gets its 44 px. */
.chart-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex: none;
  position: relative;
  padding: 0;
  border: 0;
  background: none;
  color: var(--muted);
  cursor: pointer;
}

.chart-btn svg {
  display: block;
}

.chart-btn:hover {
  color: var(--ink);
}

button.chart-btn:focus-visible {
  outline: 2px solid var(--focus-ring);
  outline-offset: 2px;
}

@media (pointer: coarse), (max-width: 767.98px) {
  .chart-btn::after {
    content: "";
    position: absolute;
    left: 50%;
    top: 50%;
    transform: translate(-50%, -50%);
    width: max(100%, var(--hit-min));
    height: max(100%, var(--hit-min));
    pointer-events: auto;
    z-index: 1;
  }
}
