/* Tracker page.
 *
 * Layout only — the cards themselves are built from the shared .card / .stat /
 * .delta anatomy in components/cards.css, so a page redesigned in a later
 * chunk gets the same pieces without copying them.
 *
 * The grid is a plain 12-column CSS grid with a --span per card. That is
 * enough for a fixed layout, and deliberately less machinery than a drag-and-
 * resize engine: the arrangement is decided, not user-managed, until there is
 * a reason for it to be otherwise. */

.tracker-page {
  padding: 28px 28px 80px;
  overflow-y: auto;

  /* The page is sized by its PANE, not by the window. #content can hold two
     panes side by side (components/split-pane.js), and the Tracker is a
     popout target besides — so a viewport media query is measuring the wrong
     box. At 1600px split down the middle every breakpoint below reads "wide"
     while the grid is actually ~700px, and three cards across a 700px column
     is where the figures start running into each other.

     Naming the container rather than relying on the nearest one keeps these
     queries pointed at the page even though .tracker-card is a container too.

     Not on .pane: container-type implies layout containment, which makes the
     element a containing block for position:fixed descendants. Half the pages
     in here open fixed-position modals from inside a pane. Scoping the
     container to this page keeps that blast radius at zero. */
  container: tracker / inline-size;
}

/* ── Typed greeting ────────────────────────────────────────────────────────
   The line starts empty and fills in a character at a time (tracker-dashboard.js).
   min-height holds the line box open while it is empty, otherwise the whole
   header would jump down when the first letter lands. It matches .page-title's
   line-height and is in em, so it tracks the font size rather than a magic
   pixel value. */
.tracker-greeting {
  min-height: 1.15em;
}

/* A caret, only while typing. steps(1) makes it blink like a terminal cursor
   rather than fade like a notification. */
.tracker-greeting.is-typing .greeting-typed::after {
  content: '';
  display: inline-block;
  width: 2px;
  height: 0.82em;
  margin-left: 3px;
  vertical-align: -0.06em;
  background: var(--gold);
  animation: greeting-caret 1s steps(1) infinite;
}

@keyframes greeting-caret { 50% { opacity: 0; } }

/* ── Card grid ─────────────────────────────────────────────────────────────
   3 / 3 / 2 / 1 across four rows at full width.

   Cards never scroll internally and never clip: a card grows to fit what is
   in it. Rows stay level because grid stretches them, not because anything is
   locked to a fixed height. */
.tracker-grid {
  display: grid;
  grid-template-columns: repeat(12, minmax(0, 1fr));
  gap: 14px;
  align-items: stretch;
  margin-bottom: 8px;
}

.tracker-card {
  grid-column: span var(--span, 4);
  min-width: 0;

  /* A second, narrower container. The page decides how many cards fit across;
     only the card knows how much room a figure actually got, and at any given
     page width the row of three and the row of two hand out different amounts.
     Rules keyed to this are in "── Figures in a narrow card" below. */
  container: tracker-card / inline-size;
}

/* Two steps down, not a jump straight to one column: at middling widths three
   cards across leaves each too narrow to read a chart in, but two is fine.

   The numbers are the page's own width, not the window's — 980px is roughly
   what a 1180px window used to leave once the sidebar and this page's padding
   came out of it, so a maximised window breaks where it always did while a
   half-width pane now breaks when it actually needs to. */
@container tracker (max-width: 980px) {
  .tracker-card { grid-column: span 6; }
  .tracker-card[data-card="calendar"] { grid-column: span 12; }
}

@container tracker (max-width: 620px) {
  .tracker-grid { gap: 12px; }
  .tracker-card { grid-column: span 12; }
}

/* Two things that stay on the viewport.

   Padding, because an element cannot query itself — and it only decides
   margins, never whether content collides, so approximate is fine.

   And a one-column floor, as the fallback for a browser with no @container
   support (before Chrome 105 / Safari 16 / Firefox 110). Everything above is
   invisible to such a browser, which would otherwise leave it on three cards
   across at every width — worse than the viewport rules this replaced. This
   cannot fight the container queries: the page is never wider than the window,
   so a 760px viewport means a container under 620px, where the rule above says
   span 12 already. The two only ever agree. */
