/* Recreates the Looker Studio report's look: white cards, thin grey rules,
   Roboto-ish system stack, blue sparklines, red/green deltas. */

:root {
  --ink:            #202124;
  --ink-2:          #5f6368;
  --ink-3:          #80868b;
  --line:           #dadce0;
  --line-soft:      #e8eaed;
  --bg:             #ffffff;
  --card:           #ffffff;
  --hdr:            #e8eef8;
  --zebra:          #f8f9fa;
  --blue:           #1a73e8;
  --blue-soft:      #d2e3fc;
  --blue-dark:      #1765cc;
  --blue-wash:      rgba(26,115,232,.10);
  --up:             #188038;
  --down:           #d93025;
  --sel:            #e8f0fe;
  --sel-line:       #1a73e8;
  --warn-bg:        #fef7e0;
  --warn-line:      #f9ab00;
  --warn-ink:       #5f4a00;
  --warn-ink-strong:#3f3100;
  --chip-ink:       #174ea6;
  --on-fill:        #fff;
  /* The funnel's own palette. A second analysis drawn in its own two colours, so which tab
     is open is legible before any text is read. */
  --fun-blue:       #5584ee;
  --fun-blue-soft:  #bdcff7;
  --fun-red:        #a82d25;
  --fun-red-soft:   #efc8c4;
  --radius:         3px;
  --card-w:         185px;
  --card-gap:       48px;
}

* { box-sizing: border-box; }

html { -webkit-text-size-adjust: 100%; }

body {
  margin: 0;
  background: var(--bg);
  color: var(--ink);
  font: 400 13px/1.45 Roboto, "Helvetica Neue", Arial, -apple-system, BlinkMacSystemFont, sans-serif;
  font-feature-settings: "tnum" 1;
}

main { max-width: 1120px; margin: 0 auto; padding: 18px 24px 64px; }

/* ---------------------------------------------------------------- boot */

#boot { position: fixed; inset: 0; display: grid; place-items: center; background: var(--bg); z-index: 50; }
.boot-inner { text-align: center; color: var(--ink-2); }
.spinner {
  width: 28px; height: 28px; margin: 0 auto 14px;
  border: 3px solid var(--line); border-top-color: var(--blue);
  border-radius: 50%; animation: spin .8s linear infinite;
}
@keyframes spin { to { transform: rotate(360deg); } }
#boot.error .spinner { display: none; }
#boot-msg { margin: 0; font-size: 13px; max-width: 46ch; }
#boot.error #boot-msg { color: var(--down); white-space: pre-wrap; text-align: left; }

/* ------------------------------------------------------------ controls */

.controls {
  display: flex; align-items: flex-start; gap: 16px;
  margin-bottom: 22px;
}
.ctl { position: relative; }
.ctl-btn {
  display: flex; align-items: center; gap: 10px;
  min-width: 210px; padding: 9px 12px;
  background: var(--card); border: 1px solid var(--line); border-radius: var(--radius);
  font: inherit; color: var(--ink); text-align: left; cursor: pointer;
}
.ctl-btn:hover { background: var(--zebra); }
.ctl-btn:focus-visible { outline: 2px solid var(--blue); outline-offset: 1px; }
.ctl-label { color: var(--ink-3); font-size: 11px; text-transform: uppercase; letter-spacing: .5px; }
.ctl-value { flex: 1; font-weight: 500; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.caret { width: 0; height: 0; border: 4px solid transparent; border-top-color: var(--ink-2); margin-top: 3px; }

.controls-note { margin-left: auto; text-align: right; color: var(--ink-3); font-size: 11px; }
.controls-note p { margin: 0; }
.currency-note { margin-top: 4px !important; color: var(--ink-2); font-weight: 500; }

.popover {
  position: absolute; top: calc(100% + 4px); left: 0; z-index: 30;
  min-width: 260px; max-height: 420px; overflow: auto;
  background: var(--card); border: 1px solid var(--line); border-radius: var(--radius);
  box-shadow: 0 2px 10px rgba(60,64,67,.28); padding: 8px;
}
.popover-wide { min-width: 320px; }
.pop-section { padding: 4px 0; }
.pop-section + .pop-section { border-top: 1px solid var(--line-soft); margin-top: 6px; padding-top: 8px; }
.pop-title { font-size: 11px; text-transform: uppercase; letter-spacing: .5px; color: var(--ink-3); margin: 2px 4px 6px; }
/* Prose notes, not labels: leave the casing alone. */
.pop-title.prose { text-transform: none; letter-spacing: 0; font-size: 11.5px; line-height: 1.45; }
.pop-row {
  display: flex; align-items: center; gap: 9px;
  padding: 5px 6px; border-radius: var(--radius); cursor: pointer; user-select: none;
}
.pop-row:hover { background: var(--zebra); }
.pop-row input { margin: 0; accent-color: var(--blue); flex: none; }
.pop-row .muted { color: var(--ink-3); margin-left: auto; font-size: 11px; }
.pop-actions { display: flex; gap: 8px; padding: 4px; }
.linkish {
  background: none; border: 0; padding: 3px 4px; font: inherit; font-size: 12px;
  color: var(--blue); cursor: pointer; border-radius: var(--radius);
}
.linkish:hover { background: var(--sel); }
/* A date preset; the active one used to carry style="text-align:left;font-weight:600",
   and because the element already had a style attribute that second declaration never
   applied. */
.preset { text-align: left; }
.preset[aria-current="true"] { font-weight: 600; }
/* A preset outside a free trial: shown, muted, with a padlock and the badge that says what
   opens it (controls.js:renderDatePop). */
.preset.locked { display: flex; align-items: center; gap: 5px; color: var(--ink-3); }
.preset.locked:hover { background: var(--zebra); color: var(--ink-2); }
.preset.locked .lock { flex: none; }
.badge {
  margin-left: auto; padding: 0 6px; border-radius: 8px;
  background: var(--sel); color: var(--chip-ink); font-size: 10px; font-weight: 500; line-height: 16px;
}
/* The upgrade prompt that replaces the date popover's content (upgrade.js). */
.upgrade { display: flex; flex-direction: column; align-items: flex-start; gap: 10px; padding: 4px; max-width: 340px; }
.upgrade p { margin: 0; font-size: 12px; line-height: 1.5; }
.upgrade-account { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; }
.upgrade-name { flex-basis: 100%; font-size: 11px; color: var(--ink-3); }
.upgrade button.primary { padding: 6px 12px; font-size: 12px; }
.upgrade-error { color: var(--down); }
/* An <a> that sits in a row of .linkish buttons (the footer's Privacy link). */
a.linkish { text-decoration: none; }
.preset-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 2px; }
.date-fields { display: flex; align-items: center; gap: 8px; padding: 6px 4px 2px; }
.date-fields input, .date-fields select {
  font: inherit; padding: 5px 7px; border: 1px solid var(--line); border-radius: var(--radius);
  color: var(--ink); background: var(--card);
}
.date-fields span { color: var(--ink-3); }

