:root {
  color-scheme: light dark;
  --bg: #ffffff;
  --surface: #f9f9f9;
  --hover: #efefef;
  --border: #e2e2e2;
  --divider: #dfdfdf;
  --border-strong: #e7e7e7;
  --google-frame: #fff; /* Google's own dialog frame round the Sheets add-on's fields editor, in every theme */
  --switch-off: #8a8a8a;
  /* the site page colour (dark only), here on :root so html:has(body.site) can paint the overscroll with it */
  --site-bg: #0f0f0f;
  --text: #181818;
  --muted: #6b6b6b;
  --primary-bg: #181818;
  --primary-text: #ffffff;
  --accent: #181818;
  --focus: #6b6b6b;
  --popover-bg: #ffffff;
  --chip-bg: #deefff;
  --chip-text: #004f99;
  --link: #004f99;
  --danger: #b00020;
  --ok: #1d6b34;
  --warn: #8a5300;
  --scrim: rgba(0, 0, 0, 0.32);
  --shadow: 0 4px 16px rgba(0, 0, 0, 0.08);
  --notice-info-bg: #f1f1f1;
  --notice-info-text: #181818;
  --notice-warn-bg: #fdf1dc;
  --notice-warn-text: #7a4500;
  --notice-error-bg: #fcebee;
  --notice-error-text: #a0001c;
  --notice-ok-bg: #e7f4ea;
  --notice-ok-text: #1a6130;
  /* Continue with Google: Google's own light button colours (sign-in branding) */
  --google-btn-bg: #ffffff;
  --google-btn-border: #747775;
  --google-btn-text: #1f1f1f;
  /* Google's "G" mark, the same in every theme */
  --google-g-blue: #4285f4;
  --google-g-red: #ea4335;
  --google-g-yellow: #fbbc05;
  --google-g-green: #34a853;
  --p-google_ads: #4c8df6;
  --p-ga4: #bb8500;
  --p-search_console: #b0359a;
  --p-meta: #a463f2;
  --p-tiktok: #14a19a;
  --p-chatgpt_ads: #e8615a;
  --p-other: #8a8a8a;
  --space-1: 4px;
  --space-2: 8px;
  --space-3: 12px;
  --space-4: 16px;
  --space-5: 24px;
  --space-6: 32px;
  --radius: 8px;
  --radius-lg: 12px;
  --round: 999px;
  --control-x: var(--space-3);
  /* C6: one control height in the app (buttons, dropdowns, chips, fields, header icon buttons). The block
     padding is worked out from the control's own line height and its 1px border, so a wrapping label grows
     instead of being clipped. Tabs, menu rows and the site's 40px .btn-site keep their own sizes.
     B1 (13 Oct, after the owner's Ads Manager reference): 32px tall, 14px text, 12px sides. */
  --ctl-h: 32px;
  --ctl-font: 14px;
  --ctl-pad-y: calc((var(--ctl-h) - 1lh - 2px) / 2);
}
:root[data-theme="light"] { color-scheme: light; }
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    color-scheme: dark;
    --bg: #212121;
    --surface: #181818;
    --hover: #262626;
    --border: #343434;
    --divider: #1c1c1c;
    --border-strong: #4d4d4d;
    --switch-off: #707070;
    --text: #f3f3f3;
    --muted: #929292;
    --primary-bg: #f3f3f3;
    --primary-text: #181818;
    --accent: #0285ff;
    --focus: #a8a8a8;
    --popover-bg: #181818;
    --chip-bg: #1d2e3e;
    --chip-text: #4ea1ff;
    --link: #8ab4f8;
    --danger: #ff8a9b;
    --ok: #6fd18a;
    --warn: #f0b45a;
    --scrim: rgba(0, 0, 0, 0.6);
    --shadow: 0 4px 16px rgba(0, 0, 0, 0.4);
    --notice-info-bg: #2c2c2c;
    --notice-info-text: #f3f3f3;
    --notice-warn-bg: #3a2d13;
    --notice-warn-text: #f0b45a;
    --notice-error-bg: #3d1d23;
    --notice-error-text: #ff8a9b;
    --notice-ok-bg: #1a3322;
    --notice-ok-text: #6fd18a;
    --google-btn-bg: #131314;
    --google-btn-border: #8e918f;
    --google-btn-text: #e3e3e3;
    --p-google_ads: #4c8df6;
    --p-ga4: #f2a900;
    --p-search_console: #de6bc9;
    --p-meta: #a463f2;
    --p-tiktok: #19b8b0;
    --p-chatgpt_ads: #e8615a;
    --p-other: #8a8a8a;
  }
}
:root[data-theme="dark"] {
  color-scheme: dark;
  --bg: #212121;
  --surface: #181818;
  --hover: #262626;
  --border: #343434;
  --divider: #1c1c1c;
  --border-strong: #4d4d4d;
  --switch-off: #707070;
  --text: #f3f3f3;
  --muted: #929292;
  --primary-bg: #f3f3f3;
  --primary-text: #181818;
  --accent: #0285ff;
  --focus: #a8a8a8;
  --popover-bg: #181818;
  --chip-bg: #1d2e3e;
  --chip-text: #4ea1ff;
  --link: #8ab4f8;
  --danger: #ff8a9b;
  --ok: #6fd18a;
  --warn: #f0b45a;
  --scrim: rgba(0, 0, 0, 0.6);
  --site-shadow: 0 4px 16px rgba(0, 0, 0, 0.4);
  --shadow: var(--site-shadow);
  --notice-info-bg: #2c2c2c;
  --notice-info-text: #f3f3f3;
  --notice-warn-bg: #3a2d13;
  --notice-warn-text: #f0b45a;
  --notice-error-bg: #3d1d23;
  --notice-error-text: #ff8a9b;
  --notice-ok-bg: #1a3322;
  --notice-ok-text: #6fd18a;
  --google-btn-bg: #131314;
  --google-btn-border: #8e918f;
  --google-btn-text: #e3e3e3;
  --p-google_ads: #4c8df6;
  --p-ga4: #f2a900;
  --p-search_console: #de6bc9;
  --p-meta: #a463f2;
  --p-tiktok: #19b8b0;
  --p-chatgpt_ads: #e8615a;
  --p-other: #8a8a8a;
}
* { box-sizing: border-box; }
/* The page's own colour on html too, so a reserved scrollbar gutter (the Sheets sidebar's scrollbar-gutter: stable)
   is painted the theme's background, not the browser's default light. */
html { background: var(--bg); scrollbar-gutter: stable; }
body { margin: 0; font-family: 'Google Sans', system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif; font-size: 16px; line-height: 1.5; background: var(--bg); color: var(--text); }
main { max-width: 960px; margin: 0 auto; padding: 24px 16px 48px; }
main.narrow { max-width: 380px; padding-top: 48px; }
h1 { font-size: 22px; margin: 0 0 8px; }
h2 { font-size: 17px; margin: 32px 0 8px; }
p { margin: 8px 0; }
a, a:visited { color: var(--link); }
.muted { color: var(--muted); }
[hidden] { display: none !important; }
.visually-hidden { position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0; overflow: hidden; clip: rect(0, 0, 0, 0); white-space: nowrap; border: 0; }
.row { display: flex; flex-wrap: wrap; gap: var(--space-2); align-items: center; margin-top: var(--space-4); }
.row > input, .row > select, .row > .select { width: auto; flex: 1 1 160px; }
.row.tight { margin-top: 0; }
/* the last part of a toolbar row, pushed to the right (a date range); on phones a row of its own */
.row > .row-end { margin-left: auto; }
@media (width < 700px) {
  .row > .row-end { flex: 1 1 100%; margin-left: 0; }
  .row-end > .drp, .row-end .drp-trigger { width: 100%; }
}

/* ===== KIT ===== */
/* Every component's look lives here, once (rule 18); each is shown on /kit. Page sections after the
   END KIT marker only lay components out. kit.test.js enforces the boundary. */

/* ---- focus (rule 19): a click or tap never shows a ring; the keyboard gets a neutral --focus ring ---- */
:focus:not(:focus-visible) { outline: none; }
:focus-visible { outline: 2px solid var(--focus); outline-offset: 2px; }

/* ---- names on one row (rule 17): cut with an ellipsis; a cell holding one gives up its width so it can ---- */
.one-line { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; min-width: 0; }
td:has(> .one-line), th:has(> .one-line) { max-width: 0; }

/* ---- buttons: secondary (plain), primary, danger, small, text, icon; a link styled as one ---- */
button { padding: var(--ctl-pad-y) var(--control-x); font: inherit; font-size: var(--ctl-font); color: var(--text); background: var(--bg); border: 1px solid var(--border-strong); border-radius: var(--round); cursor: pointer; }
button:hover:not(:disabled) { background: var(--hover); }
button.primary { background: var(--primary-bg); color: var(--primary-text); border-color: var(--primary-bg); }
button.primary:hover:not(:disabled) { background: var(--primary-bg); opacity: 0.88; }
button.danger { color: var(--danger); border-color: var(--danger); }
button:disabled { opacity: 0.5; cursor: default; }
button[aria-busy="true"] { cursor: progress; }
button.small { padding: var(--ctl-pad-y) 10px; font-size: var(--ctl-font); }
button.text-btn { padding: var(--ctl-pad-y) var(--space-2); color: var(--muted); background: transparent; border-color: transparent; }
.icon-btn { position: relative; display: inline-flex; flex: none; align-items: center; justify-content: center; width: var(--ctl-h); height: var(--ctl-h); padding: 0; color: var(--text); background: transparent; border: 0; border-radius: var(--round); }
.icon-btn:hover:not(:disabled) { background: var(--hover); }
.icon { display: block; flex: none; }
button:not(.icon-btn):has(> .icon) { display: inline-flex; align-items: center; gap: var(--space-2); }
/* the plain text link (login's "No account? Sign up", the Sheets add-on's Account links): the text colour, underlined */
a.text-link, a.text-link:visited { color: var(--text); text-decoration: underline; }
a.button, a.button:visited { display: inline-block; padding: var(--ctl-pad-y) var(--control-x); font-size: var(--ctl-font); color: var(--text); text-decoration: none; background: var(--bg); border: 1px solid var(--border-strong); border-radius: var(--round); }
a.button:hover { background: var(--hover); }
a.button.primary, a.button.primary:visited { color: var(--primary-text); background: var(--primary-bg); border-color: var(--primary-bg); }
a.button.primary:hover { opacity: 0.88; }
/* the public site's buttons, sized like x.ai/bot: a 40px pill, 14px, no border, no shadow; secondary filled grey,
   primary white. Colours are the --site-btn tokens, so they live inside a .site scope (the site pages, the /kit demo) */
.btn.btn-site, .btn.btn-site:visited { display: inline-flex; flex: none; align-items: center; justify-content: center; height: 40px; min-height: 40px; padding: 0 18px; font: inherit; font-size: 14px; font-weight: 500; line-height: 1; white-space: nowrap; text-decoration: none; color: var(--site-btn2-text); background: var(--site-btn2-bg); border: 0; border-radius: 9999px; box-shadow: none; opacity: 1; cursor: pointer; }
.btn.btn-site:hover:not(:disabled) { color: var(--site-btn2-text); background: var(--site-btn2-hover); opacity: 1; }
.btn.btn-site.primary, .btn.btn-site.primary:visited { color: var(--site-btn-text); background: var(--site-btn-bg); }
.btn.btn-site.primary:hover:not(:disabled) { color: var(--site-btn-text); background: var(--site-btn-hover); opacity: 1; }
.btn.btn-site:disabled { opacity: 0.5; cursor: default; }
/* a disabled site button that says why with a "Coming soon" pill: muted text at full opacity so the pill
   reads, the pill one step lighter than the button */
.btn.btn-site:disabled:has(> .pill-soon) { gap: 10px; padding-right: 7px; color: var(--site-muted); opacity: 1; }
/* a long label with a pill may wrap onto two lines on a phone rather than push the page sideways */
.btn.btn-site:has(> .pill-soon) { max-width: 100%; height: auto; padding-top: 7px; padding-bottom: 7px; line-height: 1.3; text-align: left; white-space: normal; }
.btn.btn-site > .pill-soon { height: 26px; background: var(--site-pill-on-btn); }
/* Continue with Google (login, signup, join): Google's sign-in branding overrides rule 19 for this one button,
   so it keeps Google's fill, 1px border and text colours (the --google-btn tokens, dark on the site) and the
   multicolour G at the start; full width on the form, 40px like the other site buttons */
