@import url("/v2/static/tokens.css");

/* ============================================================================
   Components. Every value here comes from a token; a raw number in this file
   is either a hairline, a percentage, or a bug.
   ========================================================================= */

/* Cross-document view transitions: the browser cross-fades between the old and
   the new page instead of flashing white. Native, declarative, and invisible to
   browsers that do not support it — unlike the JS click interception this
   replaced, it cannot leave a click doing nothing. */
@view-transition { navigation: auto; }
::view-transition-old(root), ::view-transition-new(root) {
  animation-duration: var(--dur-2);
  animation-timing-function: var(--ease-out);
}
/* the page plane is painted on <html> too, so the gap between documents is the
   dashboard's own background rather than white */
html { background: var(--canvas); }

*, *::before, *::after { box-sizing: border-box; }

body {
  margin: 0;
  background: var(--canvas);
  color: var(--ink-1);
  font-family: var(--font-sans);
  font-size: var(--text-md);
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}
a { color: inherit; text-decoration: none; }
p a { text-decoration: underline; text-underline-offset: 2px; }

/* one focus treatment for the whole product, never removed */
:focus-visible {
  outline: 2px solid var(--ring);
  outline-offset: 2px;
  border-radius: var(--radius-xs);
}

/* numbers that sit in columns must not dance as they change */
.num, .tvalue, table.grid td.r, .chart .tick, .tip b, .kpi-value {
  font-variant-numeric: tabular-nums;
}

/* --------------------------------------------------------------- header --- */
.topbar {
  view-transition-name: topbar;
  display: flex; align-items: center; gap: var(--space-6);
  padding: 0 var(--space-6); height: 56px;
  background: color-mix(in srgb, var(--surface-1) 88%, transparent);
  backdrop-filter: saturate(180%) blur(12px);
  border-bottom: 1px solid var(--line-1);
}
.brand {
  font-weight: 640; letter-spacing: var(--tracking-tight);
  font-size: var(--text-md); white-space: nowrap;
}
.brand span {
  color: var(--ink-3); font-weight: 500; font-size: var(--text-xs);
  border: 1px solid var(--line-2); border-radius: var(--radius-pill);
  padding: 1px 7px; margin-left: var(--space-2); vertical-align: 1px;
}
.tabs { display: flex; gap: 2px; overflow-x: auto; scrollbar-width: none; }
.tabs::-webkit-scrollbar { display: none; }
.tabs a {
  position: relative; padding: var(--space-2) var(--space-3);
  border-radius: var(--radius-sm); color: var(--ink-2);
  font-size: var(--text-sm); font-weight: 520; white-space: nowrap;
  transition: color var(--dur-1) var(--ease-out), background var(--dur-1) var(--ease-out);
}
.tabs a:hover { color: var(--ink-1); background: var(--surface-3); }
.tabs a.on { color: var(--ink-1); background: var(--surface-3); }
.tabs a.on::after {
  content: ""; position: absolute; left: var(--space-3); right: var(--space-3);
  bottom: -9px; height: 2px; border-radius: 2px; background: var(--accent);
}
.right { margin-left: auto; display: flex; align-items: center; gap: var(--space-2); }

.iconbtn {
  display: inline-grid; place-items: center; width: 34px; height: 34px;
  border: 1px solid var(--line-1); border-radius: var(--radius-sm);
  background: var(--surface-1); color: var(--ink-2); cursor: pointer;
  transition: background var(--dur-1) var(--ease-out), color var(--dur-1) var(--ease-out);
}
.iconbtn:hover { background: var(--surface-3); color: var(--ink-1); }
.iconbtn svg { width: 17px; height: 17px; stroke-width: 1.7; }
:root[data-theme="dark"] .iconbtn .i-sun, .iconbtn .i-moon { display: none; }
:root[data-theme="dark"] .iconbtn .i-moon { display: block; }
@media (prefers-color-scheme: dark) {
  :root:where(:not([data-theme="light"])) .iconbtn .i-sun { display: none; }
  :root:where(:not([data-theme="light"])) .iconbtn .i-moon { display: block; }
}

main { max-width: 1240px; margin: 0 auto; padding: var(--space-6) var(--space-6) var(--space-10); }
@media (max-width: 760px) { main { padding: var(--space-4); } .topbar { padding: 0 var(--space-4); } }

/* ---- form controls: one rule, every control ----------------------------- */
/* The language dropdown on Analytics shipped as a bare <select> and looked
   like a foreign object next to the chips — because styling lived in
   component-scoped rules (.payform, .bulkbar) and a control born outside them
   inherited nothing. This block is keyed on the ELEMENTS, so the next control
   anyone adds is already dressed; the component rules below only adjust
   layout, never appearance. */
select, textarea,
input[type="text"], input[type="search"], input[type="number"],
input[type="date"], input[type="password"] {
  background: var(--surface-2); border: 1px solid var(--line-1);
  border-radius: var(--radius-sm); padding: 6px 10px;
  font: inherit; color: var(--ink-1); max-width: 100%;
  transition: border-color var(--dur-1) var(--ease-out),
              box-shadow var(--dur-1) var(--ease-out);
}
select:hover, textarea:hover, input[type="text"]:hover,
input[type="search"]:hover, input[type="number"]:hover, input[type="date"]:hover {
  border-color: var(--line-2);
}
select:focus-visible, textarea:focus-visible,
input[type="text"]:focus-visible, input[type="search"]:focus-visible,
input[type="number"]:focus-visible, input[type="date"]:focus-visible,
input[type="password"]:focus-visible {
  outline: none; border-color: var(--accent);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--accent) 22%, transparent);
}
::placeholder { color: var(--ink-3); }
select:disabled, input:disabled { opacity: .55; cursor: not-allowed; }

/* The native arrow is the one part a browser will not let a stylesheet reach,
   so it is replaced: `appearance:none` plus a chevron drawn as a data URI.
   Its colour cannot be `currentColor` inside a data URI, hence one value per
   theme, switched by the same two signals the tokens use. */
