/* ChatFlow Ads view (#campaigns-view, design A). Needs tokens.css, components.css and
   chrome.css (.cf-page) first. Layout from the Ads boards: page header with the snapshot
   line and Period + Refresh, the KPI hero row, then one section per geo with its table.
   Colours come from tokens only, so night needs no rules here.

   Status is always a word on a chip in the colour language (COLOUR-TOKENS): Kill, Disabled,
   Disapproved and an account that is not active red (.chip-bad); Watch, Scheduled and With
   Issues amber (.chip-warn); Paused, Off and other stopped states grey (.chip-idle). The C2L %
   and Cost/Purchase cells take their band's colour (.num-bad / .num-warn / .num-ok). A paused
   row is ink-2, numbers included, never faded with opacity. The tables and the skeleton are
   raised surfaces (--shadow-card). */

/* ---------- Page header ---------- */
/* the text column takes the room, so Period and Refresh stay on the title's line */
.ads-head .page-head-text { flex: 1 1 320px; }
.ads-meta { display: flex; align-items: center; flex-wrap: wrap; gap: 4px 10px; }
.ads-meta .page-sub { min-width: 0; }
.ads-meta .page-sub:empty { display: none; }
.ads-dead {
  flex: 0 1 auto;
  align-items: flex-start;
  min-width: 0;
  gap: 4px;
  padding: 1px 8px 1px 6px;
  font: var(--fw-semibold) var(--fs-caption)/var(--lh-caption) var(--font);
  white-space: normal;
}
.ads-dead .ic { margin-top: 1px; }
.ads-dead[hidden] { display: none; }

/* Period: a native select dressed as the neutral button ("Period Today"), so keyboard,
   screen readers and the phone picker all work as before. */
.ads-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;
}
.ads-period:hover { background-image: linear-gradient(var(--press-overlay), var(--press-overlay)); }
.ads-period-label { color: var(--ink-2); }
.ads-period select {
  appearance: none;
  -webkit-appearance: none;
  margin: 0;
  padding: 0 24px 0 0;
  margin-right: -24px;
  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;
}
.ads-period .ic { color: var(--ink-2); pointer-events: none; }
.ads-period:has(select:focus-visible) { outline: 2px solid var(--focus); outline-offset: 2px; }
.ads-custom { display: inline-flex; align-items: center; gap: 6px; }
.ads-custom[hidden] { display: none; }
.ads-custom .input { width: auto; height: var(--control-h); }
.ads-to { font: var(--fw-regular) var(--fs-label)/var(--lh-label) var(--font); color: var(--ink-2); }
.ads-refresh[aria-busy="true"] .ic { animation: ads-spin 0.9s linear infinite; }
@keyframes ads-spin { to { transform: rotate(360deg); } }

/* ---------- KPI hero row: groups split by hairlines, 28/600 values, 12px labels ----------
   The hairline sits in the 49px gap before each group; the row clips it, so a group that
   wraps to the start of a new line shows no stray line and no indent. */