.btn.btn-site.btn-google, .btn.btn-site.btn-google:visited { gap: 10px; width: 100%; padding: 0 12px; color: var(--google-btn-text); background: var(--google-btn-bg); border: 1px solid var(--google-btn-border); }
.btn.btn-site.btn-google:hover:not(:disabled) { color: var(--google-btn-text); background: color-mix(in srgb, var(--google-btn-text) 8%, var(--google-btn-bg)); }
.google-g-blue { fill: var(--google-g-blue); }
.google-g-red { fill: var(--google-g-red); }
.google-g-yellow { fill: var(--google-g-yellow); }
.google-g-green { fill: var(--google-g-green); }
/* the "or" between Continue with Google and the form: one hairline each side of the word */
.divider-or { display: flex; align-items: center; gap: var(--space-3); margin: var(--space-4) 0; font-size: 14px; color: var(--muted); }
.divider-or::before, .divider-or::after { content: ''; flex: 1; height: 1px; background: var(--border); }
/* a few buttons that sit together on one pill (the graph's zoom) */
.btn-group { display: flex; gap: var(--space-1); }
.btn-group button { min-width: var(--ctl-h); padding-right: var(--space-3); padding-left: var(--space-3); }
/* a small count on an icon button (the bell) */
.count { position: absolute; top: -2px; right: -4px; min-width: 16px; height: 16px; padding: 0 4px; font-size: 12px; font-weight: 500; line-height: 16px; text-align: center; color: var(--primary-text); background: var(--primary-bg); border-radius: var(--round); }

/* ---- inputs: one box for text, email, password, search, number, textarea and native selects ---- */
label { display: block; margin: var(--space-3) 0 var(--space-1); font-size: 14px; }
label.inline { display: inline; margin: 0; }
input, select, textarea { width: 100%; padding: var(--ctl-pad-y) var(--space-2); font: inherit; font-size: var(--ctl-font); color: var(--text); background: var(--bg); border: 1px solid var(--border); border-radius: var(--radius); }
textarea { min-height: 96px; resize: vertical; }
/* B1: fields read at the control size; on touch screens 16px, below which iOS zooms the page on focus */
@media (pointer: coarse) {
  input, select, textarea, .search-input { font-size: 16px; }
}
/* the public site (login, sign-up) keeps its 16px fields */
body.site input, body.site select, body.site textarea { font-size: 16px; }
input::placeholder, textarea::placeholder { color: var(--muted); }
/* ticks in the primary colour: black in light, near-white in dark; never blue */
input[type="checkbox"], input[type="radio"] { width: auto; accent-color: var(--primary-bg); }
input:focus-visible, textarea:focus-visible, select:focus-visible { outline: none; border-color: var(--focus); }
input[type="checkbox"]:focus-visible, input[type="radio"]:focus-visible { outline: 2px solid var(--focus); outline-offset: 2px; }
input:disabled, textarea:disabled, select:disabled { opacity: 0.5; cursor: default; }
input[aria-invalid="true"], textarea[aria-invalid="true"] { border-color: var(--danger); }
.field > label { margin-top: 0; }
.field-hint { margin: var(--space-1) 0 0; font-size: 14px; color: var(--muted); }
.field-error { margin: var(--space-1) 0 0; font-size: 14px; color: var(--danger); }
.field-error:empty { display: none; }

/* ---- dropdown (select): the hidden native select stays the source of truth; the button opens a listbox ---- */
.select { position: relative; display: flex; width: 100%; min-width: 0; }
.select-native { position: absolute; bottom: 0; left: 0; width: 100%; height: 1px; padding: 0; opacity: 0; pointer-events: none; }
.select-btn { display: flex; flex: 1 1 auto; align-items: center; gap: var(--space-2); min-width: 0; padding: var(--ctl-pad-y) 10px var(--ctl-pad-y) var(--space-3); text-align: left; background: var(--bg); border: 1px solid var(--border); border-radius: var(--radius); }
.select-value { flex: 1 1 auto; }
.select-btn .icon { color: var(--muted); }
.select-group { padding: 6px 10px 2px; font-size: 13px; color: var(--muted); }
/* a searchable dropdown whose search finds nothing: one muted line where the rows go */
.select-empty { margin: 0; padding: var(--space-2) 10px; font-size: var(--ctl-font); }

/* ---- the one popover panel: no border, the soft shadow on its own surface (--popover-bg: the page in light,
   --surface in dark); menus, dropdown lists, the date picker and the tooltip are this panel ---- */
.popover { position: absolute; top: calc(100% + 6px); right: 0; z-index: 40; width: min(360px, calc(100vw - 32px)); max-height: 70vh; overflow-y: auto; padding: var(--space-3); background: var(--popover-bg); border-radius: var(--radius-lg); box-shadow: var(--shadow); }
.popover-head { display: flex; align-items: center; justify-content: space-between; gap: var(--space-2); }
/* menus and dropdown lists hang fixed under their button, so a table's scrolling box never clips them */
.popover.menu, .popover.select-panel { position: fixed; z-index: 70; width: auto; max-width: calc(100vw - 16px); padding: var(--space-1); }
.popover.select-panel { max-width: min(480px, calc(100vw - 16px)); max-height: min(320px, 60vh); }
/* select({ searchable: true }): the search box stays at the top of the list while the rows scroll under it */
.select-panel > input.select-search { position: sticky; top: calc(-1 * var(--space-1)); z-index: 1; margin-bottom: var(--space-1); }
/* a pop-up under an icon button (iconPopover(): Filter and Columns), fixed like the menus */
.popover.popover-fixed { position: fixed; z-index: 70; }
.popover-anchor { position: relative; flex: none; }
/* the column picker (fieldPicker(), F5) in the wide dialog: the fields on the left, Your columns on the right,
   split by one hairline. Each pane keeps its head (the search box; Your columns, Reset and the sets) still and
   scrolls only its list, with the thin scrollbar. Below 640px the panes stack, nothing inside scrolls on its
   own: the dialog scrolls and its footer stays at the bottom */
.picker { display: grid; grid-template-columns: minmax(0, 3fr) minmax(0, 2fr); gap: var(--space-5); margin-top: var(--space-3); }
.picker-pane { display: flex; flex-direction: column; min-width: 0; }
.picker-scroll { max-height: min(48vh, 440px); overflow-y: auto; scrollbar-width: thin; scrollbar-color: var(--border-strong) transparent; }
.picker-results { margin-top: var(--space-2); }
.picker-chosen { padding-left: var(--space-5); border-left: 1px solid var(--divider); }
.picker-chosen > .select { margin-top: var(--space-2); }
.picker-head { margin: var(--space-3) 0 0; font-size: 14px; font-weight: 500; }
button.picker-fold { display: flex; align-items: center; gap: var(--space-2); width: 100%; margin-top: var(--space-1); padding: var(--ctl-pad-y) 0; font-weight: 500; text-align: left; color: var(--text); background: transparent; border: 0; border-radius: 0; }
button.picker-fold:hover:not(:disabled) { background: transparent; }
button.picker-fold:disabled { opacity: 1; cursor: default; }
button.picker-fold .icon, button.picker-fold svg { flex: none; color: var(--muted); }
.picker-group { padding-left: var(--space-5); }
/* the field lists: a tick box and its name on one row; in Recommended the platform follows in a muted span
   that gives way first, so the name keeps its room */
.picker-list { margin: var(--space-1) 0; padding: 0; list-style: none; }
.picker-list.cols { columns: 200px; column-gap: var(--space-5); }
.picker-list li { display: flex; align-items: center; gap: var(--space-2); min-width: 0; padding: var(--space-1) 0; break-inside: avoid; }
.picker-list li > input { flex: none; margin: 0; }
.picker-list li > label { flex: 0 1 auto; margin: 0; font-size: var(--ctl-font); }
.picker-list li[title] > label { color: var(--muted); }
.picker-platform { flex: 0 100 auto; font-size: 13px; }
/* the footer: the tick box beside its label, then the set's name, then Apply and Cancel */
.picker-save { display: inline-flex; align-items: center; gap: var(--space-2); }
.picker-save input { flex: none; margin: 0; }
.picker-save label { margin: 0; font-size: var(--ctl-font); }
input.picker-set-name { flex: 1 1 12rem; width: auto; min-width: 0; }
.picker-actions { display: flex; gap: var(--space-2); }
.picker-chips { margin-top: var(--space-2); }
/* Your columns: a grip, the name (its platform beside it), then × (a 32px target); Name alone shows the lock;
   a row being dragged dims and a line shows where it lands */
.col-list { margin: var(--space-2) 0 0; padding: 0; list-style: none; }
.col-list li { display: flex; align-items: center; gap: var(--space-1); min-height: var(--ctl-h); font-size: var(--ctl-font); }
.col-list li > .one-line { flex: 1 1 auto; }
.col-list li.locked { color: var(--muted); }
.col-list li.dragging { opacity: 0.5; }
.col-list li.drop-before { box-shadow: inset 0 2px 0 var(--muted); }
.col-list li.drop-after { box-shadow: inset 0 -2px 0 var(--muted); }
.col-list .icon-btn { flex: none; min-width: var(--ctl-h); min-height: var(--ctl-h); }
.col-grip { flex: none; width: var(--ctl-h); color: var(--muted); cursor: grab; touch-action: none; }
.col-platform { flex: 0 1 auto; max-width: 40%; font-size: 13px; }
.col-lock, .col-end { display: inline-flex; flex: none; justify-content: center; width: var(--ctl-h); color: var(--muted); }
@media (width < 640px) {
  .picker { grid-template-columns: minmax(0, 1fr); gap: var(--space-3); }
  .picker-scroll { max-height: none; overflow: visible; }
  /* a long dialog (dialog({ long: true })): its list does not scroll on its own either */
  .dialog-long .account-results { max-height: none; overflow: visible; }
  .picker-chosen { padding: var(--space-3) 0 0; border-top: 1px solid var(--divider); border-left: 0; }
  .dialog-long > .row, .dialog-wide > .row { position: sticky; bottom: calc(-1 * var(--space-5)); z-index: 1; margin-bottom: calc(-1 * var(--space-5)); padding: var(--space-3) 0 var(--space-5); background: var(--bg); border-top: 1px solid var(--divider); }
}

.menu-item, .select-opt { display: block; width: 100%; margin: 0; padding: var(--space-2) 10px; font-size: var(--ctl-font); text-align: left; color: var(--text); background: transparent; border: 0; border-radius: var(--radius); cursor: pointer; }
.menu-item:hover, .select-opt:hover, .menu-item:focus-visible, .select-opt:focus-visible { background: var(--hover); }
.menu-item:focus-visible, .select-opt:focus-visible { outline-offset: -2px; }
.menu-item.danger { color: var(--danger); }
/* menu({ 'separator' }): one hairline between groups of items (before Remove) */
.menu-sep { height: 1px; margin: var(--space-1) 0; background: var(--divider); }
.select-opt[aria-selected="true"] { font-weight: 600; background: var(--hover); }
.select-opt[aria-disabled="true"] { color: var(--muted); cursor: default; background: transparent; }
/* the tooltip bubble (collapsed sidebar labels): fixed to the viewport, the popover's surface and shadow */
.tooltip { position: fixed; z-index: 60; transform: translateY(-50%); padding: var(--space-1) var(--space-2); font-size: 13px; line-height: 1.4; color: var(--text); white-space: nowrap; background: var(--popover-bg); border-radius: var(--radius); box-shadow: var(--shadow); pointer-events: none; }
.tooltip.below { transform: translateX(-50%); }

/* ---- the one pop-up (dialog()): a native <dialog> over the --scrim backdrop ---- */
.dialog { width: min(560px, calc(100vw - 32px)); max-height: calc(100vh - 32px); padding: var(--space-4) var(--space-5) var(--space-5); color: var(--text); background: var(--bg); border: 1px solid var(--border); border-radius: var(--radius-lg); box-shadow: var(--shadow); }
.dialog::backdrop { background: var(--scrim); }
.dialog h2 { margin: 0; }
/* a footer action set apart at the far end (Remove schedule); on a narrow screen it wraps and stays at the end */
.dialog > .row > .dialog-end { margin-inline-start: auto; }
/* wide: true (the column picker's two panes) */
.dialog.dialog-wide { width: min(880px, calc(100vw - 32px)); }
/* the bar (dialog({ bar: true }), the site's cookie bar): the same shell held along the bottom of the window,
   no backdrop, so the top bar stays usable; text, then the buttons, then the ×; stacked on phones */
