/* ============================================================================
   Split Test Pro — Design System
   Semantic HTML + CSS Custom Properties
   ============================================================================

   Class naming — BEM (TASK-60):
     block            page-head, banner, results-table
     block__element   page-head__meta, banner__content
     block--modifier  btn--primary, badge--live
   Allowed alongside BEM:
     - Layout blocks: row, stack, inline, grid (+ their -- modifiers). Mix
       them onto component elements: class="panel__footer row".
     - Text block: text--muted, text--mono, text--tiny, … (tone/typography).
     - JS state classes: is-open, is-active, … (toggled at runtime only).
   No single-purpose utilities (mt-4, muted, font-bold, …) and no static
   inline style="…" — inline styles are for JS-computed dynamic values, plus
   the one sanctioned idiom `style="display:none"` on initially-hidden
   elements that JS reveals by clearing the inline style.
   Enforced by scripts/check-bem-classes.mjs in CI.
   ============================================================================ */

/* --------------------------------------------------------------------------
   Design Tokens — Glass + Magazine (redesign v2, glass variant)
   Source: redesign-assets/project/Split Test Pro Redesign v2.html:1247-1304
   The prototype's `TWEAK_DEFAULTS` (line 3256) sets variant=glass by default;
   we promote those tokens to :root so there's no runtime variant switch.
   -------------------------------------------------------------------------- */
:root {
  color-scheme: dark;

  /* Neutrals — dark navy / violet base with translucent elevation */
  --bg: #0a0b1a;
  --bg-elev: rgba(255, 255, 255, 0.04);
  --bg-sunken: rgba(255, 255, 255, 0.02);
  --line: rgba(255, 255, 255, 0.1);
  --line-strong: rgba(255, 255, 255, 0.18);

  /* Text ramp — light on dark */
  --ink: #f4f4ff;
  --ink-2: #c8c8e0;
  --ink-3: #8a8aa8;
  --ink-4: #5a5a75;

  /* Accent — violet */
  --accent: #8b7aff;
  --accent-soft: rgba(139, 122, 255, 0.15);
  --accent-deep: #a693ff;
  --accent-contrast: #1a1230;

  /* Status — vivid on dark */
  --pos: #5ee3a4;
  --pos-bg: rgba(94, 227, 164, 0.15);
  --neg: #ff6b8a;
  --neg-bg: rgba(255, 107, 138, 0.12);
  --warn: #ffc866;
  --warn-bg: rgba(255, 200, 102, 0.12);

  /* Radii — glass is rounder than classic */
  --radius-sm: 10px;
  --radius: 16px;
  --radius-lg: 24px;

  /* Shadows — deep dark shadows + subtle top-highlight */
  --shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.2), 0 0 0 1px var(--line);
  --shadow: inset 0 1px 0 rgba(255, 255, 255, 0.08), 0 8px 32px rgba(0, 0, 0, 0.1), 0 0 0 1px var(--line);
  --shadow-lg: inset 0 1px 0 rgba(255, 255, 255, 0.1), 0 24px 70px rgba(0, 0, 0, 0.55);

  /* Typography */
  --font-sans: 'DM Sans', ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
  --font-display: 'DM Sans', ui-sans-serif, system-ui, sans-serif;
  --font-mono: 'JetBrains Mono', ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  --font-serif: 'Lora', ui-serif, Georgia, serif;

  /* Spacing */
  --space-1: 4px;
  --space-2: 8px;
  --space-3: 12px;
  --space-4: 16px;
  --space-5: 20px;
  --space-6: 24px;
  --space-8: 32px;
  --space-10: 40px;
  --space-12: 48px;
  --space-16: 64px;

  /* --------------------------------------------------------------------
     Back-compat aliases — existing unmigrated views read --color-*.
     Mapped to the dark tokens so old views pick up new palette; their
     markup (light cards etc.) will still look rough on dark bg until
     each phase restyles the view. Transition state, intentional.
     -------------------------------------------------------------------- */
  --color-bg: var(--bg);
  --color-surface: var(--bg-elev);
  --color-surface-hover: var(--bg-sunken);
  --color-border: var(--line);
  --color-border-hover: var(--line-strong);
  --color-text: var(--ink);
  --color-text-secondary: var(--ink-3);
  --color-text-disabled: var(--ink-4);
  --color-link: var(--accent);
  --color-link-hover: var(--accent-deep);
  --color-success: var(--pos);
  --color-success-bg: var(--pos-bg);
  --color-warning: var(--warn);
  --color-warning-bg: var(--warn-bg);
  --color-critical: var(--neg);
  --color-critical-bg: var(--neg-bg);
  --color-info: var(--accent);
  --color-info-bg: var(--accent-soft);

  --font-family: var(--font-sans);
  --font-size-xs: 0.75rem;
  --font-size-sm: 0.8125rem;
  --font-size-base: 0.875rem;
  --font-size-md: 1rem;
  --font-size-lg: 1.25rem;
  --font-size-xl: 1.5rem;
  --font-size-2xl: 1.75rem;
  --line-height-tight: 1.25;
  --line-height-normal: 1.5;

  --radius-md: var(--radius);
  --radius-full: 9999px;
  --border: 1px solid var(--color-border);

  --shadow-md: var(--shadow);

  --page-max-width: none;
  --page-padding: 72px;
}

/* --------------------------------------------------------------------------
   Reset & Base
   -------------------------------------------------------------------------- */
*,
*::before,
*::after {
  box-sizing: border-box;
  margin: 0;
  padding: 0;
}

html {
  font-family: var(--font-sans);
  font-size: 16px;
  line-height: var(--line-height-normal);
  color: var(--ink);
  background: var(--bg);
  overflow-y: scroll;
  scrollbar-gutter: stable;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

body,
.app {
  background:
    radial-gradient(ellipse at 10% 0%, rgba(139, 122, 255, 0.25), transparent 50%),
    radial-gradient(ellipse at 90% 20%, rgba(122, 166, 255, 0.18), transparent 50%),
    radial-gradient(ellipse at 50% 100%, rgba(170, 139, 255, 0.15), transparent 50%),
    var(--bg);
  background-attachment: fixed;
}

body {
  min-height: 100vh;
  font-family: var(--font-sans);
  color: var(--ink);
  font-size: 14px;
  line-height: 1.5;
  font-feature-settings: "cv11", "ss01", "ss03";
}

/* --------------------------------------------------------------------------
   Typography
   -------------------------------------------------------------------------- */
h1, h2, h3, h4, h5, h6 {
  line-height: var(--line-height-tight);
  font-weight: 600;
}

h1 { font-size: var(--font-size-2xl); }
h2 { font-size: var(--font-size-xl); }
h3 { font-size: var(--font-size-lg); }
h4 { font-size: var(--font-size-md); }

p {
  color: var(--color-text-secondary);
  font-size: var(--font-size-base);
}

a {
  color: var(--color-link);
  text-decoration: none;
}

a:hover {
  color: var(--color-link-hover);
  text-decoration: underline;
}

/* Anchors styled as buttons (.btn on an <a>) shouldn't inherit `a:hover`'s
   link-hover color. .btn:hover wins on specificity over a:hover; variant
   buttons (.btn--primary / .btn--danger / .btn--critical / .run-toggle--*)
   set their own hover color explicitly later in the file and override this. */
button:hover,
.btn:hover {
  color: var(--ink);
}

small {
  font-size: var(--font-size-xs);
  color: var(--color-text-secondary);
}

code, pre {
  font-family: var(--font-mono);
  font-size: var(--font-size-sm);
}

.code-inline {
  font-family: var(--font-mono);
  font-size: var(--font-size-sm);
  background: var(--color-bg);
  border: var(--border);
  border-radius: var(--radius-sm);
  padding: 1px 6px;
  color: var(--color-text);
}

/* --------------------------------------------------------------------------
   Page Layout
   -------------------------------------------------------------------------- */
.page {
  max-width: var(--page-max-width);
  margin: 0 auto;
  padding: var(--space-6) var(--page-padding);
  /* Defense in depth: a single rogue child (long mono span, oversized chart)
     should never push the page wider than the viewport. */
  min-width: 0;
  overflow-x: clip;
}

.page--full-width {
  max-width: none;
}

.page-header {
  display: flex;
  align-items: center;
  gap: var(--space-4);
  margin-bottom: var(--space-6);
  flex-wrap: wrap;
}

.page-header__back {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  color: var(--color-text-secondary);
  font-size: var(--font-size-sm);
  text-decoration: none;
  padding: var(--space-1) var(--space-2);
  border-radius: var(--radius-sm);
  transition: background 0.15s;
}

.page-header__back:hover {
  background: var(--color-surface-hover);
  color: var(--color-text);
  text-decoration: none;
}

.page-header__title-group {
  flex: 1;
}

.page-header__title {
  display: flex;
  align-items: center;
  gap: var(--space-3);
}

.page-header__subtitle {
  color: var(--color-text-secondary);
  font-size: var(--font-size-sm);
  margin-top: var(--space-1);
}

.page-header__actions {
  display: flex;
  gap: var(--space-2);
}

/* --------------------------------------------------------------------------
   Card — glass panel
   -------------------------------------------------------------------------- */
.card {
  background: rgba(255, 255, 255, 0.04);
  backdrop-filter: blur(16px);
  -webkit-backdrop-filter: blur(16px);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: var(--space-6);
  /* No box-shadow on .card (CU-86e2cztr6) — glass surfaces read through their
     translucent background + border alone. On these backdrop-filtered,
     radius-clipped layers Chromium rasterizes the composited layer with
     shadow-inflated square bounds, and any repaint (hover transitions on/inside
     the layer) can smear a faint offset ghost rectangle past the rounded
     corners (CU-86e2d01tz; same mechanism as .exp-card, CU-86e2d03h1). */
}

.card__header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: var(--space-4);
}

/* Stacked content sections on the experiment-detail tabs (results, order
   insights, …). Mix with .card when the section is a glass panel:
   class="card detail-section". */
.detail-section { margin-top: var(--space-4); }
.detail-section__title { margin-bottom: var(--space-4); }

/* --------------------------------------------------------------------------
   Stack Layouts
   -------------------------------------------------------------------------- */
.stack {
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
}

.stack--tight { gap: var(--space-2); }
.stack--loose { gap: var(--space-6); }

.inline {
  display: flex;
  align-items: center;
  gap: var(--space-3);
}

.inline--tight { gap: var(--space-2); }
.inline--spread { justify-content: space-between; }

/* --------------------------------------------------------------------------
   Grid
   -------------------------------------------------------------------------- */
.grid {
  display: grid;
  gap: var(--space-4);
}

.grid--2 { grid-template-columns: repeat(2, 1fr); }
.grid--3 { grid-template-columns: repeat(3, 1fr); }
.grid--sidebar { grid-template-columns: 1fr 3fr; }

@media (max-width: 768px) {
  .grid--2, .grid--3, .grid--sidebar {
    grid-template-columns: 1fr;
  }
}

/* --------------------------------------------------------------------------
   Buttons
   -------------------------------------------------------------------------- */
button, .btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  height: 32px;
  padding: 0 12px;
  font-family: var(--font-sans);
  font-size: 13px;
  font-weight: 500;
  line-height: 1;
  border: 1px solid rgba(255, 255, 255, 0.04);
  border-radius: var(--radius-sm);
  background: rgba(255, 255, 255, 0.1);
  backdrop-filter: blur(8px);
  -webkit-backdrop-filter: blur(8px);
  color: var(--ink);
  cursor: pointer;
  white-space: nowrap;
  caret-color: transparent;
  transition: background 160ms, box-shadow 160ms, transform 160ms;
}

/* Icon sizing inside buttons — prototype uses 14px SVGs. */
.btn > svg, button > svg {
  width: 14px;
  height: 14px;
  flex: none;
}

.btn > span, button > span { white-space: nowrap; }

button:hover, .btn:hover {
  background: rgba(255, 255, 255, 0.12);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1), 0 8px 24px rgba(0, 0, 0, 0.16);
}

button:disabled, .btn:disabled {
  opacity: 0.5;
  cursor: not-allowed;
}

.btn--primary {
  background: linear-gradient(135deg, #8b7aff, #a693ff);
  border: none;
  color: #1a1230;
  font-weight: 700;
}

.btn--primary:hover {
  background: linear-gradient(135deg, #a693ff, #b8a7ff);
  box-shadow: 0 0 30px rgba(139, 122, 255, 0.4);
  transform: translateY(-1px);
  color: #1a1230;
}

.btn--primary svg {
  stroke: #1a1230;
}

.btn--critical {
  background: color-mix(in srgb, var(--neg) 22%, transparent);
  color: var(--neg);
  border-color: color-mix(in srgb, var(--neg) 40%, transparent);
}

.btn--critical:hover {
  background: color-mix(in srgb, var(--neg) 30%, transparent);
  color: var(--neg);
  border-color: color-mix(in srgb, var(--neg) 55%, transparent);
}

.btn--ghost {
  background: transparent;
  border-color: transparent;
  color: var(--ink-2);
}
.btn--ghost:hover {
  background: var(--bg-sunken);
  color: var(--ink);
}

.btn--danger {
  background: color-mix(in srgb, var(--neg) 22%, transparent);
  color: var(--neg);
  border-color: color-mix(in srgb, var(--neg) 40%, transparent);
}

.btn--danger:hover {
  background: color-mix(in srgb, var(--neg) 30%, transparent);
  color: var(--neg);
  border-color: color-mix(in srgb, var(--neg) 55%, transparent);
}

/* Run-toggle modifiers: pause = warn-tinted chip, play = primary-pulse to
   draw attention to the start action. */
.run-toggle--pause {
  background: color-mix(in srgb, var(--warn) 18%, transparent);
  color: var(--warn);
  border-color: color-mix(in srgb, var(--warn) 35%, transparent);
}
.run-toggle--pause:hover {
  background: color-mix(in srgb, var(--warn) 28%, transparent);
  color: var(--warn);
  border-color: color-mix(in srgb, var(--warn) 55%, transparent);
}
.run-toggle--pause > svg { fill: currentColor; stroke: none; }

.run-toggle--play {
  animation: run-toggle-pulse 1.8s ease-out infinite;
}
@keyframes run-toggle-pulse {
  0%   { box-shadow: 0 0 0 0 color-mix(in srgb, var(--accent) 60%, transparent); }
  70%  { box-shadow: 0 0 0 10px color-mix(in srgb, var(--accent) 0%, transparent); }
  100% { box-shadow: 0 0 0 0 color-mix(in srgb, var(--accent) 0%, transparent); }
}
.run-toggle--play:hover { animation-play-state: paused; }

/* Indeterminate spinner — used for in-flight buttons (Reviewing…, Refreshing…). */
@keyframes spin {
  to { transform: rotate(360deg); }
}
/* Indeterminate SVG spinner — used in buttons (Reviewing… / Refreshing…) and
   anywhere we need a loading indicator. The animation matches the Pre-Launch
   "Reviewing…" button exactly: 0.9s linear rotation, transform-origin centered.
   Buttons constrain the size to 14px via `.btn .spinner`; standalone usages
   set their own size on the wrapper. */
svg.spinner {
  animation: spin 0.9s linear infinite;
  transform-origin: 50% 50%;
}
.btn svg.spinner {
  width: 14px;
  height: 14px;
  flex: none;
}
/* Standalone AI-body spinner — wrap the SVG in a span sized 18px so the
   indicator reads at the same weight as the Pre-Launch button glyph but is
   visible at body-text size (13–14px copy alongside it). */
.ai-analysis__spinner {
  display: inline-flex;
  align-items: center;
  width: 18px;
  height: 18px;
  flex: none;
  color: var(--accent-deep);
}
.ai-analysis__spinner > svg { width: 100%; height: 100%; }

/* Split-button group — two buttons fused side-by-side with a divider, used
   for "Preview link / Copy URL" on each variant row. The left button keeps
   the standard .btn styling; the right one is icon-only and shares borders. */
.btn-group {
  display: inline-flex;
  align-items: stretch;
  border-radius: var(--radius-sm);
  overflow: hidden;
  white-space: nowrap;
}
.btn-group > .btn {
  border-radius: 0;
  text-decoration: none;
}
.btn-group > .btn-group__main {
  border-top-left-radius: var(--radius-sm);
  border-bottom-left-radius: var(--radius-sm);
  padding-right: 12px;
}
.btn-group > .btn-group__split {
  border-top-right-radius: var(--radius-sm);
  border-bottom-right-radius: var(--radius-sm);
  border-left: 1px solid var(--line);
  padding: 0 10px;
}
.btn-group > .btn-group__split.is-copied {
  color: var(--pos);
}

/* Secondary button — neutral chip used for tertiary actions like "Get AI Review"
   that should not compete with the primary CTA visually. */
.btn--secondary {
  background: rgba(255, 255, 255, 0.06);
  color: var(--ink-2);
  border-color: var(--line-strong);
}
.btn--secondary:hover {
  background: rgba(255, 255, 255, 0.1);
  color: var(--ink);
}

.btn--loading {
  position: relative;
  color: transparent;
}

.btn--loading::after {
  content: '';
  position: absolute;
  width: 1rem;
  height: 1rem;
  border: 2px solid currentColor;
  border-right-color: transparent;
  border-radius: 50%;
  animation: spin 0.6s linear infinite;
}

/* --------------------------------------------------------------------------
   Forms
   -------------------------------------------------------------------------- */
label {
  display: block;
  font-size: var(--font-size-base);
  font-weight: 500;
  margin-bottom: var(--space-1);
}

input:not([type]),
input[type="text"],
input[type="email"],
input[type="url"],
input[type="number"],
input[type="password"],
input[type="search"],
input[type="tel"],
input[type="date"],
textarea,
select {
  display: block;
  width: 100%;
  min-width: 0;
  padding: 5px 12px;
  font-family: var(--font-sans);
  font-size: var(--font-size-base);
  line-height: var(--line-height-normal);
  color: var(--ink);
  background: rgba(255, 255, 255, 0.04);
  border: 1px solid var(--line-strong);
  border-radius: var(--radius-sm);
  -webkit-appearance: none;
  appearance: none;
  -webkit-box-shadow: none;
          box-shadow: none;
  -webkit-text-fill-color: var(--ink);
  transition: border-color 0.15s, box-shadow 0.15s;
}

/* Safari/Chrome autofill — override the default yellow + white-on-light. */
input:-webkit-autofill,
input:-webkit-autofill:hover,
input:-webkit-autofill:focus,
input:-webkit-autofill:active {
  -webkit-text-fill-color: var(--ink);
  -webkit-box-shadow: 0 0 0 1000px rgba(139, 122, 255, 0.05) inset;
  caret-color: var(--ink);
  transition: background-color 9999s ease-out 0s;
}

select {
  padding-right: calc(var(--space-3) * 2 + 12px);
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8' viewBox='0 0 12 8'%3E%3Cpath fill='%238a8aa8' d='M1 1l5 5 5-5'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right var(--space-3) center;
}

/* Native <input type="date"> — force the dark UA form-control theme (Chrome/
   Safari otherwise render the calendar icon dark-on-dark since it ignores
   the inherited :root color-scheme once the field gets its own background)
   and make the picker affordance visibly interactive. */
input[type="date"] {
  color-scheme: dark;
}
input[type="date"]::-webkit-calendar-picker-indicator {
  cursor: pointer;
  opacity: 0.7;
  border-radius: 4px;
  transition: opacity 0.15s;
}
input[type="date"]::-webkit-calendar-picker-indicator:hover {
  opacity: 1;
}

input::placeholder, textarea::placeholder {
  color: var(--ink-4);
  opacity: 0.6;
}

input:focus, textarea:focus, select:focus {
  outline: none;
  border-color: var(--accent);
  box-shadow: 0 0 0 3px rgba(139, 122, 255, 0.2);
}

/* Only color-shift the border for *user-edited* invalid fields, not inputs that
   are rendered with an empty value (e.g. autocomplete="email" fields would
   otherwise show as red on first paint). */
input:user-invalid {
  border-color: var(--color-critical);
}

fieldset {
  border: none;
  padding: 0;
}

legend {
  font-size: var(--font-size-base);
  font-weight: 500;
  margin-bottom: var(--space-2);
}

.form-group {
  margin-bottom: var(--space-4);
}

.form-group:last-child {
  margin-bottom: 0;
}

.radio-group, .checkbox-group {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
}

.radio-group label, .checkbox-group label {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  font-weight: 400;
  cursor: pointer;
}

/* --------------------------------------------------------------------------
   Banners / Alerts
   -------------------------------------------------------------------------- */
.banner {
  display: flex;
  align-items: flex-start;
  gap: var(--space-3);
  padding: var(--space-4);
  border-radius: var(--radius-md);
  border: 1px solid;
  font-size: var(--font-size-base);
}

.banner--success {
  background: var(--color-success-bg);
  border-color: var(--color-success);
  color: var(--color-success);
}

.banner--warning {
  background: var(--color-warning-bg);
  border-color: var(--color-warning);
  color: var(--color-warning);
}

.banner--critical {
  background: var(--color-critical-bg);
  border-color: var(--color-critical);
  color: var(--color-critical);
}

.banner--info {
  background: var(--color-info-bg);
  border-color: var(--color-info);
  color: var(--color-info);
}

/* Banner rendered above form content (e.g. validation errors) keeps a gap
   below itself. */
.banner--spaced { margin-bottom: var(--space-4); }

.banner__content {
  flex: 1;
}

.banner__content p {
  color: inherit;
}

.banner__actions {
  margin-top: var(--space-2);
}

/* --------------------------------------------------------------------------
   Badge
   -------------------------------------------------------------------------- */
.badge {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  padding: var(--space-1) var(--space-2);
  font-size: var(--font-size-xs);
  font-weight: 500;
  border-radius: var(--radius-full);
  line-height: 1;
  text-transform: capitalize;
  width: fit-content;
}
.badge > svg { width: 12px; height: 12px; flex: none; }

.badge--created {
  background: var(--color-info-bg);
  color: var(--color-info);
}

.badge--started, .badge--success {
  background: var(--color-success-bg);
  color: var(--color-success);
}
.badge--success > svg { width: 12px; height: 12px; }

.badge--paused {
  background: var(--color-warning-bg);
  color: var(--color-warning);
}
.badge--paused > svg {
  width: 11px;
  height: 11px;
  stroke: var(--color-warning);
}

.badge--completed {
  background: var(--color-success-bg);
  color: var(--color-success);
}

/* Done — used for the "Completed" experiment-status badge (and the
   read-only device-targeting chips). Same treatment as .badge--completed
   (tinted success background + checkmark) so a finished experiment reads
   consistently wherever its status is shown. */
.badge--done {
  background: var(--color-success-bg);
  color: var(--color-success);
}
.badge--done > svg {
  width: 12px;
  height: 12px;
  stroke: var(--color-success);
}

.badge--archived {
  background: #e4e5e7;
  color: var(--color-text-disabled);
}

.badge--winner {
  background: var(--color-success-bg);
  color: var(--color-success);
  font-weight: 600;
}
.badge--winner > svg {
  width: 12px;
  height: 12px;
  stroke: var(--color-success);
}

/* Draft / not-yet-running experiments: neutral light-grey chip. */
.badge--draft {
  background: rgba(255, 255, 255, 0.08);
  color: var(--ink-3);
}

/* Warning state — used for "Inactive", "Not connected", and similar.
   Strong yellow background + leading dot so the chip reads as a status
   indicator at a glance, not a neutral label. */
.badge--warning {
  background: color-mix(in srgb, var(--warn) 26%, transparent);
  color: var(--warn);
  font-weight: 600;
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--warn) 45%, transparent);
}
.badge--warning::before {
  content: "";
  display: inline-block;
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--warn);
  margin-right: 2px;
  flex: none;
}
.badge--warning > svg {
  width: 11px;
  height: 11px;
  stroke: var(--warn);
}