/* --------------------------------------------------------- filter chips */

.filter-bar {
  display: flex; flex-wrap: wrap; align-items: center; gap: 7px;
  margin: -8px 0 20px; padding: 9px 11px;
  background: var(--zebra); border: 1px solid var(--line-soft); border-radius: var(--radius);
}
.filter-bar .fb-label { font-size: 11px; text-transform: uppercase; letter-spacing: .5px; color: var(--ink-3); }
.chip {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 3px 5px 3px 9px; background: var(--sel); color: var(--chip-ink);
  border: 1px solid var(--blue-soft); border-radius: 11px; font-size: 12px;
}
.chip b { font-weight: 500; }
.chip .x {
  background: none; border: 0; cursor: pointer; color: var(--chip-ink);
  font-size: 14px; line-height: 1; padding: 0 2px; border-radius: 50%;
}
.chip .x:hover { background: var(--blue-soft); }

.notice {
  display: flex; gap: 10px; align-items: flex-start;
  margin: 0 0 18px; padding: 10px 12px;
  background: var(--warn-bg); border-left: 3px solid var(--warn-line); border-radius: 0 var(--radius) var(--radius) 0;
  font-size: 12px; line-height: 1.5; color: var(--warn-ink);
}
.notice b { color: var(--warn-ink-strong); }
.notice .x { margin-left: auto; background: none; border: 0; cursor: pointer; color: var(--warn-ink); font-size: 15px; line-height: 1; }
/* The free trial's standing notice: information, not a warning about the data. */
.notice.trial { background: var(--sel); border-left-color: var(--blue); color: var(--chip-ink); }
.notice.trial b { color: var(--chip-ink); }
.notice.trial .x { color: var(--chip-ink); }
.notice.trial .linkish { padding: 0 2px; font-weight: 500; text-decoration: underline; }


/* -------------------------------------------------------------- tree */

/* The tree has a fixed minimum width. Scroll it inside its own box rather than
   letting the page scroll horizontally. */
.tree-wrap { position: relative; overflow-x: auto; overflow-y: hidden; padding-bottom: 2px; }
#tree-lines { position: absolute; top: 0; left: 0; pointer-events: none; overflow: visible; }
.tree {
  position: relative; z-index: 1; min-width: max-content;
  display: grid;
  grid-template-columns: repeat(4, var(--card-w));
  justify-content: center;
  column-gap: var(--card-gap);
  row-gap: 40px;
}
.node { display: flex; flex-direction: column; }
/* Column placement as classes, not style attributes: the CSP sets `style-src 'self'`,
   which blocks inline style attributes. Only the start line is set here; .span2 below
   extends it. */
.col-1 { grid-column-start: 1; }
.col-2 { grid-column-start: 2; }
.col-3 { grid-column-start: 3; }
.col-4 { grid-column-start: 4; }
/* parents straddle two columns and sit centred over their children */
.node.span2 { grid-column-end: span 2; align-items: center; }
.node.span2 > * { width: var(--card-w); }

.card {
  border: 1px solid var(--line); border-radius: var(--radius); background: var(--card);
  padding: 10px 12px 0; min-height: 96px;
  display: flex; flex-direction: column;
}
.card.dim { opacity: .55; }
/* Beside the tree rather than in it: see TREE_ROWS. Pushed out from the grid to the content
   edge the banners above span, so they sit apart from the tree instead of inside its outline.
   --out is the grid's margin inside .tree-wrap; zero once the tree is wider than its box. */
.tree-wrap { container-type: inline-size; }
.node.detached { --out: max(0px, (100cqw - 4 * var(--card-w) - 3 * var(--card-gap)) / 2); }
.node.edge-l { translate: calc(-1 * var(--out)) 0; }
.node.edge-r { translate: var(--out) 0; }
.node.detached .card { border-style: dashed; filter: grayscale(1); }  /* recede beside the tree */
.card-caption { font-size: 10px; color: var(--ink-3); line-height: 1.3; }
.card-title {
  font-size: 12px; color: var(--ink-2); line-height: 1.3;
  display: flex; align-items: center; gap: 4px; min-height: 16px;
}
.card-title select {
  font: inherit; color: inherit; padding: 1px 2px; margin-left: -3px;
  border: 1px solid var(--line); border-radius: var(--radius); background: var(--card);
}
.card-value {
  font-size: 27px; font-weight: 400; letter-spacing: -.4px; line-height: 1.25;
  margin-top: 4px; white-space: nowrap;
}
.card-value.small { font-size: 22px; }
.delta { font-size: 12px; font-weight: 500; margin-top: 1px; height: 16px; white-space: nowrap; }
.delta.up { color: var(--up); }
.delta.down { color: var(--down); }
.delta.flat { color: var(--ink-2); }
.delta.na { color: var(--ink-3); }
/* The selection against the unfiltered total, only while a table filter is on -- see
   vsTotalHTML. Neutral so it never reads as a second YoY. */
.vs-total {
  font-size: 11px; margin-top: 1px; height: 15px; white-space: nowrap; color: var(--ink-2);
  cursor: help; width: max-content; max-width: 100%; border-bottom: 1px dotted var(--line);
}
.vs-total:empty { border-bottom: 0; }
.vs-total.na { color: var(--ink-3); cursor: default; border-bottom: 0; }
/* The revenue a metric's own move accounts for, carrying the same up/down colour as the
   percentage it qualifies -- see whatIfHTML, which takes its direction from the same
   pctChange rather than from the figure's own sign. Underlined only as wide as the text, so
   the affordance follows the figure instead of the card. */
.whatif {
  font-size: 11px; margin-top: 1px; height: 15px; white-space: nowrap;
  color: var(--ink-2); cursor: help;
  width: max-content; max-width: 100%;
  border-bottom: 1px dotted var(--line);
}
.whatif.up { color: var(--up); }
.whatif.down { color: var(--down); }
.whatif.flat { color: var(--ink-2); }
.whatif.na { color: var(--ink-3); }
.arrow { font-size: 9px; vertical-align: 1px; }
.spark { margin: auto -12px 0; display: block; width: calc(100% + 24px); height: 34px; }