.dialog.dialog-bar[open] { position: fixed; inset: auto 0 var(--space-4); z-index: 50; display: flex; align-items: center; gap: var(--space-3) var(--space-4); width: min(1152px, calc(100vw - 32px)); max-height: none; margin: 0 auto; padding: var(--space-3) var(--space-3) var(--space-3) var(--space-5); background: var(--surface); }
.dialog-bar > div:first-child { flex: 1 1 auto; min-width: 0; }
.dialog-bar p { margin: 0; }
.dialog-bar > .row { flex: none; margin-top: 0; }
@media (width < 700px) {
  .dialog.dialog-bar[open] { flex-wrap: wrap; padding: var(--space-4); }
  .dialog-bar > div:first-child { padding-right: var(--space-6); }
  /* equal halves (Reject all beside Accept all); with an odd count the first button takes the full row */
  .dialog-bar > .row { display: grid; flex: 1 1 100%; grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .dialog-bar > .row > :first-child:nth-last-child(odd) { grid-column: 1 / -1; }
  .dialog-bar > .dialog-x { position: absolute; top: var(--space-1); right: var(--space-1); }
}

/* ---- the switch (toggle()): a 36 by 20 track, the knob slides right when on; colours from tokens ---- */
/* the button reaches 12px past the track on each side (44 by 44 to tap) without moving the layout */
button.toggle, button.toggle:hover:not(:disabled) { display: inline-flex; flex: none; margin: -12px -4px; padding: 12px 4px; background: transparent; border: 0; border-radius: 9999px; }
.toggle-track { position: relative; display: block; width: 36px; height: 20px; background: var(--switch-off); border-radius: 9999px; transition: background-color 150ms ease-out; }
.toggle-knob { position: absolute; top: 2px; left: 2px; width: 16px; height: 16px; background: var(--text); border-radius: 50%; transition: transform 150ms ease-out; }
/* keyboard focus rings the track, not the 44px hit area around it */
button.toggle:focus-visible { outline: none; }
button.toggle:focus-visible .toggle-track { outline: 2px solid var(--focus); outline-offset: 2px; }
.toggle[aria-checked="true"] .toggle-track { background: var(--primary-bg); }
.toggle[aria-checked="true"] .toggle-knob { background: var(--primary-text); transform: translateX(16px); }
@media (prefers-reduced-motion: reduce) {
  .toggle-track, .toggle-knob { transition: none; }
}

/* ---- the one notice style: a tinted box, small radius, no border; info grey, warn amber, error red, done green ---- */
.notice { margin: 12px 0; padding: 8px 12px; font-size: 15px; color: var(--notice-info-text); background: var(--notice-info-bg); border: 0; border-radius: 8px; }
.notice:empty { display: none; }
/* notice() with several lines: one per line, in the one box */
.notice-line { display: block; }
.notice.warn { color: var(--notice-warn-text); background: var(--notice-warn-bg); }
.notice.error { color: var(--notice-error-text); background: var(--notice-error-bg); }
.notice.ok { color: var(--notice-ok-text); background: var(--notice-ok-bg); }

/* ---- table: the wrapper is the one frame; rows split by a hairline; numbers right in tabular figures ---- */
.table-wrap { overflow-x: auto; margin-top: var(--space-2); border: 1px solid var(--border); border-radius: var(--radius); }
/* a table drawn straight on a site card (rule 20): no frame of its own, its rows run across the card */
.table-wrap.frameless { border: 0; border-radius: 0; }
table { width: 100%; border-collapse: collapse; font-size: 15px; }
.table { table-layout: fixed; }
th, td { text-align: left; padding: var(--space-2) var(--space-3); border-bottom: 1px solid var(--divider); vertical-align: middle; }
tr:last-child td, tbody tr:not([hidden]):not(:has(~ tr:not([hidden]))) td { border-bottom: 0; }
tbody tr:hover td { background: var(--hover); }
th { font-weight: 500; color: var(--muted); background: var(--surface); white-space: nowrap; }
th.num, td.num { text-align: right; white-space: nowrap; font-variant-numeric: tabular-nums; }
tr.total td { font-weight: 600; background: var(--surface); }
tr.total:hover td { background: var(--surface); }
/* totals live in the tfoot: the last body row drops its border, so the tfoot draws the one hairline */
tfoot tr:first-child td { border-top: 1px solid var(--divider); }
tr.clickable { cursor: pointer; }
tr.clickable:focus-visible { outline-offset: -2px; }
tr.empty-row td { color: var(--muted); }
tr.empty-row:hover td { background: transparent; }
td .select { min-width: 120px; }
td input[type="text"] { min-width: 120px; }
td .row { margin-top: 0; }
/* sortable headers (sort.js): the mark hangs in the cell's left padding, so labels line up with the cells */
.sort-btn { display: inline-flex; align-items: center; gap: 2px; vertical-align: top; margin-left: calc(-1 * var(--space-3)); padding: 0; font: inherit; color: inherit; background: none; border: 0; border-radius: 4px; }
.sort-btn:hover:not(:disabled) { color: var(--text); background: none; }
.sort-mark { display: inline-block; width: 10px; font-size: 12px; }
/* moving and resizing columns in the header (table({ adjust }), F11): a grip at the start of a header on hover
   or focus, over the cell's left padding; a 6px edge on its right with the col-resize cursor. Sticky
   headers keep position: sticky (the rules below are more specific) and still hold the two. */
.adjustable th { position: relative; user-select: none; }
.th-grip { position: absolute; top: 50%; left: 0; display: flex; color: var(--muted); background: var(--surface); opacity: 0; transform: translateY(-50%); cursor: grab; touch-action: none; }
.adjustable th:hover .th-grip, .adjustable th:focus-within .th-grip, .adjustable th.col-dragging .th-grip { opacity: 1; }
/* with the grip showing, the label steps right to leave a gap after it; the column keeps its width (fixed layout, widths on the cols) */
.adjustable th:has(> .th-grip):hover, .adjustable th:has(> .th-grip):focus-within, .adjustable th.col-dragging { padding-inline-start: calc(var(--space-3) + var(--space-2)); }
@media (prefers-reduced-motion: no-preference) {
  .adjustable th { transition: padding-inline-start 120ms ease-out; }
}
/* while a double-click fits a column (kit/table.js fitWidth), the heading is measured at its resting padding */
.table.adjustable.col-fitting th:has(> .th-grip) { padding-inline-start: var(--space-3); }
.adjustable.col-fitting th { transition: none; }
.adjustable th.col-dragging { color: var(--text); }
.adjustable th.drop-before { box-shadow: inset 2px 0 0 var(--muted); }
.adjustable th.drop-after { box-shadow: inset -2px 0 0 var(--muted); }
.th-edge { position: absolute; top: 0; right: 0; bottom: 0; width: 6px; cursor: col-resize; touch-action: none; }
.th-edge::after { content: ""; position: absolute; top: 25%; bottom: 25%; left: 2px; width: 2px; border-radius: 1px; }
.th-edge:hover::after, .th-edge.active::after { background: var(--border-strong); }
/* with a grip in the left padding, the sort mark follows the label instead of hanging there, so the two never meet */
.adjustable .sort-btn { margin-left: 0; }
.adjustable .sort-mark { order: 1; }
/* a plain table with no frame or header band (the graph panel's figures) */
.table.plain { margin-top: var(--space-4); font-size: 14px; table-layout: auto; }
.table.plain caption { padding: 0 0 var(--space-1); font-size: 13px; font-weight: 500; text-align: left; }
.table.plain th { padding: 6px 0; font-weight: 400; background: transparent; }
.table.plain td { padding: 6px 0; }
.table.plain tbody tr:hover td { background: transparent; }
.table.plain tr:last-child th { border-bottom: 0; }
/* stickyFirst: the name column stays put while the table scrolls sideways, on its own row's background */
.sticky-first th:first-child, .sticky-first td:first-child { position: sticky; left: 0; z-index: 1; background: var(--bg); }
.sticky-first th:first-child { background: var(--surface); }
.sticky-first tbody tr:hover td:first-child { background: var(--hover); }
.sticky-first tr.total td:first-child, .sticky-first tr.total:hover td:first-child { background: var(--surface); }
.sticky-first tr.empty-row td:first-child, .sticky-first tr.empty-row:hover td:first-child { position: static; background: transparent; }
/* once scrolled sideways, one hairline on the pinned column's right edge */
.table-wrap.scrolled .sticky-first th:first-child::after, .table-wrap.scrolled .sticky-first td:first-child::after { content: ""; position: absolute; top: 0; right: 0; bottom: 0; width: 1px; background: var(--border); }
/* stickyFirst: 2 (the tick boxes, then Name): the second column starts where the first ends, and carries the hairline */
.sticky-second th:nth-child(2), .sticky-second td:nth-child(2) { position: sticky; left: var(--sticky-left, 0); z-index: 1; background: var(--bg); }
.sticky-second th:nth-child(2) { background: var(--surface); }
.sticky-second tbody tr:hover td:nth-child(2) { background: var(--hover); }
.sticky-second tr.total td:nth-child(2), .sticky-second tr.total:hover td:nth-child(2) { background: var(--surface); }
.table-wrap.scrolled .sticky-second th:first-child::after, .table-wrap.scrolled .sticky-second td:first-child::after { content: none; }
.table-wrap.scrolled .sticky-second th:nth-child(2)::after, .table-wrap.scrolled .sticky-second td:nth-child(2)::after { content: ""; position: absolute; top: 0; right: 0; bottom: 0; width: 1px; background: var(--border); }
/* a row's tick box (tickBox()): the label fills the cell, so a near miss ticks instead of opening the row */
.tick-cell { display: flex; align-items: center; margin: calc(-1 * var(--space-2)) calc(-1 * var(--space-3)); padding: var(--space-2) var(--space-3); cursor: pointer; }
.tick-cell input { margin: 0; }

/* ---- chips and pills: the filter chip (checkbox style) and the status pill (a dot and a word) ---- */
.chip-toggle { display: flex; align-items: center; gap: var(--space-2); min-width: 0; max-width: 100%; margin: 0; padding: calc((var(--ctl-h) - 1lh) / 2) 10px; font-size: var(--ctl-font); white-space: nowrap; border-radius: var(--radius); cursor: pointer; }
.chip-toggle:hover { background: var(--hover); }
.chip-toggle input { margin: 0; }
.chip-toggle:has(input:not(:checked)) { color: var(--muted); }
.chip-toggle:has(input:not(:checked)) .swatch { opacity: 0.3; }
.swatch { flex: none; width: 10px; height: 10px; border-radius: var(--round); }
/* the tag chip: a small label (an account's tag), on the --chip tokens */
.chip { display: inline-block; max-width: 12rem; padding: calc(var(--space-1) / 2) var(--space-3); font-size: 14px; line-height: 1.5; vertical-align: middle; color: var(--chip-text); background: var(--chip-bg); border-radius: var(--round); }
/* the selection chip (selectionChip()): "2 selected" and an × that clears it */
.chip.chip-clear { display: inline-flex; align-items: center; gap: var(--space-1); max-width: none; padding-right: var(--space-1); white-space: nowrap; }
button.chip-x { position: relative; display: inline-flex; padding: 0; color: inherit; background: transparent; border: 0; border-radius: var(--round); }
/* the 14px mark gets a 24px target without moving the chip */
button.chip-x::before { content: ""; position: absolute; inset: -5px; }
button.chip-x:hover:not(:disabled) { background: var(--hover); }
.pill { display: inline-flex; align-items: center; gap: 6px; padding: 2px 10px; font-size: 14px; line-height: 1.5; white-space: nowrap; color: var(--notice-info-text); background: var(--notice-info-bg); border-radius: var(--round); }
.pill-dot { flex: none; width: 6px; height: 6px; background: currentColor; border-radius: var(--round); }
.pill.ok { color: var(--notice-ok-text); background: var(--notice-ok-bg); }
.pill.warn { color: var(--notice-warn-text); background: var(--notice-warn-bg); }
.pill.error { color: var(--notice-error-text); background: var(--notice-error-bg); }
/* the site's "Soon" pill: 24px, 12px text, on the --site-pill tokens (a .site scope) */
.pill-soon { display: inline-flex; flex: none; align-items: center; height: 24px; padding: 0 10px; font-size: 12px; font-weight: 500; line-height: 1; white-space: nowrap; color: var(--site-pill-text); background: var(--site-pill-bg); border: 0; border-radius: var(--round); }
/* the meter (meter()): a thin track and its fill, no glow; the fill turns the warning amber from 80%, red from 95% */
.meter { display: block; height: 6px; overflow: hidden; background: var(--border); border-radius: var(--round); }
.meter-fill { display: block; height: 100%; background: var(--primary-bg); border-radius: var(--round); }
.meter.warn .meter-fill { background: var(--notice-warn-text); }
.meter.error .meter-fill { background: var(--notice-error-text); }
/* a status said in words inside a line (a schedule that failed) */
.status-ok { color: var(--ok); }
.status-reconnect { color: var(--warn); }
.status-down { color: var(--danger); }
.status-ok, .status-reconnect, .status-down { white-space: nowrap; }

/* ---- platform list (platformList()): full-width rows that are buttons, one hairline between, no box per row ---- */
.platform-list { list-style: none; margin: var(--space-3) 0 0; padding: 0; }
.platform-list li + li { border-top: 1px solid var(--border); }
/* a grid: logo, the name over its line, then the status; below 480px the status drops under the line */
button.platform-row { display: grid; grid-template-columns: 28px minmax(0, 1fr) auto; grid-template-areas: "logo text status"; align-items: center; column-gap: var(--space-3); width: 100%; padding: var(--space-3) var(--space-2); font-size: var(--ctl-font); text-align: left; background: transparent; border: 0; border-radius: var(--radius); }
button.platform-row:hover:not([aria-disabled="true"]), button.platform-row:focus-visible { background: var(--hover); }
button.platform-row:focus-visible { outline-offset: -2px; }
button.platform-row[aria-disabled="true"]:hover { background: transparent; }
button.platform-row[aria-disabled="true"] { cursor: default; }
/* a Coming soon row dims its name and logo only; the status words keep --muted (4.5:1 on --bg and --hover) */
button.platform-row[aria-disabled="true"] .platform-name { color: var(--muted); }
button.platform-row[aria-disabled="true"] .platform-logo { opacity: 0.5; }
.platform-logo { grid-area: logo; width: 28px; height: 28px; }
.platform-initial { display: inline-flex; align-items: center; justify-content: center; font-weight: 600; color: var(--text); background: var(--border); border-radius: var(--radius); }
.platform-text { grid-area: text; display: flex; flex-direction: column; min-width: 0; }
.platform-name { font-weight: 500; }
.platform-status { grid-area: status; font-size: 13px; color: var(--muted); white-space: nowrap; }
@media (width < 480px) {
  button.platform-row { grid-template-columns: 28px minmax(0, 1fr); grid-template-areas: "logo text" ". status"; }
  .platform-status { justify-self: start; }
}

/* ---- tabs: an underlined row; the chosen tab is bold with a 2px rule; one hairline under the row ---- */
.tabs { display: flex; flex-wrap: wrap; column-gap: var(--space-5); border-bottom: 1px solid var(--border); }
.tab, .tab:visited { flex: none; margin-bottom: -1px; padding: 10px 0; font: inherit; font-size: 15px; color: var(--text); text-decoration: none; white-space: nowrap; background: none; border: 0; border-bottom: 2px solid transparent; border-radius: 0; cursor: pointer; }
.tab:hover:not(:disabled) { background: none; border-bottom-color: var(--border-strong); }
/* the chosen tab keeps its full-contrast rule under the pointer too (a hover never greys it); the wash variant keeps its own look */
.tab[aria-selected="true"], .tabs:not(.tabs-wash) .tab[aria-selected="true"]:hover:not(:disabled) { font-weight: 600; border-bottom-color: var(--text); }
.tab:focus-visible { outline-offset: 0; }
/* a tab with its selection chip beside it (tabs() badge) */
.tab-item { display: inline-flex; flex: none; align-items: center; gap: var(--space-2); }
/* toolButton(): a leading icon and a word; on phones the icon alone, a square of the one control height */
@media (width < 700px) {
  button.tool-btn { justify-content: center; width: var(--ctl-h); padding-right: 0; padding-left: 0; }
  .tool-btn > .tool-btn-text { display: none; }
  /* beside a date range: the icons keep their row and the dates take what is left */
  .row-end:has(> .tool-btn) > .drp { flex: 1 1 0; width: auto; min-width: 0; }
}
/* a chip's short form ("2" for "2 selected") is for phones only */
.chip-short { display: none; }
@media (width < 700px) {
  .tabs:has(.tab-item) { column-gap: var(--space-4); }
  .tab-item { gap: var(--space-1); }
  .chip-clear > .chip-long { display: none; }
  .chip-clear > .chip-short { display: inline; }
}
/* the wash variant (the site's testimonial panel, after cloudflare.com): no hairline and no 2px bar; the
   chosen tab sits on a soft --hover fill, the others muted */
.tabs.tabs-wash { column-gap: var(--space-1); row-gap: var(--space-1); border-bottom: 0; }
.tabs-wash .tab { display: inline-flex; align-items: center; height: 40px; margin: 0; padding: 0 var(--space-4); color: var(--muted); border-bottom: 0; border-radius: var(--round); }
.tabs-wash .tab:hover:not(:disabled) { color: var(--text); background: var(--hover); }
.tabs-wash .tab[aria-selected="true"] { font-weight: 500; color: var(--text); background: var(--hover); border-bottom-color: transparent; }
/* a tab row with a control on its right (a date range): one hairline under both */
.tabs-row { display: flex; align-items: flex-end; gap: var(--space-2) var(--space-4); border-bottom: 1px solid var(--border); }
.tabs-row > .tabs { flex: 1 1 auto; min-width: 0; border-bottom: 0; }
.tabs-end { flex: none; margin-left: auto; padding-bottom: var(--space-1); }
/* phones (the same 700px edge as the page phone block): the control drops under the tabs, full width */
@media (width < 700px) {
  .tabs-row { flex-wrap: wrap; border-bottom: 0; }
  .tabs-row > .tabs { flex: 1 1 100%; border-bottom: 1px solid var(--border); }
  .tabs-end { flex: 1 1 100%; margin-left: 0; padding-bottom: 0; }
  .tabs-end > .drp, .tabs-end .drp-trigger { width: 100%; }
  /* a sticky name column leaves room for the figures beside it (table.js reads --sticky-max) */
  .sticky-first { --sticky-max: 10rem; }
}

/* ---- date range: the trigger, then quick picks beside a two-month calendar in the popover ---- */
.drp { position: relative; display: inline-block; }
.drp-trigger { display: inline-flex; align-items: center; gap: var(--space-2); white-space: nowrap; }
.drp-panel { position: fixed; z-index: 70; width: auto; max-width: calc(100vw - 32px); max-height: calc(100vh - 16px); padding: 0; overflow-y: auto; }
.drp-body { display: flex; }
.drp-presets { display: flex; flex: none; flex-direction: column; gap: 2px; min-width: 148px; padding: var(--space-2); border-right: 1px solid var(--divider); }
.drp-preset { padding: 6px 10px; font-size: var(--ctl-font); text-align: left; white-space: nowrap; background: transparent; border: 0; border-radius: var(--radius); }
.drp-preset[aria-pressed="true"] { font-weight: 600; background: var(--hover); }
.drp-cal { position: relative; padding: var(--space-2) var(--space-4) var(--space-3); }
.drp-nav { position: absolute; top: var(--space-2); right: var(--space-2); left: var(--space-2); display: flex; justify-content: space-between; pointer-events: none; }
.drp-nav button { width: 36px; height: 36px; pointer-events: auto; }
.drp-months { display: flex; gap: var(--space-5); }
.drp-month-title { height: 36px; font-size: 15px; font-weight: 500; line-height: 36px; text-align: center; }
.drp-grid { display: grid; grid-template-columns: repeat(7, 36px); row-gap: 2px; }
.drp-weekday { height: 28px; font-size: 13px; line-height: 28px; text-align: center; text-decoration: none; }
.drp-day { width: 36px; height: 36px; padding: 0; font-size: 14px; font-variant-numeric: tabular-nums; background: transparent; border: 0; border-radius: var(--round); }
.drp-day.today { font-weight: 700; text-decoration: underline; text-underline-offset: 3px; }
.drp-day.in-range, .drp-day.in-range:hover:not(:disabled) { background: var(--hover); border-radius: 0; }
.drp-day.start, .drp-day.end, .drp-day.start:hover:not(:disabled), .drp-day.end:hover:not(:disabled) { color: var(--primary-text); background: var(--primary-bg); }
.drp-day:focus-visible { outline-offset: 0; }
.drp-foot { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: var(--space-2) var(--space-4); padding: var(--space-3) var(--space-4); border-top: 1px solid var(--divider); }
.drp-preview { font-size: 15px; }
.drp-actions { display: flex; gap: var(--space-2); }

/* ---- empty state and page header ---- */
.empty-state { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-2) var(--space-4); margin: var(--space-4) 0; }
.empty-state p { margin: 0; color: var(--muted); }
.page-head { display: flex; flex-wrap: wrap; justify-content: flex-end; gap: var(--space-2); }

