/* ============================================================
   Quarry — App styles (Envoy light treatment)

   Carried over from Vidara (built from the "Vidara App Screens"
   design bundle).
   Design tokens live in /styles/tokens.css and define the
   --envoy-red, --carbon-*, --gem-*, --fg-*, --bg-* CSS vars
   used throughout this file.

   This file replaces the previous OmniSlides dark theme entirely.
   Legacy class names from the existing markup are kept as aliases
   in the "Legacy aliases" section near the bottom so the existing
   /pages/index.js + /public/app.js wiring continues to work.
   ============================================================ */

*, *::before, *::after { box-sizing: border-box; }
html, body { margin: 0; padding: 0; height: 100%; }

/* Fluid layout sizes. Page widths, the sidebar and the page gutters scale
   with the window instead of being fixed pixel widths, so the app keeps the
   same proportions on a laptop and on a wide monitor. Change them here, not
   per screen. */
:root {
  --content-max: 100%;                         /* pages fill the width beside the sidebar */
  --sidebar-w: clamp(15rem, 17vw, 17.5rem);     /* floor fits the longest label + Beta tag */
  --page-pad-x: clamp(1rem, 4vw, 3.5rem);
  --page-pad-top: clamp(1.5rem, 3.5vw, 2.5rem);
  --sch-bar-w: 9px;                            /* schedule run-history bar (a mark, like an icon) */
  --sch-bar-gap: 3px;
}
body {
  font-family: var(--font-sans);
  background: var(--arctic);
  color: var(--fg-1);
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
  line-height: 1.5;
}
a { color: inherit; text-decoration: none; }
button { font-family: inherit; cursor: pointer; }
/* Button labels use "Sofia Pro Centered" (tokens.css) so their letters sit in
   the middle of the button at every weight. Redefining --font-sans on the
   button covers rules that set font-family: var(--font-sans); the
   !important covers the ones that say font: inherit. */
button, .primary-btn, .secondary-btn, input[type="button"], input[type="submit"] {
  --font-sans: "Sofia Pro Centered", "Sofia Pro", "Proxima Nova", system-ui, -apple-system, sans-serif;
  font-family: var(--font-sans) !important;
}

.hidden { display: none !important; }
/* RBAC: app.js adds .perm-off to a [data-requires] element whose permissions
   /me doesn't grant, and sets body.no-build when it grants no screen at all
   (a USER), which shows the no-access note. */
.perm-off { display: none !important; }
/* Beta flags show only to roles with beta.access (body.has-beta, set from
   /me). Hidden until then, so a DEVELOPER or USER never sees one. */
body:not(.has-beta) .sidebar-nav-badge,
body:not(.has-beta) .beta-badge,
body:not(.has-beta) .html-rf-beta { display: none !important; }
.only-no-build { display: none; }
body.no-build .only-no-build { display: block; }

/* No-flash on reload: app.js loads afterInteractive, so the server-rendered
   sign-in screen (#auth-screen — the only top-level container without
   .hidden) paints first and flashes before the session is restored and the
   real screen is shown. The inline boot script in pages/_document.js sets
   html.quarry-session-active before first paint when a valid session exists;
   this hides the sign-in screen immediately so signed-in reloads go straight
   to the app shell. */
html.quarry-session-active #auth-screen { display: none !important; }

/* No body scrollbar behind the fixed sign-in screen. */
html:not(.quarry-session-active) body:has(#auth-screen:not(.hidden)) {
  overflow: hidden;
}

/* ============================================================
   Auth screen — simple sign-in card on Envoy arctic background
   ============================================================ */
.auth-screen {
  position: fixed; inset: 0; z-index: 200;
  display: flex; align-items: center; justify-content: center;
  background: var(--arctic);
}
.auth-card {
  display: flex; flex-direction: column; align-items: center;
  gap: 20px;
  background: #fff;
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  padding: 44px 40px;
  max-width: 25rem;
  width: calc(100% - 2rem);
  text-align: center;
  box-shadow: var(--shadow-md);
}
.auth-logo {
  display: inline-flex; align-items: center; gap: 10px;
  font-size: 18px; font-weight: var(--fw-bold);
  color: var(--fg-1);
  letter-spacing: -0.01em;
}
.auth-logo .logo-icon {
  width: 32px; height: 32px;
  background: var(--envoy-red);
  border-radius: 8px;
  display: inline-flex; align-items: center; justify-content: center;
  color: #fff;
  box-shadow: 0 4px 12px -3px rgba(250, 67, 56, 0.45);
}
.auth-description {
  color: var(--fg-3);
  font-size: 14px;
  line-height: 1.55;
  margin: 0;
}
.auth-description strong { color: var(--fg-1); font-weight: var(--fw-semibold); }
.auth-error {
  background: rgba(160, 12, 31, 0.08);
  color: var(--garnet-70);
  font-size: 13px;
  font-weight: var(--fw-medium);
  padding: 8px 12px;
  border-radius: 6px;
  width: 100%;
  text-align: left;
  margin: 0;
}

/* ============================================================
   App frame — sidebar (--sidebar-w) + page content
   ============================================================ */
.sidebar, .app-sidebar {
  position: fixed; top: 0; left: 0; bottom: 0;
  z-index: 100;
  width: var(--sidebar-w);
  background: #fff;
  border-right: 1px solid var(--border);
  display: flex; flex-direction: column;
  overflow: hidden;
}
.page-content {
  margin-left: var(--sidebar-w);
  min-height: 100vh;
  background: var(--arctic);
  display: flex;
  flex-direction: column;
}
.page-content > .main,
.page-content > #app-content > .main {
  padding: var(--page-pad-top) var(--page-pad-x) calc(var(--page-pad-top) * 1.4);
  max-width: var(--content-max);
}

/* ----- Sidebar top (brand) ----- */
.sidebar-top, .app-sb-top {
  display: flex; align-items: center; gap: 10px;
  padding: 18px 18px 18px 20px;
  border-bottom: 1px solid var(--border);
}
.logo {
  display: inline-flex; align-items: center; gap: 10px;
  text-decoration: none; /* it's a link to Home */
}
.logo-icon, .app-brand-mark {
  width: 28px; height: 28px;
  background: var(--envoy-red);
  border-radius: 7px;
  display: inline-flex; align-items: center; justify-content: center;
  color: #fff;
  box-shadow: 0 2px 6px -1px rgba(250, 67, 56, 0.4);
  flex-shrink: 0;
}
.logo-text, .app-brand-word {
  font-size: 17px;
  font-weight: var(--fw-bold);
  color: var(--fg-1);
  letter-spacing: -0.01em;
}

/* ----- Sidebar nav ----- */
.sidebar-nav, .app-sb-nav {
  display: flex; flex-direction: column;
  padding: 12px 10px;
  gap: 2px;
  flex: 1;
  overflow-y: auto;
}
/* Section header inside the sidebar nav (Create / Automate / Library). Labels
   are quieter than the links under them: small, uppercase, lighter gray, the
   same treatment as the stat-card labels (.home-kpi-label). Proximity does the
   grouping: rows inside a group sit tight together, and the space above each
   label is clearly larger than the space between rows. */
.sidebar-section-label {
  display: flex; align-items: center; gap: 10px;
  font-size: 11px;
  line-height: 1.3;
  font-weight: var(--fw-semibold);
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--fg-3);
  padding: 18px 0 4px 12px;
  user-select: none;
}
.sidebar-section-label:first-child { padding-top: 4px; }
/* Items under a section label sit flush with it and with Home: one left
   edge for every icon and label. The space above each label does the
   grouping. */
.sidebar-group {
  display: flex; flex-direction: column;
  gap: 0;
}
/* Every primary nav item shares one size, and its icon starts at 12px, the
   same as the section labels' text. */
#sidebar .sidebar-nav .sidebar-nav-item {
  padding: 6px 10px 6px 12px;
  font-size: 13.25px;
  font-weight: var(--fw-regular);
  gap: 11px;
}
/* Links (Home included) are body gray, darker than the section labels above
   them; icons a step lighter. Hover and the selected row keep their own
   colors. */
#sidebar .sidebar-nav .sidebar-nav-item:not(.active):not(:hover) { color: var(--fg-2); }
#sidebar .sidebar-nav .sidebar-nav-item:not(.active):not(:hover) > svg { color: var(--fg-3); }
/* The selected row stays medium weight so it still stands out. */
#sidebar .sidebar-nav .sidebar-nav-item.active { font-weight: var(--fw-medium); }
/* Home sits above the groups but is styled as a plain item, with Create pulled
   up closer so it reads as "Home, then the sections" rather than a lone row. */
#nav-home + .sidebar-section-label { padding-top: 12px; }
/* Sofia Pro reserves descender room below the baseline, so a centered label's
   capitals sit ~1px above the icon's middle (most visible on "Home"). */
