/* ChatFlow Analytics view (#analytics-view, design A). Needs tokens.css, components.css and
   chrome.css (.cf-page) first. Layout from the Analytics boards: page header (Recompute
   Snapshot, Refresh), the View segmented control with its channel pills and Period, the
   KPI card (hero row, then the funnel rows on Channels or a wrapping grid elsewhere), the
   bar over the charts (the jump bar to the chart sections, the Interval control), chart cards
   one to a row (two on very wide windows), on Channels in four sections (Traffic, Leads,
   Sales, Revenue) with one unit per chart, the Full Funnel Table. Colours come from tokens only, so night needs no rules here; the charts read the
   same tokens through makeChart and repaint when the theme changes.

   Series keys paint with the chart palette (--chart-*), marks only, never text. Status is a
   word on a chip in the colour language (COLOUR-TOKENS): Goal Met, Self-Liquidating and Under
   Payout green, Below Goal amber, Below Breakeven, Paying to Acquire and Over Payout red. A
   figure with a threshold takes the same colour (.num-ok / .num-warn / .num-bad): ROAS against
   the 2x goal and 1x breakeven, EPC against CPC, Cost per New Sale against the payout, C2L %
   against the Watch and Kill lines, a low-ticket CR % against 3% and 1.5%. The KPI card, the
   chart cards and the tables are raised surfaces (--shadow-card). */

/* ---------- Page header ---------- */
.an-head .page-head-text { flex: 1 1 320px; }
.an-refresh[aria-busy="true"] .ic,
#analytics-update-btn[aria-busy="true"] .ic { animation: an-spin 0.9s linear infinite; }
@keyframes an-spin { to { transform: rotate(360deg); } }

/* ---------- View, channel pills, Period ---------- */
.an-scope { display: flex; align-items: center; flex-wrap: wrap; gap: 8px 12px; margin-bottom: 16px; }
.an-view > button { min-width: 100px; }
.an-pills { display: flex; align-items: center; flex-wrap: wrap; gap: 2px; min-width: 0; }
.an-pills[hidden] { display: none; }
/* the hairline between the View control and its pills */
.an-pills::before { content: ""; flex: none; width: 1px; height: 20px; margin-right: 10px; background: var(--line); }
.an-pill {
  flex: none;
  height: 28px;
  box-sizing: border-box;
  padding: 0 10px;
  border: 0;
  border-radius: var(--radius-control);
  background: transparent;
  color: var(--ink);
  font: var(--fw-regular) var(--fs-label)/16px var(--font);
  white-space: nowrap;
  cursor: pointer;
}
.an-pill:hover:not([aria-pressed="true"]) { background: var(--hover); }
.an-pill[aria-pressed="true"] { background: var(--reply-tint); box-shadow: inset 0 0 0 1px var(--reply); font-weight: var(--fw-semibold); }
.an-pill:focus-visible { outline: 2px solid var(--focus); outline-offset: 2px; }
.an-when { display: flex; align-items: center; flex-wrap: wrap; gap: 8px; margin-left: auto; }
/* Period: a native select dressed as the neutral button ("Period This Month"), the same
   pattern as the Ads page, so keyboard, screen readers and the phone picker all work. */
.an-period {
  position: relative;
  display: inline-flex;
  align-items: center;
  gap: 8px;
  height: var(--control-h);
  box-sizing: border-box;
  padding: 0 8px 0 12px;
  border-radius: var(--radius-control);
  background: var(--fill);
  color: var(--ink);
  font: var(--fw-regular) var(--fs-label)/16px var(--font);
  white-space: nowrap;
  cursor: pointer;
}
.an-period:hover { background-image: linear-gradient(var(--press-overlay), var(--press-overlay)); }
.an-period-label { color: var(--ink-2); }
.an-period select {
  appearance: none;
  -webkit-appearance: none;
  margin: 0 -24px 0 0;
  padding: 0 24px 0 0;
  border: 0;
  background: transparent;
  color: var(--ink);
  font: var(--fw-semibold) var(--fs-label)/16px var(--font);
  color-scheme: var(--scheme);
  field-sizing: content;
  cursor: pointer;
  outline: none;
}
.an-period .ic { color: var(--ink-2); pointer-events: none; }
.an-period:has(select:focus-visible) { outline: 2px solid var(--focus); outline-offset: 2px; }
.an-custom { display: inline-flex; align-items: center; gap: 6px; }
.an-custom .input { width: auto; height: var(--control-h); }
.an-to { font: var(--fw-regular) var(--fs-label)/var(--lh-label) var(--font); color: var(--ink-2); }