/* narrow room (daterange.js pickerLayout): the picker spans the window, quick picks above one month */
.drp-panel.stacked { max-width: none; }
.drp-panel.stacked .drp-body { flex-direction: column; }
.drp-panel.stacked .drp-presets { flex-direction: row; flex-wrap: wrap; min-width: 0; border-right: 0; border-bottom: 1px solid var(--divider); }
.drp-panel.stacked .drp-months { display: block; }
.drp-panel.stacked .drp-grid { grid-template-columns: repeat(7, minmax(0, 1fr)); }
.drp-panel.stacked .drp-day { width: 100%; }

/* ---- the tick list (tickList(), and the lists in the Add pop-ups): a search box over checkbox
   rows that scroll in their own box, so the buttons under them stay in view; a row never wraps, the name
   gives way (rule 17); a group's heading is a small muted line ---- */
.account-results { max-height: min(400px, 50vh); overflow-y: auto; padding-right: var(--space-2); }
.account-results li { flex-wrap: nowrap; }
.account-results li > .muted { flex: none; font-size: 14px; }
.tick-list { margin-top: var(--space-3); }
.tick-group { margin: var(--space-3) 0 0; font-size: 14px; }

/* ---- the top-bar search: a kit input with a leading icon ---- */
.search-field { display: flex; align-items: center; gap: 8px; width: 300px; height: var(--ctl-h); padding: 0 14px; color: var(--muted); background: var(--bg); border: 1px solid var(--border); border-radius: 999px; }
.search-field:focus-within { border-color: var(--focus); }
.search-input { flex: 1 1 auto; min-width: 0; padding: 0; font-size: var(--ctl-font); background: transparent; border: 0; border-radius: 0; }
/* ---- the loader (loader.js): the outline mark, one turn every 2.4 s, linear; the line under it (beside it when small) ---- */
.loader { display: flex; flex-direction: column; align-items: center; gap: var(--space-2); padding: var(--space-5) 0; font-size: 14px; color: var(--muted); text-align: center; }
.loader-mark { flex: none; width: 40px; height: 40px; stroke: var(--text); animation: loader-turn 2.4s linear infinite; }
.loader-sm { display: inline-flex; flex-direction: row; gap: var(--space-2); padding: 0; text-align: left; }
.loader-sm .loader-mark { width: 16px; height: 16px; }
.site .loader { color: var(--site-muted); }
.site .loader-mark { stroke: var(--site-text); }
@keyframes loader-turn { to { transform: rotate(360deg); } }
/* busy(): the waiting button keeps its size; its label steps back and the small mark turns in its place */
.busy { position: relative; pointer-events: none; color: transparent !important; }
.busy > :not(.busy-mark) { visibility: hidden; }
.busy > .busy-mark { position: absolute; inset: 0; width: 16px; height: 16px; margin: auto; stroke: var(--text); }
button.primary.busy > .busy-mark { stroke: var(--primary-text); }
@media (prefers-reduced-motion: reduce) {
  .loader-mark { animation: none; }
}
/* The Sheets add-on's scrollbar: Google rounds the panel, so the bar is a rounded handle on a clear track that
   starts and ends a little in from the corners, as Adveronix's does (owner, 14 Oct: "our scroll bar its not
   rounded"). The standard scrollbar-* properties would switch these off in Chrome, so only browsers without the
   ::-webkit-scrollbar parts get them. */
/* The bar and its track are the page's own white: a clear one shows Google's grey behind the frame, a strip that
   squared the panel's right corners off (owner, 14 Oct: "its still not rounded"). */
html.in-sheets::-webkit-scrollbar, html.in-sheets::-webkit-scrollbar-corner { width: 12px; background: var(--bg); }
html.in-sheets::-webkit-scrollbar-track { margin: var(--space-3) 0; background: var(--bg); }
html.in-sheets::-webkit-scrollbar-thumb { background: var(--border-strong); background-clip: padding-box; border: 3px solid transparent; border-radius: var(--round); }
html.in-sheets::-webkit-scrollbar-thumb:hover { background-color: var(--muted); }
@supports not selector(::-webkit-scrollbar) {
  html.in-sheets { scrollbar-width: thin; scrollbar-color: var(--border-strong) transparent; }
}
/* Sheets text hierarchy (owner, 14 Oct: "everything is thick and big"), read as the Reports tab reads: what
   you chose in plain 14px text, the label or section title above it smaller and muted, nothing bold (owner: "there
   is no bold text" in Reports); tabs not chosen are muted. Pills are small tags; a role is a neutral one (.tag). */