.aside { padding: 7px 1px 0; }
.aside-title { font-size: 10px; color: var(--ink-3); line-height: 1.3; }
.aside-value { font-size: 15px; color: var(--ink); line-height: 1.35; white-space: nowrap; }
.aside-delta { font-size: 10px; font-weight: 500; }
.aside-delta.up { color: var(--up); }
.aside-delta.down { color: var(--down); }
.aside-delta.flat, .aside-delta.na { color: var(--ink-3); }
.aside-formula { font-size: 10px; color: var(--ink-3); margin-top: 2px; line-height: 1.35; }

.info {
  display: inline-grid; place-items: center; flex: none;
  width: 12px; height: 12px; border-radius: 50%;
  background: var(--ink-3); color: var(--on-fill); font-size: 9px; font-weight: 700;
  cursor: help; font-style: normal;
}
/* Outside .card-title's flex row -- a value, a delta or a table cell -- the marker sits
   inline after the figure it qualifies, so it needs its own spacing and baseline. */
.card-value .info, .aside-value .info, .delta .info, .aside-delta .info, td .info {
  margin-left: 3px; vertical-align: middle;
}

.rule { border: 0; border-top: 1px solid var(--line); margin: 40px 0 22px; }

/* ------------------------------------------------------------- tables */

.table-block { margin-bottom: 6px; }
/* A table whose filter cannot apply on this tab (selection.js:unsplit): covered, with the reason. */
.table-block.unsplit { position: relative; }
.unsplit-cover {
  position: absolute; inset: 0; z-index: 2; display: flex; align-items: center;
  justify-content: center; padding: 16px;
  background: color-mix(in srgb, var(--card) 88%, transparent);
}
.unsplit-cover p {
  max-width: 520px; margin: 0; padding: 12px 16px; font-size: 12px; color: var(--ink);
  background: var(--card); border: 1px solid var(--line); border-radius: var(--radius);
}
/* Positioned so each Metrics popover opens under its own button, not against the page. */
.table-head { position: relative; display: flex; align-items: center; gap: 10px; margin-bottom: 7px; }
.table-head h2 { font-size: 13px; font-weight: 500; margin: 0; color: var(--ink); }
.table-head .hint { font-size: 11px; color: var(--ink-3); }
.table-head .spacer { flex: 1; }
.cols-btn {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 5px 9px; background: var(--card); border: 1px solid var(--line);
  border-radius: var(--radius); font: inherit; font-size: 12px; color: var(--ink-2); cursor: pointer;
}
.cols-btn:hover { background: var(--zebra); }
.table-scroll { overflow-x: auto; border: 1px solid var(--line-soft); border-radius: var(--radius); }
/* Source / medium and campaign run to hundreds of rows: scroll them, header and total pinned. */
#table-channel .table-scroll { max-height: 70vh; overflow-y: auto; }
#table-channel thead th { position: sticky; top: 0; z-index: 1; }
#table-channel tbody tr.total td { position: sticky; bottom: 0; }
/* Campaign and source / medium labels run long; unwrapped, the first column pushes every
   metric column out past the table's edge. Capped on a span because cells ignore max-width. */
.dim-label { display: inline-block; max-width: 240px; white-space: normal; overflow-wrap: anywhere; }
.table-head h2 select {
  font: inherit; font-weight: 500; color: var(--ink); padding: 3px 6px;
  border: 1px solid var(--line); border-radius: var(--radius); background: var(--card);
}
.table-head h2 option:disabled { color: var(--ink-3); }