select {
  appearance: none; -webkit-appearance: none;
  padding-right: 30px; cursor: pointer;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8' viewBox='0 0 12 8' fill='none' stroke='%236b7280' stroke-width='1.8' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M1 1.5 6 6.5 11 1.5'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 10px center;
}
@media (prefers-color-scheme: dark) {
  :root:where(:not([data-theme="light"])) select {
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8' viewBox='0 0 12 8' fill='none' stroke='%239aa4b2' stroke-width='1.8' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M1 1.5 6 6.5 11 1.5'/%3E%3C/svg%3E");
  }
}
:root[data-theme="dark"] select {
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8' viewBox='0 0 12 8' fill='none' stroke='%239aa4b2' stroke-width='1.8' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M1 1.5 6 6.5 11 1.5'/%3E%3C/svg%3E");
}
/* the options list itself is drawn by the OS; at least keep it in our palette */
select option { background: var(--surface-1); color: var(--ink-1); }

/* ------------------------------------------------------------- controls --- */
.controls {
  /* the popover inside this bar has to paint over the cards that follow it, and
     a later sibling with position:relative beats an earlier one at the same
     level — so the bar itself is lifted rather than the popover pushed higher */
  position: relative; z-index: 30;
  display: flex; flex-wrap: wrap; align-items: center;
  gap: var(--space-3) var(--space-5);
  background: var(--surface-1); border: 1px solid var(--line-1);
  border-radius: var(--radius-lg); box-shadow: var(--shadow-1);
  padding: var(--space-3) var(--space-4); margin-bottom: var(--space-5);
}
.cgroup { display: flex; align-items: center; gap: var(--space-2); flex-wrap: wrap; min-width: 0; }
.clabel {
  color: var(--ink-3); font-size: var(--text-2xs); font-weight: 600;
  text-transform: uppercase; letter-spacing: var(--tracking-wide);
}
.divider { width: 1px; height: 22px; background: var(--line-1); }

.segmented {
  display: inline-flex; padding: 3px; gap: 2px;
  background: var(--surface-2); border: 1px solid var(--line-1);
  border-radius: var(--radius-md);
}
.segmented a, .segmented button {
  display: inline-flex; align-items: center; gap: 5px;
  padding: 5px var(--space-3); border: 0; background: transparent;
  color: var(--ink-2); font: inherit; font-size: var(--text-sm); font-weight: 520;
  border-radius: var(--radius-sm); cursor: pointer; white-space: nowrap;
  transition: background var(--dur-1) var(--ease-out), color var(--dur-1) var(--ease-out);
}
.segmented a:hover, .segmented button:hover { background: var(--surface-3); color: var(--ink-1); }
/* The selected segment is filled, not merely lifted: a white pill on a near
   white track is not an answer to "what is selected right now". */
.segmented a.on, .segmented button.on {
  background: var(--accent); color: var(--accent-ink);
  box-shadow: var(--shadow-1); font-weight: 600;
}
.segmented a.on:hover, .segmented button.on:hover { background: var(--accent-hover); color: var(--accent-ink); }
.segmented a.on .autodot, .segmented button.on .autodot { background: var(--accent-ink); opacity: .75; }
.segmented .off {
  padding: 5px var(--space-3); font-size: var(--text-sm); color: var(--ink-3);
  opacity: .45; cursor: not-allowed; white-space: nowrap;
}
.segmented .autodot {
  width: 5px; height: 5px; border-radius: 50%; background: var(--accent);
  display: inline-block; flex: none;
}

.chip {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 5px var(--space-3) 5px var(--space-2);
  border: 1px solid var(--line-1); border-radius: var(--radius-pill);
  background: var(--surface-1); color: var(--ink-2);
  font-size: var(--text-sm); cursor: pointer; user-select: none;
  transition: border-color var(--dur-1) var(--ease-out), background var(--dur-1) var(--ease-out);
}
.chip:hover { border-color: var(--line-2); }
.chip input { position: absolute; opacity: 0; pointer-events: none; }
.chip .mark {
  width: 15px; height: 15px; flex: none; border-radius: var(--radius-xs);
  border: 1.5px solid var(--line-2); display: grid; place-items: center;
  transition: background var(--dur-1) var(--ease-out), border-color var(--dur-1) var(--ease-out);
}
.chip .mark svg { width: 10px; height: 10px; opacity: 0; color: var(--accent-ink); }
.chip.on { background: var(--accent-soft); border-color: color-mix(in srgb, var(--accent) 40%, transparent); color: var(--ink-1); }
.chip.on .mark { background: var(--accent); border-color: var(--accent); }
.chip.on .mark svg { opacity: 1; }

.btn {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 6px var(--space-3); border-radius: var(--radius-sm);
  border: 1px solid var(--line-1); background: var(--surface-1); color: var(--ink-1);
  font: inherit; font-size: var(--text-sm); font-weight: 520; cursor: pointer;
  transition: background var(--dur-1) var(--ease-out), border-color var(--dur-1) var(--ease-out);
}
.btn:hover { background: var(--surface-3); }
.btn svg { width: 15px; height: 15px; stroke-width: 1.7; color: var(--ink-3); }
.btn.primary { background: var(--accent); border-color: var(--accent); color: var(--accent-ink); }
.btn.primary:hover { background: var(--accent-hover); }
.btn.primary svg { color: currentColor; }