/* Live / Running: brand purple chip used on running experiments.
   `.badge--live` carries a pulsing dot (used in detail header / dashboard).
   `.badge--running` carries a leading play icon (used on .exp-card). */
.badge--live,
.badge--running {
  background: var(--accent-soft);
  color: var(--accent-deep);
  font-weight: 600;
}
.badge--live::before {
  content: "";
  display: inline-block;
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: var(--accent-deep);
  margin-right: 2px;
  box-shadow: 0 0 0 0 var(--accent-deep);
  animation: badge-live-pulse 1.6s ease-out infinite;
}
.badge--running > svg {
  width: 11px;
  height: 11px;
  fill: currentColor;
  stroke: none;
  margin-right: 1px;
}
@keyframes badge-live-pulse {
  0%   { box-shadow: 0 0 0 0 color-mix(in srgb, var(--accent-deep) 70%, transparent); }
  70%  { box-shadow: 0 0 0 6px color-mix(in srgb, var(--accent-deep) 0%, transparent); }
  100% { box-shadow: 0 0 0 0 color-mix(in srgb, var(--accent-deep) 0%, transparent); }
}

/* --------------------------------------------------------------------------
   Tables / Resource Lists
   -------------------------------------------------------------------------- */
.resource-list {
  list-style: none;
  border: var(--border);
  border-radius: var(--radius-lg);
  overflow: hidden;
  background: var(--color-surface);
}

.resource-list__header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: var(--space-3) var(--space-4);
  background: var(--color-bg);
  border-bottom: var(--border);
  font-size: var(--font-size-sm);
}

.resource-item {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  padding: var(--space-3) var(--space-4);
  border-bottom: var(--border);
  transition: background 0.1s;
}

.resource-item:last-child {
  border-bottom: none;
}

.resource-item:hover {
  background: var(--color-surface-hover);
}

.resource-item a {
  display: flex;
  align-items: center;
  justify-content: space-between;
  color: var(--color-text);
  text-decoration: none;
  font-weight: 600;
}

.resource-item a:hover {
  text-decoration: none;
}

/* --------------------------------------------------------------------------
   Tabs
   -------------------------------------------------------------------------- */
.tabs {
  display: flex;
  gap: 0;
  border-bottom: var(--border);
  margin-bottom: var(--space-4);
}

.tab {
  padding: var(--space-3) var(--space-4);
  font-size: var(--font-size-base);
  font-weight: 500;
  color: var(--color-text-secondary);
  background: none;
  border: none;
  border-bottom: 2px solid transparent;
  cursor: pointer;
  transition: color 0.15s, border-color 0.15s;
}

.tab:hover {
  color: var(--color-text);
  /* Tab-style hover: a subtle surface fill rounded only on the top corners, so
     the tab reads as a tab sitting on the tablist's bottom border (the
     experiment detail nav). The bottom stays square to meet the underline. */
  background: var(--color-surface-hover);
  border-radius: 6px 6px 0 0;
}

.tab[aria-selected="true"],
.tab--active {
  color: var(--color-text);
  border-bottom-color: var(--color-link);
}

.tab-panel {
  display: none;
}

.tab-panel[aria-hidden="false"],
.tab-panel--active {
  display: block;
}

/* --------------------------------------------------------------------------
   Sub-tabs — pill / segmented control style
   -------------------------------------------------------------------------- */
.subtabs {
  display: inline-flex;
  gap: var(--space-1);
  background: var(--color-bg);
  border: var(--border);
  border-radius: var(--radius-full);
  padding: var(--space-1);
  margin-bottom: var(--space-4);
}

.subtab {
  padding: var(--space-2) var(--space-5);
  font-size: var(--font-size-base);
  font-weight: 500;
  color: var(--color-text-secondary);
  background: transparent;
  border: none;
  border-radius: var(--radius-full);
  cursor: pointer;
  transition: background 0.2s, color 0.2s, box-shadow 0.2s;
  text-align: center;
  white-space: nowrap;
}

.subtab:hover {
  background: var(--color-surface);
  color: var(--color-text);
}

.subtab[aria-selected="true"],
.subtab--active {
  color: var(--color-link);
  background: var(--color-surface);
  box-shadow: var(--shadow-md);
  font-weight: 600;
}

.subtab-panel {
  display: none;
}

.subtab-panel--active {
  display: block;
}

/* --------------------------------------------------------------------------
   Device Filter — segmented control
   -------------------------------------------------------------------------- */
.device-filter {
  display: inline-flex;
  gap: var(--space-1);
  background: var(--color-bg);
  border: var(--border);
  border-radius: var(--radius-full);
  padding: var(--space-1);
}

.device-filter__btn {
  padding: var(--space-1) var(--space-3);
  border: none;
  background: transparent;
  color: var(--color-text-secondary);
  font-weight: 400;
  cursor: pointer;
  font-size: var(--font-size-sm);
  border-radius: var(--radius-full);
  transition: background 0.2s, color 0.2s, box-shadow 0.2s;
  white-space: nowrap;
  font-family: var(--font-family);
  line-height: 1;
  min-height: 1.75rem;
  display: inline-flex;
  align-items: center;
}

.device-filter__btn:hover {
  background: var(--color-surface);
  color: var(--color-text);
}

.device-filter__btn--active {
  background: var(--color-surface);
  color: var(--color-link);
  font-weight: 600;
  box-shadow: var(--shadow-md);
}

/* --------------------------------------------------------------------------
   Callout Card
   -------------------------------------------------------------------------- */
.callout {
  display: flex;
  align-items: center;
  gap: var(--space-6);
  background: var(--color-surface);
  border: var(--border);
  border-radius: var(--radius-lg);
  padding: var(--space-6);
  box-shadow: var(--shadow-sm);
}

.callout + .callout {
  margin-top: var(--space-4);
}

.callout__illustration {
  width: 100px;
  height: 100px;
  flex-shrink: 0;
}

.callout__illustration img {
  width: 100%;
  height: 100%;
  object-fit: contain;
}

.callout__content {
  flex: 1;
}

.callout__content h3 {
  margin-bottom: var(--space-2);
}

.callout__actions {
  display: flex;
  gap: var(--space-2);
  margin-top: var(--space-3);
}

/* --------------------------------------------------------------------------
   Empty State
   -------------------------------------------------------------------------- */
.empty-state {
  text-align: center;
  padding: var(--space-12) var(--space-8);
}

.empty-state img {
  max-width: 200px;
  margin-bottom: var(--space-6);
}

.empty-state h3 {
  margin-bottom: var(--space-3);
}

.empty-state p {
  margin-bottom: var(--space-4);
}

/* --------------------------------------------------------------------------
   Skeleton Loading
   -------------------------------------------------------------------------- */
.skeleton {
  /* Dark-theme skeleton — matches the surrounding glass panels rather than
     the light-mode #e4e5e7 default that flashed as a "white block" while
     billing data was loading. */
  background: linear-gradient(90deg,
    rgba(255, 255, 255, 0.04) 25%,
    rgba(255, 255, 255, 0.10) 50%,
    rgba(255, 255, 255, 0.04) 75%);
  background-size: 200% 100%;
  animation: shimmer 1.5s infinite;
  border-radius: var(--radius-sm);
}

.skeleton--text {
  height: 0.875rem;
  margin-bottom: var(--space-2);
}

.skeleton--text:last-child {
  width: 60%;
}

.skeleton--heading {
  height: 1.5rem;
  width: 40%;
  margin-bottom: var(--space-4);
}

.skeleton--card {
  height: 8rem;
  border-radius: var(--radius-lg);
}

.skeleton--card + .skeleton--card { margin-top: var(--space-4); }

/* --------------------------------------------------------------------------
   Footer
   -------------------------------------------------------------------------- */
.page-footer {
  text-align: center;
  padding: var(--space-8) 0;
  font-size: var(--font-size-sm);
  color: var(--color-text-secondary);
}

/* --------------------------------------------------------------------------
   Support page — two-up info cards with icon + CTA.
   -------------------------------------------------------------------------- */
.support-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
  gap: var(--space-4);
  margin-top: var(--space-6);
}

.support-card {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
  padding: var(--space-6);
  background: var(--bg-elev);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  backdrop-filter: blur(16px);
  -webkit-backdrop-filter: blur(16px);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.06);
}

.support-card__icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 40px;
  height: 40px;
  border-radius: var(--radius-sm);
  box-shadow: inset 0 0 0 1px var(--line);
  background: var(--bg-elev);
  color: var(--ink);
}
.support-card__icon > svg {
  width: 20px;
  height: 20px;
  stroke: currentColor;
}

.support-card__title {
  font-size: 17px;
  font-weight: 600;
  margin: 0;
  color: var(--ink);
}

.support-card__body {
  margin: 0;
  color: var(--ink-3);
  font-size: 13px;
  line-height: 1.5;
}

.support-card__cta {
  align-self: flex-start;
  margin-top: var(--space-2);
  text-decoration: none;
}
.support-card__cta:hover {
  text-decoration: none;
}

/* --------------------------------------------------------------------------
   Modal / Dialog
   -------------------------------------------------------------------------- */
dialog {
  border: none;
  border-radius: var(--radius-lg);
  padding: 0;
  box-shadow: var(--shadow-lg);
  max-width: 500px;
  width: 90vw;
  margin: auto;
  background: rgba(8, 9, 20, 0.96);
  color: var(--ink);
  box-shadow: 0 24px 48px rgba(0, 0, 0, 0.45), inset 0 0 0 1px var(--line);
}

dialog::backdrop {
  background: rgba(0, 0, 0, 0.55);
  backdrop-filter: blur(4px);
}

.modal-dialog {
  border: none;
  border-radius: var(--radius-lg);
  padding: 0;
  background: rgba(8, 9, 20, 0.96);
  color: var(--ink);
  box-shadow: 0 24px 48px rgba(0, 0, 0, 0.45), inset 0 0 0 1px var(--line);
  max-width: 480px;
  width: 90vw;
  margin: auto;
}
.modal-dialog::backdrop { background: rgba(0, 0, 0, 0.55); backdrop-filter: blur(4px); }
.modal-dialog__header {
  padding: 18px 22px;
  border-bottom: 1px solid var(--line);
}
.modal-dialog__body {
  padding: 22px;
  font-size: 14px;
  line-height: 1.5;
  color: var(--ink-2);
}
.modal-dialog__footer {
  padding: 14px 22px;
  border-top: 1px solid var(--line);
  display: flex;
  justify-content: flex-end;
  gap: 8px;
}

.dialog__header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: var(--space-4) var(--space-6);
  border-bottom: var(--border);
}

.dialog__body {
  padding: var(--space-6);
}

.dialog__footer {
  display: flex;
  justify-content: flex-end;
  gap: var(--space-2);
  padding: var(--space-4) var(--space-6);
  border-top: var(--border);
}

/* Wider dialog when used to host an edit form with rich content. */
#variant-edit-dialog.modal-dialog,
#variant-code-preview-dialog.modal-dialog {
  max-width: 720px;
}

/* Image-zoom modal — fills most of the viewport with a single screenshot.
   Layout properties are scoped to [open] so the closed <dialog> stays hidden
   per the user-agent default (display: none). */
.modal-dialog--media {
  max-width: 92vw;
  width: 92vw;
  max-height: 90vh;
  background: #0a0b1a;
  padding: 0;
}
.modal-dialog--media[open] {
  display: flex;
  align-items: center;
  justify-content: center;
}
.modal-dialog--media img {
  display: block;
  max-width: 100%;
  max-height: 90vh;
  object-fit: contain;
  border-radius: var(--radius);
}
.variant-zoom__close {
  position: absolute;
  top: 12px;
  right: 12px;
  width: 36px;
  height: 36px;
  padding: 0;
  border-radius: 999px;
  background: rgba(10, 11, 26, 0.6);
  z-index: 2;
}

/* --------------------------------------------------------------------------
   Utilities
   -------------------------------------------------------------------------- */
.visually-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}

/* --------------------------------------------------------------------------
   Animations
   -------------------------------------------------------------------------- */
@keyframes spin {
  to { transform: rotate(360deg); }
}

@keyframes shimmer {
  0% { background-position: -200% 0; }
  100% { background-position: 200% 0; }
}

/* --------------------------------------------------------------------------
   Spinner
   -------------------------------------------------------------------------- */
.spinner {
  display: inline-block;
  width: 1.25rem;
  height: 1.25rem;
  border: 2px solid var(--color-border);
  border-top-color: var(--color-link);
  border-radius: 50%;
  animation: spin 0.6s linear infinite;
}

.spinner--small {
  width: 0.875rem;
  height: 0.875rem;
}

/* --------------------------------------------------------------------------
   Accordion (Statistical Analysis per-measurement)
   -------------------------------------------------------------------------- */
/* Accordion — restyled to match the prototype's stat-v2__panel pattern.
   Glass-translucent panel surface with a serif title in the header and a
   chevron toggle on the right. */
.accordion {
  background: rgba(255, 255, 255, 0.04);
  backdrop-filter: blur(16px);
  -webkit-backdrop-filter: blur(16px);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  /* No box-shadow on .accordion (CU-86e2cztr6). The old translucent stack
     (white inset highlight + 32px dark drop) inflated this backdrop-filtered
     layer's raster bounds; the header/chevron hover transitions then repaint
     the layer each frame and the radius clip lands on the square,
     shadow-expanded bounds — the faint lighter offset rectangle seen hovering
     over results-page panels (CU-86e2d01tz, same root cause as .exp-card). */
  overflow: hidden;
  margin-bottom: 12px;
}

.accordion + .accordion { margin-top: 0; }

.accordion__header {
  display: flex;
  align-items: center;
  gap: 18px;
  padding: 14px 18px;
  cursor: pointer;
  user-select: none;
  list-style: none;
  transition: background 120ms;
}

.accordion__header::-webkit-details-marker { display: none; }
.accordion__header:hover { background: rgba(255, 255, 255, 0.02); }

.accordion__chevron {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 28px;
  height: 28px;
  padding: 0;
  color: var(--ink-2);
  background: rgba(255, 255, 255, 0.06);
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  backdrop-filter: blur(8px);
  -webkit-backdrop-filter: blur(8px);
  transition: transform 220ms cubic-bezier(.2, .8, .2, 1), background 120ms, color 120ms;
  flex-shrink: 0;
  margin-left: auto;
  order: 2;
  /* ICON.chev is a right-pointing chevron (">"). Rotate it to point down
     while collapsed and up while expanded, per the results-page UX spec. */
  transform: rotate(90deg);
}
.accordion__chevron > svg { width: 14px; height: 14px; }
.accordion__header:hover .accordion__chevron {
  background: rgba(255, 255, 255, 0.1);
  color: var(--ink);
}

.accordion[open] > .accordion__header .accordion__chevron {
  transform: rotate(-90deg);
}

.accordion__title {
  font-family: var(--font-serif);
  font-size: 18px;
  font-weight: 500;
  letter-spacing: -1px;
  color: var(--ink);
  min-width: 0;
  flex: 1;
}

.accordion__overview {
  display: flex;
  align-items: center;
  gap: 12px;
  font-size: 13px;
  color: var(--ink-3);
  flex-wrap: wrap;
}

.accordion__body {
  padding: 0 var(--space-4) var(--space-4);
  border-top: var(--border);
  /* Without this, a flex/grid descendant can ignore the parent's width and
     push content past the right edge — most visible on results-page tables
     with min-width: 600/700px wrapped in overflow-x: auto. */
  min-width: 0;
  max-width: 100%;
}
.accordion {
  min-width: 0;
  max-width: 100%;
}

/* Conversion Rate Over Time accordion — .accordion__body has no padding-top,
   so the row holding the metric select (#chart-metric-select) sits flush
   against the header's border-top. Give the whole row breathing room so the
   dropdown doesn't look like it's touching the container border. */
#chart-container .accordion__body > .inline {
  margin-top: var(--space-3);
}

/* --------------------------------------------------------------------------
   Violin Chart / Cell-with-Chart (Statistical Analysis)
   -------------------------------------------------------------------------- */
.cell-with-chart {
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
  min-width: 280px;
}

.cell-with-chart__data {
  display: flex;
  gap: var(--space-4);
  margin: 0;
  font-size: var(--font-size-sm);
}

.cell-with-chart__data span {
  display: inline-flex;
  gap: var(--space-1);
}

.cell-with-chart__data dt {
  color: var(--color-text-secondary);
  font-weight: 400;
  font-size: var(--font-size-xs);
}

.cell-with-chart__data dd {
  margin: 0;
  font-weight: 600;
  font-size: var(--font-size-sm);
}

.violin-svg {
  display: block;
  margin-top: var(--space-1);
}