table { border-collapse: collapse; width: 100%; font-size: 12px; }
thead th {
  background: var(--hdr); color: var(--ink); font-weight: 500; text-align: right;
  padding: 8px 10px; vertical-align: bottom; white-space: normal; line-height: 1.3;
  border-bottom: 1px solid var(--line); cursor: pointer; user-select: none;
}
thead th:first-child { text-align: left; }
thead th:hover { background: #dde6f6; }
thead th .sort { color: var(--blue); font-size: 9px; margin-left: 3px; }
tbody td { padding: 7px 10px; text-align: right; border-bottom: 1px solid var(--line-soft); white-space: nowrap; }
tbody td:first-child { text-align: left; }
tbody tr:nth-child(even) { background: var(--zebra); }
tbody tr.pick { cursor: pointer; }
tbody tr.pick:hover td { background: #f1f3f4; }
tbody tr.sel td { background: var(--sel) !important; }
/* Accent the row once, on its first cell -- on every cell it reads as column dividers. */
tbody tr.sel td:first-child { box-shadow: inset 2px 0 0 var(--sel-line); }
tbody tr.faded td { color: var(--ink-3); }
tbody tr.total td { font-weight: 500; background: var(--card) !important; border-top: 1px solid var(--line); border-bottom: 0; }
.d-up { color: var(--up); }
.d-down { color: var(--down); }
.d-na { color: var(--ink-3); }
.table-foot { display: flex; justify-content: flex-end; gap: 14px; padding: 7px 2px 0; font-size: 11px; color: var(--ink-2); }
.table-note {
  margin: 6px 2px 0; max-width: 900px;
  font-size: 11px; line-height: 1.5; color: var(--ink-2);
}
.table-note b { font-weight: 600; color: var(--ink); }

/* -------------------------------------------------------------- funnel */

/* One SVG sized to this box, and scrollable below the width at which its two scales stop
   being readable. The caption is a normal block inside it, so it still wraps to the panel
   rather than to the chart. Only the chart scrolls: the comparison radios above it must stay
   put. */
.funnel-wrap { display: block; }
.funnel-chart { display: block; overflow-x: auto; }
.funnel { display: block; }

/* The two context cards, above the radios and the chart: the tree's own card, given the width
   the tree's grid would have handed it. */
.funnel-cards { display: flex; flex-wrap: wrap; gap: 12px; margin: 0 0 16px; }
.funnel-cards .card { width: var(--card-w); }

/* The comparison element, as a radio group directly above the chart. A fieldset is the
   accessible grouping for a radio set; the reset keeps it from drawing a box of its own. */
.funnel-cmp { margin: 0 0 12px; padding: 0; border: 0; }
.funnel-cmp legend {
  padding: 0; font-size: 11px; text-transform: uppercase; letter-spacing: .5px; color: var(--ink-3);
}
.funnel-radio-row { display: flex; flex-wrap: wrap; gap: 4px 22px; margin-top: 5px; }
.funnel-radio { display: inline-flex; align-items: baseline; gap: 6px; cursor: pointer; }
.funnel-radio input { margin: 0; accent-color: var(--blue); }
.funnel-radio-label { font-size: 12px; }
.funnel-status { margin: 0; padding: 14px 2px; max-width: 900px; color: var(--ink-2); font-size: 13px; }
.funnel-status b { color: var(--ink); }
.funnel-caption { margin-top: 12px; }
/* Raised only when a step sits above the one before it, which a session funnel should not
   produce -- see funnel.js:funnelWarn. */
.funnel-warn {
  margin: 8px 2px 0; padding: 8px 10px; max-width: 900px;
  background: var(--warn-bg); border-left: 3px solid var(--warn-line);
  border-radius: 0 var(--radius) var(--radius) 0;
  font-size: 11px; line-height: 1.5; color: var(--warn-ink);
}
.funnel-warn b { color: var(--warn-ink-strong); }

/* ------------------------------------------------------- product matrix */

/* The two boxes the tab is about carry a colour each: orange for "fix conversion", blue for
   "send traffic" -- a pair that stays apart under every common colour-vision deficiency. The
   other two recede to grey. Text stays in the ink colours; the bubble carries identity. */
.pm-bar { display: flex; flex-wrap: wrap; align-items: center; gap: 8px 16px; margin: 0 0 10px; }
.pm-dim { display: inline-flex; align-items: center; gap: 8px; font-size: 12px; color: var(--ink-2); }
.pm-dim select {
  font: inherit; color: var(--ink); padding: 4px 6px;
  border: 1px solid var(--line); border-radius: var(--radius); background: var(--card);
}
.pm-explain {
  max-width: 900px; margin: 0 0 14px; padding: 10px 12px;
  background: var(--zebra); border-left: 3px solid var(--blue); border-radius: 0 var(--radius) var(--radius) 0;
  font-size: 12px; line-height: 1.55; color: var(--ink-2);
}
.pm-explain p { margin: 0; }
.pm-explain p + p { margin-top: 6px; }
.pm-explain b { color: var(--ink); font-weight: 600; }
.pm-chart { display: block; width: 100%; max-width: 820px; height: auto; margin: 0 auto; }
.pm-line { stroke: var(--ink-3); stroke-width: 1.5; fill: none; }
.pm-axis { font-size: 11px; fill: var(--ink-2); }
.pm-title { font-weight: 500; fill: var(--ink); }
.pm-q circle { fill: var(--zebra); stroke: var(--ink-3); stroke-width: 2; }
.pm-q1 circle { fill: #fdebd9; stroke: #e8710a; }
.pm-q4 circle { fill: #dce8fc; stroke: var(--blue); }
.pm-q { cursor: help; }
/* The whole box answers the tooltip, not only the ink in it. */
.pm-hit { fill: transparent; }
.pm-value { font-weight: 600; fill: var(--ink); }
.pm-id { font-size: 12px; font-weight: 700; fill: var(--ink-2); }
.pm-name { font-size: 12px; font-weight: 600; fill: var(--ink); }
.pm-action { font-size: 11.5px; fill: var(--ink); }
.pm-count { font-size: 11px; fill: var(--ink-2); }
.pm-q2 .pm-name, .pm-q3 .pm-name, .pm-q2 .pm-action, .pm-q3 .pm-action { fill: var(--ink-2); }
.pm-est { cursor: help; color: var(--ink-3); }

/* The Matrix / Movers switch: one tab's two views, so a segmented control rather than tabs. */
.seg { display: inline-flex; border: 1px solid var(--line); border-radius: var(--radius); overflow: hidden; }
.seg-btn {
  font: inherit; font-size: 12px; padding: 5px 12px; border: 0; background: var(--card);
  color: var(--ink-2); cursor: pointer;
}
.seg-btn + .seg-btn { border-left: 1px solid var(--line); }
.seg-btn:hover { background: var(--zebra); }
.seg-btn.on { background: var(--sel); color: var(--blue); font-weight: 500; }
.seg-btn:focus-visible { outline: 2px solid var(--blue); outline-offset: -2px; }

/* Movers. The headline says what happened; the ranked moves and the grid say where. Grid cells
   are tinted by their revenue change against the largest move's, in four steps (t1-t4): red a
   loss, green a gain. Stable diagonals are muted. */
.mv-headline { font-size: 18px; line-height: 1.4; color: var(--ink); margin: 0 2px 4px; }
.mv-headline b { font-weight: 600; }
.mv-explain { margin: 6px 2px 0; }
.mv-summary { margin: 0 2px 10px; }
.mv-top { display: flex; flex-wrap: wrap; align-items: flex-start; gap: 16px 32px; }
.mv-ranked { flex: 1 1 380px; min-width: 0; }
.mv-ranked h2 { font-size: 13px; font-weight: 500; margin: 0 0 4px; }
.mv-ranked ol { margin: 0; padding: 0; list-style: none; }
.mv-rank {
  display: block; width: 100%; text-align: left; font: inherit; font-size: 13px; color: var(--ink);
  padding: 5px 8px; background: none; border: 1px solid transparent; border-radius: var(--radius); cursor: pointer;
}
.mv-rank:hover { background: var(--zebra); }
.mv-rank.on { background: var(--sel); border-color: var(--sel-line); }
.mv-grid { width: auto; border-collapse: separate; border-spacing: 3px; font-size: 12px; flex: 0 0 auto; }
.mv-grid tr { background: none !important; }
.mv-grid th { background: none; border: 0; cursor: default; font-weight: 500; text-align: center;
  padding: 2px 6px; white-space: nowrap; vertical-align: middle; }
.mv-grid thead th:hover { background: none; }
.mv-grid th .muted { display: block; font-weight: 400; font-size: 11px; }
.mv-grid th[scope="row"] { text-align: right; }
.mv-grid .corner { font-size: 11px; color: var(--ink-2); font-weight: 400; }
.mv-grid td.mv-cell { width: 84px; height: 46px; padding: 0; text-align: center; border: 1px solid var(--line-soft);
  border-radius: var(--radius); }
.mv-cell b, .mv-cell span { display: block; }
.mv-grid td.mv-cell.stay { background: var(--zebra); color: var(--ink-3); border-style: dashed; }
.mv-cell button {
  width: 100%; height: 100%; font: inherit; color: var(--ink); cursor: pointer; border: 0;
  border-radius: var(--radius); background: none; outline-offset: -2px;
}
.mv-cell button:hover { outline: 1px solid var(--ink-3); }
.mv-cell button.on { outline: 2px solid var(--sel-line); }
.mv-cell button:focus-visible { outline: 2px solid var(--blue); }
.mv-cell .loss { --c: var(--down); }
.mv-cell .gain { --c: var(--up); }
.mv-cell .t1 { background: color-mix(in srgb, var(--c) 8%, transparent); }
.mv-cell .t2 { background: color-mix(in srgb, var(--c) 18%, transparent); }
.mv-cell .t3 { background: color-mix(in srgb, var(--c) 30%, transparent); }
.mv-cell .t4 { background: color-mix(in srgb, var(--c) 45%, transparent); }
.mv-excl { display: flex; flex-wrap: wrap; align-items: baseline; gap: 6px 14px; margin: 10px 2px 0; font-size: 12px; }
.mv-excl summary { cursor: pointer; color: var(--ink-2); }
.mv-excl .mv-lists { justify-content: flex-start; }
.mv-lists { display: flex; flex-wrap: wrap; justify-content: center; gap: 8px; margin: 6px 0 4px; }
.mv-list {
  font: inherit; font-size: 12px; padding: 5px 10px; cursor: pointer; color: var(--ink);
  background: var(--card); border: 1px solid var(--line); border-radius: var(--radius);
}
.mv-list:hover { background: var(--zebra); }
.mv-list.on { background: var(--sel); border-color: var(--sel-line); }
.mv-selected { margin: 8px 2px 0; font-size: 12px; color: var(--ink-2); }
.mv-selected b { color: var(--ink); }
.mv-table th, .mv-table td, .mv-table td:first-child { text-align: left; }
.mv-table td { vertical-align: top; white-space: normal; }
.mv-table .nw { white-space: nowrap; }
.mv-table tr.mv-gaining td { color: var(--ink-2); }
.mv-detail td { background: var(--zebra); font-size: 12px; }
.mv-detail td > span { margin-right: 18px; white-space: nowrap; display: inline-block; }
.mv-open { padding: 0 4px; }

.ptable-block { margin-top: 26px; }
.ptable-head { display: flex; flex-wrap: wrap; align-items: center; gap: 6px 12px; margin-bottom: 4px; }
.ptable-head h2 { font-size: 13px; font-weight: 500; margin: 0; }
.ptable-head .spacer { flex: 1; }
.ptable-potential { font-size: 12px; color: var(--ink-2); }
.ptable-potential b { color: var(--up); font-weight: 600; }
.ptable-lead { margin: 0 2px 8px; }
/* Ten rows tall, whatever is shown: more rows scroll inside it rather than lengthen the page. */
.ptable-scroll { max-height: 352px; overflow-y: auto; }
.ptable thead th { position: sticky; top: 0; z-index: 1; cursor: default; }
.ptable thead th:hover { background: var(--hdr); }
.ptable s { color: var(--ink-3); }
.table-foot .linkish { font-size: 11px; padding: 0 4px; }

.cols-pop { left: auto; right: 0; min-width: 420px; }
.cols-grid { display: grid; grid-template-columns: 1fr repeat(4, 42px); gap: 0 2px; align-items: center; }
.cols-grid .ch { font-size: 10px; color: var(--ink-3); text-align: center; padding-bottom: 5px; letter-spacing: .3px; }
.cols-grid .mname { padding: 4px 4px; font-size: 12px; display: flex; align-items: center; gap: 4px; }
.cols-grid label { display: grid; place-items: center; padding: 4px 0; border-radius: var(--radius); cursor: pointer; }
.cols-grid label:hover { background: var(--zebra); }
.cols-grid input { margin: 0; accent-color: var(--blue); }
.cols-grid .rowline { grid-column: 1 / -1; border-top: 1px solid var(--line-soft); }
/* A column checkbox that cannot be offered here: muted and unclickable. */
.col-blocked { opacity: .3; cursor: not-allowed; }
/* The "compared with" line under the custom date fields. */
.date-note { margin-top: 8px; }

.foot {
  display: flex; flex-wrap: wrap; align-items: baseline; gap: 6px 16px;
  margin-top: 34px; padding-top: 12px; border-top: 1px solid var(--line-soft);
  font-size: 11px; color: var(--ink-3);
}
.foot-actions { margin-left: auto; display: flex; gap: 4px; }
.foot-actions .linkish { font-size: 11px; }

.tooltip {
  position: fixed; z-index: 60; max-width: 280px;
  background: #3c4043; color: var(--on-fill); font-size: 11px; line-height: 1.45;
  padding: 7px 9px; border-radius: var(--radius); pointer-events: none;
  box-shadow: 0 2px 8px rgba(0,0,0,.3);
}

@media (max-width: 980px) {
  :root { --card-w: 150px; --card-gap: 26px; }
  .controls { flex-wrap: wrap; }
  .controls-note { margin-left: 0; text-align: left; width: 100%; }
}

[hidden] { display: none !important; }

/* ---------------------------------------------------------------- tabs */

/* Right-aligned on its own line above the tab bar. */
.tour-btn { display: block; margin: 0 0 4px auto; }
.tabs { display: flex; gap: 2px; margin: 0 0 20px; border-bottom: 1px solid var(--line); }
.tab {
  display: flex; flex-direction: column; gap: 2px; align-items: flex-start;
  padding: 9px 15px 10px; background: none; border: 0; border-bottom: 2px solid transparent;
  font: inherit; color: var(--ink-2); cursor: pointer; text-align: left; margin-bottom: -1px;
}
.tab:hover { background: var(--zebra); }
.tab:focus-visible { outline: 2px solid var(--blue); outline-offset: -2px; }
.tab.on { color: var(--blue); border-bottom-color: var(--blue); }
.tab-label { font-size: 13px; font-weight: 500; }
.tab-hint { font-size: 11px; color: var(--ink-3); }
.tab.on .tab-hint { color: var(--ink-2); }

/* --------------------------------------------------------------- setup */

/* Sign-in and the property picker. Same palette and type as the dashboard, so the step from
   setup to report does not read as a change of product, but set larger: this is read, not
   scanned. */

.setup {
  min-height: 100vh; display: grid; place-items: start center; padding: 8vh 20px 40px;
  background: var(--hdr);
}
.setup-card {
  --pad: 36px;
  width: 100%; min-width: 0; max-width: 600px; padding: 30px var(--pad) 22px;
  background: var(--card); border: 1px solid var(--line); border-radius: 6px;
  box-shadow: 0 1px 2px rgba(60,64,67,.10), 0 4px 16px rgba(60,64,67,.08);
  font-size: 15px; line-height: 1.5;
}
.setup[data-step="pick"] .setup-card { max-width: 680px; }
.setup-head {
  display: flex; flex-wrap: wrap; align-items: baseline; justify-content: space-between;
  gap: 8px 20px; margin-bottom: 22px;
}
.setup h1 { margin: 0; font-size: 22px; font-weight: 500; letter-spacing: -.3px; }
/* The audience line under the product name: a quiet second line, sentence case. --ink-2 is
   6.3:1 on the card. */
.setup .brand-audience {
  margin: 1px 0 0; font-size: 13px; line-height: 1.3; font-weight: 400; letter-spacing: .2px;
  color: var(--ink-2);
}
.setup p { margin: 0 0 14px; }
.setup-lead { font-size: 18px; line-height: 1.4; color: var(--ink); }
.setup-panel { margin-bottom: 4px; }
.setup-note { color: var(--down); font-size: 12px; }
.setup code { font-size: 12px; background: var(--zebra); padding: 1px 4px; border-radius: var(--radius); }

/* The three steps, numbered because they are a sequence: done ones ticked, the current one
   filled. main.js sets aria-current. */
.steps {
  list-style: none; margin: 0; padding: 0; counter-reset: step;
  display: flex; align-items: center; gap: 8px; font-size: 12px; color: var(--ink-3);
}
.steps li { counter-increment: step; display: flex; align-items: center; gap: 6px; white-space: nowrap; }
.steps li::before {
  content: counter(step); display: inline-grid; place-items: center;
  width: 18px; height: 18px; border: 1px solid var(--line); border-radius: 50%; font-size: 10px;
}
.steps li:not(:last-child)::after { content: ""; width: 12px; height: 1px; background: var(--line); }
.steps li[aria-current="step"] { color: var(--ink); font-weight: 500; }
.steps li[aria-current="step"]::before { background: var(--blue); border-color: var(--blue); color: var(--on-fill); }
.steps li:has(~ [aria-current="step"])::before { content: "✓"; color: var(--blue); border-color: var(--blue-soft); background: var(--sel); }

/* The top of the metric tree, greyed out, as the sign-in screen's picture of what it builds.
   The lines' overlay sits where the tree starts: the figure's top padding, no side padding. */
.hero {
  position: relative; margin: 0 0 18px; padding: 18px 0;
  background: var(--zebra); border-radius: var(--radius); overflow: hidden;
}
#hero-lines { position: absolute; top: 18px; left: 0; pointer-events: none; overflow: visible; }
.tree.mini { --card-w: 116px; --card-gap: 14px; row-gap: 26px; }
.tree.mini .card { min-height: 0; padding: 7px 9px 0; }
.tree.mini .card-title { font-size: 11px; }
.tree.mini .ghost-value { height: 12px; margin-top: 6px; }
.tree.mini .ghost-delta, .tree.mini .aside { display: none; }
.tree.mini .ghost-spark { height: 14px; }
.signin-scope { margin: 12px 0 0 !important; font-size: 13px; color: var(--ink-2); }

/* The short form of the privacy note. The three points only on the sign-in step; the links
   on every step. */
.setup-privacy {
  margin-top: 24px; padding-top: 14px; border-top: 1px solid var(--line-soft);
  font-size: 12px; color: var(--ink-3);
}
.privacy-points {
  list-style: none; margin: 0 0 8px; padding: 0;
  display: flex; flex-wrap: wrap; gap: 4px 18px; color: var(--ink-2);
}
.privacy-points li::before { content: "✓"; margin-right: 6px; color: var(--up); }
.setup:not([data-step="signin"]) .privacy-points { display: none; }
.setup-privacy p { display: flex; align-items: center; gap: 14px; margin: 0; }
.setup-privacy a, .setup-privacy .linkish { color: var(--ink-2); }
.setup-privacy .linkish { padding: 0; font-size: inherit; text-decoration: underline; }

button.primary {
  padding: 9px 16px; border: 0; border-radius: var(--radius);
  background: var(--blue); color: var(--on-fill); font: inherit; font-weight: 500; cursor: pointer;
}
button.primary:hover { background: var(--blue-dark); }
button.primary:focus-visible { outline: 2px solid var(--blue); outline-offset: 2px; }
button.primary:disabled { background: var(--line); color: var(--ink-3); cursor: not-allowed; }

/* Google's sign-in branding: the four-colour G on white with a grey border and no shadow,
   per https://developers.google.com/identity/branding-guidelines. Visible text beside the
   mark, so the mark itself is aria-hidden. */
button.google {
  display: inline-flex; align-items: center; gap: 10px;
  padding: 9px 16px; border: 1px solid var(--line); border-radius: var(--radius);
  background: var(--card); color: var(--ink); font: inherit; font-weight: 500; cursor: pointer;
}
button.google:hover { background: var(--zebra); }
button.google:focus-visible { outline: 2px solid var(--blue); outline-offset: 2px; }
button.google:disabled { color: var(--ink-3); cursor: not-allowed; }
button.google svg { flex: none; }

/* ------------------------------------------------------------- documents */

/* Standalone prose pages (privacy.html): the setup card with the typography a document
   needs and the setup screen does not. */
.setup .doc h2 { margin: 20px 0 6px; font-size: 14px; font-weight: 600; }
.setup .doc h2:first-of-type { margin-top: 22px; }
.setup .doc ul { margin: 0 0 12px; padding-left: 20px; }
.setup .doc li { margin-bottom: 5px; line-height: 1.55; }
.setup .doc a { color: var(--blue); }
.setup .doc .doc-note {
  margin-top: 22px; padding-top: 12px; border-top: 1px solid var(--line-soft);
  font-size: 11px; color: var(--ink-3);
}

/* The picker: chips for what is ticked, the filter, the list, and the action bar, which stays
   in view at the bottom of the window however long the list runs. */
.pick-chips { display: flex; flex-wrap: wrap; gap: 6px; margin: 0 0 10px; }
.pick-chips:empty { display: none; }
.pick-chip {
  display: inline-flex; align-items: center; gap: 6px; padding: 3px 8px 3px 10px;
  background: var(--sel); border: 1px solid var(--blue-soft); border-radius: 999px;
  font: inherit; font-size: 13px; color: var(--chip-ink); cursor: pointer;
}
.pick-chip::after { content: "×"; font-size: 15px; line-height: 1; }
.pick-chip:hover { background: var(--blue-soft); }
.pick-chip:focus-visible { outline: 2px solid var(--blue); outline-offset: 1px; }
.pick-filter {
  width: 100%; margin-bottom: 6px; padding: 9px 11px;
  font: inherit; color: var(--ink); background: var(--card);
  border: 1px solid var(--line); border-radius: var(--radius);
}
.pick-filter:focus-visible { outline: 2px solid var(--blue); outline-offset: -1px; }
.muted { color: var(--ink-3); font-size: 11px; }
.pick-list .pop-row { padding: 6px 8px; }
.pick-account {
  font-size: 11px; text-transform: uppercase; letter-spacing: .5px; color: var(--ink-3);
  margin: 16px 8px 4px;
}
.pick-account:first-child { margin-top: 8px; }
/* With the paywall on: an account's Unlock or Manage billing buttons, and its locked rows. */
.pick-account .linkish { margin-left: 8px; text-transform: none; letter-spacing: 0; }
.pick-list .pick-locked { cursor: default; opacity: .45; }   /* the whole row, its checkbox too */
.pick-list .pick-locked:hover { background: none; }
/* Each row's access, in a column of its own after the id; and a free trial's consent under its row. */
.pick-status { flex: none; min-width: 112px; font-size: 12px; color: var(--ink-2); text-align: right; }
.pick-confirm {
  display: flex; flex-wrap: wrap; align-items: center; gap: 8px 12px;
  margin: 2px 8px 8px 30px; padding: 10px 12px;
  background: var(--zebra); border-radius: var(--radius); font-size: 13px;
}
.pick-confirm p { flex: 1 1 100%; margin: 0; }
.pick-confirm .primary { padding: 6px 12px; }
.pick-confirm-error { color: var(--down); }
/* The modal question before Delete local data and Sign out (js/confirm-box.js). The padding
   is on the inner div, so a click on the dialog box itself is a click on its backdrop. */
.confirm-box {
  max-width: 420px; padding: 0; color: var(--ink);
  background: var(--card); border: 1px solid var(--line); border-radius: var(--radius);
  box-shadow: 0 2px 10px rgba(60,64,67,.28);
}
.confirm-box::backdrop, .settings-box::backdrop { background: rgba(32,33,36,.4); }
/* The optional drop-down a confirmation may carry (Cancel subscription's reason). */
.confirm-box-choice { display: flex; flex-direction: column; gap: 6px; margin: -6px 0 18px; font-size: 13px; color: var(--ink-2); }
.confirm-box-choice select {
  padding: 6px 8px; font: inherit; color: var(--ink);
  background: var(--card); border: 1px solid var(--line); border-radius: var(--radius);
}
/* The Account box (js/settings.js): billing per paid account, then this browser's actions.
   The padding is on the inner div, as in the confirmation, so a click on the box is the backdrop's. */
.settings-box {
  width: min(520px, calc(100vw - 32px)); padding: 0; color: var(--ink);
  background: var(--card); border: 1px solid var(--line); border-radius: var(--radius);
  box-shadow: 0 2px 10px rgba(60,64,67,.28);
}
.settings-inner { padding: 20px 22px 16px; }
.settings-title { margin: 0 0 14px; font-size: 16px; font-weight: 500; }
.settings-box h3 { margin: 0 0 6px; font-size: 13px; font-weight: 500; }
.settings-box h3.settings-section, .settings-browser h3 {
  font-size: 11px; text-transform: uppercase; letter-spacing: .5px; color: var(--ink-3); font-weight: 400;
}
.settings-billing, .settings-browser { margin-bottom: 18px; }
.settings-account { padding: 12px 0; border-top: 1px solid var(--line-soft); }
.settings-status { margin: 0 0 8px; font-size: 13px; color: var(--ink-2); }
.settings-actions { display: flex; flex-wrap: wrap; gap: 4px 8px; margin-left: -8px; }
.settings-actions .linkish, .settings-browser .linkish { font-size: 13px; padding: 4px 8px; }
.settings-browser .linkish:first-of-type { margin-left: -8px; }
.settings-cancel { color: var(--down); }
.settings-note { margin: 6px 0 0; font-size: 12px; color: var(--ink-2); }
.settings-note:empty { display: none; }
.settings-error { color: var(--down); font-size: 12px; }
.confirm-box-inner { padding: 20px 22px 16px; }
.confirm-box-title { margin: 0 0 10px; font-size: 16px; font-weight: 500; }
.confirm-box-body { margin: 0 0 18px; font-size: 13px; line-height: 1.5; color: var(--ink-2); }
.confirm-box-actions { display: flex; justify-content: flex-end; align-items: center; gap: 12px; }
.confirm-box-actions .linkish { font-size: 13px; padding: 6px 8px; }
button.primary.danger { background: var(--down); }
button.primary.danger:hover { background: color-mix(in srgb, var(--down) 85%, black); }
button.primary.danger:focus-visible { outline-color: var(--down); }
.pick-more > summary { padding: 5px 8px; font-size: 13px; color: var(--ink-2); cursor: pointer; }
.pick-more > summary:hover { color: var(--ink); }
.pick-more > .pop-row { margin-left: 18px; }
.pick-actions {
  position: sticky; bottom: 0; z-index: 2;
  display: flex; align-items: center; gap: 12px;
  margin: 10px calc(-1 * var(--pad)) 0; padding: 14px var(--pad);
  background: var(--card); border-top: 1px solid var(--line-soft);
}
.pick-count { margin-right: auto; font-size: 13px; color: var(--ink-2); }
.pick-actions button { white-space: nowrap; }

.setup-error {
  margin: 12px 0 0; padding: 10px 12px;
  background: #fce8e6; border-left: 3px solid var(--down); border-radius: 0 var(--radius) var(--radius) 0;
  font-size: 12px; color: #a50e0e;
}
.setup-error p { margin: 0 0 6px; white-space: pre-wrap; }

/* ------------------------------------------------------------- loading */

/* A loading tab's bar (js/progress.js), under its status line and as wide as the page. Its width
   is set from script, through CSSOM, which the CSP allows; .done fills it and fades it out. */
.tabbar-track { height: 4px; margin: 4px 0 14px; background: var(--line-soft); border-radius: 2px; overflow: hidden; }
.tabbar { width: 0; height: 100%; background: var(--blue); }
.tabbar.off { display: none; }
.tabbar.done { width: 100% !important; opacity: 0; transition: width .2s ease-out, opacity .3s ease-in .25s; }

/* Greyed-out stand-ins for figures not yet loaded: the ghost dashboard's cards, the sign-in
   screen's tree, and a loading tab's chart. One slow pulse, all together. */
.ghost-card { border-color: var(--line-soft); }
.ghost-card .card-title { color: var(--ink-3); }
.ghost-block {
  display: block; background: var(--line-soft); border-radius: 2px;
  animation: ghost-pulse 1.6s ease-in-out infinite;
}
@keyframes ghost-pulse { 50% { opacity: .45; } }
.ghost-value { width: 62%; height: 24px; margin-top: 8px; }
.ghost-delta { width: 34%; height: 10px; margin-top: 7px; }
.ghost-spark { margin: auto -12px 0; height: 34px; background: linear-gradient(to top, var(--zebra), transparent); }
.ghost-aside { width: 50%; height: 12px; margin-top: 4px; }

/* The first fetch: the dashboard's layout with only the tree and the status showing. */
.ghost-status { display: none; }
#app.ghost > :not(.tree-wrap, .ghost-status) { display: none; }
/* About the height of the tabs and controls it stands in for, so the real tree lands where the
   ghost's was. */
#app:is(.ghost, .waiting) .ghost-status { display: block; min-height: 171px; margin: 10px 0 30px; text-align: center; }
/* A range whose months are still on their way (app.js:waiting): the controls stay, the figures go. */
#app.waiting :is(#notices, #filter-bar, .rule, .table-block) { display: none; }
.ghost-msg { margin: 0 0 12px; font-size: 15px; }
/* One row per property, one 10px cell per month; --months is set from script. */
.month-grid {
  display: inline-grid; grid-template-columns: minmax(60px, max-content) repeat(var(--months, 26), 10px);
  gap: 3px; align-items: center; max-width: 100%; overflow-x: auto; text-align: left;
}
.mg-label {
  max-width: 220px; padding-right: 10px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  font-size: 11px; color: var(--ink-2);
}
.mg-year { height: 14px; font-size: 10px; color: var(--ink-3); white-space: nowrap; overflow: visible; }
.mg-cell { display: inline-block; width: 10px; height: 10px; border-radius: 2px; background: var(--line-soft); transition: background-color .25s; }
.mg-cell.cached { background: var(--blue-soft); }
.mg-cell.got { background: var(--blue); }
.mg-legend { margin: 10px 0 0; font-size: 11px; color: var(--ink-3); }
.mg-legend .mg-cell { margin: 0 5px -1px 12px; }
.mg-legend .mg-cell:first-child { margin-left: 0; }

/* A tab whose record is still loading: a sketch of its chart over the status line, laid out as
   the chart is -- centred, the funnel on a centre line -- so the real one lands in its place. */
.ghost-line { text-align: center; max-width: none; }

/* Label | drop-off (grows left from the centre line) | sessions (grows right from it). Each
   side holds a bar and its comparison, sized per row by nth-child below. */
.ghost-funnel {
  display: grid; grid-template-columns: 1fr 1fr 2fr; row-gap: 32px; align-items: center;
  padding: 24px 0 12px;
}
.gf-label { padding-right: 24px; text-align: right; font-size: 12px; color: var(--ink-3); }
.gf-drop, .gf-sessions { display: flex; flex-direction: column; gap: 3px; }
.gf-drop { align-items: flex-end; }
.gf-sessions { align-items: flex-start; border-left: 1px solid var(--line); margin: -16px 0; padding: 16px 0; }
.gf-bar { height: 14px; }
.gf-cmp { height: 4px; opacity: .7; }
.gf-drop .gf-bar { width: var(--drop); }
.gf-drop .gf-cmp { width: var(--drop-cmp); }
.gf-sessions .gf-bar { width: var(--ses); }
.gf-sessions .gf-cmp { width: var(--ses-cmp); }
/* Sessions shrink step by step; the first step, the visits themselves, has no drop-off. */
.gf-r0 { --drop: 0; --drop-cmp: 0; --ses: 75%; --ses-cmp: 63%; }
.gf-r1 { --drop: 30%; --drop-cmp: 31%; --ses: 45%; --ses-cmp: 37%; }
.gf-r2 { --drop: 47%; --drop-cmp: 52%; --ses: 16%; --ses-cmp: 12%; }
.gf-r3 { --drop: 45%; --drop-cmp: 48%; --ses: 6%; --ses-cmp: 5%; }
.gf-r4 { --drop: 57%; --drop-cmp: 50%; --ses: 2%; --ses-cmp: 2%; }

/* The matrix's crosshair, in the chart's own centred 820px: the plot is inset more on the right,
   where the real chart writes its axis labels, and each bubble sits out towards its corner. */
.ghost-matrix {
  display: grid; grid-template-columns: 1fr 1fr; grid-auto-rows: 166px;
  max-width: 820px; margin: 24px auto 0; padding: 0 100px 0 38px;
}
.ghost-q { display: grid; align-items: center; }
.ghost-q:nth-child(odd) { justify-items: start; padding-left: 16px; border-right: 1.5px solid var(--line); }
.ghost-q:nth-child(even) { justify-items: end; padding-right: 40px; }
.ghost-q:nth-child(-n+2) { border-bottom: 1.5px solid var(--line); }
.ghost-bubble { aspect-ratio: 1; max-width: 70%; border-radius: 50%; }
.ghost-q:nth-child(1) .ghost-bubble { width: 78px; margin-left: 30px; }
.ghost-q:nth-child(2) .ghost-bubble { width: 84px; }
.ghost-q:nth-child(3) .ghost-bubble { width: 136px; }
.ghost-q:nth-child(4) .ghost-bubble { width: 60px; margin-right: 12px; }

@media (prefers-reduced-motion: reduce) {
  .ghost-block { animation: none; }
  .tabbar.done, .mg-cell { transition: none; }
}

@media (max-width: 600px) {
  .setup { padding: 4vh 12px 24px; }
  .setup-card { --pad: 20px; padding-top: 22px; }
  .tree.mini { --card-w: 68px; --card-gap: 6px; row-gap: 20px; }
  .tree.mini .card { padding: 6px 6px 0; }
  .tree.mini .card-title { font-size: 10px; }
  .ghost-matrix { padding: 0 8px; }
  /* Only the current step keeps its name; the others are their numbers. */
  .steps li:not([aria-current="step"]) { gap: 0; font-size: 0; }
}