.ads-kpis { display: flex; flex-wrap: wrap; align-items: stretch; gap: 16px 49px; overflow: hidden; }
.ads-kpi-group { position: relative; display: flex; gap: 32px; margin: 0; }
.ads-kpi-group + .ads-kpi-group::before { content: ""; position: absolute; top: 0; bottom: 0; left: -25px; border-left: 1px solid var(--line); }
.ads-kpi { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.ads-kpi dt { font: var(--fw-regular) var(--fs-caption)/var(--lh-caption) var(--font); color: var(--ink-2); white-space: nowrap; }
.ads-kpi dd {
  margin: 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;
}
.ads-kpis-2 { display: flex; flex-wrap: wrap; gap: 8px 24px; margin: 12px 0 0; }
.ads-kpis-2 > div { display: flex; align-items: baseline; gap: 6px; }
.ads-kpis-2 dt { font: var(--fw-regular) var(--fs-caption)/var(--lh-caption) var(--font); color: var(--ink-2); }
.ads-kpis-2 dd { margin: 0; font: var(--fw-semibold) var(--fs-body)/var(--lh-body) var(--font); color: var(--ink); font-variant-numeric: tabular-nums; }

/* ---------- Geo sections ---------- */
.ads-geo { margin-top: 24px; }
.ads-geo-head { display: flex; align-items: baseline; flex-wrap: wrap; gap: 2px 12px; margin-bottom: 8px; }

/* The table scrolls inside its card: sideways with a sticky Campaign column when it
   cannot fit, and down with a sticky header when it is taller than the window. */
.ads-scroll {
  max-height: max(360px, calc(100dvh - 160px));
  overflow: auto;
  overscroll-behavior-x: contain;
  border: 1px solid var(--line);
  border-radius: var(--radius-card);
  background: var(--pop);
  box-shadow: var(--shadow-card);
}
.ads-scroll:focus-visible { outline: 2px solid var(--focus); outline-offset: 2px; }
/* Token scrollbar. Chrome 121+ takes the standard properties over the old night layer's
   navy ::-webkit-scrollbar; the thumb is the 3:1 component edge (3.26:1 day, 5.21:1 night
   on --pop). The two pseudo rules only matter where that night rule still switches the
   custom scrollbar on (Safari), and give it the same token colours. */
.ads-scroll { scrollbar-width: thin; scrollbar-color: var(--edge-field) transparent; }
.ads-scroll::-webkit-scrollbar-track { background: transparent; }
.ads-scroll::-webkit-scrollbar-thumb { background: var(--edge-field); }
/* max-content: columns never squeeze below their content; the card scrolls instead.
   Every table but MRS shares one column grid: cpAlignCols sets the <col> widths to the
   widest natural width of each column (read under .is-measuring) and, when that grid is
   wider than the card, narrows the Campaign column toward its narrowest (.is-measuring-min). */
.ads-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;
}
.ads-table th,
.ads-table td {
  height: 32px;
  box-sizing: border-box;
  padding: 0 4px;
  border-bottom: 1px solid var(--line);
  background: var(--pop);
  text-align: right;
  white-space: nowrap;
  vertical-align: middle;
}
.ads-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);
}
.ads-table th:first-child,
.ads-table td:first-child { padding-left: 12px; }
.ads-table th:last-child,
.ads-table td:last-child { padding-right: 12px; }
.ads-list.is-measuring .ads-table { min-width: 0; }
.ads-list.is-measuring-min .ads-table { width: min-content; min-width: 0; }
/* a header may take two lines, only when the grid narrows its column below the header's
   width (cpAlignCols, when the card is too narrow for the one-line nicknames) */
.ads-table thead th { white-space: normal; }
.ads-table .ads-l { text-align: left; }
.ads-table .ads-acc { padding-right: 10px; }
/* the Campaign column stays put when the table scrolls sideways */
.ads-table tr > :first-child { position: sticky; left: 0; z-index: 1; text-align: left; }
.ads-table thead tr > :first-child { z-index: 3; }
.ads-scroll.is-scrolled-x .ads-table tr > :first-child { box-shadow: inset -1px 0 0 var(--line); }
.ads-table tbody th { font-weight: var(--fw-regular); }
.ads-table tbody tr:hover > * { background: var(--hover); }
.ads-table .ads-strong { font-weight: var(--fw-semibold); }
.ads-table tfoot th,
.ads-table tfoot td { border-bottom: 0; background: var(--hover); font-weight: var(--fw-semibold); }

/* Campaign and Account cells: the rep prefix in ink-2; the nickname on ONE line (Juanlu
   2026-10-01), cut with an ellipsis only when the shared grid needs the room (cpAlignCols
   sets each name's max-width; the full Meta name is on hover); tags (Scheduled with its start, an
   account that is not active) on their own line under the name, so no column widens for them */
.ads-camp { display: flex; flex-direction: column; align-items: flex-start; gap: 2px; padding: 6px 0; }
/* rep + name stay together; a status chip (Paused ...) that does not fit beside them
   drops under them instead of squeezing the name */
.ads-camp-line { display: flex; flex-wrap: wrap; align-items: baseline; gap: 2px 6px; }
.ads-camp-id { display: flex; align-items: baseline; gap: 6px; min-width: 0; }
.ads-rep { flex: none; font: var(--fw-regular) var(--fs-caption)/var(--lh-caption) var(--font); color: var(--ink-2); }
.ads-name { display: inline-block; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; vertical-align: bottom; }
/* the narrowest nickname (CP_NAME_MIN): 120px since the on/off switch took 48px of the column,
   so the tables that fitted at 1440 still fit */