/* ---------- Status line: a failed load, kept above the last good numbers ---------- */
.an-status:empty { display: none; }
.an-error {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 8px 12px;
  margin: 0 0 16px;
  padding: 8px 8px 8px 12px;
  border-radius: var(--radius-control);
  background: var(--fail-fill);
  color: var(--fail-label);
  font: var(--fw-semibold) var(--fs-label)/var(--lh-label) var(--font);
}
.an-error > .ic { flex: none; }
.an-error-text { flex: 1 1 240px; min-width: 0; margin: 0; overflow-wrap: anywhere; }

/* ---------- KPI card: hero row (28/600) over a wrapping grid (15/600) ---------- */
.an-kpis { margin-bottom: 8px; }
.an-hero { display: grid; grid-template-columns: repeat(auto-fit, minmax(160px, 1fr)); margin: 0; overflow: hidden; }
.an-tile { min-width: 0; padding: 16px; box-shadow: -1px 0 0 var(--line); }
.an-tile dt { font: var(--fw-semibold) var(--fs-caption)/var(--lh-caption) var(--font); color: var(--ink-2); }
.an-tile .an-v {
  margin: 4px 0 0;
  font: var(--fw-hero) var(--fs-hero)/var(--lh-hero) var(--font);
  color: var(--ink);
  font-variant-numeric: tabular-nums;
  letter-spacing: -0.2px;
  white-space: nowrap;
}
/* Never clipped: when a figure does not fit its tile (a 1280 window, 125% zoom, a phone),
   cfFitHero steps the whole row down to 24, 22 or 20px, so the row keeps one size; a
   figure still too wide at 20px wraps rather than hide its digits. */
.an-hero.an-fit-24 .an-v { font-size: 24px; line-height: 30px; }
.an-hero.an-fit-22 .an-v { font-size: 22px; line-height: 28px; }
.an-hero.an-fit-20 .an-v,
.an-hero.an-fit-wrap .an-v { font-size: 20px; line-height: 26px; }
.an-hero.an-fit-wrap .an-v { white-space: normal; overflow-wrap: anywhere; }
.an-tile .an-sub {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 4px 6px;
  min-height: 20px;
  margin: 4px 0 0;
  font: var(--fw-regular) var(--fs-caption)/var(--lh-caption) var(--font);
  color: var(--ink-2);
  font-variant-numeric: tabular-nums;
}
.an-sub .chip { height: 20px; box-sizing: border-box; padding: 0 8px; line-height: 20px; }
/* a tile with neither word nor sub line (Spend, Total Revenue) keeps no empty line under its
   figure; in a row its height still follows the tallest tile. The loading skeleton keeps the
   line, so the card does not jump when the figures arrive. Analytics only: the Funnels tab
   borrows these tiles (funnels.css) and keeps its own sub lines as they were. */
#analytics-view .an-tile .an-sub:empty { display: none; }
#analytics-view .an-tile:has(.an-skel) .an-sub:empty { display: flex; }
.an-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(112px, 1fr));
  gap: 12px;
  margin: 0;
  padding: 12px 16px;
  border-top: 1px solid var(--line);
}
.an-grid:empty { display: none; }
.an-cell { min-width: 0; }
.an-cell dt { font: var(--fw-regular) var(--fs-caption)/var(--lh-caption) var(--font); color: var(--ink-2); overflow-wrap: anywhere; }
.an-cell dd { margin: 2px 0 0; font: var(--fw-semibold) var(--fs-body)/var(--lh-body) var(--font); color: var(--ink); font-variant-numeric: tabular-nums; overflow-wrap: anywhere; }