/* ------------------------------------------------------- date range pop --- */
.daterange { position: relative; display: inline-flex; align-items: center; gap: 4px; }
.clearrange {
  display: inline-grid; place-items: center; width: 26px; height: 26px;
  border-radius: var(--radius-sm); color: var(--ink-3);
  transition: background var(--dur-1) var(--ease-out), color var(--dur-1) var(--ease-out);
}
.clearrange:hover { background: var(--surface-3); color: var(--ink-1); }
.clearrange svg { width: 13px; height: 13px; }
.daterange > .btn .range-text { font-variant-numeric: tabular-nums; }
.cal {
  position: absolute; top: calc(100% + var(--space-2)); left: 0; z-index: var(--z-popover);
  width: 660px; max-width: calc(100vw - var(--space-6) * 2);
  background: var(--surface-1); border: 1px solid var(--line-1);
  border-radius: var(--radius-lg); box-shadow: var(--shadow-3);
  padding: var(--space-4); display: none;
  animation: pop var(--dur-2) var(--ease-out);
}
.cal[data-open] { display: grid; grid-template-columns: 168px 1fr; gap: var(--space-4); }
@keyframes pop { from { opacity: 0; transform: translateY(-6px) scale(.99); } }
@media (max-width: 720px) {
  .cal[data-open] { grid-template-columns: 1fr; }
  .cal .presets { display: flex; flex-wrap: wrap; gap: 6px; border: 0; padding: 0; }
}
.cal .presets {
  display: flex; flex-direction: column; gap: 2px;
  border-right: 1px solid var(--line-1); padding-right: var(--space-4);
}
.cal .presets button {
  text-align: left; padding: 7px var(--space-3); border: 0; border-radius: var(--radius-sm);
  background: transparent; color: var(--ink-2); font: inherit; font-size: var(--text-sm);
  cursor: pointer; transition: background var(--dur-1) var(--ease-out);
}
.cal .presets button:hover { background: var(--surface-3); color: var(--ink-1); }
.cal .presets button.on { background: var(--accent-soft); color: var(--ink-1); font-weight: 560; }

.cal .months { display: grid; grid-template-columns: 1fr 1fr; gap: var(--space-5); }
@media (max-width: 720px) { .cal .months { grid-template-columns: 1fr; } }
.cal .mhead {
  display: flex; align-items: center; justify-content: space-between;
  margin-bottom: var(--space-2); height: 28px;
}
.cal .mhead .title {
  font-size: var(--text-sm); font-weight: 600; letter-spacing: var(--tracking-snug);
  text-transform: capitalize;
}
.cal .nav {
  width: 28px; height: 28px; display: grid; place-items: center;
  border: 1px solid var(--line-1); border-radius: var(--radius-sm);
  background: var(--surface-1); color: var(--ink-2); cursor: pointer;
}
.cal .nav:hover { background: var(--surface-3); color: var(--ink-1); }
.cal .nav svg { width: 14px; height: 14px; stroke-width: 2; }
.cal .grid7 { display: grid; grid-template-columns: repeat(7, 1fr); gap: 1px; }
.cal .dow {
  font-size: var(--text-2xs); color: var(--ink-3); text-align: center;
  padding-bottom: 4px; text-transform: uppercase; letter-spacing: .03em;
}
.cal .day {
  position: relative; height: 34px; border: 0; background: transparent;
  color: var(--ink-1); font: inherit; font-size: var(--text-sm);
  font-variant-numeric: tabular-nums; cursor: pointer;
  display: grid; place-items: center;
  transition: background var(--dur-1) var(--ease-out), color var(--dur-1) var(--ease-out);
}
.cal .day::before {
  content: ""; position: absolute; inset: 2px; border-radius: var(--radius-sm);
  transition: background var(--dur-1) var(--ease-out);
}
.cal .day > span { position: relative; z-index: 1; }
.cal .day:hover::before { background: var(--surface-3); }
.cal .day.out { color: var(--ink-3); opacity: .45; }
.cal .day.today > span { font-weight: 700; }
.cal .day.today::after {
  content: ""; position: absolute; bottom: 4px; width: 4px; height: 4px;
  border-radius: 50%; background: var(--accent);
}
.cal .day.in-range::before { background: var(--accent-soft); inset: 2px 0; border-radius: 0; }
.cal .day.edge { color: var(--accent-ink); font-weight: 640; }
.cal .day.edge::before { background: var(--accent); inset: 2px; border-radius: var(--radius-sm); }
.cal .day.edge.start::before { border-radius: var(--radius-sm) 0 0 var(--radius-sm); inset: 2px 0 2px 2px; }
.cal .day.edge.end::before   { border-radius: 0 var(--radius-sm) var(--radius-sm) 0; inset: 2px 2px 2px 0; }
.cal .day.edge.only::before  { border-radius: var(--radius-sm); inset: 2px; }
.cal .day.edge.today::after { background: var(--accent-ink); }
.cal .day:disabled { color: var(--ink-3); opacity: .3; cursor: default; }
.cal .day:disabled:hover::before { background: transparent; }
.cal .calfoot {
  grid-column: 1 / -1; display: flex; align-items: center; justify-content: space-between;
  gap: var(--space-3); border-top: 1px solid var(--line-1);
  margin-top: var(--space-3); padding-top: var(--space-3);
}
.cal .readout { font-size: var(--text-sm); color: var(--ink-2); font-variant-numeric: tabular-nums; }
.cal .readout b { color: var(--ink-1); }

/* ------------------------------------------------------------------ KPI --- */
.kpis {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(210px, 1fr));
  gap: var(--space-3); margin-bottom: var(--space-5);
}
.kpis > * { min-width: 0; }
.kpi {
  position: relative; z-index: 0; overflow: hidden;
  background: var(--surface-1); border: 1px solid var(--line-1);
  border-radius: var(--radius-lg); box-shadow: var(--shadow-1);
  padding: var(--space-4);
}
.kpi::before {
  content: ""; position: absolute; inset: 0 auto 0 0; width: 3px;
  background: var(--tone, transparent);
}
.kpi-label {
  display: flex; align-items: center; gap: 6px;
  color: var(--ink-2); font-size: var(--text-xs); font-weight: 560;
  letter-spacing: var(--tracking-wide); text-transform: uppercase;
}
.kpi-label svg { width: 14px; height: 14px; stroke-width: 1.8; color: var(--ink-3); }
.kpi-value {
  font-size: var(--text-3xl); font-weight: 660; letter-spacing: var(--tracking-tight);
  line-height: 1.15; margin: var(--space-2) 0 var(--space-1);
}
.kpi-note { color: var(--ink-3); font-size: var(--text-xs); line-height: 1.45; }
.kpi.tone-accent  { --tone: var(--accent); background: linear-gradient(180deg, var(--accent-soft), var(--surface-1) 62%); }
.kpi.tone-danger  { --tone: var(--status-critical); }
.kpi.tone-good    { --tone: var(--status-good); }