html.in-sheets body { font-size: 14px; }
html.in-sheets label, html.in-sheets .picker-fold { font-size: 13px; font-weight: 400; color: var(--muted); }
html.in-sheets .check > label { font-size: 14px; color: var(--text); }
html.in-sheets h2 { margin: 0 0 var(--space-1); font-size: 13px; font-weight: 400; color: var(--muted); }
html.in-sheets .field-hint { font-size: 13px; }
html.in-sheets .chip { font-size: 13px; }
html.in-sheets .pill { gap: 5px; padding: 0 var(--space-2); font-size: 12px; line-height: 20px; }
html.in-sheets .pill.tag { color: var(--text); background: var(--hover); }
html.in-sheets .tab { font-size: 14px; color: var(--muted); }
html.in-sheets .tab[aria-selected="true"] { color: var(--text); }
/* The fields editor sits in Google's white dialog frame: the page round it is white too. */
html.in-google-frame { background: var(--google-frame); }
/* ===== END KIT ===== */

/* ---- layout helpers ---- */
.row.fields { align-items: flex-start; }
.row.fields > .field { flex: 1 1 160px; }
ul.plain { list-style: none; margin: 8px 0; padding: 0; }
/* rule 17: each choice is the box and one label on one row; a hint under a choice takes the next line */
ul.plain li { display: flex; flex-wrap: wrap; align-items: center; gap: 0 6px; min-width: 0; padding: 4px 0; }
ul.plain li > input { flex: none; margin: 0; }
ul.plain label { flex: 1 1 0; margin: 0; font-size: 15px; }
ul.plain.cols { columns: 200px; column-gap: 24px; }
ul.plain.cols li { break-inside: avoid; }
ul.plain li[title] label { color: var(--muted); }
.invite-url { word-break: break-all; font-family: ui-monospace, Menlo, Consolas, monospace; font-size: 14px; padding: 8px; background: var(--surface); border: 1px solid var(--border); border-radius: 8px; }

/* public pages (home, privacy, terms): no shell, one readable column */
main.doc { max-width: 720px; padding-top: 48px; }
main.doc h2 { scroll-margin-top: 16px; }
main.doc ul { margin: 8px 0; padding-left: 20px; }
main.doc li { margin: 4px 0; }
.site-home, .site-home:visited { display: inline-block; margin-bottom: 24px; font-weight: 500; color: var(--text); text-decoration: none; }
.site-foot { margin-top: 48px; padding-top: 16px; border-top: 1px solid var(--divider); font-size: 14px; color: var(--muted); }
.site-foot a, .site-foot a:visited { color: var(--muted); }
.site-foot a:hover { color: var(--text); }

/* ===== SITE ===== */
/* The public site (home, legal pages, log in, sign up): dark only, in a .site scope apart from the app themes.
   The kit's own tokens take the dark set here, so a kit input or notice on the site reads dark whatever theme
   the visitor picked in the app. This block holds the tokens and lays out the top bar, main, sections, cards
   and footer; the kit paints the buttons and pills. */
/* site tokens */
.site {
  color-scheme: dark;
  /* CV1 (13 Oct): site controls are 40px, like its .btn-site pills (app controls are 32px). The padding is
     declared again so it is worked out from the 40px, not from the 32px it was given on :root. */
  --ctl-h: 40px;
  --ctl-pad-y: calc((var(--ctl-h) - 1lh - 2px) / 2);
  --site-panel: #181818;
  --site-card: #1c1c1c;
  --site-text: #f3f3f3;
  --site-muted: #a3a3a3;
  --site-line: #262626;
  --site-btn-bg: #ffffff;
  --site-btn-text: #0a0a0a;
  --site-btn-hover: #e8e8e8;
  --site-btn2-bg: #2a2a2a;
  --site-btn2-text: #ffffff;
  --site-btn2-hover: #333333;
  --site-pill-bg: #2a2a2a;
  --site-pill-text: #f3f3f3;
  --site-pill-on-btn: #3d3d3d;
  --site-gutter: 24px;
  --site-section: 160px;
  --bg: var(--site-bg);
  --surface: var(--site-panel);
  --hover: #262626;
  --border: #343434;
  --divider: #262626;
  --border-strong: #4d4d4d;
  --switch-off: #707070;
  --text: var(--site-text);
  --muted: var(--site-muted);
  --primary-bg: var(--site-text);
  --primary-text: #181818;
  --accent: var(--site-text);
  --focus: #a8a8a8;
  --popover-bg: var(--site-panel);
  --link: var(--site-text);
  --danger: #ff8a9b;
  --ok: #6fd18a;
  --warn: #f0b45a;
  --scrim: rgba(0, 0, 0, 0.6);
  --shadow: 0 4px 16px rgba(0, 0, 0, 0.4);
  --notice-info-bg: #2c2c2c;
  --notice-info-text: #f3f3f3;
  --notice-warn-bg: #3a2d13;
  --notice-warn-text: #f0b45a;
  --notice-error-bg: #3d1d23;
  --notice-error-text: #ff8a9b;
  --notice-ok-bg: #1a3322;
  --notice-ok-text: #6fd18a;
  --google-btn-bg: #131314;
  --google-btn-border: #8e918f;
  --google-btn-text: #e3e3e3;
  /* the graph's platform colours, the app's dark set (a light-theme visitor sees the same site) */
  --p-google_ads: #4c8df6;
  --p-ga4: #f2a900;
  --p-search_console: #de6bc9;
  --p-meta: #a463f2;
  --p-tiktok: #19b8b0;
  --p-chatgpt_ads: #e8615a;
  --p-other: #8a8a8a;
  /* the app window on the home page: the app's own dark page colour */
  --site-win-bg: #212121;
  /* scene motion: one curve, no bounce */
  --site-ease: cubic-bezier(.2, .7, .2, 1);
}
@media (width < 700px) {
  .site { --site-gutter: 16px; --site-section: 96px; }
}
.site { color: var(--site-text); background: var(--site-bg); }
body.site { display: flex; flex-direction: column; min-height: 100vh; font-size: 16px; line-height: 1.6; }
body.site h1 { margin: 0 0 16px; font-size: 64px; font-weight: 500; line-height: 1.05; letter-spacing: -0.02em; }
body.site h3 { margin: 0; font-size: 20px; font-weight: 500; line-height: 1.3; }
body.site h2 { margin: 48px 0 12px; font-size: 36px; font-weight: 500; line-height: 1.15; letter-spacing: -0.01em; }
body.site .muted { color: var(--site-muted); }
/* one 1320px column (the app's content width) with the side gutter; main is that column, the doc and form pages keep their reading width */
.site-wrap { width: 100%; max-width: 1320px; margin: 0 auto; padding: 0 var(--site-gutter); }
body.site main { flex: 1 0 auto; width: 100%; max-width: 1320px; margin: 0 auto; padding: 48px var(--site-gutter) var(--site-section); }
body.site main.doc { max-width: calc(720px + 2 * var(--site-gutter)); }
body.site main.narrow { max-width: calc(380px + 2 * var(--site-gutter)); }
/* the top bar: logo left, Log in and Start for free right; it stays put while the page scrolls */
.site-top { position: sticky; top: 0; z-index: 30; flex: none; height: 64px; background: var(--site-bg); }
.site-top-row { display: flex; align-items: center; justify-content: space-between; gap: 12px; height: 100%; }
.site-logo, .site-logo:visited { display: inline-flex; flex: none; align-items: center; color: var(--site-text); }
.site-top-actions { display: flex; flex: none; align-items: center; gap: 8px; }
/* sections and cards: 24px radius on --site-card, no border, no shadow */
.site-section { padding-top: var(--site-section); }
.site-section > h2:first-child { margin-top: 0; }
.site-card { padding: 32px; background: var(--site-card); border: 0; border-radius: 24px; box-shadow: none; }
/* the footer, after one hairline: the mark, the name and the company line on the left; the Product and Legal
   columns on the right (a hidden link, such as Testimonials with no quotes, takes no row) */
body.site .site-foot { flex: none; margin-top: 0; padding: 48px 0; font-size: 14px; color: var(--site-muted); border-top: 1px solid var(--site-line); }
.site-foot-row { display: flex; flex-wrap: wrap; justify-content: space-between; gap: 32px 64px; }
body.site .site-foot .site-foot-logo, body.site .site-foot .site-foot-logo:visited { display: inline-flex; align-items: center; gap: 8px; font-size: 17px; font-weight: 500; line-height: 1.2; color: var(--site-text); }
.site-foot-logo .brand-mark { --logo-h: 22px; }
.site-foot-copy { margin: 12px 0 0; }
.site-foot-cols { display: flex; flex-wrap: wrap; gap: 32px 96px; }
body.site .site-foot-head { margin: 0 0 12px; font-size: 14px; font-weight: 500; line-height: 1.5; letter-spacing: 0; color: var(--site-text); }
.site-foot-col ul { display: flex; flex-direction: column; gap: 8px; margin: 0; padding: 0; list-style: none; }
.site-foot-col li:has(> [hidden]) { display: none; }
body.site .site-foot a, body.site .site-foot a:visited { color: var(--site-muted); text-decoration: none; }
body.site .site-foot a:hover, body.site .site-foot .text-btn:hover { color: var(--site-text); }
body.site .site-foot .text-btn { padding: 0; margin: 0; font: inherit; font-size: 14px; line-height: inherit; text-align: left; color: var(--site-muted); }
/* the reading layout: legal pages and sign-in forms, one column at 720px, body 16px/1.6 */
html:has(body.site) { color-scheme: dark; background: var(--site-bg); }
.site-doc { max-width: 720px; font-size: 16px; line-height: 1.6; }
body.site .site-doc h1 { margin: 0 0 8px; }
body.site .site-doc h2 { margin: 40px 0 8px; }
.site-doc p { margin: 8px 0; }
.site-doc ul { margin: 8px 0; padding-left: 20px; }
.site-doc li { margin: 4px 0; }
.site-doc .table-wrap { margin: 12px 0; }
.site-doc th, .site-doc td { vertical-align: top; font-size: 14px; }
/* home: the top (headline, line, buttons) centred over the wide hero window */
.home-top { display: flex; flex-direction: column; align-items: center; gap: 64px; padding-top: 32px; text-align: center; }
.home-intro { max-width: 960px; }
body.site .home-top h1 { margin-bottom: 20px; }
.home-lead { max-width: 620px; margin: 0 auto; font-size: 16px; color: var(--site-muted); }
.home-cta { display: flex; flex-wrap: wrap; justify-content: center; gap: 8px; margin-top: 32px; }
.home-note { margin: 16px 0 0; font-size: 14px; color: var(--site-muted); }
.scene-hero { width: 100%; overflow: hidden; }
/* Learn more and the footer's anchors scroll smoothly (they jump under reduced motion); the sticky 64px top
   bar never covers the section they open. The last section's art runs down to the footer. */
@media (prefers-reduced-motion: no-preference) {
  html:has(body.site) { scroll-behavior: smooth; }
}
.home [id] { scroll-margin-top: 64px; }
body.site main.home { padding-bottom: 0; }
/* works with: start */
/* Works with: the one looping motion on the site, by the owner's request (13 Oct). The list is drawn twice
   (the copy aria-hidden) and the track moves left by one list's width every 40 s, so the loop has no seam.
   An alpha mask (not a coloured fill) fades 120px at each edge into the page. It pauses on hover; under
   reduced motion it stands still as one centred list that wraps. Plain names, no logos. */
.home-works { text-align: center; }
body.site .works-head { margin: 0 0 24px; font-size: 17px; font-weight: 400; line-height: 1.5; letter-spacing: 0; color: var(--site-muted); }
.marquee { overflow: hidden; -webkit-mask-image: linear-gradient(to right, transparent, black 120px, black calc(100% - 120px), transparent); mask-image: linear-gradient(to right, transparent, black 120px, black calc(100% - 120px), transparent); }
.marquee-track { display: flex; width: max-content; animation: works-run 40s linear infinite; }
.marquee:hover .marquee-track { animation-play-state: paused; }
@keyframes works-run {
  to { transform: translateX(-50%); }
}
.works { display: flex; flex: none; gap: 80px; margin: 0; padding: 0 80px 0 0; font-size: 18px; font-weight: 500; line-height: 1.5; color: var(--site-text); list-style: none; }
.works li { white-space: nowrap; }
@media (prefers-reduced-motion: reduce) {
  .marquee { -webkit-mask-image: none; mask-image: none; }
  .marquee-track { width: auto; animation: none; }
  .works { flex: 1 1 auto; flex-wrap: wrap; justify-content: center; gap: 16px 40px; padding: 0; }
  .works[aria-hidden="true"] { display: none; }
}
/* works with: end */
/* features: one row of three cards, one column below 900px. Each card is one --site-card surface (rule 20):
   its text on top, padded; then its scene, edge to edge to the card's sides and bottom, clipped by the 24px
   radius, with no second box inside. */