@media (max-width: 760px) {
  .tracker-page { padding: 20px 16px 60px; }
  .tracker-grid { gap: 12px; }
  .tracker-card { grid-column: span 12; }
}

/* ── Figures in a narrow card ───────────────────────────────────────────────
   Where the overlap came from. .stat-pair is a 1fr 1fr grid and .stat-value is
   27px, and a full-precision figure like $1,284,900 has no space in it — so it
   cannot wrap, and with nothing capping it the number simply ran on past its
   column and into the one beside it. Wide enough and you never see it; in a
   split pane the columns are ~110px and both figures collide every time.

   Three defences, in order of how much they cost the reader:

   1. Shrink the type with the card. cqi is 1% of the card's content box, so
      8cqi is ~24px in a comfortable card and bottoms out at the clamp floor
      in a cramped one. Scoped to .tracker-card, so the shared .stat-value in
      Team/Admin keeps its fixed sizes and its own viewport step.
   2. Stack the pair once side-by-side stops being honest. Two figures over
      each other still read as one subject; two figures overlapping do not.
   3. Break mid-number as a last resort. Ugly, and deliberately last — but a
      wrapped figure can still be read and an overlapped one cannot. */

.tracker-card .stat-value {
  font-size: clamp(17px, 8cqi, 27px);
}

.tracker-card .stat-value,
.tracker-card .chart-meter-pct,
.tracker-card .card-foot {
  overflow-wrap: anywhere;
}

@container tracker-card (max-width: 250px) {
  .stat-pair { grid-template-columns: 1fr; }
}

/* ── Header controls ────────────────────────────────────────────────────── */

.tracker-custom-range {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  flex-wrap: wrap;
}
/* inline-flex overrides the UA's [hidden] { display: none }, so the date
   inputs leak through on every non-Custom timeframe unless this re-asserts it. */
.tracker-custom-range[hidden] { display: none; }

.tracker-range-sep {
  font-size: 12px;
  color: var(--text-dim);
}

.tracker-date {
  /* Native date inputs size themselves from their content and ignore width on
     some platforms; a fixed basis keeps the header row from reflowing when a
     range is filled in. max-width lets that basis give way rather than push
     the whole control cluster off the side of a narrow pane — .page-header-
     actions is flex-shrink: 0, so without this there is nothing to yield. */
  width: 148px;
  max-width: 100%;
  font-family: var(--font-body);
}

/* Two date inputs, a select and the gear will not sit beside a greeting in a
   half-width pane. Let the cluster take its own row and wrap inside itself —
   the same thing the 720px viewport rule in layout.css does for a phone. */
@container tracker (max-width: 620px) {
  .page-header-actions { margin-left: 0; width: 100%; flex-wrap: wrap; }
}

#callback-bells {
  display: inline-flex;
  align-items: center;
  gap: 4px;
}

.callback-bell {
  background: none;
  border: none;
  font-size: 20px;
  cursor: pointer;
  padding: 0 2px;
  line-height: 1;
  animation: bell-swing 0.5s ease-in-out;
}

.callback-bell:hover { transform: scale(1.15); }

@keyframes bell-swing {
  0%   { transform: rotate(0deg); }
  20%  { transform: rotate(-15deg); }
  40%  { transform: rotate(12deg); }
  60%  { transform: rotate(-8deg); }
  80%  { transform: rotate(5deg); }
  100% { transform: rotate(0deg); }
}

@media (prefers-reduced-motion: reduce) {
  .callback-bell { animation: none; }
}

/* ── In-card controls ───────────────────────────────────────────────────── */

/* The apps ↔ AP pair in the Carriers card head. A segmented pair rather than
   two independent buttons, because they are one choice with two states. */
.tracker-toggle {
  border: 1px solid var(--border);
  background: var(--surface);
  color: var(--text-muted);
  font-family: var(--font-body);
  font-size: 11.5px;
  font-weight: 600;
  padding: 3px 9px;
  cursor: pointer;
  transition: background var(--speed), color var(--speed), border-color var(--speed);
}
.tracker-toggle:first-of-type {
  border-radius: var(--radius-pill) 0 0 var(--radius-pill);
  border-right-width: 0;
}
.tracker-toggle:last-of-type {
  border-radius: 0 var(--radius-pill) var(--radius-pill) 0;
}
.tracker-toggle:hover { color: var(--text); }
.tracker-toggle.is-active {
  background: var(--gold-soft);
  border-color: var(--gold);
  color: var(--gold);
}
/* The active half owns the shared edge, or the border between them reads as
   belonging to the inactive side. */