/* ---------------------------------------------------------------- panel --- */
.panel {
  background: var(--surface-1); border: 1px solid var(--line-1);
  border-radius: var(--radius-lg); box-shadow: var(--shadow-1);
  padding: var(--space-5); margin-top: var(--space-4);
}
.panel > header { margin-bottom: var(--space-4); }
.panel h2 {
  margin: 0; font-size: var(--text-lg); font-weight: 620;
  letter-spacing: var(--tracking-snug); display: flex; align-items: baseline;
  gap: var(--space-2); flex-wrap: wrap;
}
.panel h2 .muted { font-weight: 450; font-size: var(--text-sm); color: var(--ink-3); }
h3.sub { font-size: var(--text-sm); font-weight: 560; color: var(--ink-2); margin: var(--space-5) 0 var(--space-2); }
h3.sub:first-of-type { margin-top: 0; }
.lead { color: var(--ink-2); font-size: var(--text-sm); line-height: 1.6; margin: var(--space-2) 0 0; max-width: 78ch; }
.lead b { color: var(--ink-1); font-weight: 600; }
.empty { color: var(--ink-3); padding: var(--space-4) 0; font-size: var(--text-sm); }
.axis-note { color: var(--ink-3); font-size: var(--text-xs); margin: var(--space-2) 0 0; }

.note {
  display: flex; gap: var(--space-3); align-items: flex-start;
  background: var(--surface-2); border: 1px solid var(--line-1);
  border-left: 3px solid var(--status-warning);
  border-radius: var(--radius-sm); padding: var(--space-3) var(--space-4);
  margin-top: var(--space-4); font-size: var(--text-sm); color: var(--ink-2);
}
.note svg { width: 16px; height: 16px; flex: none; margin-top: 2px; color: var(--status-warning); }
.note b { color: var(--ink-1); }
.alert { composes: note; }
.alert, p.alert {
  background: var(--surface-2); border: 1px solid var(--line-1);
  border-left: 3px solid var(--status-warning);
  border-radius: var(--radius-sm); padding: var(--space-3) var(--space-4);
  margin-top: var(--space-4); font-size: var(--text-sm); color: var(--ink-2);
}
code { background: var(--surface-3); padding: 1px 6px; border-radius: var(--radius-xs);
       font-family: var(--font-mono); font-size: var(--text-xs); }

.explain { display: grid; grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
           gap: var(--space-3); margin-top: var(--space-4); }
.explain .ex { background: var(--surface-2); border: 1px solid var(--line-1);
               border-radius: var(--radius-md); padding: var(--space-3) var(--space-4);
               font-size: var(--text-sm); color: var(--ink-2); min-width: 0; line-height: 1.55; }
.explain .ex b { color: var(--ink-1); }

/* --------------------------------------------------------------- charts --- */
.chartbox { position: relative; margin-top: var(--space-4); }
svg.chart { width: 100%; height: auto; display: block; overflow: visible; }
.chart .grid { stroke: var(--grid); stroke-width: 1; }
.chart .line { fill: none; stroke-width: 2.25; stroke-linejoin: round; stroke-linecap: round; }
.chart .overlay { stroke-dasharray: 5 4; stroke-width: 2; fill: none; }
.chart .odot { stroke: var(--surface-1); stroke-width: 1.5; }
.chart .tick { fill: var(--ink-3); font-size: var(--text-2xs); }
.chart .note { fill: var(--ink-3); font-size: var(--text-2xs); }
.chart .rowlabel { fill: var(--ink-1); font-size: var(--text-xs); }
.chart .rowvalue { fill: var(--ink-2); font-size: var(--text-xs); font-variant-numeric: tabular-nums; }
.chart .breakeven { stroke: var(--axis); stroke-width: 1.5; stroke-dasharray: 5 4; }
.chart .zero { stroke: var(--axis); stroke-width: 1.5; }
.chart .dot { stroke: var(--surface-1); stroke-width: 1.5; opacity: .88; }
.chart .dot:hover { opacity: 1; }
.chart .bar { transition: opacity var(--dur-1) var(--ease-out); }
.chart .bar:hover { opacity: .82; }
.chart .seg { stroke: var(--surface-1); stroke-width: 0; }
.chart .hits rect { fill: transparent; }
.chart .crosshair { stroke: var(--axis); stroke-width: 1; pointer-events: none; }
.evmark { fill: var(--accent); opacity: .85; }
.evmark:hover { opacity: 1; }
.evcount { fill: var(--ink-3); font-size: var(--text-2xs); font-variant-numeric: tabular-nums; }
.spark { width: 148px; height: 32px; }
.spark polyline { fill: none; stroke-width: 2; stroke-linejoin: round; stroke-linecap: round; }
.legend { display: flex; flex-wrap: wrap; gap: var(--space-4); margin-top: var(--space-3);
          font-size: var(--text-xs); color: var(--ink-2); }
.key { display: inline-flex; align-items: center; gap: 6px; }
.key i { width: 10px; height: 10px; border-radius: 3px; display: inline-block; flex: none; }
.key i.dashed { height: 0; border-top: 2px dashed; background: none; width: 16px; border-radius: 0; }
.key i.hatched { background: repeating-linear-gradient(45deg, var(--series-1) 0 2px, var(--surface-1) 2px 4px);
                 border: 1px solid var(--line-1); }
.counts { display: flex; gap: var(--space-2); flex-wrap: wrap; margin-top: var(--space-3); }

/* --------------------------------------------------------------- funnel --- */
.funnel { display: flex; flex-direction: column; gap: var(--space-2); }
.frow { display: grid; grid-template-columns: 190px 1fr 220px; align-items: center; gap: var(--space-4); }
.fname { color: var(--ink-2); font-size: var(--text-sm); }
.ftrack { background: var(--surface-2); border-radius: var(--radius-xs); height: 26px; overflow: hidden; }
.fbar { height: 100%; border-radius: 0 var(--radius-xs) var(--radius-xs) 0;
        transition: width var(--dur-3) var(--ease-out); }
.fval { font-variant-numeric: tabular-nums; font-weight: 580; font-size: var(--text-sm); }
.fval .drop { display: block; color: var(--ink-3); font-size: var(--text-xs); font-weight: 400; }
@media (max-width: 760px) { .frow { grid-template-columns: 1fr; gap: 2px; } }