.ads-list.is-measuring-min .ads-name { max-width: 120px; }
.ads-when { max-width: 240px; }
/* Launch Date (from the name: "12 Sep"), between the name and the account */
.ads-table .ads-date { padding-left: 12px; padding-right: 8px; }
.ads-camp-line .chip { align-self: center; }
/* a chip that would leave the name under its floor goes under it (cpAlignCols) */
.ads-table th.is-chip-under .ads-camp-line { flex-direction: column; align-items: flex-start; }
.ads-table th.is-chip-under .ads-camp-line .chip { align-self: flex-start; }
/* a scheduled row with data: the Scheduled tag and its start under the name; the start
   wraps under the tag when the Campaign column is narrow */
.ads-when { display: inline-flex; flex-wrap: wrap; align-items: center; gap: 2px 6px; white-space: normal; font: var(--fw-regular) var(--fs-caption)/var(--lh-caption) var(--font); color: var(--ink-2); }
/* The on/off switch in front of the name: the Flows switch (flows-list.css), green when on (the
   Live green, var(--ok-solid)) and grey when off, never touched by a paused row's ink-2. Its
   centre sits on the name line (6px cell padding + half the 16px line - half the 24px switch);
   a row stays 32px. One that cannot be switched (aria-disabled, the title says why) is faded,
   like a disabled button. cpAlignCols counts its width and the gap. The Scheduled line of a
   scheduled row with data spans the whole cell, under the switch too, so it keeps the width it
   had and a row stays 48px (2px under the name line, 6px under it, as in .ads-camp). */
.ads-camp-row { display: grid; grid-template-columns: auto 1fr; column-gap: 8px; align-items: start; }
.ads-tog { margin-top: 2px; }
.ads-camp-row > .ads-when { grid-column: 1 / -1; justify-self: start; margin: -4px 0 6px; }
.ads-table .ads-tog input:checked + .flw-switch-track { background: var(--ok-solid); }
.ads-table .ads-tog input[aria-disabled="true"] { cursor: not-allowed; }
.ads-table .ads-tog input[aria-disabled="true"] + .flw-switch-track { opacity: .45; }
/* The late-start warning of the Turn On dialog: its own amber notice under the consequence
   text, the word "Late start" first (the dialog is on <body>, outside the Ads view) */
.modal-box .ads-dlg-warn { display: flex; align-items: flex-start; gap: 8px; margin: 12px 0 0; padding: 8px 10px; border-radius: var(--radius-control); background: var(--warn-tint); color: var(--warn); font: var(--fw-regular) var(--fs-label)/var(--lh-label) var(--font); }
.ads-dlg-warn > .ic { flex: none; margin-top: 1px; }
.ads-dlg-warn b { font-weight: var(--fw-semibold); }

/* a number with its status tag in front (Kill / Watch) */
.ads-tagged { display: inline-flex; align-items: center; gap: 5px; }
/* every chip in a table at the board's 1px 5px (16px tall), so a tagged row stays 48px */
.ads-table .chip { padding: 1px 5px; }

/* Paused and every other non-active campaign: the whole row in ink-2 (this outranks the
   .num-* colour of its C2L % or Cost/Purchase cell; the Kill or Watch chip keeps its colour) */
.ads-table tr.is-muted > * { color: var(--ink-2); }
/* Scheduled with no data yet: one note across the number columns */
.ads-sched { text-align: left; color: var(--ink-2); }
.ads-table td.ads-sched { text-align: left; }
.ads-sched-line { display: inline-flex; align-items: center; gap: 8px; }