/* --------------------------------------------------------------------------
   App shell — sidebar + topbar (HTML platform only; Shopify embed renders
   navigation via <ui-nav-menu> and is hidden below).
   Extracted from redesign-assets/project/Split Test Pro Redesign v2.html
   with the designer's `[data-layout]` / `[data-variant]` modifiers removed.
   -------------------------------------------------------------------------- */
.app {
  display: grid;
  grid-template-columns: 240px 1fr;
  min-height: 100vh;
}

.sidebar {
  background: rgba(10, 11, 26, 0.5);
  backdrop-filter: blur(24px);
  -webkit-backdrop-filter: blur(24px);
  border-right: 1px solid var(--line);
  padding: 16px 12px;
  caret-color: transparent;
  display: flex;
  flex-direction: column;
  gap: 4px;
  position: sticky;
  top: 0;
  height: 100vh;
}

.brand {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 6px 8px 18px;
  text-decoration: none;
}

.brand-logo {
  height: 40px;
  width: auto;
  flex: none;
  display: block;
}

.brand-name {
  font-family: var(--font-display);
  font-weight: 600;
  font-size: 15px;
  letter-spacing: -0.01em;
  color: var(--ink);
}

.nav-group {
  display: flex;
  flex-direction: column;
  gap: 4px;
}

.nav-item {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 6px 8px;
  border-radius: var(--radius-sm);
  font-size: 13px;
  color: var(--ink-2);
  font-weight: 450;
  text-decoration: none;
  cursor: pointer;
}

.nav-item:hover {
  background: var(--bg-sunken);
  color: var(--ink);
  text-decoration: none;
}

.nav-item.is-active {
  background: var(--bg-sunken);
  color: var(--ink);
  font-weight: 500;
  box-shadow: inset 0 0 0 1px var(--line);
}

.nav-item svg {
  width: 15px;
  height: 15px;
  flex: none;
  opacity: 0.8;
}

.nav-count {
  margin-left: auto;
  font-size: 11px;
  color: var(--ink-3);
  font-variant-numeric: tabular-nums;
}

.nav-spacer {
  flex: 1;
}

.nav-footer {
  margin: 12px -12px -16px;
  padding: 8px;
  background: var(--bg-sunken);
  border-top: 1px solid var(--line);
  display: flex;
  flex-direction: column;
  gap: 2px;
}

.nav-workspace {
  display: flex;
  align-items: center;
  gap: 10px;
  width: 100%;
  padding: 8px 10px;
  border-radius: var(--radius-sm);
  background: transparent;
  border: none;
  cursor: pointer;
  transition: background 120ms;
  font: inherit;
  color: inherit;
}

.nav-workspace:hover {
  background: color-mix(in srgb, var(--ink) 6%, transparent);
}

.nav-workspace__name {
  flex: 1;
  min-width: 0;
  font-family: var(--font-serif);
  font-size: 16px;
  font-weight: 500;
  color: var(--ink);
  line-height: 1.2;
  letter-spacing: 0;
  text-align: left;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.nav-workspace > svg {
  width: 14px;
  height: 14px;
  color: var(--ink-3);
  flex: none;
}

.avatar {
  width: 24px;
  height: 24px;
  border-radius: 50%;
  background: var(--accent);
  color: #fff;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-size: 11px;
  font-weight: 600;
  font-family: var(--font-mono);
  flex: none;
}

.nav-user {
  display: flex;
  align-items: center;
  gap: 10px;
  width: 100%;
  height: unset;
  padding: 8px 10px;
  border-radius: var(--radius-sm);
  background: transparent;
  border: none;
  cursor: pointer;
  transition: background 120ms;
  font: inherit;
  text-align: left;
}

.nav-user:hover {
  background: color-mix(in srgb, var(--ink) 6%, transparent);
}

.nav-user__body {
  min-width: 0;
  flex: 1;
}

.nav-user__name {
  font-weight: 500;
  color: var(--ink);
  font-size: 12px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.nav-user__email {
  color: var(--ink-3);
  font-size: 11px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* Dropdown primitive — used by sidebar workspace + user menus and anywhere
   else. Portal-style with mask-based transparency to stack over content. */
.dropdown {
  position: relative;
  display: block;
}

.dropdown__trigger > svg:last-child {
  transition: transform 220ms cubic-bezier(0.2, 0.8, 0.2, 1);
}

.dropdown.is-open .dropdown__trigger > svg:last-child {
  transform: rotate(180deg);
}

.dropdown--up .dropdown__menu {
  top: auto;
  bottom: calc(100% + 6px);
  transform-origin: bottom left;
  transform: translateY(6px) scale(0.96);
}

.dropdown--up.is-open .dropdown__menu {
  transform: translateY(0) scale(1);
}

.dropdown__menu {
  position: absolute;
  top: calc(100% + 6px);
  left: 0;
  z-index: 50;
  min-width: 180px;
  padding: 6px;
  background: #15172e;
  border-radius: var(--radius);
  box-shadow:
    0 0 0 1px rgba(255, 255, 255, 0.12),
    0 4px 12px rgba(0, 0, 0, 0.16),
    0 16px 40px rgba(0, 0, 0, 0.12);
  display: flex;
  flex-direction: column;
  gap: 2px;
  transform-origin: top left;
  transform: translateY(-6px) scale(0.96);
  opacity: 0;
  pointer-events: none;
  transition: transform 200ms cubic-bezier(0.2, 0.8, 0.2, 1), opacity 160ms;
}

/* Right-align variant — menu sits flush with the trigger's right edge and
   extends leftward. Use on triggers near the right edge of the viewport
   (like the sort dropdown on the experiments list). */
.dropdown--align-end .dropdown__menu {
  right: 0;
  left: auto;
  transform-origin: top right;
}

.dropdown.is-open .dropdown__menu {
  transform: translateY(0) scale(1);
  opacity: 1;
  pointer-events: auto;
  width: 100%;
}

.dropdown__item {
  display: inline-flex;
  align-items: center;
  justify-content: flex-start;
  gap: 10px;
  padding: 8px 12px;
  border-radius: var(--radius-sm);
  font-size: 13px;
  color: var(--ink-2);
  text-align: left;
  background: transparent;
  border: none;
  cursor: pointer;
  width: 100%;
  font: inherit;
  text-decoration: none;
  transition: background 120ms, color 120ms;
}

.dropdown__item:hover {
  background: var(--bg-sunken);
  color: var(--ink);
  text-decoration: none;
}

.dropdown__item.is-selected {
  background: var(--bg-sunken);
  color: var(--ink);
  font-weight: 500;
}

.dropdown__item > svg {
  width: 14px;
  height: 14px;
  flex: none;
  color: var(--ink-3);
  transition: color 120ms;
}

.dropdown__item:hover > svg,
.dropdown__item.is-selected > svg {
  color: var(--ink);
}

.dropdown__item--danger,
.dropdown__item--danger:hover {
  color: var(--neg);
}

.dropdown__item--danger:hover {
  background: color-mix(in srgb, var(--neg) 10%, transparent);
}

.dropdown__item--danger > svg,
.dropdown__item--danger:hover > svg {
  color: currentColor;
}

.dropdown__divider {
  height: 1px;
  background: var(--line);
  margin: 4px 2px;
}

/* Topbar — hidden in magazine layout (page-head hero replaces it) */
.topbar {
  display: none;
  height: 52px;
  border-bottom: 1px solid var(--line);
  align-items: center;
  gap: 16px;
  padding: 0 28px;
  position: sticky;
  top: 0;
  background: rgba(10, 11, 26, 0.5);
  backdrop-filter: blur(24px);
  -webkit-backdrop-filter: blur(24px);
  z-index: 10;
}

.crumbs {
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 13px;
  color: var(--ink-3);
}

.crumbs__sep { color: var(--ink-4); }
.crumbs__here { color: var(--ink); font-weight: 500; }

.crumbs a {
  color: inherit;
  text-decoration: none;
}

.crumbs a:hover {
  color: var(--ink);
  text-decoration: none;
}

.topbar-search {
  margin-left: auto;
  display: flex;
  align-items: center;
  gap: 8px;
  height: 30px;
  padding: 0 10px;
  background: var(--bg-sunken);
  border-radius: var(--radius-sm);
  font-size: 12px;
  color: var(--ink-3);
  width: 280px;
  box-shadow: inset 0 0 0 1px var(--line);
}

.topbar-search > svg {
  width: 14px;
  height: 14px;
  flex: none;
}

.topbar-search .kbd {
  margin-left: auto;
  font-family: var(--font-mono);
  font-size: 10px;
  padding: 1px 5px;
  background: var(--bg-elev);
  border-radius: 3px;
  box-shadow: inset 0 0 0 1px var(--line);
  color: var(--ink-3);
}

/* Shopify embed: the in-app sidebar and topbar are NOT rendered (the Shopify
   admin chrome already provides navigation via <ui-nav-menu>). Hide the
   native element on the HTML platform — it's a no-op inside Shopify. */
ui-nav-menu {
  display: none;
}

/* Content mount point — magazine layout with compact density (prototype default).
   Values = magazine base (48/72/100) × compact density multiplier (0.82). */
#app-content {
  padding: 40px 60px 82px;
  max-width: none;
}

/* Magazine page-head — serif display title + short subtitle, single column */
.page-head {
  padding-bottom: 0.8rem;
  margin-bottom: 32px;
  display: flex;
  flex-direction: column;
  gap: 12px;
}

.page-title {
  font-family: var(--font-serif);
  font-size: 40px;
  font-weight: 500;
  line-height: 1.05;
  letter-spacing: -1px;
  color: var(--ink);
  margin: 0;
}

.page-sub {
  font-size: 15px;
  max-width: 42ch;
  line-height: 1.6;
  color: var(--ink-3);
  margin: 0;
}

/* Two-line truncation w/ "Read more" toggle for hypothesis-style sub-titles. */
.page-sub-wrap {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 4px;
}
.page-sub--clamp {
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
  text-overflow: ellipsis;
  margin: 0;
}
.page-sub--clamp.is-expanded {
  display: block;
  -webkit-line-clamp: unset;
  overflow: visible;
}
.page-sub__more {
  height: auto;
  padding: 0;
  background: transparent;
  border: none;
  color: var(--accent-deep);
  font-size: 12px;
  font-weight: 500;
  text-decoration: underline;
  text-underline-offset: 2px;
  cursor: pointer;
}
.page-sub__more:hover {
  color: var(--ink);
  background: transparent;
  box-shadow: none;
}

/* Prototype magazine layout: title stacks above a row of sub + actions.
   Allows the "View experiments" / "New experiment" buttons to sit inline
   with the subtitle on the dashboard page-head. */
.page-head__meta {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: 24px;
  flex-wrap: wrap;
}

/* Section title used inside panels (Details / Hypothesis / Goals / etc.) */
.section-title {
  font-family: var(--font-serif);
  font-size: 20px;
  font-weight: 500;
  letter-spacing: -1px;
  color: var(--ink);
}

/* Running/detail page header row — title + status badge side by side */
.running-title-row {
  display: flex;
  align-items: center;
  gap: 12px;
}

/* Experiment-detail tabs — matches prototype v2.html:1113-1121 */
.tabs {
  display: flex;
  gap: 2px;
  border-bottom: 1px solid var(--line);
  margin-bottom: 24px;
  position: relative;
}

.tab {
  padding: 10px 14px;
  font-family: var(--font-serif);
  font-size: 18px;
  /* Buttons don't inherit the body line-height the way anchors do — pin it
     so the <button> tabs render at the same height the <a> tabs did. */
  line-height: 1.5;
  letter-spacing: -1px;
  color: var(--ink-3);
  font-weight: 500;
  background: none;
  border: none;
  cursor: pointer;
  caret-color: transparent;
  transition: color 160ms;
  text-decoration: none;
}

.tab:hover { color: var(--ink-2); }
.tab.is-active { color: var(--ink); }

/* Keyboard focus — tabs are real buttons with a roving tabindex; give
   :focus-visible an accent ring so the current tab stop is obvious. */
.tab:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: -2px;
  border-radius: var(--radius-sm);
}

.tab.is-active::after {
  content: '';
  position: absolute;
  bottom: -1px;
  height: 2px;
  background: var(--ink);
  /* The active tab marker: simple bottom border rule. Left+width computed
     by the tab's own position via left:0 / right:0 via the active rule. */
}

/* The FLIP-animated indicator the prototype uses requires JS measurement;
   for this pass we use a simple static underline via the active tab's
   ::before element to keep the CSS-only solution. */
.tab.is-active {
  position: relative;
}
.tab.is-active::before {
  content: '';
  position: absolute;
  bottom: -1px;
  left: 0;
  right: 0;
  height: 2px;
  background: var(--ink);
}

/* ── Experiment detail: running/general 2-column layout ─────── */
.running-general-layout {
  display: grid;
  grid-template-columns: 1fr 320px;
  gap: 16px;
}

.running-general-main,
.running-general-side {
  display: flex;
  flex-direction: column;
  gap: 16px;
}

/* Details panel grid — 2 columns of key/value pairs */
.details-panel__grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 20px 32px;
}

.details-panel__item .text--tiny {
  margin-bottom: 4px;
}

/* Status panel rows */
.status-panel__row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
}

.status-panel__row .text--mono { color: var(--ink); }
.status-panel__row .text--muted { font-size: 13px; }

/* Actions panel — stacked full-width buttons (centered like default .btn) */
.actions-panel__list .btn {
  width: 100%;
  padding: 0 16px;
}

/* Horizontal progress bar — used in the device breakdown cards. */
.bar {
  height: 6px;
  background: var(--bg-sunken);
  border-radius: 999px;
  overflow: hidden;
  box-shadow: inset 0 0 0 1px var(--line);
}
.bar > span {
  display: block;
  height: 100%;
  background: var(--ink);
  transition: width 240ms cubic-bezier(.2, .8, .2, 1);
}

/* Variant swatch — small color dot used in allocation rows + preview labels */
.variant-swatch {
  display: inline-block;
  width: 10px;
  height: 10px;
  border-radius: 50%;
  background: var(--accent);
  flex: none;
}

/* --------------------------------------------------------------------------
   Allocation split-bar — single horizontal control replacing per-row sliders.
   Each variant is one .split-bar__seg; dragging .split-bar__handle elements
   between segments transfers weight and the bar always sums to 100%.
   -------------------------------------------------------------------------- */
.split-bar {
  position: relative;
  display: flex;
  align-items: stretch;
  height: 24px;
  border-radius: 999px;
  overflow: hidden;
  background: var(--bg-sunken);
  box-shadow: inset 0 0 0 1px var(--line);
  margin-bottom: 20px;
  user-select: none;
}

.split-bar__seg {
  position: relative;
  height: 100%;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 0;
  overflow: hidden;
  transition: width 200ms cubic-bezier(.2,.8,.2,1);
}
.split-bar.is-dragging .split-bar__seg { transition: none; }

.split-bar__seg-label {
  display: inline-block;
  font-size: 11px;
  font-weight: 600;
  color: rgba(10, 11, 26, 0.85);
  letter-spacing: 0.01em;
  padding: 0 6px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  pointer-events: none;
}

.split-bar__handle {
  flex: none;
  width: 6px;
  background: rgba(10, 11, 26, 0.6);
  cursor: ew-resize;
  position: relative;
  z-index: 2;
  transition: background 140ms, transform 140ms;
}
.split-bar__handle::before {
  content: "";
  position: absolute;
  inset: -4px -3px;
}
.split-bar--interactive .split-bar__handle:hover,
.split-bar--interactive .split-bar__handle:focus-visible {
  background: var(--ink);
  outline: none;
  transform: scaleX(1.5);
}
.split-bar:not(.split-bar--interactive) .split-bar__handle {
  cursor: default;
  background: transparent;
}

/* Locked state: bar is rendered but not interactive (experiment running).
   A click surfaces a "pause to adjust" toast (handled in JS). */
.split-bar--locked {
  cursor: not-allowed;
  position: relative;
}

/* Single-value variant of split-bar (e.g. experiment traffic allocation):
   handle blends with the accent-colored "Included" segment instead of
   showing as a high-contrast dark slab the way the multi-variant slider
   does. Hover/focus still escalate to var(--ink) for affordance. */
#exp-traffic-allocation-bar .split-bar__handle {
  background: var(--accent);
}
#exp-traffic-allocation-bar.split-bar--interactive .split-bar__handle:hover,
#exp-traffic-allocation-bar.split-bar--interactive .split-bar__handle:focus-visible {
  background: var(--ink);
}

/* Info icon next to "Total allocated" — CSS-driven hover tooltip. */
.allocation-info {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 16px;
  height: 16px;
  border-radius: 50%;
  color: var(--ink-3);
  cursor: help;
  position: relative;
  outline: none;
}
.allocation-info > svg {
  width: 14px;
  height: 14px;
  stroke: currentColor;
}
.allocation-info[data-tooltip]::after {
  content: attr(data-tooltip);
  position: absolute;
  right: 0;
  top: calc(100% + 6px);
  width: max-content;
  max-width: 280px;
  padding: 8px 10px;
  background: #15172e;
  border: 1px solid var(--line-strong);
  border-radius: var(--radius-sm);
  color: var(--ink);
  font-size: 12px;
  font-weight: 500;
  line-height: 1.4;
  white-space: normal;
  text-align: left;
  opacity: 0;
  pointer-events: none;
  transform: translateY(4px);
  transition: opacity 160ms, transform 160ms cubic-bezier(.2,.8,.2,1);
  z-index: 1000;
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.32);
}
.allocation-info:hover::after,
.allocation-info:focus-visible::after,
.allocation-info.is-pinned::after {
  opacity: 1;
  transform: translateY(0);
}

/* --------------------------------------------------------------------------
   Variant row — header line + actions in a 2-col grid.
   -------------------------------------------------------------------------- */
.variant-row__grid {
  display: grid;
  grid-template-columns: 1fr auto;
  gap: 24px;
  align-items: center;
  padding: 14px 0;
}

/* Responsive: on narrow viewports stack the info + actions so the Preview/Edit
   button group and settings menu wrap instead of overflowing the panel. */
@media (max-width: 640px) {
  .variant-row__grid {
    grid-template-columns: 1fr;
    gap: 12px;
  }
  .variant-row__actions .row { justify-content: flex-start; }
}

/* Lift the variant row whose settings menu is open above its siblings so the
   dropdown can't be painted under the next row / the split bar handles. */
.variant-row:has(.dropdown.is-open) { position: relative; z-index: 5; }

/* "Screenshot captured …" line at the bottom of the variant edit dialog —
   read-only metadata (subtask: moved out of the row into the dialog). */
.variant-edit__captured {
  margin-top: var(--space-4);
  padding-top: var(--space-3);
  border-top: 1px solid var(--line);
  color: var(--ink-3);
  font-size: 12px;
  letter-spacing: 0.01em;
}

.variant-row__weight-pill {
  font-size: 11px;
  font-weight: 600;
  padding: 2px 8px;
  background: rgba(255, 255, 255, 0.08);
  border-radius: 999px;
  color: var(--ink-2);
  letter-spacing: 0.02em;
}

/* Drag handle on non-control variant rows. Pinned to the left of the variant
   name; control variants render without it. Dimmed by default and brightens
   on row hover, mirroring the experiments-list grip pattern. */
.variant-row__grip {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 14px;
  height: 18px;
  margin-right: 2px;
  color: var(--ink-3);
  opacity: 0.45;
  cursor: grab;
  transition: opacity 120ms, color 120ms;
  user-select: none;
  touch-action: none;
}
.variant-row__grip > svg { width: 14px; height: 14px; }
.variant-row:hover .variant-row__grip { opacity: 0.9; }
.variant-row__grip:hover { color: var(--ink); opacity: 1; }
.variant-row__grip:active { cursor: grabbing; }

.variant-row.is-dragging { opacity: 0.4; cursor: grabbing; }
.variant-row.is-dragging .variant-row__grip { opacity: 1; cursor: grabbing; }

/* Icon + text "meta-pill" used to indicate CSS / JS / redirect on a variant.
   The `--button` variant resets default button chrome so the pill stays
   compact while still being clickable (opens a code-preview modal). */