/* --------------------------------------------------------------- tables --- */
.tablewrap { overflow-x: auto; margin-top: var(--space-4);
             border: 1px solid var(--line-1); border-radius: var(--radius-md); }
table.grid { width: 100%; border-collapse: collapse; font-size: var(--text-sm); }
table.grid thead th .sub2 {
  display: block; font-weight: 400; text-transform: none;
  letter-spacing: 0; color: var(--ink-3); font-size: var(--text-2xs);
  margin-top: 2px; white-space: nowrap;
}
table.grid thead th {
  position: sticky; top: 0; background: var(--surface-2); z-index: 1;
  color: var(--ink-3); font-weight: 580; font-size: var(--text-xs);
  text-transform: uppercase; letter-spacing: var(--tracking-wide);
  white-space: nowrap; text-align: left;
  padding: var(--space-3) var(--space-3); border-bottom: 1px solid var(--line-1);
}
table.grid td { padding: var(--space-3); border-bottom: 1px solid var(--line-1); }
table.grid tbody tr:last-child td { border-bottom: 0; }
table.grid td.r, table.grid th.r { text-align: right; }
table.grid tbody tr { transition: background var(--dur-1) var(--ease-out); }
table.grid tbody tr:hover { background: var(--surface-2); }
table.grid.dense td, table.grid.dense th { padding: 7px var(--space-3); }
table.grid tfoot td {
  border-top: 2px solid var(--line-2); font-weight: 620;
  background: var(--surface-2);
}
/* the slice control belongs to its report, so it reads as a row of choices
   rather than as another global filter competing with the bar at the top */
.slice { display: flex; align-items: center; gap: var(--space-4); flex-wrap: wrap;
         margin-top: var(--space-4); }
.slice a {
  position: relative; padding-left: 22px; font-size: var(--text-sm);
  color: var(--ink-2); line-height: 20px;
}
.slice a::before {
  content: ""; position: absolute; left: 0; top: 3px; width: 14px; height: 14px;
  border-radius: 50%; border: 1.5px solid var(--line-2); background: var(--surface-1);
  transition: border-color var(--dur-1) var(--ease-out);
}
.slice a:hover::before { border-color: var(--accent); }
.slice a.on { color: var(--ink-1); font-weight: 560; }
.slice a.on::before { border-color: var(--accent); border-width: 4.5px; }

.running {
  margin-left: 6px; padding: 1px 7px; border-radius: var(--radius-pill);
  background: color-mix(in srgb, var(--accent) 14%, var(--surface));
  color: var(--accent); font-size: var(--text-2xs); font-weight: 560; white-space: nowrap;
}
.delta { font-variant-numeric: tabular-nums; font-weight: 560; }
.delta.up { color: var(--success-ink); }
.delta.down { color: var(--danger-ink); }
table.pnl thead th { vertical-align: top; }

.muted { color: var(--ink-3); }
.bad { color: var(--danger-ink); font-weight: 560; }
.warnv { color: var(--status-serious); font-weight: 560; }
.fam { font-family: var(--font-mono); font-size: var(--text-xs); }
.spark-cell { width: 160px; }

.tag { display: inline-block; padding: 2px 9px; border-radius: var(--radius-pill);
       font-size: var(--text-xs); font-weight: 520; white-space: nowrap;
       border: 1px solid transparent; }
.c-scale   { background: color-mix(in srgb, var(--status-good) 14%, var(--surface-1)); color: var(--success-ink); }
.c-fix     { background: color-mix(in srgb, var(--status-critical) 13%, var(--surface-1)); color: var(--danger-ink); }
.c-cut     { background: color-mix(in srgb, var(--status-serious) 16%, var(--surface-1)); color: var(--ink-1); }
.c-hold    { background: color-mix(in srgb, var(--status-warning) 18%, var(--surface-1)); color: var(--ink-1); }
.c-organic { background: color-mix(in srgb, var(--series-3) 13%, var(--surface-1)); color: var(--ink-1); }
.c-watch   { background: var(--surface-3); color: var(--ink-2); }

/* /v2/journal/effect verdict badges — «лучше/хуже фона» is relative to the
   SAME window's control, not an absolute scale, hence its own class names
   rather than reusing the Аналитика status tags above (that vocabulary —
   scale/fix/cut/hold/organic/watch — does not map onto this one) */
.c-better   { background: color-mix(in srgb, var(--status-good) 14%, var(--surface-1)); color: var(--success-ink); }
.c-worse    { background: color-mix(in srgb, var(--status-critical) 13%, var(--surface-1)); color: var(--danger-ink); }
.c-same     { background: var(--surface-3); color: var(--ink-2); }
.c-toosmall { background: var(--surface-3); color: var(--ink-2); }
.c-stopped  { background: var(--accent-soft); color: var(--accent); }
.c-nodata   { background: var(--surface-3); color: var(--ink-3); }

/* ----------------------------------------------------------------- feed --- */
.feed { list-style: none; margin: var(--space-3) 0 0; padding: 0; }
.feed li { display: flex; gap: var(--space-3); align-items: flex-start;
           padding: var(--space-3) 0; border-bottom: 1px solid var(--line-1); }
.feed li:last-child { border-bottom: 0; }
.feed .dot { width: 8px; height: 8px; border-radius: 50%; margin-top: 7px; flex: none; }
.sev-critical .dot { background: var(--status-critical); }
.sev-serious .dot  { background: var(--status-serious); }
.sev-warning .dot  { background: var(--status-warning); }
.sev-good .dot     { background: var(--status-good); }
.fwhat { font-weight: 540; font-size: var(--text-sm); }
.fwhat b { margin-left: 6px; font-variant-numeric: tabular-nums; }
.fwhat b.up { color: var(--success-ink); }
.fwhat b.down { color: var(--danger-ink); }
.fdetail { color: var(--ink-2); font-size: var(--text-xs); }

/* -------------------------------------------------------------- heatmap --- */
.scrollx { overflow-x: auto; }
table.heat { border-collapse: separate; border-spacing: 2px; font-size: var(--text-xs); }
table.heat th { color: var(--ink-3); font-weight: 520; font-size: var(--text-2xs);
                padding: 3px 6px; white-space: nowrap; }