/* Funnel rows (Channels; mockup A, Juanlu 2026-10-06): Traffic, Leads, Sales, Revenue, each
   a stage icon and name, then its figures in the grid's cell style. Every row has the same
   columns, so the figures line up down the card: seven on a card of 960px and more (the
   Leads row holds seven figures since Regs, L2R % and CPR, 2026-10-07; the other rows fill
   their first four or five, left-aligned), five below that (the Leads row wraps its last
   two under its first). Below a 760px card the name goes above its row, and below 480px (a
   phone) the figures take two columns. */
#analytics-view .an-kpis { container: an-kpis / inline-size; }
.an-stages { border-top: 1px solid var(--line); }
.an-stages:empty { display: none; }
.an-stage { display: grid; grid-template-columns: 136px minmax(0, 1fr); align-items: center; column-gap: 16px; padding: 10px 16px; }
.an-stage + .an-stage { border-top: 1px solid var(--line); }
.an-stage-name {
  display: flex;
  align-items: center;
  gap: 8px;
  min-width: 0;
  height: 28px;
  border-right: 1px solid var(--line);
  font: var(--fw-semibold) var(--fs-label)/var(--lh-label) var(--font);
  color: var(--ink);
}
.an-stage-ic { flex: none; display: flex; align-items: center; justify-content: center; width: 28px; height: 28px; border-radius: var(--radius-control); background: var(--fill); }
/* the accent of each stage glyph in its series colour (marks only, as in the charts), in the
   funnel rows, the chart section headings and the jump bar alike */