.meta-pill {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  font-size: 11px;
  font-weight: 500;
  padding: 2px 8px;
  background: var(--bg-sunken);
  border-radius: 999px;
  color: var(--ink-2);
  max-width: 220px;
  overflow: hidden;
}
.meta-pill--button {
  height: auto;
  border: 1px solid transparent;
  cursor: pointer;
  font-family: inherit;
  line-height: 1.2;
  transition: background 120ms, border-color 120ms, color 120ms;
}
.meta-pill--button:hover {
  background: color-mix(in srgb, var(--accent) 12%, var(--bg-sunken));
  border-color: color-mix(in srgb, var(--accent) 35%, transparent);
  color: var(--ink);
}
.meta-pill > svg {
  width: 12px;
  height: 12px;
  stroke: currentColor;
  flex: none;
}
.meta-pill > span {
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* Variant preview screenshot panels — 2-col grid below the allocation panel */
.variant-previews {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 12px;
  margin-bottom: 16px;
  position: relative;
  z-index: 0;
}

/* Lift the allocation panel above the screenshot grid so the per-variant
   settings dropdown isn't clipped behind a screenshot. The panel's own
   backdrop-filter establishes a stacking context, so a positive z-index here
   is required for sibling stacking. */
.allocation-panel {
  position: relative;
  z-index: 2;
}

/* Native color input — strip platform chrome so it reads as a clean swatch. */
input[type="color"] {
  -webkit-appearance: none;
  -moz-appearance: none;
  appearance: none;
  background: none;
  padding: 0;
  border: none;
  width: 32px;
  height: 32px;
  cursor: pointer;
}
input[type="color"]::-webkit-color-swatch-wrapper { padding: 0; }
input[type="color"]::-webkit-color-swatch { border: none; border-radius: 4px; }
input[type="color"]::-moz-color-swatch { border: none; border-radius: 4px; }

.variant-preview__placeholder {
  position: relative;
  aspect-ratio: 16 / 10;
  border-radius: var(--radius);
  overflow: hidden;
  box-shadow: inset 0 0 0 1px var(--line);
  background: repeating-linear-gradient(
    -45deg,
    rgba(255, 255, 255, 0.04),
    rgba(255, 255, 255, 0.04) 8px,
    rgba(0, 0, 0, 0.18) 8px,
    rgba(0, 0, 0, 0.18) 16px
  );
  display: flex;
  align-items: center;
  justify-content: center;
}

.variant-preview__placeholder img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}

.variant-preview__placeholder--empty::after {
  content: "No preview captured";
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--ink-3);
  font-family: var(--font-mono);
  font-size: 12px;
  pointer-events: none;
}

.variant-preview__zoom {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  width: 44px;
  height: 44px;
  border-radius: 999px;
  background: rgba(10, 11, 26, 0.55);
  border: none;
  color: var(--ink);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  backdrop-filter: blur(8px);
  -webkit-backdrop-filter: blur(8px);
  transition: background 140ms, transform 160ms cubic-bezier(.2, .8, .2, 1);
  opacity: 0;
}
.variant-preview__placeholder:hover .variant-preview__zoom { opacity: 1; }
.variant-preview__zoom:hover { background: rgba(10, 11, 26, 0.75); transform: translate(-50%, -50%) scale(1.06); }
.variant-preview__zoom > svg { width: 20px; height: 20px; }

@media (max-width: 900px) {
  .variant-previews { grid-template-columns: 1fr; }
}

/* Results summary cards (Total Sessions / Conversions / Overall Conv. Rate).
   Left-aligned, 32px serif numbers. Replaces the centered + small treatment. */
.results-summary-cards {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: var(--space-3);
  margin-top: 24px;
  margin-bottom: var(--space-4);
}
.results-summary-card {
  flex: 1;
  min-width: 180px;
  text-align: left;
  padding: 16px 18px;
}
.results-summary-card__label {
  font-size: 12px;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--ink-3);
  margin: 0 0 6px;
}
.results-summary-card__value {
  font-size: 32px;
  font-weight: 600;
  color: #fff;
  margin: 0;
  line-height: 1.1;
}

/* Device-breakdown cards become buttons that drive the active filter. When
   a filter is active the non-selected cards dim but stay clickable so users
   can pivot directly without going back to the pill-seg.
   Reset the global `button` chip styles (inline-flex, centered, nowrap,
   32px height, 0 12px padding) so the card lays out as a block container
   and its inner rows/bars stack vertically. */
.device-breakdown__card {
  display: block;
  width: 100%;
  height: auto;
  padding: 18px;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: var(--bg-elev);
  font: inherit;
  color: inherit;
  text-align: left;
  white-space: normal;
  gap: 0;
  cursor: pointer;
  transition: opacity 160ms, border-color 160ms, transform 120ms;
}
/* Hover/active affordances are shadowless (CU-86e2cztr6 / CU-86e2d01tz): these
   cards are backdrop-filtered .panel buttons, and a hover shadow next to the
   animated translateY lift re-rasterizes the composited layer with
   shadow-inflated bounds — the results-page ghost artifact. Border + lift +
   background carry the hover state; the accent border alone marks is-active
   (its old 1px shadow ring merely doubled the border). */
.device-breakdown__card:hover {
  border-color: var(--line-strong);
  transform: translateY(-1px);
  background: var(--bg-elev);
}
.device-breakdown__card.is-active {
  border-color: var(--accent-deep);
}
.device-breakdown__card.is-dimmed {
  opacity: 0.45;
}
.device-breakdown__card.is-dimmed:hover {
  opacity: 0.85;
}

/* Spinning refresh icon used inside #refresh-results-btn while results are
   recomputing. Plays alongside the "Computing…" label. */
.refresh-icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 14px;
  height: 14px;
}
.refresh-icon > svg { width: 14px; height: 14px; }
#refresh-results-btn.is-refreshing .refresh-icon {
  animation: spin 1s linear infinite;
}

/* Hypothesis panel text */
.hypothesis-panel__text {
  margin: 0;
  color: var(--ink-2);
  line-height: 1.55;
}

/* Goals panel rows (used on General tab) */
.goals-panel__row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 12px 0;
  border-bottom: 1px solid var(--line);
  gap: 12px;
}
.goals-panel__row:last-child { border-bottom: none; }
.goals-panel__row .row { gap: 10px; }

/* Danger button variant (used in actions panel) */
.btn--danger {
  color: var(--neg) !important;
  background: color-mix(in srgb, var(--neg) 14%, transparent) !important;
  border-color: color-mix(in srgb, var(--neg) 30%, transparent) !important;
}
.btn--danger:hover {
  background: color-mix(in srgb, var(--neg) 22%, transparent) !important;
  color: var(--neg) !important;
}

@media (max-width: 1100px) {
  .running-general-layout {
    grid-template-columns: 1fr;
  }
  .details-panel__grid {
    grid-template-columns: 1fr;
  }
}

/* Glass panels — used by redesigned cards / exp-cards / result-hero / kpi */
.panel {
  background: rgba(255, 255, 255, 0.04);
  backdrop-filter: blur(16px);
  -webkit-backdrop-filter: blur(16px);
  border: 1px solid var(--line);
  /* No box-shadow on .panel (CU-86e2cztr6) — see .card/.accordion notes:
     shadows on these backdrop-filtered, radius-clipped layers are also the
     hover-ghosting vector on the results page (CU-86e2d01tz). */
  border-radius: var(--radius);
}

/* Some panels are rendered as <button> (results-page .device-breakdown__card),
   which would inherit the generic `button:hover` translucent shadow stack —
   an ANIMATED box-shadow on a backdrop-filtered layer, the exact .exp-card
   ghosting recipe (CU-86e2d03h1). Pin every .panel state to shadowless so no
   generic rule can reintroduce one. */
.panel:hover,
.panel:focus-visible {
  box-shadow: none;
}

/* --------------------------------------------------------------------------
   Status confirm bar — inline confirm panel shown above the experiment when
   the user pauses / completes / deletes / starts. Tone (warn / danger / info)
   is set via data-tone and drives the icon color, left-edge accent stripe,
   and the highlighted summary box at the bottom of the message.
   -------------------------------------------------------------------------- */
.status-confirm-bar {
  position: relative;
  padding: 16px 20px;
  margin-bottom: 16px;
  overflow: hidden;
}
.status-confirm-bar[hidden] { display: none; }

.status-confirm-bar[data-tone="warn"]   { --status-tone: var(--warn);    background: color-mix(in srgb, var(--warn) 8%, var(--bg-elev)); }
.status-confirm-bar[data-tone="danger"] { --status-tone: var(--neg);     background: color-mix(in srgb, var(--neg) 9%, var(--bg-elev)); }
.status-confirm-bar[data-tone="info"]   { --status-tone: var(--accent);  background: color-mix(in srgb, var(--accent) 8%, var(--bg-elev)); }
.status-confirm-bar[data-tone="warn"]   { border-color: color-mix(in srgb, var(--warn) 35%, transparent); }
.status-confirm-bar[data-tone="danger"] { border-color: color-mix(in srgb, var(--neg) 40%, transparent); }
.status-confirm-bar[data-tone="info"]   { border-color: color-mix(in srgb, var(--accent) 35%, transparent); }

.status-confirm-bar__row {
  display: flex;
  align-items: flex-start;
  gap: 14px;
}
.status-confirm-bar__icon {
  flex: none;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 28px;
  height: 28px;
  border-radius: 999px;
  background: color-mix(in srgb, var(--status-tone, var(--warn)) 18%, transparent);
  color: var(--status-tone, var(--warn));
  margin-top: 1px;
}
.status-confirm-bar__icon > svg { width: 16px; height: 16px; }
.status-confirm-msg {
  flex: 1;
  min-width: 0;
  font-size: 14px;
  font-weight: 500;
  color: var(--ink);
  line-height: 1.45;
}
.status-confirm-bar__actions {
  flex: none;
  display: inline-flex;
  align-items: center;
  gap: 8px;
}

/* Highlighted summary at the bottom — supporting context (what happens after
   confirming, stale-results warning, etc). Tone-tinted accent stripe matches
   the bar's tone so the relationship is clear. */
.status-confirm-bar__summary {
  margin-top: 14px;
  margin-left: 42px; /* aligns with the message column (icon width + gap) */
  padding: 10px 14px;
  background: color-mix(in srgb, var(--status-tone, var(--warn)) 10%, var(--bg-sunken));
  border-left: 3px solid var(--status-tone, var(--warn));
  border-radius: var(--radius-sm);
  font-size: 13px;
  color: var(--ink-2);
  line-height: 1.5;
}
.status-confirm-bar__summary[hidden] { display: none; }
.status-confirm-bar__summary strong { color: var(--ink); }

@media (max-width: 640px) {
  .status-confirm-bar__row { flex-wrap: wrap; }
  .status-confirm-bar__actions { flex-basis: 100%; justify-content: flex-end; }
  .status-confirm-bar__summary { margin-left: 0; }
}

/* AI analysis card — animated gradient border (prototype:499-540)
   Applied by wrapping the existing AI card in class="ai-analysis". */
@property --ai-border-angle {
  syntax: '<angle>';
  initial-value: 0deg;
  inherits: false;
}

.ai-analysis {
  position: relative;
  overflow: hidden;
  border-radius: var(--radius);
  background:
    radial-gradient(ellipse at 0% 0%, rgba(139, 122, 255, 0.08), transparent 50%),
    radial-gradient(ellipse at 100% 100%, rgba(94, 227, 164, 0.06), transparent 50%),
    var(--bg-elev);
  /* No box-shadow (CU-86e2cztr6): this card is a results-page .panel, and its
     old 24px accent glow both broke the shadowless-panel rule and inflated the
     raster bounds of a layer that repaints continuously (the conic border
     animation below) — another ghost-rectangle vector (CU-86e2d01tz). */
  isolation: isolate;
}

.ai-analysis::before {
  content: '';
  position: absolute;
  inset: 0;
  border-radius: inherit;
  padding: 1.5px;
  background: conic-gradient(
    from var(--ai-border-angle),
    rgba(139, 122, 255, 0.10) 0deg,
    rgba(139, 122, 255, 0.65) 40deg,
    rgba(166, 147, 255, 0.7) 90deg,
    rgba(94, 227, 164, 0.6) 160deg,
    rgba(139, 122, 255, 0.10) 210deg,
    rgba(139, 122, 255, 0.10) 290deg,
    rgba(139, 122, 255, 0.55) 340deg,
    rgba(139, 122, 255, 0.10) 360deg
  );
  -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
          mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  -webkit-mask-composite: xor;
          mask-composite: exclude;
  pointer-events: none;
  z-index: 1;
  animation: ai-border-spin 11s linear infinite;
}

.ai-analysis > * { position: relative; z-index: 2; }

@keyframes ai-border-spin {
  to { --ai-border-angle: 360deg; }
}

/* AI icon wrap — animated blobs behind a brandmark + particle field.
   Ported from redesign-assets/project/Split Test Pro Redesign v2.html:542-612. */
.ai-analysis__icon-wrap {
  width: 48px;
  height: 48px;
  border-radius: 12px;
  background: linear-gradient(135deg, rgba(139, 122, 255, 0.1), rgba(94, 227, 164, 0.06));
  box-shadow: inset 0 0 0 1px rgba(139, 122, 255, 0.25);
  display: flex;
  align-items: center;
  justify-content: center;
  flex: none;
  position: relative;
  overflow: hidden;
  isolation: isolate;
}

.ai-analysis__icon-wrap::before,
.ai-analysis__icon-wrap::after {
  content: '';
  position: absolute;
  inset: -40%;
  border-radius: 50%;
  filter: blur(10px);
  pointer-events: none;
  z-index: 0;
  mix-blend-mode: screen;
}

.ai-analysis__icon-wrap::before {
  background: radial-gradient(circle, rgba(139, 122, 255, 0.65) 0%, rgba(139, 122, 255, 0.25) 40%, transparent 70%);
  animation: ai-blob-1 7.5s ease-in-out infinite;
}
.ai-analysis__icon-wrap::after {
  background: radial-gradient(circle, rgba(94, 227, 164, 0.55) 0%, rgba(94, 227, 164, 0.22) 40%, transparent 70%);
  animation: ai-blob-2 9.8s ease-in-out infinite;
}

@keyframes ai-blob-1 {
  0%, 100% { transform: translate(-22%, -18%) scale(1);   }
  25%      { transform: translate(18%, -10%) scale(1.18); }
  50%      { transform: translate(22%, 20%)  scale(0.88); }
  75%      { transform: translate(-14%, 24%) scale(1.08); }
}
@keyframes ai-blob-2 {
  0%, 100% { transform: translate(24%, 22%)  scale(1);    }
  25%      { transform: translate(-18%, 14%) scale(1.1);  }
  50%      { transform: translate(-22%, -20%) scale(0.92);}
  75%      { transform: translate(14%, -18%) scale(1.14); }
}

.ai-particles {
  position: absolute;
  inset: 0;
  z-index: 1;
  pointer-events: none;
  mix-blend-mode: screen;
}

.ai-analysis__brandmark {
  position: relative;
  z-index: 2;
  width: 26px;
  height: auto;
  display: block;
  filter: drop-shadow(0 0 3px rgba(0, 0, 0, 1));
}

.ai-particle {
  position: absolute;
  display: block;
  width: 1.5px;
  height: 1.5px;
  border-radius: 50%;
  background: #fff;
  box-shadow: 0 0 4px rgba(255, 255, 255, 0.8), 0 0 8px rgba(184, 169, 255, 0.5);
  opacity: 0;
  animation: ai-drift 14s linear infinite;
}

.ai-particle:nth-child(1)  { top: 20%; left: 15%; animation-duration: 13s; animation-delay: -1s;  width: 2px; height: 2px; }
.ai-particle:nth-child(2)  { top: 70%; left: 25%; animation-duration: 16s; animation-delay: -5s;  width: 1px; height: 1px; }
.ai-particle:nth-child(3)  { top: 30%; left: 65%; animation-duration: 12s; animation-delay: -9s;  width: 2px; height: 2px; box-shadow: 0 0 5px rgba(139, 255, 200, 0.9), 0 0 10px rgba(94, 227, 164, 0.55); }
.ai-particle:nth-child(4)  { top: 55%; left: 48%; animation-duration: 18s; animation-delay: -3s; }
.ai-particle:nth-child(5)  { top: 12%; left: 75%; animation-duration: 15s; animation-delay: -11s; width: 1px; height: 1px; }
.ai-particle:nth-child(6)  { top: 82%; left: 60%; animation-duration: 11s; animation-delay: -7s;  box-shadow: 0 0 4px rgba(184, 169, 255, 0.95), 0 0 8px rgba(139, 122, 255, 0.6); }
.ai-particle:nth-child(7)  { top: 45%; left: 10%; animation-duration: 17s; animation-delay: -13s; }
.ai-particle:nth-child(8)  { top: 60%; left: 80%; animation-duration: 14s; animation-delay: -2s;  width: 1px; height: 1px; box-shadow: 0 0 4px rgba(139, 255, 200, 0.85), 0 0 8px rgba(94, 227, 164, 0.45); }
.ai-particle:nth-child(9)  { top: 35%; left: 35%; animation-duration: 20s; animation-delay: -6s;  width: 2px; height: 2px; }
.ai-particle:nth-child(10) { top: 78%; left: 42%; animation-duration: 13s; animation-delay: -10s; width: 2px; height: 2px; }
.ai-particle:nth-child(11) { top: 18%; left: 50%; animation-duration: 15s; animation-delay: -4s;  width: 1px; height: 1px; box-shadow: 0 0 3px rgba(255, 255, 255, 0.9); }
.ai-particle:nth-child(12) { top: 65%; left: 20%; animation-duration: 19s; animation-delay: -15s; }

@keyframes ai-drift {
  0%   { transform: translate(0, 0)       scale(0.6); opacity: 0;   }
  15%  { transform: translate(6px, -10px) scale(1);   opacity: 0.9; }
  35%  { transform: translate(14px, -4px) scale(1.1); opacity: 0.8; }
  55%  { transform: translate(8px, 14px)  scale(0.95); opacity: 1;  }
  75%  { transform: translate(-10px, 8px) scale(1);    opacity: 0.7;}
  90%  { transform: translate(-6px, -6px) scale(0.7);  opacity: 0.3;}
  100% { transform: translate(0, 0)       scale(0.5);  opacity: 0;  }
}

.ai-analysis__details { width: 100%; }
.ai-analysis__details > summary {
  list-style: none;
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  gap: 8px;
  font-size: 13px;
  color: var(--ink-2);
  user-select: none;
}
.ai-analysis__details > summary::-webkit-details-marker { display: none; }
.ai-analysis__details > summary:hover { color: var(--ink); }
.ai-analysis__details-caret {
  display: inline-flex;
  transition: transform 0.18s ease;
}
.ai-analysis__details[open] > summary .ai-analysis__details-caret {
  transform: rotate(180deg);
}
.ai-analysis__details[open] > summary .ai-analysis__details-label {
  color: var(--ink);
}

/* Collapsible AI Analysis card. The whole panel is a <details> now — the
   header is the <summary>. Hide the default disclosure marker so the layout
   stays clean. */
.ai-analysis__toggle {
  width: 32px;
  padding: 0;
  transition: transform 0.18s ease;
}
/* The body is shown when the panel has .is-open. Hide otherwise. */
.ai-analysis--collapsible:not(.is-open) > .ai-analysis__body { display: none !important; }

/* The global `button { display: inline-flex }` rule beats the UA `[hidden]
   { display: none }` rule on specificity, so the toggle stayed visible even
   with `hidden=""` set. Force-hide here so the dropdown is gone until there's
   an analysis to collapse. */
.ai-analysis__toggle[hidden] { display: none !important; }

/* Recommendation callout — promoted to the bottom of the analysis body so
   the user's "what should I do" lands last and stands out from the rest of
   the report text. */
.ai-analysis__recommendation {
  margin-top: 18px;
  padding: 14px 16px;
  background: color-mix(in srgb, var(--accent) 10%, transparent);
  border: 1px solid color-mix(in srgb, var(--accent) 30%, transparent);
  border-radius: var(--radius-sm);
}
.ai-analysis__recommendation > h2,
.ai-analysis__recommendation > h3 {
  margin-top: 0;
  color: var(--accent-deep);
  font-family: var(--font-serif);
  letter-spacing: -1px;
}
.ai-analysis__recommendation > p:last-child { margin-bottom: 0; }