table.heat th.rl { text-align: right; }
table.heat td { padding: 6px 9px; border-radius: var(--radius-xs); text-align: right;
                font-variant-numeric: tabular-nums; min-width: 58px; }

/* -------------------------------------------------------------- tooltip --- */
.tip {
  position: fixed; pointer-events: none; z-index: var(--z-tooltip);
  background: var(--surface-1); border: 1px solid var(--line-1);
  border-radius: var(--radius-md); box-shadow: var(--shadow-3);
  padding: var(--space-2) var(--space-3); font-size: var(--text-xs); min-width: 168px;
}
.tip .th { font-weight: 640; margin-bottom: 5px; font-size: var(--text-sm); }
.tip .tr { display: flex; align-items: center; gap: var(--space-3); justify-content: space-between; }
.tip .tr + .tr { margin-top: 3px; }
.tip .tr i { width: 8px; height: 8px; border-radius: 2px; flex: none; }
.tip .tr span { color: var(--ink-2); display: inline-flex; align-items: center; gap: 6px; }
.tip .tr b { font-variant-numeric: tabular-nums; font-weight: 600; }

.foot { color: var(--ink-3); font-size: var(--text-xs); text-align: center; padding: 0 0 var(--space-8); }

body.busy main { opacity: .6; transition: opacity var(--dur-1) var(--ease-out) 80ms; }
body.busy { cursor: progress; }

/* ---- compat: the old tile classes -------------------------------------
   pulse/money keep the pre-redesign tile markup (.tiles/.tile/…). The
   design-system rewrite replaced these with .kpis/.kpi on the dashboard and
   dropped the old definitions — which left three pages with UNSTYLED headline
   numbers. Until those templates migrate, the old names get the same design. */
.tiles { display: grid; grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
  gap: var(--space-3); margin-bottom: var(--space-5); }
.tiles > * { min-width: 0; }
.tile { position: relative; background: var(--surface-1); border: 1px solid var(--line-1);
  border-radius: var(--radius-md); padding: var(--space-4) var(--space-5); overflow: hidden; }
.tile::before { content: ""; position: absolute; inset: 0 auto 0 0; width: 3px;
  background: var(--tone, transparent); }
.tlabel { color: var(--ink-3); font-size: var(--text-xs); font-weight: 560;
  letter-spacing: .02em; margin-bottom: var(--space-2); }
.tvalue { color: var(--ink-1); font-size: var(--text-2xl); font-weight: 640;
  letter-spacing: -0.015em; line-height: 1.1; margin-bottom: 3px; }
.tiles.small .tvalue { font-size: var(--text-xl); }
.tnote { color: var(--ink-3); font-size: var(--text-xs); line-height: 1.45; }
.tnote a { color: var(--ink-2); }
.tile.warn { --tone: var(--status-warning); }

/* ---- KPI deltas vs the preceding window ------------------------------- */
.kpi-delta { display: flex; align-items: center; gap: 4px; font-size: var(--text-xs);
  font-weight: 600; font-variant-numeric: tabular-nums; margin: 2px 0 3px; }
.kpi-delta .arr { font-size: 9px; }
.kpi-delta.good { color: var(--success-ink); }
.kpi-delta.bad { color: var(--danger-ink); }

/* an unfinished bucket's comparison: direction is real, magnitude is not yet */
.delta.dim { opacity: .45; font-weight: 500; }

/* dashed tail = the last bucket is still filling */
.chart .line.tail { stroke-dasharray: 4 5; opacity: .8; }

/* section scope badge: this block ignores the period filter */
.scope { display: inline-block; vertical-align: 2px; margin-left: var(--space-2);
  padding: 2px 8px; border-radius: 999px; background: var(--surface-2);
  border: 1px solid var(--line-1); color: var(--ink-3); font-size: var(--text-2xs);
  font-weight: 550; letter-spacing: .015em; white-space: nowrap; }

/* echo of the active «Разбор» slice up in the controls bar */
.slicechip { display: inline-flex; align-items: center; gap: 6px;
  padding: 4px 10px; border-radius: 999px; background: var(--accent-soft);
  border: 1px solid color-mix(in srgb, var(--accent) 40%, transparent);
  color: var(--ink-1); font-size: var(--text-xs); font-weight: 580;
  text-decoration: none; white-space: nowrap; }
.slicechip:hover { border-color: var(--accent); }

/* on narrow screens the tab row wraps instead of hiding behind an invisible
   scrollbar — a cut-off nav read as "there are only three tabs" */
@media (max-width: 760px) {
  .topbar { flex-wrap: wrap; padding-top: var(--space-2); padding-bottom: var(--space-2); }
  .tabs { order: 3; width: 100%; flex-wrap: wrap; }
}

/* ---- Google Ads cabinets table ---------------------------------------- */
.sharecell { white-space: nowrap; }
.sharebar { display: inline-block; vertical-align: -2px; width: 56px; height: 8px;
  margin-right: 8px; border-radius: 999px; background: var(--surface-2);
  overflow: hidden; }
.sharebar i { display: block; height: 100%; border-radius: 999px;
  background: var(--series-2); opacity: .85; }
.delta.plain { font-weight: 500; }

/* feed items that link into a «Разбор» slice keep the feed's own colour —
   the underline on hover is the affordance */
.fwhat a { color: inherit; text-decoration: none; border-bottom: 1px dashed var(--line-2); }
.fwhat a:hover { border-bottom-color: var(--ink-2); }

/* colour swatch tying a cabinet row to its line on the chart above */
.swatch { display: inline-block; width: 10px; height: 10px; border-radius: 3px;
  margin-right: 6px; vertical-align: -1px; }