/* ---------- List states: skeleton, empty, error ---------- */
.ads-empty { margin: 24px 0 0; font: var(--fw-regular) var(--fs-label)/var(--lh-label) var(--font); color: var(--ink-2); }
.ads-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);
}
.ads-error > .ic { flex: none; }
.ads-error-text { flex: 1 1 240px; min-width: 0; margin: 0; overflow-wrap: anywhere; }
.ads-list > .ads-error { margin-top: 0; }
.ads-skel-bar { display: block; height: 12px; border-radius: 4px; background: var(--skeleton-a); animation: ads-pulse 1.2s ease-in-out infinite alternate; }
.ads-skel-kpis { display: flex; flex-wrap: wrap; gap: 16px 32px; }
.ads-skel-kpi { display: flex; flex-direction: column; gap: 8px; }
.ads-skel-kpi .ads-skel-bar:first-child { width: 72px; height: 10px; }
.ads-skel-kpi .ads-skel-bar:last-child { width: 120px; height: 26px; }
.ads-skel-title { width: 64px; height: 16px; margin: 32px 0 12px; }
.ads-skel-table { border: 1px solid var(--line); border-radius: var(--radius-card); background: var(--pop); box-shadow: var(--shadow-card); overflow: hidden; }
.ads-skel-row { display: flex; align-items: center; justify-content: space-between; gap: 24px; height: 32px; padding: 0 12px; border-bottom: 1px solid var(--line); }
.ads-skel-row:first-child { height: 28px; background: var(--fill); }
.ads-skel-row:last-child { border-bottom: 0; }
.ads-skel-row .ads-skel-bar:first-child { width: 180px; }
.ads-skel-row .ads-skel-bar { flex: 0 1 56px; }
@keyframes ads-pulse { from { background: var(--skeleton-a); } to { background: var(--skeleton-b); } }

@media (prefers-reduced-motion: reduce) {
  .ads-refresh[aria-busy="true"] .ic, .ads-skel-bar { animation: none; }
}

/* ---------- Narrow windows (1100px and less, phones included) ----------
   The tables always scroll sideways here, so the frozen Campaign column must stay about
   a third of the card: the rep goes over the name, a status chip under it, and the name
   wraps at 160px. */
@media (max-width: 1100px) {
  .ads-camp-line, .ads-camp-id { flex-direction: column; align-items: flex-start; gap: 0; }
  .ads-camp-line .chip { align-self: flex-start; }
  /* the frozen column stays a third of the card here, so long nicknames wrap again */
  .ads-name, .ads-list.is-measuring-min .ads-name { max-width: 160px; overflow: visible; white-space: normal; overflow-wrap: break-word; }
  .ads-when { max-width: 160px; }
  /* the on/off switch sits on the rep's line, the name, a status chip and the Scheduled line
     each on their own line under it across the cell, so the frozen column keeps its width and
     a row grows by the switch's extra 8px over the rep's line, not by its 48px */
  .ads-camp-row { padding: 6px 0; }
  .ads-camp-row .ads-camp, .ads-camp-row .ads-camp-line, .ads-camp-row .ads-camp-id { display: contents; }
  .ads-camp-row .ads-tog { grid-area: 1 / 1; margin: 0; }
  .ads-camp-row .ads-rep { grid-area: 1 / 2; align-self: center; justify-self: start; }
  .ads-camp-row .ads-name, .ads-camp-row .ads-camp-line > .chip, .ads-camp-row > .ads-when { grid-column: 1 / -1; justify-self: start; }
  .ads-camp-row > .ads-when { margin: 2px 0 0; }
  /* no rep: the name takes the rep's place beside the switch, 48px narrower (160 - 48) */
  .ads-camp-row.no-rep .ads-name { grid-area: 1 / 2; align-self: center; max-width: 112px; }
}

/* ---------- Phones ---------- */
@media (max-width: 767px) {
  /* two KPIs a line; a value too wide for half the line takes a whole one, so digits
     never run into the next value (320px with 5 and 6 figure totals). The hairlines are
     gone here, so nothing needs clipping. */
  .ads-kpis { gap: 16px; overflow: visible; }
  .ads-kpi-group { display: contents; }
  .ads-kpi-group + .ads-kpi-group::before { display: none; }
  .ads-kpi { flex: 1 0 calc(50% - 8px); min-width: max-content; }
  .ads-name, .ads-list.is-measuring-min .ads-name, .ads-when { max-width: 140px; }
  .ads-camp-row.no-rep .ads-name { max-width: 92px; }
  .ads-head .page-actions { flex: 1 1 100%; min-width: 0; }
  /* the two dates take their own line under Period and Refresh */
  .ads-custom { order: 3; flex: 1 1 100%; min-width: 0; }
  .ads-custom .input { flex: 1 1 0; min-width: 0; }
  .ads-scroll { max-height: max(360px, calc(100dvh - 120px)); }
}