/* Inline stat highlights — green for positive lift, red for regression.
   Wrapped around percent values by enhanceAIAnalysisHTML(). */
.ai-analysis__stat {
  font-weight: 600;
  font-variant-numeric: tabular-nums;
}
.ai-analysis__stat.delta--pos { color: var(--pos); }
.ai-analysis__stat.delta--neg { color: var(--neg); }

/* Winner callout — shown on dashboard when a running experiment reaches
   95%+ probability-to-be-best. Prototype v2.html:3723-3733. */
.winner-callout {
  padding: 22px 24px 22px 27px;
  margin-bottom: 28px;
  display: flex;
  align-items: center;
  gap: 22px;
  position: relative;
  overflow: hidden;
}

.winner-callout__body { flex: 1; min-width: 0; }
.winner-callout__label { margin-bottom: 10px; }

.winner-callout__headline {
  font-family: var(--font-display);
  font-size: 20px;
  font-weight: 600;
  letter-spacing: -0.01em;
  color: var(--ink);
}

.winner-callout__headline .lift-serif {
  font-family: var(--font-serif);
}

/* Stat numbers (counts, rates, totals) use the serif font for tabular display. */
.stat-num,
.lift-serif {
  font-family: var(--font-serif);
  font-feature-settings: "tnum" 1, "lnum" 1;
  letter-spacing: -1px;
}

/* Inline numeric display — serif + tabular nums, but without the aggressive
   -1px tracking that .stat-num applies to large headline numbers. Use this
   on table cells, summary metrics, and any inline number that previously
   read as monospaced. Keeps digits aligned column-to-column. */
.text--num {
  font-family: var(--font-serif);
  font-feature-settings: "tnum" 1, "lnum" 1;
  font-variant-numeric: tabular-nums;
}

/* Results page outer flow — every top-level child of #results-inner is a
   distinct section (verdict, AI analysis, device cards, per-metric accordion,
   funnel, chart, ShopifyQL). Use a flex column with a uniform 1.5rem gap and
   neutralize the ad-hoc margins on direct children + the panels nested inside
   wrapper divs (#ai-analysis-card holds an .ai-analysis panel with its own
   margin-bottom; same for ShopifyQL). Inner-content margins (inside accordion
   bodies, panel padding, etc.) are unaffected.
   `min-width: 0` is mandatory on a flex container's children — without it,
   any wide content (table with min-width: 600px, long mono span, etc.) can
   push past the right edge of the page. */
#results-inner {
  display: flex;
  flex-direction: column;
  gap: 1.5rem;
  min-width: 0;
}
#results-inner > * {
  margin-top: 0;
  margin-bottom: 0;
  min-width: 0;
  max-width: 100%;
}
#results-inner > * > .panel,
#results-inner > * > .accordion,
#results-inner > .accordion {
  margin-top: 0;
  margin-bottom: 0;
}
#results-inner > *:empty { display: none; }

.winner-callout__sub {
  font-size: 13px;
  margin-top: 4px;
  color: var(--ink-3);
}

.winner-callout__chart { flex: none; }
.winner-callout__actions { flex: none; }

/* Active experiments rows — 5-column grid with posterior chart.
   Matches prototype v2.html:3743 style (inline grid). */
.active-experiments {
  padding: 16px;
}

.active-experiments__row {
  display: grid;
  grid-template-columns: 1.4fr 100px 140px 120px 80px;
  gap: 20px;
  align-items: center;
  padding: 12px 8px;
  border-bottom: 1px solid var(--line);
  cursor: pointer;
  transition: background 120ms;
}

.active-experiments__row:hover { background: rgba(255, 255, 255, 0.02); }
.active-experiments__row:last-child { border-bottom: 0; }

.active-experiments__info { min-width: 0; overflow: hidden; }
.active-experiments__name {
  font-weight: 500;
  font-size: 14px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.active-experiments__meta {
  color: var(--ink-3);
  font-size: 12px;
  margin-top: 2px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.active-experiments__spark { width: 100%; min-width: 0; }
.active-experiments__posterior { display: flex; align-items: center; min-width: 0; }
.active-experiments__lift { text-align: right; }
.active-experiments__status { text-align: right; }

.active-experiments__footer {
  padding: 10px 0 6px;
  justify-content: center;
  display: flex;
  gap: 12px;
}

/* Experiments list + card — matches prototype v2.html:1070-1111 */
.exp-list {
  display: grid;
  grid-template-columns: 1fr;
  gap: 12px;
}

.exp-list.is-reordering .exp-card {
  transition: transform 240ms cubic-bezier(.2, .8, .2, 1);
}

.exp-card {
  display: grid;
  grid-template-columns: 14px minmax(0, 1fr) 120px 110px 90px 28px;
  gap: 20px;
  align-items: center;
  padding: 16px 20px 16px 10px;
  background: rgba(255, 255, 255, 0.04);
  backdrop-filter: blur(16px);
  -webkit-backdrop-filter: blur(16px);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  /* No box-shadow on .exp-card (CU-86e2d04cp) — the card reads through its
     background + border alone. The old translucent shadow stack (white inset
     highlight + dark drop) also animated on hover, and on this
     backdrop-filtered, radius-clipped element Chromium re-rasterizes the
     composited layer with the shadow-inflated square bounds mid-transition,
     which painted a faint lighter offset rectangle past the rounded corners
     ("ghosting", CU-86e2d03h1). Keep shadows off and out of the transition
     list so the hover repaint is background-only. */
  transition: background 160ms, transform 240ms cubic-bezier(.2, .8, .2, 1);
  cursor: pointer;
  text-decoration: none;
  color: var(--ink);
}

.exp-card:hover {
  background: rgba(255, 255, 255, 0.06);
  color: var(--ink);
  text-decoration: none;
}

/* Keyboard focus — rows are tab stops (role=link, Enter opens). Accent
   outline instead of the old box-shadow ring (shadows are banned on
   .exp-card, see above); matches the .exp-card__grip focus treatment. */
.exp-card:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
  border-color: var(--accent);
}

.exp-card.is-dragging { opacity: 0.4; cursor: grabbing; }
.exp-card.is-dragging .exp-card__grip { opacity: 1; cursor: grabbing; }

.exp-card__grip {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 14px;
  height: 28px;
  margin-right: -10px;
  color: var(--ink-3);
  opacity: 0.45;
  cursor: grab;
  transition: opacity 120ms, color 120ms;
  user-select: none;
  touch-action: none;
}

.exp-card__grip:hover { color: var(--ink); opacity: 1; }
.exp-card__grip:focus-visible {
  color: var(--ink);
  opacity: 1;
  outline: 2px solid var(--accent);
  outline-offset: 1px;
  border-radius: 4px;
}
.exp-card__grip:active { cursor: grabbing; }
.exp-card__grip > svg { width: 14px; height: 14px; }
.exp-card:hover .exp-card__grip { opacity: 0.9; }

/* Hover tooltip on a locked grip — surfaces the "switch to Manual" hint
   without requiring the user to click first. Uses a CSS-only ::after popover
   so there's no JS cost and it lines up with the grip column reliably. */
.exp-card__grip[data-tooltip] {
  position: relative;
}
.exp-card__grip[data-tooltip]::after {
  content: attr(data-tooltip);
  position: absolute;
  left: 50%;
  bottom: calc(100% + 6px);
  transform: translateX(-50%) translateY(4px);
  padding: 6px 10px;
  background: #15172e;
  border: 1px solid var(--line-strong);
  border-radius: var(--radius-sm);
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.32);
  color: var(--ink);
  font-size: 12px;
  font-weight: 500;
  white-space: nowrap;
  opacity: 0;
  pointer-events: none;
  transition: opacity 160ms, transform 160ms cubic-bezier(.2,.8,.2,1);
  z-index: 1000;
}
.exp-card__grip[data-tooltip]:hover::after,
.exp-card__grip[data-tooltip]:focus-visible::after {
  opacity: 1;
  transform: translateX(-50%) translateY(0);
}

/* Transient hint shown when a user tries to drag a card while the list is
   sorted by something other than Manual. Anchored above the grip; auto-fades. */
.exp-sort-hint {
  position: absolute;
  z-index: 1000;
  padding: 6px 10px;
  background: var(--bg-elev);
  border: 1px solid var(--line-strong);
  border-radius: var(--radius-sm);
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.32);
  color: var(--ink);
  font-size: 12px;
  font-weight: 500;
  white-space: nowrap;
  opacity: 0;
  transform: translateY(4px);
  transition: opacity 180ms, transform 180ms cubic-bezier(.2,.8,.2,1);
  pointer-events: none;
}
.exp-sort-hint.exp-sort-hint--visible {
  opacity: 1;
  transform: translateY(0);
}

.exp-card__main { min-width: 0; overflow: hidden; }

.exp-card__name {
  font-weight: 550;
  font-size: 15px;
  letter-spacing: -0.005em;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.exp-card__meta {
  display: flex;
  gap: 8px;
  font-size: 12px;
  color: var(--ink-3);
  margin-top: 6px;
  flex-wrap: wrap;
}

.exp-card__meta span { display: inline-flex; align-items: center; gap: 5px; }
.exp-card__meta span + span { padding-left: 8px; border-left: 1px solid var(--line); }

.exp-card__spark { width: 100%; min-width: 0; }
.exp-card__spark-empty {
  font-size: 11px;
  color: var(--ink-4);
  font-family: var(--font-mono);
  text-align: center;
}

.exp-card__lift { text-align: right; }

.lift {
  font-family: var(--font-serif);
  font-size: 20px;
  font-weight: 600;
  letter-spacing: -1px;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

.lift-sub {
  font-size: 11px;
  color: var(--ink-3);
  font-family: var(--font-mono);
  margin-top: 2px;
}

.exp-card__chev {
  display: inline-flex;
  color: var(--ink-3);
  transition: transform 200ms cubic-bezier(.2, .8, .2, 1), color 200ms;
}
.exp-card__chev > svg { width: 20px; height: 20px; }
.exp-card:hover .exp-card__chev { transform: translateX(4px); color: var(--ink-2); }

/* Filter bar pill-seg styles — simpler version of prototype */
.pill-seg {
  position: relative;
  display: inline-flex;
  gap: 6px;
  background: var(--bg-sunken);
  padding: 6px;
  border-radius: 999px;
  box-shadow: inset 0 0 0 1px var(--line);
  width: max-content;
  caret-color: transparent;
}

.pill-seg .btn.pill {
  position: relative;
  min-width: 0;
  padding: 0 14px;
  height: 28px;
  font-size: 12px;
  border-radius: 999px;
  background: transparent;
  border: 1px solid transparent;
  box-shadow: none;
  backdrop-filter: none;
  color: var(--ink-3);
  gap: 6px;
}

.pill-seg .btn.pill:hover { color: var(--ink-2); background: transparent; }

.pill-seg .btn.pill.is-active {
  color: var(--ink);
  background: rgba(255, 255, 255, 0.1);
  border-color: rgba(255, 255, 255, 0.25);
  box-shadow: 0 1px 2px rgba(0, 0, 0, 0.14), 0 4px 12px rgba(0, 0, 0, 0.08);
}

.pill-seg .btn.pill .text--muted { font-size: 11px; color: var(--ink-4); }
.pill-seg .btn.pill.is-active .text--muted { color: var(--ink-3); }
.pill-seg .btn.pill > svg { width: 12px; height: 12px; flex: none; }

/* Section rule — used between panel groups on dashboard + detail pages */
.v2-section-rule {
  display: flex;
  align-items: center;
  gap: 12px;
  margin: 28px 0 16px;
}

.v2-section-rule h2 {
  font-family: var(--font-serif);
  font-size: 20px;
  font-weight: 500;
  letter-spacing: -1px;
  margin: 0;
  color: var(--ink);
}

.v2-section-rule hr {
  flex: 1;
  border: none;
  border-top: 1px solid var(--line);
}

.v2-section-rule a {
  color: var(--ink-3);
  font-size: 12px;
  text-decoration: none;
}

.v2-section-rule a:hover {
  color: var(--ink);
}

/* Delta / lift indicators */
.delta {
  display: inline-flex;
  align-items: center;
  gap: 2px;
  font-family: var(--font-serif);
  font-size: 14px;
  font-weight: 600;
  letter-spacing: -1px;
}

.delta--pos { color: var(--pos); }
.delta--neg { color: var(--neg); }

/* Sparkline */
.spark { display: block; width: 100%; height: 28px; }

/* Text block — typography/tone modifiers (`text--*`). The one place tone,
   numerals, and micro-type live; combine with component classes as a BEM mix
   (e.g. class="active-experiments__meta text--muted"). */
.text--display { font-family: var(--font-display); letter-spacing: -0.02em; }
.text--muted { color: var(--ink-3); }
.text--mono { font-family: var(--font-mono); font-variant-numeric: tabular-nums; }
.text--tiny { font-size: 11px; letter-spacing: 0.04em; text-transform: uppercase; color: var(--ink-3); font-weight: 500; }
.text--critical { color: var(--neg); }
.text--hint { font-size: 12px; color: var(--ink-3); margin-top: 6px; }

/* Layout blocks (row/stack/inline/grid live near the top of this file) */
.row { display: flex; align-items: center; gap: 10px; }
.row--tight { gap: var(--space-2); }
.divider { height: 1px; background: var(--line); margin: 24px 0; }

/* Form label (prototype uses `.label` instead of bare <label>) */
.label {
  display: block;
  font-size: 12px;
  font-weight: 500;
  color: var(--ink-2);
  margin-bottom: 6px;
}
/* Info bubble — small (i) icon with hover/focus tooltip. */
.info-bubble {
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 16px;
  height: 16px;
  border-radius: 50%;
  background: rgba(255, 255, 255, 0.08);
  color: var(--ink-3);
  font-size: 10px;
  font-style: italic;
  font-family: var(--font-serif, Georgia, serif);
  font-weight: 600;
  cursor: help;
  user-select: none;
  vertical-align: middle;
}
.info-bubble:hover, .info-bubble:focus-visible {
  background: var(--accent-soft);
  color: var(--accent-deep);
  outline: none;
}
.info-bubble[data-tip]::after {
  content: attr(data-tip);
  position: absolute;
  bottom: calc(100% + 8px);
  left: 50%;
  transform: translateX(-50%);
  min-width: 220px;
  max-width: 320px;
  padding: 10px 12px;
  background: var(--bg-elev);
  color: var(--ink);
  border-radius: var(--radius-sm);
  box-shadow: 0 4px 16px rgba(0, 0, 0, 0.45), inset 0 0 0 1px var(--line);
  font-size: 12px;
  font-style: normal;
  font-family: var(--font-sans);
  font-weight: 400;
  line-height: 1.5;
  text-align: left;
  white-space: normal;
  pointer-events: none;
  opacity: 0;
  visibility: hidden;
  transition: opacity 0.15s, visibility 0.15s;
  z-index: 100;
}
.info-bubble:hover::after,
.info-bubble:focus-visible::after {
  opacity: 1;
  visibility: visible;
}
.info-bubble code { background: rgba(255, 255, 255, 0.06); padding: 1px 5px; border-radius: 3px; font-size: 11px; }

/* Settings — left-nav + main column layout (prototype v2.html:5019-5150) */
.settings-layout {
  display: grid;
  grid-template-columns: 200px 1fr;
  gap: 32px;
  align-items: start;
}
.settings-nav {
  position: sticky;
  top: 24px;
  display: flex;
  flex-direction: column;
  gap: 2px;
  /* Cap to viewport so the nav can scroll internally — without this, taller
     submenus push "Danger Zone" off the bottom and the user can't reach it. */
  max-height: calc(100vh - 48px);
  overflow-y: auto;
  /* Hide the scrollbar by default; show it only on interaction. */
  scrollbar-width: thin;
}
.settings-nav__item {
  display: block;
  padding: 8px 12px;
  border-radius: var(--radius-sm);
  color: var(--ink-3);
  text-decoration: none;
  font-size: 13px;
  font-weight: 500;
  transition: background 0.15s, color 0.15s;
}
.settings-nav__item:hover {
  background: var(--bg-sunken);
  color: var(--ink-2);
  text-decoration: none;
}
.settings-nav__item.is-active {
  background: var(--accent-soft);
  color: var(--accent-deep);
  text-decoration: none;
}
.settings-main {
  display: flex;
  flex-direction: column;
  gap: 16px;
  min-width: 0;
}
.settings-section { padding: 24px; scroll-margin-top: 24px; }
.settings-section__desc { font-size: 13px; color: var(--ink-3); margin: 0 0 18px; }
.settings-section__action { margin-left: auto; }
.settings-section__footer { margin-top: 4px; }
.settings-section--danger { box-shadow: 0 0 0 1px var(--neg); }

/* Snippet block + API key row */
.snippet-block {
  background: var(--bg-sunken);
  padding: 14px;
  border-radius: var(--radius-sm);
  font-family: var(--font-mono, ui-monospace, monospace);
  font-size: 12px;
  color: var(--ink);
  overflow-x: auto;
  box-shadow: inset 0 0 0 1px var(--line);
  word-break: break-all;
  white-space: pre-wrap;
}
.api-key-row { gap: 8px; align-items: stretch; }
.api-key-row__input { flex: 1; font-family: var(--font-mono, ui-monospace, monospace); }

/* Plan-status block (billing hero) */
.plan-status {
  display: flex;
  align-items: center;
  gap: 18px;
  padding: 20px;
  background: var(--bg-sunken);
  border-radius: var(--radius-sm);
  box-shadow: inset 0 0 0 1px var(--line);
  margin-bottom: 16px;
}
.plan-status__logo { width: 56px; height: 56px; flex: none; }
.plan-status__title {
  font-family: var(--font-display);
  font-size: 20px;
  font-weight: 600;
  letter-spacing: -0.01em;
  color: var(--ink);
}
.plan-status__sub { font-size: 13px; color: var(--ink-3); margin-top: 4px; }

/* Plan picker (billing — tier selection) */
/* Active-subscription "Change plan" reveal: the grid starts collapsed and the
   toggle button flips [hidden]. Explicit rule so a broader author `display`
   can't defeat the UA `[hidden]` default. */
.plan-picker[hidden] { display: none; }
.plan-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
  gap: 12px;
  margin-top: 12px;
}
.plan-card {
  position: relative;
  display: block;
  padding: 16px;
  background: var(--bg-sunken);
  border-radius: var(--radius-sm);
  box-shadow: inset 0 0 0 1px var(--line);
  cursor: pointer;
  transition: box-shadow 0.15s ease;
}
.plan-card:hover { box-shadow: inset 0 0 0 1px var(--ink-3); }
/* Selected state needs to be unmistakable — 2px purple ring + clearly tinted
   background (~25% accent on the dark surface) + subtle outer glow so the
   card "lifts" out of the grid. */
.plan-card.is-selected {
  box-shadow:
    inset 0 0 0 2px var(--accent),
    0 0 0 1px color-mix(in srgb, var(--accent) 40%, transparent),
    0 8px 28px color-mix(in srgb, var(--accent) 20%, transparent);
  background: color-mix(in srgb, var(--accent) 18%, var(--bg-sunken));
}
.plan-card.is-selected:hover {
  box-shadow:
    inset 0 0 0 2px var(--accent),
    0 0 0 1px color-mix(in srgb, var(--accent) 40%, transparent),
    0 8px 28px color-mix(in srgb, var(--accent) 20%, transparent);
}
.plan-card--featured { box-shadow: inset 0 0 0 1px var(--accent); }
.plan-card input[type="radio"] {
  position: absolute;
  opacity: 0;
  pointer-events: none;
}
.plan-card__head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  margin-bottom: 8px;
}
.plan-card__name {
  font-family: var(--font-display);
  font-size: 16px;
  font-weight: 600;
  color: var(--ink);
}
.plan-card__price {
  font-family: var(--font-display);
  font-size: 24px;
  font-weight: 700;
  color: var(--ink);
  letter-spacing: -0.01em;
}
.plan-card__period {
  font-size: 13px;
  font-weight: 400;
  color: var(--ink-3);
}
.plan-card__sessions {
  font-size: 13px;
  color: var(--ink-2);
  margin-top: 4px;
}
.plan-card__tagline {
  font-size: 12px;
  color: var(--ink-3);
  margin-top: 8px;
  line-height: 1.4;
}