/* ---- manual payout entry (Денежный поток) ----------------------------- */
.payform {
  border: 1px solid var(--line-1); border-radius: var(--radius-md);
  padding: var(--space-4); margin-top: var(--space-4);
}
.payform summary {
  cursor: pointer; font-weight: 560; font-size: var(--text-sm); color: var(--ink-1);
}
.payform[open] summary { margin-bottom: var(--space-3); }
.payform form {
  display: flex; align-items: flex-end; gap: var(--space-3); flex-wrap: wrap;
  margin-top: var(--space-2);
}
.pf-field { display: flex; flex-direction: column; gap: 4px; min-width: 0; }
.pf-field.grow { flex: 1 1 220px; }
.pf-label {
  color: var(--ink-3); font-size: var(--text-2xs); font-weight: 600;
  text-transform: uppercase; letter-spacing: var(--tracking-wide);
}
/* appearance comes from the element-level block above; only sizing here */
.payform input[type="text"] { min-width: 220px; }

.flashmsg {
  padding: var(--space-2) var(--space-3); border-radius: var(--radius-sm);
  font-size: var(--text-sm); margin: 0 0 var(--space-3);
}
.flashmsg.ok  { color: var(--success-ink); background: color-mix(in srgb, var(--status-good) 12%, var(--surface-1)); }
.flashmsg.err { color: var(--danger-ink);  background: color-mix(in srgb, var(--status-critical) 12%, var(--surface-1)); }

/* small circular delete affordance next to a manual payout row */
.xdel {
  background: transparent; border: 0; color: var(--ink-3);
  cursor: pointer; font-size: var(--text-sm); line-height: 1; padding: 4px 6px;
  border-radius: var(--radius-xs);
  transition: color var(--dur-1) var(--ease-out);
}
.xdel:hover { color: var(--status-critical); }

/* ---- Аналитика / Домены ------------------------------------------------ */
/* `--muted` is already referenced by charts.py's scatter-chart "watch" dot
   (VERDICT_COLOUR["unknown"]) but was never actually defined anywhere in
   tokens.css — an existing gap that left that dot painted with an invalid
   custom property. Aliased here to --ink-3, the same grey every other
   "muted" thing in this file already uses; fixes that older dot too, as a
   side effect, in both themes (the alias re-resolves --ink-3 per theme,
   it does not freeze light mode's value). */
:root { --muted: var(--ink-3); }

/* four-colour status dot for the Аналитика page's traffic-light: earning
   (good) / thin (warning) / losing (critical) / unknown (muted, deliberately
   achromatic — absence of a verdict is not its own hue) */
.st-dot {
  display: inline-block; width: 8px; height: 8px; border-radius: 50%;
  margin-right: 6px; vertical-align: 1px; flex: none;
}
.st-earning { background: var(--status-good); }
.st-thin    { background: var(--status-warning); }
.st-losing  { background: var(--status-critical); }
.st-unknown { background: var(--muted); }

/* small, muted, rounded — a second word next to a status whose sibling
   decision needs one («без рекламы», «нет броней»): the action differs from
   the OTHER decision sharing the same status, and the badge says why
   without spending a second colour on it */
.pbadge {
  display: inline-block; margin-left: 6px; padding: 1px 8px;
  border-radius: var(--radius-pill); background: var(--surface-3);
  color: var(--ink-3); font-size: var(--text-2xs); font-weight: 560;
  white-space: nowrap; vertical-align: 1px;
}
/* the journal's «пора смотреть эффект» / «эффект →» badges are LINKS to
   /v2/journal/effect — the global `a { color: inherit }` reset already
   makes an <a class="pbadge"> look identical to the plain <span> variant
   at rest, so only the hover affordance needs stating here */
a.pbadge:hover { background: var(--accent-soft); color: var(--accent); }
/* the wait-state variant («эффект через N дн.») is not a link — dimmed one
   step further than the default pbadge ink so it does not compete with the
   clickable badges beside it */
.pbadge.muted { color: var(--ink-3); opacity: .8; }

/* the column(s) a page's decision is actually made on, lifted just enough
   that the eye lands there first in a table that also carries a dozen
   evidence-only columns */
th.starcol {
  font-weight: 600; color: var(--ink-1);
  background: color-mix(in srgb, var(--accent) 6%, var(--surface-2));
}

/* ---- the window bar follows the scroll ---------------------------------- */
/* Only the period + calendar row is pinned, not the whole filter block: on the
   analytics page that block is three rows tall and would eat a third of a
   laptop screen. The site header is deliberately NOT sticky any more — two
   stacked bars cost more room than the nav is worth when there are two tabs.
   Sticky containment is why this element sits as a direct child of <main> in
   every template rather than inside a panel: it can only stick while its own
   parent box is on screen, and a panel is 200px tall. */
.controls.stickybar {
  position: sticky; top: var(--space-3);
  /* above the cards it scrolls over, below the calendar popover (z 60) it opens */
  z-index: 40;
}
@supports (animation-timeline: view()) {
  /* a hairline shadow only once it has actually left its place, so the bar
     looks flat in its resting position and lifted while it floats */
  .controls.stickybar { animation: stuck linear both; animation-timeline: view();
    animation-range: exit-crossing 0% exit-crossing 1px; }
  @keyframes stuck { to { box-shadow: var(--shadow-2); } }
}
@media (max-width: 760px) {
  /* on a phone the bar wraps to three rows; pinned, it would leave no page */
  .controls.stickybar { position: static; }
}

/* ---- week grid in the daily breakdown ----------------------------------- */
/* Sunday ends a Mon..Sun week and the table runs newest-first, so a tinted
   Sunday row is where each week starts as the eye travels down: a rhythm every
   seven rows instead of counting them. The tint is on the cells, not the row —
   `background` on a <tr> loses to any cell that paints its own, which the
   hover rule does. Kept faint on purpose: this is a ruler, not a finding. */
table.grid tbody tr.weekedge td {
  background: color-mix(in srgb, var(--accent) 5%, transparent);
  border-top: 1px solid var(--line-2);
}
table.grid tbody tr.weekedge:hover td { background: var(--surface-2); }
.dow {
  color: var(--ink-3); font-size: var(--text-2xs); font-weight: 600;
  text-transform: uppercase; letter-spacing: var(--tracking-wide);
  margin-left: var(--space-1);
}
/* Sunday on a daily axis: the day's own column, tinted the same faint accent as
   the Sunday row in «Разбор». A band rather than a line because a line has to
   sit either through the point or between two of them, and at any window width
   the second choice reads as a marker that slipped sideways. */