.tracker-toggle.is-active:first-of-type { border-right-width: 1px; margin-right: -1px; }

.tracker-goal-row {
  display: flex;
  align-items: baseline;
  gap: 10px;
  flex-wrap: wrap;
}

.tracker-goal-set {
  display: inline-flex;
  align-items: baseline;
  gap: 6px;
  font-size: 13px;
  color: var(--text-muted);
}

.tracker-goal-input {
  width: 76px;
  padding: 5px 8px;
  font-family: var(--font-body);
  font-size: 14px;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  color: var(--text);
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-control);
}

.tracker-goal-input:focus {
  outline: 2px solid var(--gold);
  outline-offset: 1px;
  border-color: var(--gold);
}

/* ── Activity goal, one row per product line ────────────────────────────────
   Only rendered when the Tracker is showing every line at once. Each block is
   a label-and-goal head with its own meter under it; a line with no goal set
   is head-only, so the card doesn't fill with empty tracks that read as "0%
   of nothing" when the truth is "no target yet".

   The gap is on the block, not between blocks, because the last block must not
   add trailing space under the card's final meter. */
.tracker-goal-line {
  display: flex;
  flex-direction: column;
  gap: 6px;
}

/* .card-body already puts 10px between these blocks; this tops it up so the
   space BETWEEN lines clearly beats the 6px inside one, and each line reads as
   a unit instead of the six rows reading as one list. */
.tracker-goal-line + .tracker-goal-line { margin-top: 6px; }

.tracker-goal-line-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 10px;
}

/* The line's own name is the row's subject, so it carries the weight the
   single-bar layout gives to its headline figure — at a size that lets three
   of these stack inside a span-4 card without the card outgrowing the gauge
   and the donut it sits between. */
.tracker-goal-line-name {
  font-size: 13px;
  font-weight: 600;
  letter-spacing: 0.02em;
  color: var(--text);
}

.tracker-goal-line .tracker-goal-set {
  font-size: 11.5px;
  color: var(--text-dim);
  flex: none;
}

.tracker-goal-line .tracker-goal-input {
  width: 62px;
  padding: 3px 6px;
  font-size: 12.5px;
}

.tracker-goal-line-count {
  font-size: 13px;
  font-weight: 600;
  color: var(--text);
  font-variant-numeric: tabular-nums;
}

/* Three meters in a column is a lot of bar. Slimming the track and the
   percentage keeps the stack readable as a set rather than as three separate
   announcements — the comparison between lines is the point here, which is
   not what the single-bar layout is doing. */
.tracker-goal-line .chart-meter { gap: 5px; }
.tracker-goal-line .chart-meter-track { height: 8px; }
.tracker-goal-line .chart-meter-pct { font-size: 14px; }

/* The head above already says "12 of 20". The meter keeps its percentage,
   which is the thing the head does not say. */
.tracker-goal-line .chart-meter-of { display: none; }

.tracker-band-row {
  display: flex;
  gap: 10px;
  flex-wrap: wrap;
  margin-top: 2px;
}

.tracker-band-field {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-size: 11.5px;
  color: var(--text-dim);
}

.tracker-band-field .tracker-goal-input {
  width: 68px;
  font-size: 12.5px;
  padding: 4px 7px;
}

/* Quiet text button used inside cards ("+3 more"). Not .btn-* — those are
   sized for a header row and would dominate a card footer. */
.tracker-inline-btn {
  align-self: flex-start;
  border: 0;
  background: transparent;
  padding: 2px 0;
  font-family: var(--font-body);
  font-size: 12px;
  font-weight: 600;
  color: var(--gold);
  cursor: pointer;
}
.tracker-inline-btn:hover { text-decoration: underline; }

/* ── Calendar card ──────────────────────────────────────────────────────── */

.tracker-cal-list {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(240px, 1fr));
  gap: 2px 12px;
}