/* Per-card Subscribe / Switch / Active CTA — pinned to the bottom of the
   card so the action is consistent across cards regardless of tagline length. */
.plan-card {
  display: flex;
  flex-direction: column;
}
.plan-card__cta {
  align-self: stretch;
  margin-top: 14px;
  width: 100%;
  justify-content: center;
}

/* Active plan = green theme (matches the green Active badge + CTA so the
   "this is your current plan" cue reads at a glance). Distinct from the
   purple .is-selected highlight applied when the user clicks another card
   to consider switching. */
.plan-card--active {
  box-shadow: inset 0 0 0 2px var(--pos);
  background: color-mix(in srgb, var(--pos-bg) 70%, var(--bg-sunken));
}
.plan-card--active:hover {
  box-shadow: inset 0 0 0 2px var(--pos);
}
.plan-card--active.is-selected,
.plan-card--active.is-selected:hover {
  box-shadow: inset 0 0 0 2px var(--pos);
}

/* "Active" CTA pill — green-tinted, disabled, sits where Subscribe / Switch
   normally lives. Looks like a status badge so it doesn't read as clickable. */
.plan-card__cta--active,
.plan-card__cta--active:disabled {
  background: color-mix(in srgb, var(--pos) 18%, transparent);
  color: var(--pos);
  border-color: color-mix(in srgb, var(--pos) 35%, transparent);
  opacity: 1;
  cursor: default;
}
.plan-card__cta--active > svg { color: var(--pos); }

/* --------------------------------------------------------------------------
   Settings / Team — table layout (no row backgrounds, dividers between rows).
   Replaces the chip-list styling with a 4-column table:
     Member · Role · Last active · Manage
   -------------------------------------------------------------------------- */
/* The head + each row share the same grid template (defined as a CSS variable
   so changes flow to both). Fixed widths on Role + Manage keep the columns
   aligned regardless of badge label length or which Manage button (gear /
   Revoke / placeholder dash) is rendered. */
.team-table {
  --team-grid: minmax(0, 1fr) 120px minmax(140px, 1fr) 140px;
  display: flex;
  flex-direction: column;
  margin-top: 8px;
}
.team-table__head {
  display: grid;
  grid-template-columns: var(--team-grid);
  gap: 16px;
  padding: 8px 4px;
  border-bottom: 1px solid var(--line);
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--ink-3);
}
.team-row {
  display: grid;
  grid-template-columns: var(--team-grid);
  gap: 16px;
  align-items: center;
  padding: 14px 4px;
  border-bottom: 1px solid var(--line);
}
.team-row:last-child { border-bottom: none; }
/* Each cell clips overflowing content (long emails, long role labels) so a
   single oversized value can't push siblings out of place. */
.team-row > * { min-width: 0; }
.team-row__role { display: flex; align-items: center; }

.team-row__member {
  display: flex;
  align-items: center;
  gap: 12px;
  min-width: 0;
}
.team-row__email { min-width: 0; }
.team-row__email-text {
  font-weight: 500;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.team-row__last-active {
  font-size: 13px;
  color: var(--ink-3);
}

.team-row__manage { justify-self: end; }
.team-row__action { white-space: nowrap; }

.avatar--me {
  background: var(--accent-soft);
  color: var(--accent-deep);
}

@media (max-width: 720px) {
  .team-table__head { display: none; }
  .team-row {
    grid-template-columns: 1fr auto;
    gap: 8px 12px;
    padding: 12px 4px;
  }
  .team-row__last-active { grid-column: 1 / -1; padding-left: 44px; font-size: 12px; }
  .team-row__manage { grid-row: 1; }
}

/* --------------------------------------------------------------------------
   Segmented pill — 3-way role picker used in the Manage member modal.
   Active pill has the accent surface; siblings dim back to chip styling.
   -------------------------------------------------------------------------- */
.seg-pill {
  display: inline-flex;
  padding: 4px;
  background: var(--bg-sunken);
  border-radius: 999px;
  box-shadow: inset 0 0 0 1px var(--line);
}
.seg-pill__btn {
  height: 32px;
  padding: 0 16px;
  border-radius: 999px;
  background: transparent;
  border: none;
  color: var(--ink-3);
  font-size: 13px;
  font-weight: 500;
  cursor: pointer;
  white-space: nowrap;
  transition: background 140ms, color 140ms;
}
.seg-pill__btn:hover {
  background: rgba(255, 255, 255, 0.04);
  color: var(--ink-2);
}
.seg-pill__btn.is-selected {
  background: var(--accent-soft);
  color: var(--accent-deep);
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--accent-deep) 35%, transparent);
}
.seg-pill__btn.is-selected:hover {
  background: var(--accent-soft);
  color: var(--accent-deep);
}

/* Manage-member dialog gets a slightly wider footer because of the
   left-aligned destructive action sitting opposite Save/Cancel. */
#manage-member-dialog.modal-dialog { max-width: 520px; }

/* "Coming soon" placeholder section gets a subtler border so it visually
   recedes vs. fully-rendered sections. */
.settings-section--coming-soon {
  opacity: 0.85;
}

/* Integration row */
.integration-row {
  padding: 14px;
  background: var(--bg-sunken);
  border-radius: var(--radius-sm);
  display: flex;
  align-items: center;
  gap: 14px;
}
.integration-row__logo {
  width: 40px;
  height: 40px;
  border-radius: 8px;
  background: #fff;
  box-shadow: inset 0 0 0 1px var(--line);
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 6px;
  flex: none;
}
.integration-row__body { flex: 1; min-width: 0; }
.integration-row__name { font-weight: 550; display: inline-flex; align-items: center; gap: 6px; }
.integration-row__desc { font-size: 12px; color: var(--ink-3); margin-top: 2px; }

@media (max-width: 900px) {
  .settings-layout { grid-template-columns: 1fr; }
  .settings-nav { position: static; flex-direction: row; flex-wrap: wrap; gap: 6px; }
  .settings-nav__item { padding: 6px 10px; font-size: 12px; }
}

/* Auth shell — split-screen hero + form panel (prototype:2967-2972) */
.auth-shell {
  min-height: 100vh;
  display: grid;
  grid-template-columns: 1fr 520px;
}

.auth-hero {
  background: rgba(255, 255, 255, 0.02);
  padding: 48px;
  display: flex;
  flex-direction: column;
  border-right: 1px solid var(--line);
}

.auth-hero__logo {
  height: 40px;
  width: auto;
}

@media (min-width: 768px) {
  .auth-hero__logo {
    height: 80px;
  }
}

.auth-hero__quote {
  font-family: var(--font-display);
  font-size: 32px;
  line-height: 1.2;
  letter-spacing: -0.02em;
  margin-top: auto;
  max-width: 20ch;
  color: var(--ink);
}

.auth-hero__attrib {
  font-size: 12px;
  color: var(--ink-3);
  margin-top: 16px;
  font-family: var(--font-mono);
}

.auth-panel {
  display: flex;
  align-items: center;
  padding: 48px 72px;
}

.auth-inner { width: 100%; max-width: 360px; }

.auth-form__title {
  font-family: var(--font-display);
  font-size: 28px;
  font-weight: 600;
  letter-spacing: -0.02em;
  margin: 0 0 6px;
  color: var(--ink);
}

.auth-form__subtitle { margin: 0 0 28px; color: var(--ink-3); }

.auth-form__divider {
  display: flex;
  gap: 12px;
  margin: 22px 0;
  align-items: center;
}

.auth-form__divider-line {
  flex: 1;
  height: 1px;
  background: var(--line);
}

/* OTP code grid — 6 boxes */
.otp-inputs {
  display: flex;
  gap: 8px;
  justify-content: space-between;
}

.otp-inputs .otp-box {
  width: 48px;
  height: 52px;
  text-align: center;
  font-size: 22px;
  font-family: var(--font-mono);
  padding: 0;
  background: rgba(255, 255, 255, 0.04);
  border: 1px solid var(--line-strong);
  border-radius: var(--radius-sm);
  color: var(--ink);
  flex: none;
}

.otp-inputs .otp-box:focus {
  outline: none;
  border-color: var(--accent);
  box-shadow: 0 0 0 3px rgba(139, 122, 255, 0.2);
}

/* Standalone page shells (setup, 404) — use dark bg directly */
.page--standalone {
  min-height: 100vh;
  background: var(--bg);
  display: flex;
  flex-direction: column;
}

.standalone-topbar {
  height: 52px;
  border-bottom: 1px solid var(--line);
  display: flex;
  align-items: center;
  gap: 16px;
  padding: 0 40px;
}

@media (max-width: 900px) {
  .auth-shell { grid-template-columns: 1fr; }
  .auth-hero { display: none; }
  .auth-panel { padding: 24px; }
}

/* Prototype's .page conflicts with the existing .page on old screens.
   The existing rule (max-width 1200px, margin 0 auto, padding var(--space-6))
   remains valid and is compatible with the new shell — no override needed. */

/* Mobile topbar + sidebar backdrop — only rendered on mobile (display flipped
   on by the @media block below). The sidebar becomes a fixed off-canvas drawer
   that slides in when .app gains .is-nav-open. */
.mobile-topbar {
  display: none;
  align-items: center;
  gap: 12px;
  height: 52px;
  padding: 0 12px;
  border-bottom: 1px solid var(--line);
  background: rgba(10, 11, 26, 0.5);
  backdrop-filter: blur(24px);
  -webkit-backdrop-filter: blur(24px);
  position: sticky;
  top: 0;
  z-index: 20;
}

.mobile-nav-toggle {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 36px;
  height: 36px;
  border-radius: var(--radius-sm);
  background: transparent;
  border: none;
  color: var(--ink);
  cursor: pointer;
  flex: none;
}

.mobile-nav-toggle:hover {
  background: var(--bg-sunken);
}

.mobile-nav-toggle svg {
  width: 20px;
  height: 20px;
}

.mobile-brand {
  display: inline-flex;
  align-items: center;
  text-decoration: none;
}

.mobile-brand img {
  height: 28px;
  width: auto;
  display: block;
}

.sidebar-backdrop {
  display: none;
  position: fixed;
  inset: 0;
  background: rgba(0, 0, 0, 0.5);
  z-index: 30;
}

@media (max-width: 900px) {
  .app {
    grid-template-columns: 1fr;
  }
  .mobile-topbar {
    display: flex;
  }
  .sidebar {
    position: fixed;
    top: 0;
    left: 0;
    height: 100vh;
    width: 280px;
    max-width: 85vw;
    z-index: 40;
    transform: translateX(-100%);
    transition: transform 220ms ease;
    background: rgba(10, 11, 26, 0.96);
  }
  .app.is-nav-open .sidebar {
    transform: translateX(0);
  }
  .app.is-nav-open .sidebar-backdrop {
    display: block;
  }
  .topbar {
    padding: 0 16px;
  }
  .topbar-search {
    display: none;
  }
  #app-content {
    padding: 20px 16px 60px;
  }
  .page-title {
    font-size: 32px;
  }
}

/* --------------------------------------------------------------------------
   Goals picker (experiment config → Metrics card)
   -------------------------------------------------------------------------- */
.goals-tracked-list {
  list-style: none;
  padding: 0;
  margin: 0 0 var(--space-3) 0;
  border: var(--border);
  border-radius: var(--radius-lg);
  overflow: hidden;
  background: var(--color-surface);
}

.goals-empty {
  font-size: var(--font-size-sm);
  color: var(--color-text-secondary);
  padding: var(--space-5) var(--space-4);
  margin: 0;
  text-align: center;
}

.goals-tracked-row {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  padding: var(--space-3) var(--space-4);
  border-bottom: var(--border);
  transition: background 0.1s;
}

.goals-tracked-row:last-child {
  border-bottom: none;
}

.goals-tracked-row:hover {
  background: var(--color-surface-hover);
}

.goals-tracked-row[data-primary="true"] {
  background: var(--color-bg);
}

.goals-tracked-row__label {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  cursor: pointer;
  flex: 1;
  min-width: 0;
  font-size: var(--font-size-base);
}

.goals-tracked-row__label input[type="radio"],
.goals-tracked-row input[type="radio"] {
  appearance: none;
  -webkit-appearance: none;
  display: none;
  width: 0;
  height: 0;
  margin: 0;
  padding: 0;
  border: 0;
}

.goals-tracked-row__label input[type="radio"]:focus-visible + span {
  outline: 2px solid var(--color-link);
  outline-offset: 2px;
  border-radius: var(--radius-sm);
}