#sidebar .sidebar-nav .sidebar-nav-label { transform: translateY(1px); }
#sidebar .sidebar-nav .sidebar-nav-item > svg { width: 16px; height: 16px; }
.sidebar-nav-item, .app-sb-item {
  display: flex; align-items: center;
  gap: 11px;
  padding: 9px 12px;
  border-radius: 8px;
  color: var(--fg-2);
  font-size: 14px;
  font-weight: var(--fw-medium);
  text-decoration: none;
  cursor: pointer;
  transition: none;
}
.sidebar-nav-item:hover, .app-sb-item:hover {
  background: var(--arctic);
  color: var(--fg-1);
}
.sidebar-nav-item.active,
.sidebar-nav-item.is-active,
.app-sb-item.is-active {
  background: rgba(250, 67, 56, 0.1);
  color: var(--envoy-red);
  font-weight: var(--fw-medium);
}
.sidebar-nav-item.active:hover,
.sidebar-nav-item.is-active:hover,
.app-sb-item.is-active:hover {
  background: rgba(250, 67, 56, 0.14);
  color: var(--envoy-red);
}
.sidebar-nav-item > svg,
.app-sb-item > .app-sb-icon { color: var(--fg-3); flex-shrink: 0; }
.sidebar-nav-item.active > svg,
.sidebar-nav-item.is-active > svg,
.app-sb-item.is-active > .app-sb-icon { color: var(--envoy-red); }
.sidebar-nav-label, .app-sb-label {
  flex: 1 1 auto; min-width: 0;
  /* One line per item: a wrapped label doubles the row height and breaks the
     rhythm of the list. Truncate instead if the sidebar is ever too narrow. */
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.nav-chevron, .app-sb-trail {
  color: var(--fg-3);
  display: inline-flex;
  flex: 0 0 auto;        /* don't stretch — the label has flex:1; the chevron must stay its natural size */
  width: 12px;
  height: 12px;
  transition: transform 0.2s;
}
.nav-expandable.open .nav-chevron,
.app-sb-expand.open .app-sb-trail { transform: rotate(180deg); }

/* Suppress the default browser focus outline on sidebar links; use a subtle
   focus-visible ring instead so keyboard users still get feedback. */
.nav-sub-item:focus,
.app-sb-item:focus,
.app-sb-sub:focus { outline: none; }
.nav-sub-item:focus-visible,
.app-sb-item:focus-visible,
.app-sb-sub:focus-visible {
  outline: 2px solid rgba(250, 67, 56, 0.4);
  outline-offset: 1px;
}
.sidebar-nav-item:focus,
.sidebar-nav-item:focus-visible { outline: none; }

/* Sub-panel under "Generate Slides" */
.nav-sub-panel, .app-sb-subpanel {
  padding: 2px 0 4px 36px;
  display: flex; flex-direction: column;
  gap: 2px;
  overflow: hidden;
  max-height: 0;
  transition: max-height 0.2s ease;
}
.nav-expandable.open .nav-sub-panel,
.app-sb-expand.open .app-sb-subpanel { max-height: 200px; }
.nav-sub-item, .app-sb-sub {
  display: flex; align-items: center; gap: 8px;
  padding: 6px 10px;
  border-radius: 6px;
  color: var(--fg-3);
  font-size: 13px;
  font-weight: var(--fw-medium);
  text-decoration: none;
  cursor: pointer;
}
.nav-sub-item:hover, .app-sb-sub:hover {
  background: var(--arctic);
  color: var(--fg-1);
}
.nav-sub-item.active,
.nav-sub-item.is-active { color: var(--envoy-red); font-weight: var(--fw-semibold); }

/* ----- Sidebar bottom (user chip) ----- */
.sidebar-bottom, .app-sb-bottom {
  display: flex; align-items: center; gap: 10px;
  padding: 14px 16px;
  border-top: 1px solid var(--border);
}
/* The chip is the anchor for the account menu, which opens above it. Kept
   compact, with the avatar centered under the nav icons. */
#sidebar .sidebar-bottom { padding: 6px 10px; }
#sidebar .user-menu-btn { gap: 10px; padding: 7px 7px; border-radius: 6px; }
#sidebar .user-avatar { width: 26px; height: 26px; font-size: 11px; }
#sidebar .user-chip-info { gap: 3px; }
#sidebar .user-name { line-height: 1.3; }
/* Role pill, a smaller twin of the Settings profile's .settings-role. */
.user-role {
  align-self: flex-start; max-width: 100%;
  font-size: 9.5px; font-weight: var(--fw-semibold); letter-spacing: 0.04em; text-transform: uppercase;
  line-height: 1.4; color: var(--envoy-red); background: rgba(250, 67, 56, 0.08);
  border-radius: 999px; padding: 1px 7px;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.user-role:empty { display: none; }
.user-chip {
  position: relative;
  display: flex; align-items: center; gap: 10px;
  width: 100%;
}
.user-chip.hidden { display: none; }
.user-avatar, .app-sb-avatar {
  width: 30px; height: 30px;
  border-radius: 999px;
  background: linear-gradient(135deg, #FFE4EC 0%, #FFCCDB 100%);
  color: #BE185D;
  font-size: 12px; font-weight: var(--fw-bold);
  display: inline-flex; align-items: center; justify-content: center;
  object-fit: cover;
  flex-shrink: 0;
}
/* Photo inside the round avatar; initials show when there isn't one. */
.user-avatar { overflow: hidden; letter-spacing: 0.02em; }
.user-avatar img { width: 100%; height: 100%; object-fit: cover; display: block; }

/* Chip button: picture, name, up/down caret. Hover and open states
   match the nav rows. */
.user-menu-btn {
  display: flex; align-items: center; gap: 10px;
  width: 100%; min-width: 0;
  padding: 6px;
  background: transparent; border: 0; border-radius: 8px;
  font: inherit; text-align: left; cursor: pointer;
}
.user-menu-btn:hover,
.user-menu-btn[aria-expanded="true"] { background: var(--arctic); }
.user-menu-btn:focus { outline: none; }
.user-menu-btn:focus-visible { outline: 2px solid rgba(250, 67, 56, 0.35); outline-offset: -2px; }
.user-menu-btn .user-chip-info { flex: 1 1 auto; }
.user-name {
  font-size: 13px; font-weight: var(--fw-medium); color: var(--fg-1);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.user-name:empty { display: none; }
.user-menu-caret { flex-shrink: 0; color: var(--fg-4); }

/* The menu itself: a small card that opens above the chip. */
.user-menu {
  position: absolute; left: 0; right: 0; bottom: calc(100% + 6px);
  display: flex; flex-direction: column; gap: 1px;
  padding: 4px;
  background: #fff;
  border: 1px solid var(--border);
  border-radius: 8px;
  box-shadow: 0 8px 24px rgba(15, 23, 42, 0.12), 0 2px 6px rgba(15, 23, 42, 0.08);
  z-index: 20;
}
.user-menu.hidden { display: none; }
.user-menu-item {
  display: flex; align-items: center; gap: 8px;
  padding: 5px 8px;
  border: 0; border-radius: 5px; background: transparent;
  font: inherit; font-size: 13px; line-height: 1.35; color: var(--fg-2);
  text-align: left; text-decoration: none; cursor: pointer;
}
/* Who's signed in (photo, name, email) above the actions, split off by
   hairlines, like GitHub's account menu. */
.user-menu-header {
  display: flex; align-items: center; gap: 9px;
  padding: 6px 8px 5px;
  min-width: 0;
}
#sidebar .user-menu-header .user-avatar { width: 30px; height: 30px; font-size: 11.5px; }
.user-menu-who { display: flex; flex-direction: column; gap: 1px; min-width: 0; }
.user-menu-name {
  font-size: 13px; font-weight: var(--fw-semibold); color: var(--fg-1); line-height: 1.3;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.user-menu-email {
  font-size: 12px; color: var(--fg-3); line-height: 1.3;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.user-menu-divider { height: 1px; margin: 3px 2px; background: var(--border); }
.user-menu-item > svg { width: 14px; height: 14px; color: var(--fg-3); flex-shrink: 0; }
.user-menu-item:hover,
.user-menu-item:focus-visible { background: var(--arctic); color: var(--fg-1); outline: none; }
.user-menu-item:hover > svg,
.user-menu-item:focus-visible > svg { color: var(--fg-2); }
/* The page you're on (Settings, Access Control, How To): same red as a
   selected nav row. */
.user-menu-item.active { color: var(--envoy-red); }
.user-menu-item.active > svg { color: var(--envoy-red); }
#sign-out-btn:hover, #sign-out-btn:focus-visible { color: var(--envoy-red); }
#sign-out-btn:hover > svg, #sign-out-btn:focus-visible > svg { color: var(--envoy-red); }
.user-chip-info, .app-sb-userinfo {
  display: flex; flex-direction: column;
  gap: 3px;
  min-width: 0;
}
.user-email, .app-sb-email {
  font-size: 12px;
  color: var(--fg-3);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* ----- Preview as a role (SUPERADMIN only) ----- */
.view-as {
  display: flex; align-items: center; justify-content: space-between; gap: 16px;
  flex-wrap: wrap;
  max-width: var(--content-max); /* line up with .admin-pane below it */
  margin: 0 0 20px;
  padding: 14px 16px;
  background: var(--bg-2);
  border: 1px solid var(--border);
  border-radius: 10px;
}
.view-as.hidden { display: none; }
.view-as-text { min-width: 0; flex: 1 1 260px; }
.view-as-title { font-size: 14px; font-weight: var(--fw-semibold); color: var(--fg-1); }
.view-as-sub { font-size: 13px; color: var(--fg-3); margin-top: 2px; line-height: 1.45; }
.view-as-options, .view-as-banner-switch { display: flex; gap: 6px; flex-wrap: wrap; }
.view-as-btn {
  font: inherit; font-size: 13px; font-weight: var(--fw-medium);
  color: var(--fg-1);
  background: transparent;
  border: 1px solid var(--border-strong, var(--border));
  border-radius: 999px;
  padding: 5px 12px;
  cursor: pointer;
}
.view-as-btn:hover { border-color: var(--envoy-red); color: var(--envoy-red); }
.view-as-btn[aria-pressed="true"] {
  background: var(--envoy-red); border-color: var(--envoy-red); color: #fff; cursor: default;
}

.view-as-banner {
  display: flex; align-items: center; gap: 12px;
  flex-wrap: wrap;
  padding: 8px 20px;
  font-size: 13px;
  color: var(--envoy-red);
  background: rgba(250, 67, 56, 0.08);
  border-bottom: 1px solid rgba(250, 67, 56, 0.2);
}
.view-as-banner.hidden { display: none; }
.view-as-banner-text { color: var(--fg-1); }
.view-as-banner .view-as-btn { padding: 2px 10px; font-size: 12px; }
.view-as-exit {
  margin-left: auto;
  font: inherit; font-size: 13px; font-weight: var(--fw-semibold);
  color: var(--envoy-red);
  background: transparent; border: 0; padding: 0;
  cursor: pointer;
}
.view-as-exit:hover { text-decoration: underline; }

.home-no-access {
  font-size: 15px;
  color: var(--fg-2);
  margin: 0;
  line-height: 1.5;
}

/* ============================================================
   Page header (shared across Generate Slides flow & others)
   ============================================================ */
.main {
  width: 100%;
  max-width: var(--content-max);
}
.templates-header, .page-head {
  max-width: var(--content-max);
  margin-bottom: 28px;
}
.templates-title, .page-title, .flow-page-title, #flow-page-title {
  font-size: 28px;
  font-weight: var(--fw-bold);
  color: var(--fg-1);
  margin: 0 0 6px;
  letter-spacing: -0.02em;
}
.templates-subtitle, .page-sub, #flow-page-subtitle {
  font-size: 15px;
  color: var(--fg-3);
  margin: 0;
  line-height: 1.5;
}

/* ─── Slide Templates header (title + Import button) ──────────────────────── */
.templates-header-row {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 24px;
  max-width: var(--content-max);
}
.templates-header-row > div:first-child { min-width: 0; }
.templates-header-row .primary-btn {
  flex-shrink: 0;
  white-space: nowrap;
  align-self: flex-start;
}

/* ============================================================
   App card shell (wraps generate-slides flow)
   ============================================================ */
.card-section { width: 100%; }
.main-card, .app-card {
  max-width: var(--content-max);
  background: #fff;
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  overflow: hidden;
  box-shadow: var(--shadow-sm);
}
.tab-pane { display: none; }
.tab-pane.active { display: block; }
.tab-pane.hidden { display: none; }

/* ----- Steps bar ----- */
.steps-bar {
  display: flex; align-items: center; justify-content: space-between;
  padding: 18px 28px;
  border-bottom: 1px solid var(--border);
  background: var(--arctic);
  gap: 12px;
  flex-wrap: nowrap;
}
.step {
  display: inline-flex; align-items: center; gap: 8px;
  color: var(--fg-3);
  font-size: 13px;
  font-weight: var(--fw-medium);
  white-space: nowrap;
}
.step-number, .step-num {
  width: 22px; height: 22px;
  border-radius: 999px;
  border: 1px solid var(--border-strong);
  background: #fff;
  display: inline-flex; align-items: center; justify-content: center;
  font-size: 11px;
  font-weight: var(--fw-bold);
  color: var(--fg-3);
  flex-shrink: 0;
}
.step.active, .step.is-active {
  color: var(--fg-1);
  font-weight: var(--fw-semibold);
}
.step.active .step-number,
.step.active .step-num,
.step.is-active .step-number,
.step.is-active .step-num {
  background: var(--envoy-red);
  border-color: transparent;
  color: #fff;
}
.step.is-done, .step.done {
  color: var(--fg-2);
}
.step.is-done .step-number,
.step.is-done .step-num,
.step.done .step-number,
.step.done .step-num {
  background: var(--cilantro-40);
  border-color: transparent;
  color: #fff;
}
.step-connector, .step-conn {
  flex: 1;
  min-width: 12px;
  height: 1px;
  background: var(--border);
  margin: 0 4px;
}

/* ----- Panel container ----- */
.panel, .app-panel {
  padding: 36px 40px;
}
.panel.hidden { display: none; }

/* ============================================================
   Input form (Step 1)
   ============================================================ */
.input-group, .ig { margin-bottom: 22px; }
.input-label, .ig-label {
  display: flex; align-items: center; gap: 8px;
  font-size: 12px;
  font-weight: var(--fw-bold);
  color: var(--fg-2);
  text-transform: uppercase;
  letter-spacing: 0.06em;
  margin-bottom: 10px;
}
.input-wrapper, .ig-wrap { position: relative; }
.input-wrapper input,
.ig-input {
  width: 100%;
  padding: 13px 48px 13px 16px;
  background: #fff;
  border: 1.5px solid var(--border-strong);
  border-radius: var(--radius);
  color: var(--fg-1);
  font-family: var(--font-sans);
  font-size: 14px;
  outline: none;
  transition: border-color 0.15s, box-shadow 0.15s;
}
.input-wrapper input::placeholder,
.ig-input::placeholder { color: var(--fg-4); }
.input-wrapper input:focus,
.ig-input:focus {
  border-color: var(--envoy-red);
  box-shadow: 0 0 0 3px rgba(250, 67, 56, 0.12);
}
.paste-btn, .ig-paste {
  position: absolute; right: 10px; top: 50%;
  transform: translateY(-50%);
  background: transparent;
  border: 0;
  padding: 6px;
  border-radius: 6px;
  color: var(--fg-3);
  cursor: pointer;
  display: inline-flex;
}
.paste-btn:hover, .ig-paste:hover { background: var(--arctic); color: var(--fg-1); }
.input-hint, .ig-hint {
  margin: 8px 0 0;
  font-size: 12px;
  color: var(--fg-3);
  line-height: 1.5;
}
.input-hint code, .ig-hint code {
  font-family: var(--font-mono);
  font-size: 11px;
  background: var(--arctic);
  color: var(--fg-2);
  padding: 2px 6px;
  border-radius: 4px;
  border: 1px solid var(--border-subtle);
}

/* URL field warning state (mismatched domain etc.) */
.url-warning {
  margin: 8px 0 0;
  font-size: 12px;
  color: var(--garnet-70);
  font-weight: var(--fw-medium);
}
.url-warning.hidden { display: none; }

/* ============================================================
   Buttons
   ============================================================ */
/* Big buttons share one size everywhere (38px tall: 8px padding, a 20px
   line, a 1px border; the red one's border is transparent so it matches). */
.primary-btn {
  display: inline-flex; align-items: center; justify-content: center;
  gap: 8px;
  padding: 8px 18px;
  line-height: 20px;
  background: var(--envoy-red);
  color: #fff;
  border: 1px solid transparent;
  border-radius: var(--radius);
  font-family: var(--font-sans);
  font-size: 14px;
  font-weight: var(--fw-bold);
  cursor: pointer;
  text-decoration: none;
  transition: background 0.15s, transform 0.1s, box-shadow 0.15s, opacity 0.15s;
  width: 100%;
}
.primary-btn:hover:not(:disabled) {
  background: var(--envoy-red-hover);
  box-shadow: 0 6px 16px -4px rgba(250, 67, 56, 0.4);
  transform: translateY(-1px);
}
.primary-btn:disabled { opacity: 0.6; cursor: not-allowed; }
.btn-arrow { transition: transform 0.2s; }
/* Generate Slides / Write Data to Sheets after the click (_setGenerateBusy). */
#customize-generate-btn.is-busy { cursor: progress; }
#customize-generate-btn.is-busy .btn-arrow { display: none; }
#customize-generate-btn .spinner {
  width: 14px; height: 14px; flex: 0 0 auto; border-width: 2px;
  border-color: rgba(255, 255, 255, .45); border-top-color: #fff;
}
@media (prefers-reduced-motion: reduce) { #customize-generate-btn .spinner { animation: none; } }
.primary-btn:hover .btn-arrow { transform: translateX(3px); }

.secondary-btn {
  display: inline-flex; align-items: center; justify-content: center;
  gap: 8px;
  padding: 8px 18px;
  line-height: 20px;
  background: #fff;
  border: 1px solid var(--border-strong);
  border-radius: var(--radius);
  color: var(--fg-1);
  font-family: var(--font-sans);
  font-size: 14px;
  font-weight: var(--fw-semibold);
  cursor: pointer;
  transition: background 0.15s, border-color 0.15s;
}
.secondary-btn:hover { background: var(--arctic); border-color: var(--carbon-30); }
.secondary-btn:disabled { opacity: 0.4; cursor: default; pointer-events: none; }

/* File source segmented control */
.file-source-picker {
  display: grid;
  grid-template-columns: 1fr 1fr;
  background: var(--arctic, #f3f4f6);
  border-radius: 10px;
  padding: 3px;
  gap: 3px;
}
.file-source-option {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 12px;
  padding: 12px 18px;
  background: transparent;
  border: none;
  border-radius: 8px;
  color: var(--fg-2, #6b7280);
  font-family: var(--font-sans);
  font-size: 13px;
  font-weight: var(--fw-semibold, 600);
  cursor: pointer;
  transition: background 0.15s, color 0.15s, box-shadow 0.15s;
  white-space: nowrap;
}
.file-source-option:hover { color: var(--fg-1); }
.file-source-option--selected {
  background: #fff;
  color: var(--fg-1);
  box-shadow: 0 1px 3px rgba(0,0,0,0.10), 0 1px 2px rgba(0,0,0,0.06);
}
.file-source-option--selected:hover { background: #fff; }

/* File source picker (schedule modal: "Create in Google Drive" / "Use my own links") */
.file-source-picker {
  position: relative;
  display: grid;
  grid-template-columns: 1fr 1fr;
  background: var(--arctic, #f3f4f6);
  border-radius: 10px;
  padding: 3px;
  gap: 3px;
  /* Fixed height prevents layout shift when subtitle text wraps differently */
  align-items: stretch;
}
/* Sliding white pill indicator */
.file-source-picker::before {
  content: '';
  position: absolute;
  top: 3px;
  left: 3px;
  /* exactly half the grid minus the gap and outer padding */
  width: calc(50% - 4.5px);
  height: calc(100% - 6px);
  background: #fff;
  border-radius: 7px;
  box-shadow: 0 1px 3px rgba(0,0,0,0.10), 0 1px 2px rgba(0,0,0,0.06);
  transition: transform 0.38s cubic-bezier(0.4, 0, 0.2, 1);
  z-index: 0;
  pointer-events: none;
}
.file-source-picker--own::before {
  /* slide right by exactly one pill-width + the 3px gap */
  transform: translateX(calc(100% + 3px));
}
.file-source-option {
  position: relative;
  z-index: 1;
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 12px 16px;
  background: transparent;
  border: none;
  border-radius: 8px;
  color: var(--fg-2, #6b7280);
  font-family: var(--font-sans);
  font-size: 13px;
  cursor: pointer;
  text-align: left;
  transition: color 0.25s ease;
  min-width: 0; /* prevents grid blowout from long text */
}
.file-source-option span[style] { min-width: 0; overflow: hidden; }
/* Generate Deck's picker: no browser focus ring on click; the app's red ring
   for keyboard focus. */
#load-config-source .file-source-option:focus { outline: none; }
#load-config-source .file-source-option:focus-visible { outline: 2px solid rgba(250, 67, 56, 0.35); outline-offset: -2px; }
.file-source-option:hover { color: var(--fg-1); }
/* The sliding ::before pill is the only highlight, so the selected option
   drops the white box and shadow from the older rule above. */
.file-source-option--selected,
.file-source-option--selected:hover { color: var(--fg-1); background: transparent; box-shadow: none; }

/* Crossfade between drive-options and manual-urls panels */
.sch-source-panel {
  display: flex;
  opacity: 1;
  transition: opacity 0.25s ease;
}
.sch-source-panel--hidden {
  display: none !important;
}
/* Keep the source wrapper from collapsing under the overflow: hidden it gets
   while the panel swap animates, if it ever sits in a shrinking flex column. */
#sch-source-content { flex-shrink: 0; }

/* Compact modifier for buttons living inside cards / dense lists */
.small-btn {
  padding: 7px 12px;
  font-size: 13px;
  border-radius: 6px;
}

.danger-btn {
  display: inline-flex; align-items: center; justify-content: center;
  gap: 8px;
  padding: 8px 18px;
  line-height: 20px;
  background: #fff;
  border: 1px solid var(--garnet-70);
  border-radius: var(--radius);
  color: var(--garnet-70);
  font-family: var(--font-sans);
  font-size: 14px;
  font-weight: var(--fw-semibold);
  cursor: pointer;
}
.danger-btn:hover { background: rgba(160, 12, 31, 0.05); }
/* When combined with .small-btn, .danger-btn's own 12/22 padding wins via
   source order. Re-apply the compact sizing here so a button with both
   classes matches its sibling .secondary-btn.small-btn instead of towering
   over it (this is exactly the Add Slide vs Clear All mismatch). */
.danger-btn.small-btn,
.small-btn.danger-btn {
  padding: 7px 12px;
  font-size: 13px;
  border-radius: 6px;
}

/* ============================================================
   Progress panel (Step 3/4/5 — extracting/gathering/generating)
   ============================================================ */
.progress-container {
  display: flex; flex-direction: column;
  gap: 22px;
  text-align: center;
}
.progress-header { margin-bottom: 8px; }
.progress-label {
  font-size: 18px;
  font-weight: var(--fw-bold);
  color: var(--fg-1);
}
.progress-bar-track {
  width: 100%;
  height: 8px;
  background: var(--carbon-10);
  border-radius: 999px;
  overflow: hidden;
}
.progress-bar-fill {
  height: 100%;
  background: linear-gradient(90deg, var(--envoy-red) 0%, var(--envoy-red-hover) 100%);
  border-radius: 999px;
  transition: width 0.3s ease;
}
.progress-log {
  background: var(--arctic);
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius);
  padding: 16px;
  max-height: 25vh;
  overflow-y: auto;
  font-family: var(--font-mono);
  font-size: 12px;
  color: var(--fg-2);
  text-align: left;
  line-height: 1.6;
}

/* ============================================================
   Customize panel (Step 2 — mode selector + tile grid)
   ============================================================ */
.customize-header, .cz-head { margin-bottom: 22px; }
.customize-title, .cz-title {
  font-size: 20px;
  font-weight: var(--fw-bold);
  color: var(--fg-1);
  margin: 0 0 4px;
}
.customize-subtitle, .cz-sub {
  font-size: 14px;
  color: var(--fg-3);
  margin: 0;
}

.customize-mode-grid, .cz-mode-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 12px;
  margin-bottom: 32px;
}
.customize-mode-card, .cz-mode {
  display: flex; align-items: center;
  gap: 12px;
  padding: 12px 14px;          /* was 18px — tighter for a more compact card */
  background: #fff;
  border: 1.5px solid var(--border-strong);
  border-radius: var(--radius-md);
  text-align: left;
  cursor: pointer;
  transition: border-color 0.15s, background 0.15s;
  font-family: var(--font-sans);
}
.customize-mode-card:hover, .cz-mode:hover { border-color: var(--carbon-30); }
.customize-mode-card.active,
.customize-mode-card.is-active,
.cz-mode.is-active {
  border-color: var(--envoy-red);
  background: rgba(250, 67, 56, 0.04);
}
.customize-mode-icon, .cz-mode-icon {
  width: 32px; height: 32px;   /* was 36 */
  border-radius: 8px;
  background: var(--envoy-red);
  color: #fff;
  display: inline-flex; align-items: center; justify-content: center;
  flex-shrink: 0;
}
.customize-mode-icon > svg, .cz-mode-icon > svg { width: 18px; height: 18px; }
.customize-mode-card:not(.active):not(.is-active) .customize-mode-icon,
.cz-mode:not(.is-active) .cz-mode-icon {
  background: #F4F4F7;
  color: var(--carbon-60);
}
.customize-mode-body, .cz-mode > div { flex: 1; min-width: 0; }
/* The markup uses an `<h3>` (and `<h4>` for the older skin). Without an
   explicit override the `<h3>` renders at the browser default (huge), which
   was blowing the card up to ~120px tall. Constrain heading + paragraph to
   the same compact type scale we use elsewhere. */
.customize-mode-card h3,
.customize-mode-card h4,
.cz-mode h3,
.cz-mode h4 {
  font-size: 14px;
  font-weight: var(--fw-bold);
  color: var(--fg-1);
  margin: 0 0 2px;
  line-height: 1.25;
  letter-spacing: -0.005em;
}
.customize-mode-card p, .cz-mode p {
  font-size: 12px;
  color: var(--fg-3);
  margin: 0;
  line-height: 1.4;
}

/* Tile grid */
.basic-tiles-section { margin-bottom: 28px; }
.basic-tiles-header, .cz-tiles-head {
  display: flex; justify-content: space-between; align-items: center;
  margin-bottom: 14px;
}
.basic-tiles-label, .cz-tiles-label {
  font-size: 12px;
  font-weight: var(--fw-bold);
  color: var(--fg-2);
  text-transform: uppercase;
  letter-spacing: 0.06em;
}
/* The heading, then a toolbar row: Search charts left, count and Select All
   right, as on Deck Presets. */
.basic-tiles-header--stacked { flex-direction: column; align-items: stretch; gap: 12px; }
.basic-tiles-toolbar { display: flex; justify-content: space-between; align-items: center; gap: 16px; }
.basic-tiles-search { min-width: 0; width: 200px; height: 32px; box-sizing: border-box; padding: 0 10px; gap: 6px; }
.basic-tiles-search svg { flex-shrink: 0; }
.basic-tiles-search input { width: 100%; min-width: 0; height: 100%; padding: 2.5px 0 0; box-sizing: border-box; font-size: 13px; }
.basic-tiles-empty { margin: 4px 0 28px; font-size: 13px; color: var(--fg-3); text-align: center; }
.basic-tiles-meta, .cz-tiles-meta {
  display: flex; align-items: center;
  gap: 14px;
}
.basic-tiles-count, .cz-count {
  font-size: 12px;
  color: var(--fg-3);
  font-weight: var(--fw-medium);
}
.cz-selall {
  display: inline-flex; align-items: center;
  gap: 8px;
  font-size: 12px;
  font-weight: var(--fw-semibold);
  color: var(--fg-1);
  cursor: pointer;
}
.cz-check {
  width: 16px; height: 16px;
  border: 1.5px solid var(--border-strong);
  border-radius: 4px;
  background: #fff;
}
.basic-tiles-grid, .cz-tiles {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 10px;
  margin-bottom: 28px;
}
.tilec {
  position: relative;
  background: #fff;
  border: 1.5px solid var(--border-strong);
  border-radius: var(--radius);
  padding: 12px;
  cursor: pointer;
  transition: border-color 0.15s, box-shadow 0.15s;
  color: var(--gem-60);
}
.tilec:hover { border-color: var(--carbon-30); }
.tilec.is-selected, .tilec.selected { border-color: var(--envoy-red); }
.tilec.is-selected .tilec-check,
.tilec.selected .tilec-check {
  background: var(--envoy-red);
  border-color: var(--envoy-red);
}
.tilec.is-selected .tilec-check::after,
.tilec.selected .tilec-check::after {
  content: ""; position: absolute; inset: 0;
  background: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16"><polyline points="3.5,8.5 6.5,11 12.5,4.5" fill="none" stroke="white" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round"/></svg>') no-repeat center / 65%;
}
.tilec-check {
  position: absolute; top: 10px; right: 10px;
  width: 16px; height: 16px;
  border: 1.5px solid var(--border-strong);
  border-radius: 4px;
  background: #fff;
}
.tilec-preview {
  height: 80px;
  margin-bottom: 10px;
  border-radius: 6px;
  background: var(--arctic);
  padding: 10px;
  display: flex; align-items: center; justify-content: center;
}
.tilec-preview svg { width: 100%; height: 100%; }
.tilec-kpi {
  font-size: 22px;
  font-weight: var(--fw-bold);
  color: var(--fg-1);
  letter-spacing: -0.01em;
}
.tilec-table {
  display: grid; grid-template-columns: repeat(3, 1fr);
  gap: 4px; width: 100%; height: 100%;
  padding: 4px;
}
.tilec-table span {
  background: currentColor;
  opacity: 0.25;
  border-radius: 2px;
}
.tilec-name {
  font-size: 12px;
  font-weight: var(--fw-semibold);
  color: var(--fg-1);
  line-height: 1.3;
}

/* ─── Chart tile cards (basic-tiles-grid) ────────────────────────────────────
   The JS in `showCustomizePanel` builds tiles with the class names
   `.tile-card`, `.tile-card-check`, `.tile-card-name`, `.tile-card-footer`,
   `.tile-card-type`, `.tile-card-type-dot`. The earlier `.tilec*` styles up
   above never matched, so the cards were rendering completely unstyled —
   giant block-level names, no checkbox, no card chrome. These rules give
   them proper card layout, selection state, and a type badge. */
.tile-card {
  position: relative;
  background: #fff;
  border: 1.5px solid var(--border);
  border-radius: var(--radius);
  padding: 12px 14px;
  padding-right: 36px;          /* leave room for the absolute checkbox */
  cursor: pointer;
  display: flex;
  flex-direction: column;
  gap: 8px;
  min-height: 76px;
  transition: border-color 0.15s, box-shadow 0.15s, background 0.15s;
}
.tile-card:hover {
  border-color: var(--carbon-30);
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.04);
}
.tile-card.selected {
  border-color: var(--envoy-red);
  background: rgba(250, 67, 56, 0.03);
}
.tile-card-check {
  position: absolute;
  top: 12px;
  right: 12px;
  width: 18px;
  height: 18px;
  border: 1.5px solid var(--border-strong);
  border-radius: 4px;
  background: #fff;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  transition: background 0.15s, border-color 0.15s;
}
.tile-card-check > svg {
  opacity: 0;
  transition: opacity 0.15s;
}
.tile-card.selected .tile-card-check {
  background: var(--envoy-red);
  border-color: var(--envoy-red);
}
.tile-card.selected .tile-card-check > svg { opacity: 1; }
.tile-card-name {
  font-size: 13px;
  font-weight: var(--fw-semibold);
  color: var(--fg-1);
  line-height: 1.35;
  overflow: hidden;
  text-overflow: ellipsis;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  word-break: break-word;
  margin: 0;
}
.tile-card-footer {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-top: auto;
}
.tile-card-type {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  font-size: 11px;
  font-weight: var(--fw-semibold);
  color: var(--fg-3);
  text-transform: uppercase;
  letter-spacing: 0.04em;
}
.tile-card-type-dot {
  width: 6px;
  height: 6px;
  border-radius: 999px;
  background: var(--gem-60, #4e4eda);
  display: inline-block;
}
/* ─── "Select all" toggle in the basic-tiles header ──────────────────────── */
.tile-select-all-label {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  font-size: 12px;
  font-weight: var(--fw-semibold);
  color: var(--fg-1);
  cursor: pointer;
  user-select: none;
}
.tile-select-all-check {
  position: relative;
  width: 16px;
  height: 16px;
  border: 1.5px solid var(--border-strong);
  border-radius: 4px;
  background: #fff;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  transition: background 0.15s, border-color 0.15s;
}
.tile-select-all-check .tile-check-icon {
  opacity: 0;
  transition: opacity 0.15s;
}
.tile-select-all-check.all-selected {
  background: var(--envoy-red);
  border-color: var(--envoy-red);
}
.tile-select-all-check.all-selected .tile-check-icon { opacity: 1; }
.tile-select-all-check.partial {
  background: var(--envoy-red);
  border-color: var(--envoy-red);
}
.tile-select-all-check.partial::after {
  content: "";
  position: absolute;
  inset: 50% 3px auto 3px;
  height: 2px;
  background: #fff;
  border-radius: 1px;
  transform: translateY(-50%);
}

/* Footer actions inside customize panel */
.customize-footer, .cz-foot {
  display: flex;
  justify-content: space-between;
  gap: 12px;
}
.customize-footer .primary-btn,
.cz-foot .primary-btn { width: auto; }
.customize-footer .secondary-btn,
.cz-foot .secondary-btn { width: auto; }
/* Group the Save layout + Generate Slides buttons on the right while Back
   sits on the left. `space-between` on .customize-footer pushes the two
   sides apart automatically. */
.customize-footer-right {
  display: inline-flex;
  align-items: center;
  gap: 10px;
}

.basic-selection-warning,
.basic-tiles-error {
  display: flex;
  align-items: center;
  gap: 10px;
  background: rgba(184, 131, 12, 0.08);
  border: 1px solid rgba(184, 131, 12, 0.3);
  color: #8a6310;
  padding: 10px 14px;
  border-radius: var(--radius);
  font-size: 13px;
  line-height: 1.4;
  margin-bottom: 14px;
}
.basic-selection-warning > svg {
  flex-shrink: 0;
  color: #b8830c;
}
.basic-tiles-error {
  background: rgba(160, 12, 31, 0.06);
  border-color: rgba(160, 12, 31, 0.3);
  color: var(--garnet-70);
}
.basic-tiles-loading {
  display: flex; align-items: center; justify-content: center;
  padding: 60px 20px;
  color: var(--fg-3);
  font-size: 14px;
}
/* Sheets-mode notice when KPI tiles get filtered out of the chart picker. */
.basic-tiles-skipped-note {
  font-size: 12px;
  color: var(--fg-3);
  font-style: italic;
  margin: 0 0 10px;
}

/* ============================================================
   Result panel (Step 5 — success)
   ============================================================ */
.result-container, .result-panel {
  text-align: center;
  padding: 48px 40px;
}
.result-icon, .rs-icon {
  width: 52px; height: 52px;
  border-radius: 999px;
  background: var(--cilantro-20);
  color: var(--cilantro-60);
  display: inline-flex; align-items: center; justify-content: center;
  margin-bottom: 18px;
}
.result-title, .rs-title {
  font-size: 24px;
  font-weight: var(--fw-bold);
  color: var(--fg-1);
  margin: 0 0 6px;
  letter-spacing: -0.02em;
}
.result-subtitle, .rs-sub, #result-subtitle {
  font-size: 14px;
  color: var(--fg-3);
  margin: 0 0 32px;
}

.result-preview, .rs-preview {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 12px;
  max-width: 100%;
  margin: 0 auto 32px;
}
.rs-slide {
  aspect-ratio: 16/9;
  background: #fff;
  border: 1px solid var(--border);
  border-radius: 8px;
  padding: 16px;
  text-align: left;
  box-shadow: var(--shadow-xs);
  position: relative;
}
.rs-eyebrow {
  font-size: 9px;
  font-weight: var(--fw-bold);
  color: var(--envoy-red);
  text-transform: uppercase;
  letter-spacing: 0.06em;
}
.rs-title-l {
  font-size: 16px;
  font-weight: var(--fw-bold);
  color: var(--fg-1);
  margin-top: 6px;
  line-height: 1.15;
}
.rs-byline { font-size: 9px; color: var(--fg-3); margin-top: 4px; }
.rs-h {
  font-size: 11px;
  font-weight: var(--fw-bold);
  color: var(--fg-1);
  margin-bottom: 8px;
}
.rs-kpis { display: grid; grid-template-columns: repeat(3, 1fr); gap: 6px; }
.rs-kl {
  font-size: 8px;
  color: var(--fg-3);
  text-transform: uppercase;
  letter-spacing: 0.06em;
  font-weight: var(--fw-semibold);
}
.rs-kv {
  font-size: 13px;
  font-weight: var(--fw-bold);
  color: var(--fg-1);
}

.result-actions, .rs-actions {
  display: flex; gap: 10px; justify-content: center;
}
.result-actions .primary-btn,
.rs-actions .primary-btn,
.result-actions .secondary-btn,
.rs-actions .secondary-btn { width: auto; }
.result-secondary-links {
  display: flex;
  gap: 12px;
  justify-content: center;
  align-items: center;
  margin-top: 16px;
  font-size: 13px;
}
.result-secondary-links a,
.result-secondary-links .download-pdf-link {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  color: var(--fg-3);
  text-decoration: none;
  font-weight: var(--fw-medium);
  font-family: var(--font-sans);
  font-size: 13px;
  background: transparent;
  border: 0;
  padding: 0;
  cursor: pointer;
  transition: color 0.15s;
}
.result-secondary-links a:hover,
.result-secondary-links .download-pdf-link:hover { color: var(--envoy-red); }
.result-secondary-sep { color: var(--fg-4); }

/* ─── "Charts included" list on the success screen ──────────────────────────
   2-column card so dashboards with 40+ charts don't produce a wall of rows.
   The .query-items wrapper is a CSS grid; the header sits above it. */
.query-summary {
  margin: 32px auto 0;
  max-width: 100%;
  text-align: left;
  background: #fff;
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  overflow: hidden;
}
.query-summary > p {
  font-size: 11px;
  font-weight: var(--fw-bold);
  color: var(--fg-3);
  text-transform: uppercase;
  letter-spacing: 0.08em;
  margin: 0;
  padding: 14px 16px 10px;
  border-bottom: 1px solid var(--border);
  background: var(--arctic);
}
.query-items {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
}
.query-item {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 10px 16px;
  border-top: 1px solid var(--border);
  min-width: 0;
}
/* No top border on the first row (items 1+2) — the header above already
   provides the separator. Using top-borders (instead of bottom-borders)
   keeps things clean for odd counts: the last row never has a dangling
   border below it. */
.query-item:nth-child(-n+2) { border-top: 0; }
/* Vertical divider between the two columns. */
.query-item:nth-child(odd) { border-right: 1px solid var(--border); }
.query-name {
  font-size: 13px;
  font-weight: var(--fw-semibold);
  color: var(--fg-1);
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.query-rows {
  font-size: 11px;
  font-weight: var(--fw-medium);
  color: var(--fg-3);
  background: var(--arctic);
  border: 1px solid var(--border);
  border-radius: 999px;
  padding: 2px 8px;
  white-space: nowrap;
  flex-shrink: 0;
}

/* Drop to a single column on narrow screens — the card stops being useful
   as a table when each column is only ~200px wide. */
@media (max-width: 640px) {
  .query-items { grid-template-columns: 1fr; }
  .query-item:nth-child(odd) { border-right: 0; }
}

/* ============================================================
   Preview / Slide builder (used in custom mode)
   ============================================================ */
.preview-container { padding: 8px 0; }
.preview-title {
  font-size: 18px;
  font-weight: var(--fw-bold);
  color: var(--fg-1);
  margin: 0 0 6px;
}
.preview-subtitle {
  font-size: 13px;
  color: var(--fg-3);
  margin: 0 0 20px;
}
/* Generic loading spinner. The `.spinner` class had no CSS at all so the
   div was rendering as an empty box — now it's a 40px circle with a partial
   ring that rotates. Sized via `width/height` on the element itself when the
   caller wants something smaller (e.g. inline `style={{ width: '14px' }}`). */
.spinner {
  width: 40px;
  height: 40px;
  border: 3px solid var(--border);
  border-top-color: var(--envoy-red);
  border-radius: 50%;
  animation: spinner-rotate 0.85s linear infinite;
}
@keyframes spinner-rotate {
  to { transform: rotate(360deg); }
}
.preview-spinner {
  margin: 0 auto 18px;
}

/* Progress bar shown under the chart name in the Generating Slides step,
   plus the "Slide N of M" caption below it. */
.preview-progress {
  max-width: min(22.5rem, 60%);
  margin: 4px auto 6px;
  height: 6px;
  background: var(--arctic);
  border: 1px solid var(--border);
  border-radius: 999px;
  overflow: hidden;
}
.preview-progress-fill {
  height: 100%;
  background: var(--envoy-red);
  width: 0%;
  transition: width 0.3s ease;
  border-radius: 999px;
}
.preview-count {
  font-size: 12px;
  font-weight: var(--fw-medium);
  color: var(--fg-3);
  margin: 6px 0 0;
}
/* Slide builder — single column layout (the broken 2-column grid was leaving
   "Your slides" + Add Slide / Clear All on one side and the slide cards
   wandering to the other). */
.slide-builder {
  display: flex;
  flex-direction: column;
  gap: 14px;
  margin-bottom: 28px;
}
.slide-builder-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
}
.slide-builder-label {
  font-size: 12px;
  font-weight: var(--fw-bold);
  color: var(--fg-2);
  text-transform: uppercase;
  letter-spacing: 0.06em;
}
.slide-builder-actions {
  display: inline-flex;
  align-items: center;
  gap: 8px;
}
.slide-list {
  display: flex; flex-direction: column;
  gap: 10px;
}
/* One bordered box (same frame as the Recent Activity table): the "Your
   Slides" bar is its header row, and only the slides below it scroll, so the
   bar and its buttons stay in view and read as part of the list. The
   scrollbar sits in the box's own lane. */
.slide-list-wrap {
  /* No box of its own (it already sits in a card): "Your Slides" is a
     heading with a line under it, and the slides are rows below it, lined up
     with the Basic / Custom cards. */
  background: transparent;
  border: 0;
  border-radius: 0;
}
.slide-list-wrap .slide-builder-header {
  padding: 0 0 8px;
  background: transparent;
  border-bottom: 1px solid #E4E5EB;
}
.slide-list-wrap .slide-list:empty { display: none; }
.slide-list-wrap:has(.slide-list:empty) .slide-builder-header { border-bottom: 0; }
.slide-list-wrap .slide-list {
  max-height: 60vh;
  overflow-y: auto;
  overscroll-behavior: contain;
  gap: 0;
}
/* Inside the box, slides are table rows like Recent Activity's, not cards:
   no per-slide border or radius, just a hairline between rows (`~` so the
   drop-line markers between cards don't break it) and a tint on hover. */
.slide-list-wrap .slide-card {
  border: 0;
  border-radius: 8px;
  padding: 10px 8px;
  transition: background-color 0.15s;
}
/* The line between rows is drawn inset, so a hovered row's rounded tint
   doesn't run into it; the lines on either side of that row fade out. */
.slide-list-wrap .slide-card ~ .slide-card::before {
  content: ''; position: absolute; top: 0; left: 8px; right: 8px;
  border-top: 1px solid #EEEEF2; pointer-events: none; transition: opacity 0.15s;
}
.slide-list-wrap .slide-card:hover::before,
.slide-list-wrap .slide-card:hover + .slide-card::before,
.slide-list-wrap .slide-card:hover + .drop-line + .slide-card::before { opacity: 0; }
.slide-list-wrap .slide-card:hover { box-shadow: none; background: #F7F7FA; }
/* The drop marker: a red bar on the line between the two rows the slide
   would land between. Positioned in the list's scrolling content (app.js
   sets top), so it stays put while the list scrolls; clicks pass through. */
.slide-list-wrap .slide-list { position: relative; }
.slide-list-wrap .drop-line {
  position: absolute; left: 0; right: 8px; z-index: 2;
  height: 3px; margin: 0; transform: translateY(-50%);
  border-radius: 2px; pointer-events: none;
}
/* Same bar as .activity-body. Firefox has no ::-webkit-scrollbar (and Chrome
   would let scrollbar-color override the rules below), so the standard props
   are Firefox-only. */
@supports not selector(::-webkit-scrollbar) {
  .slide-list-wrap .slide-list { scrollbar-width: thin; scrollbar-color: #C9CAD3 #F6F6F8; }
}
.slide-list-wrap .slide-list::-webkit-scrollbar { width: 16px; }
/* A rounded light-grey lane for the bar to run in; the bar sits inside it. */
.slide-list-wrap .slide-list::-webkit-scrollbar-track { background: #F6F6F8; border-radius: 8px; } /* full 16px wide, like Recent Activity's lane */
.slide-list-wrap .slide-list::-webkit-scrollbar-thumb { background: #C9CAD3; background-clip: padding-box; border-radius: 8px; border: 2px solid transparent; border-left-width: 5px; border-right-width: 4px; }
.slide-list-wrap .slide-list::-webkit-scrollbar-thumb:hover { background-color: #A9AAB5; } /* colour only: the `background` shorthand reset background-clip, so the bar grew to fill its padding */
.drop-line {
  height: 2px;
  background: var(--envoy-red);
  border-radius: 1px;
  margin: -4px 0;
}
.drop-line.hidden { display: none; }
.add-slide-btn {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 10px 14px;
  background: #fff;
  border: 1.5px dashed var(--border-strong);
  border-radius: var(--radius);
  color: var(--fg-2);
  font-size: 13px;
  font-weight: var(--fw-semibold);
  cursor: pointer;
}
.add-slide-btn:hover { border-color: var(--envoy-red); color: var(--envoy-red); }

/* ─── New tabs banner (edit mode) ──────────────────────────────────────────*/
#new-tabs-banner {
  margin-top: 12px;
  padding: 12px 14px;
  background: var(--bg-2, #f8f8f8);
  border: 1px solid var(--border, #e5e5e5);
  border-radius: var(--radius);
}
#new-tabs-banner.hidden { display: none; }
.new-tabs-banner-header {
  font-size: 12px;
  font-weight: var(--fw-semibold);
  color: var(--fg-2);
  margin-bottom: 10px;
}
.new-tabs-list { display: flex; flex-direction: column; gap: 6px; }
.new-tab-row {
  display: flex; align-items: center; justify-content: space-between;
  gap: 8px;
}
.new-tab-name {
  font-size: 13px;
  color: var(--fg-1);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* ─── Slide card (custom mode) ──────────────────────────────────────────────
   Each entry in the slide-list. Layout: drag handle • thumbnail/preview •
   inline editors (type select + title input or tab dropdown) • action buttons
   (Change background, remove). Without these rules the children rendered as
   raw unstyled HTML controls stacked vertically — what the screenshot showed. */
.slide-card {
  position: relative;     /* anchor for .slide-layout-popup */
  display: grid;
  grid-template-columns: 24px 7.5rem minmax(0, 1fr);
  align-items: center;
  gap: 14px;
  padding: 10px 12px;
  background: #fff;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  transition: border-color 0.15s, box-shadow 0.15s;
}
.slide-card:hover {
  border-color: var(--carbon-30);
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.04);
}
.slide-card.dragging { opacity: 0.5; }
.slide-drag-handle {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 24px;
  height: 100%;
  color: var(--fg-3);
  cursor: grab;
  user-select: none;
}
.slide-drag-handle:hover { color: var(--fg-1); }
.slide-drag-handle:active { cursor: grabbing; }
.slide-card-bg {
  position: relative;
  width: 100%;
  aspect-ratio: 16 / 9;
  border-radius: 6px;
  background-color: var(--arctic);
  border: 1px solid var(--border);
  background-size: cover;
  background-position: center;
  display: flex;
  align-items: center;
  justify-content: center;
  overflow: hidden;
}
.slide-card-blank-bg {
  font-size: 9px;
  font-weight: var(--fw-bold);
  color: var(--fg-3);
  text-transform: uppercase;
  letter-spacing: 0.06em;
  white-space: nowrap;
  pointer-events: none;
}

/* ─── Mini "change layout" button rendered inside the slide thumbnail ─────
   Body slide cards include a small overlay that previews the slide layout
   (full / text-chart / chart-text) and opens a popup to swap between them.
   Without these rules it was rendering as a raw stretched button stuck in
   the bottom-right of the thumbnail. */
/* Edit button on the slide preview: opens Edit Slide (background and layout). */
.slide-edit-btn {
  position: absolute; right: 4px; bottom: 4px;
  display: inline-flex; align-items: center; gap: 4px;
  height: 20px; padding: 0 6px;
  font-size: 11px; font-weight: var(--fw-semibold); color: var(--fg-2);
  background: rgba(255, 255, 255, 0.94); border: 1px solid var(--border); border-radius: 4px;
  cursor: pointer; transition: border-color 0.15s, color 0.15s;
}
.slide-edit-btn:hover { border-color: var(--envoy-red); color: var(--envoy-red); }
.slide-edit-btn:focus { outline: none; }
.slide-edit-btn:focus-visible { border-color: var(--envoy-red); box-shadow: 0 0 0 2px rgba(250, 67, 56, 0.25); }

/* Edit Slide popup: Background / Layout tabs under the title. */
.slide-edit-tabs { position: relative; display: flex; gap: 20px; margin: 14px 0 0; border-bottom: 1px solid #EEEEF2; }
/* One red line that slides under the chosen tab (app.js showTab). */
.slide-edit-ink { position: absolute; left: 0; bottom: -1px; height: 2px; width: 0; background: var(--envoy-red); pointer-events: none; transition: transform 0.3s cubic-bezier(0.4, 0, 0.2, 1), width 0.3s cubic-bezier(0.4, 0, 0.2, 1); }
/* Room between the tabs' line and the note under it. */
.slide-edit-tabs:not(.hidden) + .modal-subtitle { margin-top: 14px; }
.slide-edit-tabs.hidden { display: none; }
.slide-edit-tab {
  padding: 0 0 10px; border: 0; background: none;
  font-size: 13px; font-weight: var(--fw-semibold); color: var(--fg-3); cursor: pointer;
}
.slide-edit-tab:hover { color: var(--fg-1); }
.slide-edit-tab.active { color: var(--envoy-red); }
.slide-edit-tab:focus { outline: none; }
.slide-edit-tab:focus-visible { box-shadow: 0 0 0 2px rgba(250, 67, 56, 0.3); border-radius: 4px; }
/* Layout tab: the layout choices as a row of cards. */
/* A grid, so a card that wraps onto the last row keeps the same width. */
.slide-edit-layouts { display: grid; grid-template-columns: repeat(auto-fill, minmax(110px, 1fr)); gap: 10px; padding: 16px 28px 20px; }
.slide-edit-layouts.hidden { display: none; }
.slide-edit-layouts .slide-layout-opt { gap: 8px; padding: 14px 10px 10px; border: 1px solid var(--border); font-size: 12px; }
.slide-edit-layouts .slide-layout-opt:hover { border-color: var(--carbon-30); }
.slide-edit-layouts .slide-layout-opt.active { border-color: var(--envoy-red); }
.slide-edit-layouts .slide-layout-opt > svg { width: 60px; height: 38px; }

/* Popup of layout choices. Anchored to `.slide-card` (which is now
   `position: relative`) so it can escape the thumbnail's `overflow: hidden`
   clip; app.js places it next to the layout button that opened it. */
.slide-layout-popup {
  position: absolute;
  bottom: calc(100% - 8px);
  right: 12px;
  z-index: 20;
  display: flex;
  gap: 4px;
  padding: 6px;
  background: #fff;
  border: 1px solid var(--border);
  border-radius: 8px;
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.12);
}
.slide-layout-popup.hidden { display: none; }
.slide-layout-opt {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 4px;
  padding: 6px 8px;
  background: transparent;
  border: 1.5px solid transparent;
  border-radius: 6px;
  color: var(--fg-3);
  font-size: 10px;
  font-weight: var(--fw-semibold);
  cursor: pointer;
  transition: background 0.15s, border-color 0.15s, color 0.15s;
}
.slide-layout-opt:hover {
  background: var(--arctic);
  color: var(--fg-1);
}
.slide-layout-opt.active {
  border-color: var(--envoy-red);
  color: var(--envoy-red);
  background: rgba(250, 67, 56, 0.04);
}
.slide-layout-opt > svg { display: block; }

/* KPI-grid layout: six narrow selects in a 3×2 arrangement, replacing the
   single chart-tab dropdown when the user picks the "KPI Grid" layout. */
.slide-kpi-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 4px;
  min-width: 0;
}

/* chart-kpis layout: chart select up top, its three KPI selects side by side
   below it, ending where the chart select ends (left of the ×). */
.slide-kpi-stack {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 4px;
  min-width: 0;
  margin-top: 2px;
  margin-right: 26px; /* the ×'s width beside the chart select */
}
.slide-kpi-cell {
  -webkit-appearance: none;
  -moz-appearance: none;
  appearance: none;
  width: 100%;
  font-family: var(--font-sans);
  font-size: 11px;
  font-weight: var(--fw-medium);
  color: var(--fg-1);
  background: #fff;
  border: 1px solid var(--border);
  border-radius: 5px;
  padding: 4px 18px 4px 8px;
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='10' height='10' viewBox='0 0 24 24' fill='none' stroke='%231F232D' stroke-width='2.2' stroke-linecap='round' stroke-linejoin='round'><polyline points='6 9 12 15 18 9'/></svg>");
  background-repeat: no-repeat;
  background-position: right 6px center;
  background-size: 10px 10px;
  cursor: pointer;
  text-overflow: ellipsis;
  overflow: hidden;
  white-space: nowrap;
}
.slide-kpi-cell:focus {
  outline: none;
  border-color: var(--envoy-red);
  box-shadow: 0 0 0 2px rgba(250, 67, 56, 0.12);
}

/* Optional inline text input on text-chart / chart-text layouts. */
/* The slide's text box: the same white field as the title and chart inputs,
   ending where they end (left of the ×). */
.slide-text-input {
  width: calc(100% - 26px);
  box-sizing: border-box;
  font-family: var(--font-sans);
  font-size: 13px;
  font-weight: var(--fw-medium);
  color: var(--fg-1);
  background: #fff;
  border: 1px solid var(--border);
  border-radius: 6px;
  padding: 6px 10px;
  transition: border-color 0.15s, box-shadow 0.15s;
}
.slide-text-input::placeholder { color: var(--fg-3); font-weight: 400; }
.slide-text-input:focus {
  outline: none;
  border-color: var(--envoy-red);
  box-shadow: 0 0 0 3px rgba(250, 67, 56, 0.1);
  background: #fff;
}
.slide-card-info {
  display: flex;
  flex-direction: column;
  gap: 6px;
  min-width: 0;
}
.slide-type-select {
  align-self: flex-start;
  font-family: var(--font-sans);
  font-size: 11px;
  font-weight: var(--fw-semibold);
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--fg-3);
  background: var(--arctic);
  border: 1px solid var(--border);
  border-radius: 4px;
  padding: 3px 8px;
  cursor: pointer;
}
.slide-type-select:focus { outline: none; border-color: var(--envoy-red); }
.slide-title-input,
.slide-card-info select:not(.slide-type-select) {
  width: 100%;
  font-family: var(--font-sans);
  font-size: 13px;
  font-weight: var(--fw-medium);
  color: var(--fg-1);
  background: #fff;
  border: 1px solid var(--border);
  border-radius: 6px;
  padding: 6px 10px;
  transition: border-color 0.15s, box-shadow 0.15s;
}
/* Custom-style the chart-tab <select> so the chevron isn't slammed against
   the right edge by the browser's native arrow rendering. The native arrow
   is hidden via `appearance: none`, and an inline SVG chevron is painted
   in via background-image with controlled offset. */
.slide-card-info select:not(.slide-type-select) {
  -webkit-appearance: none;
  -moz-appearance: none;
  appearance: none;
  padding-right: 32px;
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 24 24' fill='none' stroke='%231F232D' stroke-width='2.2' stroke-linecap='round' stroke-linejoin='round'><polyline points='6 9 12 15 18 9'/></svg>");
  background-repeat: no-repeat;
  background-position: right 12px center;
  background-size: 12px 12px;
}
.slide-title-input::placeholder { color: var(--fg-3); }
.slide-title-input:focus,
.slide-card-info select:focus {
  outline: none;
  border-color: var(--envoy-red);
  box-shadow: 0 0 0 3px rgba(250, 67, 56, 0.1);
}
.slide-card-actions {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  flex-shrink: 0;
}
/* Vertical stack for the two "Change …" buttons so they sit one above the
   other; the × button sits beside the stack, centered vertically. */
.slide-card-actions-stack {
  display: flex;
  flex-direction: column;
  align-items: stretch;
  gap: 4px;
}
.slide-card-actions-stack .slide-change-bg-btn,
.slide-card-actions-stack .slide-change-layout-btn {
  justify-content: flex-start;
}
.slide-change-bg-btn,
.slide-change-layout-btn {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-size: 12px;
  padding: 6px 10px;
  background: #fff;
  border: 1px solid var(--border);
  border-radius: 6px;
  color: var(--fg-2);
  font-weight: var(--fw-semibold);
  cursor: pointer;
  white-space: nowrap;
  transition: background 0.15s, border-color 0.15s, color 0.15s;
}
.slide-change-bg-btn:hover,
.slide-change-layout-btn:hover {
  background: var(--arctic);
  border-color: var(--carbon-30);
  color: var(--fg-1);
}
.slide-change-layout-btn > svg {
  flex-shrink: 0;
  color: var(--fg-3);
}
.slide-change-layout-btn:hover > svg { color: var(--envoy-red); }
.slide-remove-btn {
  width: 28px;
  height: 28px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 0;
  background: none;
  border: 0;
  color: var(--fg-3);
  cursor: pointer;
  flex-shrink: 0;
  transition: color 0.15s;
}
/* Only the × changes: Envoy red, no box behind it. */
.slide-remove-btn:hover { color: var(--envoy-red); }
.slide-remove-btn:focus { outline: none; }
.slide-remove-btn:focus-visible { color: var(--envoy-red); box-shadow: 0 0 0 2px rgba(250, 67, 56, 0.3); border-radius: 6px; }

/* ============================================================
   Modals — generic light theme
   ============================================================ */
.modal-overlay {
  position: fixed; inset: 0; z-index: 300;
  background: rgba(31, 35, 45, 0.55);
  backdrop-filter: blur(4px);
  display: flex; align-items: center; justify-content: center;
  padding: 32px;
}
.modal-overlay.hidden { display: none; }
.modal,
.modal-overlay > .modal,
.modal-overlay > div:not(.bg-picker-modal-inner) {
  background: #fff;
  border-radius: var(--radius-lg);
  max-width: 35rem;
  width: 100%;
  max-height: calc(100vh - 4rem);
  overflow: hidden;
  display: flex; flex-direction: column;
  box-shadow: var(--shadow-lg);
}
.modal-header { padding: 24px 28px 8px; flex-shrink: 0; }
/* Scrollable middle for modals whose content can exceed the viewport
   (e.g. Load configuration with many filter rows). Header + actions stay
   pinned; everything in between scrolls inside this body. */
.modal-body {
  flex: 1 1 auto;
  min-height: 0;
  overflow-y: auto;
  display: flex;
  flex-direction: column;
}
.modal-actions { flex-shrink: 0; }
.modal-title {
  font-size: 18px;
  font-weight: var(--fw-bold);
  color: var(--fg-1);
  margin: 0 0 4px;
}
.modal-subtitle {
  font-size: 14px;
  color: var(--fg-3);
  margin: 0;
}
.modal-preview { padding: 16px 28px; }
/* Standard input slot inside a modal — matches the spacing convention of
   `.modal-preview` so a labeled URL field can sit cleanly between the
   header and the actions row. */
.modal-input-group {
  padding: 18px 28px 8px;
}
.modal-input-group .input-label {
  margin-bottom: 8px;
}
.modal-actions {
  display: flex;
  justify-content: flex-end;
  gap: 10px;
  padding: 16px 28px 22px;
  border-top: 1px solid var(--border);
}
.modal-actions .primary-btn,
.modal-actions .secondary-btn,
.modal-actions .danger-btn { width: auto; }

/* Outer card: holds the Title section and the URL section stacked. */
.modal-url-display {
  display: flex;
  flex-direction: column;
  gap: 18px;
  background: var(--arctic);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 18px;
}
.modal-url-section {
  display: flex;
  flex-direction: column;
  gap: 10px;
  min-width: 0;
}
/* Header row inside each section: small red icon + uppercase label, on a
   shared baseline. The flex centering + explicit `display: block` on the SVG
   keeps the icon's box vertically centered with the label cap-height
   regardless of the SVG viewBox padding. */
.modal-url-label-row {
  display: flex;
  align-items: center;
  gap: 10px;
}
.modal-url-section-icon {
  color: var(--envoy-red);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  /* Reserve a square box so successive section icons align horizontally even
     if their viewBoxes don't share identical aspect ratios. */
  width: 16px;
  height: 16px;
}
.modal-url-section-icon > svg { display: block; }
.modal-url-label {
  font-size: 11px;
  font-weight: var(--fw-bold);
  color: var(--fg-3);
  text-transform: uppercase;
  letter-spacing: 0.08em;
  line-height: 1;
}

/* The dashboard name reads as a product string, not code — sans-serif, normal
   word-break, sits flush left under the label row. */
.modal-card-name {
  display: block;
  font-family: var(--font-sans);
  font-size: 15px;
  font-weight: var(--fw-semibold);
  color: var(--fg-1);
  word-break: normal;
  overflow-wrap: anywhere;
  line-height: 1.35;
  min-width: 0;
}

/* URL chip: white pill nested inside the card. Holds the URL string and the
   open-in-new-tab affordance. Min-height guarantees the pill is visible even
   while textContent is still empty (e.g. between modal open and fetch race). */
.modal-url-row {
  display: flex;
  align-items: center;
  gap: 10px;
  background: #fff;
  border: 1px solid var(--border);
  border-radius: 8px;
  padding: 10px 14px;
  min-height: 38px;
  min-width: 0;
}
.modal-url-value {
  display: block;
  flex: 1 1 auto;
  min-width: 0;
  font-family: var(--font-mono);
  font-size: 13px;
  color: var(--fg-1);
  word-break: break-all;
  line-height: 1.5;
}
.modal-url-open {
  color: var(--gem-60);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  text-decoration: none;
  flex-shrink: 0;
  padding: 4px;
  border-radius: 4px;
  transition: background 0.15s, color 0.15s;
}
.modal-url-open > svg { display: block; }
.modal-url-open:hover { background: rgba(78, 78, 218, 0.08); color: var(--gem-70); }
.modal-tile-grid {
  display: grid; grid-template-columns: repeat(3, 1fr);
  gap: 10px;
  padding: 0 28px 16px;
  max-height: 45vh;
  overflow-y: auto;
}
.modal-selection-warning {
  display: flex;
  align-items: center;
  gap: 10px;
  margin: 0 28px 16px;
  background: rgba(184, 131, 12, 0.08);
  border: 1px solid rgba(184, 131, 12, 0.3);
  color: #8a6310;
  padding: 8px 12px;
  border-radius: var(--radius);
  font-size: 12px;
  line-height: 1.4;
}
.modal-selection-warning > svg {
  flex-shrink: 0;
  color: #b8830c;
}
/* The .hidden override needs to win over the new `display: flex`. */
.modal-selection-warning.hidden { display: none; }
/* Inline loading + error states inside the Title section. Kept compact —
   no extra padding — so they slot in where the dashboard name would render
   instead of inflating the section to fixed-block size. */
.modal-card-loading {
  padding: 0;
  display: inline-flex;
  align-items: center;
  gap: 8px;
  color: var(--fg-3);
  font-size: 13px;
  line-height: 1.35;
}
.modal-card-error {
  padding: 0;
  color: var(--garnet-70);
  font-size: 13px;
  line-height: 1.35;
}
.modal-card-content.hidden,
.modal-card-error.hidden,
.modal-card-loading.hidden { display: none; }

/* Bordered validation alert — icon + message in a tinted box. Used for
   form-level errors (e.g. the schedule modal) where a bare line of red text
   reads as an afterthought. */
.modal-alert {
  display: flex;
  align-items: flex-start;
  gap: 8px;
  padding: 10px 12px;
  border: 1px solid var(--garnet-70);
  border-radius: 8px;
  background: rgba(160, 12, 31, 0.07);
  color: var(--garnet-70);
  font-size: 13px;
  line-height: 1.4;
}
.modal-alert.hidden { display: none; }
.modal-alert svg { flex-shrink: 0; margin-top: 1px; }
.modal-alert-text { min-width: 0; }

/* Background-picker modal */
.bg-picker-modal { background: #fff; }
/* Modal footer layout: "Apply to all body slides" toggle on the left, Cancel
   on the right. Uses .modal-actions's default justify-content: flex-end,
   overridden here to space the two ends apart. */
.bg-picker-actions {
  justify-content: space-between !important;
  align-items: center;
}
.bg-picker-apply-all {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  cursor: pointer;
  user-select: none;
  font-family: var(--font-sans);
  /* The label is the click target; the native checkbox lives inside it but
     is visually hidden via the sr-only pattern so only the custom box +
     text render. Without this, the browser-rendered checkbox shows up
     between the custom box and the label text, adding ~20px of dead gap. */
  position: relative;
}
.bg-picker-apply-all.hidden { display: none; }
.bg-picker-apply-all-input {
  position: absolute !important;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
  opacity: 0;
  pointer-events: none;
}
.bg-picker-apply-all-box {
  width: 18px;
  height: 18px;
  border: 1.5px solid var(--border-strong);
  border-radius: 4px;
  background: #fff;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  transition: background 0.15s, border-color 0.15s;
}
.bg-picker-apply-all-box > svg { opacity: 0; transition: opacity 0.15s; }
.bg-picker-apply-all-input:checked + .bg-picker-apply-all-box {
  background: var(--envoy-red);
  border-color: var(--envoy-red);
}
.bg-picker-apply-all-input:checked + .bg-picker-apply-all-box > svg { opacity: 1; }
.bg-picker-apply-all-input:focus-visible + .bg-picker-apply-all-box {
  outline: 2px solid rgba(250, 67, 56, 0.4);
  outline-offset: 2px;
}
.bg-picker-apply-all-text {
  font-size: 13px;
  font-weight: var(--fw-semibold);
  color: var(--fg-1);
}
/* No padding of its own: the header and actions carry the standard 28px
   sides, and the grid matches them, so everything lines up and the footer
   divider runs edge to edge like other modals. */
.bg-picker-modal-inner { padding: 0; }
.bg-picker-buttons { display: flex; gap: 10px; margin-left: auto; }
.bg-picker-loading {
  display: flex; align-items: center; justify-content: center;
  padding: 60px;
  color: var(--fg-3);
}
.bg-grid {
  display: grid; grid-template-columns: repeat(3, 1fr);
  gap: 12px;
  max-height: 55vh; overflow-y: auto;
  padding: 16px 28px 20px;
}
/* Each background thumbnail. The grid has uniform 16:9 cells regardless of
   the underlying image size, with the label sitting underneath in a clean
   caption. Without these rules the grid was rendering at the natural image
   sizes (mix of huge images + raw text for "Plain white"), spilling out of
   the modal horizontally. */
.bg-grid-item {
  display: flex;
  flex-direction: column;
  gap: 6px;
  cursor: pointer;
  background: transparent;
  border: 0;
  padding: 0;
  text-align: left;
  min-width: 0;
}
.bg-grid-item > img {
  display: block;
  width: 100%;
  aspect-ratio: 16 / 9;
  object-fit: cover;
  background: var(--arctic);
  border: 2px solid var(--border);
  border-radius: 8px;
  transition: border-color 0.15s;
}
/* Same as the site's other selectable cards: gray on hover, red when
   selected, no shadow or lift. */
.bg-grid-item:hover > img {
  border-color: var(--carbon-30);
}
.bg-grid-item-selected > img,
.bg-grid-item-selected:hover > img {
  border-color: var(--envoy-red);
}
/* Some entries (like "Plain white") have no <img> — they render just a
   labeled blank cell. Give the cell the same 16:9 footprint so the grid
   stays aligned. */
.bg-grid-item:not(:has(img)) {
  position: relative;
}
.bg-grid-item:not(:has(img))::before {
  content: "";
  display: block;
  width: 100%;
  aspect-ratio: 16 / 9;
  background: #fff;
  border: 2px dashed var(--border-strong);
  border-radius: 8px;
  transition: border-color 0.15s;
}
/* Same hover/selected as the image tiles; selected goes solid. */
.bg-grid-item:not(:has(img)):hover::before {
  border-color: var(--carbon-30);
}
.bg-grid-item-selected:not(:has(img))::before,
.bg-grid-item-selected:not(:has(img)):hover::before {
  border: 2px solid var(--envoy-red);
}
.bg-grid-item:not(:has(img))::after {
  content: attr(data-blank-label);
  position: absolute;
  inset: 0 0 28px 0;          /* leave room for the actual label below */
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 12px;
  font-weight: var(--fw-medium);
  color: var(--fg-3);
  pointer-events: none;
}
.bg-grid-label {
  /* Flush with the tile's outer edge, the label looks outdented past the
     rounded corner; a small inset lines it up with the tile's inside. */
  padding: 0 4px;
  font-size: 13px;
  font-weight: var(--fw-semibold);
  color: var(--fg-1);
  line-height: 1.3;
  overflow: hidden;
  text-overflow: ellipsis;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
}

/* ─── Custom background importer ────────────────────────────────────────── */
.custom-bg-modal-inner {
  padding: 24px 28px;
  max-width: 47.5rem;
  width: 90vw;
  max-height: 86vh;
  display: flex;
  flex-direction: column;
  gap: 0;
}
.custom-bg-url-row {
  display: flex;
  gap: 10px;
  margin-top: 16px;
}
.custom-bg-url-input {
  flex: 1;
  border: 1px solid var(--border-strong);
  border-radius: var(--radius);
  padding: 8px 12px;
  font-size: 14px;
  color: var(--fg-1);
  background: var(--surface-1);
  outline: none;
  min-width: 0;
}
.custom-bg-url-input:focus {
  border-color: var(--brand);
  box-shadow: 0 0 0 3px var(--brand-focus-ring, #e0e7ff);
}
.custom-bg-hint {
  margin-top: 10px;
  padding: 10px 14px;
  background: var(--surface-2, #f5f5f5);
  border-radius: var(--radius);
  font-size: 13px;
  color: var(--fg-2);
  line-height: 1.5;
}
.custom-bg-hint.hidden { display: none; }
.custom-bg-error {
  margin-top: 10px;
  padding: 10px 14px;
  background: #fff1f1;
  border-radius: var(--radius);
  font-size: 13px;
  color: #b91c1c;
}
.custom-bg-error.hidden { display: none; }
.custom-bg-slide-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(180px, 1fr));
  gap: 16px;
  overflow-y: auto;
  margin-top: 16px;
  padding-bottom: 4px;
  flex: 1;
  min-height: 0;
}
.custom-bg-slide-card {
  display: flex;
  flex-direction: column;
  gap: 8px;
}
.custom-bg-slide-card img {
  width: 100%;
  border-radius: var(--radius);
  border: 2px solid transparent;
  display: block;
}
.custom-bg-slide-label-row {
  display: flex;
  gap: 4px;
}
.custom-bg-type-btn {
  flex: 1;
  font-size: 11px;
  font-weight: var(--fw-semibold);
  padding: 4px 0;
  border-radius: var(--radius);
  border: 1.5px solid var(--border-strong);
  background: var(--surface-1);
  color: var(--fg-2);
  cursor: pointer;
  transition: background 0.12s, color 0.12s, border-color 0.12s;
  white-space: nowrap;
}
.custom-bg-type-btn:hover { background: var(--surface-2); }
.custom-bg-type-btn.active-title {
  background: var(--brand);
  color: #fff;
  border-color: var(--brand);
}
.custom-bg-type-btn.active-body {
  background: #0f766e;
  color: #fff;
  border-color: #0f766e;
}
.custom-bg-type-btn.active-ignore {
  background: var(--fg-3, #ccc);
  color: var(--surface-1);
  border-color: var(--fg-3, #ccc);
}
.custom-bg-slide-card[data-role="title"] img { border-color: var(--brand); }
.custom-bg-slide-card[data-role="body"] img { border-color: #0f766e; }
.custom-bg-slide-card[data-role="ignore"] { opacity: 0.45; }
.ghost-btn {
  background: none;
  border: none;
  padding: 6px 4px;
  font-size: 13px;
  color: var(--fg-2);
  cursor: pointer;
  text-decoration: underline;
  text-underline-offset: 2px;
}
.ghost-btn:hover { color: var(--fg-1); }

/* ─── Conflict modal ("Tabs already exist") ─────────────────────────────── */
.conflict-main-actions {
  display: flex;
  gap: 10px;
  padding: 16px 28px 4px;
}
.conflict-main-actions .primary-btn { flex: 1; width: auto; }
/* The advanced-options toggle is a secondary action — give it real button
   chrome so it matches the primary's height instead of looking like a tiny
   link button stuck next to a giant red bar. */
.conflict-advanced-toggle {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  background: #fff;
  border: 1px solid var(--border-strong);
  border-radius: var(--radius);
  padding: 12px 18px;
  font-family: var(--font-sans);
  color: var(--fg-1);
  font-size: 14px;
  font-weight: var(--fw-semibold);
  cursor: pointer;
  white-space: nowrap;
  transition: background 0.15s, border-color 0.15s, color 0.15s;
}
.conflict-advanced-toggle:hover {
  background: var(--arctic);
  border-color: var(--carbon-30);
}
.conflict-advanced-toggle > svg {
  transition: transform 0.2s;
}
/* Flip the chevron when the advanced panel is open. We rely on the panel
   being a sibling that's NOT `.hidden` to detect open state. */
.conflict-advanced-panel:not(.hidden) ~ * .conflict-advanced-toggle > svg,
.conflict-advanced-toggle[aria-expanded="true"] > svg { transform: rotate(180deg); }
.conflict-advanced-panel.hidden { display: none; }
.conflict-advanced-panel {
  padding: 14px 28px 4px;
}

/* "1 of N selected · Select all" row at the top of the advanced panel. */
.conflict-select-all-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 0 0 12px;
  font-size: 12px;
  color: var(--fg-2);
}
.conflict-selected-count {
  font-size: 12px;
  font-weight: var(--fw-medium);
  color: var(--fg-3);
}
/* The select-all label uses the same chip+box pattern as the main tile picker
   but inverted (label on left, box on right) inside this modal. */
.conflict-select-all-row .tile-select-all-label {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  font-size: 13px;
  font-weight: var(--fw-semibold);
  color: var(--fg-1);
  cursor: pointer;
  user-select: none;
}
.conflict-select-all-row .tile-select-all-check {
  position: relative;
  width: 18px;
  height: 18px;
  border: 1.5px solid var(--border-strong);
  border-radius: 4px;
  background: #fff;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  transition: background 0.15s, border-color 0.15s;
}
.conflict-select-all-row .tile-select-all-check .tile-check-icon {
  opacity: 0;
  transition: opacity 0.15s;
}
.conflict-select-all-row .tile-select-all-check.all-selected,
.conflict-select-all-row .tile-select-all-check.partial {
  background: var(--envoy-red);
  border-color: var(--envoy-red);
}
.conflict-select-all-row .tile-select-all-check.all-selected .tile-check-icon { opacity: 1; }
.conflict-select-all-row .tile-select-all-check.partial::after {
  content: "";
  position: absolute;
  inset: 50% 3px auto 3px;
  height: 2px;
  background: #fff;
  border-radius: 1px;
  transform: translateY(-50%);
}

/* Tab-list rows. Each is a card with a checkbox on the left, the tab name
   middle, and a rename input on the right. Bare HTML was producing a stack
   of unstyled rows; this gives proper grouping + alignment. */
.conflict-tab-list {
  list-style: none;
  margin: 0;
  padding: 0 0 4px;
  display: flex;
  flex-direction: column;
  gap: 8px;
  max-height: 40vh;
  overflow-y: auto;
}
.conflict-tab-item {
  display: grid;
  grid-template-columns: 22px 1fr minmax(8.75rem, 30%);
  align-items: center;
  gap: 12px;
  padding: 10px 14px;
  background: #fff;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  transition: border-color 0.15s, background 0.15s;
}
.conflict-tab-item.selected {
  border-color: rgba(250, 67, 56, 0.3);
  background: rgba(250, 67, 56, 0.02);
}
.conflict-tab-item:hover { border-color: var(--carbon-30); }

/* Per-row checkbox. Shares the .tile-card-check class with chart tile
   cards, which sets `position: absolute; top: 12px; right: 12px` so the
   check sits in the corner of those cards. In the conflict modal it lives
   inside a grid cell, so we have to explicitly cancel those offsets,
   otherwise the box gets shifted down-and-left out of the card. */
.conflict-tab-checkbox {
  position: static;
  top: auto;
  right: auto;
  bottom: auto;
  left: auto;
  width: 18px;
  height: 18px;
  border: 1.5px solid var(--border-strong);
  border-radius: 4px;
  background: #fff;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  cursor: pointer;
  transition: background 0.15s, border-color 0.15s;
}
.conflict-tab-checkbox > svg { opacity: 0; transition: opacity 0.15s; }
.conflict-tab-item.selected .conflict-tab-checkbox {
  background: var(--envoy-red);
  border-color: var(--envoy-red);
}
.conflict-tab-item.selected .conflict-tab-checkbox > svg { opacity: 1; }

.conflict-tab-name {
  font-size: 13px;
  font-weight: var(--fw-semibold);
  color: var(--fg-1);
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.conflict-tab-newname {
  width: 100%;
  font-family: var(--font-sans);
  font-size: 12px;
  color: var(--fg-1);
  background: #fff;
  border: 1px solid var(--border);
  border-radius: 6px;
  padding: 6px 10px;
  transition: border-color 0.15s, box-shadow 0.15s;
}
.conflict-tab-newname::placeholder { color: var(--fg-3); }
.conflict-tab-newname:focus {
  outline: none;
  border-color: var(--envoy-red);
  box-shadow: 0 0 0 3px rgba(250, 67, 56, 0.1);
}

@media (max-width: 560px) {
  .conflict-tab-item { grid-template-columns: 22px 1fr; }
  .conflict-tab-newname { grid-column: 2 / -1; }
}

/* ============================================================
   Saved / Settings / How-to / Templates screens
   (Not in the new design — kept on-brand with token-based styling)
   ============================================================ */
#screen-saved,
#screen-schedules,
#screen-activity,
#screen-dashboards,
#screen-slate,
#screen-settings,
#screen-html,
#screen-templates {
  padding: 40px 56px 56px;
  background: var(--arctic);
}
#screen-saved.hidden,
#screen-schedules.hidden,
#screen-activity.hidden,
#screen-dashboards.hidden,
#screen-slate.hidden,
#screen-settings.hidden,
#screen-html.hidden,
#screen-templates.hidden { display: none; }

/* ─── Settings screen ─────────────────────────────────────────────────────
   None of these classes had any CSS, so the page was rendering with raw
   browser defaults: label and value were inline siblings with no separator,
   producing "Emailcharisse.hao@envoy.com". Now structured as a card-based
   settings layout. */
.settings-header {
  max-width: var(--content-max);
  margin-bottom: 28px;
}
.settings-title {
  font-size: 28px;
  font-weight: var(--fw-bold);
  color: var(--fg-1);
  margin: 0 0 6px;
  letter-spacing: -0.02em;
}
.settings-subtitle {
  font-size: 15px;
  color: var(--fg-3);
  margin: 0;
  line-height: 1.5;
}
.settings-section {
  max-width: var(--content-max);
  margin-bottom: 28px;
}
.settings-section-title {
  font-size: 12px;
  font-weight: var(--fw-bold);
  color: var(--fg-2);
  text-transform: uppercase;
  letter-spacing: 0.08em;
  margin: 0 0 10px;
}
.settings-card {
  background: #fff;
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  overflow: hidden;
}
/* Account tab cards match the schedule cards. (The Access Control tab reuses
   .settings-card for its own boxes, so this is scoped.) */
#settings-pane-account .settings-card {
  max-width: var(--content-max);
  border-color: #E4E5EB;
  box-shadow: 0 1px 3px rgba(15, 23, 42, 0.06);
  margin-bottom: 16px;
}
/* Space between the page header and its content. */
#screen-settings .settings-header { margin-bottom: 20px; }
.settings-pane.hidden { display: none; }

/* Settings tabs: Account · Access Control · Connections · How To */
.settings-tabs { display: flex; gap: 4px; border-bottom: 1px solid var(--border); margin: -4px 0 24px; max-width: var(--content-max); overflow-x: auto; }
.settings-tab { position: relative; padding: 10px 14px; font-size: 14px; font-weight: 500; color: var(--fg-3); text-decoration: none; white-space: nowrap; border-radius: var(--radius-sm) var(--radius-sm) 0 0; }
.settings-tab:hover { color: var(--fg-1); background: var(--arctic); }
.settings-tab.active { color: var(--fg-1); font-weight: 600; }
.settings-tab.active::after { content: ''; position: absolute; left: 10px; right: 10px; bottom: -1px; height: 2px; border-radius: 2px; background: var(--envoy-red, #fa4338); }
.settings-tab.hidden { display: none; }

/* How To tab: one dropdown per page (native <details>). */
.howto-acc {
  max-width: var(--content-max);
  background: #fff;
  border: 1px solid #E4E5EB;
  border-radius: var(--radius-md);
  box-shadow: 0 1px 3px rgba(15, 23, 42, 0.06);
  margin-bottom: 12px;
  scroll-margin-top: 24px;
}
.howto-acc-head {
  display: flex; align-items: center; gap: 14px;
  padding: 16px 20px;
  cursor: pointer;
  list-style: none;
  border-radius: var(--radius-md);
}
.howto-acc-head::-webkit-details-marker { display: none; }
.howto-acc-head:hover { background: var(--arctic); }
.howto-acc-head:focus { outline: none; }
.howto-acc-head:focus-visible { outline: 2px solid rgba(250, 67, 56, 0.35); outline-offset: -2px; }
.howto-acc[open] > .howto-acc-head { border-bottom: 1px solid var(--border); border-radius: var(--radius-md) var(--radius-md) 0 0; }
.howto-acc-icon {
  width: 36px; height: 36px; border-radius: 8px; flex-shrink: 0;
  display: grid; place-items: center;
  color: var(--envoy-red); background: rgba(250, 67, 56, 0.08);
}
.howto-acc-text { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.howto-acc-title { font-size: 15px; font-weight: var(--fw-semibold); color: var(--fg-1); }
.howto-acc-desc { font-size: 13px; color: var(--fg-3); }
.howto-acc-chev { flex-shrink: 0; color: var(--fg-3); transition: transform 0.3s cubic-bezier(0.4, 0, 0.2, 1); }
.howto-acc[open]:not(.is-closing) .howto-acc-chev { transform: rotate(180deg); }
.howto-acc-body { padding: 24px 20px 4px; }
@media (prefers-reduced-motion: reduce) { .howto-acc-chev { transition: none; } }
/* People | Roles & Permissions, a pill toggle so it doesn't read as a second
   row of tabs under Account | Access Control. */
.access-seg { margin-bottom: 20px; }

/* Profile card: avatar, name + role, email, Sign out. */
.settings-profile { display: flex; align-items: center; gap: 16px; padding: 20px 22px; }
.settings-avatar {
  width: 48px; height: 48px; border-radius: 50%; flex-shrink: 0; overflow: hidden;
  background: #0f9b8e; color: #fff; display: grid; place-items: center; font-size: 20px; font-weight: var(--fw-semibold);
}
.settings-avatar img { width: 100%; height: 100%; object-fit: cover; display: block; }
.settings-profile-text { min-width: 0; }
.settings-name { display: flex; align-items: center; gap: 8px; font-size: 17px; font-weight: var(--fw-semibold); color: var(--fg-1); }
.settings-role {
  font-size: 11px; font-weight: var(--fw-semibold); letter-spacing: 0.04em; text-transform: uppercase;
  color: var(--envoy-red); background: rgba(250, 67, 56, 0.08); border-radius: 999px; padding: 2px 8px;
}
.settings-role.hidden { display: none; }
.settings-email { font-size: 14px; color: var(--fg-3); margin-top: 2px; overflow-wrap: anywhere; }
.settings-profile #settings-sign-out-btn { width: auto; margin-left: auto; flex-shrink: 0; }
/* Connected services card. */
.settings-card-head { padding: 14px 22px; border-bottom: 1px solid #EEEEF2; font-size: 15px; font-weight: var(--fw-semibold); color: var(--fg-1); }
.settings-service { display: flex; align-items: center; gap: 16px; padding: 18px 22px; }
.settings-service-icon { width: 40px; height: 40px; border-radius: 10px; background: #e8f5ee; display: grid; place-items: center; flex-shrink: 0; }
.settings-service-text { min-width: 0; }
.settings-service-title { font-size: 15px; font-weight: var(--fw-semibold); color: var(--fg-1); }
.settings-service-desc { font-size: 13px; color: var(--fg-3); margin-top: 2px; line-height: 1.45; }
.settings-service-copy { display: flex; align-items: center; gap: 8px; margin-left: auto; flex-shrink: 0; }
.settings-service-copy .secondary-btn { width: auto; min-width: 64px; }
@media (max-width: 900px) {
  .settings-service { flex-wrap: wrap; }
  .settings-service-copy { margin-left: 56px; flex-shrink: 1; min-width: 0; }
  .settings-service-copy .settings-code { overflow: hidden; text-overflow: ellipsis; min-width: 0; }
}
.settings-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  padding: 14px 18px;
  border-bottom: 1px solid var(--border);
}
.settings-row:last-child { border-bottom: 0; }
.settings-row-info {
  display: flex;
  flex-direction: column;
  gap: 2px;
  min-width: 0;
}
.settings-label {
  font-size: 14px;
  font-weight: var(--fw-semibold);
  color: var(--fg-1);
}
.settings-row-hint {
  font-size: 12px;
  color: var(--fg-3);
  line-height: 1.4;
}
.settings-value {
  font-size: 14px;
  color: var(--fg-2);
  text-align: right;
  font-weight: var(--fw-medium);
}
.settings-code {
  font-family: var(--font-mono);
  font-size: 12px;
  color: var(--fg-1);
  background: var(--arctic);
  border: 1px solid var(--border);
  border-radius: 6px;
  padding: 6px 10px;
  user-select: all;
  white-space: nowrap;
}

/* ─── Folders (inside Saved screen) ─────────────────────────────────────────── */
.saved-layout {
  display: flex;
  align-items: stretch;
  background: #fff;
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  overflow: hidden;
  height: calc(100vh - 280px);
  min-height: 50vh;
  width: 100%;
}
.folders-sidebar {
  flex-shrink: 0;
  width: clamp(10rem, 18%, 15rem);
  border-right: 1px solid var(--border);
  padding: 8px;
  display: flex;
  flex-direction: column;
}
/* Top-level nav (My Configs / Shared with me) */
.folders-sidebar .sidebar-nav {
  padding: 10px 8px 4px;
  display: flex;
  flex-direction: column;
  gap: 1px;
}
.folders-sidebar .sidebar-nav-item {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 0 14px;
  height: 36px;
  line-height: 36px;
  font-size: 13px;
  font-weight: var(--fw-medium);
  color: var(--fg-1);
  cursor: pointer;
  border-radius: 99px;
  box-sizing: border-box;
  user-select: none;
  transition: none;
}
.folders-sidebar .sidebar-nav-item svg { flex-shrink: 0; color: var(--fg-3); }
.folders-sidebar .sidebar-nav-item:hover { background: var(--bg-2); }
.folders-sidebar .sidebar-nav-item:focus,
.folders-sidebar .sidebar-nav-item:active,
.folders-sidebar .sidebar-nav-item:focus-visible { outline: none; }
.folders-sidebar .sidebar-nav-item.active { background: var(--accent-soft, #fff0ee); color: var(--accent); font-weight: var(--fw-medium); }
.folders-sidebar .sidebar-nav-item.active svg { color: var(--accent); }

.folders-sidebar-new-folder {
  padding: 8px;
  border-top: 1px solid var(--border);
}
.folders-new-folder-btn {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  width: 100%;
  padding: 0 14px;
  height: 32px;
  font-size: 12px;
  font-weight: var(--fw-medium);
  color: var(--envoy-red);
  background: none;
  border: 1.5px solid var(--envoy-red);
  border-radius: 99px;
  cursor: pointer;
  box-sizing: border-box;
}
.folders-new-folder-btn:hover {
  background: rgba(250, 67, 56, 0.06);
}

.sidebar-divider {
  height: 1px;
  background: var(--border);
  margin: 8px 14px;
}

.folders-sidebar-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 8px 14px 6px;
}
.folders-sidebar-title {
  font-size: 12px;
  font-weight: var(--fw-bold);
  color: var(--fg-2);
  letter-spacing: 0;
}
.folders-new-btn {
  background: none;
  border: none;
  cursor: pointer;
  color: var(--fg-3);
  padding: 4px;
  display: flex;
  align-items: center;
  border-radius: 6px;
  transition: color 0.15s, background 0.15s;
}
.folders-new-btn:hover { color: var(--fg-1); background: var(--bg-2); }
.folders-list { display: flex; flex-direction: column; gap: 1px; padding: 4px 8px; }
.folder-item {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 0 10px 0 14px;
  height: 36px;
  font-size: 13px;
  font-weight: var(--fw-medium);
  color: var(--fg-1);
  cursor: pointer;
  border-radius: 99px;
  background: none;
  width: 100%;
  text-align: left;
  position: relative;
  box-sizing: border-box;
}
.folder-item:hover { background: var(--bg-2); }
.folder-item.active { background: var(--accent-soft, #fff0ee); color: var(--accent); }
.folder-item-icon { flex-shrink: 0; color: var(--fg-3); }
.folder-item.active .folder-item-icon { color: var(--accent); }
.folder-item-name { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.folder-item-count { display: none; }
.folder-item-more {
  flex-shrink: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 24px;
  height: 24px;
  border-radius: 6px;
  border: none;
  background: none;
  color: var(--fg-3);
  cursor: pointer;
  opacity: 0;
  padding: 0;
}
.folder-item:hover .folder-item-more { opacity: 1; }
.folder-item-more:hover { background: var(--border); color: var(--fg-1); }
.folder-share-badge {
  font-size: 10px;
  background: var(--accent-soft, #fff0ee);
  color: var(--accent);
  border-radius: 99px;
  padding: 1px 5px;
  font-weight: var(--fw-medium);
}
.folders-content { flex: 1; min-width: 0; padding: 16px; overflow-y: auto; }
.folders-content.is-switching { opacity: 0; transition: opacity 0.15s ease; }
.folders-content.is-visible { opacity: 1; transition: opacity 0.15s ease; }

/* Share folder modal */
.folder-share-modal-backdrop {
  position: fixed;
  inset: 0;
  background: rgba(0,0,0,0.3);
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 1000;
}
.folder-share-modal {
  background: #fff;
  border-radius: var(--radius-md);
  padding: 24px;
  width: min(26.25rem, 90vw);
  box-shadow: 0 8px 32px rgba(0,0,0,0.12);
}
.folder-share-modal h3 { margin: 0 0 16px; font-size: 16px; font-weight: var(--fw-bold); }
.folder-share-toggle {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 12px 14px;
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  margin-bottom: 16px;
  cursor: pointer;
  user-select: none;
}
.folder-share-toggle input[type="checkbox"] { width: 16px; height: 16px; accent-color: var(--accent); cursor: pointer; }
.folder-share-toggle-label { font-size: 14px; font-weight: var(--fw-medium); color: var(--fg-1); }
.folder-share-toggle-desc { font-size: 12px; color: var(--fg-3); margin-top: 1px; }
/* Share Deck Preset, laid out like Google Drive's: People with Access, then
   General Access (Restricted or Everyone at Envoy) with a round icon, the
   choice as a text dropdown, a line under it, and everyone's access on the
   right. */
.cshare-section-title { margin: 14px 0 6px; font-size: 13px; font-weight: var(--fw-semibold); color: var(--fg-1); }
.cshare-general { display: flex; align-items: center; gap: 12px; padding: 4px 0 2px; }
.cshare-general-icon {
  width: 34px; height: 34px; border-radius: 50%; flex-shrink: 0;
  display: flex; align-items: center; justify-content: center;
  background: var(--bg-2); color: var(--fg-2);
}
.cshare-general-main { flex: 1; min-width: 0; display: flex; flex-direction: column; align-items: flex-start; gap: 1px; }
.cshare-general-sel {
  appearance: none; -webkit-appearance: none;
  border: 0; border-radius: 6px; background-color: transparent; cursor: pointer;
  font: inherit; font-size: 14px; font-weight: var(--fw-semibold); color: var(--fg-1);
  padding: 2px 22px 2px 4px; margin-left: -4px;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 24 24' fill='%231F232D'%3E%3Cpath d='M6 9h12l-6 7z'/%3E%3C/svg%3E");
  background-repeat: no-repeat; background-position: right 4px center;
}
.cshare-general-sel:hover:not(:disabled) { background-color: var(--arctic); }
.cshare-general-sel:focus-visible { outline: none; background-color: var(--arctic); } /* as on hover, not a ring */
.cshare-general-sel:disabled { cursor: default; background-image: none; padding-right: 4px; }
.cshare-general-desc { font-size: 12px; color: var(--fg-3); }
.cshare-perm-sel:disabled { opacity: 0.5; cursor: default; }
.folder-share-emails-label { font-size: 12px; font-weight: var(--fw-medium); color: var(--fg-2); margin-bottom: 6px; }
.folder-share-emails-input {
  width: 100%;
  box-sizing: border-box;
  border: 1px solid var(--border);
  border-radius: 6px;
  padding: 8px 10px;
  font-size: 13px;
  color: var(--fg-1);
  resize: vertical;
  min-height: 72px;
  font-family: inherit;
}
.folder-share-emails-hint { font-size: 11px; color: var(--fg-3); margin-top: 4px; }
.folder-share-modal-actions { display: flex; gap: 8px; justify-content: flex-end; margin-top: 20px; }

/* Config share modal — people list variant */
.config-share-modal { min-width: min(30.5rem, 90vw); } /* room for General Access's line beside its picker */
.cshare-add-row { display: flex; gap: 8px; margin: 14px 0 10px; }
.cshare-add-row input { flex: 1; padding: 8px 10px; border: 1px solid var(--border); border-radius: 8px; font-size: 13px; background: var(--bg-1, #fff); color: var(--fg-1); outline: none; }
.cshare-add-row input:focus { border-color: var(--envoy-red, #e63946); }
.cshare-empty { font-size: 13px; color: var(--fg-3); margin: 4px 0 0; }
.cshare-person-row { display: flex; align-items: center; gap: 10px; padding: 8px 0; border-bottom: 1px solid var(--border); }
.cshare-person-row:last-child { border-bottom: none; }
.cshare-avatar { width: 30px; height: 30px; border-radius: 50%; background: var(--envoy-red-tint, #fdecea); display: flex; align-items: center; justify-content: center; font-size: 11px; font-weight: 600; color: var(--envoy-red, #e63946); flex-shrink: 0; }
.cshare-person-email { flex: 1; font-size: 13px; color: var(--fg-1); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; min-width: 0; }
.cshare-perm-sel { font-family: inherit; /* dropdowns don't inherit the page font by default */ font-size: 12px; color: var(--fg-2); background: var(--bg-2); border: 1px solid var(--border); border-radius: 6px; padding: 4px 6px; cursor: pointer; flex-shrink: 0; outline: none; }
/* The access picker beside Add: the rows' picker, as tall as the email box. */
.cshare-add-row .cshare-perm-sel { align-self: stretch; padding: 0 8px; }
.cshare-remove-btn { background: none; border: none; cursor: pointer; color: var(--fg-3); padding: 2px; display: flex; align-items: center; flex-shrink: 0; border-radius: 4px; }
.cshare-remove-btn:hover { color: var(--envoy-red); } /* just turns red, like the slide list's × */

/* ─── Saved configurations screen ─────────────────────────────────────────── */
.saved-header {
  max-width: var(--content-max);
  margin-bottom: 24px;
}
.saved-header-row {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 24px;
}
.saved-header-row > div:first-child { min-width: 0; flex: 1; }
.saved-title {
  font-size: 28px;
  font-weight: var(--fw-bold);
  color: var(--fg-1);
  margin: 0 0 6px;
  letter-spacing: -0.02em;
}
.saved-subtitle {
  font-size: 15px;
  color: var(--fg-3);
  margin: 0;
  line-height: 1.5;
  max-width: var(--content-max);
}
.saved-header-row .primary-btn {
  /* .primary-btn is `width: 100%` by default for the main CTAs; in the saved
     header it should hug its label and sit beside the title, not eat the row. */
  width: auto;
  flex-shrink: 0;
  white-space: nowrap;
  align-self: flex-start;
}

#saved-list,
#schedules-list {
  display: block;
  max-width: var(--content-max);
}
.content-folders-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 10px;
  margin-bottom: 20px;
}
.content-folder-card {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 10px 12px;
  background: #fff;
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  cursor: pointer;
  font-size: 13px;
  font-weight: var(--fw-medium);
  color: var(--fg-1);
  position: relative;
}
.content-folder-card:hover { background: var(--bg-2); }
.content-folder-name { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.content-folder-more {
  flex-shrink: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 24px;
  height: 24px;
  border-radius: 6px;
  border: none;
  background: none;
  color: var(--fg-3);
  cursor: pointer;
  opacity: 0;
  padding: 0;
}
.content-folder-card:hover .content-folder-more { opacity: 1; }
.content-folder-more:hover { background: var(--border); color: var(--fg-1); }
.saved-cards-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 14px;
  align-items: start;
}
#saved-list .saved-card,
#schedules-list .saved-card {
  position: relative;
  background: #fff;
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  padding: 18px;
  display: flex;
  flex-direction: column;
  gap: 16px;
  min-width: 0;
  transition: border-color 0.15s, box-shadow 0.15s;
}
#saved-list .saved-card:hover,
#schedules-list .saved-card:hover {
  border-color: var(--border-strong, #d4d4d8);
  box-shadow: var(--shadow-sm, 0 1px 3px rgba(0, 0, 0, 0.05));
}
.saved-card-body {
  display: flex;
  gap: 12px;
  min-width: 0;
  flex: 1;
}
.saved-card-icon {
  width: 32px;
  height: 32px;
  border-radius: 8px;
  background: rgba(78, 78, 218, 0.08);
  color: var(--gem-60, #4e4eda);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
}
.saved-card-text {
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 5px;
}
.saved-card-name-row {
  display: flex;
  align-items: center;
  gap: 6px;
  min-width: 0;
  margin-bottom: 2px;
}
.saved-rename-btn {
  flex-shrink: 0;
  display: none;
  background: none;
  border: none;
  padding: 2px;
  cursor: pointer;
  color: var(--fg-3);
  line-height: 1;
  border-radius: 4px;
}
.saved-rename-btn:hover { color: var(--fg-1); background: var(--bg-2); }
.saved-card-name-row:hover .saved-rename-btn { display: flex; }
.saved-name-input {
  font-size: 14px;
  font-weight: var(--fw-semibold);
  color: var(--fg-1);
  border: 1px solid var(--accent);
  border-radius: 4px;
  padding: 1px 6px;
  width: 100%;
  background: var(--bg-1);
  outline: none;
}

/* ─── Deck Presets list: Name, Owner, Date Modified, then a ⋮ menu ────────── */
/* The page fits the window like Recent Activity: the header, search, filter
   and pager stay put and only the rows scroll. Below ~560px tall the page
   scrolls instead of squeezing the table to nothing. */
#screen-saved:not(.hidden) {
  display: flex; flex-direction: column;
  height: 100vh; min-height: 560px; box-sizing: border-box;
  padding-bottom: 20px;
}
#screen-saved .saved-header { margin-bottom: 12px; }
/* One preset's page (?flow=saved&preset=…): an ordinary scrolling page like a
   schedule's, so the list's fit-the-window layout is switched off. */
#screen-saved.is-detail:not(.hidden) { display: block; height: auto; min-height: 0; padding-bottom: 56px; }
#screen-saved.is-detail > :not(#preset-detail-view) { display: none !important; }
/* Grouped close together (the schedule header's 20px suits its switch, not three buttons). */
#preset-detail-view .preset-detail-actions { gap: 8px; }
/* The red button has no border and the others a 1px one; match their 30px height. */
#preset-detail-generate { border: 1px solid transparent; }
.preset-detail-btn { display: inline-flex; align-items: center; gap: 6px; width: auto; flex-shrink: 0; line-height: 1; }
.preset-detail-btn svg { width: 14px; height: 14px; }
.preset-slides-line { display: flex; align-items: baseline; gap: 6px; flex-wrap: wrap; margin: 0; }
.preset-slides-line b { font-weight: var(--fw-semibold, 600); color: var(--fg-1); }
/* "Default Filters ⓘ", then one field per filter, spaced like the form above. */
/* Default Filters come second to Name and Dashboard URL: a line above, a
   small grey heading (like "Your Slides") and lighter labels. */
.preset-filters-block { border-top: 1px solid #EEEEF2; padding-top: 16px; margin-top: 6px; }
.preset-filters-title {
  display: flex; align-items: center; gap: 6px; margin: 0;
  font-size: 11px; font-weight: var(--fw-semibold); letter-spacing: 0.06em;
  text-transform: uppercase; color: var(--fg-3);
}
.preset-filters-title .preset-filters-info svg { width: 13px; height: 13px; }
/* Default filters as chips ("Segment: Enterprise"), wrapping onto more lines
   as there are more; each opens a popover to change its value. */
.preset-filter-chip {
  display: inline-flex; align-items: center; gap: 4px; max-width: 100%;
  height: 28px; padding: 0 11px; border: 1px solid var(--border); border-radius: 999px;
  background: #fff; font-size: 13px; color: var(--fg-1); cursor: pointer;
  transition: border-color 0.15s, background 0.15s;
}
.preset-filter-chip:hover, .preset-filter-chip.is-open { border-color: var(--envoy-red); }
.preset-filter-chip:focus { outline: none; }
.preset-filter-chip:focus-visible { border-color: var(--envoy-red); box-shadow: 0 0 0 3px rgba(250, 67, 56, 0.12); }
.preset-filter-chip-label { color: var(--fg-3); white-space: nowrap; }
.preset-filter-chip-value { font-weight: var(--fw-semibold); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; min-width: 0; }
.preset-filter-chip-value.is-empty { font-weight: 400; color: var(--fg-3); }
.preset-filter-pop {
  position: fixed; z-index: 1000; width: 260px; padding: 12px;
  background: #fff; border: 1px solid #E4E5EB; border-radius: 8px;
  box-shadow: 0 8px 24px rgba(15, 23, 42, 0.12), 0 2px 6px rgba(15, 23, 42, 0.08);
  display: flex; flex-direction: column; gap: 10px;
}
.preset-filter-pop-label { display: flex; flex-direction: column; gap: 5px; font-size: 12px; font-weight: 500; color: var(--fg-2); }
.preset-filter-pop-actions { display: flex; justify-content: flex-end; gap: 8px; }
.preset-filter-pop-actions button { width: auto; padding: 6px 14px; font-size: 13px; }
.preset-filters-info { display: inline-flex; color: var(--fg-3); cursor: help; border-radius: 50%; }
.preset-filters-info:hover, .preset-filters-info:focus-visible { color: var(--fg-1); outline: none; }
.preset-filters { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 10px; }
.preset-form-error { margin: 4px 0 0; font-size: 13px; color: var(--envoy-red); }
.preset-form-actions { display: flex; justify-content: flex-end; gap: 10px; margin-top: 18px; }
.preset-form-actions button { width: auto; }
.preset-activity-list { margin: 4px -8px 0; min-height: 0; }
/* Activity rows don't link anywhere: no slide or red time on hover (Home's
   list style). Shares open to their changes, so those get a quiet hover. */
.preset-activity-row { cursor: default; align-items: flex-start; }
.preset-activity-row:hover { background: none; transform: none; }
.preset-activity-row:hover .home-list-time { color: var(--fg-3); }
.preset-activity-row--opens { cursor: pointer; }
.preset-activity-row--opens:hover { background: var(--arctic); }
.preset-activity-row--opens:focus { outline: none; }
.preset-activity-row--opens:focus-visible:not([data-mouse]) { outline: 2px solid rgba(250, 67, 56, 0.35); outline-offset: -2px; }
.preset-activity-row .home-list-time { display: inline-flex; align-items: center; gap: 4px; }
.preset-activity-chevron { color: var(--fg-3); transition: transform 0.2s ease; }
.preset-activity-row--opens[aria-expanded="true"] .preset-activity-chevron { transform: rotate(180deg); }
/* Two columns: who, then what changed for them. */
.preset-activity-changes { display: grid; grid-template-columns: minmax(0, max-content) minmax(0, 1fr); column-gap: 24px; row-gap: 4px; margin-top: 8px; font-size: 12px; }
/* A share's changes slide open and shut: the row grows from 0 to its
   content's height while the list fades in, as Recent Activity's rows do. */
.preset-activity-expand { display: grid; grid-template-rows: 0fr; transition: grid-template-rows 0.22s cubic-bezier(0.2, 0.7, 0.2, 1); }
.preset-activity-expand.is-open { grid-template-rows: 1fr; }
.preset-activity-expand-inner { min-height: 0; overflow: hidden; }
.preset-activity-expand .preset-activity-changes { opacity: 0; transition: opacity 0.18s ease; }
.preset-activity-expand.is-open .preset-activity-changes { opacity: 1; transition-delay: 0.04s; }
@media (prefers-reduced-motion: reduce) {
  .preset-activity-expand, .preset-activity-expand .preset-activity-changes { transition: none; }
}
.preset-activity-who { min-width: 0; color: var(--fg-1); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.preset-activity-what { color: var(--fg-3); white-space: nowrap; }
.preset-activity-empty { margin: 16px 0 0; font-size: 13px; line-height: 1.5; color: var(--fg-3); }
/* Details' dashboard link: its name on one line, cut off with … when it
   doesn't fit (the whole name is its tooltip). */
.preset-dash-link { display: inline-flex; gap: 4px; max-width: 100%; min-width: 0; vertical-align: bottom; }
.preset-dash-name { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* A wider Details column than a schedule's (240px), so most dashboard names
   fit on their one line. Stacks under 900px like the schedule page. */
#preset-detail-view .sch-detail-body { grid-template-columns: minmax(0, 1fr) 360px; }
@media (max-width: 900px) { #preset-detail-view .sch-detail-body { grid-template-columns: minmax(0, 1fr); } }
/* Details' Sharing: "3 people ▾" opens who it's shared with under the row,
   sliding open like Generate Deck's link boxes. */
.preset-share-toggle {
  display: inline-flex; align-items: center; gap: 4px; padding: 0; border: 0; background: none;
  font: inherit; color: var(--fg-1); cursor: pointer;
}
.preset-share-toggle svg { color: var(--fg-3); transition: transform 0.2s ease; }
.preset-share-toggle[aria-expanded="true"] svg { transform: rotate(180deg); }
.preset-share-toggle:hover svg { color: var(--fg-1); }
.preset-share-toggle:focus { outline: none; }
.preset-share-toggle:focus-visible { outline: 2px solid rgba(250, 67, 56, 0.35); outline-offset: 2px; border-radius: 3px; }
.preset-share-list { display: grid; grid-template-rows: 0fr; transition: grid-template-rows 0.25s cubic-bezier(0.4, 0, 0.2, 1); }
.preset-share-list.is-open { grid-template-rows: 1fr; }
/* The space under the list is inside the part that slides, so it opens and
   closes with it instead of snapping. */
.preset-share-inner { min-height: 0; overflow: hidden; }
.preset-share-body { display: flex; flex-direction: column; gap: 6px; padding: 0 0 12px; }
.preset-share-person { display: flex; justify-content: space-between; gap: 12px; font-size: 13px; line-height: 1.35; }
.preset-share-email { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; color: var(--fg-1); }
.preset-share-role { flex-shrink: 0; color: var(--fg-3); }
.preset-share-foot { margin: 2px 0 0; font-size: 12px; color: var(--fg-3); }
.preset-share-manage { padding: 0; border: 0; background: none; font: inherit; font-weight: var(--fw-semibold, 600); color: var(--envoy-red); cursor: pointer; }
.preset-share-manage:hover { text-decoration: underline; }
/* The owner's row: locked, with a padlock. */
.preset-share-owner { display: inline-flex; align-items: center; gap: 4px; }
/* The role on people the owner or an editor can change: quiet text that
   opens their menu (app.js _openSharePersonMenu). */
.preset-share-person { align-items: center; }
.preset-share-role-btn {
  display: inline-flex; align-items: center; gap: 2px; flex-shrink: 0; padding: 0; border: 0; background: none;
  font: inherit; color: var(--fg-3); cursor: pointer; white-space: nowrap;
}
.preset-share-role-btn svg { width: 12px; height: 12px; }
.preset-share-role-btn:hover, .preset-share-role-btn[aria-expanded="true"] { color: var(--fg-1); }
.preset-share-role-btn:focus { outline: none; }
.preset-share-role-btn:focus-visible { outline: 2px solid rgba(250, 67, 56, 0.35); outline-offset: 2px; border-radius: 3px; }
/* Its menu: the presets' ⋮ menu, with room for the ✓ and Remove access in red. */
.share-person-menu-gap { width: 14px; flex-shrink: 0; }
.share-person-menu .preset-menu-item.is-danger,
.share-person-menu .preset-menu-item.is-danger > svg { color: var(--envoy-red); }
/* Not shared yet: just "+ Add people" under the row. */
.preset-share-add-only { margin: 0; padding: 0 0 12px; font-size: 12px; text-align: right; }
@media (prefers-reduced-motion: reduce) { .preset-share-list, .preset-share-toggle svg { transition: none; } }
/* The slide builder in the Slides tab: the tab is its card, and the page
   already shows the name, so its own heading and name field are hidden. */
#preset-slides-host #panel-customize { padding: 6px 0 0; }
#preset-slides-host .customize-header,
#preset-slides-host #slide-name-group { display: none !important; }
#screen-saved #saved-list { flex: 0 1 auto; min-height: 0; display: flex; flex-direction: column; }
/* Toolbar: the count and Canvas's search box on the left, the filter on the
   right, so the two controls sit apart instead of side by side. The search
   box is slim (32px, like GitHub's or Linear's list search), its text and
   icon centred on the count. */
#screen-saved .saved-toolbar-left { display: flex; align-items: center; gap: 16px; min-width: 0; }
/* Optical centring: the boxes share a centre line, and these nudges put the
   letters on it too (measured by the middle of the capital letters). This font
   draws the bold count ~1px low and an input's text ~1.3px high. */
#screen-saved #saved-count { position: relative; top: -1px; }
#screen-saved #saved-filter { flex-shrink: 0; white-space: nowrap; }
/* Same height as the search box; the button font centres the labels. */
#screen-saved #saved-filter .artdash-seg-btn { padding-top: 5px; padding-bottom: 5px; }
#screen-saved .saved-search { width: 200px; max-width: 100%; min-width: 0; height: 32px; box-sizing: border-box; padding: 0 10px; gap: 6px; }
#screen-saved .saved-search svg { width: 14px; height: 14px; flex-shrink: 0; }
#screen-saved .saved-search input { width: 100%; min-width: 0; height: 100%; padding: 2.5px 0 0; box-sizing: border-box; font-size: 13px; }
@media (max-width: 900px) {
  #screen-saved .sch-toolbar { flex-wrap: wrap; }
  #screen-saved .saved-toolbar-left { flex: 1 1 100%; }
}
/* The same table as Recent Activity: its border, header row and row size. */
.preset-table {
  max-width: var(--content-max);
  display: flex; flex-direction: column; max-height: 100%; min-height: 0;
  background: #fff; border: 1px solid #E4E5EB; border-radius: var(--radius-md);
  box-shadow: 0 1px 3px rgba(15, 23, 42, 0.06);
  overflow: hidden;
}
.preset-row {
  display: grid;
  /* Name about 30%, so Owner sits close to it; Date Modified gets the most
     room since it also names who saved it last. */
  grid-template-columns: minmax(0, 1.2fr) minmax(0, 1fr) minmax(0, 1.8fr) 32px;
  align-items: center; gap: 16px;
  /* Recent Activity's row: 6px above and below a 13px line, 31px in all. */
  padding: 6px 6px 6px 16px;
  border-bottom: 1px solid #EEEEF2;
  font-size: 13px; line-height: 1.35; color: var(--fg-1);
}
.preset-row:last-child { border-bottom: none; }
.preset-head {
  padding-top: 7px; padding-bottom: 7px; background: #EBEBF0; border-bottom-color: #E0E1E7;
  font-size: 12px; font-weight: var(--fw-bold, 700); color: var(--fg-1);
  text-transform: uppercase; letter-spacing: 0.05em;
}
.preset-row:not(.preset-head):hover { background: #F7F7FA; }
/* A row opens Generate Deck. */
.preset-row--open { cursor: pointer; }
.preset-row--open:focus { outline: none; }
.preset-row--open:focus-visible { outline: 2px solid rgba(250, 67, 56, 0.35); outline-offset: -2px; }
.preset-row--open .saved-name-input { cursor: text; }
.preset-head { flex-shrink: 0; }
/* Sortable headers: they read as the plain uppercase labels, with an arrow on
   the one in use and a faint one on hover for the others. */
.preset-sort {
  display: inline-flex; align-items: center; gap: 4px; padding: 0; border: 0; background: none;
  font: inherit; letter-spacing: inherit; text-transform: inherit; color: inherit; cursor: pointer;
}
.preset-sort svg { flex-shrink: 0; opacity: 0; color: var(--fg-3); transition: opacity 0.12s; }
.preset-sort:hover svg { opacity: 0.6; }
.preset-sort.is-active svg { opacity: 1; color: var(--fg-1); }
.preset-sort:focus { outline: none; }
.preset-sort:focus-visible { outline: 2px solid rgba(250, 67, 56, 0.35); outline-offset: 2px; border-radius: 3px; }
/* With a scrollbar, the header clears its 16px lane so the columns line up. */
.preset-table--scroll .preset-head { padding-right: calc(6px + 16px); }
.preset-name-cell { display: flex; align-items: center; gap: 10px; min-width: 0; }
.preset-name { font-weight: var(--fw-medium); color: var(--fg-1); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
/* Deck preset staleness (app.js _presetFlagRows / _presetShowStale): amber
   when charts it uses are gone, as the "tiles selected" warning; red when
   its dashboard is. */
/* The reason sits under the name ("1 chart removed", "Dashboard deleted"). */
.preset-name-cell:has(> .preset-stale-flag:not(:empty)) { flex-direction: column; align-items: flex-start; gap: 1px; }
.preset-stale-flag { display: inline-flex; align-items: center; gap: 4px; flex-shrink: 0; font-size: 12px; font-weight: var(--fw-medium); color: #E59500; cursor: default; }
.preset-stale-flag svg { width: 12px; height: 12px; flex-shrink: 0; position: relative; top: -1.5px; } /* Sofia Pro sits high in its line: centered by the box, the icon looked 1.4px low */
.preset-stale-flag:empty { display: none; }
.preset-stale-flag.is-error { color: var(--envoy-red); }
/* Can't run (dashboard deleted or no access): the row fades as a whole, its
   reason included; the ⋮ stays as it is. */
.preset-row.is-unavailable > :not(.preset-more-cell) { opacity: 0.55; }
.preset-stale-banner {
  display: flex; align-items: flex-start; gap: 10px;
  margin: -4px 0 16px; padding: 12px 14px; /* 16px from the header above and the cards below */
  background: rgba(184, 131, 12, 0.08); border: 1px solid rgba(184, 131, 12, 0.3);
  border-radius: var(--radius); color: #8a6310;
}
.preset-stale-banner.hidden { display: none; }
.preset-stale-banner.is-error { background: rgba(250, 67, 56, 0.06); border-color: rgba(250, 67, 56, 0.3); color: #b3261e; }
.preset-stale-icon { display: inline-flex; flex-shrink: 0; align-self: center; } /* centered on the whole text block, like the button on the right */
.preset-stale-main { flex: 1; min-width: 0; }
.preset-stale-title { font-size: 14px; font-weight: var(--fw-semibold); }
.preset-stale-text { font-size: 13px; margin-top: 2px; color: var(--fg-2); }
.preset-stale-chips { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 8px; }
.preset-stale-chip { font: inherit; font-size: 12px; font-weight: var(--fw-medium); padding: 2px 7px; border: 0; border-radius: 4px; background: rgba(184, 131, 12, 0.14); color: #6b4d08; cursor: pointer; } /* flat tags; each goes to its slide */
.preset-stale-chip:hover, .preset-stale-chip:focus-visible { background: rgba(184, 131, 12, 0.24); outline: none; }
/* The one removed chart's name in the title: goes to its slide. */
.preset-stale-link { font: inherit; color: inherit; background: none; border: 0; padding: 0; cursor: pointer; text-decoration: underline; text-decoration-color: rgba(184, 131, 12, 0.45); text-underline-offset: 3px; }
.preset-stale-link:hover, .preset-stale-link:focus-visible { text-decoration-color: currentColor; outline: none; }
.preset-stale-ack { width: auto; flex-shrink: 0; align-self: center; }
/* The dropdown a removed chart's name was clicked for, outlined until a click elsewhere. */
select.is-located { border-color: #E59500 !important; box-shadow: 0 0 0 3px rgba(229, 149, 0, 0.25) !important; transition: box-shadow 0.25s, border-color 0.25s; }
/* Renaming in place: the same font, size and weight as the name, so the text
   doesn't jump, in a white box with a red focus ring. The negative margins
   keep the text where the name was and the row at its 31px height. */
.preset-name-cell .saved-name-input {
  font: inherit; font-size: 13px; font-weight: var(--fw-medium); line-height: 1.35; color: var(--fg-1);
  /* As wide as the name (plus room to type), growing with it, never past
     the column. Browsers without field-sizing use the input's default width. */
  field-sizing: content; width: auto; min-width: 120px; max-width: 100%; height: 24px; box-sizing: border-box;
  padding: 0 14px 0 7px; margin: -3px 0 -3px -8px;
  background: #fff; border: 1px solid var(--envoy-red); border-radius: 6px;
  box-shadow: 0 0 0 3px rgba(250, 67, 56, 0.12); outline: none;
}
.preset-name-cell .saved-name-input::placeholder { color: var(--fg-3); opacity: 1; }
.preset-owner, .preset-date { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
/* Who saved it last, after the date: quieter, like Google Drive. */
.preset-editor { color: var(--fg-3); }
.preset-more-cell { display: flex; justify-content: flex-end; }
.preset-more-btn {
  display: inline-flex; align-items: center; justify-content: center;
  /* No taller than the text line, so the ⋮ doesn't stretch the row. */
  width: 24px; height: 18px; padding: 0;
  border: 0; border-radius: 4px; background: none; color: var(--fg-3); cursor: pointer;
}
.preset-more-btn:hover, .preset-more-btn[aria-expanded="true"] { background: var(--bg-2); color: var(--fg-1); }
.preset-more-btn:focus { outline: none; }
.preset-more-btn:focus-visible { outline: 2px solid rgba(250, 67, 56, 0.35); outline-offset: 0; }
/* The ⋮ menu: compact like the account menu (13px rows, small icons, an
   inset hover). Delete is grey like the rest until you point at it. */
.preset-menu {
  position: fixed; z-index: 1000; min-width: 160px;
  display: flex; flex-direction: column; gap: 1px; padding: 4px;
  background: #fff; border: 1px solid #E4E5EB; border-radius: 8px;
  box-shadow: 0 8px 24px rgba(15, 23, 42, 0.12), 0 2px 6px rgba(15, 23, 42, 0.08);
}
.preset-menu-item {
  display: flex; align-items: center; gap: 8px; width: 100%;
  padding: 5px 8px; border: 0; border-radius: 5px; background: transparent;
  font: inherit; font-size: 13px; line-height: 1.35; color: var(--fg-2);
  text-align: left; cursor: pointer;
}
.preset-menu-item > svg { width: 14px; height: 14px; color: var(--fg-3); flex-shrink: 0; }
.preset-menu-divider { height: 1px; margin: 3px 2px; background: var(--border); }
/* Custom Slides' chart and KPI dropdowns (app.js _chartPickOpen): the ⋮
   menu's card and rows, with the Deck Presets search box on top. The current
   chart is red, as in the account menu. */
.chart-pick {
  position: fixed; z-index: 1000; box-sizing: border-box;
  display: flex; flex-direction: column; gap: 4px; padding: 6px;
  background: #fff; border: 1px solid #E4E5EB; border-radius: 8px;
  box-shadow: 0 8px 24px rgba(15, 23, 42, 0.12), 0 2px 6px rgba(15, 23, 42, 0.08);
}
.chart-pick-search { width: 100%; min-width: 0; height: 32px; box-sizing: border-box; padding: 0 10px; gap: 6px; flex-shrink: 0; }
.chart-pick-search svg { flex-shrink: 0; }
.chart-pick-search input { width: 100%; min-width: 0; height: 100%; padding: 2.5px 0 0; box-sizing: border-box; font-size: 13px; }
.chart-pick-list { max-height: 280px; overflow-y: auto; display: flex; flex-direction: column; gap: 1px; }
.chart-pick-item {
  flex-shrink: 0; padding: 6px 8px; border-radius: 5px; cursor: pointer;
  font-size: 13px; line-height: 1.35; color: var(--fg-2);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.chart-pick-item.is-active { background: var(--arctic); color: var(--fg-1); }
.chart-pick-item.is-selected { color: var(--envoy-red); font-weight: var(--fw-semibold); }
.chart-pick-item.is-placeholder { color: var(--fg-3); }
.chart-pick-group { flex-shrink: 0; padding: 8px 8px 4px; font-size: 11px; font-weight: var(--fw-bold); letter-spacing: 0.06em; text-transform: uppercase; color: var(--fg-3); }
.chart-pick-empty { padding: 10px 8px; font-size: 13px; color: var(--fg-3); }
.preset-menu-item:hover, .preset-menu-item:focus-visible { background: var(--arctic); color: var(--fg-1); outline: none; }
.preset-menu-item:hover > svg, .preset-menu-item:focus-visible > svg { color: var(--fg-2); }
.preset-menu-item.is-danger:hover, .preset-menu-item.is-danger:focus-visible,
.preset-menu-item.is-danger:hover > svg, .preset-menu-item.is-danger:focus-visible > svg { color: var(--envoy-red); }
/* Phones: just the name and the ⋮. */
@media (max-width: 640px) {
  .preset-row { grid-template-columns: minmax(0, 1fr) 40px; }
  .preset-row > :nth-child(2), .preset-row > :nth-child(3) { display: none; }
}
.saved-card-name {
  font-size: 14px;
  font-weight: var(--fw-semibold);
  color: var(--fg-1);
  line-height: 1.35;
  overflow: hidden;
  text-overflow: ellipsis;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  word-break: break-word;
}
.saved-card-meta {
  font-size: 12px;
  color: var(--fg-3);
  font-weight: var(--fw-medium);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.saved-card-url {
  font-size: 11px;
  color: var(--fg-3);
  font-family: var(--font-mono, ui-monospace, SFMono-Regular, monospace);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  margin-top: 2px;
  opacity: 0.85;
}
.saved-card-actions {
  display: flex;
  align-items: center;
  gap: 8px;
  padding-top: 12px;
  border-top: 1px solid var(--border);
  flex-wrap: wrap;
}
.saved-card-actions .secondary-btn {
  flex: 1;
  justify-content: center;
}

/* Wrapper for the filters block inside a modal — same horizontal padding
   as the rest of the modal sections. */
.modal-filters-section {
  padding: 18px 28px 4px;
}
.modal-filters-section:empty,
.modal-filters-section[style*="display: none"] { padding: 0; }
/* Generate Deck: the filters come after the Drive / own-links choice. */
#load-config-filters:not(:empty) { padding: 4px 28px 20px; }
/* Generate Deck's link boxes slide open and shut as the picker switches: the
   row grows from 0 to its height while fading in. The negative margin closes
   the 20px gap above it while it's shut. Hidden from Tab while shut. */
.load-links {
  display: grid; grid-template-rows: 0fr; opacity: 0; margin-top: -20px; visibility: hidden;
  transition: grid-template-rows 0.3s cubic-bezier(0.4, 0, 0.2, 1), margin-top 0.3s cubic-bezier(0.4, 0, 0.2, 1),
              opacity 0.2s ease, visibility 0s linear 0.3s;
}
.load-links.is-open {
  grid-template-rows: 1fr; opacity: 1; margin-top: 0; visibility: visible;
  transition: grid-template-rows 0.3s cubic-bezier(0.4, 0, 0.2, 1), margin-top 0.3s cubic-bezier(0.4, 0, 0.2, 1),
              opacity 0.25s ease 0.05s, visibility 0s;
}
/* Room for the inputs' focus rings, which overflow: hidden would clip. */
.load-links-inner { min-height: 0; overflow: hidden; display: flex; flex-direction: column; gap: 20px; padding: 3px; margin: -3px; }
.load-links.no-anim { transition: none; }
@media (prefers-reduced-motion: reduce) { .load-links, .load-links.is-open { transition: none; } }

/* ─── Filter rows (Load + Create configuration modals) ───────────────────
   Without these rules each filter row was rendering as raw inline label +
   raw input — labels and inputs of varying widths jammed together with no
   alignment. Now structured as a clean label-on-left / input-on-right grid. */
.filter-section-label {
  font-size: 11px;
  font-weight: var(--fw-bold);
  color: var(--fg-3);
  text-transform: uppercase;
  letter-spacing: 0.08em;
  margin: 0 0 10px;
}
.filter-section-hint {
  font-size: 12px;
  color: var(--fg-3);
  margin: 0 0 14px;
  line-height: 1.45;
}
.filter-controls-list {
  display: flex;
  flex-direction: column;
  gap: 8px;
  margin-bottom: 4px;
}
.filter-cell {
  display: grid;
  grid-template-columns: minmax(7rem, 22%) minmax(0, 1fr);
  align-items: center;
  gap: 14px;
}
.filter-cell-label {
  font-size: 13px;
  font-weight: var(--fw-medium);
  color: var(--fg-2);
  text-transform: capitalize;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.filter-cell-input {
  width: 100%;
  font-family: var(--font-sans);
  font-size: 13px;
  color: var(--fg-1);
  background: #fff;
  border: 1px solid var(--border);
  border-radius: 6px;
  padding: 7px 10px;
  transition: border-color 0.15s, box-shadow 0.15s;
}
.filter-cell-input::placeholder {
  color: var(--fg-3);
}
.filter-cell-input:focus {
  outline: none;
  border-color: var(--envoy-red);
  box-shadow: 0 0 0 3px rgba(250, 67, 56, 0.1);
}
.filter-cell-input--omni-default::placeholder {
  color: var(--gem-60, #4e4eda);
  font-style: italic;
}
@media (max-width: 560px) {
  .filter-cell { grid-template-columns: 1fr; gap: 4px; }
}

/* ─── Load-configuration refresh toggle ───────────────────────────────────
   Sits between the URL inputs and the action row inside the Load modal.
   The native <input type="checkbox"> is visually hidden; we paint a custom
   square box that flips to Envoy-red when checked. */
.load-config-refresh {
  display: flex;
  align-items: flex-start;
  gap: 12px;
  margin: 4px 24px 18px;
  padding: 12px 14px;
  background: var(--arctic);
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  cursor: pointer;
  user-select: none;
}
.load-config-refresh:hover { border-color: var(--carbon-30); }
.load-config-refresh-input {
  position: absolute;
  opacity: 0;
  pointer-events: none;
  width: 0; height: 0;
}
.load-config-refresh-box {
  width: 18px;
  height: 18px;
  border: 1.5px solid var(--border-strong);
  border-radius: 4px;
  background: #fff;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  margin-top: 1px;
  transition: background 0.15s, border-color 0.15s;
}
.load-config-refresh-box > svg { opacity: 0; transition: opacity 0.15s; }
.load-config-refresh-input:checked + .load-config-refresh-box {
  background: var(--envoy-red);
  border-color: var(--envoy-red);
}
.load-config-refresh-input:checked + .load-config-refresh-box > svg { opacity: 1; }
.load-config-refresh-input:focus-visible + .load-config-refresh-box {
  outline: 2px solid rgba(250, 67, 56, 0.4);
  outline-offset: 2px;
}
.load-config-refresh-text {
  display: flex;
  flex-direction: column;
  gap: 2px;
  min-width: 0;
}
.load-config-refresh-title {
  font-size: 13px;
  font-weight: var(--fw-semibold);
  color: var(--fg-1);
  line-height: 1.3;
}
.load-config-refresh-desc {
  font-size: 12px;
  color: var(--fg-3);
  line-height: 1.4;
}
.saved-card-delete {
  background: transparent;
  border: 1px solid var(--border);
  border-radius: 6px;
  padding: 6px;
  width: 30px;
  height: 30px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  color: var(--fg-3);
  cursor: pointer;
  flex-shrink: 0;
  transition: background 0.15s, color 0.15s, border-color 0.15s;
}
.saved-card-delete:hover {
  background: rgba(250, 67, 56, 0.08);
  color: var(--envoy-red);
  border-color: rgba(250, 67, 56, 0.3);
}
.saved-card-move-btn {
  background: transparent;
  border: 1px solid var(--border);
  border-radius: 6px;
  padding: 6px;
  width: 30px;
  height: 30px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  color: var(--fg-3);
  cursor: pointer;
  flex-shrink: 0;
  transition: background 0.15s, color 0.15s, border-color 0.15s;
}
.saved-card-move-btn:hover {
  background: var(--bg-2);
  color: var(--fg-1);
  border-color: var(--border-strong, var(--border));
}

/* Share button on config cards — same style as move-btn */
.saved-card-share-btn {
  background: transparent;
  border: 1px solid var(--border);
  border-radius: 6px;
  padding: 6px;
  width: 30px;
  height: 30px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  color: var(--fg-3);
  cursor: pointer;
  flex-shrink: 0;
  transition: background 0.15s, color 0.15s, border-color 0.15s;
}
.saved-card-share-btn:hover {
  background: var(--bg-2);
  color: var(--envoy-red, #e63946);
  border-color: var(--border-strong, var(--border));
}

/* "shared" badge on cards owned by someone else */
.saved-card-shared-badge {
  font-size: 10px;
  font-weight: 600;
  letter-spacing: 0.03em;
  text-transform: uppercase;
  color: var(--envoy-red, #e63946);
  background: color-mix(in srgb, var(--envoy-red, #e63946) 12%, transparent);
  border-radius: 4px;
  padding: 2px 6px;
  flex-shrink: 0;
}

/* "N shared" count badge on owned cards */
.saved-card-shared-count {
  font-size: 11px;
  color: var(--fg-3);
  background: var(--bg-2);
  border-radius: 4px;
  padding: 2px 6px;
  flex-shrink: 0;
  cursor: default;
}

/* Move-to-folder dropdown */
.move-folder-menu {
  position: fixed;
  z-index: 1200;
  background: #fff;
  border: 1px solid var(--border);
  border-radius: 10px;
  box-shadow: 0 8px 24px rgba(0,0,0,0.10), 0 2px 6px rgba(0,0,0,0.06);
  min-width: 180px;
  padding: 6px;
  display: flex;
  flex-direction: column;
  gap: 1px;
}
.move-folder-option {
  display: flex;
  align-items: center;
  gap: 8px;
  background: transparent;
  border: none;
  border-radius: 6px;
  padding: 8px 10px;
  text-align: left;
  font-size: 13px;
  font-weight: var(--fw-medium);
  color: var(--fg-1);
  cursor: pointer;
  white-space: nowrap;
  width: 100%;
}
.move-folder-option:hover { background: var(--bg-2); }
.move-folder-option.active {
  background: var(--accent-soft, #fff0ee);
  color: var(--envoy-red);
}
.move-folder-empty {
  padding: 8px 10px;
  font-size: 12px;
  color: var(--fg-3);
}

.saved-empty {
  grid-column: 1 / -1;
  padding: 60px 24px;
  text-align: center;
  color: var(--fg-3);
  font-size: 14px;
}

/* ── Schedules screen ──────────────────────────────────────────────────────── */
.sch-enabled-badge {
  font-size: 11px;
  font-weight: 600;
  padding: 2px 7px;
  border-radius: 99px;
  flex-shrink: 0;
}
.sch-enabled-badge--on  { background: #dcfce7; color: #166534; }
.sch-enabled-badge--off { background: #f1f5f9; color: #64748b; }

/* Schedule card inline toggle — positioned top-right of card */
.sch-toggle-btn {
  position: absolute;
  top: 16px;
  right: 16px;
  display: inline-flex;
  align-items: center;
  gap: 5px;
  background: none;
  border: none;
  padding: 0;
  cursor: pointer;
  flex-shrink: 0;
  z-index: 1;
}
.sch-toggle-btn:disabled { opacity: 0.5; cursor: default; pointer-events: none; }
.sch-toggle-track {
  position: relative;
  width: 28px;
  height: 16px;
  border-radius: 99px;
  background: #cbd5e1;
  transition: background 0.2s;
  flex-shrink: 0;
}
.sch-toggle-track--on { background: var(--envoy-red, #e5372c); }
.sch-toggle-thumb {
  position: absolute;
  top: 2px;
  left: 2px;
  width: 12px;
  height: 12px;
  border-radius: 50%;
  background: #fff;
  transition: transform 0.2s;
  box-shadow: 0 1px 2px rgba(0,0,0,0.2);
}
.sch-toggle-track--on .sch-toggle-thumb { transform: translateX(12px); }
.sch-toggle-label {
  font-size: 11px;
  font-weight: 600;
  color: var(--fg-2);
  min-width: 18px;
}

.sch-status { font-size: 12px; margin-top: 4px; color: var(--fg-3); }
.sch-status--ok  { color: #166534; }
.sch-status--err { color: var(--envoy-red); }
.sch-status--running { color: #2563eb; display: inline-flex; align-items: center; gap: 5px; }
.sch-status--running::before {
  content: '';
  display: inline-block;
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: #2563eb;
  animation: pulse-dot 1.2s ease-in-out infinite;
}
@keyframes pulse-dot {
  0%, 100% { opacity: 1; transform: scale(1); }
  50% { opacity: 0.4; transform: scale(0.75); }
}
.sch-error-msg { font-size: 11px; color: var(--envoy-red); margin-top: 2px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }

.sch-edit-btn { font-size: 13px; padding: 7px 12px; border-radius: 6px; }

.sch-never-run-label {
  display: inline-flex;
  align-items: center;
  font-size: 12px;
  color: var(--fg-3, #a1a1aa);
}

.sch-runs-list { display: flex; flex-direction: column; gap: 6px; }

.sch-run-row {
  display: grid;
  grid-template-columns: 10px 1fr auto;
  align-items: center;
  gap: 8px;
  font-size: 12px;
  min-height: 20px;
}
.sch-run-dot {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  flex-shrink: 0;
}
.sch-run-dot--ok  { background: #22c55e; }
.sch-run-dot--err { background: var(--envoy-red); }
.sch-run-dot--cancelled { background: var(--fg-3); }

.sch-run-ts { color: var(--fg-2); }
.sch-run-status { font-weight: 500; }
.sch-run-status--ok  { color: #166534; }
.sch-run-status--err { color: var(--envoy-red); }
.sch-run-status--cancelled { color: var(--fg-3); }

.sch-run-error {
  grid-column: 2 / -1;
  color: var(--envoy-red);
  font-size: 12px;
  overflow-wrap: anywhere;
}
.sch-run-deck-link { color: var(--envoy-blue, #3b82f6); text-decoration: none; white-space: nowrap; }
.sch-run-deck-link:hover { text-decoration: underline; }

/* ── Schedules list: one full-width row per schedule ───────────────────── */
.sch-toolbar { display: flex; align-items: center; justify-content: space-between; gap: 12px; max-width: var(--content-max); margin-bottom: 12px; }
.sch-count { font-size: 15px; font-weight: var(--fw-semibold, 600); color: var(--fg-1); }
.sch-count:empty { visibility: hidden; }
.sch-toolbar-right { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; justify-content: flex-end; }
.sch-filter .artdash-seg-btn { padding: 5px 12px; }
/* Segmented controls with a pill that slides to the active option
   (app.js _moveSegThumb sets its width and offset). */
.artdash-seg.has-thumb { position: relative; }
.artdash-seg.has-thumb .artdash-seg-btn { position: relative; z-index: 1; }
.artdash-seg.has-thumb .artdash-seg-btn.active { background: none; box-shadow: none; }
.seg-thumb {
  position: absolute; top: 3px; bottom: 3px; left: 3px; width: 0;
  background: var(--arctic); border-radius: 6px; box-shadow: inset 0 0 0 1px var(--border);
  transition: transform 0.3s cubic-bezier(0.4, 0, 0.2, 1), width 0.3s cubic-bezier(0.4, 0, 0.2, 1);
  pointer-events: none;
}
.seg-thumb.no-anim { transition: none; }
@media (prefers-reduced-motion: reduce) { .seg-thumb { transition: none; } }
.sch-sort select { width: auto; min-width: min(17.5rem, 100%); height: 36px; padding-top: 0; padding-bottom: 0; cursor: pointer; }
.sch-rows { display: flex; flex-direction: column; gap: 10px; max-width: var(--content-max); }
.sch-row {
  background: #fff; border: 1px solid #E4E5EB; border-radius: var(--radius-md);
  box-shadow: 0 1px 3px rgba(15, 23, 42, 0.06);
  overflow: hidden; cursor: pointer; transition: border-color 0.15s, box-shadow 0.15s;
}
.sch-row:hover { border-color: var(--carbon-20); box-shadow: 0 3px 10px rgba(15, 23, 42, 0.08); }
.sch-row-head {
  display: flex; align-items: center; gap: 12px;
  padding: 9px 16px; background: #fff; border-bottom: 1px solid #EEEEF2;
}
.sch-row-name { min-width: 0; font-size: 15px; font-weight: var(--fw-semibold, 600); color: var(--fg-1); text-decoration: none; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.sch-row:hover .sch-row-name { text-decoration: underline; }
/* Sit the envelope on the name's text baseline rather than centring it on
   the line box (lowercase names made a centred icon look raised). */
.sch-row-name, .sch-row-mail { align-self: baseline; }
.sch-row-mail { display: inline-flex; color: var(--fg-3); flex-shrink: 0; }
/* The envelope is drawn inset in its box; 2px down puts its outline on the
   baseline and its top at cap height. */
.sch-row-mail svg { display: block; transform: translateY(2px); }
.sch-row-actions { margin-left: auto; display: flex; align-items: center; gap: 6px; flex-shrink: 0; }
.sch-row-actions .sch-toggle-btn,
.sch-detail-head-right .sch-toggle-btn,
.sch-modal-header .sch-toggle-btn { position: static; }
.sch-modal-header { display: flex; align-items: flex-start; justify-content: space-between; gap: 16px; }
.sch-modal-header .sch-toggle-btn { margin-top: 4px; }
.sch-icon-btn {
  background: none; border: 0; color: var(--fg-3); padding: 6px; border-radius: 6px; cursor: pointer;
  display: grid; place-items: center;
}
.sch-icon-btn:hover { background: var(--arctic); color: var(--envoy-red); }
.sch-fav-btn:hover { color: #d97706; }
.sch-run-btn:disabled { opacity: 0.4; cursor: default; background: none; color: var(--fg-3); }
/* Stop, in place of Run Now while a run is going. */
.sch-stop-btn { color: var(--envoy-red); }
.sch-stop-btn:disabled { opacity: 0.4; cursor: default; background: none; }
.sch-fav-btn--on, .sch-fav-btn--on:hover { color: #f59e0b; }
.sch-row-body {
  /* Bars column sized from the bars (20 bars + 19 gaps, see .sch-bars) so rows
     with no runs keep their columns aligned with the rest. */
  display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr) minmax(0, 1fr) calc(20 * var(--sch-bar-w) + 19 * var(--sch-bar-gap));
  align-items: end; gap: 16px; padding: 10px 16px 12px;
}
.sch-col { display: flex; flex-direction: column; gap: 3px; min-width: 0; }
.sch-col-label { font-size: 12px; font-weight: var(--fw-semibold, 600); color: var(--fg-3); }
.sch-col-value { display: inline-flex; align-items: center; gap: 6px; font-size: 14px; color: var(--fg-1); min-width: 0; }
.sch-col-value > svg { flex-shrink: 0; color: var(--fg-3); }
.sch-col--bars { align-self: center; }
.sch-muted { color: var(--fg-3); }
.sch-latest { display: inline-flex; align-items: center; gap: 8px; }
.sch-latest-icon { width: 18px; height: 18px; border-radius: 50%; display: grid; place-items: center; color: #fff; flex-shrink: 0; }
.sch-latest-icon svg { width: 10px; height: 10px; }
.sch-latest-icon--ok { background: #16a34a; }
.sch-latest-icon--err { background: var(--envoy-red); }
.sch-latest-icon--cancelled { background: var(--fg-3); }
@media (max-width: 900px) {
  .sch-row-body { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); }
  .sch-col--bars:empty { display: none; }
  .sch-col--bars { grid-column: 1 / -1; }
}

/* Run-history bars: height = duration (relative), colour = outcome. */
.sch-bars {
  display: grid; grid-template-columns: repeat(var(--sch-slots, 20), var(--sch-bar-w));
  gap: var(--sch-bar-gap); height: 44px; align-items: end;
}
.sch-bar { position: relative; height: 100%; display: flex; flex-direction: column; justify-content: flex-end; padding-bottom: 14px; box-sizing: border-box; }
.sch-bar-fill { display: block; width: 100%; border-radius: 2px 2px 0 0; min-height: 4px; }
.sch-bar--ok .sch-bar-fill { background: #22c55e; }
.sch-bar--err .sch-bar-fill { background: var(--envoy-red); }
.sch-bar--cancelled .sch-bar-fill { background: var(--border-strong); }
.sch-bar:hover .sch-bar-fill { filter: brightness(0.88); }
.sch-bar-icon {
  position: absolute; left: 50%; bottom: 0; transform: translateX(-50%);
  width: 11px; height: 11px; border-radius: 50%; display: grid; place-items: center; color: #fff;
}
.sch-bar-icon svg { width: 7px; height: 7px; }
.sch-bar--ok .sch-bar-icon { background: #16a34a; }
.sch-bar--err .sch-bar-icon { background: var(--envoy-red); }
.sch-bar--cancelled .sch-bar-icon { background: var(--fg-3); }
/* The run in progress (Airflow's light green), pulsing until it finishes. */
.sch-bar--running .sch-bar-fill { background: #86efac; animation: sch-bar-pulse 1.4s ease-in-out infinite; }
.sch-bar--running .sch-bar-icon { background: #fff; box-shadow: inset 0 0 0 2px #22c55e; }
@keyframes sch-bar-pulse { 50% { opacity: 0.45; } }
@media (prefers-reduced-motion: reduce) { .sch-bar--running .sch-bar-fill { animation: none; } }
/* Hover card for a run bar (_schBarTip in app.js). */
.sch-bar-tip {
  position: fixed; z-index: 1000; display: none; min-width: 150px; max-width: 280px;
  padding: 8px 10px; border-radius: 8px; background: #fff; border: 1px solid #E4E5EA;
  box-shadow: var(--shadow-md); font-size: 12px; line-height: 1.4; color: var(--fg-1); pointer-events: none;
}
.sch-bar-tip.is-open { display: block; }
.sch-bar-tip-status { font-weight: var(--fw-semibold, 600); margin-bottom: 4px; }
.sch-bar-tip-status--ok { color: #166534; }
.sch-bar-tip-status--err { color: var(--envoy-red); }
.sch-bar-tip-status--cancelled { color: var(--fg-3); }
.sch-bar-tip-status--running { color: #16a34a; }
.sch-bar-tip-row { display: flex; justify-content: space-between; gap: 12px; }
.sch-bar-tip-row > span:first-child { color: var(--fg-3); }
.sch-bar-tip-error { margin-top: 4px; color: var(--envoy-red); overflow-wrap: anywhere; }
.sch-bar--empty::after {
  content: ''; position: absolute; left: 50%; bottom: 3px; transform: translateX(-50%);
  width: 5px; height: 5px; border-radius: 50%; background: var(--border-strong);
}

/* ── Schedule page (detail + edit) ─────────────────────────────────────── */
.sch-detail { max-width: var(--content-max); } /* same as .saved-header and .sch-rows */
/* Breadcrumb above the schedule's title: "Schedules / <name>". */
.sch-crumb { display: flex; align-items: center; gap: 6px; min-width: 0; margin: 0 0 10px; font-size: 13px; color: var(--fg-3); }
.sch-crumb a { color: var(--fg-3); font-weight: 500; text-decoration: none; flex-shrink: 0; }
.sch-crumb a:hover { color: var(--fg-1); text-decoration: underline; }
.sch-crumb-current { color: var(--fg-1); font-weight: 500; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.sch-detail-head { display: flex; align-items: flex-start; justify-content: space-between; gap: 16px; margin-bottom: 20px; }
.sch-detail-head .saved-title { overflow-wrap: anywhere; }
.sch-detail-meta { display: flex; align-items: baseline; flex-wrap: wrap; gap: 4px 8px; font-size: 14px; line-height: 1.5; color: var(--fg-3); }
.sch-detail-head .saved-title { margin-bottom: 4px; }
/* Tabs card and the Details column beside it; stacked on narrow screens. */
.sch-detail-body { display: grid; grid-template-columns: minmax(0, 1fr) 240px; gap: 20px; align-items: start; }
.sch-detail-aside {
  background: #fff; border: 1px solid #E4E5EB; border-radius: var(--radius-md);
}
/* Title, then label | value rows split by hairlines. */
.sch-aside-title { margin: 0; padding: 12px 16px; border-bottom: 1px solid #EEEEF2; font-size: 13px; font-weight: var(--fw-semibold, 600); line-height: 1.3; color: var(--fg-1); }
.sch-aside-rows { padding: 0 16px; }
.sch-aside-row { display: flex; justify-content: space-between; align-items: baseline; gap: 12px; padding: 10px 0; font-size: 13px; line-height: 1.35; }
.sch-aside-row + .sch-aside-row { border-top: 1px solid #EEEEF2; }
.sch-aside-label { color: var(--fg-3); flex-shrink: 0; }
/* Settings' Dashboard URL label when the dashboard is deleted or can't be opened. */
.preset-aside-stale { display: inline-flex; vertical-align: middle; margin-left: 6px; color: var(--envoy-red); cursor: default; }
.preset-aside-stale svg { width: 12px; height: 12px; position: relative; top: -1.5px; } /* the size of the list's, centered on the label's capitals */
.sch-aside-value { color: var(--fg-1); text-align: right; min-width: 0; overflow-wrap: anywhere; }
.sch-aside-note { margin: 0; padding: 10px 16px 12px; border-top: 1px solid #EEEEF2; font-size: 12px; line-height: 1.4; color: var(--fg-3); }
.sch-aside-link { display: inline-flex; align-items: center; gap: 4px; font-weight: var(--fw-semibold, 600); color: var(--envoy-red); text-decoration: none; }
.sch-aside-link:hover { text-decoration: underline; }
.sch-aside-link svg { align-self: center; flex-shrink: 0; }
@media (max-width: 900px) {
  .sch-detail-body { grid-template-columns: minmax(0, 1fr); }
  .sch-detail-aside { order: -1; }
}
.sch-detail-delete { display: inline-flex; align-items: center; gap: 6px; width: auto; flex-shrink: 0; line-height: 1; }
.sch-detail-delete svg { width: 14px; height: 14px; }
.sch-detail-delete:hover { color: var(--envoy-red); }
.sch-detail-card { background: #fff; border: 1px solid #E4E5EB; box-shadow: 0 1px 3px rgba(15, 23, 42, 0.06); border-radius: var(--radius-md); padding: 18px 22px; margin-bottom: 16px; }
.sch-detail-card-head { display: flex; align-items: baseline; justify-content: space-between; gap: 12px; margin-bottom: 14px; }
.sch-detail-card-head h3 { margin: 0; font-size: 15px; color: var(--fg-1); }
.sch-detail-muted { font-size: 13px; color: var(--fg-3); }
/* Header: title + schedule on the left, run bars + Delete on the right. */
.sch-detail-head-right { display: flex; align-items: center; gap: 20px; flex-shrink: 0; }
.sch-detail-head-bars:empty { display: none; }
@media (max-width: 900px) {
  .sch-detail-head { flex-wrap: wrap; }
  .sch-detail-head-bars { display: none; }
}

/* Runs | Settings tabs in one card (shared .howto-tabs.ink-tabs look). */
.sch-tabs-card { padding: 0; }
/* Doubled classes so these beat the shared .howto-tabs / .howto-tab rules,
   which come later in this file. */
.howto-tabs.sch-dtabs { margin-bottom: 0; padding: 0 12px; border-bottom-color: #EEEEF2; }
/* Line the count up with the label's baseline, not its box centre: Sofia Pro
   numerals sit high, so centring made the count look raised beside "Runs". */
.howto-tab.sch-dtab { align-items: baseline; }
.sch-dtab-count { font-size: 12px; font-weight: 500; line-height: 1; color: var(--fg-3); background: var(--arctic); border-radius: 999px; padding: 3px 8px; }
.sch-dtab.active .sch-dtab-count { color: var(--envoy-red); background: rgba(250, 67, 56, 0.08); }
.sch-dtab-count:empty { display: none; }
/* Schedule email is a beta: hidden for roles without beta.access. */
body:not(.has-beta) #sch-dtab-notifications,
body:not(.has-beta) #sch-panel-notifications { display: none !important; }
.beta-badge.sch-beta { margin-left: 2px; font-size: 10px; padding: 2px 7px; top: 0; }
.beta-badge.sch-modal-beta { margin-left: 8px; top: -2px; }
#schedule-modal:not(.is-email-step) .sch-modal-beta { display: none; }
.sch-dtab-panel { padding: 12px 22px 18px; }
/* Run rows bring their own 8px top padding, so the list starts a bit higher. */
#sch-panel-runs { padding-top: 4px; }
.sch-dtab-panel.hidden { display: none; }
#sch-detail-runs-list { gap: 0; }
/* Same space above and below (panel top + this ≈ panel bottom + card border). */
#sch-detail-runs-empty { margin: 16px 0 0; font-size: 13px; line-height: 1.5; color: var(--fg-3); }
#sch-detail-runs-empty.hidden { display: none; }
#sch-page-form-host { margin-bottom: 0; }
#sch-detail-runs-list .sch-run-row { flex-shrink: 0; padding: 8px 0; border-bottom: 1px solid #EEEEF2; }
#sch-detail-runs-list .sch-run-row:last-child { border-bottom: none; }
.sch-form-body { display: flex; flex-direction: column; gap: 12px; }
/* "Including all charts · Choose charts" under the Dashboard URL field. */
.sch-charts-line { margin: -9px 0 0; font-size: 12px; color: var(--fg-3); }
.sch-charts-line strong { font-weight: var(--fw-semibold, 600); color: var(--fg-1); }
.sch-charts-line .sch-charts-when-empty { display: none; }
.sch-charts-line--empty .sch-charts-when-url { display: none; }
.sch-charts-line--empty .sch-charts-when-empty { display: inline; }
.sch-link-btn { background: none; border: 0; padding: 0; font: inherit; font-weight: var(--fw-semibold, 600); color: var(--envoy-red); cursor: pointer; }
.sch-link-btn:hover { text-decoration: underline; }
.sch-output-label { margin: 4px 0 -6px; }
/* Form groups (Details / Output files / Schedule): a heading with clearly more
   space above it than between fields, so each group reads as one block. */
.sch-form-section { margin: 2px 0 -4px; font-size: 14px; font-weight: var(--fw-semibold, 600); color: var(--fg-1); }
.sch-form-body > .sch-form-section:first-child { margin-top: 0; }
/* Labels sit close to their field in the schedule form and email editor. */
.sch-form-body .modal-field-label, .sch-email .modal-field-label { gap: 3px; line-height: 1.3; }
/* Notes under a field sit slightly in from the box's edge. */
.sch-charts-line, #sch-sa-note, .sch-email-access, .sch-email-hint { padding-left: 4px; }
/* Email section in the schedule form. */
.sch-email { display: flex; flex-direction: column; gap: 12px; }
/* Recipient chips inside an input-looking box. */
.modal-input.sch-chips { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; min-height: 38px; padding: 5px 8px; cursor: text; }
.modal-input.sch-chips:focus-within { border-color: var(--envoy-red); box-shadow: 0 0 0 2px rgba(250,67,56,0.12); }
.sch-chips input { flex: 1 1 160px; min-width: 120px; border: 0; outline: none; padding: 3px 2px; font: inherit; font-size: 13px; color: var(--fg-1); background: transparent; }
.sch-chip { display: inline-flex; align-items: center; gap: 4px; max-width: 100%; padding: 3px 4px 3px 10px; border-radius: 999px; background: var(--arctic); border: 1px solid var(--border); font-size: 13px; color: var(--fg-1); }
.sch-chip--bad { background: #FEF2F2; border-color: #FECACA; color: #991B1B; }
.sch-chip span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.sch-chip button { border: 0; background: none; padding: 0 4px; font-size: 15px; line-height: 1; color: var(--fg-3); cursor: pointer; border-radius: 999px; }
.sch-chip button:hover { color: var(--fg-1); background: rgba(0,0,0,0.06); }
.sch-email-head { display: flex; align-items: flex-start; justify-content: space-between; gap: 16px; }
.sch-email-head .sch-toggle-btn { position: static; margin-top: 2px; }
.sch-email-sub { margin: 2px 0 0; font-size: 13px; color: var(--fg-3); }
/* "Email" is a section heading like "Output files", sat directly on its description. */
.sch-email-head .sch-form-section { margin: 0; }
.sch-email-fields { display: flex; flex-direction: column; gap: 12px; }
.sch-email-fields { transition: opacity 0.2s ease; }
.sch-email-fields.is-off { opacity: 0.45; }
.sch-email-fields.is-off .sch-chip button { visibility: hidden; }
/* In the new-schedule popup's email step the choice is the step itself. */
.sch-email--step .sch-email-head { display: none; }
.sch-email-saved { align-self: center; font-size: 13px; font-weight: var(--fw-semibold, 600); color: var(--fg-3); } /* Vidara's secondary-text grey */
.sch-email-saved.hidden { display: none; }
.sch-email-hint { margin: -4px 0 0; font-size: 12px; color: var(--fg-3); line-height: 1.45; }
.sch-email-access { display: none; margin: 0; font-size: 12px; color: var(--fg-3); }
/* Only for schedules on the user's own Slides/Sheets: Vidara shares the files
   it creates with recipients, but it may not be allowed to share yours. */
.sch-email--own-files .sch-email-access { display: block; }
.sch-modal-body { padding: 12px 28px 16px; }
/* Schedule popup: compact footer buttons (the app default is 13px × 22px). */
#schedule-modal .modal-actions { padding: 14px 28px 18px; }
/* Unsaved-changes prompt: small, no divider, compact buttons. */
.modal-overlay > .modal.sch-unsaved { max-width: 26.25rem; }
/* Generating from a deck preset: Generate Slides' run panels, moved in. */
.modal-overlay > .modal.preset-run-modal { max-width: 40rem; }
#preset-run-host > .panel { padding: 12px 28px 28px; }
#preset-run-host .result-container { padding: 8px 0 0; }
.sch-unsaved .modal-actions { border-top: 0; padding: 14px 28px 20px; }
.sch-unsaved .modal-actions .primary-btn, .sch-unsaved .modal-actions .secondary-btn { width: auto; }
/* Email step after a new schedule saves: success label, no repeated hint,
   no divider above the buttons. */
.sch-modal-eyebrow { display: inline-flex; align-items: center; gap: 6px; margin: 0 0 8px; font-size: 13px; font-weight: var(--fw-semibold, 600); color: #157347; }
.sch-modal-eyebrow.hidden { display: none; }
#schedule-modal.is-email-step .modal-actions { border-top: 0; padding-top: 4px; }
#schedule-modal.is-email-step .sch-email-hint { display: none; }
#schedule-modal .modal-actions .primary-btn,
#schedule-modal .modal-actions .secondary-btn { width: auto; }
/* Close under the last field so the buttons read as part of the form. */
.sch-form-actions { display: flex; justify-content: flex-end; align-items: center; gap: 10px; padding-top: 16px; }
/* The schedule summary sits at the left of the page's button row. */
.sch-preview-inline { margin-right: auto; min-width: 0; }
.sch-email-hint.sch-email-hint--inline { margin: -12px auto 0 0; min-width: 0; }
/* Notifications Save row: Save sits 16px under "Send when" like Save schedule;
   the note is pulled up to sit just under the dropdown like other notes. */
#sch-page-email-actions { padding-top: 16px; align-items: flex-start; }
#sch-modal-actions-host { align-items: center; }
.sch-preview-inline.hidden { display: none !important; }
.sch-form-actions .primary-btn, .sch-form-actions .secondary-btn { width: auto; }

/* Schedule modal fields */
.modal-field-label {
  display: flex;
  flex-direction: column;
  gap: 5px;
  font-size: 13px;
  font-weight: 500;
  color: var(--fg-2);
}
.modal-field-row { flex-direction: row; align-items: center; }
.modal-field-hint {
  font-size: 12px;
  font-weight: 400;
  color: var(--fg-3);
  line-height: 1.35;
}
.modal-input {
  width: 100%;
  padding: 8px 10px;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  font-family: inherit; /* form controls don't inherit the page font by default */
  font-size: 13px;
  color: var(--fg-1);
  background: #fff;
  box-sizing: border-box;
}
/* Same chevron as the Access Control selects instead of the native arrow. */
select.modal-input {
  appearance: none; -webkit-appearance: none;
  padding-right: 32px;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 24 24' fill='none' stroke='%236b7280' stroke-width='2.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='6 9 12 15 18 9'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 11px center;
  cursor: pointer;
}
.modal-input:focus { outline: none; border-color: var(--envoy-red); box-shadow: 0 0 0 2px rgba(250,67,56,0.12); }
/* A link at the end of a popup's message (app.js _showInputModal linkText). */
.modal-inline-link { font: inherit; padding: 0; border: 0; background: none; color: var(--envoy-red); font-weight: var(--fw-semibold); cursor: pointer; }
.modal-inline-link:hover { text-decoration: underline; text-underline-offset: 2px; }
.modal-inline-link:focus-visible { outline: 2px solid rgba(250, 67, 56, 0.35); outline-offset: 2px; border-radius: 3px; }
/* A field whose value is the problem (e.g. a deck preset's dashboard link that
   was deleted or can't be opened): red outline, focused or not. */
.modal-input[aria-invalid="true"] { border-color: var(--envoy-red); box-shadow: 0 0 0 2px rgba(250,67,56,0.12); }

/* Schedule builder */
.sch-mode-tabs {
  display: flex;
  gap: 0;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  overflow: hidden;
  width: fit-content;
}
.sch-mode-tab {
  padding: 6px 14px;
  font-size: 12px;
  font-weight: 500;
  border: none;
  background: #fff;
  color: var(--fg-2);
  cursor: pointer;
  transition: background 0.15s, color 0.15s;
}
.sch-mode-tab + .sch-mode-tab { border-left: 1px solid var(--border); }
.sch-mode-tab.active { background: var(--envoy-red); color: #fff; }
.sch-mode-tab:not(.active):hover { background: var(--bg-2,#f3f4f6); }
.sch-builder-row {
  display: flex;
  align-items: center;
  gap: 12px;
}
.sch-builder-label {
  font-size: 12px;
  font-weight: 500;
  color: var(--fg-2);
  min-width: 90px;
  flex-shrink: 0;
}
.sch-day-pills {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
}
.sch-day-pill {
  display: flex;
  align-items: center;
  gap: 0;
  cursor: pointer;
}
.sch-day-pill input[type="checkbox"], .sch-day-pill input[type="radio"] { display: none; }
.sch-day-pill span, .sch-day-pill {
  padding: 5px 10px;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  font-size: 12px;
  font-weight: 500;
  color: var(--fg-2);
  background: #fff;
  transition: background 0.12s, color 0.12s, border-color 0.12s;
  user-select: none;
}
.sch-day-pill:has(input:checked) {
  background: var(--envoy-red);
  color: #fff;
  border-color: var(--envoy-red);
}
.sch-time-trigger {
  display: flex;
  align-items: center;
  justify-content: space-between;
  cursor: pointer;
  user-select: none;
}
.sch-time-dropdown {
  position: absolute;
  top: calc(100% + 4px);
  left: 0;
  right: 0;
  background: #fff;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  z-index: 200;
  overflow: hidden;
  box-shadow: 0 4px 12px rgba(0,0,0,.08);
}
.sch-time-scroll {
  max-height: 210px;
  overflow-y: auto;
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 5px;
  padding: 8px;
}
.sch-time-section {
  grid-column: 1 / -1;
  font-size: 10px;
  color: var(--fg-3);
  font-weight: 500;
  letter-spacing: .05em;
  text-transform: uppercase;
  padding: 2px 2px 0;
}
.sch-time-option {
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 5px 4px;
  font-size: 12px;
  font-weight: 500;
  cursor: pointer;
  color: var(--fg-2);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  background: #fff;
  transition: background .12s, color .12s, border-color .12s;
  user-select: none;
}
.sch-time-option input[type="checkbox"] { display: none; }
.sch-time-option:has(input:checked) {
  background: var(--envoy-red);
  color: #fff;
  border-color: var(--envoy-red);
}

/* How-to (shared tab bar + guide content, now under Settings → How To) */
.howto-tabs {
  display: flex; gap: 8px;
  border-bottom: 1px solid var(--border);
  margin-bottom: 24px;
}
.howto-tab {
  display: inline-flex;
  align-items: center;
  gap: 8px;                 /* breathing room between the icon and the label */
  background: transparent;
  border: 0;
  padding: 10px 16px;
  font-size: 14px;
  font-weight: var(--fw-semibold);
  color: var(--fg-3);
  cursor: pointer;
  border-bottom: 2px solid transparent;
  margin-bottom: -1px;
  white-space: nowrap;
}
.howto-tab > svg { flex-shrink: 0; }
.howto-tab.active { color: var(--envoy-red); border-bottom-color: var(--envoy-red); }

/* Tab bars with one underline that slides between tabs (app.js _moveTabInk),
   and panes that slide in from the side you moved toward. Used by Access
   control and the schedule page. */
.ink-tabs { position: relative; }
.ink-tabs .howto-tab.active { border-bottom-color: transparent; }
/* No browser focus box after a click; keyboard focus gets a soft brand ring. */
.ink-tabs .howto-tab:focus { outline: none; }
.ink-tabs .howto-tab:focus-visible { outline: 2px solid rgba(250, 67, 56, 0.35); outline-offset: -2px; border-radius: 6px; }
.ink-tabs .tab-ink {
  position: absolute; left: 0; bottom: -1px;
  height: 2px; width: 0;
  background: var(--envoy-red);
  transition: transform 0.3s cubic-bezier(0.4, 0, 0.2, 1), width 0.3s cubic-bezier(0.4, 0, 0.2, 1);
  pointer-events: none;
}
.ink-tabs .tab-ink.no-anim { transition: none; }
@keyframes pane-in-right { from { opacity: 0; transform: translateX(28px); } to { opacity: 1; transform: none; } }
@keyframes pane-in-left  { from { opacity: 0; transform: translateX(-28px); } to { opacity: 1; transform: none; } }
.pane-in-right { animation: pane-in-right 0.3s cubic-bezier(0.4, 0, 0.2, 1); }
.pane-in-left  { animation: pane-in-left 0.3s cubic-bezier(0.4, 0, 0.2, 1); }
@media (prefers-reduced-motion: reduce) {
  .ink-tabs .tab-ink { transition: none; }
  .pane-in-right, .pane-in-left { animation: none; }
}
.howto-section { margin-bottom: 32px; max-width: var(--content-max); }
.howto-section-title {
  font-size: 18px;
  font-weight: var(--fw-bold);
  color: var(--fg-1);
  margin: 0 0 12px;
}
.howto-feature-grid,
.howto-mode-cards {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
  gap: 12px;
}
.howto-feature,
.howto-mode-card {
  background: #fff;
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  padding: 16px;
}
.howto-feature-icon {
  width: 36px; height: 36px;
  border-radius: 9px;
  background: rgba(250, 67, 56, 0.1);
  color: var(--envoy-red);
  display: inline-flex; align-items: center; justify-content: center;
  margin-bottom: 10px;
}
.howto-feature-label,
.howto-mode-card-title {
  display: inline-flex;
  align-items: center;
  gap: 8px;             /* breathing room between the icon and the title */
  font-size: 14px;
  font-weight: var(--fw-bold);
  color: var(--fg-1);
  margin-bottom: 4px;
}
.howto-mode-card-title > svg,
.howto-feature-label > svg { flex-shrink: 0; color: var(--envoy-red); }
.howto-feature-desc,
.howto-mode-card p {
  font-size: 13px;
  color: var(--fg-3);
  line-height: 1.5;
}
.howto-steps { display: flex; flex-direction: column; gap: 14px; }
.howto-step { display: flex; gap: 14px; }
.howto-step-num {
  width: 28px; height: 28px;
  border-radius: 999px;
  background: var(--envoy-red);
  color: #fff;
  font-weight: var(--fw-bold);
  font-size: 13px;
  display: inline-flex; align-items: center; justify-content: center;
  flex-shrink: 0;
}
.howto-step-title {
  font-size: 14px;
  font-weight: var(--fw-bold);
  color: var(--fg-1);
  margin-bottom: 2px;
}
.howto-step-desc {
  font-size: 13px;
  color: var(--fg-3);
  line-height: 1.5;
}
.howto-flow-desc {
  font-size: 14px;
  color: var(--fg-2);
  line-height: 1.55;
}
.howto-tip {
  background: var(--arctic);
  border-left: 3px solid var(--envoy-red);
  padding: 10px 14px;
  font-size: 13px;
  color: var(--fg-2);
  border-radius: 0 6px 6px 0;
  margin-top: 12px;
  display: flex; align-items: flex-start; gap: 8px;
}
.howto-tip > svg { flex-shrink: 0; margin-top: 2px; color: var(--envoy-red); }
.howto-service-email {
  font-family: var(--font-mono);
  font-size: 12px;
  background: var(--arctic);
  padding: 2px 6px;
  border-radius: 4px;
}

/* ============================================================
   Toast
   ============================================================ */
#app-toast {
  position: fixed; bottom: 24px;
  /* Centred on the content area right of the sidebar; see _toastInset(). */
  left: calc(var(--toast-inset, 0px) + (100% - var(--toast-inset, 0px)) / 2);
  background: var(--carbon-90);
  color: #fff;
  padding: 10px 18px;
  border-radius: 999px;
  font-size: 13px;
  font-weight: var(--fw-medium);
  z-index: 400;
  box-shadow: var(--shadow-md);
  /* Hidden by default — only `.toast-show` makes it visible. Without these
     rules the toast was permanently stuck on-screen because `.toast-hide`
     in the JS has nothing to bind to. */
  opacity: 0;
  pointer-events: none;
  transform: translateX(-50%) translateY(8px);
  transition: opacity 0.18s ease, transform 0.18s ease;
}
#app-toast.toast-show {
  opacity: 1;
  transform: translateX(-50%) translateY(0);
}
#app-toast.toast-hide {
  opacity: 0;
  transform: translateX(-50%) translateY(8px);
}
#app-toast.hidden { display: none; }
/* A toast with a link (showToast's opts.action) takes clicks while it's up. */
#app-toast.has-action.toast-show { pointer-events: auto; }
#app-toast .toast-action {
  margin-left: 12px; padding: 0; border: 0; background: none; cursor: pointer;
  font: inherit; color: #fff; text-decoration: underline; text-underline-offset: 2px;
}
#app-toast .toast-action:hover { opacity: 0.85; }

/* ============================================================
   Responsive
   ============================================================ */
@media (max-width: 980px) {
  .home-hero { flex-direction: column; align-items: flex-start; gap: 24px; }
  .home-actions { grid-template-columns: 1fr; }
  .basic-tiles-grid, .cz-tiles { grid-template-columns: repeat(2, 1fr); }
  .customize-mode-grid, .cz-mode-grid { grid-template-columns: 1fr; }
  .result-preview, .rs-preview { grid-template-columns: 1fr; }
}
@media (max-width: 640px) {
  .home-title { font-size: 36px; }
  .panel, .app-panel { padding: 24px 20px; }
  .steps-bar { padding: 12px 16px; gap: 6px; overflow-x: auto; }
}

/* ============================================================
   Sign-in screen (Quarry): one centred card on the arctic background
   ============================================================ */
.auth-screen.qy-landing {
  background:
    radial-gradient(60rem 30rem at 50% -10%, rgba(250, 67, 56, 0.10), transparent 70%),
    var(--arctic);
  padding: 16px;
}
.qy-landing-card {
  display: flex; flex-direction: column; align-items: center;
  gap: 18px;
  width: 100%; max-width: 28rem;
  padding: 48px 36px 36px;
  background: #fff;
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-md);
  text-align: center;
}
.qy-landing-brand { display: inline-flex; align-items: center; gap: 12px; }
.qy-landing-word {
  font-size: 34px; font-weight: var(--fw-bold);
  color: var(--fg-1); letter-spacing: -0.02em;
}
.qy-landing-line {
  margin: 0; max-width: 22rem;
  font-size: 17px; line-height: 1.45; color: var(--fg-2);
}
.qy-landing-btn { width: 100%; max-width: 18rem; justify-content: center; margin-top: 6px; }
.qy-landing-fine { margin: 4px 0 0; font-size: 12px; color: var(--fg-3); }
/* Until /api/config confirms Okta, the button shows it isn't ready yet. */
.lp-btn-loading { opacity: 0.6; cursor: progress; }
@media (max-width: 480px) {
  .qy-landing-card { padding: 36px 20px 28px; }
  .qy-landing-word { font-size: 28px; }
}

/* Sidebar mark: the stone carries its own colour, so no red tile behind it. */
.logo-icon.qy-logo-icon { background: none; box-shadow: none; border-radius: 0; }

/* No-access note (a role /me grants none of Quarry's screens). */
.screen-noaccess { flex: 1; display: flex; align-items: center; justify-content: center; padding: var(--page-pad-top) var(--page-pad-x); }
.qy-empty { display: flex; flex-direction: column; align-items: center; gap: 10px; text-align: center; max-width: 28rem; }
.qy-empty-title { margin: 8px 0 0; font-size: 22px; font-weight: var(--fw-bold); color: var(--fg-1); }
.qy-empty-sub { margin: 0; font-size: 15px; line-height: 1.5; color: var(--fg-3); }

/* Settings › Account › Google Drive status pill. */
.settings-drive-status {
  display: inline-block; margin-left: 8px; padding: 1px 8px;
  border-radius: 999px; font-size: 11px; font-weight: var(--fw-semibold);
  background: var(--arctic); color: var(--fg-3); vertical-align: 1px;
}
.settings-drive-status.is-on { background: rgba(24, 128, 56, 0.10); color: #188038; }

/* Beta pill inside the sidebar nav item (pushed right by the flex:1 label).
   Same filled pill as the account chip's role (.user-role). */
.sidebar-nav-badge {
  flex: 0 0 auto;
  font-size: 9.5px;
  font-weight: var(--fw-semibold);
  letter-spacing: 0.04em;
  text-transform: uppercase;
  padding: 1px 7px;
  border-radius: 999px;
  border: 0;
  background: rgba(250, 67, 56, 0.08);
  color: var(--envoy-red);
  line-height: 1.4;
}
/* On the selected row's pink highlight, a touch stronger so it still shows. */
.sidebar-nav-item.active .sidebar-nav-badge {
  background: rgba(250, 67, 56, 0.14);
  color: var(--envoy-red);
}

/* Beta pill next to the screen title */
.beta-badge {
  display: inline-block;
  vertical-align: middle;
  margin-left: 10px;
  font-size: 11px;
  font-weight: var(--fw-bold, 700);
  letter-spacing: 0.05em;
  text-transform: uppercase;
  padding: 3px 9px;
  border-radius: var(--radius-pill);
  background: rgba(250, 67, 56, 0.12);
  color: var(--envoy-red);
  position: relative;
  top: -2px;
}

/* ── Access control (Settings → Access Control tab) ───────────────────────
   Reuses .settings-section/.settings-card, so only the table, badges and
   add-form need defining here. */
.admin-error {
  margin: 0 0 20px; padding: 11px 15px; border-radius: var(--radius-md);
  background: #FDECEA; color: #8A2018; font-size: 13.5px; max-width: var(--content-max);
}
.admin-error.hidden { display: none; }

/* Wider than a Settings section (720px) and narrower than full-bleed: these
   are data tables, and the permission matrix needs room for one column per
   role. Matches the How To screen's use of the full content area. */
.admin-pane { max-width: var(--content-max); margin-bottom: 28px; }
.admin-pane.hidden { display: none; }
.admin-note {
  font-size: 13.5px; line-height: 1.6; color: var(--fg-3);
  margin: 0 0 24px; /* full pane width, like the cards below it */
}
.admin-list-title { margin-top: 28px; }

/* Add-someone form ------------------------------------------------------- */
.admin-add-card { padding: 12px; }
.admin-add-row .admin-select { flex: 0 0 auto; min-width: 140px; }
.admin-add-row { display: flex; gap: 10px; flex-wrap: wrap; align-items: center; }
.admin-input, .admin-select {
  font: inherit; font-size: 14px; padding: 9px 12px;
  border-radius: 8px; border: 1px solid var(--border-strong, var(--border));
  background: #fff; color: var(--fg-1);
}
.admin-input { flex: 1 1 260px; min-width: 200px; } /* fills the row; select and button keep their size */
.admin-input::placeholder { color: var(--fg-4, var(--fg-3)); }
.admin-input:focus, .admin-select:focus {
  outline: none; border-color: var(--envoy-red);
  box-shadow: 0 0 0 3px rgba(250, 67, 56, .12);
}
/* Native arrow sits far out at the box edge; draw our own, tucked in. */
.admin-select {
  appearance: none; -webkit-appearance: none;
  padding-right: 32px;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 24 24' fill='none' stroke='%236b7280' stroke-width='2.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='6 9 12 15 18 9'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 11px center;
  cursor: pointer;
}
/* .primary-btn is width:100% by default; keep it inline here. */
.admin-add-btn { width: auto; flex: 0 0 auto; align-self: stretch; } /* same height as the input and select */

/* People / permissions tables -------------------------------------------- */
.admin-table-wrap { overflow-x: auto; }
.admin-table { width: 100%; border-collapse: collapse; font-size: 14px; }
.admin-table th {
  text-align: left; font-size: 11px; text-transform: uppercase; letter-spacing: .07em;
  color: var(--fg-3); font-weight: var(--fw-bold, 700);
  background: var(--arctic);
  border-bottom: 1px solid var(--border);
  padding: 10px 18px; white-space: nowrap;
}
.admin-table td {
  border-bottom: 1px solid var(--border);
  padding: 13px 18px; vertical-align: middle; color: var(--fg-2);
}
.admin-table tbody tr:last-child td { border-bottom: none; }
.admin-table tbody tr:hover { background: var(--arctic); }
.admin-table .is-right { text-align: right; }
.admin-table .is-center { text-align: center; }
.admin-table select { max-width: 100%; }

/* Column widths, scoped per pane — the two tables want different shapes.
   People: Person takes the slack, the rest fixed, so a row reads as one line
   instead of drifting apart on a wide screen. */
#admin-pane-people .admin-table th:nth-child(2) { width: 18%; }
#admin-pane-people .admin-table th:nth-child(3) { width: 13%; }
#admin-pane-people .admin-table th:nth-child(4) { width: 14%; }

/* Matrix: the permission name takes the slack, every role column is equal. */
#admin-pane-roles .admin-table th:not(:first-child) { width: 10%; }

.admin-person-email { font-weight: var(--fw-semibold, 600); color: var(--fg-1); }
.admin-person-name { font-size: 12.5px; color: var(--fg-3); margin-top: 2px; }
.admin-role-static { font-weight: var(--fw-semibold, 600); color: var(--fg-1); }
.admin-you-pill {
  display: inline-block; vertical-align: middle;
  background: var(--carbon-10, #E7EAEF); color: var(--fg-3);
  border-radius: var(--radius-pill, 999px);
  padding: 1px 8px; font-size: 10.5px; font-weight: 700; margin-left: 8px;
  text-transform: uppercase; letter-spacing: .04em;
}
.admin-badge {
  display: inline-block; border-radius: var(--radius-pill, 999px);
  padding: 3px 10px; font-size: 11.5px; font-weight: 700; letter-spacing: .02em;
}
.admin-badge.is-active { background: #E8F5EC; color: #1B7F3B; }
.admin-badge.is-off    { background: #F1F3F6; color: var(--fg-3); }
.admin-empty { color: var(--fg-3); font-style: italic; padding: 18px; }

/* Permission-matrix cells ------------------------------------------------- */
/* The permission id, used as the row heading. Monospace because it is an
   identifier — the string an error message quotes and the one you'd grep for. */
.admin-perm-label {
  font-weight: var(--fw-semibold, 600); color: var(--fg-1);
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 13px; letter-spacing: -.01em;
}
/* The sentence that actually explains the checkbox. The three role columns are
   a fixed 150px each, so this one takes whatever is left — usually plenty. The
   cap only stops the measure running past readability on a wide window; it is
   deliberately above the column's usual width so it does NOT wrap early. */
.admin-table tr.admin-perm-section { cursor: pointer; }
.admin-table tr.admin-perm-section.is-single { cursor: default; }
.admin-table tr.admin-perm-section td {
  padding: 14px 18px;
  border-bottom: 1px solid var(--border);
}
.admin-table tr.admin-perm-section:focus-visible { outline: 2px solid rgba(250, 67, 56, 0.35); outline-offset: -2px; }
.admin-perm-head { display: flex; align-items: baseline; }
.admin-perm-head > .admin-perm-chevron { align-self: center; }
.admin-perm-chevron {
  display: inline-block; width: 14px; margin-right: 6px; flex-shrink: 0;
  color: var(--fg-3); font-size: 16px; line-height: 1;
  transition: transform 0.15s ease;
}
.admin-perm-section.is-open .admin-perm-chevron { transform: rotate(90deg); }
.admin-perm-section-title {
  display: inline;
  font-size: 14px; font-weight: var(--fw-semibold, 600); color: var(--fg-1);
}
.admin-perm-section-title svg { color: var(--fg-3); vertical-align: -2px; margin-right: 8px; }
.admin-perm-section-count { margin-left: 10px; font-size: 12px; color: var(--fg-3); }
.admin-perm-dirty {
  display: inline-block; width: 7px; height: 7px; margin-left: 8px; flex-shrink: 0;
  border-radius: 50%; background: var(--envoy-red);
}
.admin-table tr.admin-perm-row td { padding: 8px 18px; background: none; border-bottom: none; }
/* The group's last row closes it off with the usual divider. */
.admin-table tr.admin-perm-row:has(+ tr.admin-perm-section) td,
.admin-table tr.admin-perm-row:last-child td { border-bottom: 1px solid var(--border); padding-bottom: 12px; }
.admin-table tr.admin-perm-section.is-open td { border-bottom: none; }
.admin-table tr.admin-perm-row td:first-child { padding-left: 48px; }
.admin-perm-name { font-size: 13.5px; color: var(--fg-1); }
.admin-perm-info {
  position: relative;
  display: inline;
  margin-left: 6px; font-size: 12px; color: var(--fg-3); cursor: default;
}
.admin-perm-info:hover, .admin-perm-info:focus { color: var(--fg-1); outline: none; }
.admin-perm-tip {
  display: none;
  position: absolute; left: calc(100% + 10px); top: 50%; transform: translateY(-50%);
  z-index: 20;
  width: min(18.75rem, 40vw);
  padding: 10px 12px;
  background: var(--fg-1, #1f2937); color: #fff;
  border-radius: 8px;
  font-size: 12.5px; line-height: 1.45; white-space: normal;
  pointer-events: none;
}
.admin-perm-tip:empty { display: none !important; }
.admin-perm-info:hover .admin-perm-tip,
.admin-perm-info:focus .admin-perm-tip { display: block; }
/* Let the tooltip spill past the table instead of being clipped by it. */
#admin-pane-roles .admin-table-wrap { overflow: visible; }
.admin-perm-toggle-all {
  font: inherit; font-size: 11px; letter-spacing: .07em; text-transform: uppercase;
  color: var(--fg-3); background: none; border: 0; padding: 0; cursor: pointer;
}
.admin-perm-toggle-all:hover { color: var(--envoy-red); }
.admin-perm-desc {
  font-size: 12.5px; line-height: 1.45; color: var(--fg-3);
  margin-top: 3px; max-width: 78ch;
}
.admin-table input[type="checkbox"] { width: 15px; height: 15px; accent-color: var(--envoy-red); cursor: pointer; }
.admin-table input[type="checkbox"]:disabled { cursor: not-allowed; }

/* Save / reset row -------------------------------------------------------- */
.admin-save-row { display: flex; gap: 10px; margin-top: 20px; flex-wrap: wrap; align-items: center; }
.admin-save-row .primary-btn { width: auto; }
/* Says whether there is anything to save, so the disabled button isn't a
   mystery. Greys out when clean; picks up weight once something is pending. */
.admin-save-note { font-size: 12.5px; color: var(--fg-3); margin-left: 4px; }
.admin-save-note.is-dirty { color: var(--fg-2); font-weight: var(--fw-semibold, 600); }
.admin-save-hint { font-size: 12.5px; color: var(--fg-3); margin-left: auto; }
.admin-btn-ghost {
  font: inherit; font-weight: var(--fw-semibold, 600); font-size: 13px; padding: 7px 13px;
  border-radius: 8px; border: 1px solid var(--border-strong, var(--border));
  background: #fff; color: var(--fg-2); cursor: pointer;
  transition: background .15s, color .15s, border-color .15s;
}
.admin-btn-ghost:hover { color: var(--fg-1); background: var(--arctic); }
/* These two sit side by side, so they have to be the same box. .primary-btn is
   sized for full-width form submits (13px/22px padding, 14px bold) and
   .admin-btn-ghost for inline table actions (7px/13px, 13px) — next to each
   other that read as two different controls. Size them together here, and give
   the primary a transparent border so the 1px the ghost carries doesn't leave
   it 2px shorter. */
.admin-save-row .primary-btn,
.admin-save-row .admin-btn-ghost {
  width: auto;
  padding: 8px 18px;
  font-size: 14px;
  font-weight: var(--fw-semibold, 600);
  line-height: 20px;
  border-radius: 8px;
  border: 1px solid transparent;
}
.admin-save-row .admin-btn-ghost { border-color: var(--border-strong, var(--border)); }
.admin-btn-danger {
  font: inherit; font-weight: var(--fw-semibold, 600); font-size: 13px; padding: 7px 13px;
  border-radius: 8px; border: 1px solid #F3C9C5;
  background: #FFF6F5; color: #B3261E; cursor: pointer;
}
.admin-btn-danger:hover { background: #FDECEA; }
.admin-table button:disabled, .admin-table select:disabled,
.admin-btn-ghost:disabled, .admin-save-row .primary-btn:disabled { opacity: .5; cursor: not-allowed; }

/* The Envoy logo, stamped by Vidara in the same corner of every slide. The
   model is told to leave this corner empty. */
.html-slide-footer{
  position:absolute;left:44px;bottom:18px;z-index:5;pointer-events:none;
  display:flex;align-items:center;gap:10px;
  font-family:inherit;font-size:10px;line-height:1;color:#717684;
}
.html-slide-footer.is-dark{color:rgba(255,255,255,.72);}
/* Hold the footer band open even if the model forgets: its root keeps its
   height and background, but its content stops 56px above the bottom. */
.html-ai-canvas > :first-child:not(.html-slide-footer){
  box-sizing:border-box !important;padding-bottom:56px !important;
}
.html-slide-logo svg,.html-slide-logo img{display:block;height:16px;width:auto;}
.html-slide-logo:empty{display:none;}

/* Errors: same pill as #app-toast, but stays until its × is clicked. */
#app-error-toast{
  position:fixed;bottom:24px;transform:translateX(-50%);
  left:calc(var(--toast-inset, 0px) + (100% - var(--toast-inset, 0px)) / 2);
  display:none;align-items:center;gap:12px;
  max-width:min(640px,calc(100vw - var(--toast-inset, 0px) - 32px));
  background:var(--carbon-90);color:#fff;
  padding:10px 12px 10px 18px;border-radius:16px;
  border-left:4px solid var(--envoy-red,#FA4338);
  font-size:13px;font-weight:var(--fw-medium);line-height:1.4;
  z-index:401;box-shadow:var(--shadow-md);
}
#app-error-toast.toast-show{display:flex;}
#app-error-toast .toast-close{
  flex:none;background:none;border:0;color:inherit;opacity:.7;cursor:pointer;
  font-size:18px;line-height:1;padding:2px 4px;
}
#app-error-toast .toast-close:hover{opacity:1;}
/* A confirmation shown while an error is open sits above it, not on it. */
body.has-error-toast #app-toast{bottom:80px;}


/* ============================================================
   Artifact Dashboards (Beta) — list / upload / viewer
   ============================================================ */
#artdash-root { max-width: var(--content-max); }
#artdash-root:has(.artdash-vhead) { max-width: none; }
.artdash-back {
  display: inline-flex; align-items: center; gap: 4px;
  background: none; border: 0; padding: 4px 6px 4px 0; margin: 0 0 12px;
  color: var(--fg-3); font: inherit; font-size: 13px; font-weight: var(--fw-semibold); cursor: pointer;
}
.artdash-back:hover { color: var(--fg-1); }
.artdash-muted { color: var(--fg-3); font-size: 13px; }
.artdash-right { text-align: right; margin-top: 8px; }
.artdash-dot { color: var(--carbon-30); margin: 0 2px; }

/* toolbar */
.artdash-toolbar { display: flex; align-items: center; justify-content: space-between; gap: 16px; margin-bottom: 20px; flex-wrap: wrap; }
.artdash-seg { display: inline-flex; background: #fff; border: 1px solid var(--border); border-radius: var(--radius); padding: 3px; }
.artdash-seg-btn {
  border: 0; background: none; font: inherit; font-size: 13px; font-weight: var(--fw-semibold);
  color: var(--fg-3); padding: 6px 14px; border-radius: 6px; cursor: pointer;
}
.artdash-seg-btn:hover { color: var(--fg-1); }
.artdash-seg-btn.active { background: var(--arctic); color: var(--fg-1); box-shadow: inset 0 0 0 1px var(--border); }
.artdash-search {
  display: inline-flex; align-items: center; gap: 8px; min-width: min(16rem, 100%);
  background: #fff; border: 1px solid var(--border); border-radius: var(--radius); padding: 0 12px; color: var(--fg-3);
}
.artdash-search:focus-within { border-color: var(--carbon-30); }
.artdash-search input { border: 0; outline: none; font: inherit; font-size: 14px; padding: 9px 0; flex: 1; background: none; color: var(--fg-1); }

/* grid + cards */
.artdash-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(260px, 1fr)); gap: 16px; }
.artdash-card {
  display: flex; flex-direction: column; gap: 8px; min-height: 170px;
  background: #fff; border: 1px solid var(--border-subtle); border-radius: var(--radius-md);
  padding: 18px; color: inherit; text-decoration: none;
  transition: border-color .15s, box-shadow .15s, transform .1s;
}
.artdash-card:hover { border-color: var(--carbon-20); box-shadow: 0 8px 24px -12px rgba(31,35,45,.25); transform: translateY(-1px); }
.artdash-card:focus-visible { outline: 2px solid var(--envoy-red); outline-offset: 2px; }
.artdash-card-top { display: flex; align-items: center; justify-content: space-between; }
.artdash-card-icon {
  width: 34px; height: 34px; border-radius: 9px; display: grid; place-items: center;
  background: rgba(250, 67, 56, 0.10); color: var(--envoy-red);
}
.artdash-card-title { margin: 4px 0 0; font-size: 16px; font-weight: var(--fw-bold); color: var(--fg-1); line-height: 1.3; }
.artdash-card-desc { margin: 0; font-size: 13px; color: var(--fg-3); line-height: 1.45; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }
.artdash-card-foot { margin-top: auto; display: flex; align-items: center; justify-content: space-between; gap: 8px; font-size: 12px; color: var(--fg-3); }
.artdash-card-owner { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.artdash-status { display: inline-flex; align-items: center; gap: 6px; }
.artdash-status::before { content: ""; width: 7px; height: 7px; border-radius: 50%; background: #1f9d55; }
.artdash-status.warn::before { background: #d97706; }
.artdash-status.muted::before { background: var(--carbon-30); }
/* Partly failed refresh: an amber triangle in the dot's place; hover says how many. */
.artdash-status.has-warn::before { content: none; }
.artdash-refresh-warn { display: inline-flex; align-items: center; justify-content: center; width: 12px; margin-left: -2.5px; color: #d97706; cursor: default; }
.artdash-refresh-warn svg { display: block; }
.artdash-refresh-warn:focus-visible { outline: 2px solid var(--envoy-red); outline-offset: 2px; border-radius: 3px; }
.artdash-chip {
  display: inline-flex; align-items: center; gap: 5px; font-size: 11px; font-weight: var(--fw-semibold);
  color: var(--fg-2); background: var(--arctic); border: 1px solid var(--border-subtle);
  padding: 3px 8px; border-radius: var(--radius-pill); white-space: nowrap;
}
/* list page: Recent Activity tiles, then the same toolbar and table as Deck Presets */
.artdash-recent { margin-bottom: 24px; }
.artdash-recent.hidden { display: none; }
.artdash-recent-title {
  margin: 0 0 10px; font-size: 12px; font-weight: var(--fw-semibold); letter-spacing: .06em;
  text-transform: uppercase; color: var(--fg-3);
}
.artdash-recent-empty { margin: 0; font-size: 13px; color: var(--fg-3); }
.artdash-recent-grid { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 12px; }
@media (max-width: 1100px) { .artdash-recent-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
/* Each item is a white tile filling its column, so the strip reads as four equal slots. */
.artdash-rcard {
  display: flex; align-items: center; gap: 10px; min-width: 0; padding: 6px;
  background: #fff; border: 1px solid var(--border-subtle); border-radius: var(--radius);
  color: inherit; text-decoration: none; transition: border-color .15s;
}
.artdash-rcard:hover { border-color: var(--carbon-30); }
.artdash-rcard:focus-visible { outline: 2px solid var(--envoy-red); outline-offset: 2px; }
/* Small live thumbnail of the dashboard's first screen. */
.artdash-rcard-preview {
  position: relative; display: block; flex-shrink: 0; width: 88px; aspect-ratio: 16 / 9; overflow: hidden;
  background: var(--border-subtle); border-radius: 5px;
}
/* Edge drawn over the iframe, which would otherwise cover an inset shadow. */
.artdash-rcard-preview::after {
  content: ""; position: absolute; inset: 0; z-index: 1; border-radius: inherit; pointer-events: none;
  box-shadow: inset 0 0 0 1px var(--border-subtle);
}
/* Static snapshot: no scrolling, clicks go to the card link. */
.artdash-rcard-frame {
  position: absolute; top: 0; left: 0; border: 0; transform-origin: 0 0;
  pointer-events: none; opacity: 0; transition: opacity .2s;
}
.artdash-rcard-preview.loaded .artdash-rcard-frame { opacity: 1; }
.artdash-rcard-text { display: flex; flex-direction: column; gap: 1px; min-width: 0; }
.artdash-rcard-title { font-size: 13px; font-weight: var(--fw-semibold); color: var(--fg-1); line-height: 1.35; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.artdash-rcard-meta { font-size: 12px; color: var(--fg-3); line-height: 1.35; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* Toolbar: Deck Presets' (#screen-saved), so the count, slim search and
   filter line up the same way on both pages. */
.artdash-list-toolbar .saved-toolbar-left { display: flex; align-items: center; gap: 16px; min-width: 0; }
.artdash-list-toolbar #artdash-count { position: relative; top: -1px; }
.artdash-list-toolbar .sch-filter { flex-shrink: 0; white-space: nowrap; }
.artdash-list-toolbar .sch-filter .artdash-seg-btn { padding-top: 5px; padding-bottom: 5px; }
.artdash-list-toolbar .saved-search { width: 200px; max-width: 100%; min-width: 0; height: 32px; box-sizing: border-box; padding: 0 10px; gap: 6px; }
.artdash-list-toolbar .saved-search svg { width: 14px; height: 14px; flex-shrink: 0; }
.artdash-list-toolbar .saved-search input { width: 100%; min-width: 0; height: 100%; padding: 2.5px 0 0; box-sizing: border-box; font-size: 13px; }
@media (max-width: 900px) {
  .artdash-list-toolbar { flex-wrap: wrap; }
  .artdash-list-toolbar .saved-toolbar-left { flex: 1 1 100%; }
}
/* Table: Deck Presets' .preset-table; the whole row opens the dashboard.
   Name · Last Refreshed · Owner · Last Activity */
.artdash-ptable .preset-row { grid-template-columns: 12px minmax(0, 1.1fr) minmax(0, 0.85fr) minmax(0, 1fr) minmax(0, 1.25fr); column-gap: 12px; padding-left: 14px; padding-right: 16px; }
/* Name hugs its star: 8px apart instead of the 12px between other columns (header too). */
.artdash-ptable .preset-row > :nth-child(2) { margin-left: -4px; }
/* The star (Schedules' .sch-fav-btn) in a narrow column before Name; negative
   margins so its padding doesn't grow the row or push the name right. */
.artdash-star-cell { display: flex; justify-content: center; }
.artdash-star-cell .sch-fav-btn { margin: -6px; }
/* Smaller than Schedules' 16px star, to sit with the 13px row text. */
.artdash-star-cell .sch-fav-btn svg { width: 12px; height: 12px; }
/* Unstarred: a light outline, so a column of empty stars stays quiet. Hover and
   starred keep Schedules' amber. */
.artdash-star-cell .sch-fav-btn:not(.sch-fav-btn--on) { color: var(--carbon-30); }
.artdash-star-cell .sch-fav-btn:not(.sch-fav-btn--on):hover { color: #d97706; }
/* A little more air than Deck Presets' 6px rows: fewer, wider rows here. */
.artdash-ptable .preset-body .preset-row { padding-top: 9px; padding-bottom: 9px; }
.artdash-ptable .preset-owner,
.artdash-ptable .artdash-pact { color: var(--fg-1); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
/* What happened reads first; when, quieter after it. */
.artdash-ptable .artdash-pact-when { color: var(--fg-3); }
.artdash-status-by { color: var(--fg-3); }
/* Block-level, not inline: inline, a row whose status starts with the
   triangle (no text) took the icon's bottom as its baseline and grew taller. */
.artdash-ptable .artdash-status { display: flex; }
/* Sofia Pro draws its letters ~1.5px above the middle of their line, so a
   box-centred status dot sits low beside the words. Lift it onto the text's
   centre line, the same nudge as Deck Presets' warning icon (.preset-stale-flag svg).
   Not the triangle: its weight sits in its wide base, so box-centred it
   already reads level with the text. */
.artdash-ptable .artdash-status::before { position: relative; top: -1.5px; }
@media (max-width: 760px) {
  .artdash-ptable .preset-row { grid-template-columns: 12px minmax(0, 1.4fr) minmax(0, 1fr); }
  .artdash-ptable .preset-row > :nth-child(4), .artdash-ptable .preset-row > :nth-child(5) { display: none; }
}

/* upload */
.artdash-drop {
  background: #fff; border: 1.5px dashed var(--border-strong); border-radius: var(--radius-md);
  padding: 40px 24px; text-align: center; cursor: pointer; transition: border-color .15s, background .15s, padding .2s;
}
.artdash-drop:hover, .artdash-drop:focus-visible, .artdash-drop.dragging { border-color: var(--envoy-red); background: rgba(250,67,56,.03); outline: none; }
.artdash-drop.compact { padding: 16px 24px; }
.artdash-drop.compact .artdash-drop-icon, .artdash-drop.compact .artdash-drop-sub { display: none; }
.artdash-drop.compact .artdash-drop-title { display: inline; margin-right: 12px; }
.artdash-drop.compact .artdash-drop-actions { display: inline-flex; }
.artdash-drop-icon { color: var(--envoy-red); margin-bottom: 8px; }
.artdash-drop-title { margin: 0; font-weight: var(--fw-semibold); color: var(--fg-1); }
.artdash-drop-sub { margin: 6px 0 10px; color: var(--fg-3); font-size: 13px; }
.artdash-drop-actions { display: inline-flex; gap: 8px; }
.artdash-panel { background: #fff; border: 1px solid var(--border-subtle); border-radius: var(--radius-md); padding: 20px; margin-top: 16px; }
.artdash-panel-head { display: flex; align-items: baseline; gap: 12px; margin-bottom: 12px; flex-wrap: wrap; }
.artdash-panel-head h3 { margin: 0; font-size: 15px; color: var(--fg-1); }
.artdash-field { margin-bottom: 16px; border: 0; padding: 0; min-width: 0; }
.artdash-field:last-child { margin-bottom: 0; }
.artdash-field.hidden { display: none; }
.artdash-field .modal-field-label { display: block; margin-bottom: 6px; }
.artdash-input {
  width: 100%; box-sizing: border-box; font: inherit; font-size: 14px; color: var(--fg-1);
  border: 1px solid var(--border-strong); border-radius: var(--radius); padding: 10px 12px; background: #fff; resize: vertical;
}
.artdash-input:focus { outline: none; border-color: var(--envoy-red); box-shadow: 0 0 0 3px rgba(250,67,56,.12); }
.artdash-vis { display: grid; grid-template-columns: repeat(3, 1fr); gap: 8px; }
.artdash-vis legend { grid-column: 1 / -1; }
.artdash-vis-opt {
  display: flex; gap: 10px; align-items: flex-start; padding: 12px; cursor: pointer;
  border: 1px solid var(--border); border-radius: var(--radius); background: #fff; transition: border-color .15s, background .15s;
}
.artdash-vis-opt:has(input:checked) { border-color: var(--envoy-red); background: rgba(250,67,56,.04); }
.artdash-vis-opt input { position: absolute; opacity: 0; pointer-events: none; }
.artdash-vis-opt:has(input:focus-visible) { outline: 2px solid var(--envoy-red); outline-offset: 2px; }
.artdash-vis-icon { color: var(--fg-3); padding-top: 1px; }
.artdash-vis-opt:has(input:checked) .artdash-vis-icon { color: var(--envoy-red); }
.artdash-vis-opt strong { display: block; font-size: 13px; color: var(--fg-1); }
.artdash-vis-opt small { display: block; font-size: 12px; color: var(--fg-3); margin-top: 2px; line-height: 1.35; }
.artdash-qtable { border: 1px solid var(--border-subtle); border-radius: var(--radius); overflow: hidden; }
.artdash-q + .artdash-q { border-top: 1px solid var(--border-subtle); }
.artdash-q summary {
  display: grid; grid-template-columns: 10px minmax(120px, 1.1fr) minmax(0, 1.4fr) minmax(0, 1fr) auto;
  align-items: center; gap: 12px; padding: 10px 14px; cursor: pointer; list-style: none; font-size: 13px;
}
.artdash-q summary::-webkit-details-marker { display: none; }
.artdash-q summary:hover { background: var(--arctic); }
.artdash-q-dot { width: 8px; height: 8px; border-radius: 50%; background: #1f9d55; }
.artdash-q.bad .artdash-q-dot { background: var(--garnet-70, #a00c1f); }
.artdash-q-key { font-size: 12px; color: var(--fg-1); overflow: hidden; text-overflow: ellipsis; }
.artdash-q-name, .artdash-q-file { color: var(--fg-3); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.artdash-q-msg { color: #1f9d55; font-weight: var(--fw-semibold); font-size: 12px; white-space: nowrap; }
.artdash-q.bad .artdash-q-msg { color: var(--garnet-70, #a00c1f); white-space: normal; }
.artdash-sql {
  margin: 0; padding: 12px 14px; background: #0f1724; color: #dbe4f0; font-size: 12px; line-height: 1.5;
  max-height: 35vh; overflow: auto; white-space: pre; font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
}
.artdash-actions { display: flex; justify-content: flex-end; gap: 10px; margin-top: 20px; }
.artdash-actions .primary-btn { width: auto; }
.artdash-error { color: var(--garnet-70, #a00c1f); background: rgba(160,12,31,.05); border: 1px solid rgba(160,12,31,.2); border-radius: var(--radius); padding: 10px 12px; font-size: 13px; margin: 12px 0 0; }
.artdash-error.hidden { display: none; }
.artdash-error ul { margin: 6px 0 0; padding-left: 18px; }
.artdash-warn { color: #92400e; background: #fffbeb; border: 1px solid #fde68a; border-radius: var(--radius); padding: 10px 12px; font-size: 13px; margin: 16px 0 0; }

/* viewer */
.artdash-vhead { display: flex; align-items: flex-start; justify-content: space-between; gap: 20px; margin-bottom: 14px; flex-wrap: wrap; }
.artdash-vhead-text { min-width: 0; flex: 1 1 420px; }
.artdash-vtitle { margin: 0 0 6px; font-size: 24px; line-height: 1.25; font-weight: var(--fw-bold); color: var(--fg-1); letter-spacing: -0.02em; }
.artdash-vmeta { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; font-size: 13px; color: var(--fg-3); }
.artdash-vactions { display: flex; gap: 8px; flex-wrap: wrap; }
.artdash-vactions .primary-btn { width: auto; padding: 7px 14px; font-size: 13px; }
.artdash-vactions .secondary-btn.on { background: var(--arctic); border-color: var(--carbon-30); }
/* Icon-only secondary actions (Queries, Share, Download, ⋯): square, same height as Refresh Data. */
.artdash-vactions .artdash-icon-action { display: inline-flex; align-items: center; justify-content: center; padding: 7px 9px; }
.artdash-vactions .artdash-icon-action svg { display: block; }
.artdash-vactions .primary-btn.spinning svg { animation: artdash-spin 0.9s linear infinite; }
.artdash-banner { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; padding: 10px 14px; border-radius: var(--radius); font-size: 13px; margin-bottom: 12px; }
.artdash-banner.warn { color: #92400e; background: #fffbeb; border: 1px solid #fde68a; }
.artdash-link { background: none; border: 0; padding: 0; font: inherit; font-weight: var(--fw-semibold); color: inherit; text-decoration: underline; cursor: pointer; }
/* Two tracks always, so opening the Queries drawer can ease its column open
   instead of jumping; the closed track is 0 wide with no gap. */
.artdash-body {
  display: grid; grid-template-columns: minmax(0, 1fr) 0px; column-gap: 0; row-gap: 16px;
  transition: grid-template-columns .28s cubic-bezier(.2, .8, .2, 1), column-gap .28s cubic-bezier(.2, .8, .2, 1);
}
.artdash-body.hidden { display: none; }
.artdash-body.with-drawer { grid-template-columns: minmax(0, 1fr) clamp(18rem, 28%, 26rem); column-gap: 16px; }
#artdash-drawer-slot { min-width: 0; overflow: hidden; }
/* Keep the panel full width while its column narrows, so it slides rather than squashes. */
#artdash-drawer-slot .artdash-drawer { min-width: 18rem; }
.artdash-drawer.entering { animation: artdash-drawer-in .28s cubic-bezier(.2, .8, .2, 1); }
@keyframes artdash-drawer-in { from { opacity: 0; transform: translateX(24px); } }
@media (prefers-reduced-motion: reduce) {
  .artdash-body { transition: none; }
  .artdash-drawer.entering { animation: none; }
}
.artdash-frame-wrap {
  position: relative; background: #fff; border: 1px solid var(--border-subtle); border-radius: var(--radius-md);
  overflow: hidden; height: calc(100vh - 210px); min-height: 60vh;
}
.artdash-frame { width: 100%; height: 100%; border: 0; display: block; background: #fff; }
.artdash-frame-overlay {
  position: absolute; inset: 0; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 12px;
  background: rgba(255,255,255,.72); backdrop-filter: blur(2px); color: var(--fg-2); font-size: 14px; font-weight: var(--fw-semibold);
}
.artdash-frame-overlay.hidden { display: none; }
/* Spinner and text on one line; Cancel sits underneath. */
.artdash-overlay-row { display: flex; align-items: center; gap: 10px; }
.artdash-spinner { width: 18px; height: 18px; border-radius: 50%; border: 2px solid var(--carbon-20); border-top-color: var(--envoy-red); animation: artdash-spin 0.8s linear infinite; }
@keyframes artdash-spin { to { transform: rotate(360deg); } }
.artdash-drawer {
  background: #fff; border: 1px solid var(--border-subtle); border-radius: var(--radius-md); padding: 16px;
  height: calc(100vh - 210px); min-height: 60vh; overflow-y: auto; box-sizing: border-box;
}
.artdash-drawer-head { display: flex; align-items: center; justify-content: space-between; }
.artdash-drawer-head h3 { margin: 0; font-size: 15px; color: var(--fg-1); }
.artdash-drawer > .artdash-muted { margin: 4px 0 12px; }
.artdash-icon-btn { background: none; border: 0; color: var(--fg-3); padding: 4px; border-radius: 6px; cursor: pointer; display: grid; place-items: center; }
.artdash-icon-btn:hover { background: var(--arctic); color: var(--fg-1); }
/* Inline in the upload popup's subtitle, sitting on the text line. */
.artdash-copy-prompt { display: inline-grid; vertical-align: -3px; margin: -4px 0; color: var(--fg-2); }
.artdash-dq { border: 1px solid var(--border-subtle); border-radius: var(--radius); margin-bottom: 8px; overflow: hidden; }
.artdash-dq summary { display: flex; align-items: center; justify-content: space-between; gap: 8px; padding: 10px 12px; cursor: pointer; font-size: 13px; }
.artdash-dq summary code { overflow: hidden; text-overflow: ellipsis; }
.artdash-dq-name { margin: 0; padding: 0 12px 8px; font-size: 12px; color: var(--fg-3); }
.artdash-dq .artdash-error { margin: 0 12px 10px; }
/* The query a clicked number came from. */
.artdash-dq.is-focused { border-color: var(--envoy-red); background: color-mix(in srgb, var(--envoy-red) 6%, transparent); }
.artdash-pill { font-size: 11px; font-weight: var(--fw-semibold); padding: 2px 8px; border-radius: var(--radius-pill); background: var(--arctic); color: var(--fg-3); white-space: nowrap; }
.artdash-pill.ok { background: #ecfdf3; color: #157347; }
.artdash-pill.bad { background: rgba(160,12,31,.08); color: var(--garnet-70, #a00c1f); }
.artdash-modal .modal { max-width: 40rem; }
.artdash-modal-body { padding: 8px 28px 4px; }
/* Upload Dashboard popup: wide enough for the preview beside the details;
   the body scrolls between the pinned header and buttons. */
.modal-overlay.artdash-upload-modal > .modal { max-width: 45rem; }
/* Once a folder is read, wide enough for the preview beside the details (app.js _artdashAccept). */
.modal-overlay.artdash-upload-modal.is-review > .modal { max-width: min(64rem, calc(100vw - 32px)); }
/* Its Details / Queries tabs (Edit Slide's .slide-edit-tabs), under the title. */
.artdash-up-tabs { margin-top: 12px; }
.artdash-up-count { display: inline-block; min-width: 18px; padding: 0 5px; margin-left: 4px; border-radius: 9px; background: var(--arctic); color: var(--fg-3); font-size: 11px; line-height: 18px; text-align: center; }
.slide-edit-tab.active .artdash-up-count { background: rgba(250, 67, 56, 0.10); color: var(--envoy-red); }
.artdash-up-count.bad { background: var(--envoy-red); color: #fff; }
/* Set only while the popup grows from the drop box to the review (app.js _artdashAccept). */
.artdash-upload-modal .modal.artdash-resizing { transition: height .45s cubic-bezier(.4, 0, .2, 1), max-width .45s cubic-bezier(.4, 0, .2, 1); }
.artdash-upload-body { padding-bottom: 16px; }
.artdash-upload-body > * { flex-shrink: 0; }
.artdash-upload-body .artdash-drop { margin-top: 4px; }
/* Review (app.js _artdashPaintReview): preview + folder on the left, the
   details on the right; no boxes inside the popup's box. */
.artdash-up-grid { display: grid; grid-template-columns: minmax(0, 1.15fr) minmax(0, 1fr); gap: 24px; align-items: start; margin-top: 8px; }
.artdash-up-side { display: flex; flex-direction: column; gap: 4px; min-width: 0; }
.artdash-up-preview {
  position: relative; display: block; width: 100%; aspect-ratio: 16 / 10; overflow: hidden; margin-bottom: 8px;
  background: var(--arctic); border-radius: var(--radius);
}
.artdash-up-preview::after { content: ""; position: absolute; inset: 0; border-radius: inherit; box-shadow: inset 0 0 0 1px var(--border-subtle); pointer-events: none; }
.artdash-up-preview.loaded .artdash-rcard-frame { opacity: 1; }
.artdash-up-file { display: flex; align-items: baseline; justify-content: space-between; gap: 8px; min-width: 0; }
.artdash-up-name { font-size: 13px; font-weight: var(--fw-semibold); color: var(--fg-1); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.artdash-up-change { flex-shrink: 0; font-size: 13px; color: var(--fg-2); }
.artdash-up-meta { font-size: 12px; color: var(--fg-3); }
.artdash-up-ok { color: #157347; font-weight: var(--fw-semibold); }
.artdash-up-bad { font-size: 12px; font-weight: var(--fw-semibold); color: var(--envoy-red); }
/* Spaced like the New Schedule form (.sch-form-body): 12px between fields,
   label 4px above its .modal-input. */
.artdash-up-fields { display: flex; flex-direction: column; gap: 12px; }
.artdash-up-fields .artdash-field { margin: 0; }
.artdash-up-fields .artdash-field .modal-field-label { display: block; margin-bottom: 4px; }
.artdash-up-fields textarea.modal-input { resize: vertical; line-height: 1.45; }
/* Who Can See It: the sliding switcher, spread across the field. */
.artdash-up-vis { display: flex; width: 100%; box-sizing: border-box; }
.artdash-up-vis .artdash-seg-btn { flex: 1; padding-top: 5px; padding-bottom: 5px; white-space: nowrap; }
.artdash-up-hint { margin: 8px 0 10px; font-size: 12px; }
.artdash-up-alert { display: inline-block; width: 6px; height: 6px; margin-left: 5px; border-radius: 50%; background: var(--envoy-red); vertical-align: 2px; }
/* Data tab: Queries and Parameters, each a section that folds open and shut. */
.artdash-up-section { border-bottom: 1px solid var(--border-subtle); padding: 12px 0; }
.artdash-up-section:first-child { padding-top: 6px; }
.artdash-up-section:last-child { border-bottom: 0; padding-bottom: 0; }
.artdash-up-summary {
  display: flex; align-items: center; gap: 6px; list-style: none; cursor: pointer; user-select: none;
  font-size: 14px; font-weight: var(--fw-semibold); color: var(--fg-1);
}
.artdash-up-summary::-webkit-details-marker { display: none; }
.artdash-up-summary .artdash-up-count { margin-left: 2px; }
.artdash-up-chev { color: var(--fg-3); transition: transform .2s ease; }
.artdash-up-section[open] > .artdash-up-summary .artdash-up-chev { transform: rotate(90deg); }
.artdash-up-summary:focus { outline: none; }
.artdash-up-summary:focus-visible { outline: 2px solid var(--envoy-red); outline-offset: 2px; border-radius: 4px; }
.artdash-up-side .artdash-up-bad { text-align: left; font-size: 12px; }
@media (max-width: 640px) { .artdash-up-grid { grid-template-columns: minmax(0, 1fr); } }
@media (max-width: 900px) {
  .artdash-body, .artdash-body.with-drawer { grid-template-columns: minmax(0, 1fr); column-gap: 0; }
  #artdash-drawer-slot .artdash-drawer { min-width: 0; }
  .artdash-vis { grid-template-columns: 1fr; }
  .artdash-q summary { grid-template-columns: 10px 1fr auto; }
  .artdash-q-name, .artdash-q-file { display: none; }
}
.artdash-params { display: grid; grid-template-columns: repeat(auto-fill, minmax(220px, 1fr)); gap: 10px; }
.artdash-param { display: flex; flex-direction: column; gap: 4px; font-size: 12px; color: var(--fg-2); }
.artdash-param .artdash-input { padding: 8px 10px; font-size: 13px; }
.artdash-param .artdash-input[readonly] { background: var(--arctic); color: var(--fg-2); }
.artdash-drawer-params { border: 1px solid var(--border-subtle); border-radius: var(--radius); padding: 12px; margin-bottom: 12px; background: var(--arctic); }
.artdash-drawer-params h4 { margin: 0 0 8px; font-size: 13px; color: var(--fg-1); }
.artdash-drawer-params .artdash-params { grid-template-columns: 1fr; margin-bottom: 10px; }
.artdash-drawer-params .artdash-input { background: #fff; }
/* Drawer parameters reuse .preset-filter-chip (Deck Presets' Default Filters). */
.artdash-pchips-wrap { margin-bottom: 12px; }
.artdash-pchips.preset-filters { margin-top: 0; }
.preset-filter-chip.is-readonly { cursor: default; }
.preset-filter-chip.is-readonly:hover { border-color: var(--border); }
.artdash-pchips-hint { margin: 6px 0 0; font-size: 11px; color: var(--fg-3); }

/* Roles & permissions matrix: role columns stay narrow and fixed; the name
   column takes the rest, so section headers sit on one line. */
#admin-pane-roles .admin-table th.is-center,
#admin-pane-roles .admin-table td.is-center { width: 10%; padding-left: 8px; padding-right: 8px; }
#admin-pane-roles tr.admin-perm-section td:first-child { white-space: nowrap; }
#admin-pane-roles tr.admin-perm-row td:first-child { white-space: nowrap; }


/* ─── Slate (Beta): SQL -> AI-designed Google Slides deck ─────────────────────────────── */
/* Same fluid frame as Generate Slides (.page-content .main): page gutters
   and full content width, not the fixed 40px/56px secondary-screen padding. */
#screen-slate,
#screen-dashboards { padding: var(--page-pad-top) var(--page-pad-x) calc(var(--page-pad-top) * 1.4); }
#slate-root { max-width: var(--content-max); }
/* Step sections sit inside the shared .main-card, so they drop their own card chrome. */
#slate-body .slate-card { border: 0; padding: 0; border-radius: 0; background: none; max-width: none !important; }
.slate-card { background: #fff; border: 1px solid var(--border-subtle); border-radius: var(--radius-md); padding: 20px; }
.slate-h { font-size: 16px; font-weight: var(--fw-semibold, 600); color: var(--fg-1); margin: 0 0 14px; }
.slate-row { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.slate-grow { flex: 1; }
.slate-actions { display: flex; align-items: center; gap: 8px; margin-top: 16px; flex-wrap: wrap; }
.slate-btn { width: auto; padding: 9px 18px; font-size: 13px; text-decoration: none; display: inline-flex; align-items: center; gap: 6px; white-space: nowrap; }
.slate-btn.small { padding: 7px 14px; }
.slate-label { font-size: 11px; font-weight: var(--fw-semibold, 600); letter-spacing: .06em; text-transform: uppercase; color: var(--fg-3); margin: 16px 0 8px; }
.slate-hint { display: block; font-size: 12px; margin-top: 4px; }
.slate-chip { display: inline-flex; align-items: center; gap: 5px; font-size: 12px; padding: 3px 9px; border-radius: 999px; background: var(--arctic); color: var(--fg-2); border: 1px solid var(--border-subtle); }
.slate-chip.lock { background: #fff7ed; color: #9a3412; border-color: #fed7aa; }
.slate-soon { font-size: 11px; font-weight: 600; color: var(--fg-3); background: var(--arctic); border-radius: 999px; padding: 1px 7px; margin-left: 4px; }
.slate-ok { font-size: 12px; color: #15803d; }
.slate-okbig { width: 32px; height: 32px; border-radius: 50%; background: #ecfdf3; color: #15803d; display: grid; place-items: center; font-weight: 700; }
.slate-choices { display: grid; grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); gap: 12px; }
.slate-choice { text-align: left; display: flex; flex-direction: column; gap: 6px; padding: 16px; border-radius: var(--radius-md); border: 1px solid var(--border-subtle); background: #fff; cursor: pointer; font: inherit; color: var(--fg-2); font-size: 13px; }
.slate-choice strong { color: var(--fg-1); font-size: 14px; }
.slate-choice.sel { border-color: var(--envoy-red); box-shadow: 0 0 0 3px rgba(250,67,56,.12); }
.slate-choice:disabled { cursor: not-allowed; opacity: .6; }
.slate-title-input { max-width: 360px; font-weight: var(--fw-semibold, 600); }
.slate-code { margin: 0; padding: 14px 16px; background: #0f1724; color: #dbe4f0; border-radius: 8px; font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 13px; line-height: 1.6; overflow: auto; white-space: pre; max-height: 360px; }
.slate-kw { color: #ff8a80; }
.slate-fn { color: #9ecbff; }
.slate-grid2 { display: grid; grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); gap: 0 14px; }
.slate-opts { border: 0; padding: 0; margin: 0; }
.slate-cb { display: flex; align-items: center; gap: 8px; font-size: 13px; color: var(--fg-2); padding: 3px 0; }
.slate-split { display: flex; gap: 16px; flex-wrap: wrap; align-items: flex-start; }
.slate-slide { flex: 999 1 520px; min-width: 0; aspect-ratio: 16 / 9; background: #fff; border: 1px solid var(--border-subtle); border-radius: var(--radius-md); box-shadow: 0 8px 24px rgba(16,24,40,.06); padding: 4% 5%; box-sizing: border-box; display: flex; flex-direction: column; position: relative; overflow: hidden; }
#slate-live .slate-slide { width: 100%; }
.slate-slide-logo { position: absolute; top: 4%; right: 5%; font-size: 11px; font-weight: 800; letter-spacing: .14em; color: var(--envoy-red); }
.slate-slide-h { font-size: clamp(16px, 2.2vw, 24px); line-height: 1.2; margin: 0 60px 6px 0; color: var(--fg-1); }
.slate-slide-s { font-size: 13px; color: var(--fg-2); margin: 0 0 8px; }
.slate-slide-chart { flex: 1; min-height: 0; display: flex; align-items: center; justify-content: center; }
.slate-chart { width: 100%; height: 100%; max-height: 100%; }
.slate-slide-foot { display: flex; justify-content: space-between; font-size: 10px; color: var(--fg-3); border-top: 1px solid var(--border-subtle); padding-top: 6px; }
.slate-kpis { display: flex; gap: 24px; justify-content: center; flex-wrap: wrap; width: 100%; }
.slate-kpi { text-align: center; min-width: 140px; }
.slate-kpi-v { font-size: clamp(36px, 6vw, 64px); font-weight: 800; color: var(--fg-1); }
.slate-kpi-l { font-size: 13px; color: var(--fg-3); }
.slate-mini-table { border-collapse: collapse; font-size: 11px; width: 100%; }
.slate-mini-table th, .slate-mini-table td { padding: 4px 8px; border-bottom: 1px solid var(--border-subtle); text-align: left; }
.slate-panel { flex: 1 1 280px; background: #fff; border: 1px solid var(--border-subtle); border-radius: var(--radius-md); padding: 16px; box-sizing: border-box; }
.slate-panel h4 { font-size: 12px; text-transform: uppercase; letter-spacing: .06em; color: var(--fg-3); margin: 14px 0 8px; }
.slate-panel h4:first-child { margin-top: 0; }
.slate-p { font-size: 13px; color: var(--fg-2); line-height: 1.5; margin: 0 0 8px; }
.slate-kc { display: flex; gap: 8px; align-items: baseline; font-size: 13px; color: var(--fg-2); padding: 4px 0; }
.slate-kc b { min-width: 70px; }
.slate-kc.up b { color: #15803d; }
.slate-kc.down b { color: #b42318; }
.slate-kc.flat b { color: var(--fg-3); }
.slate-list { border: 1px solid var(--border-subtle); border-radius: 8px; overflow: hidden; }
.slate-li { display: flex; align-items: center; gap: 10px; padding: 10px 12px; border-bottom: 1px solid var(--border-subtle); }
.slate-li:last-child { border-bottom: 0; }
.slate-li-n { font-family: ui-monospace, monospace; color: var(--fg-3); font-size: 12px; }
.slate-li-main { flex: 1; min-width: 0; display: flex; flex-direction: column; font-size: 13px; }
.slate-li-main strong { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; color: var(--fg-1); }
.slate-progress { margin-top: 14px; font-size: 13px; color: var(--fg-2); display: flex; flex-direction: column; gap: 6px; }
.slate-progress .now { display: flex; align-items: center; gap: 8px; color: var(--fg-1); font-weight: var(--fw-semibold, 600); }
.slate-progress .now .artdash-spinner { width: 14px; height: 14px; }
.slate-progress .done { color: #15803d; }
.slate-url { flex: 1; min-width: 0; font-family: ui-monospace, monospace; font-size: 12.5px; }
.slate-draft-chip { border: 1px solid #fed7aa; background: #fff7ed; color: #9a3412; border-radius: 999px; padding: 6px 12px; font: inherit; font-size: 12.5px; font-weight: 600; cursor: pointer; }
@media (max-width: 640px) {
  .slate-card { padding: 16px; }
}
.slate-editor {
  display: block; width: 100%; box-sizing: border-box; min-height: 220px; resize: vertical; border: 0; outline: none; border-radius: 8px;
  padding: 14px 16px; background: #0f1724; color: #dbe4f0; caret-color: #fff;
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 13px; line-height: 1.6; tab-size: 2;
}
.slate-editor:focus { box-shadow: inset 0 0 0 2px rgba(250,67,56,.5); }
.slate-grid-wrap { overflow: auto; max-height: 60vh; border: 1px solid var(--border-subtle); border-radius: 8px; }
.slate-grid { border-collapse: separate; border-spacing: 0; font-size: 12.5px; width: max-content; min-width: 100%; }
.slate-grid th, .slate-grid td { padding: 7px 12px; border-bottom: 1px solid var(--border-subtle); text-align: left; white-space: nowrap; max-width: 420px; overflow: hidden; text-overflow: ellipsis; }
.slate-grid thead th { position: sticky; top: 0; background: var(--arctic); color: var(--fg-1); font-weight: var(--fw-semibold, 600); z-index: 1; }
.slate-grid tbody tr:hover td { background: #fafafc; }
.slate-grid td { font-family: ui-monospace, SFMono-Regular, Menlo, monospace; color: var(--fg-2); }
.slate-null { color: var(--fg-4, #8A8F9E); font-style: italic; }
.slate-chart-wrap { width: 100%; height: 100%; display: flex; flex-direction: column; min-height: 0; }
.slate-chart-wrap .slate-chart { flex: 1; min-height: 0; }
.slate-axis-t { font-size: 10.5px; color: var(--fg-3); margin-bottom: 2px; }
.slate-legend { display: flex; flex-wrap: wrap; gap: 4px 14px; justify-content: center; font-size: 11px; color: var(--fg-2); margin-top: 4px; }
.slate-legend span { display: inline-flex; align-items: center; gap: 5px; }
.slate-legend i { width: 10px; height: 10px; border-radius: 2px; display: inline-block; }
.slate-ask { display: flex; gap: 8px; align-items: center; margin-top: 14px; background: #fff; border: 1px solid var(--border-subtle); border-radius: var(--radius-md); padding: 8px 8px 8px 14px; }
.slate-ask .artdash-input { border: 0; box-shadow: none; padding: 6px 4px; }
.slate-ask-ic { color: var(--envoy-red); font-size: 15px; }
.slate-chips { display: flex; flex-wrap: wrap; gap: 6px; }
.slate-chipbtn { border: 1px solid var(--border-subtle); background: var(--arctic); color: var(--fg-2); border-radius: 999px; padding: 4px 10px; font: inherit; font-size: 12px; cursor: pointer; }
.slate-chipbtn:hover { border-color: var(--envoy-red); color: var(--fg-1); }

/* ── Recent Activity (screen + Home panel) ─────────────────────────────────── */
/* The page fits the window and the table scrolls inside itself, so the
   header, filters and pager stay put. Below ~560px tall the page scrolls
   instead of squeezing the table to nothing. */
#screen-activity:not(.hidden) {
  display: flex; flex-direction: column;
  height: 100vh; min-height: 560px; box-sizing: border-box;
  /* Less bottom padding than other screens: the table gets the height. */
  padding-bottom: 20px;
}
/* Tighter gap under the subtitle, so the table starts higher. */
#screen-activity .saved-header { margin-bottom: 12px; }
.activity-list { max-width: var(--content-max); flex: 0 1 auto; min-height: 0; display: flex; flex-direction: column; }
/* One table for the page: columns line up across days, and each day is a
   thin divider row instead of its own card. It shrinks to its rows, up to
   the space left, then scrolls. */
.activity-table {
  background: #fff; border: 1px solid #E4E5EB; border-radius: var(--radius-md);
  box-shadow: 0 1px 3px rgba(15, 23, 42, 0.06);
  max-height: 100%; min-height: 0; overflow: hidden;
  display: flex; flex-direction: column;
}
/* Only the rows scroll: the header row sits above this, so the scrollbar
   starts under it. A slim bar in its own lane (not macOS's overlay bar,
   which sat on the Open / View links), only when the rows overflow: app.js
   (_fitActivityScroll) sets .activity-table--scroll, and the header's
   right padding follows so its columns line up either way. */
.activity-body {
  flex: 0 1 auto; min-height: 0; overflow-y: auto; overscroll-behavior: contain;
}
/* Firefox has no ::-webkit-scrollbar. Chrome would let these override the
   rules below and go back to the overlay bar, so they're Firefox-only. */
@supports not selector(::-webkit-scrollbar) {
  .activity-body { scrollbar-width: thin; scrollbar-color: #C9CAD3 #F6F6F8; }
}
.activity-body::-webkit-scrollbar { width: 16px; }
/* A visible track with its own divider, so rows and day bands end at a clear
   edge instead of stopping short of a blank lane. */
.activity-body::-webkit-scrollbar-track { background: #F6F6F8; border-left: 1px solid #EEEEF2; }
/* Even space either side of the bar: the left gets 1px more because the
   track's divider line sits in it. 2px above and below. */
.activity-body::-webkit-scrollbar-thumb { background: #C9CAD3; background-clip: padding-box; border-radius: 8px; border: 2px solid transparent; border-left-width: 5px; border-right-width: 4px; }
.activity-body::-webkit-scrollbar-thumb:hover { background-color: #A9AAB5; } /* colour only: the `background` shorthand reset background-clip, so the bar grew to fill its padding */
.activity-row {
  display: grid;
  /* Activity is a fixed width, sized to its longest label: icon 18 + 8 gap +
     "Export to Google Slides failed" 179 + 8 + a short detail ("· 26 charts")
     ~70. Longer details are cut with an ellipsis. Name takes the rest. */
  grid-template-columns: 58px 290px minmax(160px, 1fr) 116px;
  align-items: baseline; gap: 16px; padding: 6px 16px; box-sizing: border-box;
  border-bottom: 1px solid #EEEEF2; min-width: 0; font-size: 13px; line-height: 1.35; color: var(--fg-1);
}
.activity-row:last-child { border-bottom: none; }
/* The fixed day bar between the header and the scrolling rows (app.js
   _wireActivityDayBar keeps it on the day at the top). */
.activity-day-current { flex-shrink: 0; }
/* Open / View sit close to the edge; the scrollbar lane is the rest of the gap. */
.activity-body .activity-row { padding-right: 6px; }
/* With a scrollbar, the header also clears its 16px lane. */
.activity-table--scroll .activity-row--head { padding-right: calc(6px + 16px); }
.activity-row--head {
  flex-shrink: 0;
  /* Right padding = the rows' 6px + the body's 16px scrollbar lane, so the
     header's columns line up with the rows'. */
  padding: 7px 6px 7px 16px; background: #EBEBF0;
  border-bottom: 1px solid #E0E1E7;
  /* Capitals, like the date bars and Home's labels (ACTIVE SCHEDULES); a
     size up from the date bars so the two read as different levels. */
  font-size: 12px; font-weight: var(--fw-bold, 700); color: var(--fg-1);
  text-transform: uppercase; letter-spacing: 0.05em;
}
.activity-day-row {
  /* Slightly stronger than the rows around it, so each day reads as a chunk. */
  padding: 5px 16px; line-height: 1.4; background: #F1F1F5;
  border-top: 1px solid #E6E7EC; border-bottom: 1px solid #E6E7EC;
  font-size: 10px; font-weight: var(--fw-bold, 700); color: var(--fg-2);
  text-transform: uppercase; letter-spacing: 0.05em;
}
.activity-cell { min-width: 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
/* The label sets the cell's baseline, so every column sits on one text line;
   the icon centres on it. */
.activity-cell--what { display: flex; align-items: baseline; gap: 8px; }
.activity-cell--what .activity-icon { align-self: center; }
.activity-label { flex-shrink: 0; }
.activity-cell--name { font-weight: 400; font-size: 12px; }
.activity-cell--detail { color: var(--fg-3); }
.activity-dash { color: var(--fg-2); text-decoration: none; }
/* The detail after the activity ("· 4 charts"), quieter than the label. */
.activity-what-detail { color: var(--fg-3); min-width: 0; overflow: hidden; text-overflow: ellipsis; }
.activity-row--err .activity-what-detail { color: var(--envoy-red); opacity: 0.85; }
/* A row's panel, the same for every kind of entry: one strip of facts
   (a small label over each value) that wraps, then a run's charts and
   buttons, then an error. It starts under the Activity column (16px pad +
   58px time + 16px gap). */
.activity-panel {
  padding: 10px 6px 12px 90px;
  font-size: 13px; line-height: 1.5; color: var(--fg-1);
}
.activity-facts { display: flex; flex-wrap: wrap; gap: 10px 36px; align-items: flex-start; }
.activity-fact { display: flex; flex-direction: column; min-width: 0; max-width: 420px; }
.activity-fact-label { font-size: 11.5px; color: var(--fg-3); white-space: nowrap; }
.activity-fact-value { overflow-wrap: anywhere; }
/* "· unfinished" after a cancelled or failed run's new Drive file. */
.activity-fact-note { color: var(--fg-3); font-size: 12px; white-space: nowrap; }
.activity-fact-value .activity-run-chips { margin-top: 2px; }
/* Each block (facts, a run's charts and buttons, an error) a step apart. */
.activity-panel > * + * { margin-top: 12px; }
.activity-panel > .activity-run > :first-child,
.activity-panel > .activity-run-charts > :first-child { margin-top: 0; }
.activity-dash:hover { color: var(--envoy-red); text-decoration: underline; }
/* Rows that open (app.js _wireActivityExpand): the same grey hover for every
   kind, failed ones included. */
.activity-row--expandable { cursor: pointer; }
.activity-row--expandable:hover { background: #F7F7FA; }
/* No browser focus outline on click; a red ring for keyboard focus only. */
.activity-row--expandable:focus { outline: none; }
.activity-row--expandable:focus-visible:not([data-mouse]) { outline: 2px solid var(--envoy-red); outline-offset: -2px; }
/* Action button slot + chevron slot, both fixed width. */
.activity-cell--link { display: grid; grid-template-columns: 84px 16px; gap: 8px; align-items: center; justify-content: end; overflow: visible; align-self: center; }
/* Flex, not a line of text: a text line put space around the button and
   made rows with one about a pixel taller than rows without. */
.activity-action-slot { display: flex; align-items: center; }
.activity-chevron-slot { display: flex; justify-content: center; align-items: center; }
.activity-chevron-slot svg { display: block; }
.activity-action {
  display: inline-flex; align-items: center; justify-content: center; box-sizing: border-box;
  /* Small enough to leave room above and below it in the row. */
  width: 84px; height: 20px; padding: 0 6px;
  margin: -1px 0;
  /* Same outlined box on every row, so the actions read as one column. */
  border: 1px solid #D6D7DE; border-radius: 6px; background: #fff;
  font: inherit; font-size: 11.5px; font-weight: var(--fw-semibold, 600); color: var(--fg-1);
  text-decoration: none; white-space: nowrap; cursor: pointer;
  transition: background-color 0.15s ease, border-color 0.15s ease, color 0.15s ease;
}
/* Vidara red on hover only, like the main Run Again button. */
.activity-action:hover { background: var(--envoy-red); border-color: var(--envoy-red); color: #fff; }
.activity-action:focus-visible { outline: 2px solid var(--envoy-red); outline-offset: 1px; }
/* An earlier change to a config or schedule that's since been deleted: nowhere to go. */
.activity-action--disabled,
.activity-action--disabled:hover { background: var(--bg-1, #F5F5F7); border-color: #E4E5EA; color: var(--fg-3); cursor: not-allowed; }
/* [data-tip]'s tooltip (app.js _wireTips): looks like the browser's own and,
   like it, appears under where the pointer comes to rest and stays there, but
   sooner (0.15s; a title waits a second or so). Fixed, so the table's scroll
   box can't clip it. */
.vd-tip {
  position: fixed; z-index: 3000; display: none; pointer-events: none;
  padding: 3px 7px; border-radius: 4px; background: #F2F2F2; border: 1px solid #C9C9C9;
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.15);
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", system-ui, sans-serif;
  font-size: 12px; line-height: 1.3; font-weight: 400; color: #1F1F1F; white-space: nowrap;
}
.vd-tip.is-open { display: block; }
.activity-chevron { color: var(--fg-3); flex-shrink: 0; transition: transform 0.15s; }
.activity-row--expandable[aria-expanded="true"] .activity-chevron { transform: rotate(180deg); }
/* One panel per row; an error, a change list and run settings stack in it. */
/* Slides open and shut: the panel's row of the grid grows from 0fr to 1fr
   (its content's height) while the content fades in. */
.activity-expand {
  display: grid; grid-template-rows: 0fr;
  border-bottom: 0 solid #EEEEF2;
  transition: grid-template-rows 0.22s cubic-bezier(0.2, 0.7, 0.2, 1), border-bottom-width 0.22s;
}
.activity-expand.is-open { grid-template-rows: 1fr; border-bottom-width: 1px; }
/* Rows reopened after a reload (app.js _activityReopen) open at once. */
.activity-list--instant .activity-expand,
.activity-list--instant .activity-expand > [role="cell"],
.activity-list--instant .activity-row { transition: none !important; }
.activity-expand > [role="cell"] {
  min-height: 0; overflow: hidden;
  opacity: 0; transition: opacity 0.18s ease;
}
.activity-expand.is-open > [role="cell"] { opacity: 1; transition-delay: 0.04s; }
/* Only the shading fades. The left bar (box-shadow) switches instantly:
   animated, it ran on its own timing and looked out of step with the panel. */
.activity-row--expandable { transition: background-color 0.2s ease; }
@media (prefers-reduced-motion: reduce) {
  .activity-expand, .activity-expand > [role="cell"], .activity-row--expandable { transition: none; }
}
/* An open row and its panel read as one block: a faint line between them,
   and a firmer line where the next entry starts. Only the entry opened last
   (.activity-row--current) is tinted and gets the bar; other open ones stay
   white, so it's clear which is which. */
/* A faint line between the entry's own line and its dropdown. */
.activity-row--expandable[aria-expanded="true"] { border-bottom-color: #EEEEF2; }
/* On the tinted (most recent) entry the faint line needs a touch more to show. */
.activity-row--current.activity-row--expandable[aria-expanded="true"] { border-bottom-color: #E6E7EC; }
.activity-row--expandable[aria-expanded="true"] + .activity-expand { border-bottom: 1px solid #DCDDE3; }
.activity-row--current.activity-row--expandable[aria-expanded="true"],
.activity-row--current.activity-row--expandable[aria-expanded="true"] + .activity-expand { background: #F7F7FA; }

/* The left bar: next to the entry's own row only (not down its panel), as
   its own layer so it fades in and out. Grey when open, red for the entry
   opened last (failed ones too: only their text is red). Its colour doesn't depend on
   being open, so it keeps it while it fades out. */
.activity-row--expandable { position: relative; }
.activity-row--expandable::before {
  content: ''; position: absolute; left: 0; top: 0; bottom: 0; width: 3px;
  background: #A9AAB5; opacity: 0; pointer-events: none;
  transition: opacity 0.2s ease;
}
.activity-row--current.activity-row--expandable[aria-expanded="true"]::before { opacity: 1; }
.activity-row--current::before { background: var(--envoy-red); }
@media (prefers-reduced-motion: reduce) {
  .activity-row--expandable::before { transition: none; }
}
/* "Charts (n)" / "Slides (n)": collapsed until clicked. */
.activity-run-more { margin-top: 8px; }
.activity-run-more summary {
  display: inline-flex; align-items: center; gap: 6px; cursor: pointer; list-style: none;
  color: var(--fg-2); font-weight: var(--fw-semibold, 600); user-select: none;
}
.activity-run-more summary::-webkit-details-marker { display: none; }
.activity-run-more summary::after {
  content: ''; width: 6px; height: 6px; border-right: 1.5px solid currentColor; border-bottom: 1.5px solid currentColor;
  transform: translateY(-2px) rotate(45deg); transition: transform 0.15s;
}
.activity-run-more[open] summary::after { transform: translateY(1px) rotate(-135deg); }
.activity-run-more summary:hover { color: var(--envoy-red); }
.activity-run-chips { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 6px; }
.activity-run-chip--removed { color: var(--fg-3); text-decoration: line-through; text-decoration-color: rgba(0,0,0,.25); }
.activity-run-chip {
  border: 1px solid var(--border); border-radius: 99px; padding: 1px 10px; background: #fff;
  font-size: 12px; color: var(--fg-2); white-space: nowrap;
}
.activity-run-list { margin: 6px 0 0; padding-left: 18px; }
.activity-run-list li { padding: 1px 0; }
.activity-run-note { color: var(--fg-3); font-size: 12px; }
.activity-run-actions { display: flex; align-items: center; gap: 12px; margin-top: 10px; }
/* Run Again in progress: spinner, what it's on, Cancel. */
.activity-spinner {
  width: 16px; height: 16px; border-radius: 50%; flex-shrink: 0;
  border: 2px solid #E1E2E8; border-top-color: var(--envoy-red);
  animation: activity-spin 0.8s linear infinite;
}
@keyframes activity-spin { to { transform: rotate(360deg); } }
@media (prefers-reduced-motion: reduce) { .activity-spinner { animation-duration: 2s; } }
.activity-run-status-text { color: var(--fg-2); min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.activity-run-actions .primary-btn,
.activity-run-actions .secondary-btn { width: auto; padding: 7px 14px; font-size: 13px; }
.activity-change-from { color: var(--fg-3); text-decoration: line-through; text-decoration-color: rgba(0,0,0,.25); overflow-wrap: anywhere; }
.activity-change-arrow { color: var(--fg-3); }
.activity-change-to { overflow-wrap: anywhere; }
.activity-change-empty { font-style: italic; }
/* Restore's preview (app.js _activityRestorePreview), styled like the app's
   other small dialogs (_showInputModal). */
.restore-preview-backdrop {
  position: fixed; inset: 0; z-index: 2000; background: rgba(0, 0, 0, 0.45);
  display: flex; align-items: center; justify-content: center;
}
.restore-preview {
  background: #fff; border: 1px solid var(--border); border-radius: 12px; padding: 24px;
  width: min(30rem, 90vw); max-height: 85vh; overflow-y: auto; box-sizing: border-box;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.28); display: flex; flex-direction: column; gap: 6px;
}
.restore-preview-title { font-size: 15px; font-weight: 600; color: var(--fg-1); }
.restore-preview-name { font-size: 13px; color: var(--fg-2); margin-bottom: 10px; }
.restore-preview-grid {
  display: grid; grid-template-columns: auto minmax(0, 1fr); gap: 8px 16px;
  font-size: 13px; line-height: 1.4; align-items: baseline;
}
.restore-preview-label { color: var(--fg-3); font-size: 12px; white-space: nowrap; }
.restore-preview-value { color: var(--fg-1); overflow-wrap: anywhere; }
.restore-preview-actions { display: flex; justify-content: flex-end; gap: 8px; margin-top: 18px; }
.restore-preview-actions .primary-btn,
.restore-preview-actions .secondary-btn { width: auto; padding: 7px 16px; font-size: 13px; }

/* A failure's error, under the facts: red text, then a copy icon. */
.activity-error { color: var(--envoy-red); }
.activity-error-text { color: var(--envoy-red); white-space: pre-wrap; overflow-wrap: anywhere; user-select: text; }
.activity-error-copy {
  display: inline-flex; align-items: center; justify-content: center; vertical-align: -2px;
  width: 20px; height: 20px; margin-left: 4px; padding: 0; border: none; border-radius: 4px;
  background: none; color: var(--fg-3); cursor: pointer;
}
.activity-error-copy:hover { background: var(--bg-1, #F0F0F3); color: var(--fg-1); }
.activity-error-copy:focus-visible { outline: 2px solid var(--envoy-red); outline-offset: 1px; }
/* A failed row's error is red, but its dashboard link stays a link. */
.activity-row--err .activity-cell--detail .activity-dash,
.activity-row--err .activity-cell--detail .activity-sep { color: var(--fg-2); }
.activity-row--err .activity-label,
.activity-row--err .activity-cell--detail { color: var(--envoy-red); }
/* A quiet label, not a peer of the activity: smaller, lighter, with a
   narrower "AM". */
.activity-cell--time { color: var(--fg-3); font-size: 12px; font-variant-numeric: tabular-nums; letter-spacing: -0.01em; }
/* The header's Time label looks like the other column labels, not like a time. */
.activity-row--head .activity-cell--time { font-size: inherit; letter-spacing: inherit; color: inherit; font-variant-numeric: normal; }
.activity-cell--link { text-align: right; }
.activity-icon {
  width: 18px; height: 18px; border-radius: 5px; flex-shrink: 0;
  display: inline-flex; align-items: center; justify-content: center;
  background: var(--bg-1); color: var(--gem-60);
}
.activity-icon svg { width: 11px; height: 11px; }
.activity-icon--export { background: #E6F1FB; color: #185FA5; }
.activity-icon--config { background: #F3EEFB; color: #6B3FA0; }
.activity-icon--schedule { background: #EAF6EE; color: #166534; }
.activity-icon--error { background: #FDECEC; color: var(--envoy-red); }
/* Cancelled: muted, so it reads as "didn't happen" rather than an error. */
.activity-icon--cancelled { background: #F1F1F4; color: var(--fg-3); }
.activity-row--cancelled .activity-label { color: var(--fg-3); }
/* Rows with nothing to open or expand (app.js inert): softened as a whole.
   Easy to drop: remove this rule. */
.activity-row--inert > .activity-cell { opacity: 0.6; }
.activity-meta--err { color: var(--envoy-red); }
/* Pager under the list, right-aligned like a table footer. */
/* Right under the table; the table scrolls, so this never moves. */
.activity-pager {
  max-width: var(--content-max); margin-top: 8px; flex-shrink: 0;
  display: flex; align-items: center; justify-content: flex-end; gap: 24px; flex-wrap: wrap;
  font-size: 13px; color: var(--fg-2);
}
.activity-pager-size { display: inline-flex; align-items: center; gap: 8px; }
.activity-pager-size select {
  height: 30px; padding: 0 26px 0 10px; border: 1px solid var(--border); border-radius: var(--radius);
  background: #fff; font: inherit; color: var(--fg-1); cursor: pointer;
}
.activity-pager-range { font-variant-numeric: tabular-nums; min-width: 6.5em; text-align: right; }
.activity-pager-btns { display: inline-flex; gap: 4px; }
.activity-pager-btn {
  width: 30px; height: 30px; display: inline-flex; align-items: center; justify-content: center;
  border: 1px solid var(--border); border-radius: var(--radius); background: #fff; color: var(--fg-1); cursor: pointer;
}
.activity-pager-btn:hover:not(:disabled) { background: var(--arctic); border-color: var(--carbon-30); }
.activity-pager-btn:disabled { color: var(--fg-3); opacity: 0.45; cursor: default; }
/* The filter has five labels; let it scroll rather than push the page wide. */
#activity-filter { max-width: 100%; overflow-x: auto; }

/* Narrower: Details drops under Name, and the header row goes. */
@media (max-width: 1000px) {
  .activity-row:not(.activity-row--head) {
    grid-template-columns: 62px minmax(0, 1fr) 116px;
    grid-template-areas: "time what link" "time name link";
    row-gap: 2px;
  }
  .activity-row--head { display: none; }
  .activity-cell--what { grid-area: what; }
  .activity-cell--name { grid-area: name; }
  .activity-cell--time { grid-area: time; }
  .activity-cell--link { grid-area: link; }
}
@media (max-width: 720px) {
  .sch-toolbar:has(#activity-filter) { flex-direction: column; align-items: flex-start; }
}


/* Basic / Custom Slides switch (same sliding pill as the Drive / own-links one). */
.customize-mode-switch { margin-bottom: 20px; }
.customize-mode-switch .file-source-option:focus { outline: none; }
.customize-mode-switch .file-source-option:focus-visible { outline: 2px solid rgba(250, 67, 56, 0.35); outline-offset: -2px; }
/* Like the Drive / own-links switch: no colour on the chosen icon; the
   other side's icon is faded, as its text is. Content stays centred. */
.customize-mode-switch .file-source-option { justify-content: center; }
.mode-switch-icon { display: inline-flex; flex-shrink: 0; opacity: 0.6; transition: opacity 0.25s; }
.mode-switch-icon > svg { width: 20px; height: 20px; }
.customize-mode-switch .file-source-option--selected .mode-switch-icon { opacity: 1; }

/* A deck preset's Slides tab saves an edit, so its buttons match the Settings
   tab: Cancel / Discard and Save Changes together in the bottom right, with
   no "next step" arrow. Generate Slides keeps Back on the left. */
#preset-slides-host .customize-footer { justify-content: flex-end; gap: 10px; }
#preset-slides-host .customize-footer .btn-arrow { display: none; }

/* The × sits right after a slide's first field, on the same line. */
.slide-line { display: flex; align-items: center; gap: 4px; min-width: 0; }
.slide-line--top { align-items: flex-start; }
.slide-line > input, .slide-line > select, .slide-line > .slide-kpi-grid { flex: 1; min-width: 0; }
.slide-line > .slide-remove-btn { margin-right: -6px; }

/* Your Slides header actions as text links: + Add Slide in Envoy red,
   Clear All in quiet grey, both sized to the heading. */
.slide-text-btn {
  display: inline-flex; align-items: center; gap: 4px;
  padding: 4px 2px; background: none; border: 0;
  font-size: 13px; font-weight: var(--fw-semibold); color: var(--envoy-red);
  cursor: pointer; transition: color 0.15s, opacity 0.15s;
}
.slide-text-btn:hover { color: var(--envoy-red-hover); }
.slide-text-btn--quiet { color: var(--fg-3); font-weight: 500; }
.slide-text-btn--quiet:hover { color: var(--fg-1); }
.slide-text-btn:focus { outline: none; }
.slide-text-btn:focus-visible { box-shadow: 0 0 0 2px rgba(250, 67, 56, 0.3); border-radius: 4px; }
.slide-builder-actions:has(.slide-text-btn) { gap: 16px; }
.slide-builder-count { color: var(--fg-3); font-weight: 500; }

/* Deck preset tabs: less space between the labels and the line under them,
   so the tabs sit on it instead of floating above. */
#preset-dtabs .howto-tab { padding-bottom: 5px; }

/* Slide list edge fades: the slides fade to nothing over 28px at an edge with
   more slides beyond it (app.js toggles .fade-top / .fade-bottom). A mask,
   so nothing is drawn over the slides; the scrollbar strip on the right is
   left unmasked. The registered properties let the fades ease in and out. */
@property --slide-fade-top { syntax: '<length>'; inherits: false; initial-value: 0px; }
@property --slide-fade-bottom { syntax: '<length>'; inherits: false; initial-value: 0px; }
.slide-list-wrap .slide-list {
  --slide-fade-top: 0px;
  --slide-fade-bottom: 0px;
  -webkit-mask-image: linear-gradient(to bottom, transparent 0, #000 var(--slide-fade-top), #000 calc(100% - var(--slide-fade-bottom)), transparent 100%), linear-gradient(#000, #000);
  mask-image: linear-gradient(to bottom, transparent 0, #000 var(--slide-fade-top), #000 calc(100% - var(--slide-fade-bottom)), transparent 100%), linear-gradient(#000, #000);
  -webkit-mask-size: calc(100% - 16px) 100%, 16px 100%;
  mask-size: calc(100% - 16px) 100%, 16px 100%;
  -webkit-mask-position: left top, right top;
  mask-position: left top, right top;
  -webkit-mask-repeat: no-repeat;
  mask-repeat: no-repeat;
  transition: --slide-fade-top 0.2s ease, --slide-fade-bottom 0.2s ease;
}
/* No fade at the top: the line under "Your Slides" already marks that edge.
   Once scrolled, the header casts a faint shadow onto the list instead, as if
   it floats over the slides; it goes away back at the top. */
.slide-list-wrap .slide-builder-header { position: relative; z-index: 1; transition: box-shadow 0.2s ease; }
.slide-list-wrap:has(.slide-list.fade-top) .slide-builder-header { box-shadow: 0 6px 8px -6px rgba(15, 23, 42, 0.14); }
.slide-list-wrap .slide-list.fade-bottom { --slide-fade-bottom: 28px; }

/* Save as Preset in Generate Slides: a quiet grey text link with a bookmark
   icon beside Generate Slides; Envoy red on hover. */
.customize-footer .customize-save-link {
  display: inline-flex; align-items: center; gap: 6px; padding: 6px 8px;
  background: none; border: 0; border-radius: 6px;
  font-size: 13px; font-weight: var(--fw-semibold); color: var(--fg-2);
  cursor: pointer; transition: color 0.15s;
}
.customize-footer .customize-save-link:hover { color: var(--envoy-red); }
.customize-footer .customize-save-link:focus { outline: none; }
.customize-footer .customize-save-link:focus-visible { box-shadow: 0 0 0 2px rgba(250, 67, 56, 0.3); }

/* Bottom fade for scrolling boxes wired by app.js _wireBottomFade: the
   content fades out over 28px while there's more below. The scrollbar strip
   on the right is left unmasked. */
@property --scroll-fade-bottom { syntax: '<length>'; inherits: false; initial-value: 0px; }
.scroll-fade {
  --scroll-fade-bottom: 0px;
  -webkit-mask-image: linear-gradient(to bottom, #000 calc(100% - var(--scroll-fade-bottom)), transparent 100%), linear-gradient(#000, #000);
  mask-image: linear-gradient(to bottom, #000 calc(100% - var(--scroll-fade-bottom)), transparent 100%), linear-gradient(#000, #000);
  -webkit-mask-size: calc(100% - 14px) 100%, 14px 100%;
  mask-size: calc(100% - 14px) 100%, 14px 100%;
  -webkit-mask-position: left top, right top;
  mask-position: left top, right top;
  -webkit-mask-repeat: no-repeat;
  mask-repeat: no-repeat;
  transition: --scroll-fade-bottom 0.2s ease;
}
.scroll-fade.fade-bottom { --scroll-fade-bottom: 28px; }

/* Once the chart picker is scrolled, its "Select Charts to Include" header
   casts a faint shadow onto the charts, as the slide list's header does. */
/* The header's 14px gap is padding (not margin) so its box, and the shadow,
   reach right down to where the charts start. */
.basic-tiles-header { position: relative; z-index: 1; margin-bottom: 0; padding-bottom: 14px; background: #fff; transition: box-shadow 0.2s ease; }
.basic-tiles-section:has(.basic-tiles-grid.is-scrolled) .basic-tiles-header { box-shadow: 0 6px 8px -6px rgba(15, 23, 42, 0.14); }
/* The charts line up with the toolbar above them: .modal-tile-grid's 28px
   sides are for a popup. The scrollbar is the slide list's 16px lane, set
   just past the toolbar's right edge so the cards end under Select All. */
.basic-tiles-section .basic-tiles-grid { padding: 0 0 16px; margin-right: -16px; }
@supports not selector(::-webkit-scrollbar) {
  .basic-tiles-section .basic-tiles-grid { scrollbar-width: thin; scrollbar-color: #C9CAD3 #F6F6F8; }
}
.basic-tiles-section .basic-tiles-grid::-webkit-scrollbar { width: 16px; }
.basic-tiles-section .basic-tiles-grid::-webkit-scrollbar-track { background: #F6F6F8; border-radius: 8px; } /* the slide list's lane */
.basic-tiles-section .basic-tiles-grid::-webkit-scrollbar-thumb { background: #C9CAD3; background-clip: padding-box; border-radius: 8px; border: 2px solid transparent; border-left-width: 5px; border-right-width: 4px; }
.basic-tiles-section .basic-tiles-grid::-webkit-scrollbar-thumb:hover { background-color: #A9AAB5; }

/* Edit Slide: the backgrounds didn't load. Spans the whole grid, centred. */
.bg-grid-error {
  grid-column: 1 / -1; display: flex; flex-direction: column; align-items: center;
  gap: 4px; padding: 6px 16px 2px; text-align: center; /* the grid's own padding is enough space */
}
.bg-grid-error-title { margin: 0; font-size: 14px; font-weight: var(--fw-semibold); color: var(--fg-1); }
.bg-grid-error-text { margin: 0 0 10px; font-size: 13px; color: var(--fg-3); }
.bg-grid-error-retry { width: auto; padding: 7px 16px; font-size: 13px; }

/* The preview as a tiny slide: soft grey blocks where the title, chart, text
   and KPIs go for this layout; white and see-through over a background image.
   Redrawn when the layout changes. */
.slide-mini { position: absolute; inset: 0; pointer-events: none; }
.slide-mini > i { position: absolute; border-radius: 2px; background: #E4E5EB; }
.slide-mini--on-image > i { background: rgba(255, 255, 255, 0.55); box-shadow: 0 0 0 0.5px rgba(0, 0, 0, 0.08); }
.slide-card-bg .slide-edit-btn { z-index: 1; }
/* Body slides: the type dropdown on the left and the layout's name on the
   right, above the ×, so the top-right corner isn't empty. */
.slide-type-line { display: flex; align-items: center; justify-content: space-between; gap: 10px; min-width: 0; }
.slide-layout-name { font-size: 11px; color: var(--fg-3); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; text-align: right; }
/* A slide whose chart is gone from the dashboard (app.js renderSlideList). */
/* Beside the slide's type dropdown, the ⚠ then the words; the layout name
   stays on the right. Same amber and icon nudge as the list's labels. */
.slide-missing { display: inline-flex; align-items: center; gap: 4px; margin-right: auto; flex-shrink: 0; font-size: 12px; font-weight: var(--fw-medium); color: #E59500; white-space: nowrap; cursor: default; }
.slide-missing svg { width: 12px; height: 12px; flex-shrink: 0; position: relative; top: -1.5px; }

/* Edit Slide's Cancel / Apply: the same compact size as the confirm popups'
   buttons, not the full-size form buttons. */
.bg-picker-buttons .secondary-btn,
.bg-picker-buttons .primary-btn { width: auto; padding: 7px 16px; font-size: 13px; font-weight: 600; }

/* "Saved" sits just left of Cancel in the preset's Settings and Slides tabs;
   Generate Slides' footer never shows it. */
.preset-form-actions .sch-email-saved, #preset-slides-host .customize-footer .sch-email-saved { margin-right: 4px; }

/* Settings › Billing (public/js/billing.js) */
.billing-head { display: flex; align-items: flex-start; justify-content: space-between; gap: 16px; flex-wrap: wrap; margin-bottom: 14px; }
.billing-h { margin: 0 0 4px; font-size: 17px; font-weight: 700; color: var(--fg-1); }
.billing-h4 { margin: 0 0 14px; font-size: 13px; font-weight: 700; color: var(--fg-2); letter-spacing: .01em; }
.billing-muted { margin: 0; font-size: 13px; color: var(--fg-3); line-height: 1.5; }
.billing-muted code, .billing-warn code { font-size: 12px; background: var(--bg-2, #f4f4f6); padding: 1px 5px; border-radius: 4px; }
.billing-fresh { display: flex; align-items: center; gap: 10px; }
.billing-fresh .secondary-btn { width: auto; }
.billing-warn { margin: 0 0 14px; padding: 10px 14px; border: 1px solid rgba(178, 107, 0, .3); background: #FFF6E5; border-radius: 10px; font-size: 13px; color: #6B4300; line-height: 1.5; }
.billing-stats { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 12px; margin-bottom: 14px; }
@media (max-width: 860px) { .billing-stats { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (max-width: 480px) { .billing-stats { grid-template-columns: 1fr; } }
.billing-stat { display: flex; flex-direction: column; gap: 2px; padding: 14px 16px; border: 1px solid var(--border); border-radius: 12px; background: var(--bg-0); }
.billing-stat span { font-size: 12px; font-weight: 600; color: var(--fg-3); }
.billing-stat b { font-size: 24px; font-weight: 800; color: var(--fg-1); letter-spacing: -.01em; }
.billing-stat em { font-style: normal; font-size: 12px; color: var(--fg-3); }
.billing-stat em.up { color: #B3241A; } .billing-stat em.down { color: #17703A; }
.billing-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(320px, 1fr)); gap: 12px; margin-bottom: 12px; }
.billing-card { margin-bottom: 12px; padding: 20px 22px; }
.billing-svg { width: 100%; height: auto; display: block; }
.billing-svg .billing-x { font-size: 11px; fill: #5F6472; }
.billing-svg .billing-v { font-size: 11px; font-weight: 700; fill: #3F4450; }
.billing-svg .billing-grid-l { stroke: #EBEBF0; stroke-width: 1; }
.billing-legend { display: flex; flex-wrap: wrap; gap: 6px 14px; margin-top: 6px; font-size: 12px; color: var(--fg-2); }
.billing-legend i { display: inline-block; width: 9px; height: 9px; border-radius: 2px; margin-right: 5px; vertical-align: -1px; }
.billing-table { width: 100%; border-collapse: collapse; font-size: 13px; }
.billing-table th, .billing-table td { padding: 8px 10px; border-bottom: 1px solid var(--border); text-align: left; }
.billing-table th { font-size: 12px; font-weight: 600; color: var(--fg-3); }
.billing-table .num { text-align: right; font-variant-numeric: tabular-nums; }
.billing-table tfoot td { font-weight: 700; border-bottom: 0; }
.billing-untagged { list-style: none; margin: 10px 0 0; padding: 0; display: grid; grid-template-columns: repeat(auto-fill, minmax(200px, 1fr)); gap: 6px 18px; font-size: 13px; }
.billing-untagged li { display: flex; justify-content: space-between; gap: 10px; border-bottom: 1px dashed var(--border); padding: 4px 0; }
.billing-foot { margin-top: 4px; }
.billing-steps ol { margin: 4px 0 10px; padding-left: 20px; font-size: 13.5px; color: var(--fg-2); line-height: 1.6; }
.billing-steps li { margin-bottom: 4px; }
.billing-v-sub { font-weight: 600; fill: #5F6472; }
.billing-note { margin: 0 0 14px; padding: 10px 14px; border: 1px solid var(--border); border-left: 3px solid #4141A2; border-radius: 10px; font-size: 13px; color: var(--fg-2); line-height: 1.5; background: var(--bg-0); }
/* On phones the 560-wide charts would shrink their text to ~7px: keep them readable and let them scroll sideways inside the card. */
.billing-chart { overflow-x: auto; }
@media (max-width: 520px) { .billing-chart .billing-svg { min-width: 480px; } }
.billing-sr { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0; }

/* Billing setup state */
#billing-root { max-width: 1080px; }
.bl-top { display: flex; align-items: flex-start; justify-content: space-between; gap: 16px; flex-wrap: wrap; margin-bottom: 18px; }
.bl-top .billing-muted { max-width: 60ch; }
.bl-title-row { display: flex; align-items: center; gap: 10px; margin-bottom: 4px; }
.bl-title-row .billing-h { margin: 0; }
.bl-pill { display: inline-flex; align-items: center; gap: 6px; padding: 3px 10px; border-radius: var(--radius-pill); background: #FFF4E0; color: #8A5300; font-size: 12px; font-weight: 600; }
.bl-pill i { width: 6px; height: 6px; border-radius: 50%; background: #E09400; }
.bl-grid { display: grid; grid-template-columns: minmax(0, 1.15fr) minmax(0, 1fr); gap: 14px; align-items: start; }
@media (max-width: 920px) { .bl-grid { grid-template-columns: 1fr; } }
.bl-steps { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; }
.bl-step { display: grid; grid-template-columns: 22px minmax(0, 1fr) auto; gap: 12px; align-items: start; padding: 12px 0; border-top: 1px solid var(--border-subtle, #EEEEF2); }
.bl-step:first-child { border-top: 0; padding-top: 2px; }
.bl-step-ic svg { width: 20px; height: 20px; display: block; stroke-width: 1.6; stroke-linecap: round; stroke-linejoin: round; }
.bl-step.is-done .bl-step-ic svg { fill: #1E8E4E; stroke: #fff; }
.bl-step.is-done .bl-step-ic circle { stroke: none; }
.bl-step.is-wait .bl-step-ic svg { fill: #FFF4E0; stroke: #C77E00; }
.bl-step.is-todo .bl-step-ic svg { stroke: var(--border-strong, #C9CBD3); }
.bl-step-t b { display: block; font-size: 14px; font-weight: 600; color: var(--fg-1); line-height: 1.35; }
.bl-step.is-done .bl-step-t b { color: var(--fg-2); }
.bl-step-t span { display: block; margin-top: 2px; font-size: 12.5px; color: var(--fg-3); line-height: 1.45; }
.bl-step-t code { font-size: 12px; background: var(--bg-2, #f4f4f6); padding: 1px 5px; border-radius: 4px; font-weight: 500; }
.bl-chip { font-size: 11.5px; font-weight: 600; padding: 2px 8px; border-radius: var(--radius-pill); white-space: nowrap; }
.bl-chip.is-done { background: #E6F4EC; color: #17703A; }
.bl-chip.is-wait { background: #FFF4E0; color: #8A5300; }
.bl-chip.is-todo { background: var(--bg-2, #f4f4f6); color: var(--fg-3); }
.bl-note { margin: 12px 0 0; padding-top: 12px; border-top: 1px solid var(--border-subtle, #EEEEF2); font-size: 12.5px; color: var(--fg-3); }
.bl-kvs { display: flex; flex-direction: column; }
.bl-kv { display: flex; justify-content: space-between; gap: 12px; padding: 10px 0; border-top: 1px solid var(--border-subtle, #EEEEF2); font-size: 13.5px; }
.bl-kv:first-child { border-top: 0; padding-top: 2px; }
.bl-kv span { color: var(--fg-3); }
.bl-kv b { font-weight: 600; color: var(--fg-1); text-align: right; }
.bl-note code { font-size: 12px; background: var(--bg-2, #f4f4f6); padding: 1px 5px; border-radius: 4px; }
.bl-est .billing-h4 { display: flex; align-items: center; gap: 8px; }
.bl-tag { font-size: 11px; font-weight: 600; padding: 1px 7px; border-radius: var(--radius-pill); background: #EEEEFB; color: #3A3A8F; letter-spacing: 0; }
.bl-big { font-size: 34px; font-weight: 800; letter-spacing: -.02em; color: var(--fg-1); line-height: 1.1; margin-bottom: 6px; font-variant-numeric: tabular-nums; }
.bl-big small { font-size: 15px; font-weight: 600; color: var(--fg-3); letter-spacing: 0; }
.bl-bars { list-style: none; margin: 16px 0 0; padding: 0; display: flex; flex-direction: column; gap: 12px; }
.bl-bar { display: grid; grid-template-columns: minmax(0, 1.3fr) minmax(0, 1fr) 70px; gap: 12px; align-items: center; }
.bl-bar-l { min-width: 0; }
.bl-bar-n { display: block; font-size: 13.5px; font-weight: 600; color: var(--fg-1); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.bl-bar-b { display: block; font-size: 12px; color: var(--fg-3); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.bl-bar-track { height: 8px; border-radius: 4px; background: var(--bg-2, #f4f4f6); overflow: hidden; }
.bl-bar-track i { display: block; height: 100%; border-radius: 4px; background: #4141A2; }
.bl-bar-v { text-align: right; font-size: 13.5px; font-weight: 600; color: var(--fg-1); font-variant-numeric: tabular-nums; }
@media (max-width: 480px) { .bl-bar { grid-template-columns: minmax(0, 1fr) 64px; } .bl-bar-track { display: none; } }