.tracker-cal-item {
  display: flex;
  align-items: baseline;
  gap: 10px;
  width: 100%;
  padding: 7px 8px;
  border: none;
  background: transparent;
  border-radius: var(--radius-control);
  text-align: left;
  cursor: pointer;
  font-family: var(--font-body);
  color: var(--text);
}
.tracker-cal-item:hover { background: var(--hover); }

.tracker-cal-when {
  display: flex;
  flex-direction: column;
  flex: 0 0 auto;
  min-width: 62px;
  line-height: 1.2;
}
.tracker-cal-date { font-size: 11.5px; font-weight: 700; }
.tracker-cal-time { font-size: 10.5px; color: var(--text-dim); }

.tracker-cal-name {
  flex: 1 1 auto;
  min-width: 0;
  font-size: 13px;
  font-weight: 500;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* ── Settings popover ───────────────────────────────────────────────────── */

.tracker-edit-wrap {
  position: relative;
  display: flex;
  align-items: center;
}

.tracker-edit-popover {
  position: absolute;
  top: calc(100% + 8px);
  right: 0;
  z-index: 500;
  width: 290px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-card);
  box-shadow: var(--shadow-pop);
  padding: 12px 0 8px;
}
.tracker-edit-popover[hidden] { display: none; }

.edit-menu-header {
  padding: 0 14px 8px;
  font-weight: 600;
  font-size: 13px;
  color: var(--text);
}

.edit-menu-section {
  padding: 10px 14px 12px;
  border-top: 1px solid var(--border-light);
}

.edit-menu-section-title {
  font-size: 10.5px;
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--text-dim);
  margin-bottom: 8px;
}

.edit-menu-hint {
  margin: 8px 0 0;
  font-size: 11px;
  line-height: 1.45;
  color: var(--text-dim);
}

.edit-menu-radio,
.edit-menu-check {
  display: flex;
  align-items: flex-start;
  gap: 8px;
  padding: 6px 0;
  font-size: 13px;
  color: var(--text);
  cursor: pointer;
}
.edit-menu-radio input,
.edit-menu-check input {
  margin: 2px 0 0;
  cursor: pointer;
  flex-shrink: 0;
}

.edit-menu-radio-hint {
  color: var(--text-dim);
  font-size: 11px;
  font-weight: 400;
}

.edit-menu-segmented {
  display: inline-flex;
  background: var(--bg-warm);
  border-radius: var(--radius-control);
  padding: 2px;
  gap: 2px;
  width: 100%;
}

.edit-menu-seg {
  flex: 1;
  background: transparent;
  border: 0;
  font: inherit;
  font-size: 12px;
  font-weight: 500;
  color: var(--text-muted);
  padding: 6px 8px;
  border-radius: calc(var(--radius-control) - 3px);
  cursor: pointer;
  transition: background-color var(--speed), color var(--speed);
}
.edit-menu-seg:hover { color: var(--text); }
.edit-menu-seg.is-active {
  background: var(--surface);
  color: var(--text);
  box-shadow: var(--shadow-card);
}

/* ── Forecast simulator ─────────────────────────────────────────────────── */

.forecast-section {
  margin-top: 20px;
  border: 1px solid var(--border);
  border-radius: var(--radius-card);
  background: var(--surface);
  box-shadow: var(--shadow-card);
  overflow: hidden;
}

.forecast-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 16px 20px;
  cursor: pointer;
  user-select: none;
}

.forecast-header-right {
  display: flex;
  align-items: center;
  gap: 8px;
}

.forecast-header-title {
  font-family: var(--font-display);
  font-size: 15px;
  font-weight: 600;
  color: var(--text);
}

.forecast-edit-btn {
  display: none;
  align-items: center;
  justify-content: center;
  width: 26px;
  height: 26px;
  border-radius: var(--radius-control);
  background: none;
  border: 1px solid var(--border);
  color: var(--text-muted);
  cursor: pointer;
  font-size: 13px;
  transition: background var(--speed), color var(--speed), border-color var(--speed);
}

.forecast-edit-btn:hover,
.forecast-edit-btn.active {
  background: var(--gold-soft);
  border-color: var(--gold);
  color: var(--gold);
}

.forecast-edit-btn.visible { display: flex; }

.forecast-chevron {
  color: var(--gold);
  font-size: 14px;
  transition: transform var(--speed);
  line-height: 1;
}

.forecast-chevron.open { transform: rotate(180deg); }