body.site .home-features > h2 { margin-bottom: 32px; }
.home-cards { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 24px; }
.home-card, .home-sheet { --card-pad: 32px; }
/* subgrid: every card's text block takes the tallest one's height, so the three scenes start on one line */
.home-cards { grid-template-rows: auto auto; }
.home-card { display: grid; grid-row: span 2; grid-template-rows: subgrid; row-gap: 0; min-width: 0; padding: 0; overflow: hidden; }
.home-card-text { padding: var(--card-pad) var(--card-pad) 0; }
body.site .home-card h3 { margin: 0; }
.home-card-text p { margin: 12px 0 0; color: var(--site-muted); }
/* Google Sheets (v3, after linear.app's "Planning and monitoring"): a top row of two columns, the large
   heading on the left and the line with its one button on the right; under it the sheet on one card at the
   full 1320px column. The card's bottom 160px fades into the page through an alpha mask (no coloured fill),
   so the sheet runs on into the testimonials. One column on phones: heading, line, button, sheet. */
.home-sheets-top { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: 24px 48px; align-items: end; margin-bottom: 48px; }
body.site .home-sheets h2 { margin: 0; }
.home-sheets .home-lead { margin: 0; }
.home-sheets .home-cta { justify-content: flex-start; margin-top: 24px; }
.home-sheet { min-width: 0; padding: 0; overflow: hidden; -webkit-mask-image: linear-gradient(to bottom, black calc(100% - 160px), transparent); mask-image: linear-gradient(to bottom, black calc(100% - 160px), transparent); }
/* testimonials (v3, after cloudflare.com): one --site-card panel, nothing boxed inside it (rule 20). On top,
   the quote at
   28px (22px on phones), its words lit one after another by site-quotes.js, then the name line; the
   company's logo or name sits on the right on desktop. */
.quotes { padding: 40px 32px; }
.quote { display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: 48px; align-items: center; margin: 0; }
.quote blockquote { margin: 0; }
.quote-text { margin: 0; font-size: 28px; font-weight: 500; line-height: 1.35; letter-spacing: -0.01em; color: var(--site-text); }
.quote figcaption { margin-top: 24px; font-size: 15px; color: var(--site-muted); }
.quote figcaption strong { font-weight: 500; color: var(--site-text); }
.quote-company { max-width: 240px; font-size: 28px; font-weight: 500; line-height: 1.2; color: var(--site-muted); }
.quote-logo { display: block; width: auto; height: 28px; }
/* the reading highlight: each word muted until lit; with motion on, a short colour fade (gated on the panel
   playing, .is-reading) */
.quote-word { color: var(--site-muted); }
.quote-word.is-lit { color: var(--site-text); }
.quotes.is-reading .quote-word { transition: color 300ms var(--site-ease); }
/* "And many more" and the logo row: only with six entries or more (site-quotes.js); the Works with marquee */
.quote-more { margin-top: 48px; text-align: center; }
body.site .quote-more-head { margin: 0 0 24px; font-size: 17px; color: var(--site-muted); }
.quote-more .works { align-items: center; }
.quote-company .quote-logo { height: 64px; }
/* FAQs (after x.ai/bot): the H2 on the left, the questions on the right; one hairline between rows, no
   boxes. Each row is a <details name="faq"> (one open at a time; site-home.js closes the others where the
   browser does not). Ruling F1: the +/× at the row's right edge is a disclosure marker, not a button icon
   (rule 8); it turns 45° into × when open. The answer fades in over 200 ms; no height animation. */
.home-faq { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 2fr); gap: 32px 48px; align-items: start; }
body.site .home-faq > h2 { margin: 0; }
.faq-item + .faq-item { border-top: 1px solid var(--border); }
.faq-item > summary { display: flex; align-items: center; justify-content: space-between; gap: 24px; padding: 20px 0; font-size: 16px; font-weight: 500; line-height: 1.4; list-style: none; cursor: pointer; }
.faq-item > summary::-webkit-details-marker { display: none; }
.faq-item:first-child > summary { padding-top: 4px; }
.faq-icon { flex: none; color: var(--site-muted); transition: transform 200ms var(--site-ease); }
.faq-item[open] .faq-icon { transform: rotate(45deg); }
.faq-item > p { max-width: 640px; margin: 0; padding: 0 40px 24px 0; color: var(--site-muted); }
.faq-item[open] > p { animation: faq-in 200ms var(--site-ease); }
@keyframes faq-in {
  from { opacity: 0; }
}
@media (prefers-reduced-motion: reduce) {
  .faq-icon { transition: none; }
  .faq-item[open] > p { animation: none; }
}
/* the last call (after linear.app): a big, tight two-line heading, centred, two buttons */
.home-last { text-align: center; }
body.site .home-last h2 { margin: 0; }
/* the pointer art (site-art.js), its own section after the call: the Dataden mark drawn as an outline (the
   petal path of img/mark-outline.svg, inlined), 180px (120px on phones). A 1px line in --site-muted so it
   reads as thin (13 Oct); no will-change, since a layer rastered once and turned by the compositor drew
   the stroke jagged. */
.home-art { display: flex; justify-content: center; padding-bottom: var(--site-section); pointer-events: none; }
.home-art .art-mark { display: block; flex: none; width: 180px; height: 180px; color: var(--site-muted); }
@media (width < 900px) {
  .home-cards, .home-sheets-top, .home-faq { grid-template-columns: minmax(0, 1fr); }
  .quote { grid-template-columns: minmax(0, 1fr); }
  .quote-company { display: none; }
}
@media (width < 700px) {
  body.site h1 { font-size: 40px; }
  body.site h2 { font-size: 28px; }
  body.site h3 { font-size: 18px; }
  .home-top { gap: 40px; padding-top: 8px; }
  .home-card, .home-sheet { --card-pad: 24px; }
  .quotes { padding: 24px 16px; }
  .quote-text { font-size: 22px; }
  .home-art .art-mark { width: 120px; height: 120px; }
}
/* the hero: the one framed app window on the page, with the app's own dark surfaces, sidebar and top bar.
   Its phone layout (.is-phone, from site-scenes.js heroLayout) drops the sidebar and is laid out at 368px,
   scaled down from the top left on narrower screens */
.app-win { --bg: var(--site-win-bg); --surface: var(--site-panel); display: grid; grid-template-columns: 208px minmax(0, 1fr); overflow: hidden; font-size: 15px; line-height: 1.5; text-align: left; color: var(--text); background: var(--bg); border-radius: 16px; transform-origin: 0 0; }
.app-win-side { display: flex; flex-direction: column; gap: 8px; min-width: 0; padding: 8px; background: var(--surface); }
.app-win-brand { display: flex; align-items: center; min-height: 40px; padding-left: 12px; }
.app-win-brand .brand-wordmark { --logo-h: 20px; }
.app-win-nav { display: flex; flex-direction: column; gap: 2px; }
/* the window's nav items sit at the left edge, icon then label, as in the app: the app's collapsed-sidebar
   rule (:root[data-sidebar="collapsed"] .side-link, set by theme.js from the visitor's app choice) centred
   them here (v3) */
body.site .app-win .side-link { justify-content: flex-start; padding: 8px 12px; text-align: left; }
.app-win-main { display: flex; flex-direction: column; min-width: 0; }
.app-win-top { display: flex; flex: none; align-items: center; gap: 8px; height: 56px; padding: 0 16px 0 24px; border-bottom: 1px solid var(--border); }
.app-win-body { position: relative; padding: var(--space-4); }
.app-win.is-phone { grid-template-columns: minmax(0, 1fr); width: max(100%, 368px); border-radius: 12px; }
.app-win.is-phone .app-win-side { display: none; }
.app-win.is-phone .app-win-top { height: 48px; padding: 0 12px 0 16px; }
.app-win.is-phone .app-win-body { padding: var(--space-3) var(--space-2); }
/* the hero's motion: Get data presses, then the rows come in one by one (site-scenes.js adds .is-in) */
.hero-report .table-wrap { margin-top: var(--space-4); }
.hero-row { opacity: 0; transform: translateY(4px); }
.scene.is-playing .hero-row.is-in, .scene.is-done .hero-row { opacity: 1; transform: none; }
.scene.is-playing .hero-row { transition: opacity 300ms var(--site-ease), transform 300ms var(--site-ease); }
.hero-get.is-pressed { opacity: 0.8; transform: scale(0.96); }
.scene.is-playing .hero-get { transition: opacity 150ms var(--site-ease), transform 150ms var(--site-ease); }
/* the feature cards' scenes: straight on the card (rule 20), no window and no shadow, and nothing after
   them on the card (v3: no "Sample data" pill, ruling H2). Laid out at 536px at least, or at 320px in the phone layout (.is-phone), and scaled down
   from the top left by site-scenes.js (layoutFor), which also takes back the height the scale frees. Tables
   use the kit's frameless variant: their rows run across the card. */
.scene-small { display: flex; flex-direction: column; overflow: hidden; }
.scene-body { --shadow: none; position: relative; width: max(100%, 536px); padding: var(--space-3) var(--card-pad, var(--space-5)) var(--card-pad, var(--space-5)); font-size: 15px; line-height: 1.5; text-align: left; transform-origin: 0 0; }
.scene-body.is-phone { width: max(100%, 320px); }
.scene-body > .table-wrap:first-child { margin-top: 0; }
/* a scene is a picture: its table never scrolls (a 1px rounding overflow under the scale showed a scrollbar) */
.scene-body .table-wrap { overflow: hidden; }
.scene-heading { font-weight: 500; }
.scene-toolbar { display: flex; gap: var(--space-2); }
.scene-body .field { margin-top: var(--space-3); }
/* phones: rows stack in one column */
.scene-stack .row { flex-direction: column; align-items: stretch; }
.scene-stack .row > .select { flex: none; width: 100%; }
/* "Get fresh numbers": the kit dropdown (its trigger and its list), a small report and its time line. The
   list pops over the card from the trigger: a popover, not a card (rule 20). It hangs from the trigger here
   rather than fixed to the window as in the app, since the scene is a picture that is scaled and clipped;
   the scene turns --shadow off, so the list takes the site's shadow back. */
.scene-body .field + .table-wrap { margin-top: var(--space-4); }
.select-panel.scene-list { --shadow: var(--site-shadow); position: absolute; top: calc(100% + var(--space-1)); right: 0; left: 0; z-index: 2; opacity: 0; transform: translateY(calc(-1 * var(--space-1))); }
.select-panel.scene-list.is-open { opacity: 1; transform: none; }
.scene-time { margin: var(--space-3) 0 0; font-size: 14px; }
/* a figure that just changed: a soft wash behind it, fading out (opacity only, .scene-wash.is-fresh below) */
.scene-wash { position: relative; isolation: isolate; }
.scene-wash::after { content: ''; position: absolute; inset: calc(-1 * var(--space-1)) calc(-1 * var(--space-2)); z-index: -1; background: var(--border); opacity: 0; }
/* "Your clients on one map": a small labelled tree drawn at its own size (it only shrinks), the lit path
   from the picked dot up to its client, the rest dimmed; the panel under it is plain text on the card */
.scene-canvas { position: relative; }
.map-svg { display: block; max-width: 100%; height: auto; }
.map-link, .map-trace { fill: none; }
.map-link { stroke: var(--border-strong); stroke-width: 1; }
.map-trace { stroke: var(--site-text); stroke-width: 1.5; }
.map-traces { opacity: 0; }
.map-traces.is-on { opacity: 1; }
.map-label { font-size: 13px; fill: var(--site-muted); }
.map-label.is-lit { fill: var(--site-text); }
.map-svg .is-dim { opacity: 0.3; }
.map-ring { fill: none; stroke: var(--site-text); stroke-width: 1.5; opacity: 0; transform: scale(0.5); transform-box: fill-box; transform-origin: center; }
.map-ring.is-on { opacity: 1; transform: none; }
/* the pointer: an arrow drawn as an outline, like the outline mark, filled with the card so the text it
   passes over does not show through it; it presses with a small scale */