.chart .weekband { fill: color-mix(in srgb, var(--accent) 6%, transparent); }

/* ---- sortable column headers -------------------------------------------- */
.sortlink {
  color: inherit; text-decoration: none; display: inline-flex; align-items: center;
  gap: 3px; white-space: nowrap; cursor: pointer;
}
.sortlink:hover { color: var(--ink-1); }
.sortlink.on { color: var(--accent); }
.sarr { font-size: 9px; line-height: 1; }

/* ---- Журнал решений ----------------------------------------------------- */
/* the "record a decision" affordance inside the Аналитика table: small and
   muted so it never competes with the page name it sits next to, accent on
   hover is the only sign it does anything until the pointer arrives */
.jadd {
  display: inline-block; margin-left: 6px; color: var(--ink-3);
  font-size: var(--text-sm); line-height: 1; vertical-align: 1px;
  transition: color var(--dur-1) var(--ease-out);
}
.jadd:hover { color: var(--accent); }

/* the journal's own "Было" cell: several short facts on one line, same
   tabular-nums treatment as every other money/number column so a column of
   them still lines up */
.beforecell { font-variant-numeric: tabular-nums; white-space: nowrap; }

/* ---- journal: the merged "Детали" column -------------------------------- */
/* a manual row stacks note / "было" / effect badge / delete button; a
   grouped cabinet row's own content (pages/ad-groups) lives in the SAME
   column instead of three near-always-empty ones — see journal.html's
   `campaign_detail` macro and the "Детали" <td>. */
.detailstack { display: flex; flex-direction: column; align-items: flex-start; gap: 4px; }
.detailstack form { margin: 0; }
/* <details>/<summary> reused for a campaign group's page/ad-group footprint
   and for a manual row's cabinet-confirmation badge — same interaction
   as .payform's own summary above the table, sized for a table cell instead
   of a whole panel */
.rowdetails summary {
  cursor: pointer; color: var(--ink-2); font-size: var(--text-sm);
  list-style: none;
}
.rowdetails summary::-webkit-details-marker { display: none; }
.rowdetails[open] summary { margin-bottom: 4px; }
.detaillist {
  color: var(--ink-3); font-size: var(--text-xs); line-height: 1.5;
  max-width: 440px;
}

/* ---- bulk selection on Analytics ---------------------------------------- */
.selcol { width: 30px; text-align: center; }
.selcol input { accent-color: var(--accent); cursor: pointer; }
.qsearch { min-width: 190px; }
/* Sticky, because a hundred-row worklist is several screens of scrolling and
   the button that records the selection sat under the table — out of sight at
   exactly the moment the reader was ticking boxes. It holds the bottom of the
   viewport while its own section is on screen and rejoins the flow at the end
   of it. Sticky and not fixed: nothing is lifted out of the layout, so on a
   narrow screen the bar wraps like any other row of controls and scrolls away
   with the section it belongs to instead of sitting on top of the page.

   The background must stay opaque — table rows scroll UNDER it. Both halves
   are tokens, so the dark theme follows without a second rule, and the shadow
   does the separating that a heavier border would otherwise have to. */
.bulkbar {
  display: flex; align-items: center; gap: var(--space-3); flex-wrap: wrap;
  margin-top: var(--space-3); padding: var(--space-3) var(--space-4);
  border: 1px solid var(--line-1); border-radius: var(--radius-md);
  background: color-mix(in srgb, var(--accent) 5%, var(--surface-1));
  position: sticky; bottom: var(--space-3); z-index: 2;
  box-shadow: 0 -2px 14px color-mix(in srgb, var(--ink-1) 12%, transparent);
}
.bulkbar input[type="text"] { flex: 1; min-width: 180px; }
.bulkcount { font-size: var(--text-sm); color: var(--ink-2); white-space: nowrap; }

/* ---- pager --------------------------------------------------------------- */
.pager {
  display: flex; align-items: center; justify-content: center; gap: var(--space-4);
  margin-top: var(--space-4); font-size: var(--text-sm);
}
.pager a {
  color: var(--ink-1); text-decoration: none; padding: 5px 12px;
  border: 1px solid var(--line-1); border-radius: var(--radius-sm);
  background: var(--surface-1);
}
.pager a:hover { border-color: var(--accent); color: var(--accent); }
.pager .off { color: var(--ink-3); padding: 5px 12px; opacity: .5; }
.pagerinfo { color: var(--ink-2); white-space: nowrap; }
.bulkall-filter { display: inline-flex; align-items: center; gap: 6px;
  font-size: var(--text-sm); color: var(--ink-2); white-space: nowrap; cursor: pointer; }

/* Inline one-click actions inside a table cell — «сделал» / «не сейчас» on the
   «К решению» rows. A form per button rather than JS: the page is
   server-rendered and a POST+redirect keeps the browser's back button honest. */
.inlineform { display: inline; }
.btn.tiny {
  font-size: 11px; padding: 3px 8px; margin-left: 4px;
  border-radius: 6px; line-height: 1.4;
}
.btn.tiny.ghost { background: transparent; opacity: .65; }
.btn.tiny.ghost:hover { opacity: 1; }
/* width:1% with nowrap is the classic shrink-to-content column: without it the
   table gives this cell an equal share, the buttons wrap onto three lines and a
   row grows to 150px for two words. */
td.nowrap, th.nowrap { white-space: nowrap; width: 1%; }

/* «Что делать»: the step corridor under a row's own buttons — «tROAS 180% →
   150–160%». Its own block so it drops below the buttons instead of fighting
   them for the same line, and tabular-nums because a column of these is read
   by comparing the numbers down it, exactly like every money column. */
.stephint {
  display: block; margin-top: 4px; font-size: var(--text-xs);
  color: var(--ink-3); font-variant-numeric: tabular-nums;
}

/* A second line UNDER a number in its cell — «$390 из $31» beneath the ROAS:
   what the ratio is made of. Quieter and smaller than the figure above it, or
   the column reads as two columns. */
.subval {
  display: block; margin-top: 2px; font-size: var(--text-xs);
  color: var(--ink-3); font-variant-numeric: tabular-nums; font-weight: 400;
}