.forecast-body {
  display: none;
  padding: 20px 24px 24px;
  border-top: 1px solid var(--border-light);
}

.forecast-body.open {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 32px;
  align-items: start;
}

@container tracker (max-width: 760px) {
  .forecast-body.open { grid-template-columns: 1fr; gap: 20px; }
  .forecast-body { padding: 16px; }
}

.forecast-slider-row {
  display: grid;
  grid-template-columns: 22px 130px minmax(0, 1fr) 80px;
  align-items: center;
  gap: 8px;
  margin-bottom: 16px;
  transition: opacity var(--speed);
}

/* A range input has an intrinsic min-content width (~130px in Chrome), and a
   plain 1fr track refuses to go below it — so the row stayed 260px wide no
   matter how little room it had and pushed the panel sideways. minmax(0, 1fr)
   above lets the track collapse; this lets the input follow it down. */
.forecast-slider-row input[type="range"] { min-width: 0; width: 100%; }
.forecast-slider-row input[type="number"] { min-width: 0; max-width: 100%; }

/* Past this there is no honest way to keep label, slider and readout on one
   line. The label takes the top row, and the slider and its number sit under
   it — still one visual unit, just two lines deep.

   Every cell is placed explicitly. Auto-flow will not do it: once the label
   spans two columns, the cursor has passed the end of row 1 and the slider
   lands in the 22px lever column on row 2. */
@container tracker (max-width: 520px) {
  .forecast-slider-row {
    grid-template-columns: 22px minmax(0, 1fr) 72px;
    row-gap: 5px;
  }
  /* Spans both rows so the × stays centred on the pair it removes. */
  .forecast-slider-row .lever-x-btn        { grid-area: 1 / 1 / 3 / 2; align-self: center; }
  .forecast-slider-row .forecast-slider-label { grid-area: 1 / 2 / 2 / 4; }
  .forecast-slider-row input[type="range"]  { grid-area: 2 / 2 / 3 / 3; }
  .forecast-slider-row input[type="number"] { grid-area: 2 / 3 / 3 / 4; }
}

.forecast-slider-row.disabled { opacity: 0.35; }
.forecast-slider-row.disabled input { pointer-events: none; }

.lever-x-btn {
  display: flex;           /* always in flow — preserves grid spacing */
  visibility: hidden;      /* invisible until edit mode */
  width: 18px;
  height: 18px;
  border-radius: 50%;
  background: none;
  border: 1px solid var(--text-dim);
  color: var(--text-dim);
  font-size: 10px;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  line-height: 1;
  padding: 0;
  transition: background var(--speed), color var(--speed), border-color var(--speed);
  flex-shrink: 0;
}

.lever-x-btn:hover,
.forecast-slider-row.disabled .lever-x-btn {
  background: var(--red-soft);
  border-color: var(--red);
  color: var(--red);
}

.forecast-slider-label {
  font-size: 12px;
  color: var(--text-muted);
}

.forecast-output {
  background: var(--bg-warm);
  border: 1px solid var(--border);
  border-radius: var(--radius-card);
  padding: 24px;
  align-self: start;
}

.forecast-output-title {
  font-family: var(--font-display);
  font-size: 11px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--text-dim);
  margin-bottom: 16px;
}

.forecast-result-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 10px 0;
  border-bottom: 1px solid var(--border-light);
}

.forecast-result-row:last-child { border-bottom: none; }

.forecast-result-label {
  font-size: 13px;
  color: var(--text-muted);
}

.forecast-result-value {
  font-size: 20px;
  font-weight: 600;
  color: var(--gold);
  font-family: var(--font-body);
  font-variant-numeric: tabular-nums;
}

/* ── Pipeline ───────────────────────────────────────────────────────────── */

.pipeline-header-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin: 28px 0 14px;
}

.pipeline-title {
  font-family: var(--font-display);
  font-size: 16px;
  font-weight: 600;
  letter-spacing: -0.01em;
  color: var(--text);
}

/* The goal card carries far less than the gauge and the donut beside it, and
   the grid stretches all three to the tallest. Centring its body turns the
   leftover space into breathing room instead of a void hanging under the
   figure. Same for any card that resolves to a single empty-state line. */
.tracker-card[data-card="goal"] .card-body { justify-content: center; }