.map-pointer path { fill: var(--site-card); stroke: var(--site-text); stroke-width: 1.25; stroke-linejoin: round; }
.map-pointer-press { transform-box: fill-box; transform-origin: 0 0; }
.map-pointer.is-pressed .map-pointer-press { transform: scale(0.85); }
.map-panel { margin-top: var(--space-2); }
.map-parents { font-size: 14px; }
.map-name, .map-parents, .map-panel .scene-figures { opacity: 0; }
.map-name.is-on, .map-parents.is-on, .map-panel .scene-figures.is-on { opacity: 1; }
.scene-figures { padding: var(--space-3) 0 0; }
.scene-figure-row { display: flex; gap: var(--space-4); margin-top: var(--space-1); }
.scene-figure { display: flex; flex-direction: column; min-width: 0; font-size: 14px; }
.scene-figure-value { font-weight: 500; white-space: nowrap; font-variant-numeric: tabular-nums; }
/* the sheet: the row numbers and the header row read as the sheet's own */
.sheet .sheet-n { color: var(--muted); }
.sheet .sheet-head { font-weight: 500; }
/* the steps: .swap crossfades the date range in one spot, the sheet's rows fade in 80 ms apart */
.swap { display: inline-grid; justify-items: start; min-width: 0; max-width: 100%; }
.swap > * { grid-area: 1 / 1; max-width: 100%; overflow: hidden; white-space: nowrap; text-overflow: ellipsis; }
.swap-now { opacity: 0; }
.sheet-row { opacity: 0; }
.scene.is-playing .swap-was, .scene.is-done .swap-was { opacity: 0; }
.scene.is-playing .swap-now, .scene.is-done .swap-now, .scene.is-playing .sheet-row, .scene.is-done .sheet-row { opacity: 1; transform: none; }
.scene.is-playing .swap > *, .scene.is-playing .sheet-row { transition: opacity 300ms var(--site-ease) var(--delay, 0ms), transform 300ms var(--site-ease) var(--delay, 0ms); }
.scene.is-playing .flip-row { transition: transform 500ms var(--site-ease); }
.scene.is-playing .scene-list, .scene.is-playing .map-traces, .scene.is-playing .map-ring, .scene.is-playing .map-dot, .scene.is-playing .map-link, .scene.is-playing .map-label, .scene.is-playing .map-name, .scene.is-playing .map-parents, .scene.is-playing .scene-figures { transition: opacity 300ms var(--site-ease), transform 300ms var(--site-ease); }
.scene.is-playing .map-pointer { transition: transform 800ms var(--site-ease); }
.scene.is-playing .map-pointer-press { transition: transform 120ms var(--site-ease); }
.scene.is-playing .scene-wash.is-fresh::after { animation: scene-wash 800ms var(--site-ease); }
.scene.is-playing .scene-new { animation: scene-new 300ms var(--site-ease); }
@keyframes scene-wash {
  from { opacity: 1; }
  to { opacity: 0; }
}
@keyframes scene-new {
  from { opacity: 0; }
}
/* the sheet's eight rows, 80 ms apart (row 1 is the header row) */
.sheet-row:nth-child(3) { --delay: 80ms; }
.sheet-row:nth-child(4) { --delay: 160ms; }
.sheet-row:nth-child(5) { --delay: 240ms; }
.sheet-row:nth-child(6) { --delay: 320ms; }
.sheet-row:nth-child(7) { --delay: 400ms; }
.sheet-row:nth-child(8) { --delay: 480ms; }
.sheet-row:nth-child(9) { --delay: 560ms; }
/* between two loops (site-motion.js, ruling H1): the content fades out over 300 ms, the scene is redrawn at
   its start, then it fades back in as the next cycle plays */
.scene.is-leaving > * { opacity: 0; transition: opacity 300ms var(--site-ease); }
.scene.is-playing > * { transition: opacity 300ms var(--site-ease); }
@media (prefers-reduced-motion: reduce) {
  .scene *, .scene > *, .quote-word { transition: none !important; animation: none !important; }
}
/* cookie consent (site-consent.js): the bar's line at the site's small size, the pop-up's title at the app's
   size (not the site's headline), and one row per category: name and line on the left, the switch right */
body.site > .dialog { font-size: 15px; line-height: 1.5; }
body.site > .dialog h2 { margin: 0; font-size: 20px; line-height: 1.3; letter-spacing: 0; }
.consent-links { display: inline-flex; gap: var(--space-3); white-space: nowrap; }
body.site > .dialog a, body.site > .dialog a:visited { color: var(--site-text); }
.consent-row { display: flex; align-items: center; justify-content: space-between; gap: var(--space-4); padding: var(--space-3) 0; border-bottom: 1px solid var(--divider); }
.consent-row:first-child { margin-top: var(--space-3); }
.consent-row p { margin: 0; }
.consent-name { font-weight: 500; }
.consent-line, .consent-on { font-size: 14px; color: var(--site-muted); }
.consent-on { flex: none; white-space: nowrap; }
/* the pop-up's actions: Reject all and Accept all on the left, Save preferences on the right */
body.site > .dialog:not(.dialog-bar) > .row > :last-child:nth-child(3) { margin-left: auto; }
@media (width < 700px) {
  /* Reject all and Accept all as equal halves, Save preferences on the full row under them */
  body.site > .dialog:not(.dialog-bar) > .row { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); }
  body.site > .dialog:not(.dialog-bar) > .row > :last-child:nth-child(odd) { grid-column: 1 / -1; margin-left: 0; }
}
/* ---- docs ---- */
/* The top bar is the logo and the two buttons only; Docs is linked from the footer (owner, 14 Oct). */
/* /docs (lib/docs.js, docs.js): the menu (240px) on the left, the page (up to 720px), and from 1100px the On
   this page list (200px) on the right; below 768px one column, the menu folded under the Menu button. The
   site's one type scale; no boxes: the menu, the list and Previous/Next are plain rows. The current menu
   item copies the app sidebar's current item (.side-link[aria-current]). */
body.site main.docs { display: grid; grid-template-columns: 240px minmax(0, 720px); gap: var(--space-6) 48px; align-items: start; padding-top: var(--space-6); }
.docs-nav, .docs-toc { position: sticky; top: calc(64px + var(--space-5)); max-height: calc(100vh - 64px - 2 * var(--space-5)); overflow-y: auto; scrollbar-width: thin; scrollbar-color: var(--border) transparent; }
.docs-toc { display: none; }
.docs-search { margin-bottom: var(--space-5); }
.docs-results { display: flex; flex-direction: column; gap: 2px; margin: var(--space-2) 0 0; padding: 0; list-style: none; }
.docs-results[hidden] { display: none; }
.docs-result, .docs-result:visited { display: flex; flex-direction: column; min-width: 0; padding: var(--space-2) var(--space-3); font-size: 15px; line-height: 1.4; color: var(--site-text); text-decoration: none; border-radius: var(--radius); }
.docs-result:hover { background: var(--hover); }
.docs-result-title { font-weight: 500; }
.docs-result-line, .docs-result-none { font-size: 14px; color: var(--site-muted); }
.docs-result-none { padding: var(--space-2) var(--space-3); }
.btn.btn-site.docs-menu-btn { display: none; }
body.site .docs-menu-head { margin: var(--space-5) 0 var(--space-2); padding-left: var(--space-3); font-size: 14px; font-weight: 500; line-height: 1.5; color: var(--site-muted); }
.docs-menu > .docs-menu-head:first-child, .docs-toc > .docs-menu-head:first-child { margin-top: 0; }
body.site .docs-toc > .docs-menu-head { padding-left: 0; }
.docs-list { display: flex; flex-direction: column; gap: 2px; margin: 0; padding: 0; list-style: none; }
.docs-link, .docs-link:visited { display: block; padding: var(--space-1) var(--space-3); font-size: 15px; line-height: 1.5; color: var(--site-muted); text-decoration: none; border-radius: var(--radius); }
.docs-link:hover { color: var(--site-text); }
.docs-link[aria-current="page"] { font-weight: 500; color: var(--site-text); background: var(--hover); }
.docs-toc-link, .docs-toc-link:visited { display: block; padding: var(--space-1) 0; font-size: 14px; line-height: 1.5; color: var(--site-muted); text-decoration: none; }
.docs-toc-link:hover, .docs-toc-link[aria-current] { color: var(--site-text); }
.docs-page { min-width: 0; }
body.site .docs-page h2 { scroll-margin-top: calc(64px + var(--space-4)); }
/* Docs read at a reference page's scale, not the home page's (owner, 14 Oct: "they're too big"): a 36px title,
   22px sections, 16px text. */
body.site .docs-page h1 { margin: 0 0 var(--space-3); font-size: 36px; line-height: 1.15; }
body.site .docs-page h2 { margin: 40px 0 var(--space-2); font-size: 22px; line-height: 1.3; letter-spacing: 0; }
body.site .docs-page h3 { margin: var(--space-5) 0 var(--space-2); font-size: 17px; }
body.site .docs-page p, body.site .docs-page li { font-size: 16px; line-height: 1.65; }
/* A screenshot of the 300px add-on at its own size (sample data only), never stretched. */
.docs-page img { display: block; width: 300px; max-width: 100%; height: auto; margin: var(--space-4) 0; border: 1px solid var(--site-line); border-radius: var(--radius); }
@media (width < 768px) {
  body.site .docs-page h1 { font-size: 28px; }
  body.site .docs-page h2 { font-size: 20px; }
}
.docs-page p { margin: var(--space-2) 0; }
.docs-page ul, .docs-page ol { margin: var(--space-2) 0; padding-left: 20px; }
.docs-page li { margin: var(--space-1) 0; }
.docs-prevnext { display: flex; justify-content: space-between; gap: var(--space-4); margin-top: 64px; padding-top: var(--space-5); border-top: 1px solid var(--site-line); }
.docs-step, .docs-step:visited { display: flex; flex-direction: column; min-width: 0; max-width: 50%; color: var(--site-text); text-decoration: none; }
.docs-next { margin-left: auto; align-items: flex-end; text-align: right; }
.docs-step-word { font-size: 14px; color: var(--site-muted); }
.docs-step-title { max-width: 100%; font-weight: 500; }
.docs-step:hover .docs-step-title { text-decoration: underline; }
@media (width >= 1100px) {
  body.site main.docs { grid-template-columns: 240px minmax(0, 720px) 200px; }
  .docs-toc { display: block; }
}
@media (width < 768px) {
  body.site main.docs { grid-template-columns: minmax(0, 1fr); gap: var(--space-5); padding-top: var(--space-4); }
  .docs-nav { position: static; display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: var(--space-2); max-height: none; overflow: visible; }
  .docs-search { margin-bottom: 0; }
  .btn.btn-site.docs-menu-btn { display: inline-flex; }
  .docs-menu { grid-column: 1 / -1; padding-top: var(--space-3); }
  .docs-nav:not([data-open]) .docs-menu { display: none; }
  /* finger-sized rows on phones */
  .docs-link, .docs-link:visited, .docs-result, .docs-result:visited { padding-top: var(--space-2); padding-bottom: var(--space-2); }
}
/* ===== END SITE ===== */

/* app shell: the sidebar sits on --surface; the top bar and the content on --bg */
body.shell { display: grid; grid-template-columns: 240px minmax(0, 1fr); grid-template-rows: 56px auto; min-height: 100vh; }
:root[data-sidebar="collapsed"] body.shell { grid-template-columns: 64px minmax(0, 1fr); }
main.content { grid-column: 2; grid-row: 2; width: 100%; max-width: 1320px; margin: 0 auto; padding: 24px 32px 48px; }

.sidebar { grid-column: 1; grid-row: 1 / span 2; align-self: start; position: sticky; top: 0; z-index: 30; display: flex; flex-direction: column; gap: 8px; height: 100vh; padding: 8px; overflow-x: hidden; overflow-y: auto; background: var(--surface); border-right: 1px solid var(--border); }
.sidebar-head { display: flex; align-items: center; justify-content: space-between; gap: 8px; min-height: 40px; padding-left: 12px; }
.sidebar .brand, .sidebar .brand:visited { overflow: hidden; font-weight: 600; color: var(--text); text-decoration: none; white-space: nowrap; text-overflow: ellipsis; }
/* The logos are black shapes on transparent PNGs; the mask lets the text token colour them in every theme. */
.brand-mark, .brand-wordmark { display: inline-block; flex: none; height: var(--logo-h, 24px); background-color: var(--text); -webkit-mask-repeat: no-repeat; mask-repeat: no-repeat; -webkit-mask-position: left center; mask-position: left center; -webkit-mask-size: contain; mask-size: contain; }
.brand-mark { -webkit-mask-position: center; mask-position: center; width: calc(var(--logo-h, 24px) * 384 / 414); -webkit-mask-image: url(/img/mark.png); mask-image: url(/img/mark.png); }
.brand-wordmark { width: calc(var(--logo-h, 24px) * 418 / 112); -webkit-mask-image: url(/img/wordmark.png); mask-image: url(/img/wordmark.png); }
.brand-lg { --logo-h: 32px; }
.sidebar .brand { display: flex; align-items: center; }
.sidebar nav { display: flex; flex: 1 1 auto; flex-direction: column; gap: 2px; }
.side-link, .side-link:visited { display: flex; align-items: center; gap: 12px; padding: 8px 12px; font-size: 15px; color: var(--text); text-decoration: none; white-space: nowrap; border-radius: 8px; }
.side-link:hover { background: var(--hover); }
.side-link[aria-current="page"] { font-weight: 500; background: var(--hover); }
.sidebar-foot { padding: 12px 12px 4px; border-top: 1px solid var(--border); }
.workspace-label { display: block; margin: 0 0 4px; font-size: 13px; color: var(--muted); }
.workspace-name { overflow: hidden; font-size: 15px; white-space: nowrap; text-overflow: ellipsis; }
/* collapsed, the top slot is one button: the mark at rest, the panel icon on hover or keyboard focus */
.open-btn { display: none; }
.open-btn .icon { display: none; }
.open-btn:hover .brand-mark, .open-btn:focus-visible .brand-mark { display: none; }
.open-btn:hover .icon, .open-btn:focus-visible .icon { display: block; }
@media (min-width: 700px) {
  :root[data-sidebar="collapsed"] .sidebar .brand,
  :root[data-sidebar="collapsed"] .collapse-btn,
  :root[data-sidebar="collapsed"] .sidebar .label,
  :root[data-sidebar="collapsed"] .sidebar-foot { display: none; }
  :root[data-sidebar="collapsed"] .sidebar-head { justify-content: center; padding-left: 0; }
  :root[data-sidebar="collapsed"] .open-btn { display: inline-flex; }
  :root[data-sidebar="collapsed"] .side-link { justify-content: center; padding: 10px; }
}