.goals-tracked-row__label span {
  font-weight: 500;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.goals-tracked-row__badge {
  font-size: var(--font-size-xs);
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--color-success, #008060);
  background: color-mix(in srgb, var(--color-success, #008060) 12%, transparent);
  padding: 2px 8px;
  border-radius: var(--radius-sm);
  white-space: nowrap;
  flex-shrink: 0;
}

.goals-tracked-row__remove {
  background: none;
  border: var(--border);
  border-radius: var(--radius-sm);
  cursor: pointer;
  color: var(--color-text-secondary);
  font-size: 1rem;
  line-height: 1;
  width: 28px;
  height: 28px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 0;
  flex-shrink: 0;
  transition: color 0.1s, border-color 0.1s, background 0.1s;
}

.goals-tracked-row__remove:hover {
  color: var(--color-critical, #d72c0d);
  border-color: var(--color-critical, #d72c0d);
  background: color-mix(in srgb, var(--color-critical, #d72c0d) 8%, transparent);
}

.goals-add-area {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-2);
  margin-bottom: var(--space-3);
}

.goals-add-dropdown {
  flex: 1;
  min-width: 220px;
}

.goals-add-select {
  max-width: 320px;
  width: 100%;
}

.goals-validation-msg {
  font-size: var(--font-size-sm);
  color: var(--color-critical, #d72c0d);
  background: color-mix(in srgb, var(--color-critical, #d72c0d) 8%, transparent);
  border-left: 3px solid var(--color-critical, #d72c0d);
  padding: var(--space-2) var(--space-3);
  border-radius: var(--radius-sm);
  margin-bottom: var(--space-3);
}

/* ============================================================================
   TASK-60 — component classes extracted from inline styles.
   Appended last on purpose: several of these are BEM mixes that must win
   same-specificity ties against the generic blocks above (.delta, .row, …).
   ============================================================================ */

/* Text block extensions — sizes & tones used across views */
.text--xs { font-size: 12px; }
.text--sm { font-size: var(--font-size-sm); }
.text--xxs { font-size: 11px; }
.text--ink { color: var(--ink); }
.text--ink-2 { color: var(--ink-2); }

/* Scrollable table wrapper + generic data table (plain metrics tables inside
   cards/accordions: revenue, subscriptions, custom & calculated metrics,
   per-goal stats, click analysis) */
.table-scroll { overflow-x: auto; }
.data-table {
  width: 100%;
  border-collapse: collapse;
}
.data-table thead tr { border-bottom: var(--border); text-align: left; }
.data-table tbody tr { border-bottom: var(--border); }
.data-table th,
.data-table td { padding: var(--space-2); }
.data-table--wide { min-width: 700px; }
.data-table--compact { font-size: var(--font-size-sm); }
.data-table--compact th,
.data-table--compact td { padding: var(--space-1) var(--space-2); }
.data-table__col-wide { min-width: 320px; }
.data-table__swatch { margin-right: var(--space-2); }
.data-table .badge--xs { font-size: 0.7rem; }

/* Badge size modifier */
.badge--xs { font-size: 0.7rem; }

/* Delta rendered as a fine table annotation */
.delta--fine { font-size: 11px; font-weight: 500; margin-left: 4px; }

/* detail-section extras */
.detail-section__desc { margin: 0 0 var(--space-3); font-size: 13px; }
.detail-section__title-badge { vertical-align: middle; }

/* Accordion header extras (goal/stats accordions) */
.accordion__title-tag {
  font-size: 0.7rem;
  color: var(--color-primary);
  font-weight: 600;
  margin-left: var(--space-1);
}
.accordion__overview-aside { margin-left: auto; }
.accordion__overview-delta { font-weight: 600; }
.accordion__overview-note { margin-left: var(--space-3); }
.accordion__overview-badge { font-size: 0.65rem; margin-left: var(--space-2); }

/* Conversion funnel accordion (results tab) */
.conversion-funnel__overview { gap: 6px; }
.conversion-funnel__primary { margin-left: 8px; }
.conversion-funnel__body { padding: 0; }
.stat-v2__table {
  width: 100%;
  border-collapse: collapse;
  font-size: 13px;
  min-width: 600px;
}
.stat-v2__table th {
  text-align: left;
  padding: 10px 14px;
  color: var(--ink-3);
  font-weight: 500;
}
.stat-v2__table td { padding: 14px; }
.stat-v2__table tbody tr { border-top: 1px solid var(--line); }
.stat-v2__cvr { font-weight: 600; }
.stat-v2__delta { font-weight: 500; margin-left: 4px; }
.stat-v2__cell-note { font-size: 11px; margin-left: 4px; }

/* New vs Returning breakdown card */
.visitor-breakdown__head {
  justify-content: space-between;
  align-items: baseline;
  flex-wrap: wrap;
  gap: 8px;
}
.visitor-breakdown__title { margin: 0; }
.visitor-breakdown__note { font-size: 13px; margin: 12px 0 0; }
.visitor-breakdown__grid {
  display: grid;
  gap: 1.5rem;
  grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
  margin-top: 12px;
}
.visitor-breakdown__segment { padding: 16px; }
.visitor-breakdown__seg-label { font-weight: 550; }
.visitor-breakdown__seg-empty { margin-top: 8px; }
.visitor-breakdown__seg-head { justify-content: space-between; margin-bottom: 12px; }
.visitor-breakdown__lift { font-size: 13px; font-weight: 600; }
.visitor-breakdown__bars { gap: 10px; }
.visitor-breakdown__bar { margin-top: 4px; }
.visitor-breakdown__bar-label {
  justify-content: space-between;
  font-size: 12px;
  color: var(--ink-3);
}
.visitor-breakdown__total { margin-top: 12px; }

/* Advanced DOM insights (Shopify) */
.dom-insights__item { margin-bottom: var(--space-3); }
.dom-insights__item-head {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  margin-bottom: var(--space-1);
}
.dom-insights__stat { margin: 0 0 var(--space-1); font-size: var(--font-size-sm); }
.dom-insights__note { margin: 0; font-size: var(--font-size-sm); }
.dom-insights__substat {
  margin: 0;
  font-size: var(--font-size-sm);
  color: var(--color-text-secondary);
}
.dom-insights__warn {
  margin: var(--space-1) 0 0;
  font-size: var(--font-size-sm);
  color: var(--color-warning, #b98900);
}
.dom-insights__toggle-row {
  margin-top: var(--space-3);
  padding-top: var(--space-3);
  border-top: var(--border);
}
.dom-insights__toggle {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  cursor: pointer;
  font-size: var(--font-size-sm);
}
.dom-insights__click-group { margin-bottom: var(--space-4); }
.dom-insights__variant-title { margin-bottom: var(--space-2); font-size: var(--font-size-sm); }
.dom-insights__el { font-family: monospace; }
.dom-insights__row--hot { background: rgba(255, 193, 7, 0.08); }

/* Conversion-rate-over-time accordion */
.conversion-over-time__select {
  width: auto;
  min-width: 200px;
  font-size: 13px;
  padding: 6px 28px 6px 10px;
}
.conversion-over-time__controls { margin-bottom: var(--space-4); }
.conversion-over-time__desc { margin: 0; font-size: 13px; }
.conversion-over-time__chart { width: 100%; min-height: 300px; }
.conversion-over-time__loading {
  display: flex;
  align-items: center;
  justify-content: center;
  height: 300px;
  color: var(--ink-3);
}

/* from frontend/src/views/404.js */
.standalone-topbar__brand {
  gap: 10px;
  text-decoration: none;
}
.standalone-topbar__logo {
  height: 36px;
  width: auto;
}
.not-found {
  flex: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 40px;
}
.not-found__panel {
  max-width: 520px;
  text-align: center;
}
.not-found__title {
  font-size: 64px;
  font-weight: 600;
  letter-spacing: -0.04em;
  margin: 18px 0 14px;
}
.not-found__lede {
  font-size: 15px;
  margin: 0 0 28px;
}
.not-found__actions {
  justify-content: center;
  gap: 10px;
}
.not-found__stats {
  margin-top: 56px;
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 1px;
  background: var(--line);
  border-radius: var(--radius);
  overflow: hidden;
  box-shadow: 0 0 0 1px var(--line);
}
.not-found__stat {
  background: var(--bg-elev);
  padding: 18px;
}
.not-found__stat-value {
  font-size: 24px;
  font-weight: 600;
  margin-top: 6px;
}
.not-found__stat-value--neg { color: var(--neg); }
.not-found__stat-value--pos { color: var(--pos); }

/* from frontend/src/lib/app.js */
/* :hover co-selectors mirror .dropdown__item--danger: the replaced inline
   styles also won over .dropdown__item:hover's color (specificity 0,2,0). */
.dropdown__item--loading,
.dropdown__item--loading:hover {
  color: var(--ink-3);
  font-size: 11px;
  padding: 6px 12px;
}
.dropdown__item--error,
.dropdown__item--error:hover {
  color: var(--neg);
}
.dropdown__icon-spacer {
  width: 14px;
}
.create-workspace__title {
  margin: 0;
}
.create-workspace__form {
  display: flex;
  flex-direction: column;
  gap: 14px;
}
.create-workspace__note {
  margin: 0;
}
.create-workspace__error {
  display: none;
}

/* from frontend/src/lib/icons.js */
/* svg-qualified so it out-ranks `button > svg` (14px) and ties with
   `.meta-pill > svg` (12px) at 0,1,1 — appended last, so it wins the tie,
   matching what the replaced inline width/height did in those contexts. */
svg.icon-arrow {
  width: 0.9em;
  height: 0.9em;
}

/* from frontend/src/lib/violin.js */
.violin__empty {
  font-size: 0.75rem;
}
.cell-with-chart__range {
  margin-bottom: 4px;
}
.cell-with-chart__bound {
  font-weight: 600;
}
.cell-with-chart__warning {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  color: var(--warn);
  font-weight: 600;
  margin-bottom: 4px;
}

/* from frontend/src/views/experiment-detail.js */
.page-head--detail {
  margin-bottom: 20px;
}
.page-head__crumbs {
  margin-bottom: 6px;
}
.page-head__meta--centered {
  align-items: center;
  gap: 16px;
}
.page-sub-wrap--fill {
  flex: 1;
  min-width: 0;
  max-width: 60ch;
}
.page-head__spacer {
  flex: 1;
}
.page-head__actions {
  flex: none;
}
.copy-dialog__intro {
  margin-top: 0;
}
.copy-dialog__form-group {
  margin-top: var(--space-4);
  margin-bottom: 0;
}

/* from frontend/src/views/experiment-detail-results.js */

/* Results toolbar (device pill-seg + segment toggle + date range + refresh).
   Mixed with .row, which already carries display:flex + align-items:center;
   gap here overrides .row's 10px (this file is appended after it). */
.results-toolbar {
  margin-bottom: 20px;
  gap: 16px;
  flex-wrap: wrap;
}
.results-toolbar__aside { margin-left: auto; }

/* "Showing N of M days · Started …" context line under the toolbar.
   Mixed with inline (flex/center/gap12) + text--muted + text--xs. */
.results-range-context {
  margin-bottom: 16px;
  flex-wrap: wrap;
}

/* Date-range picker widget: trigger button + anchored popover. The wrap and
   option classes already existed in the markup as hooks; styled here. */
.date-range-wrap { position: relative; }
.date-range__caret {
  opacity: 0.6;
  margin-left: 4px;
}
.date-range__popover {
  position: absolute;
  top: calc(100% + 6px);
  left: 0;
  z-index: 50;
  min-width: 260px;
  padding: 8px;
  background: var(--bg);
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  box-shadow: 0 6px 24px rgba(0,0,0,0.18);
}
.date-range__presets { gap: 2px; } /* overrides .stack's gap */
.date-range-option {
  justify-content: flex-start;
  width: 100%;
  background: transparent;
  box-shadow: none;
}
/* Parity: as inline styles these declarations also suppressed the generic
   button:hover / .btn:hover background + shadow treatment; keep doing so. */
.date-range-option:hover {
  background: transparent;
  box-shadow: none;
}
.date-range__option-dot {
  display: inline-block;
  width: 14px;
}
.date-range__divider {
  border-top: 1px solid var(--line);
  margin: 6px 0;
}
.date-range__custom { padding: 4px 8px; }
.date-range__custom-label { margin-bottom: 4px; } /* + text--muted text--xxs */
.date-range__custom-inputs { gap: 6px; } /* mixed with .row */
.date-range__custom-input {
  flex: 1;
  min-width: 0;
}
.date-range__custom-actions {
  margin-top: 8px;
  justify-content: flex-end;
}

/* Device breakdown cards (per-device summary grid on the results tab).
   .device-breakdown__card itself already lives in global.css. */
.device-breakdown__grid {
  display: grid;
  gap: 1.5rem;
  grid-template-columns: repeat(3, minmax(0, 1fr));
}
.device-breakdown__card-head {
  justify-content: space-between;
  margin-bottom: 12px;
}
.device-breakdown__icon {
  display: inline-flex;
  width: 18px;
  height: 18px;
}
.device-breakdown__label { font-weight: 550; }
.device-breakdown__lift {
  /* overrides .delta's 14px on the lift badge */
  font-size: 13px;
  font-weight: 600;
}
.device-breakdown__note { margin-top: 8px; } /* + text--muted text--xs */
.device-breakdown__bars { gap: 10px; } /* overrides .stack's gap */
.device-breakdown__bar-row { justify-content: space-between; }
.device-breakdown__bar { margin-top: 4px; }
.device-breakdown__sessions { margin-top: 12px; }

/* from frontend/src/views/experiment-detail-shopifyql.js */

/* "(store-wide, test period)" aside inside a detail-section__title h3 —
   font-size comes from the text--sm mix, this undoes the heading weight. */
.detail-section__title-aside { font-weight: normal; }

/* Order Insights card: row of big-number stats (Discount Usage / Return Rate) */
.order-insights__stats {
  display: flex;
  gap: var(--space-6);
  flex-wrap: wrap;
}
.order-insights__stat-label { margin-bottom: 2px; } /* font-size via text--sm mix */
.order-insights__stat-value {
  font-size: 1.4rem;
  font-weight: 600;
}

/* from frontend/src/views/experiment-detail-stats.js */

/* Conversion-over-time chart widget (renders into #results-chart) */

/* "No data available yet" placeholder — color via text--muted mix */
.conversion-chart__empty {
  display: flex;
  align-items: center;
  justify-content: center;
  height: 300px;
}
.conversion-chart__svg {
  width: 100%;
  height: auto;
  display: block;
  overflow: visible;
}
/* Legend row under the chart — font-size via text--xs mix, color via
   text--ink-2 mix; padding-left stays inline (JS-computed ${padL}px). */
.conversion-chart__legend {
  display: flex;
  gap: 18px;
  align-items: center;
  margin-top: 12px;
  flex-wrap: wrap;
}
.conversion-chart__legend-item {
  display: inline-flex;
  align-items: center;
  gap: 6px;
}
.conversion-chart__legend-line {
  width: 14px;
  height: 2px;
  border-radius: 1px;
}

/* from frontend/src/views/experiment-targeting.js */

/* Section shells shared by the URL targeting / Audience / Activation panels */
.targeting__panel { padding: 20px; margin-bottom: 16px; }
.targeting__section-head { justify-content: space-between; margin-bottom: 12px; }
.targeting__group-head { justify-content: space-between; margin-bottom: 10px; }
.targeting__section-desc { margin-bottom: 16px; }

/* Preview-URL match banner */
.targeting__preview-banner {
  padding: 10px 14px;
  margin-bottom: 12px;
  border-radius: var(--radius-sm);
  font-size: 13px;
  display: flex;
  align-items: center;
  gap: 12px;
}
.targeting__preview-banner--muted { background: var(--bg-sunken); color: var(--ink-3); }
.targeting__preview-banner--warn { background: color-mix(in srgb, var(--warn) 12%, transparent); color: var(--warn); }
.targeting__preview-banner--pos { background: var(--pos-bg); color: var(--pos); }
.targeting__preview-url { color: inherit; }

/* Inline add/edit rule form (initial display:none stays inline — JS-toggled) */
.targeting__form {
  padding: 16px;
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  background: var(--bg-sunken);
  margin: 12px 0;
}
.targeting__form-title { font-size: 14px; }
.targeting__label-note { font-weight: 400; }
.targeting__form-actions { margin-top: 12px; }
.targeting__empty { padding: 12px 0; }
.targeting__rules-note { margin-top: 12px; }

/* Rule chip rows */
.targeting__rule { background: var(--bg-sunken); border-radius: var(--radius-sm); padding: 12px; }
.targeting__rule-line { flex-wrap: wrap; }
.targeting__rule-urls {
  flex: 1;
  min-width: 0;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  flex-wrap: wrap;
}
.targeting__rule-url { white-space: nowrap; }
.targeting__rule-or { font-style: italic; }
.targeting__rule-actions { gap: 4px; flex-shrink: 0; }

/* Inline delete confirm (initial display:none stays inline — JS-toggled) */
.targeting-delete-confirm {
  margin-top: 12px;
  padding: 12px;
  background: color-mix(in srgb, var(--neg) 10%, transparent);
  border-radius: var(--radius-sm);
  border: 1px solid color-mix(in srgb, var(--neg) 30%, transparent);
}
.targeting-delete-confirm__row { justify-content: space-between; gap: 8px; flex-wrap: wrap; }
.targeting-delete-confirm__msg { margin: 0; }
.targeting-delete-confirm__btns { gap: 6px; }

/* Inline icon shells (device icons, preview-match check) */
.targeting__icon { display: inline-flex; width: 14px; height: 14px; }
.targeting__icon--sm { width: 12px; height: 12px; }
.targeting__icon--pos { color: var(--pos); }

/* Audience (device targeting) */
.targeting__audience-grid { gap: 24px; }
.targeting__device-checks { display: flex; flex-wrap: wrap; gap: 8px; }
.device-chip {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  cursor: pointer;
  padding: 6px 12px;
  background: var(--bg-sunken);
  border-radius: 999px;
  box-shadow: inset 0 0 0 1px var(--line);
  font-size: 12px;
}
.targeting__device-checkbox { width: auto; accent-color: var(--accent); }
.targeting__devices-hint { margin-top: 8px; display: block; }
.targeting__device-save { margin-top: 10px; }
.targeting__chip-row { gap: 6px; flex-wrap: wrap; }
.targeting__device-badge { gap: 6px; }

/* Activation */
.targeting__activation-row { gap: 24px; align-items: flex-start; flex-wrap: wrap; }
.targeting__activation-col { flex: 1; min-width: 200px; }
.targeting__activation-col--soon { opacity: 0.5; pointer-events: none; }
.targeting__field-label { margin-bottom: 6px; }
.targeting__activation-select { margin-bottom: 8px; }
.targeting__activation-save { margin-top: 8px; }

/* from frontend/src/views/login.js — auth-* rules here are SHARED with
   frontend/src/views/register.js (register.css holds only register-only rules). */

/* Bottom-anchored quote area of the auth hero column. */
.auth-hero__footer {
  flex: 1;
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  padding-bottom: 40px;
}

/* Field wrapper — class already existed in markup as a bare hook; every
   instance (login x2, register x1) carried the same inline margin. */
.auth-form__field { margin-bottom: 14px; }

/* Step containers (otp form, workspace picker) start hidden; JS shows them
   via el.style.display = 'block', which overrides this class. */
.auth-form__step--hidden { display: none; }

/* Primary submit buttons. justify-content restated from the removed inline
   style (base button rule already centers — kept verbatim for parity). */
.auth-form__submit {
  width: 100%;
  justify-content: center;
}

.auth-form__submit--tall { height: 40px; }

/* Single 6-char OTP entry (not the .otp-box per-digit grid). */
.auth-form__otp-input {
  text-align: center;
  letter-spacing: 8px;
  font-family: var(--font-mono);
  font-size: 18px;
  height: 48px;
}

/* "Didn't get the code?" hint under the verify button. */
.auth-form__resend-note {
  font-size: 12px;
  margin-top: 12px;
  text-align: center;
}

/* Error/success feedback lines. Hidden until JS sets el.style.display. */
.auth-form__msg {
  display: none;
  margin-top: 14px;
  font-size: 13px;
  text-align: center;
}

.auth-form__msg--error { color: var(--neg); }

.auth-form__msg--success { color: var(--pos); }

/* "Don't have an account?" / "Already have an account?" line. Margin lives on
   the modifiers so the two views' different spacings never override each other. */
.auth-form__switch {
  font-size: 13px;
  text-align: center;
}

.auth-form__switch--roomy { margin-top: 28px; }

/* Inline links (sign up / sign in / terms / privacy). */
.auth-form__link { color: var(--accent-deep); }

.auth-form__link--strong { font-weight: 500; }

/* Workspace picker option — class already existed as the JS click hook. */
.workspace-option {
  justify-content: space-between;
  height: auto;
  padding: 12px 14px;
  width: 100%;
  text-align: left;
}

.workspace-option__info {
  display: flex;
  flex-direction: column;
  gap: 2px;
  align-items: flex-start;
}

.workspace-option__name { font-weight: 500; }

.workspace-option__role {
  font-size: 11px;
  text-transform: uppercase;
}

/* from frontend/src/views/register.js — register-only rules. Shared auth-*
   rules (auth-hero__footer, auth-form__field, auth-form__submit[--tall],
   auth-form__msg[--error/--success], auth-form__switch, auth-form__link[--strong])
   live in login.css. */

/* Register's hero logo renders 40px at every width today. The bare
   .auth-hero__logo base jumps to 80px at >=768px via a global.css media rule;
   this modifier (appended after it, same specificity) pins the 40px height. */
.auth-hero__logo--fixed { height: 40px; }

/* Invite flow: readonly email input (was a conditionally-emitted static
   style="opacity: 0.7;"). */
.auth-form__input--dimmed { opacity: 0.7; }

/* Terms/privacy consent line under the submit button. */
.auth-form__terms-note {
  font-size: 12px;
  text-align: center;
  margin-top: 14px;
}

/* Register's switch-line spacing (login uses --roomy, 28px). */
.auth-form__switch--tight { margin-top: 16px; }

/* from frontend/src/views/setup.js */

/* Topbar home link — mixes with .row; gap restated verbatim from the removed
   inline style (same 10px value .row provides). */
.setup__home-link {
  gap: 10px;
  text-decoration: none;
}

/* Topbar logo (36px — intentionally not the 40/80px .auth-hero__logo). */
.setup__logo {
  height: 36px;
  width: auto;
}

.setup__topbar-spacer { flex: 1; }

.setup__cancel { min-width: 0; }

/* Centered content column under the standalone topbar. */
.setup__container {
  flex: 1;
  max-width: 640px;
  margin: 0 auto;
  padding: 48px 24px;
  width: 100%;
}

/* "Step 1 of 3" label — mixes with .text--tiny. */
.setup__step-label { margin-bottom: 10px; }

/* Page title — mixes with .text--display (letter-spacing restated verbatim
   from the removed inline style; same -0.02em value). */
.setup__title {
  font-size: 36px;
  font-weight: 600;
  letter-spacing: -0.02em;
  margin: 0 0 10px;
}

/* Intro paragraph — mixes with .text--muted. */
.setup__lede {
  margin: 0 0 32px;
  font-size: 15px;
}

/* Form panel padding (.panel declares none of its own). */
.setup__panel { padding: 24px; }

.setup__submit {
  height: 40px;
  justify-content: center;
  margin-top: 8px;
}

/* Hidden until JS sets el.style.display = 'block'. */
.setup__error {
  display: none;
  color: var(--neg);
  margin-top: 12px;
  font-size: 13px;
}

/* from frontend/src/views/settings-funnels.js */

/* Section chrome (header/action row, platform-default note, save footer) */
.funnels__head { justify-content: space-between; margin-bottom: 4px; }
.funnels__default-note { margin-bottom: 12px; }
.funnels__footer { justify-content: flex-start; align-items: center; gap: 12px; }
.funnels__save-msg { display: none; }
.funnels__save-msg--success { color: var(--pos); }
.funnels__list { display: flex; flex-direction: column; gap: 10px; }

/* Empty message when no funnels are defined */
.funnels-empty {
  font-size: 13px;
  padding: 20px;
  text-align: center;
  background: var(--bg-sunken);
  border-radius: var(--radius-sm);
}

/* Per-funnel editor card */
.funnel-row {
  display: flex;
  flex-direction: column;
  gap: 10px;
  padding: 12px;
  background: var(--bg-sunken);
  border-radius: var(--radius-sm);
}
.funnel-row__head { gap: 12px; align-items: flex-end; }
.funnel-row__name-field { flex: 1; min-width: 0; }
.funnel-default-label {
  flex: none;
  gap: 6px;
  font-size: 13px;
  padding-bottom: 8px;
  cursor: pointer;
}
.funnel-remove-btn { flex: none; }

/* Ordered step list inside a funnel card */
.funnel-steps { display: flex; flex-direction: column; gap: 6px; }
.funnel-steps-empty { margin: 0; }
.funnel-step {
  padding: 6px 10px;
  background: var(--panel, var(--bg));
  border: 1px solid var(--line);
  border-radius: 6px;
}
.funnel-step__num { width: 18px; text-align: right; }
.funnel-step-label { flex: 1; min-width: 0; }
.funnel-step__key { margin-left: 6px; }
.funnel-step__ctrl { padding: 2px 8px; }
.funnel-step-add { max-width: 320px; }

/* from frontend/src/views/settings-calculated-metrics.js */

/* Section chrome (header/action row, save footer) */
.calc-metrics__head { justify-content: space-between; margin-bottom: 4px; }
.calc-metrics__footer { justify-content: flex-start; align-items: center; gap: 12px; }
.calc-metrics__save-msg { display: none; }
.calc-metrics__save-msg--success { color: var(--pos); }
.calc-metrics__list { display: flex; flex-direction: column; gap: 10px; }

/* Empty message when no calculated metrics are defined */
.calc-metrics__empty {
  font-size: 13px;
  padding: 20px;
  text-align: center;
  background: var(--bg-sunken);
  border-radius: var(--radius-sm);
}

/* Per-metric editor card */
.calc-metric-row {
  display: flex;
  flex-direction: column;
  gap: 10px;
  padding: 12px;
  background: var(--bg-sunken);
  border-radius: var(--radius-sm);
}
.calc-metric-row__field-row { gap: 12px; align-items: flex-end; }
.calc-metric-row__field-row--wrap { flex-wrap: wrap; }
.calc-metric-row__name-field { flex: 1; min-width: 0; }
.calc-metric-remove-btn { flex: none; }
.calc-metric-row__source-field { flex: 2; min-width: 180px; }
.calc-metric-row__divide { flex: none; padding-bottom: 8px; font-size: 15px; }
.calc-metric-row__format-field { flex: 1; min-width: 110px; }

/* from frontend/src/views/experiment-config.js */

/* Shared chrome for the three config cards (General / Metrics / Funnels) —
   mixed onto the global `card` block. */
.config-card { margin-bottom: var(--space-4); }
.config-card__body { padding: var(--space-3); }
.config-card__title { margin-bottom: var(--space-1); }
.config-card__title--spaced { margin-bottom: var(--space-2); }
/* card intro copy — color via text--muted mix */
.config-card__desc {
  font-size: 0.85rem;
  margin-bottom: var(--space-3);
}
/* read-only "Calculated metrics: N tracked" note — color via text--muted mix */
.config-card__note {
  font-size: 0.85rem;
  margin-top: var(--space-2);
}

/* General settings card (experiment name / meta / preview URL / copy form) */
.exp-general__name-group { margin-bottom: var(--space-2); }
.exp-general__name { font-size: 1rem; }
/* Type/Created meta row — flex + 8px gap via inline inline--tight mix
   (gap repeated here verbatim from the removed inline style) */
.exp-general__meta {
  flex-wrap: wrap;
  gap: var(--space-2);
}
.exp-general__meta-label { font-size: 0.8rem; }
.exp-general__preview-field { margin-top: var(--space-3); }
.exp-general__preview-input { font-size: 0.95rem; }
.exp-general__field-note {
  margin-top: var(--space-1);
  display: block;
}
/* hidden by default; JS toggles with explicit style.display = "block"/"none" */
.exp-general__field-error {
  margin-top: var(--space-1);
  display: none;
}
.exp-general__actions { margin-top: var(--space-3); }
/* initial display:none stays inline on #copy-exp-form — JS reveals it by
   clearing the inline style (style.display = ""), so a class would stick */
.exp-general__copy-form {
  margin-top: var(--space-3);
  padding: var(--space-3);
  background: var(--color-info-bg);
  border-radius: var(--radius-md);
}
.exp-general__copy-actions { margin-top: var(--space-2); }

/* Kind chip on tracked metric rows ("Page view" / "Calculated") */
.goals-tracked-row__chip {
  margin-left: 6px;
  padding: 2px 6px;
  background: var(--bg-sunken);
  border-radius: 4px;
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 0.04em;
}

/* Funnels card */
/* loading / error / no-funnels messages — color via text--muted mix */
.funnels-card__msg { font-size: 0.85rem; }
.funnels-card__msg--flush { margin: 0; }
.funnels-card__save { margin-top: var(--space-3); }
/* "workspace default funnel" hint under the list — color via text--muted mix */
.funnels-card__hint {
  font-size: 0.8rem;
  margin: var(--space-2) 0 0;
}

/* Funnel picker rows */
.funnel-select-row--readonly {
  padding: 4px 0;
  font-size: 0.9rem;
}
/* flex + 8px gap via row row--tight mix */
.funnel-select-row--editable {
  padding: 6px 0;
  cursor: pointer;
  font-size: 0.9rem;
}
.funnel-select-row__badge { margin-left: 6px; }
.funnel-select-row__meta { font-size: 0.8rem; }
.funnel-select-row__meta--offset { margin-left: 8px; }

/* from experiment-detail-anomalies.js */

/* Anomaly alert cards (mixed onto .card; per-severity border-left and
   background stay dynamic inline). */
.anomaly { margin-bottom: var(--space-3); position: relative; }
.anomaly__row { display: flex; align-items: flex-start; gap: var(--space-2); }
.anomaly__icon { font-size: 1.1rem; flex-shrink: 0; }
.anomaly__content { flex: 1; }
.anomaly__message { margin: 0 0 var(--space-1) 0; font-weight: 600; }
.anomaly__recommendation { margin: 0; }
.anomaly__meta { margin: var(--space-1) 0 0; font-size: var(--font-size-xs); color: var(--color-text-tertiary); text-transform: uppercase; letter-spacing: .04em; }
.anomaly__dismiss { flex-shrink: 0; margin-left: var(--space-2); }

/* from experiment-detail-launch-qa.js */

/* Warning-toned inline text (stale-results notes in the End-experiment
   confirm summary). Companion modifier to the existing .text--critical. */
.text--warn { color: var(--warn); }

/* Pre-launch checklist rendered into the status-confirm bar. */
.launch-qa__title { display: block; margin-bottom: var(--space-2); }
.launch-qa__check { display: flex; gap: var(--space-2); align-items: flex-start; margin-bottom: var(--space-2); }
.launch-qa__check-icon { font-weight: 700; flex-shrink: 0; min-width: 1.2rem; }
.launch-qa__variants-cta { display: block; margin-top: var(--space-1); color: var(--color-link); font-weight: 600; text-decoration: underline; }
.launch-qa__ai-review { margin-top: var(--space-3); padding: var(--space-2) var(--space-3); background: var(--color-surface); border-radius: var(--radius); }
.launch-qa__billing-cta { margin-top: var(--space-3); }
.launch-qa__settings-link { color: inherit; font-weight: 600; text-decoration: underline; display: inline-block; margin-top: var(--space-1); }

/* Settings dropdown in the page-head actions. */
.dropdown__menu--wide { min-width: 220px; }

/* from experiment-detail-ai-analysis.js */

/* Card shell (header row + collapsible body). --flush zeroes the panel's own
   padding; header/body carry it instead. */
.ai-analysis--flush { padding: 0; }
.ai-analysis__header { display: flex; align-items: center; gap: 16px; padding: 20px; }
.ai-analysis__header-text { flex: 1; min-width: 0; }
.ai-analysis__title { margin: 0; font-family: var(--font-display); font-size: 16px; font-weight: 600; color: var(--ink); }
.ai-analysis__sub { margin: 2px 0 0; }
.ai-analysis__header-actions { flex: none; display: inline-flex; align-items: center; gap: 8px; }
/* Hidden until showAIBody() sets inline display:block (JS-owned state, wins
   over this class); the collapsed panel is additionally force-hidden by the
   existing .ai-analysis--collapsible:not(.is-open) rule in global.css. */
.ai-analysis__body { display: none; padding: 0 20px 20px; border-top: 1px solid var(--line); }

/* Rendered-analysis body. */
.ai-analysis__content { line-height: 1.6; color: var(--ink-2); padding-top: 14px; }
.ai-analysis__staleness { margin: 12px 0 0; }
.ai-analysis__footer { margin-top: 16px; display: flex; justify-content: flex-end; }
.ai-analysis__loading { padding-top: 14px; }
.ai-analysis__error { padding: 12px 14px; margin-top: 14px; background: color-mix(in srgb, var(--neg) 10%, transparent); border-radius: var(--radius-sm); border: 1px solid color-mix(in srgb, var(--neg) 30%, transparent); }

/* Markdown elements emitted by renderMarkdown(). The h2/h3/p selectors are
   ancestor-qualified on purpose: the same elements can be moved inside
   .ai-analysis__recommendation, whose global.css rules
   (`> h2/h3 { margin-top: 0 }`, `> p:last-child { margin-bottom: 0 }`) were
   beaten by the old inline styles. (0,2,1) specificity + this file being
   appended after global.css preserves that exact outcome. */
.ai-analysis__content h2.ai-analysis__md-h2 { margin: var(--space-4) 0 var(--space-2); font-size: 1.1rem; }
.ai-analysis__content h3.ai-analysis__md-h3 { margin: var(--space-4) 0 var(--space-2); }
.ai-analysis__content p.ai-analysis__md-p { margin: var(--space-1) 0; }
.ai-analysis__md-list { margin: var(--space-2) 0 var(--space-2) var(--space-4); padding: 0; }
.ai-analysis__md-item { margin-bottom: var(--space-1); }
.ai-analysis__md-code { background: var(--color-surface-2,#f3f4f6); padding: 1px 4px; border-radius: 3px; }

/* from frontend/src/views/settings.js */

/* Page footer */
.settings-footer { margin-top: 32px; text-align: center; color: var(--ink-3); font-size: 12px; }
.settings-footer__link { color: var(--accent-deep); }

/* Section chrome shared across the settings panels */
.settings-section--center { text-align: center; }
.settings-section__head { justify-content: space-between; margin-bottom: 4px; }
.settings-section__head--spaced { margin-bottom: 8px; }
.settings-section__head--roomy { margin-bottom: 16px; }
.settings-section__title { margin-bottom: 8px; }
.settings-section__title--tight { margin-bottom: 4px; }
.settings-section__desc--offset { margin-top: 18px; }
.settings-section__actions { gap: 8px; margin-top: 12px; }
/* footer row is a `row` mix; the gap widens over row's 10px default */
.settings-section__footer { justify-content: flex-start; gap: 12px; }

/* Save-status spans: hidden until JS sets style.display = "inline"/"none"
   explicitly (never clear-to-""), so the class can host the initial none. */
.settings-msg { display: none; font-size: 13px; }
.settings-msg--ok { color: var(--pos); }
.settings-msg--error { color: var(--neg); }

/* "Activating your subscription…" interstitial */
.billing-activation__title { margin-bottom: 12px; }
.billing-activation__sub { margin-bottom: 16px; }
.billing-activation__spinner { margin: 0 auto; }
.billing-activation__action { margin-top: 12px; }

/* Current-plan summary (billing) */
.plan-summary__info { flex: 1; }
.plan-summary__actions { justify-content: flex-start; gap: 8px; flex-wrap: wrap; margin-top: 16px; }
.plan-summary__note { margin: 12px 0 0; }

/* Monthly session usage meter */
.usage-bar { margin-bottom: 18px; }
.usage-bar__head { justify-content: space-between; margin-bottom: 6px; }
.usage-bar__row { justify-content: space-between; }
.usage-bar__track { height: 6px; background: var(--bg-sunken); border-radius: 3px; overflow: hidden; }
.usage-bar__over-note { margin: 8px 0 0; }
.usage-bar__near-note { margin: 8px 0 0; }

/* AI add-on block (billing) */
.ai-addon { margin-top: 18px; padding: 16px; border: 1px solid var(--border); border-radius: 10px; }
.ai-addon__row { justify-content: space-between; gap: 12px; flex-wrap: wrap; }
.ai-addon__name { font-weight: 600; }
.ai-addon__price { font-weight: 500; }
.ai-addon__note { margin: 4px 0 0; flex: 1; min-width: 220px; }
.ai-addon__actions { flex-shrink: 0; }

/* GA4 integration card */
.ga4-card__logo-svg { width: 100%; height: 100%; }
.ga4-card__oauth { margin-top: 14px; }
.ga4-card__desc { margin: 0 0 10px; }
.ga4-card__picker { gap: 10px; align-items: stretch; flex-wrap: wrap; }
.ga4-card__picker--spaced { margin-bottom: 10px; }
.ga4-card__property-host { flex: 1; min-width: 220px; }
/* hidden until JS sets style.display explicitly (same contract as .settings-msg) */
.ga4-card__error { display: none; color: var(--neg); font-size: 12px; margin-top: 8px; }
.ga4-card__stream-note { margin-top: 0; }

/* Metrics/goals editor */
.custom-goals__builtin { margin-bottom: 16px; }
.custom-goals__builtin-head { gap: 8px; margin-bottom: 8px; }
.custom-goals__builtin-label { font-size: 12px; font-weight: 500; text-transform: uppercase; letter-spacing: 0.04em; }
.custom-goals__chips { gap: 8px; flex-wrap: wrap; }
.custom-goals__chip { gap: 6px; padding: 4px 10px; background: var(--bg-sunken); border-radius: 6px; font-size: 12px; }
.custom-goals__chip-name { font-weight: 500; }
.custom-goals__empty { font-size: 13px; padding: 20px; text-align: center; background: var(--bg-sunken); border-radius: var(--radius-sm); }
.custom-goals__list { display: flex; flex-direction: column; gap: 10px; }
.custom-goals__fields { gap: 12px; align-items: flex-end; }
.custom-goals__field { flex: 1; min-width: 0; }
.custom-goals__field--fixed { flex: 0 0 160px; min-width: 0; }
.custom-goals__field--wide { flex: 2; min-width: 0; }
.custom-goals__remove { flex: none; }
/* pre-existing hook class on editor rows gains the row card chrome */
.goal-row { display: flex; flex-direction: column; gap: 10px; padding: 12px; background: var(--bg-sunken); border-radius: var(--radius-sm); }

/* Team dialogs (invite / manage member) */
.team-dialog__body { display: flex; flex-direction: column; gap: 14px; }
.team-dialog__body--roomy { gap: 18px; }
.team-dialog__member-email { margin-top: 4px; font-weight: 500; }
.team-dialog__role-hint { margin-top: 8px; }
.team-dialog__footer { justify-content: space-between; }
.team-row__you { font-weight: 400; }

/* Danger zone */
.danger-zone__title { color: var(--neg); margin-bottom: 6px; }
.danger-zone__row { justify-content: space-between; gap: 16px; flex-wrap: wrap; }
.danger-zone__info { flex: 1; min-width: 240px; }
.danger-zone__label { font-weight: 550; }
.danger-zone__desc { margin-top: 2px; }
.danger-zone__list { margin: 0 0 14px 18px; }

/* from frontend/src/views/experiment-detail-panels.js */

/* Right-rail panels on the experiment-detail page */
.details-panel,
.hypothesis-panel,
.goals-panel,
.funnels-panel { padding: 20px; }
.status-panel,
.actions-panel { padding: 18px 20px; }
.panel__head { justify-content: space-between; margin-bottom: 12px; }
.panel__head--roomy { margin-bottom: 16px; }
.section-title--sm { margin-bottom: 12px; font-size: 14px; }
.details-panel__value { margin-top: 4px; }
/* hidden until JS sets style.display = "block"/"none" explicitly */
.details-panel__field-error { color: var(--neg); display: none; }
.details-panel__actions { margin-top: 16px; gap: 8px; }
.details-panel__item--wide { grid-column: span 2; }
.details-panel__link-wrap { color: var(--accent-deep); word-break: break-all; }
.details-panel__link { color: inherit; text-decoration: underline; }
.details-panel__textarea { resize: vertical; }
.details-panel__prose { color: var(--ink-2); line-height: 1.5; }
.details-panel__traffic-bar { margin-top: 6px; margin-bottom: 4px; }
.status-panel__rows { gap: 12px; }
.actions-panel__list { gap: 8px; }
.badge--neg { background: var(--neg-bg); color: var(--neg); }
.text--pos { color: var(--pos); }

/* Result hero (Summary verdict accordion) */
.result-hero { padding: 24px 28px; margin-bottom: 16px; }
.result-hero__title { margin-bottom: 8px; }
.result-hero__body { padding: 24px 28px; min-width: 0; }
.result-hero__grid {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 320px;
  gap: 32px;
  align-items: center;
}
.result-hero__main { min-width: 0; }
.result-hero__verdict-text {
  font-size: 14px;
  color: var(--ink-2);
  line-height: 1.5;
  max-width: 56ch;
  overflow-wrap: anywhere;
}
.result-hero__viz { display: flex; align-items: center; justify-content: center; min-width: 0; }
.result-hero__runway {
  margin-top: 20px;
  padding: 14px 18px;
  display: flex;
  align-items: center;
  gap: 12px;
  background: var(--bg-sunken);
  border-radius: var(--radius-sm);
  box-shadow: inset 0 0 0 1px var(--line);
}
.result-hero__runway-icon { display: inline-flex; width: 18px; height: 18px; color: var(--ink-3); flex: none; }
.result-hero__runway-text { flex: 1; font-size: 13px; color: var(--ink-2); }
.result-hero__cta { margin-top: 18px; gap: 8px; }

/* from frontend/src/views/experiment-variants.js */

.allocation-panel { padding: 20px; margin-bottom: 16px; }
.allocation-total-label { font-size: 12px; display: inline-flex; align-items: center; gap: 6px; }
.variant-list__empty { padding: 12px 0; }
.variant-list__footer { justify-content: space-between; margin-top: 16px; }
.text--strong { font-weight: 600; }

.variant-row { border-top: 1px solid var(--line); }
.variant-row__info { min-width: 0; }
.variant-row__name-row { gap: 8px; flex-wrap: wrap; }
.variant-name-label { font-weight: 550; }
.variant-row__actions { gap: 6px; justify-content: flex-end; flex-wrap: wrap; }
.variant-row__menu { min-width: 200px; }

/* Both boxes keep their initial display:none inline — JS reads/clears the
   inline value to toggle them. */
.variant-readonly {
  padding: 16px;
  background: var(--bg-sunken);
  border-radius: var(--radius-sm);
  margin: 0 0 14px;
}
.variant-delete-confirm {
  padding: 12px 14px;
  background: color-mix(in srgb, var(--neg) 12%, transparent);
  border-radius: var(--radius-sm);
  border: 1px solid color-mix(in srgb, var(--neg) 30%, transparent);
  margin: 0 0 14px;
}
.variant-delete-confirm__row { justify-content: space-between; gap: 8px; flex-wrap: wrap; }
.variant-delete-confirm__btns { gap: 6px; }

.variant-preview__ghost { opacity: 0.35; }
.variant-preview__progress {
  position: absolute;
  inset: 0;
  display: flex;
  flex-direction: column;
  gap: 8px;
  align-items: center;
  justify-content: center;
  background: color-mix(in srgb, var(--color-bg) 62%, transparent);
}
.variant-preview__spinner {
  width: 26px;
  height: 26px;
  border: 3px solid var(--line);
  border-top-color: var(--color-primary);
  border-radius: 50%;
  animation: spin 0.8s linear infinite;
}
.variant-preview__retry {
  position: absolute;
  inset: 0;
  display: flex;
  flex-direction: column;
  gap: 10px;
  align-items: center;
  justify-content: center;
  text-align: center;
  padding: var(--space-3);
}
.variant-preview__retry-btn { font-size: 0.8rem; padding: 6px 12px; gap: 6px; }
.variant-preview__card { padding: 16px; }
.variant-preview__label { margin-bottom: 12px; gap: 8px; }

/* Editable/readonly variant change groups */
.variant-fieldset {
  border: var(--border);
  border-radius: var(--radius-sm);
  padding: var(--space-3);
  margin-bottom: var(--space-3);
}
.variant-fieldset__legend { font-weight: 600; padding: 0 var(--space-1); }
.variant-editor__mount { border: var(--border); border-radius: var(--radius-sm); overflow: hidden; }
.variant-editor__hint { margin-top: var(--space-1); }
.variant-editor__color-swatch { width: 40px; height: 32px; border: none; cursor: pointer; }
.variant-editor__color-hex { width: 90px; }
.variant-editor__note { font-size: 0.8rem; margin-top: var(--space-1); }
.variant-readonly__label { font-size: 0.8rem; display: block; margin-bottom: var(--space-1); }
.variant-readonly__group { margin-bottom: var(--space-2); }
.variant-readonly__code {
  background: var(--color-surface);
  border: var(--border);
  border-radius: var(--radius-sm);
  padding: var(--space-2);
  font-size: 0.8rem;
  overflow-x: auto;
  white-space: pre-wrap;
  word-break: break-all;
  margin: 0;
}
.variant-readonly__url { font-size: 0.8rem; word-break: break-all; }

/* from frontend/src/views/dashboard.js */

.dashboard__subtitle { min-height: 24px; flex: 1; }
.dashboard-actions { gap: 8px; flex: none; }
.dashboard__cta-panel { padding: 24px; display: flex; gap: 20px; align-items: center; }
.dashboard__cta-text { flex: 1; }
.dashboard__cta-title { font-weight: 500; font-size: 16px; }
.dashboard__cta-sub { margin-top: 4px; }
.dashboard__concluded-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
  gap: 12px;
}
.concluded-card { padding: 16px 18px; display: block; text-decoration: none; color: inherit; }
.concluded-card__head { justify-content: space-between; margin-bottom: 8px; }
.concluded-card__name { font-weight: 500; }
.concluded-card__meta { margin-top: 2px; }
.v2-section-rule--offset { margin-top: 48px; }
.dashboard__resources-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
  gap: 12px;
}
.resource-card { padding: 16px 18px; text-decoration: none; color: inherit; }
.resource-card__title { font-weight: 500; }
.resource-card__desc { margin-top: 4px; }
.dashboard__error { padding: 20px; color: var(--neg); }
.dashboard__stat-sep { margin: 0 6px; color: var(--ink-3); font-weight: 400; }
.dashboard__status-panel { padding: 14px 18px; display: flex; gap: 14px; align-items: center; margin-bottom: 20px; }
.dashboard__status-msg { flex: 1; font-size: 13px; }

/* from frontend/src/views/experiments-list.js */

.exp-list__subtitle { flex: 1; }
.experiments-actions { gap: 8px; flex: none; }
.exp-list__empty { padding: 40px; text-align: center; }
.exp-list__empty-title { font-size: 24px; font-weight: 600; margin-bottom: 8px; }
.exp-list__empty-sub { margin-bottom: 20px; }
.exp-list__error { padding: 20px; color: var(--neg); }
.exp-list__as-of { opacity: 0.8; }
.exp-list__limit-banner {
  padding: 12px 16px;
  margin-bottom: 16px;
  border-left: 3px solid var(--neg);
  display: flex;
  align-items: center;
  gap: 10px;
}
.exp-list__limit-icon { color: var(--neg); flex: none; }
.exp-list__limit-link { color: var(--accent); text-decoration: none; }
.exp-filter-bar { justify-content: space-between; margin-bottom: 18px; gap: 12px; flex-wrap: wrap; }
.exp-card__name-row { gap: 10px; }