.an-stage-traffic .i3 .a { color: var(--chart-cpm); }
.an-stage-leads .i3 .a { color: var(--chart-leads); }
.an-stage-sales .i3 .a,
.an-stage-revenue .i3 .a { color: var(--chart-revenue); }
.an-stage-cells { display: grid; grid-template-columns: repeat(5, minmax(0, 1fr)); gap: 8px 16px; margin: 0; }
@container an-kpis (min-width: 960px) {
  .an-stage-cells { grid-template-columns: repeat(7, minmax(0, 1fr)); }
}
@container an-kpis (max-width: 759px) {
  .an-stage { grid-template-columns: minmax(0, 1fr); row-gap: 8px; }
  .an-stage-name { border-right: 0; }
  .an-stage-cells { grid-template-columns: repeat(auto-fill, minmax(112px, 1fr)); gap: 12px; }
}
@container an-kpis (max-width: 479px) {
  .an-stage { padding: 12px; }
  .an-stage-cells { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
/* A figure coloured by its threshold: the ink of the two rules above outranks the bare
   .num-* helpers of components.css, so the three colours are repeated at this weight. */
.an-tile .an-v.num-ok, .an-cell dd.num-ok { color: var(--ok); }
.an-tile .an-v.num-warn, .an-cell dd.num-warn { color: var(--warn); }
.an-tile .an-v.num-bad, .an-cell dd.num-bad { color: var(--bad); }
.an-empty { grid-column: 1 / -1; margin: 0; padding: 16px; font: var(--fw-regular) var(--fs-label)/var(--lh-label) var(--font); color: var(--ink-2); }
/* provenance: where the numbers come from, under the card they describe */
.an-note { margin: 0 0 16px; font: var(--fw-regular) var(--fs-caption)/var(--lh-caption) var(--font); color: var(--ink-2); }
.an-note:empty { display: none; }

/* skeleton while the first load is in flight */
.an-skel { display: block; height: 12px; border-radius: 4px; background: var(--skeleton-a); animation: an-pulse 1.2s ease-in-out infinite alternate; }
.an-tile .an-skel { width: 64px; height: 10px; }
.an-tile .an-skel + .an-skel { width: 120px; height: 26px; margin-top: 8px; }
@keyframes an-pulse { from { background: var(--skeleton-a); } to { background: var(--skeleton-b); } }

/* ---------- Over the charts: the jump bar (left) and the Interval (right) ---------- */
.an-chartbar { display: flex; align-items: center; flex-wrap: wrap; gap: 8px 16px; margin: 0 0 8px; }
.an-chartbar[hidden] { display: none; }
/* Jump bar (Channels): a real button per chart section, which scrolls it into view. The
   section's stage glyph keeps its accent, so a button reads as its heading below. */
.an-jump { display: flex; align-items: center; flex-wrap: wrap; gap: 2px; min-width: 0; }
.an-jump[hidden] { display: none; }
.an-jump-btn {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  height: 28px;
  box-sizing: border-box;
  padding: 0 10px 0 8px;
  border: 0;
  border-radius: var(--radius-control);
  background: transparent;
  color: var(--ink);
  font: var(--fw-regular) var(--fs-label)/16px var(--font);
  white-space: nowrap;
  cursor: pointer;
}
.an-jump-btn[hidden] { display: none; }
.an-jump-btn:hover { background: var(--canvas-ctl); box-shadow: var(--canvas-ctl-shadow); }
.an-jump-btn:focus-visible { outline: 2px solid var(--focus); outline-offset: 2px; }
.an-jump-btn .i3 { flex: none; }
/* Interval: Day, Week, Month, at the bar's right end */
.an-interval { display: flex; align-items: center; justify-content: flex-end; gap: 8px; margin: 0 0 0 auto; }
.an-interval[hidden] { display: none; }
.an-interval-label { font: var(--fw-regular) var(--fs-label)/16px var(--font); color: var(--ink-2); }
.an-interval .seg > button { min-width: 64px; }

/* ---------- Chart cards ----------
   One chart to a row, as on a phone (Juanlu 2026-10-06: "On desktop, it should show only one
   chart at a time (like in mobile), or maximum 2 if the browser window gets too wide"). Two
   to a row from a 1900px window, where the chart area is about 1600px wide (sidebar open);
   a 1440 or 1680 laptop keeps one, sidebar open or closed. A chart's height follows its
   card's width (38% of it, 280 to 480px), so a full-width chart is no flat strip and every
   card in a row has the same height. */
.an-charts { display: grid; grid-template-columns: minmax(0, 1fr); gap: 16px; }
.an-charts[hidden] { display: none; }
@media (min-width: 1900px) {
  .an-charts { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  /* a chart left alone in its row (the third of Sales, or of Revenue on a geo; a one-day
     section's only chart) takes the whole row rather than leave half of it empty */
  .an-charts > .an-chart:nth-child(odd of :not([hidden])):nth-last-child(1 of :not([hidden])) { grid-column: 1 / -1; }
}
/* Channels' chart sections, Revenue first and Traffic last (the funnel rows' stages in reverse,
   Juanlu 2026-10-07), each headed by its funnel row's stage glyph and name, no caption. A jump
   bar button scrolls its section to the top, with some air. */
.an-sec { scroll-margin-top: 16px; }
.an-sec[hidden] { display: none; }
.an-sec + .an-sec { margin-top: 24px; }
.an-sec-title {
  display: flex;
  align-items: center;
  gap: 8px;
  margin: 0 0 8px;
  font: var(--fw-semibold) var(--fs-body)/var(--lh-body) var(--font);
  color: var(--ink);
}
.an-sec-title:focus { outline: none; }
.an-sec-title:focus-visible { outline: 2px solid var(--focus); outline-offset: 2px; border-radius: 4px; }
/* on the canvas the glyph's tile is the card ground, raised like the controls standing there */
.an-sec-title .an-stage-ic { background: var(--canvas-ctl); box-shadow: var(--canvas-ctl-shadow); }
.an-chart { min-width: 0; padding: 16px; container-type: inline-size; }
.an-chart[hidden] { display: none; }
.an-chart-head { display: flex; align-items: center; justify-content: space-between; flex-wrap: wrap; gap: 4px 12px; min-height: 28px; }
.an-chart-title { margin: 0; font: var(--fw-semibold) var(--fs-body)/var(--lh-body) var(--font); color: var(--ink); }
.an-zoom { display: flex; align-items: center; gap: 12px; margin-left: auto; }
.an-zoom-hint,
.an-zoom-range { margin: 0; font: var(--fw-regular) var(--fs-caption)/var(--lh-caption) var(--font); color: var(--ink-2); font-variant-numeric: tabular-nums; white-space: nowrap; }

/* legend: each series key with its total underneath; a series entry is a toggle */
.an-legend { display: flex; flex-wrap: wrap; gap: 8px 24px; margin: 12px 0 0; }
.an-leg { display: flex; flex-direction: column; align-items: flex-start; gap: 2px; min-width: 0; margin: 0; padding: 0; border: 0; background: none; color: var(--ink); font: inherit; text-align: left; }
button.an-leg { cursor: pointer; border-radius: 4px; }
button.an-leg:focus-visible { outline: 2px solid var(--focus); outline-offset: 3px; }
.an-leg-name { display: flex; align-items: center; gap: 6px; font: var(--fw-regular) var(--fs-caption)/var(--lh-caption) var(--font); color: var(--ink-2); white-space: nowrap; }
.an-leg-val { display: flex; align-items: center; gap: 6px; font: var(--fw-semibold) var(--fs-body)/var(--lh-body) var(--font); color: var(--ink); font-variant-numeric: tabular-nums; white-space: nowrap; }
.an-leg-val .chip { font-weight: var(--fw-semibold); }
/* a hidden series: its key goes hollow and the name is struck, the total stays readable */
.an-leg[aria-pressed="false"] .an-leg-name { text-decoration: line-through; }
.an-leg[aria-pressed="false"] .an-key-bar { background: transparent; box-shadow: inset 0 0 0 1.5px currentColor; }
.an-key { flex: none; display: inline-block; color: var(--ink-2); }
.an-key-bar { width: 10px; height: 10px; border-radius: 2px; background: currentColor; }
.an-key-line { width: 16px; height: 0; border-top: 2px solid currentColor; border-radius: 1px; }
.an-key-dash { width: 16px; height: 0; border-top: 2px dashed currentColor; }
.an-key-dot { width: 16px; height: 0; border-top: 2px dotted currentColor; }
.k-revenue { color: var(--chart-revenue); }
.k-roas { color: var(--chart-roas); }
.k-leads { color: var(--chart-leads); }
.k-cost { color: var(--chart-cost); }
.k-c2l { color: var(--chart-c2l); }
.k-spend { color: var(--chart-spend); }
.k-cpm { color: var(--chart-cpm); }
.k-paypal { color: var(--chart-paypal); }
.k-regs { color: var(--chart-regs); }
.k-new { color: var(--chart-new); }
.k-warn { color: var(--warn); }
.k-alert { color: var(--alert); }
.k-ok { color: var(--ok); }

.an-canvas { position: relative; height: 300px; height: clamp(280px, 38cqi, 480px); margin-top: 12px; }
.an-canvas canvas { display: block; }

/* ---------- Full Funnel Table ---------- */
.an-table-sec { margin-top: 24px; }
.an-table-sec .section-head { margin-bottom: 8px; }
.an-table-hint { margin: 0; font: var(--fw-regular) var(--fs-caption)/var(--lh-caption) var(--font); color: var(--ink-2); }
.an-scroll {
  max-height: 420px;
  overflow: auto;
  overscroll-behavior-x: contain;
  border: 1px solid var(--line);
  border-radius: var(--radius-card);
  background: var(--pop);
  box-shadow: var(--shadow-card);
  scrollbar-width: thin;
  scrollbar-color: var(--edge-field) transparent;
}
.an-scroll:focus-visible { outline: 2px solid var(--focus); outline-offset: 2px; }
.an-scroll::-webkit-scrollbar-track { background: transparent; }
.an-scroll::-webkit-scrollbar-thumb { background: var(--edge-field); }
.an-table {
  width: max-content;
  min-width: 100%;
  border-collapse: separate;
  border-spacing: 0;
  color: var(--ink);
  font: var(--fw-regular) var(--fs-label)/16px var(--font);
  font-variant-numeric: tabular-nums;
}
.an-table th,
.an-table td {
  height: 32px;
  box-sizing: border-box;
  padding: 0 8px;
  border-bottom: 1px solid var(--line);
  background: var(--pop);
  text-align: right;
  white-space: nowrap;
  vertical-align: middle;
}
.an-table thead th {
  position: sticky;
  top: 0;
  z-index: 2;
  height: 28px;
  background: var(--fill);
  color: var(--ink-2);
  font: var(--fw-semibold) var(--fs-caption)/var(--lh-caption) var(--font);
}
.an-table th:first-child,
.an-table td:first-child { padding-left: 12px; }
.an-table th:last-child,
.an-table td:last-child { padding-right: 12px; }
/* the first column (Period, Step, Date) stays put when the table scrolls sideways */
.an-table tr > :first-child { position: sticky; left: 0; z-index: 1; text-align: left; box-shadow: inset -1px 0 0 var(--line); }
.an-table thead tr > :first-child { z-index: 3; }
.an-table tbody tr:last-child > * { border-bottom: 0; }
.an-table tbody tr:hover > * { background: var(--hover); }
.an-table tbody th { font-weight: var(--fw-regular); }
.an-table .muted { color: var(--ink-2); }
.an-table .an-l { text-align: left; }
.an-table b { font-weight: var(--fw-semibold); }

@media (prefers-reduced-motion: reduce) {
  .an-refresh[aria-busy="true"] .ic, #analytics-update-btn[aria-busy="true"] .ic, .an-skel { animation: none; }
}

/* ---------- Phones ---------- */
@media (max-width: 767px) {
  .an-head .page-actions { flex: 1 1 100%; }
  .an-view { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); width: 100%; }
  .an-view > button { min-width: 0; padding: 0 4px; }
  .an-pills { flex: 1 1 100%; flex-wrap: nowrap; overflow-x: auto; scrollbar-width: none; }
  .an-pills::before { display: none; }
  .an-when { flex: 1 1 100%; margin-left: 0; }
  .an-custom { flex: 1 1 100%; min-width: 0; }
  .an-custom .input { flex: 1 1 0; min-width: 0; }
  .an-hero { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .an-tile { padding: 12px; box-shadow: -1px 0 0 var(--line), 0 -1px 0 var(--line); }
  .an-tile .an-v { font-size: 24px; line-height: 30px; }
  .an-grid { grid-template-columns: repeat(auto-fill, minmax(96px, 1fr)); }
  .an-chart { padding: 12px; }
  .an-legend { gap: 8px 16px; }
  .an-canvas { height: 240px; }
  .an-zoom-hint { display: none; }
}
@media (pointer: coarse) {
  .an-pill, .an-jump-btn { height: 44px; }
  /* no wheel on touch, so no Cmd zoom and no hint; double-tap still resets */
  .an-zoom-hint { display: none; }
}
/* the word chip after a grid figure (Watch, Kill, Low, Below Goal); a long word wraps under
   the figure, flush left (the gap only applies on a shared line) */
.an-cell dd:has(> .chip) { display: flex; flex-wrap: wrap; align-items: center; gap: 2px 6px; }