.topbar { grid-column: 2; grid-row: 1; position: sticky; top: 0; z-index: 20; display: flex; align-items: center; gap: 8px; height: 56px; padding: 0 16px 0 32px; background: var(--bg); border-bottom: 1px solid var(--border); }
.topbar-title { flex: 1 1 auto; min-width: 0; overflow: hidden; font-size: 18px; font-weight: 500; white-space: nowrap; text-overflow: ellipsis; }
.topbar-actions { display: flex; align-items: center; gap: 4px; }
.menu-btn { display: none; }
.backdrop { display: none; }

.bell, .profile, .search { position: relative; }
.bell-panel li.unread a { font-weight: 600; }

.search-toggle, .search-cancel { display: none; }
.search-results { padding: 6px; }
.search-group + .search-group { margin-top: 4px; padding-top: 4px; border-top: 1px solid var(--divider); }
.search-group-label { padding: 6px 10px 2px; font-size: 12px; color: var(--muted); }
.search-item, .search-item:visited { display: block; padding: 6px 10px; color: var(--text); text-decoration: none; border-radius: 8px; }
.search-item.active { background: var(--hover); }
.search-label, .search-sub { display: block; overflow: hidden; white-space: nowrap; text-overflow: ellipsis; }
.search-label { font-size: 15px; }
.search-sub { font-size: 13px; color: var(--muted); }
.search-empty { margin: 0; padding: 8px 10px; font-size: 15px; }

.avatar { display: inline-flex; align-items: center; justify-content: center; width: 32px; height: 32px; font-size: 13px; font-weight: 500; color: var(--text); background: var(--hover); border-radius: 999px; }
.profile-btn:hover:not(:disabled) .avatar { background: var(--border); }
.profile-menu { width: min(280px, calc(100vw - 32px)); padding: 8px; }
.profile-who { margin-bottom: 4px; padding: 8px; border-bottom: 1px solid var(--divider); }
.profile-name { font-weight: 500; }
.profile-email { font-size: 14px; color: var(--muted); }
.profile-row { display: flex; align-items: center; gap: 8px; padding: 4px 8px; }
.profile-theme { display: flex; flex: 1 1 auto; align-items: center; gap: 8px; margin: 0; font-size: 15px; }
.profile-row .select { width: auto; flex: 0 1 auto; max-width: 60%; }
.profile-menu .menu-item { margin-top: 4px; }
a.menu-item, a.menu-item:visited { color: var(--text); text-decoration: none; }

/* Clients: one plain section per client, its name and ⋯ menu on one line above its accounts table */
.section-head { display: flex; align-items: center; justify-content: space-between; gap: 8px; margin-top: 24px; }
.section-head h2 { margin: 0; }
/* Add account and the ⋯ menu stay side by side; the client name gives way */
.section-head > .row { flex: none; flex-wrap: nowrap; }
.client-section { scroll-margin-top: 72px; }
/* every client's table has the same set columns, so they line up from section to section */
.accounts-table { table-layout: fixed; }
.accounts-table .col-status { width: 10rem; }
.accounts-table .col-actions { width: 5rem; }
.accounts-table td:last-child .row { justify-content: flex-end; }
.accounts-table th:last-child { text-align: right; }
.accounts-table td .muted { font-size: 14px; }
/* an account's second line: its tag chip, then what it shows, its time zone and currency, on one row */
.accounts-table .account-sub { flex-wrap: nowrap; }
/* when the row is narrow, the tag gives way first, so "12 of 40" stays readable */
.accounts-table .account-sub > .chip { flex-shrink: 10; min-width: 2.5rem; }
.client-section.open { margin: 16px -12px 0; padding: 0 12px 12px; background: var(--surface); border-radius: 12px; }
.client-section.open .section-head { margin-top: 8px; }

/* the sample banner: one tinted line; its two links read as text inside it */
/* one line at every width: the Back to name gives way (ellipsis), Delete sample always shows */
.sample-banner { display: flex; flex-wrap: nowrap; align-items: center; gap: 4px 8px; }
.sample-banner .sample-links { display: flex; flex: 0 1 auto; align-items: center; gap: 4px; min-width: 0; white-space: nowrap; }
.sample-links > .one-line { flex: 0 1 auto; min-width: 0; }
.sample-banner > button { flex: none; }
.sample-error:empty { display: none; }
.sample-banner:has(.sample-error:not(:empty)) { flex-wrap: wrap; }

/* Get started: a plain list; a done step shows a check and its button goes */
.get-started { flex: none; padding-bottom: 12px; border-bottom: 1px solid var(--border); }
/* beside a graph it keeps to the top part and scrolls; with no graph yet it shows every step */
#overview:has(> #graph-stage:not([hidden])) > .get-started { max-height: 45%; overflow-y: auto; }
.get-started-head { display: flex; align-items: center; justify-content: space-between; gap: 8px; }
.get-started-head h2 { margin: 0; }
.steps { list-style: none; margin: 8px 0 0; padding: 0; }
.step { display: flex; flex-wrap: wrap; align-items: center; gap: 4px 12px; padding: 6px 0; }
.step-mark { flex: none; display: inline-flex; align-items: center; justify-content: center; width: 20px; height: 20px; border: 1.5px solid var(--border-strong); border-radius: 999px; }
.step.done .step-mark { color: var(--ok); border-color: var(--ok); }
.step.done .step-text { color: var(--muted); }
.step-text { flex: 1 1 200px; }

/* Overview graph: one toolbar row, then the canvas fills the rest of the page edge to edge; the panel sits on its right */
#overview { display: flex; flex-direction: column; max-width: none; height: calc(100vh - 56px); height: calc(100dvh - 56px); min-height: 0; overflow: hidden; padding: 0; }
.graph-toolbar { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; padding: 12px 24px; border-bottom: 1px solid var(--border); }
.graph-toolbar > input, .graph-toolbar > .select { width: auto; min-width: 0; }
.graph-search { flex: 1 1 160px; min-width: 120px; max-width: 280px; }
.graph-toolbar > .select { flex: 0 1 auto; min-width: 9rem; max-width: 240px; }
.graph-toolbar > .drp { flex: none; }
.platforms-wrap { position: relative; flex: none; }
.platforms-popover { right: 0; left: auto; display: flex; flex-direction: column; gap: 4px; width: auto; min-width: 220px; padding: 8px; }
#overview > .notice, #overview > .get-started { margin: 12px 24px; }
#overview > #graph-empty > .empty-state { margin: 12px 24px; }
.graph-stage { position: relative; flex: 1 1 0; min-height: 0; overflow: hidden; }
#graph { display: block; width: 100%; height: 100%; cursor: grab; touch-action: none; }
.graph-zoom { position: absolute; right: 16px; bottom: 16px; z-index: 2; }
.graph-stage:has(> .graph-panel:not([hidden])) .graph-zoom { right: 356px; }
.graph-panel { position: absolute; top: 0; right: 0; bottom: 0; z-index: 3; width: 340px; max-width: 100%; overflow-y: auto; padding: 16px; background: var(--bg); border-left: 1px solid var(--border); }
.panel-head { display: flex; align-items: center; justify-content: space-between; gap: 8px; }
.panel-type { font-size: 13px; color: var(--muted); }
.graph-panel h2 { margin: 4px 0 0; overflow-wrap: anywhere; }
.panel-parents { margin: 2px 0 0; font-size: 14px; }
.panel-count { margin: 8px 0 0; font-size: 14px; }

/* the UI kit page: sections in one column, each component's states side by side */
.kit-section { margin-top: var(--space-6); }
.kit-section > h2 { margin: 0 0 var(--space-3); font-size: 15px; font-weight: 500; }
.kit-row { display: flex; flex-wrap: wrap; align-items: flex-start; gap: var(--space-3); margin-top: var(--space-3); }
.kit-row > .field, .kit-row > .select { flex: 0 1 240px; width: 240px; }
.kit-col { display: flex; flex-direction: column; gap: var(--space-2); }
.kit-site { margin-top: var(--space-3); padding: var(--space-1) var(--space-4) var(--space-4); border-radius: var(--radius-lg); }
.kit-narrow { max-width: 380px; margin-top: var(--space-3); }
.kit-site.kit-narrow { padding-top: var(--space-4); }
.kit-row > .pill-soon { align-self: center; }

/* phones: the sidebar is a drawer behind Menu, the search opens full width, and every button and nav item is at least 40px tall */
@media (max-width: 699px) {
  body.shell, :root[data-sidebar="collapsed"] body.shell { grid-template-columns: minmax(0, 1fr); }
  .topbar, main.content { grid-column: 1; }
  .topbar { gap: 4px; padding: 0 8px; }
  .topbar-title { font-size: 17px; }
  main.content { padding: 16px 16px 48px; }
  .menu-btn { display: inline-flex; }
  .sidebar { position: fixed; top: 0; bottom: 0; left: 0; z-index: 50; width: min(280px, 85vw); height: 100%; align-self: stretch; visibility: hidden; transform: translateX(-100%); transition: transform 0.2s ease, visibility 0.2s; }
  .drawer-open .sidebar { visibility: visible; transform: none; }
  .drawer-open .backdrop { display: block; position: fixed; inset: 0; z-index: 45; background: var(--scrim); }
  .collapse-btn { display: none; }
  .search { position: static; }
  .search-field { display: none; }
  .search-toggle { display: inline-flex; }
  .topbar.search-open .search { position: absolute; inset: 0; z-index: 25; display: flex; align-items: center; gap: 8px; padding: 0 8px 0 16px; background: var(--bg); }
  .topbar.search-open .search-field { display: flex; flex: 1 1 auto; width: auto; }
  .topbar.search-open .search-cancel { display: inline-block; }
  .search-results { left: 8px; right: 8px; width: auto; }
  /* the nav links stay 40px to tap; buttons and dropdowns keep the one --ctl-h (C6) */
  .sidebar a { min-height: 40px; }
  /* the accounts table fits the phone: a narrower status column, tighter cells, a long status may wrap */
  .accounts-table .col-status { width: 7rem; }
  .accounts-table .col-actions { width: 4.5rem; }
  .accounts-table th, .accounts-table td { padding: 8px; }
  .accounts-table .pill { white-space: normal; }
  /* the tag chip takes its own row above the muted line, so neither is cut to a few letters */
  .accounts-table .account-sub { flex-wrap: wrap; row-gap: var(--space-1); }
  .graph-toolbar { flex-wrap: wrap; padding: 8px 16px; }
  .graph-search { flex: 1 1 60%; max-width: none; }
  .platforms-wrap { order: 1; }
  .graph-toolbar > .select { order: 2; flex: 1 1 0; min-width: 7.5rem; max-width: none; }
  /* the dates keep their full width; the client dropdown beside them gives way */
  .graph-toolbar > .drp { order: 2; flex: none; }
  #overview > .notice, #overview > .get-started, #overview > #graph-empty > .empty-state { margin: 12px 16px; }
  .graph-stage:has(> .graph-panel:not([hidden])) .graph-zoom { right: 16px; }
  .graph-panel { position: fixed; top: auto; right: 0; bottom: 0; left: 0; z-index: 35; width: auto; max-height: 60vh; border-top: 1px solid var(--border); border-left: 0; border-radius: 16px 16px 0 0; box-shadow: var(--shadow); }
}

/* after the phone block, so it wins over the drawer transition */
@media (prefers-reduced-motion: reduce) {
  .sidebar { transition: none; }
}
