/*
  D3pth AI — "Enterprise Clarity" design tokens (ported from src/app/globals.css).
  Phase 0: tokens + fonts + shell utilities. Full Tailwind utility parity lands later.
*/

/* ── Self-hosted fonts (static/fonts → /fonts via assets-dir) ───────────── */

@font-face {
  font-family: "Inter";
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url("/fonts/inter/inter-latin-400-normal.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA,
    U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193,
    U+2212, U+2215, U+FEFF, U+FFFD;
}

@font-face {
  font-family: "Inter";
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url("/fonts/inter/inter-latin-500-normal.woff2") format("woff2");
}

@font-face {
  font-family: "Inter";
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: url("/fonts/inter/inter-latin-600-normal.woff2") format("woff2");
}

@font-face {
  font-family: "Inter";
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url("/fonts/inter/inter-latin-700-normal.woff2") format("woff2");
}

@font-face {
  font-family: "Fraunces";
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url("/fonts/fraunces/fraunces-latin-400-normal.woff2") format("woff2");
}

@font-face {
  font-family: "Fraunces";
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url("/fonts/fraunces/fraunces-latin-500-normal.woff2") format("woff2");
}

@font-face {
  font-family: "Fraunces";
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: url("/fonts/fraunces/fraunces-latin-600-normal.woff2") format("woff2");
}

@font-face {
  font-family: "Fraunces";
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url("/fonts/fraunces/fraunces-latin-700-normal.woff2") format("woff2");
}

@font-face {
  font-family: "JetBrains Mono";
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url("/fonts/jetbrains-mono/jetbrains-mono-latin-400-normal.woff2")
    format("woff2");
}

@font-face {
  font-family: "JetBrains Mono";
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url("/fonts/jetbrains-mono/jetbrains-mono-latin-500-normal.woff2")
    format("woff2");
}

/* ── Design tokens (match Next globals.css @theme) ──────────────────────── */

:root {
  /* Surfaces */
  --color-bg: #ffffff;
  --color-panel: #f8fafc;
  --color-border: #e2e8f0;

  /* Text */
  --color-text: #0f172a;
  --color-text-muted: #475569;
  --color-text-faint: #64748b;

  /* Accents */
  --color-accent: #3b82f6;
  --color-accent-2: #0ea5e9;
  --color-telemetry: #10b981;

  /* AA-safe text accents */
  --color-accent-strong: #2563eb;
  --color-telemetry-strong: #047857;

  /* Semantic status */
  --color-warn: #b45309;
  --color-warn-bg: #fffbeb;
  --color-warn-border: #fcd34d;
  --color-danger: #b91c1c;
  --color-danger-bg: #fef2f2;
  --color-danger-border: #fca5a5;

  /* Dark-navy application chrome (portal + dashboards only) */
  --color-chrome: #0b1f3a;
  --color-chrome-2: #0f2a4d;

  /* Typography */
  --font-display: "Fraunces", ui-serif, Georgia, serif;
  --font-sans: "Inter", ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji",
    "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";
  --font-mono: "JetBrains Mono", ui-monospace, SFMono-Regular, Menlo, Monaco,
    Consolas, "Liberation Mono", "Courier New", monospace;

  --radius-card: 0.75rem;
  --shadow-card: 0 1px 2px rgba(15, 23, 42, 0.05),
    0 4px 10px -3px rgba(15, 23, 42, 0.09),
    0 12px 28px -10px rgba(15, 23, 42, 0.07);
  --shadow-float: 0 2px 6px -1px rgba(15, 23, 42, 0.08),
    0 14px 32px -10px rgba(15, 23, 42, 0.14),
    0 0 28px -6px color-mix(in srgb, var(--color-accent) 24%, transparent);
  --shadow-glow: 0 0 0 1px color-mix(in srgb, var(--color-accent) 14%, transparent),
    0 10px 34px -8px color-mix(in srgb, var(--color-accent) 30%, transparent);
}

/* ── Base ───────────────────────────────────────────────────────────────── */

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

html {
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

body {
  margin: 0;
  background: var(--color-bg);
  color: var(--color-text);
  font-family: var(--font-sans);
  line-height: 1.5;
}

::selection {
  background: color-mix(in srgb, var(--color-accent) 22%, transparent);
}

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

/* ── Utilities ported from globals ──────────────────────────────────────── */

.bg-grid {
  background-image: linear-gradient(
      to right,
      color-mix(in srgb, var(--color-border) 60%, transparent) 1px,
      transparent 1px
    ),
    linear-gradient(
      to bottom,
      color-mix(in srgb, var(--color-border) 60%, transparent) 1px,
      transparent 1px
    );
  background-size: 56px 56px;
}

.frosted {
  background: color-mix(in srgb, var(--color-bg) 72%, transparent);
  backdrop-filter: blur(12px);
  -webkit-backdrop-filter: blur(12px);
}

/* ── Phase 0 shell layout ───────────────────────────────────────────────── */

.site {
  min-height: 100svh;
  display: flex;
  flex-direction: column;
}

.nav {
  position: sticky;
  top: 0;
  z-index: 40;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1.5rem;
  padding: 0.875rem 1.25rem;
  border-bottom: 1px solid var(--color-border);
}

.brand {
  display: inline-flex;
  align-items: center;
  gap: 0.625rem;
  height: 28px;
  font-weight: 700;
  letter-spacing: -0.02em;
  text-decoration: none;
  color: var(--color-text);
  line-height: 1;
}

.brand-mark {
  /* Compact bead mark — closer to Next DotLogo footprint */
  width: 1.5rem;
  height: 1.5rem;
  border-radius: 999px;
  background:
    radial-gradient(circle at 32% 30%, #fff 0 10%, transparent 11%),
    radial-gradient(circle at 50% 50%, var(--color-accent) 0 34%, transparent 36%),
    radial-gradient(circle at 58% 62%, color-mix(in srgb, var(--color-accent) 55%, #1e3a5f) 0 55%, transparent 56%),
    radial-gradient(circle at 50% 50%, #0b1220 0 100%);
  box-shadow: 0 0 0 1px color-mix(in srgb, var(--color-accent) 20%, transparent);
  flex-shrink: 0;
}
.brand-mark-live {
  animation: brand-pulse 3.2s ease-in-out infinite;
}
@keyframes brand-pulse {
  0%, 100% { box-shadow: 0 0 0 1px color-mix(in srgb, var(--color-accent) 25%, transparent); }
  50% { box-shadow: 0 0 0 4px color-mix(in srgb, var(--color-accent) 18%, transparent); }
}
@media (prefers-reduced-motion: reduce) {
  .brand-mark-live { animation: none; }
}

.brand-word {
  font-family: var(--font-sans, inherit);
  font-size: 1.25rem;
  font-weight: 700;
  letter-spacing: -0.03em;
  display: inline-flex;
  align-items: center;
  height: 28px;
  line-height: 1;
}
.brand-3 { color: var(--color-accent); }
.brand-bead {
  display: inline-block;
  width: 0.32em; height: 0.32em;
  margin: 0 0.3em;
  border-radius: 999px;
  background: #22d3ee;
  box-shadow: 0 0 8px 2px #22d3ee, 0 0 14px #38bdf8;
}
.brand-ai {
  font-size: 0.72em;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--color-text-muted);
}
.brand-name {
  font-family: var(--font-display);
  font-size: 1.125rem;
}
.icon { display: block; flex-shrink: 0; }
.icon-lg { width: 1.25rem; height: 1.25rem; }
.icon-xs { width: 0.75rem; height: 0.75rem; display: inline-block; vertical-align: -0.1em; }
.btn-lg { padding: 0.7rem 1.25rem; font-size: 1rem; }
.dot-logo-canvas {
  display: block;
  flex-shrink: 0;
  width: 28px;
  height: 28px;
  margin: 0;
  /* Optical: bead mass sits a hair high in the 64² viewBox; nudge to the wordmark. */
  transform: translateY(1px);
}

.nav-links {
  display: flex;
  align-items: center;
  gap: 1.25rem;
  font-size: 0.9375rem;
  color: var(--color-text-muted);
}

.nav-links a:hover {
  color: var(--color-text);
}

.nav-cta {
  color: var(--color-accent-strong) !important;
  font-weight: 600;
}

.shell {
  flex: 1;
  width: 100%;
  max-width: 72rem;
  margin: 0 auto;
  padding: 0 1.25rem;
}

.hero {
  padding: 4.5rem 0 5rem;
}

.eyebrow {
  margin: 0 0 0.75rem;
  font-size: 0.8125rem;
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--color-accent-strong);
}

.display {
  margin: 0;
  font-family: var(--font-display);
  font-size: clamp(2.25rem, 5vw, 3.5rem);
  font-weight: 600;
  line-height: 1.12;
  letter-spacing: -0.03em;
}

.accent-text {
  color: var(--color-accent-strong);
}

.lede {
  margin: 1.25rem 0 0;
  max-width: 36rem;
  font-size: 1.0625rem;
}

.muted {
  color: var(--color-text-muted);
}

.faint {
  color: var(--color-text-faint);
}

.mono {
  font-family: var(--font-mono);
  font-size: 0.8125rem;
}

.cta-row {
  display: flex;
  flex-wrap: wrap;
  gap: 0.75rem;
  margin-top: 1.75rem;
}

.btn {
  position: relative;
  overflow: hidden;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 0.625rem 1.125rem;
  border-radius: 999px;
  font-size: 0.9375rem;
  font-weight: 600;
  border: 1px solid transparent;
  transition: background 120ms ease, color 120ms ease, box-shadow 120ms ease;
}

.btn-ripple-canvas {
  position: absolute;
  inset: 0;
  display: block;
  width: 100%;
  height: 100%;
  pointer-events: none;
}

.btn-primary {
  background: var(--color-accent-strong);
  color: #fff;
  box-shadow: var(--shadow-card);
}

.btn-primary:hover {
  box-shadow: var(--shadow-float);
}

.btn-ghost {
  background: var(--color-panel);
  border-color: var(--color-border);
  color: var(--color-text);
}

.btn-ghost:hover {
  border-color: color-mix(in srgb, var(--color-accent) 40%, var(--color-border));
}

.token-swatches {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(6.5rem, 1fr));
  gap: 0.75rem;
  margin: 2.5rem 0 1.5rem;
  max-width: 28rem;
}

.token-swatches dt {
  font-family: var(--font-mono);
  font-size: 0.6875rem;
  color: var(--color-text-faint);
  margin-bottom: 0.35rem;
}

.token-swatches dd {
  margin: 0;
}

.swatch {
  height: 2.5rem;
  border-radius: var(--radius-card);
  border: 1px solid var(--color-border);
  box-shadow: var(--shadow-card);
}

.swatch-accent {
  background: var(--color-accent);
}
.swatch-accent-2 {
  background: var(--color-accent-2);
}
.swatch-telemetry {
  background: var(--color-telemetry);
}
.swatch-chrome {
  background: var(--color-chrome);
}

.footer {
  border-top: 1px solid var(--color-border);
  padding: 1.25rem;
  text-align: center;
  font-size: 0.8125rem;
}

@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
  }
}

/* ── Expanded layout (Phase 3+) ─────────────────────────────────────────── */

.shell-wide {
  flex: 1;
  width: 100%;
}

.page-hero {
  max-width: 72rem;
  margin: 0 auto;
  padding: 3.5rem 1.25rem 2rem;
}

.content-block {
  max-width: 72rem;
  margin: 0 auto;
  padding: 1.5rem 1.25rem 4rem;
}

.section-title {
  margin: 0.5rem 0 0.75rem;
  font-family: var(--font-display);
  font-size: clamp(1.5rem, 3vw, 2rem);
  font-weight: 600;
  letter-spacing: -0.02em;
}

.text-strong {
  font-weight: 600;
  color: var(--color-text);
}

.link {
  color: var(--color-accent-strong);
  text-decoration: underline;
  text-underline-offset: 2px;
}

.footer-inner {
  max-width: 72rem;
  margin: 0 auto;
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 1rem;
  flex-wrap: wrap;
}

.footer-links {
  display: flex;
  gap: 1rem;
  color: var(--color-text-muted);
  font-size: 0.875rem;
}

.phase-list {
  list-style: none;
  margin: 2rem 0 0;
  padding: 0;
  display: grid;
  gap: 1rem;
}

.phase-card {
  display: grid;
  grid-template-columns: auto 1fr;
  gap: 1rem;
  padding: 1.25rem;
  border: 1px solid var(--color-border);
  border-radius: var(--radius-card);
  background: var(--color-panel);
  box-shadow: var(--shadow-card);
}

.phase-n {
  color: var(--color-accent-strong);
  font-weight: 600;
}

.phase-card h3 {
  margin: 0;
  font-family: var(--font-display);
  font-size: 1.125rem;
}

.phase-sub {
  margin: 0.15rem 0 0.5rem;
  font-size: 0.8125rem;
  color: var(--color-text-faint);
  text-transform: uppercase;
  letter-spacing: 0.06em;
}

.logo-wall {
  list-style: none;
  display: flex;
  flex-wrap: wrap;
  gap: 0.75rem;
  margin: 1rem 0 0;
  padding: 0;
}

.logo-chip {
  padding: 0.5rem 0.9rem;
  border: 1px solid var(--color-border);
  border-radius: 999px;
  background: var(--color-panel);
  font-weight: 600;
  font-size: 0.875rem;
}

.founder-quote {
  margin: 2.5rem 0 0;
  padding: 1.75rem;
  border: 1px solid var(--color-border);
  border-radius: var(--radius-card);
  background: color-mix(in srgb, var(--color-panel) 90%, transparent);
}

.quote-body {
  font-family: var(--font-display);
  font-size: 1.35rem;
  line-height: 1.45;
  margin: 0.75rem 0;
}

/* Next renders the byline `uppercase tracking-wider text-xs`. */
.founder-quote footer {
  margin-top: 1rem;
  font-size: 0.75rem;
  letter-spacing: 0.05em;
  text-transform: uppercase;
}

.dot-field {
  min-height: 8rem;
  border-radius: var(--radius-card);
  background-image: radial-gradient(circle at 20% 30%, var(--color-accent) 1.5px, transparent 1.6px),
    radial-gradient(circle at 70% 60%, var(--color-accent-2) 1.2px, transparent 1.3px),
    radial-gradient(circle at 40% 80%, var(--color-telemetry) 1px, transparent 1.1px),
    radial-gradient(circle at 85% 25%, var(--color-chrome) 1.2px, transparent 1.3px);
  background-size: 24px 24px, 32px 32px, 18px 18px, 40px 40px;
  opacity: 0.55;
  border: 1px solid var(--color-border);
}

.dot-field.dense {
  min-height: 14rem;
  opacity: 0.7;
}

/* founder-cloud only when used outside full-bleed stage */
.founder-cloud { margin-top: 2rem; position: relative; }

/* Legal — parity with Next privacy/terms:
   `mx-auto max-w-3xl px-5 py-16 sm:px-8` around a `mt-10 space-y-8` body.
   The narrow measure is load-bearing: without it the prose ran the full
   viewport width and the page came out ~360px shorter than Next. */
.legal {
  max-width: 48rem;
  margin: 0 auto;
  padding: 4rem 1.25rem;
}
@media (min-width: 640px) {
  .legal {
    padding: 4rem 2rem;
  }
}
.legal-body {
  margin-top: 2.5rem;
}
.legal-body > section + section {
  margin-top: 2rem;
}
.legal h2 {
  font-family: var(--font-display);
  font-size: 1.25rem;
  font-weight: 600;
  line-height: 1.4;
  margin: 0;
}
.legal p {
  color: var(--color-text-muted);
  line-height: 1.625;
  margin: 0.5rem 0 0;
}

/* Cards */
.card-grid {
  list-style: none;
  margin: 1.25rem 0 0;
  padding: 0;
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(15rem, 1fr));
  gap: 1rem;
}
.card {
  border: 1px solid var(--color-border);
  border-radius: var(--radius-card);
  background: var(--color-panel);
  padding: 1.1rem 1.2rem;
  box-shadow: var(--shadow-card);
}
.card h3 {
  margin: 0 0 0.35rem;
  font-family: var(--font-display);
  font-size: 1.05rem;
}
.key-list {
  list-style: none;
  margin: 0.75rem 0 0;
  padding: 0;
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem 1rem;
  font-size: 0.8125rem;
}

/* Booking */
.booking-section {
  position: relative;
  overflow: hidden;
}
.booking-card {
  max-width: 42rem;
  margin: 0 auto;
  padding: 0;
  border: 1px solid color-mix(in srgb, #fff 60%, var(--color-border));
  border-radius: 1.25rem;
  background: color-mix(in srgb, #fff 70%, transparent);
  box-shadow: var(--shadow-card, 0 8px 32px rgba(0,0,0,0.05));
  backdrop-filter: blur(12px);
  overflow: hidden;
}
.booking-section {
  max-width: 42rem;
  margin: 0 auto;
  padding: 5rem 1.25rem;
}
@media (min-width: 640px) {
  .booking-section { padding: 5rem 2rem; }
}
.booking-card-head {
  padding: 1.5rem 1.25rem 1.25rem;
  border-bottom: 1px solid color-mix(in srgb, #fff 40%, var(--color-border));
  background: color-mix(in srgb, #fff 40%, transparent);
  text-align: center;
}
@media (min-width: 640px) {
  .booking-card-head { padding: 2rem; }
}
.booking-title {
  margin: 0;
  font-size: clamp(1.5rem, 3vw, 2.25rem);
  text-align: center;
}
.booking-sub { margin: 0.5rem 0 0; text-align: center; }
.booking-card-body { padding: 1.5rem 1.25rem 1.75rem; }
@media (min-width: 640px) {
  .booking-card-body { padding: 1.75rem 1.5rem 2rem; }
}
.booking-progress { margin-top: 1rem; }
.booking-progress-canvas {
  display: block;
  width: 100%;
  height: 34px;
}
.booking-progress-labels {
  display: none;
  position: relative;
  height: 1.25rem;
  margin-top: 0.25rem;
  justify-content: space-between;
}
/* Mobile caption: the one place Next uppercases + tracks the step label. Its
   base rule must precede the min-width override below, or `display: flex` here
   would win over `display: none` there and the caption would show on desktop
   alongside the rail it replaces. */
.booking-progress-mobile {
  display: flex;
  align-items: baseline;
  justify-content: center;
  gap: 0.5rem;
  margin: 0.5rem 0 0;
  font-size: 0.75rem;
  text-transform: uppercase;
  letter-spacing: 0.06em;
}
.bp-mobile-step { color: var(--color-text-faint); }
.bp-mobile-label { color: var(--color-accent-strong); font-weight: 600; }
@media (min-width: 640px) {
  .booking-progress-labels { display: flex; }
  .booking-progress-mobile { display: none; }
}
/* The rail labels are <button>s (completed steps are pressable). This sheet has
   no global button reset, so without this they render with UA button chrome.
   Deliberately carries NO color/font-family/font-size: `.bp-label`, `.on` and
   `.done` below own those at equal specificity, and duplicating them here would
   make the active/done colours depend on source order. `font: inherit` is
   enough to defeat the UA's buttontext/13px Arial. */
.bp-step-btn {
  font: inherit;
  background: transparent;
  border: 0;
  padding: 0;
  border-radius: 0.125rem;
  cursor: default;
  white-space: nowrap;
}
.bp-step-btn:enabled { cursor: pointer; }
.bp-step-btn:enabled:hover {
  color: var(--color-accent-strong);
  text-decoration: underline;
  text-underline-offset: 4px;
}
.bp-step-btn:focus-visible {
  outline: 2px solid color-mix(in srgb, var(--color-accent) 50%, transparent);
  outline-offset: 2px;
}
/* Desktop rail labels. Next's `booking-progress.tsx` renders these with
   `font-mono text-[11px]` and deliberately WITHOUT `uppercase`/`tracking-wider`
   — only the mobile caption above gets those — so neither belongs here. */
.bp-label {
  font-family: var(--font-mono);
  font-size: 0.6875rem;
  color: var(--color-text-faint);
}
.bp-label.on { color: var(--color-accent-strong); font-weight: 600; }
.bp-label.done { color: var(--color-accent); }
.thank-you-burst {
  position: fixed;
  inset: 0;
  z-index: 80;
  pointer-events: none;
}
.thank-you-burst-canvas {
  display: block;
  width: 100%;
  height: 100%;
}
.topic-grid, .time-grid {
  display: grid;
  gap: 0.6rem;
  margin-top: 1rem;
}
.topic-grid {
  grid-template-columns: 1fr;
}
.time-grid {
  grid-template-columns: repeat(2, minmax(0, 1fr));
}
@media (min-width: 640px) {
  .time-grid {
    grid-template-columns: repeat(3, minmax(0, 1fr));
  }
}
.topic-btn, .day-btn, .time-btn {
  text-align: left;
  padding: 0.75rem 1rem;
  border-radius: var(--radius-card);
  border: 1px solid var(--color-border);
  background: var(--color-bg);
  font: inherit;
  cursor: pointer;
}
/* Touch devices sticky-hover the last tap, so the previous day kept looking
   selected after a new one was chosen. Hover chrome is pointer-only; the
   actual selection is `[aria-checked=true]`. */
@media (hover: hover) {
  .topic-btn:hover, .day-btn:hover, .time-btn:hover {
    border-color: var(--color-accent);
    box-shadow: var(--shadow-glow);
  }
}
.topic-btn[aria-pressed="true"],
.day-btn[aria-checked="true"],
.time-btn[aria-checked="true"] {
  border-color: var(--color-accent);
  background: color-mix(in srgb, var(--color-accent) 8%, var(--color-bg));
  box-shadow: var(--shadow-glow);
}
.time-btn[aria-checked="true"] {
  background: var(--color-accent);
  color: var(--color-bg);
}
.booking-tz-line {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.5rem 0.75rem;
}
.booking-tz { display: inline-flex; align-items: center; }
.day-rail-wrap {
  position: relative;
  margin-top: 1.25rem;
}
.day-rail {
  display: flex;
  gap: 0.5rem;
  overflow-x: auto;
  scroll-smooth;
  padding-bottom: 0.25rem;
  overscroll-behavior-x: contain;
  -webkit-overflow-scrolling: touch;
}
.day-btn {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 0.15rem;
  min-width: 3.75rem;
  flex-shrink: 0;
  padding: 0.5rem 0.75rem;
  text-align: center;
}
.day-btn-wd,
.day-btn-mo {
  font-family: var(--font-mono);
  font-size: 0.625rem;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--color-text-faint);
}
.day-btn-num {
  font-family: var(--font-display);
  font-size: 1.125rem;
  font-weight: 600;
  line-height: 1;
  color: var(--color-text);
}
.day-btn[aria-checked="true"] .day-btn-num {
  color: var(--color-accent-strong);
}
.day-rail-fade {
  display: none;
}
@media (max-width: 639px) {
  .day-rail-fade {
    display: block;
    pointer-events: none;
    position: absolute;
    top: 0;
    right: 0;
    bottom: 0.25rem;
    width: 2rem;
    background: linear-gradient(to left, var(--color-bg), transparent);
  }
}
.form-stack {
  display: grid;
  gap: 0.85rem;
  margin-top: 1rem;
}
.form-stack label {
  display: grid;
  gap: 0.35rem;
  font-size: 0.875rem;
  font-weight: 500;
}
.form-stack input {
  padding: 0.6rem 0.75rem;
  border: 1px solid var(--color-border);
  border-radius: 0.5rem;
  font: inherit;
}
.form-error {
  color: var(--color-danger);
  font-size: 0.875rem;
}
.hp {
  position: absolute;
  left: -9999px;
  height: 0;
  overflow: hidden;
}
.thank-you h2 {
  font-family: var(--font-display);
}

/* Portal chrome */
.portal-shell {
  min-height: 100svh;
  background: var(--color-chrome);
  color: #e2e8f0;
}
.portal-nav {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 1rem;
  padding: 0.9rem 1.25rem;
  border-bottom: 1px solid color-mix(in srgb, #fff 12%, transparent);
  background: color-mix(in srgb, var(--color-chrome-2) 90%, transparent);
}
.portal-brand .brand-name { color: #fff; }
.portal-badge {
  margin-left: 0.5rem;
  font-size: 0.7rem;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: #93c5fd;
  font-family: var(--font-mono);
}
.portal-nav-links {
  display: flex;
  gap: 1rem;
  font-size: 0.9rem;
  color: #cbd5e1;
}
.portal-nav-links a:hover { color: #fff; }
.portal-main {
  max-width: 72rem;
  margin: 0 auto;
  padding: 1.5rem 1.25rem 3rem;
}
.portal-display { color: #fff; }
.portal-login { max-width: 28rem; }
.login-terminal {
  margin-top: 1.5rem;
  padding: 1.5rem;
  border-radius: var(--radius-card);
  border: 1px solid color-mix(in srgb, #fff 14%, transparent);
  background: color-mix(in srgb, #000 25%, var(--color-chrome-2));
}
.pacman-stub {
  display: flex;
  gap: 0.5rem;
  align-items: center;
  margin-bottom: 1rem;
}
.pac {
  width: 1.25rem;
  height: 1.25rem;
  border-radius: 50%;
  background: #facc15;
}
.ghost {
  width: 1rem;
  height: 1.15rem;
  border-radius: 0.5rem 0.5rem 0 0;
  background: #60a5fa;
}
.portal-toolbar {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 1rem;
  flex-wrap: wrap;
  margin-bottom: 1rem;
}
.portal-toolbar .section-title { color: #fff; margin: 0; }
.portal-shell .muted { color: #94a3b8; }
.portal-shell .card {
  background: color-mix(in srgb, #fff 6%, var(--color-chrome-2));
  border-color: color-mix(in srgb, #fff 12%, transparent);
  color: #e2e8f0;
}
.portal-shell .card h3 { color: #fff; }
.metric-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(8rem, 1fr));
  gap: 0.75rem;
  margin: 1rem 0 1.5rem;
}
.metric-grid div {
  padding: 0.9rem;
  border-radius: var(--radius-card);
  border: 1px solid color-mix(in srgb, #fff 12%, transparent);
  background: color-mix(in srgb, #000 18%, transparent);
}
.metric-grid dt {
  font-size: 0.75rem;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: #94a3b8;
}
.metric-grid dd {
  margin: 0.35rem 0 0;
  font-size: 1.25rem;
  color: #fff;
}

.tenant-switcher { position: relative; }
.tenant-demo-label {
  margin: 0 0 0.35rem 0.15rem;
  font-size: 0.625rem;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: #64748b;
}
.tenant-btn {
  display: flex;
  width: 100%;
  align-items: center;
  justify-content: space-between;
  gap: 0.5rem;
  font: inherit;
  cursor: pointer;
  padding: 0.5rem 0.75rem;
  border-radius: 0.5rem;
  border: 1px solid color-mix(in srgb, #fff 10%, transparent);
  background: color-mix(in srgb, #000 25%, transparent);
  color: #e2e8f0;
  text-align: left;
}
.tenant-btn-text { display: flex; min-width: 0; flex-direction: column; gap: 0.1rem; }
.tenant-name { display: block; font-weight: 600; font-size: 0.875rem; color: #fff; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.tenant-meta { display: block; font-size: 0.625rem; color: #64748b; }
.tenant-list {
  position: absolute;
  right: 0;
  top: calc(100% + 0.35rem);
  z-index: 30;
  list-style: none;
  margin: 0;
  padding: 0.35rem;
  min-width: 16rem;
  max-height: 18rem;
  overflow: auto;
  border-radius: var(--radius-card);
  border: 1px solid color-mix(in srgb, #fff 14%, transparent);
  background: var(--color-chrome-2);
  box-shadow: var(--shadow-float);
}
/* Next opens upward from the sidebar foot */
.tenant-list-up {
  top: auto;
  bottom: calc(100% + 0.5rem);
  left: 0;
  right: 0;
  width: 100%;
  min-width: 0;
}
.tenant-list button,
.tenant-option {
  width: 100%;
  text-align: left;
  font: inherit;
  color: #e2e8f0;
  background: transparent;
  border: 0;
  padding: 0.55rem 0.7rem;
  border-radius: 0.4rem;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.5rem;
}
.tenant-list button:hover,
.tenant-option:hover {
  background: color-mix(in srgb, #fff 10%, transparent);
}
.tenant-option.selected { background: color-mix(in srgb, #fff 5%, transparent); }
.tenant-option-text { display: flex; min-width: 0; flex-direction: column; gap: 0.1rem; }
.tenant-option-name {
  display: block; font-size: 0.75rem; font-weight: 500; color: #e2e8f0;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.tenant-option-meta { font-size: 0.625rem; color: #64748b; }
.tenant-check { color: var(--color-accent-2, #0ea5e9); font-size: 0.875rem; flex-shrink: 0; }
.tenant-btn:hover { background: color-mix(in srgb, #fff 5%, transparent); }
.tenant-chevron { color: #94a3b8; flex-shrink: 0; font-size: 0.75rem; }

.dashboard-shell .section-title { color: #fff; }
.dashboard-stage {
  margin: 1rem 0;
}
.dash-panel {
  padding: 1rem;
  border-radius: var(--radius-card);
  border: 1px solid color-mix(in srgb, #fff 12%, transparent);
  background: color-mix(in srgb, #000 20%, transparent);
}
.schematic-panel {
  display: grid;
  gap: 0.75rem;
  max-width: 36rem;
}
.schematic-panel .btn {
  justify-self: start;
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
}
.workspace-light .schematic-panel,
.drawer-dash.schematic-panel {
  border-color: var(--color-border);
  background: var(--color-panel);
}
.dash-viz { margin: 0.75rem 0; }
.portal-shell .link { color: #93c5fd; }

@media (max-width: 640px) {
  .nav-links a:not(.nav-cta) { display: none; }
  .portal-toolbar { align-items: flex-start; flex-direction: column; }
}

/* ── Captcha ────────────────────────────────────────────────────────────── */
.captcha {
  margin: 0.75rem 0 0;
  width: 100%;
  min-width: 0;
  max-width: 100%;
  overflow: hidden;
  box-sizing: border-box;
}
.captcha-trigger {
  display: flex; width: 100%; align-items: center; justify-content: center;
  gap: 0.75rem; font: inherit; cursor: pointer;
  padding: 1.25rem; border-radius: 0.75rem;
  border: 1px solid color-mix(in srgb, var(--color-accent) 40%, var(--color-border));
  background: color-mix(in srgb, var(--color-accent) 10%, transparent);
  font-weight: 600; font-size: 0.875rem; color: var(--color-text);
  box-shadow: inset 0 1px 2px color-mix(in srgb, var(--color-accent) 8%, transparent);
  transition: background 120ms ease, border-color 120ms ease, transform 120ms ease;
}
.captcha-trigger-icon {
  width: 1.25rem; height: 1.25rem; color: var(--color-accent); flex-shrink: 0;
}
.captcha-trigger:hover {
  background: color-mix(in srgb, var(--color-accent) 20%, transparent);
  border-color: color-mix(in srgb, var(--color-accent) 60%, var(--color-border));
}
.captcha-ok-row {
  display: flex; width: 100%; align-items: center; gap: 0.75rem;
  padding: 1.1rem 1.25rem; border-radius: 0.75rem;
  border: 1px solid color-mix(in srgb, var(--color-telemetry-strong, #10b981) 30%, var(--color-border));
  background: color-mix(in srgb, var(--color-telemetry-strong, #10b981) 5%, transparent);
  box-sizing: border-box;
}
.captcha-ok { color: var(--color-text); margin: 0; font-size: 0.875rem; font-weight: 500; }
.captcha-panel {
  display: flex; flex-direction: column; align-items: center; gap: 1rem;
  width: 100%; max-width: 100%; min-width: 0;
  padding: 1.25rem; box-sizing: border-box;
  overflow: hidden;
  border-radius: 0.75rem;
  background: color-mix(in srgb, var(--color-panel) 30%, transparent);
  border: 1px solid color-mix(in srgb, var(--color-border) 60%, transparent);
}
.captcha-head {
  display: flex; width: 100%; min-width: 0;
  justify-content: space-between; align-items: center; gap: 0.75rem;
}
.captcha-title {
  font-size: 0.875rem; font-weight: 500;
  min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.captcha-head-actions {
  display: flex; align-items: center; gap: 0.5rem; flex-shrink: 0;
}
.captcha-reroll {
  font: inherit; font-size: 0.6875rem; font-weight: 500; letter-spacing: 0.06em;
  text-transform: uppercase; color: var(--color-text-muted);
  background: transparent; border: 0; cursor: pointer; padding: 0.25rem 0.35rem;
  white-space: nowrap;
}
.captcha-reroll:disabled { opacity: 0.5; cursor: not-allowed; }
.captcha-close {
  width: 1.5rem; height: 1.5rem; padding: 0;
  display: inline-flex; align-items: center; justify-content: center;
  border-radius: 0.375rem; border: 1px solid var(--color-border);
  background: var(--color-bg); color: var(--color-text-muted); cursor: pointer;
}
.captcha-canvas-wrap {
  position: relative; width: 100%; overflow: hidden;
  border-radius: 0.5rem; border: 1px solid color-mix(in srgb, var(--color-border) 80%, transparent);
  background: var(--color-bg); aspect-ratio: 32 / 10;
  /* Finger drags must move the marker, not scroll the consult/login panel.
     `touch-action: none` is the reliable lever — preventDefault on pointerdown
     is ignored by browsers that treat the listener as passive. */
  touch-action: none;
  user-select: none;
  -webkit-user-select: none;
  -webkit-touch-callout: none;
  cursor: grab;
}
.captcha-canvas-wrap.is-dragging,
.captcha-canvas-wrap.is-carrying {
  cursor: grabbing;
}
.captcha-canvas {
  display: block; width: 100%; height: 100%; margin: 0;
  border: 0; background: transparent;
  touch-action: none;
  /* Hits go to the wrap so pointer capture + touch-action apply to one element. */
  pointer-events: none;
}
.captcha-row { display: flex; width: 100%; min-width: 0; gap: 0.5rem; align-items: center; }
.captcha-input {
  flex: 1; min-width: 0; padding: 0.55rem 1rem; text-align: center;
  font-family: var(--font-mono); font-size: 1.125rem; letter-spacing: 0.2em;
  border: 1px solid var(--color-border); border-radius: 0.5rem;
  background: var(--color-bg); color: var(--color-text); outline: none;
}
.captcha-input:focus { border-color: var(--color-accent); box-shadow: 0 0 0 2px color-mix(in srgb, var(--color-accent) 20%, transparent); }
.captcha-input-error {
  border-color: var(--color-danger, #dc2626); color: var(--color-danger, #dc2626);
}
.captcha-input:disabled { opacity: 0.5; }
.captcha-verify { position: relative; overflow: hidden; flex-shrink: 0; }
.captcha-hint, .captcha-error {
  margin: 0; width: 100%; text-align: center; font-size: 0.75rem;
  overflow-wrap: anywhere;
}
.sr-only {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0,0,0,0); white-space: nowrap; border: 0;
}

/* ── Dashboard widgets ──────────────────────────────────────────────────── */
.dash-host { color: #e2e8f0; }
.dash-host-head .section-title { color: #fff; margin: 0.25rem 0 0.75rem; }
.dash-host-body { margin-top: 0.5rem; }
.dash-widget {
  padding: 1rem;
  border-radius: var(--radius-card);
  border: 1px solid color-mix(in srgb, #fff 12%, transparent);
  background: color-mix(in srgb, #000 22%, transparent);
}
.dash-svg, .map-canvas, .spark, .doc-scan-svg {
  width: 100%; max-height: 22rem; display: block;
  border-radius: 0.4rem; margin-top: 0.75rem;
  background: #0f172a;
}
.map-canvas { max-height: none; height: auto; cursor: crosshair; }
.toggle-row, .chip-row {
  display: flex; flex-wrap: wrap; gap: 0.4rem; margin: 0.5rem 0;
  align-items: center;
}
.filter-btn {
  font: inherit; cursor: pointer;
  padding: 0.35rem 0.7rem; border-radius: 999px;
  border: 1px solid color-mix(in srgb, #fff 18%, transparent);
  background: transparent; color: #e2e8f0; font-size: 0.8rem;
}
.filter-btn[aria-pressed="true"] {
  background: color-mix(in srgb, var(--color-accent) 28%, transparent);
  border-color: var(--color-accent);
  color: #fff;
}
.metric-grid.light div {
  background: color-mix(in srgb, #fff 6%, transparent);
}
.dash-table {
  width: 100%; border-collapse: collapse; font-size: 0.85rem; margin-top: 0.75rem;
}
.dash-table th, .dash-table td {
  text-align: left; padding: 0.4rem 0.5rem;
  border-bottom: 1px solid color-mix(in srgb, #fff 10%, transparent);
}
.dash-table th { color: #94a3b8; font-weight: 600; font-size: 0.75rem; text-transform: uppercase; }
.status-reconciled { color: #34d399; }
.status-variance { color: #f87171; }
.status-pending { color: #fbbf24; }
.slider-label {
  display: grid; gap: 0.35rem; margin: 0.6rem 0; font-size: 0.85rem;
}
.slider-label input[type="range"] { width: 100%; }
.split-view { display: grid; grid-template-columns: 1fr 1fr; gap: 0.75rem; margin-top: 0.75rem; }
.ledger-list { list-style: none; margin: 0; padding: 0; display: grid; gap: 0.5rem; }
.ledger-item {
  display: grid; grid-template-columns: auto 1fr; gap: 0.75rem;
  padding: 0.6rem; border-radius: 0.4rem;
  border: 1px solid color-mix(in srgb, #fff 10%, transparent);
}
.intake-area {
  width: 100%; min-height: 5rem; font: inherit; padding: 0.6rem;
  border-radius: 0.4rem; border: 1px solid color-mix(in srgb, #fff 14%, transparent);
  background: color-mix(in srgb, #000 30%, transparent); color: #e2e8f0;
}

/* Flow field — full footer backdrop (Next density 240 / inset-0) */
.flow-field-wrap {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  overflow: hidden;
  border: 0;
  background: transparent;
}
.flow-canvas { width: 100%; height: 100%; display: block; }

/* Command panels */
.command-panel { margin: 1rem 0; }
.command-list { list-style: none; margin: 0.75rem 0 0; padding: 0; display: grid; gap: 0.75rem; }
.command-list li {
  padding: 0.75rem;
  border-radius: 0.5rem;
  border: 1px solid color-mix(in srgb, #fff 12%, transparent);
  background: color-mix(in srgb, #000 18%, transparent);
}
.fleet-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(7rem, 1fr));
  gap: 0.5rem;
  margin-top: 0.75rem;
}
.fleet-node {
  padding: 0.5rem;
  border-radius: 0.4rem;
  border: 1px solid color-mix(in srgb, #fff 12%, transparent);
  display: grid; gap: 0.25rem;
}
.fleet-bar {
  height: 0.35rem; border-radius: 999px;
  background: color-mix(in srgb, #fff 12%, transparent); overflow: hidden;
}
.fleet-fill {
  height: 100%;
  background: linear-gradient(90deg, #10b981, #3b82f6);
}
.fleet-lo { width: 35%; }
.fleet-mid { width: 62%; }
.fleet-hi { width: 88%; }

/* Consult modal */
.consult-modal {
  position: fixed; inset: 0; z-index: 90;
  display: grid; place-items: center;
}
.consult-backdrop {
  position: absolute; inset: 0; border: 0; padding: 0;
  background: color-mix(in srgb, #0f172a 50%, transparent);
  cursor: pointer;
}
.consult-panel {
  position: relative; z-index: 1;
  width: min(40rem, 94vw);
  max-height: min(90svh, 48rem);
  overflow: auto;
  padding: 1.25rem;
  border-radius: var(--radius-card);
  background: var(--color-bg);
  border: 1px solid var(--color-border);
  box-shadow: var(--shadow-float);
}
.consult-head {
  display: flex; justify-content: space-between; align-items: center;
  margin-bottom: 0.75rem;
}
.consult-body { margin-top: 0.5rem; }
button.nav-cta {
  background: none; border: 0; font: inherit; cursor: pointer;
  color: var(--color-accent-strong); font-weight: 600;
}

/* Login */
.login-form { margin: 0; text-align: left; }

.login-otp {
  letter-spacing: 0.28em;
  text-align: center;
  font-family: var(--font-mono);
  font-size: 1.15rem;
}
.login-lede {
  margin: 0 0 0.35rem;
  font-size: 0.75rem;
  line-height: 1.45;
}
.login-sep {
  border: 0; border-top: 1px solid color-mix(in srgb, #fff 14%, transparent);
  margin: 1.25rem 0;
}
.portal-login .form-stack label { color: #e2e8f0; }
.portal-login .form-stack input {
  background: color-mix(in srgb, #000 30%, transparent);
  border-color: color-mix(in srgb, #fff 16%, transparent);
  color: #fff;
}

/* ── Marketing chrome (Next-aligned) ───────────────────────────────────── */
.skip-link {
  position: absolute; left: -9999px; top: 0; z-index: 100;
  background: var(--color-bg); padding: 0.5rem 1rem;
}
.skip-link:focus { left: 0.5rem; top: 0.5rem; }
.mkt-header {
  position: sticky; top: 0; z-index: 50;
  border-bottom: 1px solid var(--color-border);
  background: color-mix(in srgb, var(--color-bg) 72%, transparent);
}
.mkt-nav {
  max-width: 80rem; margin: 0 auto;
  height: 4rem; display: flex; align-items: center; justify-content: space-between;
  gap: 1rem; padding: 0 1.25rem;
}
.mkt-pill-nav {
  list-style: none; margin: 0; padding: 0.35rem;
  display: none; gap: 0.25rem;
  border: 1px solid color-mix(in srgb, var(--color-border) 70%, transparent);
  border-radius: 999px; background: color-mix(in srgb, var(--color-panel) 60%, transparent);
}
@media (min-width: 768px) {
  .mkt-pill-nav { display: flex; }
  .mkt-menu-toggle { display: none !important; }
  .mkt-nav-actions { display: flex !important; }
}
/* Marketing nav pills — sentence case (do not uppercase) */
.mkt-pill-nav .pill {
  position: relative; overflow: hidden;
  display: block; padding: 0.5rem 1.25rem; border-radius: 999px;
  font-size: 0.875rem; font-weight: 500; color: var(--color-text-muted);
  text-transform: none; letter-spacing: normal;
}
.mkt-pill-nav .pill.active, .mkt-pill-nav .pill:hover {
  background: var(--color-bg); color: var(--color-text);
  box-shadow: 0 2px 10px rgba(0,0,0,0.08);
}
.mkt-nav-actions { display: none; align-items: center; gap: 0.5rem; }
.btn-sm { padding: 0.4rem 0.85rem; font-size: 0.8125rem; }
/* Same box as Schedule a consult — ghost/outline, not the stubby btn-sm Login. */
.mkt-nav-actions .btn,
.mkt-mobile-actions .mkt-login-btn,
.mkt-login-btn {
  box-sizing: border-box;
  min-height: 2.5rem;
  padding: 0.625rem 1.125rem;
  font-size: 0.9375rem;
  font-weight: 600;
  line-height: 1.25;
}
.mkt-nav-actions .btn-ghost,
.mkt-login-btn {
  background: transparent;
  border: 1px solid var(--color-border);
  color: var(--color-text);
}
.mkt-nav-actions .btn-ghost:hover,
.mkt-login-btn:hover {
  border-color: var(--color-text);
}
.mkt-menu-toggle {
  display: inline-flex; width: 2.25rem; height: 2.25rem;
  align-items: center; justify-content: center;
  border: 1px solid var(--color-border); border-radius: 0.4rem;
  background: transparent; font-size: 1.1rem; cursor: pointer;
}
.mkt-mobile { border-top: 1px solid var(--color-border); background: var(--color-bg); }
.mkt-mobile ul { list-style: none; margin: 0 auto; padding: 1rem 1.25rem; max-width: 80rem; }
.mkt-mobile a { display: block; padding: 0.5rem 0.75rem; color: var(--color-text-muted); }
.mkt-mobile-actions { display: flex; gap: 0.5rem; margin-top: 0.75rem; }

.mkt-footer {
  position: relative; overflow: hidden;
  border-top: 1px solid var(--color-border);
  background: var(--color-panel); color: var(--color-text-muted);
}
.mkt-footer-flow { position: absolute; inset: 0; opacity: 0.55; pointer-events: none; }
.mkt-footer-flow-fade {
  position: absolute; inset: 0;
  background: linear-gradient(to bottom, transparent 55%, var(--color-panel) 95%);
}
.mkt-footer-flow-scrub {
  position: absolute; inset: 0;
  background: radial-gradient(80% 70% at 16% 10%, var(--color-bg), transparent 55%);
}
.mkt-footer-inner { position: relative; max-width: 80rem; margin: 0 auto; padding: 3rem 1.25rem; }
.mkt-footer-cta {
  display: flex; flex-wrap: wrap; gap: 1.25rem;
  align-items: center; justify-content: space-between;
  margin-bottom: 2.5rem;
}
.mkt-footer-h2 {
  margin: 0; font-family: var(--font-display);
  font-size: clamp(1.35rem, 3vw, 1.75rem); font-weight: 700; color: var(--color-text);
}
.mkt-footer-grid {
  display: flex; flex-wrap: wrap; gap: 2rem; justify-content: space-between;
}
.mkt-footer-brand { max-width: 18rem; }
.mkt-footer-cols {
  display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 1.5rem;
}
.footer-heading {
  margin: 0 0 0.5rem; font-size: 0.75rem; text-transform: uppercase;
  letter-spacing: 0.08em; color: var(--color-text-faint);
}
.mkt-footer-cols ul { list-style: none; margin: 0; padding: 0; }
.mkt-footer-cols a { color: var(--color-text-muted); font-size: 0.9rem; }
.mkt-footer-cols a:hover { color: var(--color-text); }
.footer-copy { margin-top: 2rem; }

/* Hero stage — full-bleed ambient like Next HeroDotStage */
.hero-stage {
  position: relative; min-height: 92svh;
  display: flex; flex-direction: column; overflow: hidden;
  border-bottom: 1px solid var(--color-border);
}
/* Match Next contact/about short stage — title sits mid/lower, form below fold */
.hero-stage-short {
  min-height: min(72svh, 640px);
  justify-content: flex-end;
}
.hero-stage-short .hero-stage-copy {
  padding-bottom: 4rem;
  padding-top: 2rem;
}
/* Contact: full 92svh like Next HeroDotStage — booking card below the fold */
.hero-stage-contact {
  min-height: 92svh;
  justify-content: flex-end;
}
.hero-stage-contact .hero-stage-copy {
  padding-bottom: clamp(3rem, 8vh, 5rem);
  padding-top: 1.5rem;
}
/* Process: Next min-h-[50svh] */
.hero-stage-process {
  min-height: 50svh;
  justify-content: flex-end;
}
.hero-stage-process .hero-stage-copy {
  padding-bottom: 2.5rem;
}
/* Legal (privacy/terms): Next min-h-[40svh] */
.hero-stage-legal {
  min-height: 40svh;
  justify-content: flex-end;
}
.hero-stage-legal .hero-stage-copy {
  padding-bottom: 2.5rem;
}
.hero-stage-bg { position: absolute; inset: 0; pointer-events: none; overflow: hidden; }
.hero-stage-gradient {
  position: absolute; inset: 0;
  background: linear-gradient(180deg, #f8fafc 0%, #eef4fb 50%, #dbeafe 100%);
}
.hero-cloud {
  position: absolute !important;
  inset: 0 !important;
  margin: 0 !important;
  width: 100% !important;
  height: 100% !important;
  max-width: none !important;
}
.hero-canvas {
  display: block !important;
  width: 100% !important;
  height: 100% !important;
  max-width: none !important;
  border: 0 !important;
  border-radius: 0 !important;
  background: transparent !important;
  background-color: transparent !important;
}
.hero-fallback-dots {
  position: absolute; inset: 0;
  background-image:
    radial-gradient(circle, #10b981 1.15px, transparent 1.55px),
    radial-gradient(circle, #0ea5e9 1.15px, transparent 1.55px),
    radial-gradient(circle, #2563eb 1.15px, transparent 1.55px);
  background-size: 9px 11px, 11px 9px, 10px 12px;
  background-position: 0 0, 4px 5px, 7px 2px;
  opacity: 0.55;
  mask-image: radial-gradient(ellipse at center, black 38%, transparent 78%);
  -webkit-mask-image: radial-gradient(ellipse at center, black 38%, transparent 78%);
  pointer-events: none;
  transition: opacity 0.25s ease;
}
.hero-cloud[data-hero="ready"] .hero-fallback-dots {
  opacity: 0;
}
.hero-stage-scrim {
  /* `inset-x` is a Tailwind class name, not a CSS property. As a declaration it
     is invalid and the whole line was dropped, so the scrim collapsed to zero
     width and never painted on home / contact / about / process. */
  position: absolute; left: 0; right: 0; bottom: 0; height: 11rem;
  background: linear-gradient(to top, #f6f9fd, rgba(246,249,253,0.6), transparent);
}
.hero-stage-copy {
  position: relative; margin-top: auto;
  max-width: 48rem; margin-left: auto; margin-right: auto;
  padding: 1.5rem 1.25rem 3.5rem; text-align: center;
  z-index: 1;
}
@media (min-width: 640px) {
  .hero-stage-copy { padding: 1.5rem 2rem 5rem; }
}
.hero-stage-h1 {
  margin: 1rem auto 0; font-family: var(--font-display);
  font-size: clamp(2rem, 5vw, 3.5rem); font-weight: 700;
  letter-spacing: -0.03em; line-height: 1.1;
}
.hero-stage-sub { margin: 1.25rem auto 0; max-width: 36rem; line-height: 1.6; }
.cta-row.center { justify-content: center; }
.sr-only {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0,0,0,0); white-space: nowrap; border: 0;
}

/* Portal workspace shell */
.portal-workspace {
  display: flex; min-height: 100svh;
  background: #0b1220; color: #e2e8f0;
}
.portal-sidebar {
  width: 15rem; flex-shrink: 0;
  display: flex; flex-direction: column;
  background: var(--color-chrome); color: #cbd5e1;
  border-right: 1px solid color-mix(in srgb, #fff 10%, transparent);
}
.portal-side-brand {
  display: flex; align-items: center; gap: 0.65rem;
  padding: 1rem 1.25rem;
  border-bottom: 1px solid color-mix(in srgb, #fff 10%, transparent);
}
.portal-side-title { margin: 0; font-family: var(--font-display); font-weight: 700; color: #fff; font-size: 0.9rem; }
.portal-side-sub { margin: 0; font-size: 0.65rem; letter-spacing: 0.08em; text-transform: uppercase; color: #64748b; }
.portal-side-nav {
  flex: 1; overflow: auto; padding: 0.75rem;
  display: flex; flex-direction: column; gap: 0.2rem;
}
.side-link {
  display: flex; align-items: center; gap: 0.75rem;
  padding: 0.5rem 0.75rem; border-radius: 0.5rem;
  font-size: 0.875rem; color: #94a3b8; text-align: left;
  background: transparent; border: 0; width: 100%; cursor: pointer;
  font: inherit; text-decoration: none;
}
.side-link:hover { background: color-mix(in srgb, #fff 5%, transparent); color: #e2e8f0; }
.side-link.active { background: color-mix(in srgb, #fff 10%, transparent); color: #fff; }
.side-icon {
  display: inline-flex; width: 1rem; height: 1rem;
  align-items: center; justify-content: center;
  font-size: 0.85rem; opacity: 0.85; flex-shrink: 0;
}
.portal-side-foot {
  padding: 0.75rem; border-top: 1px solid color-mix(in srgb, #fff 10%, transparent);
  display: grid; gap: 0.5rem;
}
.side-foot-link { color: #94a3b8; }
.portal-content, .portal-login-main { flex: 1; min-width: 0; overflow: auto; }
.portal-content { background: #f8fafc; }
.portal-login-shell {
  min-height: 100svh;
  background: #f8fafc;
  position: relative;
}
.portal-login-shell > .portal-login-main {
  min-height: 100svh;
  overflow: hidden;
  position: relative;
}
.workspace-page { padding: 1.5rem; color: #e2e8f0; }
.workspace-page.workspace-light {
  color: var(--color-text);
  max-width: 72rem;
  margin: 0 auto;
}
.workspace-header { margin-bottom: 1.25rem; }
.workspace-header-stack { display: flex; flex-direction: column; gap: 1rem; }
.workspace-header-row {
  display: flex; flex-wrap: wrap; align-items: flex-end; justify-content: space-between; gap: 0.75rem;
}
.workspace-header-main { min-width: 0; }
.back-link {
  display: inline-flex; align-items: center; gap: 0.35rem;
  font-size: 0.875rem; color: var(--color-text-muted); text-decoration: none;
}
.back-link:hover { color: var(--color-text); }
.workspace-h1 {
  margin: 0.35rem 0 0; font-family: var(--font-display);
  font-size: 1.5rem; font-weight: 700; letter-spacing: -0.02em; color: #fff;
}
.workspace-light .workspace-h1 { color: var(--color-text); }
.workspace-light .muted { color: var(--color-text-muted); }
.workspace-light .eyebrow { color: var(--color-accent); }
.label-caps {
  margin: 1rem 0 0.5rem;
  font-size: 0.625rem; text-transform: uppercase; letter-spacing: 0.08em;
}
.badge {
  display: inline-flex; align-items: center; gap: 0.35rem;
  padding: 0.25rem 0.65rem; border-radius: 999px; font-size: 0.75rem;
  border: 1px solid color-mix(in srgb, #fff 14%, transparent);
  background: color-mix(in srgb, #000 20%, transparent);
  white-space: nowrap;
}
.workspace-light .badge {
  border-color: var(--color-border);
  background: #fff;
  color: var(--color-text-muted);
}
.badge-warn {
  border-color: color-mix(in srgb, #f59e0b 35%, transparent);
  background: color-mix(in srgb, #f59e0b 8%, transparent);
  color: #b45309;
}
.badge-live {
  border-color: color-mix(in srgb, #34d399 40%, transparent);
  background: color-mix(in srgb, #34d399 10%, transparent);
  color: #059669;
}
/* `statusTone` in src/app/(portal)/portal/apps/[slug]/page.tsx:31 has a danger
   arm. No demo app status reaches it today (they are only Active/Processing),
   but the tone map is ported whole, so the rule has to exist. */
.badge-danger {
  border-color: color-mix(in srgb, #f87171 40%, transparent);
  background: color-mix(in srgb, #f87171 10%, transparent);
  color: #b91c1c;
}
.status-dot {
  width: 0.4rem; height: 0.4rem; border-radius: 999px;
  background: #94a3b8; flex-shrink: 0;
}
.status-dot.live { background: #10b981; box-shadow: 0 0 0 2px color-mix(in srgb, #10b981 25%, transparent); }
.status-dot.warn { background: #f59e0b; }
.dash-map-embed {
  margin: 0; padding: 0; border: 0; background: transparent;
}
.dash-map-embed .map-canvas {
  display: block; width: 100%; height: min(56vh, 520px);
  border-radius: 0.875rem; background: #0b1220;
  cursor: grab;
}
.dash-map-embed.dash-widget {
  border: 0; background: transparent; padding: 0;
}
.mesh-svg { width: 100%; height: min(56vh, 480px); margin: 0; border-radius: 0.875rem; }
.mesh-toolbar {
  position: absolute; z-index: 2; top: 0.75rem; left: 0.75rem;
  display: flex; gap: 0.35rem;
}
.dash-map-embed { position: relative; }
.mesh-sliders {
  position: absolute; bottom: 0.5rem; left: 0.75rem; right: 0.75rem;
  display: flex; gap: 0.75rem; opacity: 0.55;
}
.mesh-sliders input[type=range] { width: 100%; }
.telemetry-bar { margin: 1rem 0 1.25rem; }
.telemetry-bar-joined {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 1px;
  margin: 1.5rem 0 1.25rem;
  overflow: hidden;
  border-radius: 0.875rem;
  border: 1px solid var(--color-border);
  background: var(--color-border);
}
@media (min-width: 768px) {
  .telemetry-bar-joined { grid-template-columns: repeat(4, 1fr); }
}
.tele-cell { background: #fff; padding: 1.25rem; }
.tele-k {
  margin: 0;
  font-family: var(--font-mono);
  font-size: 0.625rem;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--color-text-faint);
}
.tele-v {
  margin: 0.25rem 0 0;
  font-family: var(--font-display);
  font-size: 1.5rem;
  font-weight: 700;
  color: var(--color-text);
  font-variant-numeric: tabular-nums;
}
.tele-v.sm { font-size: 1.15rem; }
.faint-num { color: var(--color-text-faint); }
.panel-card {
  background: #fff;
  border: 1px solid var(--color-border);
  border-radius: 0.875rem;
  padding: 1.25rem;
  box-shadow: var(--shadow-card, 0 1px 2px rgb(0 0 0 / 0.04));
  margin-bottom: 1.25rem;
}
.panel-head {
  display: flex; align-items: center; justify-content: space-between;
  margin-bottom: 1rem; gap: 0.75rem;
}
.panel-title {
  margin: 0; font-size: 0.875rem; font-weight: 600; color: var(--color-text);
}
.cmd-two-col {
  display: grid; gap: 1.25rem;
  grid-template-columns: 1fr;
  margin-bottom: 1.25rem;
}
.cmd-split {
  display: grid; gap: 1.25rem;
  grid-template-columns: 1fr;
}
@media (min-width: 1024px) {
  .cmd-two-col { grid-template-columns: 1fr 1fr; }
  .cmd-split { grid-template-columns: 1.4fr 1fr; }
}
.fleet-status-row { display: flex; gap: 1.5rem; align-items: flex-start; }
.fleet-counts { display: grid; gap: 0.75rem; min-width: 4rem; }
.fleet-dots-wrap { flex: 1; min-width: 0; }
.fleet-dots {
  display: grid;
  grid-template-columns: repeat(10, 1fr);
  gap: 0.375rem;
}
.fleet-dot {
  width: 0.625rem; height: 0.625rem; border-radius: 0.15rem;
  background: var(--color-border);
}
.fleet-dot.on { background: var(--color-telemetry); }
.util-row {
  display: flex; justify-content: space-between; align-items: center;
  margin-top: 1rem; font-size: 0.75rem;
}
.util-bar {
  margin-top: 0.375rem; height: 0.5rem; border-radius: 999px;
  background: var(--color-border); overflow: hidden;
}
.util-fill {
  height: 100%;
  background: linear-gradient(90deg, var(--color-accent), var(--color-telemetry));
  border-radius: 999px;
}
.health-grid {
  display: grid; gap: 1rem 2rem;
  grid-template-columns: repeat(2, 1fr);
}
@media (min-width: 640px) {
  .health-grid { grid-template-columns: repeat(4, 1fr); }
}
.node-load-grid {
  display: grid;
  grid-template-columns: repeat(10, 1fr);
  gap: 0.375rem;
}
.node-load-grid.wide { grid-template-columns: repeat(10, 1fr); }
.node-cell {
  display: flex; align-items: center; justify-content: center;
  height: 2.25rem; border-radius: 0.375rem;
  font-family: var(--font-mono); font-size: 0.5625rem;
}
.node-cell.lo { background: #0f172a; color: #94a3b8; }
.node-cell.mid { background: color-mix(in srgb, var(--color-telemetry) 40%, transparent); color: var(--color-text); }
.node-cell.hi { background: var(--color-telemetry); color: #0b1220; }
.active-apps { list-style: none; margin: 0; padding: 0; display: grid; gap: 0.625rem; }
.active-app-row {
  display: flex; align-items: center; justify-content: space-between; gap: 0.75rem;
  padding: 0.75rem; border: 1px solid var(--color-border); border-radius: 0.5rem;
}
.app-row-name { margin: 0; font-size: 0.875rem; font-weight: 500; }
.app-row-meta { display: flex; align-items: center; gap: 0.75rem; flex-shrink: 0; }
.health-ok { color: var(--color-telemetry-strong); }
.health-warn { color: #b45309; }
.health-bad { color: #dc2626; }
.launch-x {
  display: inline-flex; width: 1.75rem; height: 1.75rem;
  align-items: center; justify-content: center;
  border-radius: 0.375rem; border: 1px solid var(--color-border);
  color: var(--color-text-faint); text-decoration: none;
}
.launch-x:hover { border-color: var(--color-accent); color: var(--color-accent); }
.latency-svg { width: 100%; height: auto; display: block; }
.chart-label { fill: var(--color-text-faint); font-family: var(--font-mono); font-size: 8px; }
.xs { font-size: 0.75rem; }
.demo-notice {
  display: flex; align-items: flex-start; gap: 0.5rem;
  margin: 0 0 1.25rem; padding: 0.5rem 0.75rem;
  border-radius: 0.5rem;
  border: 1px solid color-mix(in srgb, #f59e0b 30%, transparent);
  background: color-mix(in srgb, #f59e0b 5%, transparent);
  color: #b45309; font-size: 0.6875rem;
}
.stat-tiles {
  display: grid; gap: 1.25rem;
  grid-template-columns: 1fr;
  margin-bottom: 1.5rem;
}
@media (min-width: 640px) {
  .stat-tiles { grid-template-columns: repeat(3, 1fr); }
}
.stat-tile {
  background: #fff; border: 1px solid var(--color-border);
  border-radius: 0.875rem; padding: 1.25rem;
}
.timeline {
  list-style: none; margin: 0; padding: 0 0 0 1.5rem;
  border-left: 1px solid var(--color-border);
  display: grid; gap: 1rem;
}
.timeline-item { position: relative; }
.timeline-item::before {
  content: "";
  position: absolute; left: -1.9rem; top: 1.25rem;
  width: 0.625rem; height: 0.625rem; border-radius: 999px;
  background: var(--color-accent);
  border: 2px solid #f8fafc;
}
.timeline-card { margin-bottom: 0; }
.timeline-title {
  margin: 0.5rem 0 0.35rem;
  font-family: var(--font-display); font-size: 1rem; font-weight: 600;
  color: var(--color-text);
}
.pill-row { display: flex; flex-wrap: wrap; align-items: center; gap: 0.5rem; }
/* Status/badge pills only — do NOT override marketing .mkt-pill-nav .pill */
.pill-row .pill,
.stat-tile .pill,
.timeline-card .pill,
.doc-card .pill,
.panel-card .pill,
.light-table .pill {
  display: inline-flex; align-items: center;
  padding: 0.125rem 0.625rem; border-radius: 999px;
  font-family: var(--font-mono); font-size: 0.625rem;
  text-transform: uppercase; letter-spacing: 0.06em;
  border: 1px solid var(--color-border);
  background: var(--color-panel, #f1f5f9);
  color: var(--color-text-muted);
}
.pill-milestone {
  border-color: color-mix(in srgb, var(--color-accent) 40%, transparent);
  background: color-mix(in srgb, var(--color-accent) 10%, transparent);
  color: var(--color-accent-strong, #1d4ed8);
}
.pill-delivery {
  border-color: color-mix(in srgb, var(--color-telemetry) 40%, transparent);
  background: color-mix(in srgb, var(--color-telemetry) 10%, transparent);
  color: var(--color-telemetry-strong);
}
.pill-sent {
  border-color: color-mix(in srgb, var(--color-accent) 40%, transparent);
  background: color-mix(in srgb, var(--color-accent) 10%, transparent);
  color: var(--color-accent-strong, #1d4ed8);
}
.pill-paid {
  border-color: color-mix(in srgb, var(--color-telemetry) 40%, transparent);
  background: color-mix(in srgb, var(--color-telemetry) 10%, transparent);
  color: var(--color-telemetry-strong);
}
.pill-overdue {
  border-color: color-mix(in srgb, #ef4444 40%, transparent);
  background: color-mix(in srgb, #ef4444 10%, transparent);
  color: #b91c1c;
}
.table-wrap { overflow-x: auto; }
.light-table { width: 100%; min-width: 42rem; border-collapse: collapse; text-align: left; font-size: 0.875rem; }
.light-table th {
  padding: 0.5rem 1rem 0.5rem 0;
  font-family: var(--font-mono); font-size: 0.625rem; font-weight: 400;
  text-transform: uppercase; letter-spacing: 0.06em;
  color: var(--color-text-faint);
  border-bottom: 1px solid var(--color-border);
}
.light-table td {
  padding: 0.75rem 1rem 0.75rem 0;
  border-bottom: 1px solid color-mix(in srgb, var(--color-border) 60%, transparent);
  vertical-align: top;
}
.light-table .num { text-align: right; }
.block { display: block; }
.lock-note { margin-top: 1rem; }
.btn-sm { font-size: 0.75rem; padding: 0.25rem 0.6rem; }
.profile-grid {
  display: grid; gap: 1rem 2rem;
  grid-template-columns: 1fr;
}
@media (min-width: 640px) {
  .profile-grid { grid-template-columns: 1fr 1fr; }
}
.profile-grid dd { margin: 0.15rem 0 0; font-size: 0.875rem; font-weight: 500; }
.key-list-plain { list-style: none; margin: 0; padding: 0; display: grid; gap: 0.75rem; }
.key-list-plain li { display: flex; flex-wrap: wrap; gap: 0.75rem; align-items: baseline; }
.app-launch-grid {
  list-style: none; margin: 2.5rem 0 0; padding: 0;
  display: grid; gap: 1.25rem;
  grid-template-columns: 1fr;
}
@media (min-width: 640px) {
  .app-launch-grid { grid-template-columns: repeat(2, 1fr); }
}
@media (min-width: 1024px) {
  .app-launch-grid { grid-template-columns: repeat(3, 1fr); }
}
.app-launch-card {
  display: block; padding: 1.25rem;
  border-radius: 0.875rem;
  border: 1px solid var(--color-border);
  background: #fff;
  box-shadow: var(--shadow-card, 0 1px 2px rgb(0 0 0 / 0.04));
  text-decoration: none; color: inherit;
  transition: border-color 0.15s ease;
}
.app-launch-card:hover { border-color: var(--color-accent); }
.app-card-top {
  display: flex; align-items: center; justify-content: space-between;
}
.app-icon {
  display: inline-flex; width: 2.25rem; height: 2.25rem;
  align-items: center; justify-content: center;
  border-radius: 0.5rem; background: var(--color-panel, #f1f5f9);
  color: var(--color-accent); font-size: 1.05rem;
}
.app-open { color: var(--color-text-faint); font-size: 0.875rem; }
.app-code-chip {
  font-size: 0.625rem !important;
  color: var(--color-text-faint) !important;
  border: 0 !important;
  background: transparent !important;
  padding: 0 !important;
}
.activity-clock { opacity: 0.7; }
.app-card-title {
  margin: 1rem 0 0.35rem;
  font-family: var(--font-display); font-size: 1rem; font-weight: 600;
  color: var(--color-text); line-height: 1.3;
}
.app-card-blurb {
  margin: 0; font-size: 0.875rem;
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical;
  overflow: hidden;
}
.app-card-meta { margin-top: 1rem; display: flex; gap: 0.5rem; flex-wrap: wrap; }
.app-activity { margin: 0.75rem 0 0; font-size: 0.625rem; }
.doc-list { list-style: none; margin: 0; padding: 0; display: grid; gap: 1rem; }
.doc-card { margin-bottom: 0; }

/* Projects / work page density */
.flagship-grid { margin-top: 1.5rem; }
.flagship-card h3 { font-size: 1.05rem; line-height: 1.3; }
.flagship-meta {
  display: flex; align-items: center; justify-content: space-between; gap: 0.75rem;
  margin-bottom: 0.75rem;
}
.chip-row {
  list-style: none; margin: 1rem 0 1.5rem; padding: 0;
  display: flex; flex-wrap: wrap; gap: 0.5rem;
}
.chip {
  border: 1px solid var(--color-border);
  background: var(--color-panel, #f1f5f9);
  border-radius: 999px;
  padding: 0.25rem 0.75rem;
  font-size: 0.75rem;
  color: var(--color-text-muted);
}
.bullet-list {
  margin: 0.75rem 0;
  padding-left: 1.1rem;
  font-size: 0.875rem;
}
.prior-grid { margin-top: 1.5rem; }
.proof-grid {
  display: grid; gap: 1.25rem;
  grid-template-columns: 1fr;
  margin-top: 1.5rem;
}
@media (min-width: 1024px) {
  .proof-grid { grid-template-columns: 1fr 1fr; }
}
.modality-grid {
  list-style: none; margin: 1rem 0 0; padding: 0;
  display: grid; grid-template-columns: 1fr 1fr; gap: 0.75rem;
}
.modality-cell {
  border: 1px solid var(--color-border);
  background: var(--color-panel, #f1f5f9);
  border-radius: 0.5rem;
  padding: 0.75rem 1rem;
  font-size: 0.875rem; font-weight: 500;
}
.perf-stats {
  display: flex; flex-wrap: wrap; gap: 1.5rem 2.5rem;
  margin: 1rem 0;
}
.perf-stats dt { margin: 0; }
.perf-stats dd { margin: 0.25rem 0 0; font-size: 0.875rem; }
.display-stat {
  font-family: var(--font-display);
  font-size: 2rem; font-weight: 700;
  color: var(--color-text);
  font-variant-numeric: tabular-nums;
}

/* Footer trust logos (Next TrustLogos) */
.mkt-trust-logos { display: grid; gap: 1.5rem; }
.trust-tier .footer-heading { margin-bottom: 0.75rem; }
.trust-marks {
  list-style: none; margin: 0; padding: 0;
  display: flex; flex-wrap: wrap; align-items: center; gap: 1rem 1.5rem;
}
.trust-logo { width: auto; opacity: 0.85; object-fit: contain; }
.trust-logo.stack { height: 1.25rem; }
.brand-ai { font-weight: 500; }

/* Projects drawer + service cards */
.flagship-btn {
  width: 100%; text-align: left; cursor: pointer;
  font: inherit; color: inherit;
  background: #fff; border: 1px solid var(--color-border);
}
.flagship-btn:hover { border-color: var(--color-accent); }
.sector-pill {
  display: inline-flex; width: fit-content;
  padding: 0.125rem 0.5rem; border-radius: 999px;
  font-family: var(--font-mono); font-size: 0.625rem;
  text-transform: uppercase; letter-spacing: 0.06em;
  border: 1px solid color-mix(in srgb, var(--color-accent) 30%, transparent);
  background: color-mix(in srgb, var(--color-accent) 10%, transparent);
  color: var(--color-accent-strong, #1d4ed8);
}
.open-arrow { color: var(--color-text-faint); }
.outcome-block {
  margin-top: 1.25rem; padding-top: 1rem;
  border-top: 1px solid var(--color-border);
}
.outcome-text { margin: 0.25rem 0 0; font-size: 0.875rem; font-weight: 500; }
.explore-btn {
  margin-top: 1rem;
  display: inline-flex; align-items: center; gap: 0.35rem;
  padding: 0.25rem 0.625rem; border-radius: 0.375rem;
  border: 1px solid color-mix(in srgb, var(--color-accent) 40%, transparent);
  background: transparent; color: var(--color-accent);
  font-size: 0.75rem; cursor: pointer;
}
.demo-teaser {
  margin-top: 1rem; padding-top: 0.75rem;
  border-top: 1px solid var(--color-border);
}
.service-card.service-open { grid-column: 1 / -1; }
.service-expand {
  margin-top: 1rem; padding-top: 1rem;
  border-top: 1px solid var(--color-border);
}
.service-head {
  display: flex; align-items: center; justify-content: space-between;
}
.service-icon {
  display: inline-flex; width: 2.5rem; height: 2.5rem;
  align-items: center; justify-content: center;
  border-radius: 0.5rem; border: 1px solid var(--color-border);
  color: var(--color-accent);
}
.bullet-list .check { color: var(--color-telemetry-strong); margin-right: 0.35rem; }
.drawer-root {
  position: fixed; inset: 0; z-index: 80;
  display: flex; justify-content: flex-end;
}
.drawer-backdrop {
  position: absolute; inset: 0;
  border: 0; padding: 0; cursor: pointer;
  background: rgb(15 23 42 / 0.45);
}
.drawer-panel {
  position: relative; z-index: 1;
  width: min(40rem, 100%);
  height: 100%; overflow: auto;
  background: #fff; color: var(--color-text);
  box-shadow: -8px 0 32px rgb(0 0 0 / 0.12);
  padding: 1rem 1.25rem 2rem;
}
.drawer-head {
  display: flex; align-items: center; justify-content: space-between;
  margin-bottom: 1rem;
}
.drawer-close {
  border: 1px solid var(--color-border); background: #fff;
  border-radius: 0.375rem; width: 2rem; height: 2rem; cursor: pointer;
}
.drawer-title { font-size: 1.35rem; margin: 0.35rem 0; }
.drawer-dash {
  margin: 1rem 0; min-height: 16rem;
  border: 1px solid var(--color-border); border-radius: 0.75rem;
  overflow: hidden; background: #0f172a;
}
.catalog-grid { margin-top: 1.25rem; }

/* Settings / HIPAA / keys */
.hipaa-row {
  display: flex; align-items: center; justify-content: space-between; gap: 1rem;
  margin-top: 1.25rem; padding: 0.75rem;
  border: 1px solid var(--color-border); border-radius: 0.5rem;
}
.hipaa-title { margin: 0; font-size: 0.875rem; font-weight: 500; }
.avatar {
  display: inline-flex; width: 1.5rem; height: 1.5rem;
  align-items: center; justify-content: center;
  border-radius: 999px; background: var(--color-panel, #f1f5f9);
  font-size: 0.65rem;
}
.key-toolbar { display: flex; justify-content: flex-end; margin-bottom: 0.75rem; }
.key-row {
  display: flex; align-items: flex-start; justify-content: space-between;
  gap: 1rem; padding: 0.75rem 0;
  border-bottom: 1px solid var(--color-border);
}
.key-name { margin: 0; font-size: 0.875rem; font-weight: 500; }
.key-actions { display: flex; gap: 0.35rem; flex-shrink: 0; }
.autopay-panel { margin-bottom: 1.25rem; }

/* Contact booking steps */
.booking-steps {
  list-style: none; margin: 0.75rem 0; padding: 0;
  display: flex; flex-wrap: wrap; gap: 0.75rem 1rem;
}
.booking-steps .step-on { color: var(--color-accent-strong, #1d4ed8); font-weight: 600; }
.topic-hint { display: block; font-size: 0.7rem; margin-top: 0.25rem; }
.section-kicker {
  margin: 1.5rem 0 0.75rem;
  font-size: 0.6875rem;
  text-transform: uppercase;
  letter-spacing: 0.06em;
}
.region-list { list-style: none; margin: 0; padding: 0; display: grid; gap: 0.75rem; }
.region-row {
  display: flex; align-items: center; justify-content: space-between; gap: 0.75rem;
  padding: 0.5rem 0;
  border-bottom: 1px solid var(--color-border);
}
/* The label + utilization meter that fills the region row. Same two rules as
   .fleet-dots-wrap, which this replaced; the zeroed .util-row margin drops the
   1rem the shared meter carries when it is the row's only child. */
.region-meter { flex: 1; min-width: 0; }
.region-meter .util-row { margin-top: 0; }
.doc-actions {
  display: flex; flex-wrap: wrap; gap: 0.75rem; align-items: center;
  margin-top: 0.75rem;
}
.pill-draft, .pill-due {
  border-color: var(--color-border);
  background: var(--color-panel, #f1f5f9);
}
/* Quote status tones — `quoteStatusTone` in src/components/portal/section-widgets.tsx:301.
   Accepted is telemetry green there, not the neutral panel it used to share
   with Draft. Expired is the amber roll gamma and iota land on. */
.pill-accepted {
  border-color: color-mix(in srgb, var(--color-telemetry) 30%, transparent);
  background: color-mix(in srgb, var(--color-telemetry) 10%, transparent);
  color: var(--color-telemetry-strong);
}
.pill-expired {
  border-color: color-mix(in srgb, #fcd34d 60%, transparent);
  background: color-mix(in srgb, #fffbeb 100%, transparent);
  color: #b45309;
}
.portal-login-page {
  min-height: 100svh; display: grid; place-items: center; padding: 2rem 1rem;
  position: relative; z-index: 2;
}
/* Next portal page: light shell; PacmanField clearRect is transparent.
   Maze canvas receives clicks; the login card (higher z) stays clickable. */
.pacman-login {
  position: relative;
  min-height: 100svh;
  background: #f8fafc;
  overflow: hidden;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 4rem 1.25rem;
  box-sizing: border-box;
}
.pacman-bg {
  position: absolute; inset: 0; opacity: 1; z-index: 0;
  pointer-events: auto;
}
.pacman-canvas {
  width: 100%; height: 100%; display: block;
  pointer-events: auto;
  cursor: default;
}
.portal-login-center {
  position: relative;
  z-index: 10;
  /* Shrink-wraps the card instead of tracking the viewport, so the countdown
     (absolutely positioned against this box) stays centred on the card and the
     card's measured width never depends on this wrapper. */
  width: auto;
  max-width: 100%;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  pointer-events: none;
}
/* Scoreboard HUD.
   `pacman_field.rs::measure_score_css` measures THIS element's border box and
   suppresses every pellet and wall dot whose tile centre falls inside it (plus
   6px), so the box is not just chrome — it is literally the hole punched in the
   maze. Two rules follow:
     1. The box must hug the visible mark. `width: max-content` keeps it
        shrink-wrapped as the score grows a digit, and is deliberately used
        instead of the automatic shrink-to-fit an absolutely positioned box
        already gets: shrink-to-fit is capped by the available width, which on a
        narrow viewport would let the flex row squeeze the fixed-size digit
        canvases and distort the glyphs. max-content never clamps.
     2. It must read as a panel, so the cleared band looks intended. Same glass
        recipe as `.login-card` — token border at 50%, translucent bg, backdrop
        blur, lifted shadow — with the radius stepped down for a chip this size,
        so the two floating surfaces belong to one UI. */
.swarm-score-corner {
  position: absolute; top: 1.5rem; right: 1.5rem; z-index: 5;
  pointer-events: none;
  box-sizing: border-box;
  width: max-content;
  /* Asymmetric on purpose: the last digit canvas still carries ~6px of its own
     dead space after the trim below, so an even padding would leave the right
     edge visibly airier than the left. */
  padding: 0.5rem 0.75rem 0.5rem 1rem;
  border-radius: 16px;
  border: 1px solid color-mix(in srgb, var(--color-border) 50%, transparent);
  background: color-mix(in srgb, var(--color-bg, #fff) 82%, transparent);
  box-shadow: 0 12px 28px -10px rgb(0 0 0 / 0.22), 0 1px 2px rgb(0 0 0 / 0.04);
  backdrop-filter: blur(40px);
  -webkit-backdrop-filter: blur(40px);
}
.swarm-score { display: flex; flex-direction: row; align-items: center; gap: 0.5rem; }
.swarm-score-label {
  font-family: var(--font-display, inherit);
  font-weight: 700;
  font-size: 1.25rem;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--text-muted, #94a3b8);
  white-space: nowrap;
}
.swarm-score-digits { display: flex; gap: 2px; align-items: center; }
/* gfx.rs draws a bold 42px glyph centred in a fixed 46x68 canvas, which leaves
   ~10px of dead space at each side and ~18px above and below the ink. Left
   alone that padding is what made the cleared band read as twice the height of
   "SCORE : 00120". Negative margins pull the boxes back to the ink without
   touching the backing store, so nothing is rescaled or clipped — the glyph and
   its glow still paint in full, they just stop reserving layout for air.
   `flex: 0 0 auto` keeps the canvases at their natural size in every case. */
.swarm-digit-canvas {
  width: 46px; height: 68px; display: block;
  flex: 0 0 auto;
  margin: -0.75rem -0.25rem;
  filter: drop-shadow(0 0 8px rgba(59, 130, 246, 0.5));
}
.swarm-countdown-wrap {
  position: absolute;
  top: -7rem;
  left: 50%;
  transform: translateX(-50%);
  width: 360px;
  height: 140px;
  pointer-events: none;
  z-index: 3;
}
.swarm-countdown-fade {
  transition: opacity 1s ease;
  opacity: 1;
}
.swarm-countdown-fade.is-empty { opacity: 0; }
.swarm-countdown-canvas {
  width: 360px; height: 140px; display: block;
  filter: drop-shadow(0 0 12px rgba(59, 130, 246, 0.8));
}
.app-code-chip {
  border-color: var(--color-border);
  background: var(--color-panel, #f1f5f9);
  color: var(--color-text-muted);
  font-size: 0.625rem;
}
/* Dashboard embed — no host chrome (Next AppInterface) */
.dash-host-body { min-height: 20rem; }
.dash-host { border: 1px solid var(--color-border); border-radius: 0.75rem; overflow: hidden; background: #0f172a; }
.login-brand {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  text-align: center;
  margin-bottom: 1.5rem;
}
.login-brand-row {
  display: flex; align-items: center; justify-content: center; gap: 1rem;
  width: 100%;
}
.login-brand-title {
  font-family: var(--font-display, inherit);
  font-size: 1.65rem; font-weight: 700; letter-spacing: -0.02em;
  color: var(--color-text);
}
.login-portal-label {
  margin: 0.35rem 0 0;
  font-size: 0.7rem;
  letter-spacing: 0.28em;
  text-transform: uppercase;
}
.login-portal-swarm {
  width: 100%;
  display: flex;
  justify-content: center;
  margin: 0.5rem 0 0;
  padding: 0 0.5rem;
  box-sizing: border-box;
  filter: drop-shadow(0 0 4px rgba(59, 130, 246, 0.4));
}
.swarm-static-text {
  display: block;
  pointer-events: none;
  flex-shrink: 0;
}
.login-wordmark-dot {
  width: 2.25rem; height: 2.25rem; margin: 0 auto;
  border-radius: 999px;
  background: radial-gradient(circle at 35% 35%, #60a5fa, #1d4ed8 70%);
  box-shadow: 0 0 18px rgba(59,130,246,0.45);
}
.login-brand-rule {
  width: 4rem; height: 1px; margin: 1rem auto;
  background: var(--color-border); opacity: 0.6;
}
/* Next login-terminal: p-10, rounded-[24px], max-w-md.
   The card holds ONE stable width per breakpoint rather than tracking the
   viewport: the Pac-Man maze measures this box live and rebuilds its cutout
   whenever the box changes, so a fluid width churns the maze on every resize
   tick. `max-width: 100%` is only a guard against large root font sizes —
   at every step below, the width already clears the page gutters. */
.login-card {
  width: 28rem;
  max-width: 100%;
  box-sizing: border-box;
  padding: 2.5rem;
  border-radius: 24px;
  border: 1px solid color-mix(in srgb, var(--color-border) 50%, transparent);
  background: color-mix(in srgb, var(--color-bg, #fff) 40%, transparent);
  box-shadow: 0 25px 50px -12px rgb(0 0 0 / 0.25);
  backdrop-filter: blur(40px);
  -webkit-backdrop-filter: blur(40px);
  color: var(--color-text);
  position: relative;
  z-index: 10;
  pointer-events: auto;
  display: flex;
  flex-direction: column;
  align-items: stretch;
  transition: box-shadow 500ms ease, border-color 500ms ease, transform 500ms ease;
}
.login-card::before {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: 24px;
  pointer-events: none;
  background: linear-gradient(to bottom, rgb(255 255 255 / 0.05), transparent);
}
.login-card:hover {
  border-color: color-mix(in srgb, var(--color-accent) 30%, var(--color-border));
  box-shadow: 0 0 40px -10px rgba(59, 130, 246, 0.3), 0 25px 50px -12px rgb(0 0 0 / 0.25);
}
.pacman-login .login-card {
  background: #ffffff;
  backdrop-filter: blur(40px);
  -webkit-backdrop-filter: blur(40px);
}
.pacman-login .login-card:hover {
  transform: none;
}
/* Card width steps — one discrete size per band, never interpolated.
   496px is the first viewport that still clears 28rem plus the 1.25rem
   gutters on each side of `.pacman-login`. */
@media (max-width: 495px) {
  .login-card { width: 19.5rem; padding: 1.75rem; }
}
/* Narrow phones: tighten the page gutters and take one more step down so a
   320px viewport still has breathing room around the card. */
@media (max-width: 359px) {
  .pacman-login { padding: 3rem 0.875rem; }
  .login-card { width: 17rem; padding: 1.5rem; }
}
/* Maze chrome keeps adapting to the viewport — the scoreboard and countdown
   are fixed-size canvases, so scale them down rather than let them clip. */
@media (max-width: 495px) {
  .swarm-score-corner {
    top: 1rem;
    right: 1rem;
    transform: scale(0.6);
    transform-origin: top right;
  }
  .swarm-countdown-wrap {
    transform: translateX(-50%) scale(0.78);
    transform-origin: top center;
  }
}
.app-desc { max-width: 48rem; margin: 0.75rem 0 0.5rem; }
.login-forgot-row { display: flex; justify-content: flex-end; }
.login-forgot-btn {
  background: none;
  border: 0;
  padding: 0;
  cursor: pointer;
  font-family: var(--font-mono, "JetBrains Mono", ui-monospace, monospace);
  font-size: 0.75rem;
  line-height: 1rem;
  color: var(--color-text-muted, #64748b);
  text-decoration: none;
  transition: color 150ms ease;
}
.login-forgot-btn:hover { color: var(--color-text); }
.login-form .login-forgot-btn {
  display: block;
  width: 100%;
  text-align: center;
  margin-top: 0.25rem;
  padding: 0.5rem 0;
}
/* Next login-terminal demo CTA: rounded-lg, font-mono text-sm, bg-accent, py-3 px-4 */
.login-demo-btn {
  display: flex;
  width: 100%;
  align-items: center;
  justify-content: center;
  gap: 0.5rem;
  margin-top: 0.5rem;
  padding: 0.75rem 1rem;
  border: 0;
  border-radius: 0.5rem;
  background: var(--color-accent);
  color: #fff;
  font-family: var(--font-mono);
  font-size: 0.875rem;
  font-weight: 400;
  letter-spacing: 0;
  line-height: 1.25rem;
  cursor: pointer;
  position: relative;
  overflow: hidden;
  transition: background 300ms ease, box-shadow 300ms ease, transform 300ms ease;
}
.login-demo-btn:hover {
  background: color-mix(in srgb, var(--color-accent) 90%, transparent);
  box-shadow:
    0 10px 15px -3px color-mix(in srgb, var(--color-accent) 20%, transparent),
    0 4px 6px -4px color-mix(in srgb, var(--color-accent) 20%, transparent);
  transform: scale(1.02);
}
.login-demo-btn:active {
  transform: scale(0.98);
}
.login-demo-arrow {
  width: 1rem;
  height: 1rem;
  flex-shrink: 0;
  transition: transform 300ms ease;
}
.login-card:hover .login-demo-arrow {
  transform: translateX(0.25rem);
}
.login-home-link {
  display: block;
  margin-top: 0.75rem;
  text-align: center;
  font-family: var(--font-mono, "JetBrains Mono", ui-monospace, monospace);
  font-size: 0.75rem;
  letter-spacing: 0.04em;
  color: var(--color-text-muted, #64748b);
  text-decoration: none;
  transition: color 150ms ease;
}
.login-home-link:hover {
  color: var(--color-accent, #2563eb);
}
.login-card .form-stack {
  gap: 1rem;
  margin-top: 0;
  position: relative;
  z-index: 1;
}
.login-brand { position: relative; z-index: 1; }
.login-card .form-stack label { color: var(--color-text); }
.login-card .form-stack input {
  width: 100%;
  box-sizing: border-box;
  background: transparent;
  border: 1px solid var(--color-border);
  border-radius: 0.5rem;
  color: var(--color-text);
  font-family: var(--font-mono, "JetBrains Mono", ui-monospace, monospace);
  font-size: 0.875rem;
  line-height: 1.25rem;
  padding: 0.75rem 1rem;
  outline: none;
  transition: border-color 300ms ease, box-shadow 300ms ease;
}
.login-card .form-stack input::placeholder {
  color: var(--color-text-faint, #64748b);
}
.login-card .form-stack input:hover {
  border-color: var(--color-text-muted, #64748b);
}
.login-card .form-stack input:focus {
  border-color: var(--color-accent);
  box-shadow: 0 0 0 2px color-mix(in srgb, var(--color-accent) 50%, transparent);
}
.login-email-wrap {
  position: relative;
  display: flex;
  align-items: center;
}
.login-bait-cursor {
  position: absolute;
  left: 8px;
  display: flex;
  align-items: center;
  pointer-events: none;
  z-index: 5;
}
.login-bait-bar {
  width: 0.5rem;
  height: 1.25rem;
  border-radius: 0.125rem;
  background: var(--color-accent, #3b82f6);
  box-shadow: 0 0 14px rgba(59, 130, 246, 0.7), 0 0 4px rgba(59, 130, 246, 0.9);
  animation: login-bait-pulse 1.2s ease-in-out infinite;
}
@keyframes login-bait-pulse {
  0%, 100% { opacity: 1; }
  50% { opacity: 0.35; }
}
.score-line { letter-spacing: 0.12em; text-align: center; }

/* ── Swarm timeline (process / about) ───────────────────────────────────── */
.swarm-timeline {
  position: relative;
  max-width: 64rem;
  margin: 3rem auto 0;
  padding: 2.5rem 0 4rem;
}
.swarm-timeline-canvas {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  pointer-events: none;
  z-index: 0;
  background: transparent;
}
.swarm-timeline-fallback {
  position: absolute;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  background-image:
    radial-gradient(circle, #10b981 1.2px, transparent 1.6px),
    radial-gradient(circle, #0ea5e9 1.2px, transparent 1.6px),
    radial-gradient(circle, #2563eb 1.2px, transparent 1.6px);
  background-size: 8px 10px, 10px 8px, 9px 11px;
  background-position: 0 0, 5px 4px, 3px 7px;
  mask-image: linear-gradient(to right, transparent 12%, black 38%, black 62%, transparent 88%);
  -webkit-mask-image: linear-gradient(to right, transparent 12%, black 38%, black 62%, transparent 88%);
  opacity: 0.7;
  transition: opacity 0.4s ease;
}
.swarm-timeline[data-river="ready"] .swarm-timeline-fallback {
  opacity: 0;
}
.swarm-timeline-fade-top,
.swarm-timeline-fade-bot {
  position: absolute;
  inset-inline: 0;
  height: 6rem;
  z-index: 1;
  pointer-events: none;
}
.swarm-timeline-fade-top {
  top: 0;
  background: linear-gradient(to bottom, var(--color-bg, #f8fafc), transparent);
}
.swarm-timeline-fade-bot {
  bottom: 0;
  background: linear-gradient(to top, var(--color-bg, #f8fafc), transparent);
}
.swarm-timeline-list {
  position: relative;
  z-index: 2;
  list-style: none;
  margin: 0;
  padding: 1.5rem 0;
  display: flex;
  flex-direction: column;
  gap: 8rem;
}
.swarm-step {
  display: flex;
  width: 100%;
}
.swarm-step-left { justify-content: flex-start; }
.swarm-step-right { justify-content: flex-end; }
.swarm-card {
  width: min(calc(50% - 1rem), 28rem);
  border-radius: 1rem;
  border: 1px solid color-mix(in srgb, #fff 60%, var(--color-border));
  background: color-mix(in srgb, #fff 70%, transparent);
  box-shadow: 0 8px 32px rgba(0,0,0,0.05), inset 0 0 0 1px rgba(255,255,255,0.8);
  backdrop-filter: blur(12px);
  transition: transform 0.35s ease, border-color 0.35s ease, box-shadow 0.35s ease;
}
@media (max-width: 720px) {
  .swarm-step-left, .swarm-step-right { justify-content: stretch; }
  .swarm-card { width: 100%; }
  .swarm-timeline-list { gap: 2.5rem; }
}
.swarm-card:hover {
  transform: translateY(-0.35rem);
  border-color: color-mix(in srgb, var(--color-accent) 40%, var(--color-border));
  box-shadow: 0 0 40px color-mix(in srgb, var(--color-accent-2) 22%, transparent),
    0 12px 40px rgba(0,0,0,0.08);
}
.swarm-card-inner {
  display: flex;
  gap: 1rem;
  padding: 1.25rem;
}
@media (min-width: 640px) {
  .swarm-card-inner { padding: 1.75rem; gap: 1.25rem; }
}
.swarm-n {
  display: inline-flex;
  width: 3rem; height: 3rem;
  flex-shrink: 0;
  align-items: center; justify-content: center;
  border-radius: 0.75rem;
  border: 1px solid var(--color-border);
  background: var(--color-panel);
  color: var(--color-accent-strong);
  font-size: 0.8125rem;
  font-weight: 500;
}
.swarm-card-body { min-width: 0; flex: 1; }
.swarm-card-head {
  display: flex; flex-wrap: wrap; align-items: baseline;
  justify-content: space-between; gap: 0.5rem 0.75rem;
}
.swarm-card-head h3 {
  margin: 0;
  font-family: var(--font-display);
  font-size: 1.125rem;
  font-weight: 700;
  letter-spacing: -0.02em;
}
.swarm-sublabel {
  border-radius: 999px;
  background: color-mix(in srgb, var(--color-accent) 10%, transparent);
  color: var(--color-accent-strong);
  font-family: var(--font-mono);
  font-size: 0.6875rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  padding: 0.15rem 0.6rem;
}
.swarm-card-body .muted { margin: 0.75rem 0 0; font-size: 0.875rem; }
.swarm-detail {
  margin-top: 1.15rem;
  padding-top: 0.85rem;
  border-top: 1px solid color-mix(in srgb, var(--color-border) 60%, transparent);
}
.swarm-detail-chip {
  display: inline-flex;
  align-items: center;
  padding: 0.25rem 0.6rem;
  border-radius: 0.375rem;
  border: 1px solid color-mix(in srgb, var(--color-border) 50%, transparent);
  background: var(--color-panel);
  font-size: 0.6875rem;
  color: var(--color-text-muted);
}
.process-block { max-width: 80rem; }

/* Process phase chips carry a Lucide glyph, never a numeral: Next passes an
   `icon` for every phase, so `s.n` is never rendered there. The glyphs are
   decorative, so they live in CSS as masks tinted by the chip's own color. */
.process-block .swarm-n::before {
  content: "";
  width: 1.25rem;
  height: 1.25rem;
  background-color: currentColor;
  -webkit-mask-image: var(--phase-icon);
  mask-image: var(--phase-icon);
  -webkit-mask-repeat: no-repeat;
  mask-repeat: no-repeat;
  -webkit-mask-position: center;
  mask-position: center;
  -webkit-mask-size: contain;
  mask-size: contain;
}
/* lucide `messages-square` */
.process-block .swarm-step:nth-child(1) .swarm-n {
  --phase-icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M16 10a2 2 0 0 1-2 2H6.828a2 2 0 0 0-1.414.586l-2.202 2.202A.71.71 0 0 1 2 14.286V4a2 2 0 0 1 2-2h10a2 2 0 0 1 2 2z'/%3E%3Cpath d='M20 9a2 2 0 0 1 2 2v10.286a.71.71 0 0 1-1.212.502l-2.202-2.202A2 2 0 0 0 17.172 19H10a2 2 0 0 1-2-2v-1'/%3E%3C/svg%3E");
}
/* lucide `map` */
.process-block .swarm-step:nth-child(2) .swarm-n {
  --phase-icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M14.106 5.553a2 2 0 0 0 1.788 0l3.659-1.83A1 1 0 0 1 21 4.619v12.764a1 1 0 0 1-.553.894l-4.553 2.277a2 2 0 0 1-1.788 0l-4.212-2.106a2 2 0 0 0-1.788 0l-3.659 1.83A1 1 0 0 1 3 19.381V6.618a1 1 0 0 1 .553-.894l4.553-2.277a2 2 0 0 1 1.788 0z'/%3E%3Cpath d='M15 5.764v15'/%3E%3Cpath d='M9 3.236v15'/%3E%3C/svg%3E");
}
/* lucide `boxes` */
.process-block .swarm-step:nth-child(3) .swarm-n {
  --phase-icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M2.97 12.92A2 2 0 0 0 2 14.63v3.24a2 2 0 0 0 .97 1.71l3 1.8a2 2 0 0 0 2.06 0L12 19v-5.5l-5-3-4.03 2.42Z'/%3E%3Cpath d='m7 16.5-4.74-2.85'/%3E%3Cpath d='m7 16.5 5-3'/%3E%3Cpath d='M7 16.5v5.17'/%3E%3Cpath d='M12 13.5V19l3.97 2.38a2 2 0 0 0 2.06 0l3-1.8a2 2 0 0 0 .97-1.71v-3.24a2 2 0 0 0-.97-1.71L17 10.5l-5 3Z'/%3E%3Cpath d='m17 16.5-5-3'/%3E%3Cpath d='m17 16.5 4.74-2.85'/%3E%3Cpath d='M17 16.5v5.17'/%3E%3Cpath d='M7.97 4.42A2 2 0 0 0 7 6.13v4.37l5 3 5-3V6.13a2 2 0 0 0-.97-1.71l-3-1.8a2 2 0 0 0-2.06 0l-3 1.8Z'/%3E%3Cpath d='M12 8 7.26 5.15'/%3E%3Cpath d='m12 8 4.74-2.85'/%3E%3Cpath d='M12 13.5V8'/%3E%3C/svg%3E");
}
/* lucide `wrench` */
.process-block .swarm-step:nth-child(4) .swarm-n {
  --phase-icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M14.7 6.3a1 1 0 0 0 0 1.4l1.6 1.6a1 1 0 0 0 1.4 0l3.106-3.105c.32-.322.863-.22.983.218a6 6 0 0 1-8.259 7.057l-7.91 7.91a1 1 0 0 1-2.999-3l7.91-7.91a6 6 0 0 1 7.057-8.259c.438.12.54.662.219.984z'/%3E%3C/svg%3E");
}
.about-experience { max-width: 80rem; padding-top: 4rem; padding-bottom: 4rem; }
.about-lead { max-width: 42rem; margin-top: 1rem; }

/* Logo wall — credential marks */
.logo-wall-section {
  border-block: 1px solid var(--color-border);
  background: color-mix(in srgb, var(--color-panel) 60%, transparent);
  padding: 3.5rem 1.25rem;
}
.logo-wall-eyebrow { text-align: center; margin: 0; }
.logo-wall-branded {
  max-width: 64rem;
  margin: 2.5rem auto 0;
  display: grid;
  grid-template-columns: 1fr;
  gap: 2.5rem;
  justify-items: center;
  list-style: none;
  padding: 0;
}
@media (min-width: 640px) {
  .logo-wall-branded { grid-template-columns: repeat(3, 1fr); gap: 3rem; }
}
.logo-cred {
  display: flex; flex-direction: column; align-items: center; gap: 0.75rem;
}
.logo-cred-mark {
  display: flex; height: 3rem; align-items: center; justify-content: center;
}
.logo-cred-img {
  max-height: 3rem; width: auto; opacity: 0.9;
}
.logo-cred-note {
  font-size: 0.6875rem;
  text-transform: uppercase;
  letter-spacing: 0.08em;
}

/* Founder silhouette cloud */
.founder-block {
  border-top: 1px solid var(--color-border);
  background: color-mix(in srgb, var(--color-panel) 40%, transparent);
  padding: 4rem 1.25rem;
}
.founder-grid {
  max-width: 80rem;
  margin: 0 auto;
  display: grid;
  gap: 2.5rem;
  align-items: center;
}
@media (min-width: 1024px) {
  .founder-grid { grid-template-columns: 0.9fr 1.1fr; gap: 2.5rem; }
  .founder-cloud-col { order: 1; }
  .founder-copy-col { order: 2; }
}
.founder-cloud-stage {
  position: relative;
  width: 100%;
  height: 400px;
}
@media (min-width: 640px) {
  .founder-cloud-stage { height: 500px; }
}
.founder-cloud-canvas {
  display: block;
  width: 100%;
  height: 100%;
  position: relative;
  z-index: 1;
}
.founder-cloud-fallback {
  position: absolute; inset: 0; z-index: 0;
  background-image:
    radial-gradient(circle, #10b981 1.2px, transparent 1.6px),
    radial-gradient(circle, #0ea5e9 1.2px, transparent 1.6px),
    radial-gradient(circle, #2563eb 1.2px, transparent 1.6px);
  background-size: 9px 11px, 11px 9px, 10px 12px;
  background-position: 0 0, 4px 5px, 7px 2px;
  opacity: 0.55;
  mask-image: radial-gradient(ellipse at center, black 38%, transparent 78%);
  -webkit-mask-image: radial-gradient(ellipse at center, black 38%, transparent 78%);
  pointer-events: none;
  transition: opacity 0.4s ease;
}
.founder-cloud-stage[data-founder="ready"] .founder-cloud-fallback {
  opacity: 0;
}

/* Portal command chrome density */
.workspace-page.workspace-light { padding: 1.5rem; }
.telemetry-bar-joined {
  margin-top: 1.5rem;
  margin-bottom: 1.25rem;
}
.cmd-two-col { margin-top: 0; gap: 1.25rem; }
.cmd-two-col .panel-card,
.cmd-split .panel-card,
.workspace-page > .panel-card {
  margin-bottom: 0;
}
.workspace-page > .panel-card { margin-top: 1.25rem; }
.cmd-split { margin-top: 1.25rem; }
.fleet-dots {
  gap: 0.375rem;
}
.fleet-dot {
  width: 0.625rem;
  height: 0.625rem;
  border-radius: 0.15rem;
}
.tele-cell { padding: 1.25rem; }
.tele-v { font-size: 1.5rem; }
.panel-card { padding: 1.25rem; }

/* Consulting workspace (client home + master dashboard) */
.consult-home .consult-grid,
.consult-firm .consult-firm-form {
  display: grid;
  gap: 1.25rem;
  margin-top: 1.25rem;
}
.consult-master {
  display: grid;
  gap: 1.25rem;
  margin-top: 1.25rem;
}
@media (min-width: 900px) {
  .consult-home .consult-grid {
    grid-template-columns: 1fr 1fr;
  }
  .consult-master {
    grid-template-columns: 1.15fr 0.85fr;
    align-items: start;
  }
  .consult-firm-form {
    grid-template-columns: 1fr 1fr;
  }
  .consult-firm-form > button[type="submit"] {
    grid-column: 1 / -1;
    justify-self: start;
  }
}
.consult-engagement-list {
  list-style: none;
  margin: 0.75rem 0 0;
  padding: 0;
  display: grid;
  gap: 0.5rem;
}
.consult-engagement-btn {
  display: grid;
  gap: 0.2rem;
  width: 100%;
  text-align: left;
  border-radius: 0.5rem;
  border: 1px solid color-mix(in srgb, currentColor 18%, transparent);
  background: #fff;
  color: inherit;
  padding: 0.75rem 0.9rem;
  font: inherit;
  cursor: pointer;
}
.consult-engagement-btn:hover,
.consult-engagement-btn:focus-visible {
  border-color: color-mix(in srgb, var(--color-accent, #10b981) 45%, transparent);
}
.consult-engagement-name {
  font-weight: 600;
}
.consult-card { margin-top: 1.25rem; }
.consult-dl {
  display: grid;
  gap: 0.75rem;
  margin: 0;
}
.consult-dl dt {
  font-size: 0.75rem;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: color-mix(in srgb, currentColor 55%, transparent);
}
.consult-dl dd { margin: 0.15rem 0 0; }
.consult-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 0.75rem;
  margin-top: 1rem;
}
.consult-thread {
  list-style: none;
  margin: 0 0 1rem;
  padding: 0;
  display: grid;
  gap: 0.75rem;
  max-height: 22rem;
  overflow: auto;
}
.consult-msg {
  border: 1px solid color-mix(in srgb, var(--color-accent, #10b981) 18%, transparent);
  border-radius: 0.5rem;
  padding: 0.75rem 1rem;
  background: color-mix(in srgb, #0b1f3a 6%, transparent);
}
.consult-msg.firm {
  border-color: color-mix(in srgb, #10b981 35%, transparent);
}
.consult-msg-meta { margin: 0 0 0.35rem; font-size: 0.75rem; }
.consult-msg-body { margin: 0; }
.consult-compose {
  display: grid;
  gap: 0.75rem;
}
.consult-textarea {
  width: 100%;
  min-height: 4.5rem;
  border-radius: 0.5rem;
  border: 1px solid color-mix(in srgb, currentColor 18%, transparent);
  padding: 0.75rem;
  font: inherit;
  background: #fff;
  color: #0f172a;
}
.consult-firm-form label {
  display: grid;
  gap: 0.35rem;
  font-size: 0.875rem;
}
.consult-firm-form input {
  border-radius: 0.5rem;
  border: 1px solid color-mix(in srgb, currentColor 18%, transparent);
  padding: 0.6rem 0.75rem;
  font: inherit;
  background: #fff;
  color: #0f172a;
}
.consult-requests {
  list-style: none;
  margin: 0.75rem 0 0;
  padding: 0;
  display: grid;
  gap: 0.5rem;
}
.consult-req {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem 0.75rem;
  align-items: baseline;
  padding: 0.65rem 0;
  border-bottom: 1px solid color-mix(in srgb, currentColor 10%, transparent);
}
.consult-magic {
  margin-top: 1.25rem;
  padding: 1rem;
  border-radius: 0.5rem;
  border: 1px dashed color-mix(in srgb, #10b981 40%, transparent);
  background: color-mix(in srgb, #10b981 6%, transparent);
}
.consult-magic-url {
  display: block;
  word-break: break-all;
  margin: 0.5rem 0 0.75rem;
  font-size: 0.8rem;
}
.btn-primary.consult-open-planner,
.consult-actions .btn-primary {
  background: linear-gradient(135deg, #059669, #10b981);
  color: #fff;
  border: none;
}
.pill-build, .pill-discovery, .pill-active, .pill-review {
  --pl-chip-hue: #0ea5e9;
}

/* Launchpad polish */
.app-launch-grid { margin-top: 2rem; gap: 1.25rem; }
.app-launch-card {
  transition: border-color 0.15s ease, box-shadow 0.15s ease, transform 0.15s ease;
}
.app-launch-card:hover {
  border-color: var(--color-accent);
  box-shadow: 0 8px 24px -8px color-mix(in srgb, var(--color-accent) 28%, transparent);
  transform: translateY(-1px);
}
.app-icon {
  width: 2.5rem; height: 2.5rem;
  border-radius: 0.625rem;
}
.app-card-title { font-size: 1.05rem; }

@media (prefers-reduced-motion: reduce) {
  .swarm-card:hover { transform: none; }
  .app-launch-card:hover { transform: none; }
  .login-demo-btn,
  .login-demo-btn:hover,
  .login-demo-btn:active {
    transition: none;
    transform: none;
  }
  .login-card,
  .login-card:hover {
    transition: none;
    transform: none;
  }
  .login-demo-arrow,
  .login-card:hover .login-demo-arrow {
    transition: none;
    transform: none;
  }
}
/* ─────────────────────────────────────────────────────────────────────── */
/* D3pth Planner — "The Nicer Theme" (light-default, dark first-class)     */
/* ─────────────────────────────────────────────────────────────────────── */

/* ── Tokens: LIGHT is default, declared on .pl-app ──────────────────────── */

.pl-app {
  /* Ground + surfaces */
  --pl-ground: linear-gradient(180deg, #f8fafc 0%, #eef4fb 50%, #dbeafe 100%);
  --pl-panel-1: #ffffff;
  --pl-panel-2: #f8fafc;
  --pl-border: #e2e8f0;
  --pl-track: #e2e8f0;
  --pl-block: #eef2f7;

  /* Text */
  --pl-text: #0f172a;
  --pl-muted: #475569;
  --pl-faint: #64748b;

  /* Accents */
  --pl-blue: #2563eb;
  --pl-sky: #0ea5e9;
  --pl-green: #10b981;
  --pl-navy: #0b1f3a;
  --pl-amber: #d97706;
  --pl-red: #dc2626;
  --pl-violet: var(--pl-sky);

  /* Chip tint formula: bg = X at bg-mix% over transparent, border = X at border-mix% */
  --pl-chip-bg-mix: 10%;
  --pl-chip-border-mix: 40%;

  /* Elevation (reuses marketing shadow language) */
  --pl-shadow-card: 0 1px 2px rgba(15, 23, 42, 0.05),
    0 4px 10px -3px rgba(15, 23, 42, 0.09), 0 12px 28px -10px rgba(15, 23, 42, 0.07);
  --pl-shadow-float: 0 2px 6px -1px rgba(15, 23, 42, 0.08),
    0 14px 32px -10px rgba(15, 23, 42, 0.14),
    0 0 28px -6px color-mix(in srgb, var(--pl-blue) 24%, transparent);

  /* Glass surfaces (panel, tour tip, save gate, nudge) */
  --pl-glass-bg: rgba(255, 255, 255, 0.65);
  --pl-glass-border: rgba(255, 255, 255, 0.5);
  --pl-glass-shadow: 0 12px 32px -8px rgba(15, 23, 42, 0.18),
    0 2px 8px rgba(15, 23, 42, 0.08);
  --pl-modal-shadow: 0 20px 60px -12px rgba(15, 23, 42, 0.35),
    0 4px 16px rgba(15, 23, 42, 0.12);
  --pl-modal-backdrop: rgba(15, 23, 42, 0.4);

  /* Button anatomy (same brand gradient both themes — the "signature") */
  --pl-btn-primary-grad: linear-gradient(135deg, #2563eb, #0ea5e9);
  --pl-btn-green-grad: linear-gradient(135deg, #059669, #10b981);
  --pl-btn-shadow: 0 1px 2px rgba(15, 23, 42, 0.2), 0 4px 14px -4px rgba(37, 99, 235, 0.5);
  --pl-btn-shadow-hover: 0 2px 4px rgba(15, 23, 42, 0.22),
    0 8px 22px -4px rgba(37, 99, 235, 0.6);
  --pl-btn-green-shadow: 0 1px 2px rgba(15, 23, 42, 0.2),
    0 4px 14px -4px rgba(16, 185, 129, 0.5);
  --pl-btn-green-shadow-hover: 0 2px 4px rgba(15, 23, 42, 0.22),
    0 8px 22px -4px rgba(16, 185, 129, 0.6);
  --pl-sheen: linear-gradient(120deg, transparent, rgba(255, 255, 255, 0.55), transparent);

  display: flex;
  flex-direction: column;
  height: 100vh;
  background: var(--pl-ground);
  color: var(--pl-text);
  font-family: var(--font-sans);
  overflow: hidden;
}

/* ── Tokens: DARK — re-declares every custom property above ────────────── */

.pl-app[data-pl-theme="dark"] {
  --pl-ground: linear-gradient(160deg, #060f1e 0%, #0b1f3a 100%);
  --pl-panel-1: #0d2445;
  --pl-panel-2: #123256;
  --pl-border: #1e3a5f;
  --pl-track: #24466e;
  --pl-block: #16304f;

  --pl-text: #e6eef9;
  --pl-muted: #93a9c6;
  --pl-faint: #6b83a3;

  --pl-blue: #3b82f6;
  --pl-sky: #0ea5e9;
  --pl-green: #10b981;
  --pl-navy: #0b1f3a;
  --pl-amber: #f59e0b;
  --pl-red: #ef4444;
  --pl-violet: var(--pl-sky);

  --pl-chip-bg-mix: 12%;
  --pl-chip-border-mix: 100%;

  --pl-shadow-card: 0 1px 2px rgba(0, 0, 0, 0.3), 0 4px 10px -3px rgba(0, 0, 0, 0.35),
    0 12px 28px -10px rgba(0, 0, 0, 0.3);
  --pl-shadow-float: 0 2px 6px -1px rgba(0, 0, 0, 0.35), 0 14px 32px -10px rgba(0, 0, 0, 0.5),
    0 0 28px -6px color-mix(in srgb, var(--pl-sky) 30%, transparent);

  --pl-glass-bg: rgba(13, 36, 69, 0.62);
  --pl-glass-border: rgba(255, 255, 255, 0.08);
  --pl-glass-shadow: 0 12px 32px rgba(0, 0, 0, 0.5), 0 2px 8px rgba(0, 0, 0, 0.3);
  --pl-modal-shadow: 0 20px 48px rgba(0, 0, 0, 0.6);
  --pl-modal-backdrop: rgba(3, 9, 20, 0.82);

  --pl-btn-shadow: 0 1px 2px rgba(0, 0, 0, 0.3), 0 4px 14px -4px rgba(59, 130, 246, 0.5);
  --pl-btn-shadow-hover: 0 2px 4px rgba(0, 0, 0, 0.35), 0 8px 22px -4px rgba(59, 130, 246, 0.6);
  --pl-btn-green-shadow: 0 1px 2px rgba(0, 0, 0, 0.3), 0 4px 14px -4px rgba(16, 185, 129, 0.5);
  --pl-btn-green-shadow-hover: 0 2px 4px rgba(0, 0, 0, 0.35),
    0 8px 22px -4px rgba(16, 185, 129, 0.6);
  --pl-sheen: linear-gradient(120deg, transparent, rgba(255, 255, 255, 0.25), transparent);
}

/* ── Root layout ────────────────────────────────────────────────────────── */

.pl-topbar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 12px 16px;
  background: var(--pl-panel-1);
  border-bottom: 1px solid var(--pl-border);
  min-height: 56px;
  flex-shrink: 0;
  transition: background-color 200ms, border-color 200ms;
}

.pl-work {
  display: flex;
  flex: 1;
  overflow: hidden;
}

.pl-view[hidden] {
  display: none !important;
}

.pl-view {
  display: flex;
  flex: 1;
  overflow: auto;
  gap: 16px;
  padding: 16px;
}

/* ── Topbar controls ────────────────────────────────────────────────────── */

.pl-demo-pill {
  display: inline-flex;
  align-items: center;
  padding: 6px 12px;
  background: var(--pl-panel-2);
  border: 1px solid var(--pl-border);
  border-radius: 12px;
  font-size: 12px;
  font-weight: 500;
  color: var(--pl-muted);
  cursor: default;
}

.pl-tabs {
  display: flex;
  gap: 8px;
  background: transparent;
}

.pl-tab {
  min-height: 30px;
  padding: 6px 12px;
  background: transparent;
  border: 1px solid transparent;
  border-radius: 6px;
  color: var(--pl-muted);
  cursor: pointer;
  font-size: 13px;
  font-weight: 500;
  transition: color 150ms, border-color 150ms, background-color 150ms;
}

.pl-tab:hover {
  color: var(--pl-text);
  border-color: var(--pl-border);
}

.pl-tab[aria-selected="true"] {
  color: var(--pl-text);
  background: var(--pl-panel-2);
  border-color: var(--pl-border);
}

.pl-top-right {
  display: flex;
  align-items: center;
  gap: 12px;
}

.pl-credit-chip {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  padding: 6px 10px;
  background: var(--pl-panel-2);
  border: 1px solid var(--pl-border);
  border-radius: 6px;
  font-family: var(--font-mono);
  font-size: 11px;
  color: var(--pl-muted);
  font-weight: 500;
}

.pl-note-chip {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  padding: 6px 10px;
  background: var(--pl-panel-2);
  border: 1px solid var(--pl-border);
  border-radius: 6px;
  font-family: var(--font-mono);
  font-size: 11px;
  color: var(--pl-muted);
  font-weight: 500;
}

/* ── Theme toggle (topbar) ──────────────────────────────────────────────── */

.pl-theme-toggle {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 34px;
  min-height: 34px;
  padding: 6px;
  background: var(--pl-panel-2);
  border: 1px solid var(--pl-border);
  border-radius: 8px;
  color: var(--pl-muted);
  cursor: pointer;
  transition: all 150ms;
}

.pl-theme-toggle:hover {
  border-color: var(--pl-blue);
  color: var(--pl-text);
}

.pl-theme-toggle:focus-visible {
  outline: 2px solid var(--pl-sky);
  outline-offset: 2px;
}

/* ── Map stage and canvas ───────────────────────────────────────────────── */

.pl-map-stage {
  position: relative;
  flex: 1.35;
  min-width: 400px;
  background: var(--pl-panel-1);
  border: 1px solid var(--pl-border);
  border-radius: 12px;
  overflow: hidden;
  box-shadow: var(--pl-shadow-card);
}

.pl-edge-canvas {
  position: absolute;
  inset: 0;
  /* Replaced element: inset alone never stretches a canvas — without an
     explicit 100% box it lays out at its width/height attrs (css*dpr),
     rendering every edge at 2x its true position. */
  width: 100%;
  height: 100%;
  display: block;
  pointer-events: none;
  z-index: 0;
}

.pl-tier {
  position: relative;
  z-index: 1;
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
  padding: 16px;
  justify-content: center;
}

.pl-tier-label {
  display: block;
  text-align: center;
  margin: 0 0 8px;
  font-size: 10px;
  font-family: var(--font-mono);
  color: var(--pl-faint);
  text-transform: uppercase;
  letter-spacing: 0.05em;
}

.pl-tier-list {
  display: flex;
  gap: 12px;
  flex-wrap: wrap;
  justify-content: center;
}

/* ── Nodes ──────────────────────────────────────────────────────────────── */

.pl-node {
  position: relative;
  padding: 12px;
  background: var(--pl-panel-2);
  border: 1px solid var(--pl-border);
  border-radius: 12px;
  min-width: 180px;
  max-width: 280px;
  cursor: pointer;
  box-shadow: var(--pl-shadow-card);
  transition: all 150ms;
}

.pl-node:hover {
  border-color: var(--pl-blue);
  transform: translateY(-2px);
  box-shadow: var(--pl-shadow-float);
}

.pl-node-sel {
  border: 1px solid var(--pl-sky);
  box-shadow: 0 0 0 1px var(--pl-sky), var(--pl-shadow-float);
}

.pl-node-ghost {
  border: 2px dashed var(--pl-sky);
  background: color-mix(in srgb, var(--pl-sky) 6%, transparent);
}

.pl-node-site {
  min-width: 230px;
  background: linear-gradient(
    135deg,
    var(--pl-panel-2) 0%,
    color-mix(in srgb, var(--pl-blue) 12%, var(--pl-panel-2)) 100%
  );
  border: 1px solid color-mix(in srgb, var(--pl-blue) 30%, var(--pl-border));
  display: flex;
  align-items: center;
  justify-content: center;
}

.pl-add-card {
  display: flex;
  align-items: center;
  justify-content: center;
  min-width: 180px;
  height: 60px;
  background: var(--pl-panel-1);
  border: 2px dashed var(--pl-border);
  border-radius: 12px;
  cursor: pointer;
  transition: all 150ms;
  color: var(--pl-muted);
  font-size: 14px;
  font-weight: 500;
}

.pl-add-card:hover {
  border-color: var(--pl-blue);
  background: color-mix(in srgb, var(--pl-blue) 6%, var(--pl-panel-1));
  color: var(--pl-text);
}

.pl-nid {
  font-size: 11px;
  font-family: var(--font-mono);
  color: var(--pl-faint);
  opacity: 0.7;
}

.pl-nt {
  font-size: 13px;
  font-weight: 600;
  color: var(--pl-text);
  margin-top: 4px;
}

.pl-nk {
  display: flex;
  gap: 4px;
  margin-top: 8px;
  flex-wrap: wrap;
  align-items: flex-start;
}

.pl-badges {
  display: flex;
  gap: 6px;
  flex-wrap: wrap;
  align-items: center;
}

/* ── Chips (tint = pl-chip-bg-mix over X, border = pl-chip-border-mix) ──── */

.pl-chip {
  display: inline-flex;
  align-items: center;
  padding: 4px 8px;
  border-radius: 4px;
  font-family: var(--font-mono);
  font-size: 8.5px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  border: 1px solid;
  white-space: nowrap;
}

/* Suffix hues live on the glassglow pass (--pl-chip-hue). Opaque
   .pl-chip-* fills were deleted so they cannot beat that family. */

.pl-notes-dot {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 18px;
  height: 18px;
  border-radius: 50%;
  background: color-mix(in srgb, var(--pl-blue) 20%, transparent);
  border: 1px solid var(--pl-blue);
  color: var(--pl-blue);
  font-size: 10px;
  font-weight: 600;
  font-family: var(--font-mono);
}

/* ── Flow handle and hints ──────────────────────────────────────────────── */

.pl-flow-handle {
  position: absolute;
  left: 50%;
  bottom: -22px;
  transform: translateX(-50%);
  width: 44px;
  height: 44px;
  display: grid;
  place-items: center;
  background: none;
  border: none;
  padding: 0;
  cursor: grab;
  z-index: 2;
}

.pl-flow-handle::before {
  content: "";
  width: 14px;
  height: 14px;
  border-radius: 50%;
  background: linear-gradient(135deg, var(--pl-blue) 0%, var(--pl-sky) 100%);
  box-shadow: 0 2px 6px rgba(37, 99, 235, 0.4);
  transition: transform 150ms;
}

.pl-flow-handle:hover::before {
  transform: scale(1.25);
}

.pl-flow-handle:active {
  cursor: grabbing;
}

.pl-flow-hint {
  position: absolute;
  font-size: 10px;
  color: var(--pl-faint);
  pointer-events: none;
  font-family: var(--font-mono);
  white-space: nowrap;
}

/* ── Detail panel ───────────────────────────────────────────────────────── */

.pl-detail {
  display: grid;
  grid-template-columns: 1.35fr minmax(300px, 1fr);
  gap: 16px;
  flex: 1;
  min-width: 0;
}

@media (max-width: 950px) {
  .pl-detail {
    grid-template-columns: 1fr;
  }
}

.pl-crumbs {
  display: flex;
  gap: 8px;
  align-items: center;
  font-size: 12px;
  margin-bottom: 12px;
  color: var(--pl-muted);
}

.pl-crumb-here {
  color: var(--pl-text);
  font-weight: 500;
}

.pl-pagenav {
  display: flex;
  gap: 8px;
  margin-top: 12px;
}

.pl-fig-head {
  font-size: 15px;
  font-weight: 600;
  color: var(--pl-text);
  margin-bottom: 4px;
}

.pl-fig-meta {
  font-size: 12px;
  color: var(--pl-muted);
  margin-bottom: 12px;
}

.pl-mockbox {
  background: var(--pl-panel-1);
  border: 1px solid var(--pl-border);
  border-radius: 12px;
  padding: 16px;
  min-height: 200px;
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--pl-faint);
  font-size: 13px;
}

.pl-wire {
  background: var(--pl-panel-2);
  border: 1px dashed var(--pl-border);
  border-radius: 8px;
  padding: 12px;
  font-family: var(--font-mono);
  font-size: 11px;
  color: var(--pl-muted);
  line-height: 1.6;
  overflow-x: auto;
}

.pl-wregion {
  background: var(--pl-panel-2);
  border: 1px solid var(--pl-border);
  border-radius: 8px;
  padding: 12px;
  margin-bottom: 8px;
  transition: all 150ms;
}

.pl-wregion:hover {
  border-color: var(--pl-blue);
  box-shadow: var(--pl-shadow-card);
}

.pl-wregion-sel {
  border: 1px solid var(--pl-sky);
  background: color-mix(in srgb, var(--pl-sky) 6%, var(--pl-panel-2));
  box-shadow: 0 0 0 1px var(--pl-sky);
}

.pl-wregion-flash {
  animation: wregion-flash 600ms ease-out;
}

@keyframes wregion-flash {
  0% {
    background: color-mix(in srgb, var(--pl-amber) 20%, var(--pl-panel-2));
  }
  100% {
    background: var(--pl-panel-2);
  }
}

@media (prefers-reduced-motion: reduce) {
  .pl-wregion-flash {
    animation: none;
  }
}

.pl-wid {
  font-family: var(--font-mono);
  font-size: 10px;
  color: var(--pl-faint);
  opacity: 0.7;
}

.pl-wdrafted {
  opacity: 0.6;
}

.pl-fake {
  color: var(--pl-faint);
  font-style: italic;
}

.pl-bar {
  height: 7px;
  background: var(--pl-track);
  border-radius: 7px;
  margin: 6px 0;
}

.pl-blk {
  background: var(--pl-block);
  border-radius: 6px;
  padding: 12px;
  margin: 6px 0;
  min-height: 40px;
}

.pl-hero-blk {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 10px;
  min-height: 96px;
  padding: 18px 16px;
  border-radius: 8px;
  background: linear-gradient(160deg, var(--pl-panel-2), transparent);
  text-align: center;
}

.pl-hero-blk p {
  margin: 0;
  font-family: var(--font-sans);
  font-size: clamp(14px, 1.6vw, 18px);
  font-weight: 600;
  line-height: 1.3;
  color: var(--pl-text);
  max-width: 34ch;
}

/* Mockup CTA — inherits the real primary button anatomy, scaled down */
.pl-cta-fake {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: auto;
  padding: 6px 14px;
  border-radius: 7px;
  margin: 2px 0;
  font-family: var(--font-sans);
  font-size: 11px;
  font-weight: 600;
  color: #ffffff;
  white-space: nowrap;
  background: var(--pl-btn-primary-grad);
  box-shadow: var(--pl-btn-shadow);
}

.pl-g3 {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 8px;
}

.pl-pin {
  position: absolute;
  width: 21px;
  height: 28px;
  background: color-mix(in srgb, var(--pl-sky) 55%, var(--pl-navy, #0b1f3a));
  border: 2px solid color-mix(in srgb, var(--pl-sky) 45%, var(--pl-glass-border));
  border-radius: 50% 50% 50% 4px;
  display: flex;
  align-items: center;
  justify-content: center;
  font-family: var(--font-mono);
  font-size: 10px;
  font-weight: 600;
  color: #ffffff;
  box-shadow: inset 0 1px 0 color-mix(in srgb, #ffffff 28%, transparent),
    0 0 12px -4px color-mix(in srgb, var(--pl-sky) 40%, transparent);
  transform: translate(-50%, -100%);
}

.pl-missing {
  background: repeating-linear-gradient(
      45deg,
      transparent,
      transparent 4px,
      color-mix(in srgb, var(--pl-sky) 22%, transparent) 4px,
      color-mix(in srgb, var(--pl-sky) 22%, transparent) 8px
    ),
    color-mix(in srgb, var(--pl-navy, #0b1f3a) 8%, var(--pl-glass-bg));
  border: 2px dashed color-mix(in srgb, var(--pl-sky) 55%, var(--pl-border));
  border-radius: 6px;
  padding: 12px;
  color: var(--pl-text);
  font-size: 11px;
  font-weight: 500;
  text-align: center;
  min-height: 60px;
  display: flex;
  align-items: center;
  justify-content: center;
}

/* ── Glass surfaces: panel, tour tip, save gate, nudge ──────────────────── */

.pl-panel,
.pl-tour-tip,
.pl-save-gate,
.pl-nudge {
  background: var(--pl-glass-bg);
  backdrop-filter: blur(14px) saturate(1.3);
  -webkit-backdrop-filter: blur(14px) saturate(1.3);
  border: 1px solid var(--pl-glass-border);
  box-shadow: var(--pl-glass-shadow);
}

@supports not ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
  .pl-panel,
  .pl-tour-tip,
  .pl-save-gate,
  .pl-nudge {
    background: var(--pl-panel-2);
  }
}

/* ── Panel and buttons ──────────────────────────────────────────────────── */

.pl-panel {
  border-radius: 12px;
  padding: 16px;
}

.pl-panel-h {
  margin-bottom: 16px;
  font-size: 14px;
  font-weight: 600;
  color: var(--pl-text);
}

/* Primary button — the centerpiece. Gradient fill, layered glow shadow,
   skewed sheen sweep on hover (::after), lift on hover, compress on press. */
.pl-btn {
  position: relative;
  overflow: hidden;
  min-height: 44px;
  padding: 8px 16px;
  background: var(--pl-btn-primary-grad);
  color: #ffffff;
  border: none;
  border-radius: 10px;
  font-size: 13px;
  font-weight: 600;
  cursor: pointer;
  box-shadow: var(--pl-btn-shadow);
  transition: transform 150ms ease, box-shadow 150ms ease;
  font-family: var(--font-sans);
}

.pl-btn::after {
  content: "";
  position: absolute;
  top: 0;
  left: -150%;
  width: 60%;
  height: 100%;
  background: var(--pl-sheen);
  transform: skewX(-20deg);
  transition: left 600ms ease;
  pointer-events: none;
}

.pl-btn:hover {
  transform: translateY(-1px);
  box-shadow: var(--pl-btn-shadow-hover);
}

.pl-btn:hover::after {
  left: 150%;
}

.pl-btn:active {
  transform: translateY(0);
  box-shadow: var(--pl-btn-shadow);
}

.pl-btn:focus-visible {
  outline: 2px solid var(--pl-sky);
  outline-offset: 2px;
}

/* Same anatomy, emerald gradient */
.pl-btn-green {
  position: relative;
  overflow: hidden;
  min-height: 44px;
  padding: 8px 16px;
  background: var(--pl-btn-green-grad);
  color: #ffffff;
  border: none;
  border-radius: 10px;
  font-size: 13px;
  font-weight: 600;
  cursor: pointer;
  box-shadow: var(--pl-btn-green-shadow);
  transition: transform 150ms ease, box-shadow 150ms ease;
  font-family: var(--font-sans);
}

.pl-btn-green::after {
  content: "";
  position: absolute;
  top: 0;
  left: -150%;
  width: 60%;
  height: 100%;
  background: var(--pl-sheen);
  transform: skewX(-20deg);
  transition: left 600ms ease;
  pointer-events: none;
}

.pl-btn-green:hover {
  transform: translateY(-1px);
  box-shadow: var(--pl-btn-green-shadow-hover);
}

.pl-btn-green:hover::after {
  left: 150%;
}

.pl-btn-green:active {
  transform: translateY(0);
  box-shadow: var(--pl-btn-green-shadow);
}

.pl-btn-green:focus-visible {
  outline: 2px solid var(--pl-sky);
  outline-offset: 2px;
}

.pl-btn-sm {
  min-height: 34px;
  padding: 4px 12px;
  font-size: 12px;
  background: var(--pl-glass-bg);
  backdrop-filter: blur(10px) saturate(1.2);
  -webkit-backdrop-filter: blur(10px) saturate(1.2);
  color: var(--pl-muted);
  border: 1px solid var(--pl-glass-border);
  border-radius: 6px;
  cursor: pointer;
  transition: all 150ms;
}

@supports not ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
  .pl-btn-sm {
    background: var(--pl-panel-2);
  }
}

.pl-btn-sm:hover {
  border-color: var(--pl-blue);
  color: var(--pl-text);
  background: color-mix(in srgb, var(--pl-blue) 10%, var(--pl-glass-bg));
}

.pl-btn-sm:focus-visible {
  outline: 2px solid var(--pl-sky);
  outline-offset: 2px;
}

/* Ghost — glass chip, fills toward accent tint on hover */
.pl-ghost {
  min-height: 44px;
  padding: 6px 12px;
  background: var(--pl-glass-bg);
  backdrop-filter: blur(10px) saturate(1.2);
  -webkit-backdrop-filter: blur(10px) saturate(1.2);
  border: 1px solid var(--pl-glass-border);
  color: var(--pl-text);
  border-radius: 6px;
  font-size: 13px;
  cursor: pointer;
  transition: all 150ms;
}

@supports not ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
  .pl-ghost {
    background: var(--pl-panel-2);
  }
}

.pl-ghost:hover {
  border-color: var(--pl-blue);
  background: color-mix(in srgb, var(--pl-blue) 10%, var(--pl-glass-bg));
}

.pl-ghost:focus-visible {
  outline: 2px solid var(--pl-sky);
  outline-offset: 2px;
}

@media (prefers-reduced-motion: reduce) {
  .pl-btn,
  .pl-btn::after,
  .pl-btn-green,
  .pl-btn-green::after,
  .pl-btn-sm,
  .pl-ghost {
    transition: none;
  }
}

/* ── Segments and labels ────────────────────────────────────────────────── */

.pl-seg {
  display: flex;
  gap: 8px;
  margin-bottom: 12px;
}

.pl-lbl {
  display: block;
  font-size: 12px;
  font-weight: 500;
  color: var(--pl-text);
  margin-bottom: 6px;
}

.pl-swrow {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 8px 0;
  border-bottom: 1px solid var(--pl-border);
}

.pl-swrow:last-child {
  border-bottom: none;
}

.pl-swatch {
  display: inline-block;
  width: 18px;
  height: 18px;
  border-radius: 4px;
  border: 1px solid var(--pl-border);
  cursor: pointer;
  transition: all 150ms;
}

.pl-swatch:hover {
  box-shadow: 0 0 0 2px var(--pl-sky);
}

/* ── Toast and hints ────────────────────────────────────────────────────── */

.pl-toast {
  position: fixed;
  bottom: 20px;
  right: 20px;
  padding: 12px 16px;
  background: var(--pl-panel-2);
  border: 1px solid var(--pl-border);
  border-radius: 8px;
  color: var(--pl-text);
  font-size: 13px;
  box-shadow: var(--pl-shadow-float);
  z-index: 1000;
  animation: toast-slide 300ms ease-out;
}

.pl-warn-toast {
  background: color-mix(in srgb, var(--pl-amber) 12%, var(--pl-panel-2));
  border-color: var(--pl-amber);
  color: var(--pl-amber);
}

@keyframes toast-slide {
  from {
    transform: translateX(400px);
    opacity: 0;
  }
  to {
    transform: translateX(0);
    opacity: 1;
  }
}

@media (prefers-reduced-motion: reduce) {
  .pl-toast {
    animation: none;
  }
}

.pl-hint {
  font-size: 12px;
  color: var(--pl-faint);
  margin-top: 4px;
}

.pl-empty {
  padding: 40px 20px;
  text-align: center;
  color: var(--pl-muted);
  font-size: 14px;
}

/* ── Choice items (decision list) ───────────────────────────────────────── */

.pl-citem {
  background: var(--pl-panel-1);
  border: 1px solid var(--pl-border);
  border-radius: 8px;
  padding: 12px;
  margin-bottom: 8px;
  box-shadow: var(--pl-shadow-card);
  transition: all 150ms;
  cursor: pointer;
}

.pl-citem:hover {
  border-color: var(--pl-blue);
  background: color-mix(in srgb, var(--pl-blue) 6%, var(--pl-panel-1));
  box-shadow: var(--pl-shadow-float);
}

.pl-cm {
  font-size: 13px;
  font-weight: 500;
  color: var(--pl-text);
  margin-bottom: 4px;
}

.pl-cid {
  font-size: 11px;
  font-family: var(--font-mono);
  color: var(--pl-faint);
  opacity: 0.7;
}

.pl-cnode {
  display: flex;
  gap: 4px;
  margin-top: 6px;
  flex-wrap: wrap;
}

/* ── Kind and status chips (decision specific) ──────────────────────────── */

.pl-kchip {
  display: inline-flex;
  align-items: center;
  padding: 3px 7px;
  border-radius: 3px;
  font-family: var(--font-mono);
  font-size: 9px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  border: 1px solid;
  white-space: nowrap;
}

.pl-k-change {
  background: color-mix(in srgb, var(--pl-blue) var(--pl-chip-bg-mix), transparent);
  border-color: color-mix(in srgb, var(--pl-blue) var(--pl-chip-border-mix), transparent);
  color: var(--pl-blue);
}

.pl-k-question {
  background: color-mix(in srgb, var(--pl-sky) var(--pl-chip-bg-mix), transparent);
  border-color: color-mix(in srgb, var(--pl-sky) var(--pl-chip-border-mix), transparent);
  color: var(--pl-sky);
}

.pl-k-approve {
  background: color-mix(in srgb, var(--pl-green) var(--pl-chip-bg-mix), transparent);
  border-color: color-mix(in srgb, var(--pl-green) var(--pl-chip-border-mix), transparent);
  color: var(--pl-green);
}

.pl-k-reject {
  background: color-mix(in srgb, var(--pl-red) var(--pl-chip-bg-mix), transparent);
  border-color: color-mix(in srgb, var(--pl-red) var(--pl-chip-border-mix), transparent);
  color: var(--pl-red);
}

.pl-k-request {
  background: transparent;
  border: 1px dashed var(--pl-sky);
  color: var(--pl-sky);
}

.pl-k-decide {
  background: color-mix(in srgb, var(--pl-amber) var(--pl-chip-bg-mix), transparent);
  border-color: color-mix(in srgb, var(--pl-amber) var(--pl-chip-border-mix), transparent);
  color: var(--pl-amber);
}

.pl-k-logic {
  background: color-mix(in srgb, var(--pl-faint) var(--pl-chip-bg-mix), transparent);
  border-color: color-mix(in srgb, var(--pl-faint) var(--pl-chip-border-mix), transparent);
  color: var(--pl-faint);
}

.pl-k-permission {
  background: color-mix(in srgb, var(--pl-sky) var(--pl-chip-bg-mix), transparent);
  border-color: color-mix(in srgb, var(--pl-sky) var(--pl-chip-border-mix), transparent);
  color: var(--pl-sky);
}

.pl-schip {
  display: inline-flex;
  align-items: center;
  padding: 3px 7px;
  border-radius: 3px;
  font-family: var(--font-mono);
  font-size: 9px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  border: 1px solid;
  white-space: nowrap;
}

.pl-s-open {
  background: color-mix(in srgb, var(--pl-sky) var(--pl-chip-bg-mix), transparent);
  border-color: color-mix(in srgb, var(--pl-sky) var(--pl-chip-border-mix), transparent);
  color: var(--pl-sky);
}

.pl-s-applied {
  background: color-mix(in srgb, var(--pl-green) var(--pl-chip-bg-mix), transparent);
  border-color: color-mix(in srgb, var(--pl-green) var(--pl-chip-border-mix), transparent);
  color: var(--pl-green);
}

.pl-s-queued {
  background: color-mix(in srgb, var(--pl-amber) var(--pl-chip-bg-mix), transparent);
  border-color: color-mix(in srgb, var(--pl-amber) var(--pl-chip-border-mix), transparent);
  color: var(--pl-amber);
}

/* ── Complex decision/choice styling ────────────────────────────────────── */

.pl-ct {
  font-size: 13px;
  font-weight: 600;
  color: var(--pl-text);
  margin-bottom: 8px;
}

.pl-cx {
  display: flex;
  gap: 8px;
  align-items: center;
  padding: 8px 0;
  border-bottom: 1px solid var(--pl-border);
}

.pl-cx:last-child {
  border-bottom: none;
}

.pl-cx-sw {
  flex-shrink: 0;
}

.pl-res {
  font-size: 12px;
  color: var(--pl-muted);
  margin-top: 4px;
}

.pl-queue-note {
  background: color-mix(in srgb, var(--pl-amber) 6%, transparent);
  border: 1px solid color-mix(in srgb, var(--pl-amber) 30%, var(--pl-border));
  border-radius: 6px;
  padding: 8px 12px;
  font-size: 12px;
  color: var(--pl-amber);
  margin-top: 8px;
}

.pl-apply-row {
  display: flex;
  gap: 8px;
  align-items: center;
  padding: 12px;
  background: var(--pl-panel-1);
  border: 1px solid var(--pl-border);
  border-radius: 8px;
  margin-top: 8px;
  box-shadow: var(--pl-shadow-card);
}

.pl-apply-btn {
  flex: 1;
}

.pl-apply-cost {
  font-size: 12px;
  color: var(--pl-muted);
  white-space: nowrap;
  font-family: var(--font-mono);
}

.pl-pbar {
  height: 6px;
  background: var(--pl-border);
  border-radius: 6px;
  overflow: hidden;
  margin: 8px 0;
}

.pl-pbar-fill {
  height: 100%;
  background: linear-gradient(90deg, var(--pl-blue) 0%, var(--pl-sky) 50%, var(--pl-green) 100%);
  width: 0%;
  transition: width 200ms ease-out;
}

@media (prefers-reduced-motion: reduce) {
  .pl-pbar-fill {
    transition: none;
  }
}

.pl-pmsg {
  font-size: 12px;
  color: var(--pl-muted);
  margin-top: 4px;
  text-align: center;
}

/* ── Portal/permissions ────────────────────────────────────────────────── */

.pl-pmx {
  background: var(--pl-panel-1);
  border: 1px solid var(--pl-border);
  border-radius: 8px;
  padding: 12px;
  margin-bottom: 8px;
  box-shadow: var(--pl-shadow-card);
}

.pl-pmx-role {
  font-size: 12px;
  font-weight: 500;
  color: var(--pl-text);
  margin-bottom: 8px;
}

.pl-ptog {
  position: relative;
  display: inline-flex;
  align-items: center;
  width: 34px;
  height: 19px;
  background: var(--pl-border);
  border-radius: 19px;
  cursor: pointer;
  border: none;
  padding: 0;
  transition: background 200ms;
}

.pl-ptog::before {
  content: "";
  position: absolute;
  left: 2px;
  width: 13px;
  height: 13px;
  background: var(--pl-panel-1);
  border-radius: 50%;
  box-shadow: 0 1px 2px rgba(15, 23, 42, 0.3);
  transition: left 200ms;
}

.pl-ptog:hover {
  background: color-mix(in srgb, var(--pl-border) 120%, transparent);
}

.pl-ptog[aria-pressed="true"] {
  background: var(--pl-green);
}

.pl-ptog[aria-pressed="true"]::before {
  left: 19px;
}

.pl-ptog:focus-visible {
  outline: 2px solid var(--pl-sky);
  outline-offset: 2px;
}

@media (prefers-reduced-motion: reduce) {
  .pl-ptog,
  .pl-ptog::before {
    transition: none;
  }
}

.pl-pmx-note {
  font-size: 11px;
  color: var(--pl-faint);
  margin-top: 6px;
}

/* ── Tour ──────────────────────────────────────────────────────────────── */

.pl-tour-ring[hidden],
.pl-tour-tip[hidden] {
  display: none !important;
}

.pl-tour-ring {
  position: fixed;
  border: 2px solid var(--pl-sky);
  border-radius: 12px;
  box-shadow: 0 0 0 6000px var(--pl-modal-backdrop), 0 0 12px rgba(14, 165, 233, 0.4);
  pointer-events: none;
  z-index: 999;
  transition: all 300ms;
}

.pl-tour-tip {
  position: fixed;
  max-width: 320px;
  border-radius: 12px;
  padding: 16px;
  color: var(--pl-text);
  font-size: 13px;
  line-height: 1.5;
  z-index: 1000;
}

.pl-tour-step {
  font-size: 11px;
  font-family: var(--font-mono);
  color: var(--pl-faint);
  margin-bottom: 4px;
}

.pl-tour-say {
  font-size: 13px;
  color: var(--pl-text);
  margin-bottom: 12px;
  line-height: 1.5;
}

.pl-tour-row {
  display: flex;
  gap: 8px;
  margin-top: 8px;
}

.pl-tour-skip {
  flex: 1;
  min-height: 34px;
  padding: 4px 12px;
  background: transparent;
  border: 1px solid var(--pl-border);
  color: var(--pl-muted);
  border-radius: 6px;
  font-size: 12px;
  cursor: pointer;
  transition: all 150ms;
}

.pl-tour-skip:hover {
  border-color: var(--pl-blue);
  color: var(--pl-text);
}

.pl-tour-skip:focus-visible {
  outline: 2px solid var(--pl-sky);
  outline-offset: 2px;
}

/* ── Form controls (scoped to planner) ──────────────────────────────────── */

.pl-app button {
  font-family: var(--font-sans);
}

.pl-app input,
.pl-app textarea,
.pl-app select {
  font-family: var(--font-sans);
  color: var(--pl-text);
  background: var(--pl-panel-1);
  border: 1px solid var(--pl-border);
  border-radius: 6px;
  padding: 8px 12px;
  font-size: 13px;
}

.pl-app input:focus,
.pl-app textarea:focus,
.pl-app select:focus {
  outline: none;
  border-color: var(--pl-blue);
  box-shadow: 0 0 0 2px color-mix(in srgb, var(--pl-blue) 20%, transparent);
}

.pl-app input[type="radio"],
.pl-app input[type="checkbox"] {
  cursor: pointer;
  width: 18px;
  height: 18px;
}

/* ── Make button — topbar CTA, primary anatomy + size bump + glow pulse ── */

.pl-make-btn {
  position: relative;
  overflow: hidden;
  min-height: 48px;
  padding: 10px 22px;
  background: var(--pl-btn-primary-grad);
  color: #ffffff;
  font-weight: 600;
  border: none;
  border-radius: 10px;
  font-size: 14px;
  cursor: pointer;
  font-family: var(--font-sans);
  box-shadow: var(--pl-btn-shadow);
  transition: transform 150ms ease, box-shadow 150ms ease;
  animation: pl-make-glow 2.4s ease-in-out infinite;
}

.pl-make-btn::after {
  content: "";
  position: absolute;
  top: 0;
  left: -150%;
  width: 60%;
  height: 100%;
  background: var(--pl-sheen);
  transform: skewX(-20deg);
  transition: left 600ms ease;
  pointer-events: none;
}

@keyframes pl-make-glow {
  0%,
  100% {
    box-shadow: var(--pl-btn-shadow);
  }
  50% {
    box-shadow: var(--pl-btn-shadow-hover);
  }
}

.pl-make-btn:hover {
  transform: translateY(-1px);
  box-shadow: var(--pl-btn-shadow-hover);
}

.pl-make-btn:hover::after {
  left: 150%;
}

.pl-make-btn:active {
  transform: translateY(0);
  box-shadow: var(--pl-btn-shadow);
}

.pl-make-btn:focus-visible {
  outline: 2px solid var(--pl-sky);
  outline-offset: 2px;
}

@media (prefers-reduced-motion: reduce) {
  .pl-make-btn {
    animation: none;
    transition: none;
  }
  .pl-make-btn::after {
    transition: none;
  }
}

/* Gallery container */
.pl-gallery {
  display: flex;
  flex-direction: column;
  align-items: center;
  max-width: 1000px;
  margin: 0 auto;
  padding: 0 16px;
}

.pl-gallery > h2,
.pl-gallery > h3 {
  width: 100%;
  margin-bottom: 24px;
  font-size: 18px;
  font-weight: 600;
  color: var(--pl-text);
}

/* Gallery card grid */
.pl-gallery-cards {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(240px, 1fr));
  gap: 16px;
  width: 100%;
}

/* Gallery card — large clickable card with hover lift+glow */
.pl-gallery-card {
  display: flex;
  flex-direction: column;
  background: var(--pl-panel-1);
  border: 1px solid var(--pl-border);
  border-radius: 14px;
  padding: 20px;
  cursor: pointer;
  box-shadow: var(--pl-shadow-card);
  transition: all 200ms;
}

.pl-gallery-card:hover {
  transform: translateY(-4px);
  border-color: var(--pl-sky);
  box-shadow: var(--pl-shadow-float);
}

.pl-gallery-card:focus-visible {
  outline: 2px solid var(--pl-sky);
  outline-offset: 2px;
}

/* Selected card variant with sky ring */
.pl-gallery-card-sel {
  border: 2px solid var(--pl-sky);
  background: color-mix(in srgb, var(--pl-sky) 6%, var(--pl-panel-1));
  box-shadow: 0 0 0 1px var(--pl-sky), var(--pl-shadow-float);
}

@media (prefers-reduced-motion: reduce) {
  .pl-gallery-card {
    transition: none;
  }
}

/* Gallery thumbnail — 150px wireframe preview */
.pl-gallery-thumb {
  width: 100%;
  height: 150px;
  background: var(--pl-block);
  border: 1px solid var(--pl-border);
  border-radius: 8px;
  padding: 12px;
  display: flex;
  flex-direction: column;
  gap: 8px;
  margin-bottom: 12px;
  position: relative;
}

/* Wireframe bars — layered blocks pattern */
.pl-gallery-thumb::before {
  content: "";
  display: block;
  height: 6px;
  background: linear-gradient(
    90deg,
    var(--pl-blue) 0%,
    var(--pl-blue) 30%,
    transparent 30%,
    transparent 100%
  );
  border-radius: 2px;
}

.pl-gallery-thumb::after {
  content: "";
  position: absolute;
  bottom: 0;
  left: 0;
  right: 0;
  height: 4px;
  background: linear-gradient(
    90deg,
    var(--pl-sky) 0%,
    var(--pl-sky) 45%,
    var(--pl-green) 45%,
    var(--pl-green) 100%
  );
  border-radius: 0 0 8px 8px;
}

/* Nudge card — fixed bottom-right slide-in, glass */
.pl-nudge {
  position: fixed;
  bottom: 24px;
  right: 24px;
  max-width: 320px;
  border-radius: 12px;
  padding: 16px;
  z-index: 70;
  animation: slideInUp 300ms ease-out;
  font-size: 13px;
  color: var(--pl-text);
  line-height: 1.5;
}

.pl-nudge[hidden] {
  display: none !important;
}

@keyframes slideInUp {
  from {
    opacity: 0;
    transform: translateY(20px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

@media (prefers-reduced-motion: reduce) {
  .pl-nudge {
    animation: none;
  }
}

/* Save overlay — fixed inset backdrop with blur */
.pl-save-overlay {
  position: fixed;
  inset: 0;
  background: var(--pl-modal-backdrop);
  backdrop-filter: blur(4px);
  -webkit-backdrop-filter: blur(4px);
  z-index: 80;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 16px;
}

.pl-save-overlay[hidden] {
  display: none !important;
}

/* Save gate — centered modal card, glass */
.pl-save-gate {
  border-radius: 16px;
  padding: 24px;
  max-width: 520px;
  width: 100%;
  box-shadow: var(--pl-modal-shadow);
  animation: fadeInScale 250ms ease-out;
}

@keyframes fadeInScale {
  from {
    opacity: 0;
    transform: scale(0.95);
  }
  to {
    opacity: 1;
    transform: scale(1);
  }
}

@media (prefers-reduced-motion: reduce) {
  .pl-save-gate {
    animation: none;
  }
}

.pl-save-gate h2,
.pl-save-gate h3 {
  margin: 0 0 12px;
  color: var(--pl-text);
  font-size: 16px;
  font-weight: 600;
}

.pl-save-gate-body {
  display: grid;
  gap: 12px;
}

/* Save email input — full-width field */
.pl-save-email {
  width: 100%;
  padding: 12px;
  background: var(--pl-panel-1);
  border: 1px solid var(--pl-border);
  border-radius: 8px;
  color: var(--pl-text);
  font-family: var(--font-sans);
  font-size: 13px;
  box-sizing: border-box;
  transition: all 150ms;
}

.pl-save-email:focus {
  outline: none;
  border-color: var(--pl-blue);
  box-shadow: 0 0 0 2px color-mix(in srgb, var(--pl-blue) 20%, transparent);
}

.pl-save-email::placeholder {
  color: var(--pl-muted);
}

/* Save demo link — monospace, sky color, break long text */
.pl-save-demo-link {
  font-family: var(--font-mono);
  font-size: 12px;
  color: var(--pl-sky);
  word-break: break-all;
  white-space: pre-wrap;
  line-height: 1.4;
  padding: 12px;
  background: var(--pl-panel-1);
  border-radius: 6px;
  border: 1px solid color-mix(in srgb, var(--pl-sky) 20%, var(--pl-border));
  user-select: all;
}

/* ── Save gate button row ────────────────────────────────────────────────── */

.pl-save-actions {
  display: flex;
  gap: 8px;
  margin-top: 16px;
}

.pl-save-actions button {
  flex: 1;
  min-height: 34px;
  padding: 8px 16px;
  border: none;
  border-radius: 8px;
  font-size: 13px;
  font-weight: 500;
  cursor: pointer;
  transition: all 150ms;
  font-family: var(--font-sans);
}

.pl-save-actions .pl-save-confirm {
  background: var(--pl-btn-primary-grad);
  color: #ffffff;
  box-shadow: var(--pl-btn-shadow);
}

.pl-save-actions .pl-save-confirm:hover {
  box-shadow: var(--pl-btn-shadow-hover);
  transform: translateY(-1px);
}

.pl-save-actions .pl-save-cancel {
  background: transparent;
  border: 1px solid var(--pl-border);
  color: var(--pl-muted);
}

.pl-save-actions .pl-save-cancel:hover {
  border-color: var(--pl-blue);
  color: var(--pl-text);
}

@media (prefers-reduced-motion: reduce) {
  .pl-save-actions button {
    transition: none;
  }
}

/* planner round2 polish: gallery lists are semantic, not bulleted */
.pl-gallery ul,
.pl-gallery ol {
  list-style: none;
  margin: 0;
  padding: 0;
}

/* ── Accessibility and reduced motion (kills transitions/animations/sheen) */

@media (prefers-reduced-motion: reduce) {
  .pl-app * {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
  }
}

/* planner theme v3 */
/* ── Gallery showcase v4 — per-vertical thumb cards ─────────────────────────
   Upgrades .pl-gallery-card from generic wireframes to designed, per-kind
   showcase thumbs built from small reusable primitives (pl-th-*), tinted
   from each template's accent via the --th-accent custom property set
   inline on .pl-gallery-card. All non-accent color/spacing lives here on
   the existing --pl-* tokens so light/dark just work. */

/* ── Intro block ─────────────────────────────────────────────────────────── */

.pl-gallery-intro {
  width: 100%;
  max-width: 720px;
  margin: 0 auto 28px;
  text-align: center;
}

.pl-gallery-title {
  margin: 0 0 8px;
  font-family: var(--font-display);
  font-size: 22px;
  font-weight: 600;
  color: var(--pl-text);
  line-height: 1.3;
}

.pl-gallery-sub {
  margin: 0;
  font-size: 14px;
  color: var(--pl-muted);
  line-height: 1.5;
}

/* ── Grid: autofill, first card featured on wide screens ────────────────── */

.pl-gallery-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
  gap: 20px;
  width: 100%;
  list-style: none;
  margin: 0;
  padding: 0;
}

.pl-gallery-grid > li {
  display: contents;
}

@media (min-width: 900px) {
  .pl-gallery-grid > li:first-child > .pl-gallery-card {
    grid-column: span 2;
  }
  .pl-gallery-grid > li:first-child .pl-gallery-thumb {
    height: 210px;
  }
}

/* ── Card chrome ─────────────────────────────────────────────────────────── */

.pl-gallery-card {
  display: flex;
  flex-direction: column;
  width: 100%;
  background: var(--pl-glass-bg);
  border: 1px solid var(--pl-glass-border);
  border-radius: 16px;
  padding: 16px;
  cursor: pointer;
  text-align: left;
  box-shadow: var(--pl-shadow-card);
  backdrop-filter: blur(10px);
  -webkit-backdrop-filter: blur(10px);
  transition: transform 200ms ease, box-shadow 200ms ease, border-color 200ms ease;
  font-family: var(--font-sans);
}

.pl-gallery-card:hover {
  transform: translateY(-3px);
  border-color: color-mix(in srgb, var(--th-accent, var(--pl-sky)) 55%, var(--pl-border));
  box-shadow: var(--pl-shadow-float);
}

.pl-gallery-card:focus-visible {
  outline: 2px solid var(--th-accent, var(--pl-sky));
  outline-offset: 2px;
}

.pl-gallery-card-sel {
  border: 2px solid var(--th-accent, var(--pl-sky));
  background: color-mix(in srgb, var(--th-accent, var(--pl-sky)) 8%, var(--pl-glass-bg));
  box-shadow: 0 0 0 1px color-mix(in srgb, var(--th-accent, var(--pl-sky)) 60%, transparent),
    var(--pl-shadow-float);
}

@media (prefers-reduced-motion: reduce) {
  .pl-gallery-card {
    transition: none;
  }
  .pl-gallery-card:hover {
    transform: none;
  }
}

/* Hover lift/parallax on the thumb itself, on top of the card lift. */
.pl-gallery-thumb {
  transition: transform 200ms ease;
}

.pl-gallery-card:hover .pl-gallery-thumb {
  transform: translateY(-2px) scale(1.01);
}

@media (prefers-reduced-motion: reduce) {
  .pl-gallery-thumb {
    transition: none;
  }
  .pl-gallery-card:hover .pl-gallery-thumb {
    transform: none;
  }
}

/* ── Card body text ──────────────────────────────────────────────────────── */

.pl-gallery-card-body {
  display: flex;
  flex-direction: column;
  gap: 3px;
}

.pl-gallery-card-eyebrow {
  font-family: var(--font-mono);
  font-size: 10px;
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: color-mix(in srgb, var(--th-accent, var(--pl-sky)) 75%, var(--pl-muted));
  margin-bottom: 2px;
}

.pl-gallery-card-name {
  font-family: var(--font-display);
  font-size: 18px;
  font-weight: 600;
  color: var(--pl-text);
  line-height: 1.25;
}

.pl-gallery-card-accent {
  display: block;
  width: 32px;
  height: 3px;
  border-radius: 2px;
  margin: 6px 0 8px;
  background: var(--th-accent, var(--pl-sky));
}

.pl-gallery-card-company {
  font-size: 12px;
  font-weight: 600;
  color: var(--pl-faint);
}

.pl-gallery-card-desc {
  font-size: 13px;
  color: var(--pl-muted);
  line-height: 1.45;
  margin-bottom: 4px;
}

.pl-gallery-card-foot {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  margin-top: 10px;
}

.pl-gallery-card-foot .pl-btn-ghost {
  font-size: 12px;
  padding: 6px 12px;
  pointer-events: none;
}

.pl-gallery-foot {
  width: 100%;
  max-width: 720px;
  margin: 24px auto 0;
  text-align: center;
  font-size: 13px;
  color: var(--pl-faint);
  line-height: 1.5;
}

/* ── Thumb frame ─────────────────────────────────────────────────────────── */

.pl-gallery-thumb {
  --th-accent-soft: color-mix(in srgb, var(--th-accent, var(--pl-sky)) 16%, var(--pl-block));
  --th-accent-mid: color-mix(in srgb, var(--th-accent, var(--pl-sky)) 40%, var(--pl-block));
  width: 100%;
  height: 168px;
  background: var(--pl-block);
  border: 1px solid var(--pl-border);
  border-radius: 12px;
  padding: 10px;
  margin-bottom: 14px;
  display: flex;
  flex-direction: column;
  gap: 6px;
  overflow: hidden;
  position: relative;
}

/* ── Primitives ──────────────────────────────────────────────────────────── */

.pl-th-band {
  display: block;
  flex: 1 1 auto;
  min-height: 0;
  border-radius: 8px;
  background: linear-gradient(135deg, var(--th-accent-soft), var(--th-accent-mid));
}

.pl-th-row {
  display: flex;
  align-items: center;
  gap: 6px;
  flex: 0 0 auto;
}

.pl-th-tile {
  flex: 1 1 0;
  min-width: 0;
  height: 34px;
  border-radius: 6px;
  background: var(--pl-panel-1);
  border: 1px solid var(--pl-border);
}

.pl-th-pill {
  align-self: flex-start;
  flex: 0 0 auto;
  padding: 5px 12px;
  border-radius: 999px;
  font-size: 10px;
  font-weight: 600;
  color: #fff;
  background: var(--th-accent, var(--pl-sky));
  white-space: nowrap;
}

.pl-th-split {
  display: flex;
  gap: 4px;
  flex: 1 1 auto;
  min-height: 0;
}

.pl-th-split .pl-th-tile {
  height: auto;
  border-radius: 8px;
}

.pl-th-split .pl-th-tile:first-child {
  background: var(--pl-panel-2);
}

.pl-th-split .pl-th-tile:last-child {
  background: var(--th-accent-soft);
  border-color: color-mix(in srgb, var(--th-accent, var(--pl-sky)) 35%, var(--pl-border));
}

.pl-th-dot {
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--th-accent, var(--pl-sky));
  margin-left: auto;
  flex: 0 0 auto;
}

.pl-th-grid2 {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 6px;
  flex: 1 1 auto;
  min-height: 0;
}

.pl-th-grid2 .pl-th-tile,
.pl-th-grid2 .pl-th-row {
  height: auto;
}

.pl-th-stripe {
  flex: 1 1 0;
  min-width: 0;
  height: 100%;
  min-height: 18px;
  border-radius: 4px;
  background: var(--th-accent-mid);
}

/* ── Per-kind tuning: same primitives, different feel via nth-child ─────── */

/* Hauling: hero band up top, tiles as service cards below. */
.pl-gallery-thumb[data-pl-kind="hauling"] .pl-th-row .pl-th-tile {
  background: var(--pl-panel-1);
}

/* Salon: rounder image-grid tiles. */
.pl-gallery-thumb[data-pl-kind="salon"] .pl-th-grid2 .pl-th-tile {
  border-radius: 10px;
  background: linear-gradient(160deg, var(--th-accent-soft), var(--pl-panel-1));
}

/* Ranch: wide landscape band + season strip with alternating tone. */
.pl-gallery-thumb[data-pl-kind="ranch"] .pl-th-band {
  flex: 1 1 70%;
}

.pl-gallery-thumb[data-pl-kind="ranch"] .pl-th-row {
  flex: 0 0 22px;
}

.pl-gallery-thumb[data-pl-kind="ranch"] .pl-th-stripe:nth-child(2n) {
  background: var(--th-accent-soft);
}

/* Contractor: before/after split reads left-flat, right-tinted. */
.pl-gallery-thumb[data-pl-kind="contractor"] .pl-th-split {
  flex: 1 1 60%;
}

.pl-gallery-thumb[data-pl-kind="contractor"] .pl-th-row {
  flex: 0 0 34px;
}

/* Clinic: calm header, quiet 2x2 card rows. */
.pl-gallery-thumb[data-pl-kind="clinic"] .pl-th-band {
  flex: 0 0 30%;
}

.pl-gallery-thumb[data-pl-kind="clinic"] .pl-th-grid2 .pl-th-row {
  min-height: 30px;
  border-radius: 6px;
  background: var(--pl-panel-1);
  border: 1px solid var(--pl-border);
}

/* Restaurant: menu rows, each a thin line ending in a price dot. */
.pl-gallery-thumb[data-pl-kind="restaurant"] {
  justify-content: space-evenly;
}

.pl-gallery-thumb[data-pl-kind="restaurant"] .pl-th-row {
  height: 10px;
  border-radius: 3px;
  background: var(--pl-panel-1);
  border: 1px solid var(--pl-border);
  padding: 0 8px;
}

/* Gym: dense schedule stripes, brighter on the "booked" slots. */
.pl-gallery-thumb[data-pl-kind="gym"] .pl-th-grid2 {
  grid-template-columns: repeat(3, 1fr);
  grid-auto-rows: 1fr;
}

.pl-gallery-thumb[data-pl-kind="gym"] .pl-th-stripe:nth-child(3n) {
  background: var(--th-accent, var(--pl-sky));
}

/* Bank: flat rate rows + a shield chip pinned to the corner. */
.pl-gallery-thumb[data-pl-kind="bank"] .pl-th-row {
  height: 22px;
  border-radius: 5px;
  background: var(--pl-panel-1);
  border: 1px solid var(--pl-border);
}

.pl-gallery-thumb[data-pl-kind="bank"] .pl-th-pill {
  align-self: flex-end;
  margin-top: auto;
}

/* Healthcare: urgent (accent) vs scheduled (neutral) side by side. */
.pl-gallery-thumb[data-pl-kind="healthcare"] .pl-th-split {
  flex: 1 1 100%;
}

.pl-gallery-thumb[data-pl-kind="healthcare"] .pl-th-split .pl-th-tile:first-child {
  background: color-mix(in srgb, var(--th-accent, var(--pl-red)) 22%, var(--pl-panel-1));
  border-color: color-mix(in srgb, var(--th-accent, var(--pl-red)) 45%, var(--pl-border));
}

/* Gov: plain banner strip + station rows, deliberately unfancy. */
.pl-gallery-thumb[data-pl-kind="gov"] .pl-th-band {
  flex: 0 0 26%;
  border-radius: 6px;
}

.pl-gallery-thumb[data-pl-kind="gov"] .pl-th-row {
  height: 20px;
  border-radius: 4px;
  background: var(--pl-panel-1);
  border: 1px solid var(--pl-border);
}

/* Portables: unit/trailer split + fence-panel stripes + book pill. */
.pl-gallery-thumb[data-pl-kind="portables"] .pl-th-split {
  flex: 1 1 100%;
  min-height: 42px;
}

.pl-gallery-thumb[data-pl-kind="portables"] .pl-th-split .pl-th-tile:first-child {
  background: color-mix(in srgb, var(--th-accent, var(--pl-green)) 28%, var(--pl-panel-1));
}

.pl-gallery-thumb[data-pl-kind="portables"] .pl-th-row {
  gap: 4px;
}

.pl-gallery-thumb[data-pl-kind="portables"] .pl-th-stripe {
  height: 10px;
  border-radius: 2px;
}

.pl-gallery-thumb[data-pl-kind="portables"] .pl-th-pill {
  align-self: flex-end;
  margin-top: auto;
}

/* [hidden] guard, matches the rest of the planner surface. */
.pl-gallery-thumb[hidden],
.pl-gallery-card[hidden] {
  display: none !important;
}

@media (prefers-reduced-motion: reduce) {
  .pl-gallery-thumb * {
    transition: none !important;
    animation: none !important;
  }
}

/* gallery showcase v4 */
/* ── Style studio: pickers + live sandbox + try-on (pl-studio-*) ─────────
   All colors/fonts the studio itself needs are read from --pl-studio-*
   custom properties set inline on .pl-studio by style_studio.rs (the
   canonical "inline style for user-picked dynamic values" case) — this
   sheet only wires those tokens into layout, chip states, and the sandbox
   mini-page. Existing --pl-* design tokens style everything else. */

.pl-studio {
  display: block;
}

.pl-studio [hidden] {
  display: none !important;
}

/* ── Two-column layout ────────────────────────────────────────────────── */

.pl-studio-grid {
  display: grid;
  grid-template-columns: minmax(300px, 420px) 1fr;
  gap: 20px;
  align-items: start;
}

.pl-studio-left {
  display: flex;
  flex-direction: column;
  gap: 16px;
  min-width: 0;
}

.pl-studio-right {
  position: sticky;
  top: 16px;
  display: flex;
  flex-direction: column;
  gap: 14px;
  min-width: 0;
}

@media (max-width: 950px) {
  .pl-studio-grid {
    grid-template-columns: 1fr;
  }

  .pl-studio-right {
    position: static;
  }
}

.pl-studio-panel {
  display: flex;
  flex-direction: column;
  gap: 4px;
}

.pl-studio-hint {
  margin: -4px 0 8px;
  font-size: 12px;
  line-height: 1.4;
  color: var(--pl-muted);
}

/* ── Color wheel ──────────────────────────────────────────────────────── */

.pl-studio-wheel-wrap {
  display: flex;
  justify-content: center;
  padding: 4px 0 6px;
}

.pl-studio-wheel {
  width: 220px;
  height: 220px;
  border-radius: 50%;
  cursor: crosshair;
  touch-action: none;
  box-shadow: var(--pl-shadow-card);
}

.pl-studio-wheel:focus-visible {
  outline: 2px solid var(--pl-sky);
  outline-offset: 4px;
}

.pl-studio-palette-row {
  display: flex;
  gap: 8px;
  flex-wrap: wrap;
  margin-top: 8px;
}

.pl-studio-swatch {
  flex: 1 1 56px;
  min-width: 52px;
  height: 50px;
  border-radius: 8px;
  border: 1px solid var(--pl-border);
  display: flex;
  align-items: flex-end;
  padding: 4px;
}

.pl-studio-swatch small {
  display: inline-block;
  padding: 1px 4px;
  border-radius: 4px;
  background: rgba(0, 0, 0, 0.4);
  color: #ffffff;
  font-size: 9px;
  line-height: 1.3;
  white-space: nowrap;
}

/* ── Chip rows: scheme, button style, glass intensity ────────────────── */

.pl-studio-scheme-row,
.pl-studio-style-chips,
.pl-studio-glass-chips {
  display: flex;
  gap: 6px;
  flex-wrap: wrap;
  margin-top: 10px;
}

.pl-studio-scheme-chip,
.pl-studio-style-chip {
  padding: 6px 12px;
  border-radius: 999px;
  border: 1px solid var(--pl-border);
  background: var(--pl-panel-2);
  color: var(--pl-muted);
  font-size: 12px;
  font-weight: 600;
  cursor: pointer;
  transition: all 150ms;
}

.pl-studio-scheme-chip:hover,
.pl-studio-style-chip:hover {
  border-color: var(--pl-studio-primary, var(--pl-blue));
  color: var(--pl-text);
}

.pl-studio-scheme-chip:focus-visible,
.pl-studio-style-chip:focus-visible,
.pl-studio-pairing-card:focus-visible,
.pl-studio-wheel:focus-visible,
.pl-studio-toggle-row:focus-visible {
  outline: 2px solid var(--pl-sky);
  outline-offset: 2px;
}

.pl-studio-scheme-chip[aria-checked="true"],
.pl-studio-style-chip[aria-checked="true"] {
  background: var(--pl-studio-primary);
  color: #ffffff;
  border-color: transparent;
  box-shadow: 0 4px 14px -6px color-mix(in srgb, var(--pl-studio-primary) 65%, transparent);
}

/* ── Type pairing cards ───────────────────────────────────────────────── */

.pl-studio-pairing-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 8px;
}

.pl-studio-pairing-card {
  text-align: left;
  display: flex;
  flex-direction: column;
  gap: 4px;
  padding: 10px 12px;
  border: 1px solid var(--pl-border);
  border-radius: 10px;
  background: var(--pl-panel-2);
  cursor: pointer;
  transition: border-color 150ms, background 150ms;
}

.pl-studio-pairing-card[aria-checked="true"] {
  border-color: var(--pl-studio-primary);
  background: color-mix(in srgb, var(--pl-studio-primary) 12%, var(--pl-panel-2));
}

.pl-studio-pairing-name {
  font-size: 15px;
  font-weight: 700;
  color: var(--pl-text);
}

.pl-studio-pairing-sample {
  font-size: 11px;
  color: var(--pl-muted);
}

/* ── Radius slider + button specimens ────────────────────────────────── */

.pl-studio-radius-row {
  display: flex;
  flex-direction: column;
  gap: 6px;
  font-size: 12px;
  font-weight: 600;
  color: var(--pl-muted);
  margin-bottom: 2px;
}

.pl-studio-slider {
  width: 100%;
  accent-color: var(--pl-studio-primary);
}

.pl-studio-btn-row {
  display: flex;
  gap: 10px;
  flex-wrap: wrap;
  margin-top: 12px;
  padding-top: 12px;
  border-top: 1px dashed var(--pl-border);
}

.pl-studio-btn {
  min-height: 36px;
  padding: 8px 16px;
  font-size: 12px;
  font-weight: 600;
  font-family: var(--pl-studio-font-body, inherit);
  border-radius: var(--pl-studio-radius, 10px);
  border: 1px solid transparent;
  cursor: default;
  transition: transform 150ms, box-shadow 150ms;
}

.pl-studio-btn-ghost {
  background: transparent;
  color: var(--pl-studio-ink);
  border-color: var(--pl-border);
}

[data-pl-studio-btn="gradient"] .pl-studio-btn-primary {
  background: linear-gradient(92deg, var(--pl-studio-primary), var(--pl-studio-partner));
  color: #ffffff;
  box-shadow: 0 10px 22px -10px color-mix(in srgb, var(--pl-studio-primary) 60%, transparent);
}

[data-pl-studio-btn="gradient"] .pl-studio-btn-secondary {
  background: transparent;
  color: var(--pl-studio-primary);
  border-color: var(--pl-studio-primary);
}

[data-pl-studio-btn="solid"] .pl-studio-btn-primary {
  background: var(--pl-studio-primary);
  color: #ffffff;
}

[data-pl-studio-btn="solid"] .pl-studio-btn-secondary {
  background: var(--pl-studio-partner);
  color: #ffffff;
}

[data-pl-studio-btn="outline"] .pl-studio-btn-primary {
  background: transparent;
  color: var(--pl-studio-primary);
  border-color: var(--pl-studio-primary);
}

[data-pl-studio-btn="outline"] .pl-studio-btn-secondary {
  background: transparent;
  color: var(--pl-studio-ink);
  border-color: var(--pl-border);
}

[data-pl-studio-btn="soft"] .pl-studio-btn-primary {
  background: color-mix(in srgb, var(--pl-studio-primary) 18%, transparent);
  color: var(--pl-studio-primary);
}

[data-pl-studio-btn="soft"] .pl-studio-btn-secondary {
  background: color-mix(in srgb, var(--pl-studio-partner) 18%, transparent);
  color: var(--pl-studio-partner);
}

/* ── Feel: glass chips + gradient-hero switch ────────────────────────── */

.pl-studio-toggle-row {
  display: flex;
  align-items: center;
  gap: 10px;
  width: 100%;
  padding: 8px 0 2px;
  margin-top: 4px;
  background: transparent;
  border: none;
  color: var(--pl-text);
  font-size: 13px;
  font-weight: 500;
  text-align: left;
  cursor: pointer;
}

.pl-studio-toggle {
  position: relative;
  flex: 0 0 auto;
  width: 36px;
  height: 20px;
  border-radius: 999px;
  background: var(--pl-border);
  transition: background 150ms;
}

.pl-studio-toggle::after {
  content: "";
  position: absolute;
  top: 2px;
  left: 2px;
  width: 16px;
  height: 16px;
  border-radius: 50%;
  background: #ffffff;
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.35);
  transition: transform 150ms;
}

.pl-studio-toggle-row[aria-checked="true"] .pl-studio-toggle {
  background: var(--pl-studio-primary);
}

.pl-studio-toggle-row[aria-checked="true"] .pl-studio-toggle::after {
  transform: translateX(16px);
}

/* ── Sandbox: the mini-page that repaints from --pl-studio-* tokens ─────
   Nav → hero → 3 tiles → footer, all colored/shaped from the draft. */

.pl-studio-sandbox {
  border-radius: 16px;
  overflow: hidden;
  border: 1px solid var(--pl-border);
  background: var(--pl-studio-paper);
  color: var(--pl-studio-ink);
  font-family: var(--pl-studio-font-body, inherit);
  box-shadow: var(--pl-shadow-card);
}

.pl-studio-sb-nav {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 14px 18px;
  border-bottom: 1px solid color-mix(in srgb, var(--pl-studio-ink) 10%, transparent);
}

.pl-studio-sb-brand {
  font-family: var(--pl-studio-font-display, inherit);
  font-weight: 800;
  font-size: 15px;
  color: var(--pl-studio-primary);
}

.pl-studio-sb-navlinks {
  display: flex;
  gap: 14px;
  font-size: 12px;
  opacity: 0.7;
}

.pl-studio-sb-hero {
  padding: 40px 20px;
  text-align: center;
  background: var(--pl-studio-paper);
  transition: background 150ms;
}

[data-pl-studio-gradient="true"] .pl-studio-sb-hero {
  background: linear-gradient(
    160deg,
    color-mix(in srgb, var(--pl-studio-primary) 16%, var(--pl-studio-paper)),
    var(--pl-studio-paper) 72%
  );
}

.pl-studio-sb-headline {
  margin: 0 0 8px;
  font-family: var(--pl-studio-font-display, inherit);
  font-size: 22px;
  font-weight: 700;
  line-height: 1.15;
}

.pl-studio-sb-sub {
  margin: 0 0 18px;
  font-size: 13px;
  opacity: 0.75;
}

.pl-studio-sb-cta {
  min-height: 40px;
}

.pl-studio-sb-tiles {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 10px;
  padding: 16px;
}

.pl-studio-sb-tile {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 6px;
  padding: 14px 8px;
  border-radius: calc(var(--pl-studio-radius, 10px) * 0.8);
  background: color-mix(in srgb, var(--pl-studio-ink) 5%, transparent);
  border: 1px solid color-mix(in srgb, var(--pl-studio-ink) 8%, transparent);
  font-size: 11px;
  text-align: center;
  transition: background 150ms, backdrop-filter 150ms;
}

[data-pl-studio-glass="1"] .pl-studio-sb-tile {
  background: color-mix(in srgb, var(--pl-studio-paper) 55%, transparent);
  backdrop-filter: blur(6px) saturate(1.15);
  -webkit-backdrop-filter: blur(6px) saturate(1.15);
}

[data-pl-studio-glass="2"] .pl-studio-sb-tile {
  background: color-mix(in srgb, var(--pl-studio-paper) 38%, transparent);
  border-color: color-mix(in srgb, #ffffff 30%, transparent);
  box-shadow: 0 10px 26px -14px rgba(0, 0, 0, 0.3);
  backdrop-filter: blur(14px) saturate(1.3);
  -webkit-backdrop-filter: blur(14px) saturate(1.3);
}

.pl-studio-sb-tile-dot {
  width: 10px;
  height: 10px;
  border-radius: 50%;
  background: var(--pl-studio-accent2);
}

.pl-studio-sb-footer {
  padding: 12px 18px;
  border-top: 1px solid color-mix(in srgb, var(--pl-studio-ink) 10%, transparent);
  font-size: 10px;
  opacity: 0.55;
  text-align: center;
}

/* ── Try-on actions + floating bar ───────────────────────────────────── */

.pl-studio-actions {
  display: flex;
  justify-content: flex-end;
}

.pl-tryon-bar {
  position: fixed;
  left: 50%;
  bottom: 20px;
  transform: translateX(-50%);
  z-index: 60;
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 10px 16px;
  border-radius: 999px;
  background: var(--pl-glass-bg);
  backdrop-filter: blur(16px) saturate(1.3);
  -webkit-backdrop-filter: blur(16px) saturate(1.3);
  border: 1px solid var(--pl-glass-border);
  box-shadow: var(--pl-shadow-float, var(--pl-glass-shadow));
}

@supports not ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
  .pl-tryon-bar {
    background: var(--pl-panel-2);
  }
}

.pl-tryon-msg {
  font-size: 12px;
  font-weight: 700;
  color: var(--pl-text);
  padding-right: 2px;
}

/* ── Reduced motion ───────────────────────────────────────────────────── */

@media (prefers-reduced-motion: reduce) {
  .pl-studio-scheme-chip,
  .pl-studio-style-chip,
  .pl-studio-pairing-card,
  .pl-studio-toggle,
  .pl-studio-toggle::after,
  .pl-studio-btn,
  .pl-studio-sb-tile,
  .pl-studio-sb-hero {
    transition: none;
  }
}

/* studio v5 */
/* Element inspector: magnifier trigger on every pl-wregion + fixed
   overlay/card that shows a zoomed region render (left) and an attributes
   panel with quick actions (right). Tokens only — no literal colors. */

/* ── Trigger: small magnifier, top-right of each region, ≥44px hit area ── */
.pl-wregion {
  position: relative;
}

.pl-inspect-btn {
  position: absolute;
  top: 4px;
  right: 4px;
  width: 44px;
  height: 44px;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 0;
  border: 1px solid var(--pl-border);
  border-radius: 8px;
  background: var(--pl-glass-bg);
  color: var(--pl-muted);
  font-size: 15px;
  line-height: 1;
  cursor: pointer;
  opacity: 0;
  transform: translateY(-2px);
  transition: opacity 150ms ease, transform 150ms ease, border-color 150ms ease,
    color 150ms ease;
}

.pl-wregion:hover .pl-inspect-btn,
.pl-wregion:focus-within .pl-inspect-btn,
.pl-inspect-btn:focus-visible {
  opacity: 1;
  transform: translateY(0);
}

.pl-inspect-btn:hover,
.pl-inspect-btn:focus-visible {
  border-color: var(--pl-sky);
  color: var(--pl-sky);
}

@media (prefers-reduced-motion: reduce) {
  .pl-inspect-btn {
    transition: none;
  }
}

/* ── Overlay + card: same glass/modal treatment as the save gate ── */
.pl-inspect-overlay {
  position: fixed;
  inset: 0;
  z-index: 60;
  background: var(--pl-modal-backdrop);
  backdrop-filter: blur(4px);
  -webkit-backdrop-filter: blur(4px);
}

.pl-inspector {
  position: fixed;
  z-index: 61;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  width: min(760px, calc(100vw - 32px));
  max-height: calc(100vh - 64px);
  overflow-y: auto;
  padding: 20px;
  border-radius: 14px;
  background: var(--pl-glass-bg);
  border: 1px solid var(--pl-glass-border);
  box-shadow: var(--pl-modal-shadow);
  backdrop-filter: blur(20px) saturate(1.3);
  -webkit-backdrop-filter: blur(20px) saturate(1.3);
}

@supports not
  ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
  .pl-inspector {
    background: var(--pl-panel-1);
  }
}

.pl-inspect-overlay[hidden],
.pl-inspector[hidden] {
  display: none;
}

.pl-inspect-close {
  position: absolute;
  top: 12px;
  right: 12px;
  width: 32px;
  height: 32px;
  display: flex;
  align-items: center;
  justify-content: center;
  border: 1px solid var(--pl-border);
  border-radius: 8px;
  background: var(--pl-panel-2);
  color: var(--pl-muted);
  font-size: 13px;
  cursor: pointer;
  transition: color 150ms ease, border-color 150ms ease;
}

.pl-inspect-close:hover,
.pl-inspect-close:focus-visible {
  color: var(--pl-text);
  border-color: var(--pl-sky);
}

.pl-inspect-body {
  display: grid;
  grid-template-columns: minmax(0, 1.2fr) minmax(0, 1fr);
  gap: 20px;
  margin-top: 8px;
}

@media (max-width: 640px) {
  .pl-inspect-body {
    grid-template-columns: 1fr;
  }
}

/* ── Left: zoomed wireframe bones, ~2x scale ── */
.pl-inspect-zoom {
  position: relative;
  min-height: 220px;
  padding: 16px;
  border: 1px dashed var(--pl-border);
  border-radius: 10px;
  background: var(--pl-panel-2);
  display: flex;
  align-items: center;
  justify-content: center;
  overflow: hidden;
}

.pl-inspect-zoom-inner {
  position: relative;
  transform: scale(2);
  transform-origin: center;
  font-family: var(--font-mono);
  font-size: 11px;
  width: 100%;
}

@media (prefers-reduced-motion: reduce) {
  .pl-inspect-zoom-inner {
    transition: none;
  }
}

.pl-inspect-pin {
  position: absolute;
  transform: translate(-50%, -100%) scale(0.5);
  transform-origin: bottom center;
}

/* ── Right: attributes panel ── */
.pl-inspect-attrs {
  display: flex;
  flex-direction: column;
  gap: 10px;
  min-width: 0;
}

.pl-inspect-chip {
  align-self: flex-start;
  padding: 3px 8px;
  border-radius: 6px;
  border: 1px solid var(--pl-border);
  background: var(--pl-panel-2);
  color: var(--pl-faint);
  font-family: var(--font-mono);
  font-size: 11px;
}

.pl-inspect-blurb {
  margin: 0;
  color: var(--pl-muted);
  font-size: 13px;
  line-height: 1.5;
}

.pl-inspect-swatch-row {
  display: flex;
  align-items: center;
  gap: 8px;
}

.pl-inspect-swatch {
  width: 18px;
  height: 18px;
  border-radius: 5px;
  border: 1px solid var(--pl-border);
  flex-shrink: 0;
}

.pl-inspect-swatch-label {
  font-family: var(--font-mono);
  font-size: 11px;
  color: var(--pl-faint);
}

.pl-inspect-actions {
  display: flex;
  flex-direction: column;
  gap: 8px;
  margin-top: 4px;
}

.pl-inspect-actions .pl-btn {
  width: 100%;
  justify-content: center;
}

/* inspector v5 */
/* ── Peek pop-outs: full-size single-setting previews (pl-peek-*) ────────
   Per-panel "Preview" buttons open one fixed overlay (always in the DOM,
   [hidden]-gated) whose glass card re-renders the shared sandbox mini-page
   large. The mini-page carries its own inline --pl-studio-* vars — one
   draft setting over the plan's baseline — so this sheet only does layout,
   the chip row, and the house glass treatment from existing --pl-* tokens. */

.pl-peek-overlay[hidden],
.pl-peek[hidden] {
  display: none !important;
}

/* ── Panel-header affordance ──────────────────────────────────────────── */

.pl-peek-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
}

.pl-peek-btn {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  min-width: 34px;
  min-height: 34px;
  padding: 5px 12px;
  border-radius: 999px;
  border: 1px solid var(--pl-border);
  background: var(--pl-panel-2);
  color: var(--pl-muted);
  font-size: 12px;
  font-weight: 600;
  white-space: nowrap;
  cursor: pointer;
  transition: border-color 150ms, color 150ms;
}

.pl-peek-btn:hover {
  border-color: var(--pl-studio-primary, var(--pl-blue));
  color: var(--pl-text);
}

.pl-peek-btn:focus-visible {
  outline: 2px solid var(--pl-sky);
  outline-offset: 2px;
}

.pl-peek-btn-eye {
  font-size: 14px;
  line-height: 1;
}

/* ── Fixed overlay + glass card ───────────────────────────────────────── */

.pl-peek-overlay {
  position: fixed;
  inset: 0;
  z-index: 90;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 24px;
  background: var(--pl-modal-backdrop);
}

.pl-peek {
  width: min(768px, 92vw);
  max-width: 92vw;
  max-height: min(88vh, 860px);
  display: flex;
  flex-direction: column;
  gap: 12px;
  padding: 18px;
  border-radius: 18px;
  overflow: auto;
  background: var(--pl-glass-bg);
  backdrop-filter: blur(16px) saturate(1.3);
  -webkit-backdrop-filter: blur(16px) saturate(1.3);
  border: 1px solid var(--pl-glass-border);
  box-shadow: var(--pl-modal-shadow, var(--pl-glass-shadow));
  animation: pl-peek-in 180ms ease-out;
}

@supports not ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
  .pl-peek {
    background: var(--pl-panel-2);
  }
}

@keyframes pl-peek-in {
  from {
    opacity: 0;
    transform: translateY(10px) scale(0.98);
  }

  to {
    opacity: 1;
    transform: none;
  }
}

/* ── Card header + chip row ───────────────────────────────────────────── */

.pl-peek-top {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
}

.pl-peek-title {
  margin: 0;
  font-size: 13px;
  font-weight: 700;
  color: var(--pl-text);
}

.pl-peek-close {
  flex: 0 0 auto;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 34px;
  min-height: 34px;
  border-radius: 50%;
  border: 1px solid var(--pl-border);
  background: var(--pl-panel-2);
  color: var(--pl-muted);
  font-size: 14px;
  line-height: 1;
  cursor: pointer;
  transition: border-color 150ms, color 150ms;
}

.pl-peek-close:hover {
  border-color: var(--pl-studio-primary, var(--pl-blue));
  color: var(--pl-text);
}

.pl-peek-close:focus-visible {
  outline: 2px solid var(--pl-sky);
  outline-offset: 2px;
}

.pl-peek-chips {
  display: flex;
  gap: 6px;
  flex-wrap: wrap;
}

.pl-peek-chip {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 4px 10px;
  border-radius: 999px;
  border: 1px solid var(--pl-border);
  background: var(--pl-panel-2);
  color: var(--pl-text);
  font-size: 11px;
  font-weight: 600;
}

.pl-peek-chip-dot {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  border: 1px solid var(--pl-border);
  /* background comes inline from the picked hex (user-picked dynamic value) */
}

/* ── Stage: the shared mini-page rendered LARGE (~720px, scales down) ─── */

.pl-peek-stage {
  width: min(720px, 100%);
  margin: 0 auto;
}

.pl-peek-stage .pl-studio-sandbox {
  width: 100%;
}

@media (max-width: 640px) {
  .pl-peek-overlay {
    padding: 12px;
  }

  .pl-peek {
    padding: 14px;
  }
}

/* ── Reduced motion ───────────────────────────────────────────────────── */

@media (prefers-reduced-motion: reduce) {
  .pl-peek,
  .pl-peek-btn,
  .pl-peek-close {
    animation: none;
    transition: none;
  }
}

/* peek v5.1 */

/* ── review fixes v5.2 (orchestrator) ─────────────────────────────────── */

/* stale v3 wireframe chrome must not paint over v4 showcase thumbs */
.pl-gallery-thumb::before,
.pl-gallery-thumb::after {
  content: none;
}

/* nudge dismiss: real target, corner placement, tokened */
.pl-nudge {
  position: fixed;
}
.pl-nudge-dismiss {
  position: absolute;
  top: 6px;
  right: 6px;
  width: 32px;
  height: 32px;
  display: grid;
  place-items: center;
  border-radius: 8px;
  color: var(--pl-muted);
  background: transparent;
  border: none;
  cursor: pointer;
}
.pl-nudge-dismiss::after {
  content: "";
  position: absolute;
  inset: -8px;
}
.pl-nudge-dismiss:hover {
  color: var(--pl-text);
  background: var(--pl-panel-2);
}
.pl-nudge-dismiss:focus-visible {
  outline: 2px solid var(--pl-sky);
  outline-offset: 2px;
}

/* tabs emit aria-pressed, not aria-selected */
.pl-tab[aria-pressed="true"] {
  background: var(--pl-panel-2);
  color: var(--pl-text);
}

/* selected swatch needs a visible ring + focus state */
.pl-swatch[aria-pressed="true"] {
  box-shadow: 0 0 0 2px var(--pl-panel-1), 0 0 0 4px var(--pl-sky);
}
.pl-swatch:focus-visible {
  outline: 2px solid var(--pl-sky);
  outline-offset: 2px;
}

/* 44px hit areas without visual bloat */
.pl-ptog,
.pl-swatch,
.pl-inspect-close,
.pl-theme-toggle,
.pl-tab {
  position: relative;
}
.pl-ptog::after,
.pl-swatch::after,
.pl-inspect-close::after {
  content: "";
  position: absolute;
  inset: -12px;
}
.pl-tab,
.pl-theme-toggle {
  min-height: 40px;
}

/* warn toast keeps base toast chrome */
.pl-warn-toast {
  border: 1px solid var(--pl-amber, #f59e0b);
}

/* pins anchor to the mockbox they were measured against */
.pl-mockbox {
  position: relative;
}

/* save gate: fixed, centered, above its scrim regardless of DOM nesting */
.pl-save-overlay {
  z-index: 80;
}
.pl-save-gate {
  position: fixed;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  z-index: 90;
  max-width: min(560px, 92vw);
  width: 100%;
  max-height: 88vh;
  overflow-y: auto;
}
.pl-save-close {
  position: absolute;
  top: 10px;
  right: 10px;
  width: 36px;
  height: 36px;
  display: grid;
  place-items: center;
  border-radius: 8px;
  color: var(--pl-muted);
  background: transparent;
  border: none;
  cursor: pointer;
}
.pl-save-close::after {
  content: "";
  position: absolute;
  inset: -8px;
}
.pl-save-close:hover {
  color: var(--pl-text);
  background: var(--pl-panel-2);
}
.pl-save-close:focus-visible {
  outline: 2px solid var(--pl-sky);
  outline-offset: 2px;
}

/* v5.2.1: the shared try-on bar must respect hidden (display:flex beat the UA default) */
.pl-tryon-bar[hidden] {
  display: none !important;
}

/* ── v5.2.2: mockups fill their space like real page thumbnails ────────── */
.pl-wire {
  display: flex;
  flex-direction: column;
  gap: 10px;
  min-height: 460px;
}
.pl-wregion {
  flex: 1 1 auto;
  display: flex;
  flex-direction: column;
}
.pl-wregion > div:not(.pl-hero-blk) {
  flex: 1;
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: 8px;
}
.pl-wregion:has(.pl-hero-blk) {
  flex: 2 1 auto;
}
.pl-wregion .pl-hero-blk {
  flex: 1;
}
.pl-wregion .pl-g3 {
  flex: 1;
  display: grid;
  align-items: stretch;
}
.pl-wregion .pl-g3 .pl-blk {
  height: auto;
  min-height: 40px;
}
/* nodethumbs v5.3 */
/* ── Picture marks: real generated mockups layered over the wireframe
   primitives (pl-nt-*) and skeleton bones (pl-wire). Convention: images
   live at /planner/mockups/{template}/{page_id}.png once the pipeline has
   run them; requested/new pages never get an <img> (skipped in markup, not
   just hidden). Everywhere an <img> IS rendered, the primitives/bones it
   covers are still present underneath, unconditionally — so a 404 (image
   requested but pipeline hasn't produced it yet) falls back to the honest
   wireframe via the img's own on:error handler, no layout shift, no shape
   divergence between ssr and hydrate. */

/* Tier-3 page-card and gallery-card thumbs: image covers the primitive
   skeleton absolutely, within the existing (already-positioned) card. */

.pl-nt-img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  border-radius: 6px;
  z-index: 1;
}

.pl-nt-img-missing {
  display: none !important;
}

/* Detail-view mockbox: full-width banner above the interactive wireframe
   regions — regions stay in normal flow underneath as real click targets,
   the banner is purely a picture mark, not a hit-test surface. */
.pl-mock-img {
  display: block;
  width: 100%;
  height: auto;
  border-radius: 10px;
  border: 1px solid var(--pl-border);
  margin-bottom: 10px;
}

.pl-mock-img-missing {
  display: none !important;
}

/* Dark theme: images keep their own colors as-is — just a touch less
   glare against the dark ground, matching how photography reads dimmed
   everywhere else in the dark theme. */
[data-pl-theme="dark"] .pl-nt-img,
[data-pl-theme="dark"] .pl-mock-img {
  filter: brightness(0.92);
}

/* picturemark v6 */

/* ── v6.1: picture marks fill their space, primitives fully suppressed ── */
.pl-gallery-thumb {
  position: relative;
  height: auto;
  aspect-ratio: 8 / 5;
  overflow: hidden;
}
.pl-nt-img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: top center;
  z-index: 2;
  border-radius: inherit;
  background: var(--pl-panel-2);
}
/* DANGER-MEMO NOTE: the old `.pl-gallery-thumb:has(.pl-nt-img:not(
   .pl-nt-img-missing))` "hidden" polarity rule that used to live here is
   deleted for real (main.css:6536-6539 per the fix2-tour-gallery.css
   dead-rule ledger below) — superseded by the `.pl-nt-img-loaded`-keyed
   rule in that same fix2-tour-gallery.css block further down this file.
   The sibling "visible" rule right below (keyed on .pl-nt-img-missing) is
   UNCHANGED and still correct, per that same ledger — left in place. */
.pl-nt-img-missing {
  display: none !important;
}
.pl-gallery-thumb:has(.pl-nt-img-missing) > :not(.pl-nt-img),
.pl-node-thumb:has(.pl-nt-img-missing) > :not(.pl-nt-img) {
  visibility: visible;
}

/* ── v6.2: node card text hierarchy (ids/titles/desc were running together) ── */
.pl-node .pl-nid {
  display: block;
  margin-bottom: 3px;
  font-size: 9.5px;
  letter-spacing: 0.06em;
  text-transform: uppercase;
}
.pl-node .pl-nt {
  display: block;
  font-size: 14px;
  line-height: 1.25;
  margin-bottom: 3px;
}
.pl-node .pl-nk {
  display: block;
  font-size: 11.5px;
  line-height: 1.45;
}
.pl-node .pl-chip {
  margin-top: 7px;
  display: inline-block;
}
.pl-node-site .pl-nid { text-align: center; }
/* ─────────────────────────────────────────────────────────────────────────
   D3pth Planner — map zones. Three-zone IA for the Plan map:
     Zone 1 "your business"  (pl-zone-biz)   — wide company header card
     Zone 2 "the work area"  (pl-zone-pages) — area tabs + roomy page grid
     Zone 3 "the web"        (pl-zone-web)   — full-plan micro-node overview
   Layout + new surfaces only: node interiors, chips, picture marks, flow
   handles, and the edge canvas keep their existing sheets. Tokens only
   (--pl-*, --font-*); light is the .pl-app default, dark comes free via
   the .pl-app[data-pl-theme="dark"] token re-declarations upstream.
   ───────────────────────────────────────────────────────────────────────── */

/* ── Stage: three stacked zones, its own vertical scroller ─────────────── */

.pl-app .pl-map-stage {
  display: flex;
  flex-direction: column;
  gap: 18px;
  padding: 16px;
  overflow-y: auto;
  overflow-x: hidden;
}

/* [hidden] guard for the surviving zone surface. */
.pl-area-tabs[hidden] {
  display: none !important;
}

/* ── Zone 2 — the work area ────────────────────────────────────────────── */

/* Segmented area switcher — one pill per surface. */
.pl-area-tabs {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  width: fit-content;
  max-width: 100%;
  padding: 6px;
  border-radius: 14px;
  background: var(--pl-glass-bg);
  border: 1px solid var(--pl-glass-border);
  -webkit-backdrop-filter: blur(10px);
  backdrop-filter: blur(10px);
  box-shadow: var(--pl-shadow-card);
}

.pl-area-tab {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  min-height: 40px;
  padding: 8px 14px;
  border-radius: 10px;
  border: 1px solid transparent;
  background: transparent;
  color: var(--pl-muted);
  font-size: 13px;
  font-weight: 600;
  cursor: pointer;
  transition: color 150ms, background-color 150ms, border-color 150ms;
}

.pl-area-tab:hover {
  color: var(--pl-text);
  border-color: var(--pl-border);
}

.pl-area-tab[aria-pressed="true"] {
  color: var(--pl-text);
  background: var(--pl-panel-2);
  border-color: color-mix(in srgb, var(--pl-sky) 45%, var(--pl-border));
  box-shadow: 0 0 0 1px color-mix(in srgb, var(--pl-sky) 35%, transparent);
}

.pl-area-tab:focus-visible {
  outline: 2px solid var(--pl-sky);
  outline-offset: 2px;
}

.pl-area-tab-count {
  font-family: var(--font-mono);
  font-size: 11px;
  line-height: 1;
  padding: 3px 7px;
  border-radius: 999px;
  background: var(--pl-block);
  color: var(--pl-faint);
}

.pl-area-lock {
  font-size: 11px;
  line-height: 1;
  filter: grayscale(1);
  opacity: 0.7;
}

.pl-page-cell {
  display: flex;
  min-width: 0;
}

/* ── Reduced motion ─────────────────────────────────────────────────────── */

@media (prefers-reduced-motion: reduce) {
  .pl-area-tab {
    transition: none !important;
  }
}

/* mapzones v6.2 */
/* ── Style studio v2: centerstage layout + new modifiers ──────────────────
   Loaded downstream of main.css (cascade-later wins), so every studio
   layout class this file touches is RE-DECLARED here rather than patched —
   do not assume main.css's original .pl-studio-grid/.pl-studio-left/
   .pl-studio-right rules still apply; they're superseded below.

   New sitewide custom props (emitted inline by StudioTheme::vars() in
   style_studio.rs, same "user-picked dynamic value" pattern as the
   existing --pl-studio-* tokens):
     --pl-studio-space     10 / 16 / 24px   (density: compact/comfy/airy)
     --pl-studio-anim-ms   500/320/180ms    (speed: calm/standard/lively)
     --pl-studio-shadow    box-shadow preset (depth: flat/soft/floating)

   New data-* keyword attributes (mirrors the existing data-pl-studio-btn/
   -glass/-gradient pattern for non-numeric choices):
     data-pl-studio-entrance   none|fade|rise|scale   — on .pl-studio-sandbox
     data-pl-studio-hover      lift|sheen|pulse       — on .pl-studio-sandbox
                                                          AND .pl-studio-btn-row
     .pl-studio-entrance-play  toggled by a reflow trick in style_studio.rs
                                to force the CSS keyframe to restart */

.pl-studio [hidden] {
  display: none !important;
}

/* ── Three-column stage: left rail / center device / right rail ─────────── */

.pl-studio-stage {
  display: grid;
  grid-template-columns: minmax(240px, 300px) minmax(420px, 1fr) minmax(240px, 300px);
  grid-template-areas: "rail-l center rail-r";
  gap: 18px;
  align-items: start;
}

.pl-studio-rail-l {
  grid-area: rail-l;
  display: flex;
  flex-direction: column;
  gap: 12px;
  min-width: 0;
}

.pl-studio-rail-r {
  grid-area: rail-r;
  display: flex;
  flex-direction: column;
  gap: 12px;
  min-width: 0;
}

.pl-studio-center {
  grid-area: center;
  display: flex;
  flex-direction: column;
  gap: 12px;
  min-width: 0;
}

@media (min-width: 1101px) {
  .pl-studio-center {
    position: sticky;
    top: 16px;
  }
}

@media (max-width: 1100px) {
  .pl-studio-stage {
    grid-template-columns: 1fr 1fr;
    grid-template-areas:
      "center center"
      "rail-l rail-r";
  }
}

@media (max-width: 700px) {
  .pl-studio-stage {
    grid-template-columns: 1fr;
    grid-template-areas:
      "center"
      "rail-l"
      "rail-r";
  }
}

/* ── Compact panels: tight paddings, all controls stay visible ──────────── */

.pl-studio-rail-l .pl-panel,
.pl-studio-rail-r .pl-panel {
  border-radius: 10px;
  padding: 12px;
}

.pl-studio-rail-l .pl-panel-h,
.pl-studio-rail-r .pl-panel-h {
  margin-bottom: 0;
  font-size: 12.5px;
}

.pl-studio-panel {
  display: flex;
  flex-direction: column;
  gap: 4px;
}

.pl-studio-hint {
  margin: -2px 0 4px;
  font-size: 11px;
  line-height: 1.4;
  color: var(--pl-muted);
}

.pl-studio-subhint {
  margin: 6px 0 -2px;
  font-size: 10px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--pl-muted);
  opacity: 0.8;
}

/* ── Color wheel + chip rows: compact spacing only, rest inherited ──────── */

.pl-studio-wheel-wrap {
  display: flex;
  justify-content: center;
  padding: 2px 0 4px;
}

.pl-studio-palette-row {
  display: flex;
  gap: 6px;
  flex-wrap: wrap;
  margin-top: 6px;
}

.pl-studio-swatch {
  flex: 1 1 48px;
  min-width: 44px;
  height: 42px;
  border-radius: 7px;
  border: 1px solid var(--pl-border);
  display: flex;
  align-items: flex-end;
  padding: 3px;
}

.pl-studio-scheme-row,
.pl-studio-style-chips,
.pl-studio-glass-chips {
  display: flex;
  gap: 5px;
  flex-wrap: wrap;
  margin-top: 6px;
}

.pl-studio-scheme-chip,
.pl-studio-style-chip {
  padding: 5px 10px;
  border-radius: 999px;
  border: 1px solid var(--pl-border);
  background: var(--pl-panel-2);
  color: var(--pl-muted);
  font-size: 11px;
  font-weight: 600;
  cursor: pointer;
  transition: all 150ms;
}

.pl-studio-scheme-chip:hover,
.pl-studio-style-chip:hover {
  border-color: var(--pl-studio-primary, var(--pl-blue));
  color: var(--pl-text);
}

.pl-studio-scheme-chip[aria-checked="true"],
.pl-studio-style-chip[aria-checked="true"] {
  background: var(--pl-studio-primary);
  color: #ffffff;
  border-color: transparent;
  box-shadow: 0 4px 14px -6px color-mix(in srgb, var(--pl-studio-primary) 65%, transparent);
}

.pl-studio-pairing-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 6px;
}

.pl-studio-pairing-card {
  text-align: left;
  display: flex;
  flex-direction: column;
  gap: 3px;
  padding: 8px 10px;
  border: 1px solid var(--pl-border);
  border-radius: 9px;
  background: var(--pl-panel-2);
  cursor: pointer;
  transition: border-color 150ms, background 150ms;
}

.pl-studio-pairing-card[aria-checked="true"] {
  border-color: var(--pl-studio-primary);
  background: color-mix(in srgb, var(--pl-studio-primary) 12%, var(--pl-panel-2));
}

.pl-studio-radius-row {
  display: flex;
  flex-direction: column;
  gap: 4px;
  font-size: 11px;
  font-weight: 600;
  color: var(--pl-muted);
  margin-bottom: 0;
}

.pl-studio-btn-row {
  display: flex;
  gap: 8px;
  flex-wrap: wrap;
  margin-top: 8px;
  padding-top: 8px;
  border-top: 1px dashed var(--pl-border);
}

.pl-studio-toggle-row {
  padding: 6px 0 0;
  margin-top: 2px;
}

/* ── Device frame: browser chrome bar over the sandbox ───────────────────── */

.pl-studio-device {
  width: min(460px, 100%);
  margin: 0 auto;
  border-radius: 18px;
  overflow: hidden;
  border: 1px solid var(--pl-border);
  background: var(--pl-panel-2);
  box-shadow: var(--pl-shadow-card);
}

.pl-studio-device-chrome {
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 9px 12px;
  background: var(--pl-panel-2);
  border-bottom: 1px solid var(--pl-border);
}

.pl-studio-device-dot {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: var(--pl-border);
}

.pl-studio-device-url {
  margin-left: 8px;
  padding: 3px 10px;
  border-radius: 999px;
  background: var(--pl-panel);
  color: var(--pl-muted);
  font-size: 10px;
  font-weight: 600;
  letter-spacing: 0.02em;
}

.pl-studio-device .pl-studio-sandbox {
  border: none;
  border-radius: 0;
  box-shadow: none;
}

/* ── Sandbox: same nav → hero → tiles → footer, now spaced by density ───── */

.pl-studio-sandbox {
  border-radius: 16px;
  overflow: hidden;
  border: 1px solid var(--pl-border);
  background: var(--pl-studio-paper);
  color: var(--pl-studio-ink);
  font-family: var(--pl-studio-font-body, inherit);
  box-shadow: var(--pl-studio-shadow, var(--pl-shadow-card));
  transition: box-shadow 150ms;
}

.pl-studio-sb-nav {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: calc(var(--pl-studio-space, 16px) * 0.875) calc(var(--pl-studio-space, 16px) * 1.125);
  border-bottom: 1px solid color-mix(in srgb, var(--pl-studio-ink) 10%, transparent);
}

.pl-studio-sb-hero {
  padding: calc(var(--pl-studio-space, 16px) * 2.5) calc(var(--pl-studio-space, 16px) * 1.25);
  text-align: center;
  background: var(--pl-studio-paper);
  transition: background 150ms, padding 150ms;
}

[data-pl-studio-gradient="true"] .pl-studio-sb-hero {
  background: linear-gradient(
    160deg,
    color-mix(in srgb, var(--pl-studio-primary) 16%, var(--pl-studio-paper)),
    var(--pl-studio-paper) 72%
  );
}

.pl-studio-sb-tiles {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: calc(var(--pl-studio-space, 16px) * 0.625);
  padding: var(--pl-studio-space, 16px);
}

.pl-studio-sb-tile {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: calc(var(--pl-studio-space, 16px) * 0.375);
  padding: calc(var(--pl-studio-space, 16px) * 0.875) calc(var(--pl-studio-space, 16px) * 0.5);
  border-radius: calc(var(--pl-studio-radius, 10px) * 0.8);
  background: color-mix(in srgb, var(--pl-studio-ink) 5%, transparent);
  border: 1px solid color-mix(in srgb, var(--pl-studio-ink) 8%, transparent);
  font-size: 11px;
  text-align: center;
  transition: background 150ms, backdrop-filter 150ms, padding 150ms;
}

.pl-studio-sb-footer {
  padding: calc(var(--pl-studio-space, 16px) * 0.75) calc(var(--pl-studio-space, 16px) * 1.125);
  border-top: 1px solid color-mix(in srgb, var(--pl-studio-ink) 10%, transparent);
  font-size: 10px;
  opacity: 0.55;
  text-align: center;
}

/* ── Entrance animations: replayed on every draft change via a bump-driven
   remove/reflow/add of .pl-studio-entrance-play (see studio_mini_page) ──── */

@keyframes pl-studio-anim-fade {
  from { opacity: 0; }
  to { opacity: 1; }
}

@keyframes pl-studio-anim-rise {
  from { opacity: 0; transform: translateY(18px); }
  to { opacity: 1; transform: translateY(0); }
}

@keyframes pl-studio-anim-scale {
  from { opacity: 0; transform: scale(0.94); }
  to { opacity: 1; transform: scale(1); }
}

.pl-studio-sandbox.pl-studio-entrance-play[data-pl-studio-entrance="fade"] {
  animation: pl-studio-anim-fade var(--pl-studio-anim-ms, 320ms) ease-out;
}

.pl-studio-sandbox.pl-studio-entrance-play[data-pl-studio-entrance="rise"] {
  animation: pl-studio-anim-rise var(--pl-studio-anim-ms, 320ms) ease-out;
}

.pl-studio-sandbox.pl-studio-entrance-play[data-pl-studio-entrance="scale"] {
  animation: pl-studio-anim-scale var(--pl-studio-anim-ms, 320ms) ease-out;
}

/* ── Hover behaviors: sandbox CTA + Buttons panel specimen row ───────────── */

@keyframes pl-studio-anim-pulse {
  0%, 100% { transform: scale(1); }
  50% { transform: scale(1.045); }
}

[data-pl-studio-hover="lift"] .pl-studio-btn {
  transition: transform var(--pl-studio-anim-ms, 320ms) ease, box-shadow var(--pl-studio-anim-ms, 320ms) ease;
}

[data-pl-studio-hover="lift"] .pl-studio-btn:hover {
  transform: translateY(-2px);
}

[data-pl-studio-hover="sheen"] .pl-studio-btn {
  position: relative;
  overflow: hidden;
}

[data-pl-studio-hover="sheen"] .pl-studio-btn::after {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(115deg, transparent 35%, rgba(255, 255, 255, 0.4) 50%, transparent 65%);
  transform: translateX(-120%);
  transition: transform var(--pl-studio-anim-ms, 320ms) ease;
  pointer-events: none;
}

[data-pl-studio-hover="sheen"] .pl-studio-btn:hover::after {
  transform: translateX(120%);
}

[data-pl-studio-hover="pulse"] .pl-studio-btn:hover {
  animation: pl-studio-anim-pulse var(--pl-studio-anim-ms, 320ms) ease-in-out infinite;
}

/* ── Live caption under the try-on button ─────────────────────────────────── */

.pl-studio-actions {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 6px;
}

.pl-studio-live-caption {
  margin: 0;
  font-size: 11px;
  color: var(--pl-muted);
  text-align: center;
}

/* ── Peek stage: keep the shared mini-page centered inside the pop-out ───── */

.pl-peek-stage .pl-studio-sandbox {
  width: 100%;
}

/* ── Reduced motion: kill every studio-v2 animation and transition ──────── */

@media (prefers-reduced-motion: reduce) {
  .pl-studio-sandbox,
  .pl-studio-sandbox.pl-studio-entrance-play,
  .pl-studio-sb-hero,
  .pl-studio-sb-tile,
  .pl-studio-btn,
  .pl-studio-btn::after {
    animation: none !important;
    transition: none !important;
  }

  [data-pl-studio-hover="lift"] .pl-studio-btn:hover {
    transform: none;
  }

  [data-pl-studio-hover="pulse"] .pl-studio-btn:hover {
    animation: none !important;
  }
}

/* studio v2 centerstage */
/* ── Build-your-own wizard (pl-wiz-*) ─────────────────────────────────────
   Full-screen takeover. Tokens only (--pl-*); the stage additionally reads
   --pl-wiz-accent/-2/-3, set inline per-render from the current palette by
   wizard.rs. Glass surfaces mirror the save-gate/style-studio treatment. */

.pl-wizard {
  position: fixed;
  inset: 0;
  z-index: 80;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 16px;
  background: var(--pl-modal-backdrop);
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
}

.pl-wizard[hidden] {
  display: none !important;
}

.pl-wiz-shell {
  display: flex;
  flex-direction: column;
  width: min(1180px, 100%);
  height: min(880px, 100%);
  background: var(--pl-panel-1);
  border: 1px solid var(--pl-border);
  border-radius: 18px;
  box-shadow: var(--pl-modal-shadow);
  overflow: hidden;
}

/* ── Header ────────────────────────────────────────────────────────────── */

.pl-wiz-head {
  display: flex;
  align-items: baseline;
  gap: 10px;
  padding: 16px 20px 10px;
  border-bottom: 1px solid var(--pl-border);
  flex-shrink: 0;
}

.pl-wiz-step-label {
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--pl-faint);
}

.pl-wiz-title {
  flex: 1;
  margin: 0;
  font-size: 18px;
  font-weight: 700;
  color: var(--pl-text);
}

.pl-wiz-close {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 32px;
  height: 32px;
  border-radius: 8px;
  border: 1px solid var(--pl-border);
  background: var(--pl-panel-2);
  color: var(--pl-muted);
  cursor: pointer;
  font-size: 14px;
  transition: background 120ms, color 120ms;
}

.pl-wiz-close:hover {
  background: var(--pl-block);
  color: var(--pl-text);
}

.pl-wiz-close:focus-visible {
  outline: 2px solid var(--pl-blue);
  outline-offset: 2px;
}

.pl-wiz-banner {
  margin: 0;
  padding: 8px 20px;
  font-size: 12.5px;
  color: var(--pl-blue);
  background: color-mix(in srgb, var(--pl-blue) 8%, var(--pl-panel-1));
  border-bottom: 1px solid var(--pl-border);
  flex-shrink: 0;
}

/* ── Main: rail | stage ───────────────────────────────────────────────── */
/* DEAD: .pl-wiz-main (grid rail|stage wrapper) removed here — wizard.rs
   renders .pl-wiz-panes for this wrapper instead (see the matching DEAD
   note further down this file, near .pl-wiz-edit, for the full context
   on this and .pl-wiz-stage-wrap below). */

.pl-wiz-rail {
  overflow-y: auto;
  padding: 18px 20px 24px;
  border-right: 1px solid var(--pl-border);
}

.pl-wiz-rail-body {
  display: flex;
  flex-direction: column;
  gap: 10px;
  animation: pl-wiz-fade 150ms ease;
}

@keyframes pl-wiz-fade {
  from {
    opacity: 0;
    transform: translateY(4px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

.pl-wiz-q {
  margin: 0;
  font-size: 16px;
  font-weight: 700;
  color: var(--pl-text);
}

.pl-wiz-q-sm {
  font-size: 12.5px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--pl-muted);
  margin: 10px 0 0;
}

.pl-wiz-hint {
  margin: 0;
  font-size: 12.5px;
  line-height: 1.4;
  color: var(--pl-muted);
}

.pl-wiz-hint-notes {
  color: var(--pl-blue);
}

.pl-wiz-lbl {
  font-size: 12px;
  font-weight: 600;
  color: var(--pl-muted);
}

.pl-wiz-input {
  width: 100%;
  padding: 9px 11px;
  border-radius: 9px;
  border: 1px solid var(--pl-border);
  background: var(--pl-panel-2);
  color: var(--pl-text);
  font-size: 14px;
  min-height: 40px;
}

.pl-wiz-input:focus-visible {
  outline: 2px solid var(--pl-blue);
  outline-offset: 1px;
}

/* ── Option cards ─────────────────────────────────────────────────────── */

.pl-wiz-grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 8px;
}

.pl-wiz-opt {
  position: relative;
  display: flex;
  flex-direction: column;
  gap: 4px;
  align-items: flex-start;
  text-align: left;
  padding: 10px 12px;
  min-height: 40px;
  border-radius: 10px;
  border: 1px solid var(--pl-border);
  background: var(--pl-panel-2);
  color: var(--pl-text);
  cursor: pointer;
  transition: border-color 120ms, background 120ms, box-shadow 120ms;
}

.pl-wiz-opt:hover {
  border-color: var(--pl-blue);
}

.pl-wiz-opt:focus-visible {
  outline: 2px solid var(--pl-blue);
  outline-offset: 2px;
}

.pl-wiz-opt-rec {
  border-color: color-mix(in srgb, var(--pl-blue) 45%, var(--pl-border));
}

.pl-wiz-opt-sel {
  border-color: var(--pl-blue);
  background: color-mix(in srgb, var(--pl-blue) 8%, var(--pl-panel-2));
  box-shadow: 0 0 0 1px var(--pl-blue) inset;
}

.pl-wiz-opt-label {
  font-size: 13.5px;
  font-weight: 700;
}

.pl-wiz-opt-why {
  font-size: 11.5px;
  line-height: 1.35;
  color: var(--pl-muted);
}

.pl-wiz-badge {
  display: inline-flex;
  align-items: center;
  padding: 2px 7px;
  border-radius: 999px;
  font-size: 10px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.03em;
  color: #fff;
  background: var(--pl-btn-primary-grad, var(--pl-blue));
  align-self: flex-start;
}

.pl-wiz-badge-sm {
  font-size: 9.5px;
  padding: 2px 6px;
}

/* ── Color swatches ───────────────────────────────────────────────────── */

.pl-wiz-swatchrow {
  display: flex;
  gap: 3px;
}

.pl-wiz-swatch {
  width: 18px;
  height: 18px;
  border-radius: 5px;
  border: 1px solid var(--pl-glass-border);
  flex-shrink: 0;
}

.pl-wiz-swatch-sm {
  width: 14px;
  height: 14px;
  border-radius: 4px;
}

/* ── Fine-tune wheel ──────────────────────────────────────────────────── */

.pl-wiz-wheel-wrap {
  display: flex;
  justify-content: center;
  padding: 6px 0;
}

.pl-wiz-wheel {
  position: relative;
  width: 180px;
  height: 180px;
  border-radius: 50%;
  cursor: crosshair;
  touch-action: none;
  box-shadow: var(--pl-shadow-card);
  background:
    radial-gradient(circle, #fff 0%, rgba(255, 255, 255, 0) 62%),
    conic-gradient(from 90deg, #ff0000, #ffff00, #00ff00, #00ffff, #0000ff, #ff00ff, #ff0000);
}

.pl-wiz-wheel-thumb {
  position: absolute;
  width: 16px;
  height: 16px;
  margin-left: -8px;
  margin-top: -8px;
  border-radius: 50%;
  background: #fff;
  border: 2px solid var(--pl-text);
  box-shadow: 0 1px 4px rgba(0, 0, 0, 0.4);
  pointer-events: none;
}

/* ── Chips ────────────────────────────────────────────────────────────── */

.pl-wiz-chiprow {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
}

.pl-wiz-chip {
  position: relative;
  min-height: 40px;
  padding: 8px 14px;
  border-radius: 999px;
  border: 1px solid var(--pl-border);
  background: var(--pl-panel-2);
  color: var(--pl-text);
  font-size: 13px;
  font-weight: 600;
  cursor: pointer;
  transition: border-color 120ms, background 120ms, color 120ms;
}

.pl-wiz-chip:hover {
  border-color: var(--pl-blue);
}

.pl-wiz-chip:focus-visible {
  outline: 2px solid var(--pl-blue);
  outline-offset: 2px;
}

.pl-wiz-chip-rec::after {
  content: "";
  position: absolute;
  top: 4px;
  right: 4px;
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--pl-blue);
}

.pl-wiz-chip-sel {
  border-color: var(--pl-blue);
  background: var(--pl-blue);
  color: #fff;
}

.pl-wiz-chip-sel.pl-wiz-chip-rec::after {
  background: #fff;
}

/* ── Toggle rows (pages / features) ──────────────────────────────────── */

.pl-wiz-togglelist {
  display: flex;
  flex-direction: column;
  gap: 6px;
}

.pl-wiz-toggle-row {
  display: flex;
  align-items: center;
  gap: 10px;
  min-height: 44px;
  padding: 8px 12px;
  border-radius: 10px;
  border: 1px solid var(--pl-border);
  background: var(--pl-panel-2);
  color: var(--pl-text);
  cursor: pointer;
  text-align: left;
  transition: border-color 120ms, background 120ms;
}

.pl-wiz-toggle-row:hover {
  border-color: var(--pl-blue);
}

.pl-wiz-toggle-row:focus-visible {
  outline: 2px solid var(--pl-blue);
  outline-offset: 2px;
}

.pl-wiz-toggle-box {
  flex-shrink: 0;
  width: 18px;
  height: 18px;
  border-radius: 5px;
  border: 1px solid var(--pl-border);
  background: var(--pl-panel-1);
}

.pl-wiz-toggle-on .pl-wiz-toggle-box {
  background: var(--pl-blue);
  border-color: var(--pl-blue);
  box-shadow: inset 0 0 0 3px var(--pl-panel-2);
}

.pl-wiz-toggle-text {
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 1px;
}

.pl-wiz-toggle-label {
  font-size: 13px;
  font-weight: 700;
}

.pl-wiz-toggle-why {
  font-size: 11.5px;
  color: var(--pl-muted);
}

/* ── Review step ──────────────────────────────────────────────────────── */

.pl-wiz-review-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 4px;
}

.pl-wiz-review-list li {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 9px 0;
  border-bottom: 1px solid var(--pl-border);
}

.pl-wiz-review-k {
  flex-shrink: 0;
  width: 84px;
  font-size: 11.5px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.03em;
  color: var(--pl-faint);
}

.pl-wiz-review-v {
  flex: 1;
  min-width: 0;
  font-size: 13px;
  color: var(--pl-text);
  overflow-wrap: break-word;
}

.pl-wiz-review-swatches {
  display: flex;
  gap: 3px;
}

.pl-wiz-edit {
  flex-shrink: 0;
  min-height: 32px;
  padding: 4px 10px;
  border-radius: 7px;
  border: 1px solid var(--pl-border);
  background: transparent;
  color: var(--pl-blue);
  font-size: 12px;
  font-weight: 700;
  cursor: pointer;
}

.pl-wiz-edit:hover {
  background: color-mix(in srgb, var(--pl-blue) 10%, transparent);
}

.pl-wiz-edit:focus-visible {
  outline: 2px solid var(--pl-blue);
  outline-offset: 2px;
}

/* ── Persistent center stage ──────────────────────────────────────────── */
/* DEAD: .pl-wiz-stage-wrap removed here — wizard.rs renders
   .pl-wiz-stage-dock for this wrapper instead (see the matching DEAD
   note further down, near .pl-wiz-edit). */

.pl-wiz-stage {
  --pl-wiz-accent: var(--pl-blue);
  --pl-wiz-accent-2: var(--pl-sky);
  --pl-wiz-accent-3: var(--pl-green);
  width: min(560px, 100%);
  border-radius: 14px;
  overflow: hidden;
  background: var(--pl-panel-1);
  border: 1px solid var(--pl-border);
  box-shadow: var(--pl-shadow-float);
}

.pl-wiz-chrome {
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 8px 10px;
  background: var(--pl-panel-2);
  border-bottom: 1px solid var(--pl-border);
}

.pl-wiz-cdot {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: var(--pl-track);
  flex-shrink: 0;
}

.pl-wiz-tabstrip {
  display: flex;
  gap: 4px;
  margin-left: 10px;
  overflow: hidden;
  flex-wrap: wrap;
}

.pl-wiz-tab {
  padding: 3px 9px;
  border-radius: 6px 6px 0 0;
  background: var(--pl-panel-1);
  border: 1px solid var(--pl-border);
  border-bottom: none;
  font-size: 10.5px;
  font-weight: 600;
  color: var(--pl-muted);
  white-space: nowrap;
  transition: background 200ms;
}

.pl-wiz-tab:first-child {
  color: var(--pl-wiz-accent);
}

.pl-wiz-page {
  display: flex;
  flex-direction: column;
}

.pl-wiz-nav {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 12px 16px;
  border-bottom: 1px solid var(--pl-border);
}

.pl-wiz-brand {
  font-weight: 800;
  font-size: 14px;
  color: var(--pl-wiz-accent);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.pl-wiz-navlinks {
  display: flex;
  gap: 10px;
  margin-left: auto;
}

.pl-wiz-navlinks span {
  width: 26px;
  height: 6px;
  border-radius: 3px;
  background: var(--pl-track);
}

.pl-wiz-navpill {
  padding: 5px 12px;
  border-radius: 999px;
  background: var(--pl-wiz-accent);
  color: #fff;
  font-size: 10.5px;
  font-weight: 700;
}

.pl-wiz-hero {
  display: flex;
  flex-direction: column;
  gap: 10px;
  padding: 26px 18px;
  transition: background 200ms;
}

.pl-wiz-hero-ph {
  height: 100px;
  border-radius: 10px;
  background: linear-gradient(135deg, var(--pl-wiz-accent), var(--pl-wiz-accent-2));
}

.pl-wiz-hero[data-pl-wiz-imagery="illustration"] .pl-wiz-hero-ph {
  background: var(--pl-block);
  background-image:
    radial-gradient(circle at 20% 30%, var(--pl-wiz-accent) 0 8px, transparent 9px),
    radial-gradient(circle at 70% 60%, var(--pl-wiz-accent-2) 0 12px, transparent 13px),
    linear-gradient(45deg, transparent 48%, var(--pl-wiz-accent-3) 49%, var(--pl-wiz-accent-3) 51%, transparent 52%);
}

.pl-wiz-hero[data-pl-wiz-imagery="3d"] .pl-wiz-hero-ph {
  background: var(--pl-block);
  background-image:
    radial-gradient(circle at 30% 35%, var(--pl-wiz-accent) 0 34px, transparent 35px),
    radial-gradient(circle at 72% 65%, var(--pl-wiz-accent-2) 0 22px, transparent 23px);
  box-shadow: inset 0 -8px 20px rgba(0, 0, 0, 0.12);
}

.pl-wiz-hero[data-pl-wiz-imagery="flat"] .pl-wiz-hero-ph {
  background: var(--pl-wiz-accent-3);
  background-image:
    linear-gradient(120deg, var(--pl-wiz-accent) 0 30%, transparent 30%),
    linear-gradient(-120deg, var(--pl-wiz-accent-2) 0 25%, transparent 25%);
}

.pl-wiz-hero-copy {
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.pl-wiz-hero-title {
  display: block;
  width: 70%;
  height: 16px;
  border-radius: 4px;
  background: var(--pl-text);
  opacity: 0.85;
}

.pl-wiz-hero-sub {
  display: block;
  width: 90%;
  height: 9px;
  border-radius: 4px;
  background: var(--pl-muted);
  opacity: 0.5;
}

.pl-wiz-hero-cta {
  display: block;
  width: 96px;
  height: 26px;
  margin-top: 4px;
  border-radius: 7px;
  background: var(--pl-wiz-accent);
}

.pl-wiz-body {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 10px;
  padding: 0 18px 20px;
}

.pl-wiz-blk {
  height: 54px;
  border-radius: 8px;
  background: var(--pl-block);
}

/* Layout-pack reshaping */

.pl-wiz-stage[data-pl-wiz-layout="bold"] .pl-wiz-hero {
  padding: 40px 18px;
}

.pl-wiz-stage[data-pl-wiz-layout="bold"] .pl-wiz-hero-ph {
  height: 130px;
}

.pl-wiz-stage[data-pl-wiz-layout="bold"] .pl-wiz-hero-title {
  height: 22px;
  width: 85%;
}

.pl-wiz-stage[data-pl-wiz-layout="editorial"] .pl-wiz-hero {
  flex-direction: row;
  align-items: center;
}

.pl-wiz-stage[data-pl-wiz-layout="editorial"] .pl-wiz-hero-ph {
  flex: 1;
  height: 120px;
}

.pl-wiz-stage[data-pl-wiz-layout="editorial"] .pl-wiz-hero-copy {
  flex: 1;
}

.pl-wiz-stage[data-pl-wiz-layout="minimal"] .pl-wiz-hero {
  align-items: center;
  text-align: center;
  padding: 34px 40px;
}

.pl-wiz-stage[data-pl-wiz-layout="minimal"] .pl-wiz-hero-ph {
  width: 60%;
}

.pl-wiz-stage[data-pl-wiz-layout="minimal"] .pl-wiz-hero-title,
.pl-wiz-stage[data-pl-wiz-layout="minimal"] .pl-wiz-hero-sub {
  width: 60%;
  align-self: center;
}

.pl-wiz-stage[data-pl-wiz-layout="minimal"] .pl-wiz-body {
  grid-template-columns: 1fr;
}

/* ── Bottom bar ───────────────────────────────────────────────────────── */

.pl-wiz-bottom {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 12px 20px;
  border-top: 1px solid var(--pl-border);
  flex-shrink: 0;
  flex-wrap: wrap;
}

.pl-wiz-dots {
  display: flex;
  gap: 6px;
}

.pl-wiz-dot-btn {
  width: 22px;
  height: 22px;
  padding: 0;
  border-radius: 50%;
  border: none;
  background: transparent;
  cursor: pointer;
  position: relative;
}

.pl-wiz-dot-btn::after {
  content: "";
  position: absolute;
  inset: 8px;
  border-radius: 50%;
  background: var(--pl-track);
  transition: background 120ms, inset 120ms;
}

.pl-wiz-dot-btn:hover::after {
  background: var(--pl-muted);
}

.pl-wiz-dot-btn:focus-visible {
  outline: 2px solid var(--pl-blue);
  outline-offset: 2px;
}

.pl-wiz-dot-cur::after {
  inset: 6px;
  background: var(--pl-blue);
}

.pl-wiz-bottom-actions {
  display: flex;
  align-items: center;
  gap: 8px;
}

.pl-wiz-skip {
  font-size: 12.5px;
}

.pl-wiz-generate-btn {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  min-height: 40px;
  padding: 10px 20px;
  border: none;
  border-radius: 10px;
  background: var(--pl-btn-green-grad);
  color: #fff;
  font-weight: 700;
  font-size: 14px;
  cursor: pointer;
  box-shadow: var(--pl-btn-green-shadow);
  transition: box-shadow 120ms, transform 120ms;
}

.pl-wiz-generate-btn:hover {
  box-shadow: var(--pl-btn-green-shadow-hover);
}

.pl-wiz-generate-btn:focus-visible {
  outline: 2px solid var(--pl-green);
  outline-offset: 2px;
}

.pl-wiz-generate-btn:disabled {
  cursor: default;
  opacity: 0.85;
}

.pl-wiz-generating {
  animation: pl-wiz-pulse 900ms ease-in-out infinite;
}

@keyframes pl-wiz-pulse {
  0%, 100% {
    transform: scale(1);
  }
  50% {
    transform: scale(1.03);
  }
}

/* ── Escape confirm ───────────────────────────────────────────────────── */

.pl-wiz-confirm-overlay {
  position: fixed;
  inset: 0;
  z-index: 90;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 16px;
  background: var(--pl-modal-backdrop);
}

.pl-wiz-confirm-overlay[hidden] {
  display: none !important;
}

.pl-wiz-confirm {
  width: min(360px, 100%);
  padding: 20px;
  border-radius: 14px;
  background: var(--pl-glass-bg);
  backdrop-filter: blur(14px) saturate(1.3);
  -webkit-backdrop-filter: blur(14px) saturate(1.3);
  border: 1px solid var(--pl-glass-border);
  box-shadow: var(--pl-glass-shadow);
  display: flex;
  flex-direction: column;
  gap: 14px;
}

.pl-wiz-confirm p {
  margin: 0;
  font-size: 14px;
  color: var(--pl-text);
  line-height: 1.4;
}

.pl-wiz-confirm-actions {
  display: flex;
  gap: 8px;
  justify-content: flex-end;
}

/* ── Responsive ───────────────────────────────────────────────────────── */

@media (max-width: 900px) {
  .pl-wiz-rail {
    border-right: none;
    border-bottom: 1px solid var(--pl-border);
    max-height: 46vh;
  }
}

@media (max-width: 560px) {
  .pl-wiz-grid {
    grid-template-columns: 1fr;
  }

  .pl-wiz-review-k {
    width: 68px;
  }
}

/* ── Reduced motion ───────────────────────────────────────────────────── */

@media (prefers-reduced-motion: reduce) {
  .pl-wiz-rail-body {
    animation: none;
  }

  .pl-wiz-generating {
    animation: none;
  }

  .pl-wiz-hero-ph,
  .pl-wiz-tab {
    transition: none;
  }
}

/* wizard v7 */
/* ─────────────────────────────────────────────────────────────────────────
   D3pth Planner — picture-node chart. The map is a mermaid-flavored
   diagram of LINKED NODES: a compact business picture-node top-center,
   area cluster headers, and every page as a picture-node whose face IS
   its generated mockup — never a wireframe primitive. Re-declares the
   zone classes map_view.rs no longer emits the old way (pl-chart-* is
   new; pl-pic-* replaces pl-node-thumb usage on the chart). Tokens only
   (--pl-*, --font-*); dark comes free via the existing
   .pl-app[data-pl-theme="dark"] token re-declarations upstream — no
   separate dark block needed here.
   ───────────────────────────────────────────────────────────────────────── */

/* ── Chart stage: positioning parent + coordinate frame for the edge
   canvas. Content sits at z-index 1 with a transparent ground so beads
   stay visible between nodes; the canvas (z 0, pointer-events none) fills
   the stage — same convention the old pl-zone-web used. ────────────────── */

.pl-chart-stage {
  position: relative;
  flex-shrink: 0;
  padding: 20px 16px 24px;
  border-radius: 12px;
  border: 1px solid var(--pl-border);
  background: color-mix(in srgb, var(--pl-panel-2) 45%, transparent);
  overflow: hidden;
}

.pl-chart-stage .pl-edge-canvas {
  position: absolute;
  inset: 0;
  /* A canvas is a replaced element: inset alone never stretches it, it lays
     out at its intrinsic width/height attrs (css*dpr after the resize call),
     which displayed every edge and bead at exactly 2x its true position.
     Explicit 100% pins the CSS box to the stage so canvas css coords and
     DOM rect coords are the same frame. */
  width: 100%;
  height: 100%;
  display: block;
  z-index: 0;
  pointer-events: none;
}

.pl-chart-stage .pl-chart-label,
.pl-chart-field {
  position: relative;
  z-index: 1;
}

.pl-chart-label {
  margin-bottom: 14px;
}

/* Field: business node top-center, clusters below — a connected canvas,
   not stacked tiers. */
.pl-chart-field {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 26px;
}

/* ── Business node — compact picture card, top-center ─────────────────── */

.pl-app .pl-chart-biz {
  width: 176px;
  min-width: 0;
  max-width: 176px;
}

.pl-chart-biz-caption {
  align-items: center;
  text-align: center;
}

/* ── Clusters — one per area, always rendered ──────────────────────────── */

.pl-chart-clusters {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-start;
  justify-content: center;
  gap: 22px;
  width: 100%;
}

/* Border-only panels, no fill, so edges show through the space between
   nodes — echoes the old pl-web-cluster treatment. */
.pl-chart-cluster {
  display: flex;
  flex-direction: column;
  gap: 12px;
  flex: 1 1 260px;
  min-width: 240px;
  max-width: 100%;
  padding: 14px;
  border-radius: 10px;
  border: 1px dashed color-mix(in srgb, var(--pl-border) 85%, transparent);
  background: transparent;
  transition: opacity 150ms;
}

/* Quick-filter dim: the chart always shows the whole plan, this only
   fades non-matching clusters, never removes them. */
.pl-chart-cluster-dim {
  opacity: 0.42;
}

.pl-chart-cluster-cap {
  display: flex;
  align-items: center;
  gap: 6px;
  font-family: var(--font-mono);
  font-size: 10px;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  color: var(--pl-faint);
}

.pl-chart-cluster-cap-title {
  color: var(--pl-muted);
}

.pl-chart-cluster-empty {
  margin: 0;
  font-size: 12px;
  color: var(--pl-faint);
}

.pl-chart-cluster-grid {
  display: flex;
  flex-wrap: wrap;
  justify-content: flex-start;
  gap: 14px;
  margin: 0;
  padding: 0;
  list-style: none;
}

.pl-chart-add {
  align-self: flex-start;
  height: auto;
  min-height: 44px;
}

/* ── Picture-node cards — image face, thin caption bar ─────────────────── */

.pl-app .pl-pic-node {
  width: 168px;
  min-width: 152px;
  max-width: 168px;
  padding: 0;
  display: flex;
  flex-direction: column;
}

/* Selected = ring + slight scale, never a grid-span grow — higher
   specificity than the base .pl-node-sel ring-only rule and than
   .pl-node:hover's translateY so selection always wins visually. */
.pl-pic-node.pl-node-sel {
  transform: scale(1.035);
  z-index: 2;
}

.pl-pic-node:hover {
  transform: translateY(-2px);
}

.pl-pic-node.pl-node-sel:hover {
  transform: scale(1.035) translateY(-2px);
}

.pl-pic-face {
  position: relative;
  display: block;
  width: 100%;
  aspect-ratio: 4 / 3;
  overflow: hidden;
  background: var(--pl-block);
}

.pl-pic-img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: top;
}

.pl-pic-img-missing {
  display: none !important;
}

/* Neutral "picture coming" tile: shown outright for requested pages, or
   as the fallback when a real <img> 404s (toggled via :has, no cfg, no
   layout shift, no fake wireframe bars). */
.pl-pic-placeholder {
  position: absolute;
  inset: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 4px;
  background: color-mix(in srgb, var(--pl-sky) 5%, var(--pl-block));
  border: 1px dashed color-mix(in srgb, var(--pl-sky) 35%, var(--pl-border));
}

.pl-pic-placeholder-fallback {
  display: none;
}

.pl-pic-face:has(.pl-pic-img-missing) .pl-pic-placeholder-fallback {
  display: flex;
}

.pl-pic-placeholder-id {
  font-family: var(--font-mono);
  font-size: 11px;
  letter-spacing: 0.04em;
  color: var(--pl-muted);
}

.pl-pic-placeholder-label {
  font-size: 10px;
  color: var(--pl-faint);
}

/* Dark theme: images keep their own colors, just a touch less glare —
   matches how photography reads dimmed everywhere else in dark. */
[data-pl-theme="dark"] .pl-pic-img {
  filter: brightness(0.92);
}

/* Thin caption bar beneath the face: page id mono + title + chips. */
.pl-pic-caption {
  display: flex;
  flex-direction: column;
  gap: 4px;
  padding: 8px 10px 10px;
}

.pl-pic-caption .pl-nid {
  font-family: var(--font-mono);
  font-size: 10px;
  letter-spacing: 0.04em;
  color: var(--pl-faint);
}

.pl-pic-caption .pl-nt {
  font-size: 13px;
  font-weight: 600;
  color: var(--pl-text);
  line-height: 1.25;
}

.pl-pic-caption .pl-badges {
  margin-top: 2px;
}

/* DEAD: `.pl-pic-node .pl-flow-handle` (former wizard-v7 anchor: top-right
   of the card) removed here — the flow handle is a <span> SIBLING of the
   .pl-pic-node <button> inside <li class="pl-page-cell">, not a
   descendant of it (map_view.rs), so this descendant selector never
   matched live markup. `.pl-app .pl-page-cell > .pl-flow-handle` (further
   down this file) is both the structurally-correct AND the
   higher-specificity rule, and is unaffected by this removal. */

/* ── Reduced motion: no hover lift, no selected-scale animation — the
   ring alone still marks selection. ────────────────────────────────────── */
@media (prefers-reduced-motion: reduce) {
  .pl-pic-node,
  .pl-pic-node:hover,
  .pl-pic-node.pl-node-sel,
  .pl-pic-node.pl-node-sel:hover,
  .pl-chart-cluster {
    transition: none;
    transform: none;
  }
}

/* [hidden] guard for every surface this sheet adds. */
.pl-chart-stage[hidden],
.pl-chart-clusters[hidden],
.pl-chart-cluster[hidden] {
  display: none !important;
}

/* picturenodes v8 */
/* ── Picture + click-zones: the page detail view's mockup is the HARD-
   GENERATED PICTURE (/planner/mockups/{template}/{page}.png), never a DOM
   wireframe. This sheet covers the click-zone overlay (positioned from the
   sidecar recipe's bones.region_map), its honest pill-strip fallback for
   when that sidecar is 404/malformed/empty, and the inspector's cropped-
   picture zoom pane. Tokens only — no literal colors. [hidden] guards,
   ≥40px targets, reduced-motion throughout. */

/* ── Stage: the mockbox becomes exactly the picture's box — no padding,
   no flex-centering, no min-height — so the click-zones' percentage
   coordinates (measured against the picture itself) land pixel-true over
   it. `.pl-mockbox` already carries `position: relative` upstream; this
   just neutralizes the older centered-placeholder box model. Two classes
   for specificity — this always wins over the single-class legacy rule
   regardless of stylesheet load order. */
.pl-mockbox.pl-pic-stage {
  display: block;
  padding: 0;
  min-height: 0;
  overflow: hidden;
  border-radius: 12px;
}

/* The picture itself sits flush in that box — no legacy margin/border
   that would shift its rendered box away from the 0–100% coordinate
   space the zones and pins are measured in. */
.pl-pic-stage .pl-mock-img {
  margin-bottom: 0;
  border: none;
  border-radius: 0;
}

/* A page with no picture at all (still queued / never requested) has no
   stage — nothing here to misalign. */
.pl-pic-wrap {
  display: flex;
  flex-direction: column;
  gap: 10px;
}

/* ── Click-zones: one transparent button per region, placed by the sidecar
   recipe's region_map percentages. The wrap div carries the position; the
   zone itself is the real, focusable, ≥ hit-testable button (CSS spec:
   "they are buttons") — the ⌕ inspect trigger rides its corner as a
   sibling, never nested (a <button> cannot contain a <button>). ── */
.pl-pic-zone-wrap {
  position: absolute;
}

.pl-pic-zone {
  position: relative;
  display: block;
  width: 100%;
  height: 100%;
  min-width: 40px;
  min-height: 40px;
  padding: 0;
  margin: 0;
  border: 1px solid transparent;
  border-radius: 6px;
  background: transparent;
  cursor: pointer;
  transition: background-color 150ms ease, border-color 150ms ease,
    box-shadow 150ms ease;
}

/* Hover / focus: soft accent outline — the picture stays untouched, only
   a tint + ring reads as "this is a live region". */
.pl-pic-zone:hover,
.pl-pic-zone:focus-visible {
  border-color: color-mix(in srgb, var(--pl-sky) 55%, transparent);
  background: color-mix(in srgb, var(--pl-sky) 10%, transparent);
  box-shadow: 0 0 0 1px color-mix(in srgb, var(--pl-sky) 35%, transparent);
}

.pl-pic-zone:focus-visible {
  outline: 2px solid var(--pl-sky);
  outline-offset: 2px;
}

/* Selected / just-applied: reuse the existing region-select semantics
   (pl-wregion-sel / pl-wregion-flash) as-is — same classes, same rules,
   just applied to a transparent overlay button instead of a wireframe
   card. The old base .pl-wregion box model (padding/margin/background)
   never applies here since the zone never wears that class. */
.pl-pic-zone.pl-wregion-sel {
  border-color: var(--pl-sky);
  background: color-mix(in srgb, var(--pl-sky) 14%, transparent);
}

/* The upstream .pl-wregion-flash keyframe fades to var(--pl-panel-2) —
   right for an opaque wireframe card, wrong for a transparent overlay on
   a photo (it'd leave a solid box sitting on the picture). Same class,
   same trigger, a transparent-safe keyframe instead. */
.pl-pic-zone.pl-wregion-flash {
  animation: pl-pic-zone-flash 600ms ease-out;
}

@keyframes pl-pic-zone-flash {
  0% {
    background: color-mix(in srgb, var(--pl-amber) 35%, transparent);
    border-color: var(--pl-amber);
  }
  100% {
    background: transparent;
    border-color: transparent;
  }
}

@media (prefers-reduced-motion: reduce) {
  .pl-pic-zone.pl-wregion-flash {
    animation: none;
  }
}

@media (prefers-reduced-motion: reduce) {
  .pl-pic-zone {
    transition: none;
  }
}

/* Hover label chip: the region's title, revealed on hover/focus so a
   reviewer knows what they're about to comment on before they click. */
.pl-pic-zone-label {
  position: absolute;
  left: 50%;
  bottom: calc(100% + 6px);
  transform: translateX(-50%) translateY(2px);
  padding: 4px 8px;
  border-radius: 6px;
  background: var(--pl-glass-bg);
  border: 1px solid var(--pl-glass-border);
  color: var(--pl-text);
  font-family: var(--font-sans);
  font-size: 11px;
  font-weight: 600;
  white-space: nowrap;
  pointer-events: none;
  opacity: 0;
  transition: opacity 150ms ease, transform 150ms ease;
  z-index: 2;
}

.pl-pic-zone:hover .pl-pic-zone-label,
.pl-pic-zone:focus-visible .pl-pic-zone-label {
  opacity: 1;
  transform: translateX(-50%) translateY(0);
}

@media (prefers-reduced-motion: reduce) {
  .pl-pic-zone-label {
    transition: none;
  }
}

/* ⌕ inspect trigger riding the zone's corner — same look/behavior as the
   trigger everywhere else in the planner, just anchored to the wrap div
   (a sibling of the zone button, not nested inside it) so hover-reveal
   still fires from anywhere in the zone's footprint. */
.pl-pic-zone-wrap {
  z-index: 1;
}

.pl-pic-zone-wrap:hover .pl-inspect-btn,
.pl-pic-zone-wrap:focus-within .pl-inspect-btn,
.pl-pic-zone-wrap .pl-inspect-btn:focus-visible {
  opacity: 1;
  transform: translateY(0);
}

/* ── Pins ride above zones (dropped last, meant to stay visible). ── */
.pl-pic-stage .pl-pin {
  z-index: 3;
}

/* ── Pill-strip fallback: sidecar 404, malformed, or empty region_map.
   Plain text buttons under the picture — no layout, no positioning math,
   commenting never breaks even when the pipeline hasn't shipped
   coordinates yet. ── */
.pl-pic-pills {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}

.pl-pic-pill {
  display: inline-flex;
  align-items: stretch;
  border: 1px solid var(--pl-border);
  border-radius: 999px;
  overflow: hidden;
  background: var(--pl-panel-2);
}

.pl-pic-pill-btn {
  display: inline-flex;
  align-items: center;
  min-height: 40px;
  padding: 0 14px;
  border: none;
  background: transparent;
  color: var(--pl-text);
  font-family: var(--font-sans);
  font-size: 13px;
  font-weight: 500;
  cursor: pointer;
  transition: background-color 150ms ease, color 150ms ease;
}

.pl-pic-pill-btn:hover,
.pl-pic-pill-btn:focus-visible {
  background: color-mix(in srgb, var(--pl-sky) 12%, transparent);
  color: var(--pl-sky);
}

.pl-pic-pill-inspect {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 40px;
  min-height: 40px;
  padding: 0 12px;
  border: none;
  border-left: 1px solid var(--pl-border);
  background: transparent;
  color: var(--pl-muted);
  font-size: 13px;
  cursor: pointer;
  transition: background-color 150ms ease, color 150ms ease;
}

.pl-pic-pill-inspect:hover,
.pl-pic-pill-inspect:focus-visible {
  background: color-mix(in srgb, var(--pl-sky) 12%, transparent);
  color: var(--pl-sky);
}

.pl-pic-pill-btn:focus-visible,
.pl-pic-pill-inspect:focus-visible {
  outline: 2px solid var(--pl-sky);
  outline-offset: -2px;
}

@media (prefers-reduced-motion: reduce) {
  .pl-pic-pill-btn,
  .pl-pic-pill-inspect {
    transition: none;
  }
}

/* ── Inspector crop viewport: the zoom pane shows the actual generated
   picture, cropped and zoomed to the inspected region via CSS
   transform — never DOM bones. The outer .pl-inspect-zoom (upstream)
   still supplies the dashed frame + glass panel; these two classes are
   new, everything else about the inspector (overlay, attrs, actions,
   cycling, focus trap) is untouched. ── */
.pl-pic-crop {
  position: relative;
  width: 100%;
  overflow: hidden;
  border-radius: 6px;
  background: var(--pl-panel-1);
}

.pl-pic-crop-inner {
  position: relative;
  width: 100%;
  transform-origin: 0 0;
}

.pl-pic-crop-img {
  display: block;
  width: 100%;
  height: auto;
}

/* No region_map coordinates for this region yet: show the full picture,
   unzoomed, honestly labeled rather than pretending a crop exists. */
.pl-pic-crop-hint {
  margin-top: 8px;
  text-align: center;
}

@media (prefers-reduced-motion: reduce) {
  .pl-pic-crop-inner {
    transition: none;
  }
}

/* pictureregions v8 */

/* ── Responsive topbar v9 — the toolbar must never clip controls off the
   viewport (on mobile the credits/notes/theme/wizard/save buttons were
   unreachable). Wrap into rows on medium widths; on phones the view tabs
   become a horizontally scrollable strip and the action row wraps with
   full-width tap targets. CSS-only: markup is orchestrator-owned and
   hydration-stable. ─────────────────────────────────────────────────── */
.pl-topbar {
  flex-wrap: wrap;
  row-gap: 10px;
}

.pl-tabs {
  min-width: 0;
}

.pl-top-right {
  flex-wrap: wrap;
  row-gap: 8px;
}

@media (max-width: 1080px) {
  .pl-topbar {
    justify-content: flex-start;
    column-gap: 12px;
  }
  .pl-top-right {
    flex: 1 1 100%;
    justify-content: flex-end;
  }
}

@media (max-width: 760px) {
  .pl-demo-pill {
    flex: 1 1 100%;
    text-align: center;
  }
  .pl-tabs {
    flex: 1 1 100%;
    display: flex;
    flex-wrap: nowrap;
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
    scrollbar-width: none;
    gap: 6px;
    padding-bottom: 2px;
  }
  .pl-tabs::-webkit-scrollbar {
    display: none;
  }
  .pl-tabs .pl-tab {
    flex: 0 0 auto;
    white-space: nowrap;
    min-height: 44px;
  }
  .pl-top-right {
    flex: 1 1 100%;
    justify-content: stretch;
  }
  .pl-top-right > * {
    flex: 1 1 auto;
    min-height: 44px;
  }
  .pl-make-btn,
  .pl-build-btn {
    flex: 1 1 100%;
  }
}

/* ─────────────────────────────────────────────────────────────────────────
   D3pth Planner — map view fixes (fix-map.css). Appended AFTER the other
   planner sheets on purpose: these rules correct picturenodes.css /
   planner-theme.css behavior and must out-cascade them. Tokens only
   (--pl-*, --font-*); dark theme comes free via the .pl-app token
   re-declarations upstream.
   ───────────────────────────────────────────────────────────────────────── */

/* ── 1 · Full-picture faces ─────────────────────────────────────────────
   Mockup PNGs are 800×500 (8:5); the old 4:3 face cropped ~17% off the
   sides under object-fit:cover. 8:5 + auto height means cover shows the
   whole picture. One rule covers page nodes, the business node, and the
   requested-page placeholder tile alike — they all render inside
   .pl-pic-face. */
.pl-app .pl-pic-face {
  aspect-ratio: 8 / 5;
  height: auto;
}

/* ── 2 · 404-honest placeholder, no hydration race ──────────────────────
   The "picture coming" tile is visible by default, stacked UNDER the
   image: a mockup that loads simply covers it, one that 404s before
   hydration leaves it showing (an <img> with alt="" paints nothing while
   pending/failed). The pl-pic-img-loaded class — set on load, or on
   mount for cache hits — hides the tile outright so translucent PNGs
   never show it bleeding through. pl-pic-img-missing (existing rule)
   still hides a failed <img> box itself. */
.pl-app .pl-pic-placeholder-fallback {
  display: flex;
  z-index: 0;
}

.pl-app .pl-pic-img {
  z-index: 1;
}

.pl-app .pl-pic-face:has(.pl-pic-img-loaded) .pl-pic-placeholder-fallback {
  display: none;
}

/* ── 3/4 · Flow handle rides the caption bar, not the artwork ───────────
   The handle is now a SIBLING of the page button (a focusable
   role=button inside a real <button> was invalid nesting), so the cell
   <li> becomes the positioning parent, and the handle anchors to the
   caption bar's bottom-right corner — never over the mockup image. The
   base .pl-flow-handle rule (left:50%; bottom:-22px; translateX) is
   fully reset here so it can't out-constrain this anchor. Hit target
   stays 44×44 (sized by the base rule). */
.pl-app .pl-page-cell {
  position: relative;
}

.pl-app .pl-page-cell > .pl-flow-handle {
  top: auto;
  left: auto;
  right: 0;
  bottom: 0;
  transform: none;
  border-radius: 50%;
  z-index: 2;
}

.pl-app .pl-page-cell > .pl-flow-handle:focus-visible {
  outline: 2px solid var(--pl-sky);
  outline-offset: 2px;
}

/* Keep caption text and chips clear of the handle's 44px hit target. */
.pl-app .pl-page-cell .pl-pic-caption {
  padding-right: 46px;
}

/* ── 8 · Hint + area tabs on narrow screens ─────────────────────────────
   The drag hint is a normal static block in flow right under the tabs —
   the base rule's position:absolute made it collide with the tab card on
   mobile. */
.pl-app .pl-flow-hint {
  position: static;
  margin: 0;
  white-space: normal;
  pointer-events: none;
}

/* Tabs become one horizontally scrollable chip row on narrow screens —
   no wrap, scrollbar hidden but the row stays scrollable. */
@media (max-width: 640px) {
  .pl-app .pl-area-tabs {
    flex-wrap: nowrap;
    width: 100%;
    max-width: 100%;
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
    scrollbar-width: none;
  }

  .pl-app .pl-area-tabs::-webkit-scrollbar {
    display: none;
  }

  .pl-app .pl-area-tab {
    flex: 0 0 auto;
    white-space: nowrap;
  }
}

/* [hidden] guards for the toggleable surfaces this sheet touches. */
.pl-flow-hint[hidden],
.pl-flow-confirm[hidden],
.pl-page-cell > .pl-flow-handle[hidden] {
  display: none !important;
}

/* fix-detail.css — page detail view organization pass.
   Picture LEFT, working rail RIGHT (composer, decision, notes) as the
   default at >=980px; single column only below that. Also: real decision
   option cards, composer row grouping, and rail scroll behavior.
   Tokens only (--pl-*); appended after the other planner sheets, so the
   doubled-class selectors below intentionally out-rank earlier rules. */

/* ── 1. Detail layout: crumbs + pagenav stack, then the two-column grid ── */

.pl-detail.pl-detail {
  display: flex;
  flex-direction: column;
  min-width: 0;
}

.pl-detail-grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: 20px;
  align-items: start;
  min-width: 0;
}

.pl-detail-fig,
.pl-detail-rail {
  min-width: 0;
}

.pl-detail-rail {
  display: flex;
  flex-direction: column;
  gap: 16px;
}

@media (min-width: 980px) {
  .pl-detail-grid {
    grid-template-columns: minmax(0, 1fr) minmax(320px, 400px);
  }

  /* Picture stays put while the reviewer works the rail. */
  .pl-detail-fig {
    position: sticky;
    top: 16px;
  }

  /* The rail scrolls on its own so long note lists never push the
     composer out of reach. */
  .pl-detail-rail {
    position: sticky;
    top: 16px;
    max-height: calc(100vh - 32px);
    overflow-y: auto;
    overscroll-behavior: contain;
    padding-right: 4px;
  }
}

/* ── 2. Decision options: real cards, not thin unstyled strips ── */

.pl-dq {
  margin: 0 0 10px;
  font-size: 13px;
  line-height: 1.5;
  color: var(--pl-text);
}

.pl-opt-list {
  display: flex;
  flex-direction: column;
  gap: 10px;
  margin-bottom: 12px;
}

.pl-opt {
  display: flex;
  align-items: flex-start;
  gap: 12px;
  width: 100%;
  min-height: 44px;
  padding: 12px 14px;
  text-align: left;
  border: 1px solid var(--pl-border);
  border-radius: 10px;
  background: var(--pl-panel-2);
  color: var(--pl-text);
  cursor: pointer;
  transition: border-color 150ms ease, background 150ms ease;
}

.pl-opt:hover {
  border-color: var(--pl-sky);
}

.pl-opt:focus-visible {
  outline: 2px solid var(--pl-sky);
  outline-offset: 2px;
}

.pl-opt[aria-pressed="true"] {
  border-color: var(--pl-sky);
  background: var(--pl-panel-1);
}

/* Radio-style selection dot. */
.pl-opt-radio {
  flex: 0 0 auto;
  width: 16px;
  height: 16px;
  margin-top: 1px;
  border-radius: 50%;
  border: 2px solid var(--pl-border);
  background: transparent;
  transition: border-color 150ms ease, background 150ms ease,
    box-shadow 150ms ease;
}

.pl-opt[aria-pressed="true"] .pl-opt-radio {
  border-color: var(--pl-sky);
  background: var(--pl-sky);
  box-shadow: inset 0 0 0 3px var(--pl-panel-1);
}

.pl-opt-main {
  display: flex;
  flex-direction: column;
  gap: 4px;
  min-width: 0;
}

.pl-opt-head {
  display: flex;
  align-items: center;
  gap: 8px;
  flex-wrap: wrap;
}

.pl-opt-title {
  font-size: 13px;
  font-weight: 600;
  color: var(--pl-text);
}

.pl-rb {
  padding: 2px 8px;
  border-radius: 999px;
  border: 1px solid var(--pl-green);
  color: var(--pl-green);
  font-size: 10px;
  font-weight: 600;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  white-space: nowrap;
}

.pl-why {
  font-size: 12px;
  line-height: 1.5;
  color: var(--pl-muted);
}

.pl-opt-confirm {
  display: flex;
  justify-content: flex-end;
  align-items: center;
  flex-wrap: wrap;
  gap: 10px;
}

/* ── 3. Composer alignment (scoped to the rail so other views keep
       their own spacing) ── */

.pl-detail-rail .pl-seg {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}

.pl-add-row {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin-top: 8px;
  padding-top: 10px;
  border-top: 1px dashed var(--pl-border);
}

.pl-detail-rail .pl-composer-text {
  width: 100%;
  min-height: 88px;
  margin-top: 10px;
  resize: vertical;
}

.pl-swrow-label {
  display: block;
  margin-top: 10px;
  font-size: 12px;
  color: var(--pl-muted);
}

.pl-detail-rail .pl-swrow {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: flex-start;
  gap: 8px;
  margin-top: 6px;
}

.pl-post-row {
  display: flex;
  justify-content: flex-end;
  margin-top: 10px;
}

/* ── L2 page chat (replaces the old Leave-a-note composer) ──
   One block, scoped under .pl-panel.pl-page-chat so (0,3,0)+ beats the
   later duplicate .pl-detail-rail composer rules without changing them.
   Chat transcript is the hero; kind chips and color swatches stay compact. */

.pl-panel.pl-page-chat {
  /* Mark pair — same hexes as the living logo ramp + chrome (do not invent). */
  --pl-navy: #0b1f3a;
  display: flex;
  flex-direction: column;
  gap: 8px;
  min-width: 0;
}

.pl-panel.pl-page-chat .pl-page-chat-head {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 8px;
}

.pl-panel.pl-page-chat .pl-page-chat-head .pl-panel-h {
  margin: 0 0 4px;
  font-size: 14px;
}

.pl-panel.pl-page-chat .pl-page-chat-head .pl-hint {
  margin: 0;
  font-size: 12px;
  line-height: 1.4;
}

.pl-panel.pl-page-chat .pl-page-chat-head .pl-ghost,
.pl-panel.pl-page-chat .pl-page-chat-head .pl-btn-sm {
  flex-shrink: 0;
  min-height: 28px;
  padding: 4px 10px;
  font-size: 12px;
  box-shadow: none;
  background: var(--pl-panel-2);
  border-color: var(--pl-border);
  color: var(--pl-muted);
}

.pl-panel.pl-page-chat .pl-page-chat-head .pl-ghost:hover,
.pl-panel.pl-page-chat .pl-page-chat-head .pl-btn-sm:hover {
  border-color: color-mix(in srgb, var(--pl-navy) 28%, var(--pl-border));
  background: var(--pl-panel-2);
  color: var(--pl-text);
}

.pl-panel.pl-page-chat .pl-page-chat-free {
  margin: 0;
  padding: 4px 8px;
  font-size: 11px;
  line-height: 1.4;
  color: var(--pl-muted);
  background: color-mix(in srgb, var(--pl-green) 10%, transparent);
  border-radius: 6px;
}

.pl-panel.pl-page-chat .pl-page-chat-thread-lbl {
  display: flex;
  flex-direction: column;
  gap: 4px;
  font-size: 11px;
  font-weight: 600;
  color: var(--pl-muted);
}

.pl-panel.pl-page-chat .pl-page-chat-thread {
  width: 100%;
  min-height: 32px;
  padding: 5px 8px;
  font-family: var(--font-sans);
  font-size: 12px;
  font-weight: 500;
  color: var(--pl-text);
  background: var(--pl-panel-1);
  border: 1px solid var(--pl-border);
  border-radius: 6px;
}

.pl-panel.pl-page-chat .pl-page-chat-thread:focus-visible {
  outline: 2px solid var(--pl-sky);
  outline-offset: 2px;
}

.pl-panel.pl-page-chat .pl-toast {
  position: static;
  inset: auto;
  margin: 0;
  padding: 8px 10px;
  font-size: 12px;
  box-shadow: none;
  z-index: auto;
  animation: none;
}

.pl-panel.pl-page-chat .pl-page-chat-log {
  display: flex;
  flex-direction: column;
  gap: 8px;
  min-height: 140px;
  max-height: 280px;
  overflow-x: hidden;
  overflow-y: auto;
  overscroll-behavior: contain;
  scroll-behavior: smooth;
  padding: 10px;
  border: 1px solid var(--pl-border);
  border-radius: 10px;
  background: var(--pl-panel-1);
  scrollbar-width: thin;
  scrollbar-color: var(--pl-track) transparent;
}

.pl-panel.pl-page-chat .pl-page-chat-turn {
  display: flex;
  flex-direction: column;
  gap: 4px;
  max-width: 100%;
}

.pl-panel.pl-page-chat .pl-page-chat-turn-user {
  align-items: flex-end;
}

.pl-panel.pl-page-chat .pl-page-chat-turn-bot {
  align-items: flex-start;
}

.pl-panel.pl-page-chat .pl-page-chat-bubble {
  margin: 0;
  max-width: 92%;
  padding: 8px 11px;
  border-radius: 12px;
  font-size: 13px;
  line-height: 1.45;
  white-space: pre-wrap;
  overflow-wrap: anywhere;
}

.pl-panel.pl-page-chat .pl-page-chat-turn-user .pl-page-chat-bubble {
  background: var(--pl-navy);
  color: #ffffff;
  border-bottom-right-radius: 4px;
}

.pl-panel.pl-page-chat .pl-page-chat-turn-bot .pl-page-chat-bubble {
  background: var(--pl-block);
  color: var(--pl-text);
  border-bottom-left-radius: 4px;
}

.pl-panel.pl-page-chat .pl-page-chat-turn-sys {
  align-items: stretch;
}

.pl-panel.pl-page-chat .pl-page-chat-turn-sys .pl-page-chat-bubble {
  max-width: 100%;
  background: color-mix(in srgb, var(--pl-amber) var(--pl-chip-bg-mix), transparent);
  border: 1px solid color-mix(in srgb, var(--pl-amber) var(--pl-chip-border-mix), transparent);
  color: var(--pl-muted);
  font-size: 12px;
  border-radius: 8px;
}

.pl-panel.pl-page-chat .pl-page-chat-actions .pl-page-chat-confirm {
  background: color-mix(in srgb, var(--pl-green) var(--pl-chip-bg-mix), transparent);
  border-color: color-mix(in srgb, var(--pl-green) var(--pl-chip-border-mix), transparent);
  color: var(--pl-green);
}

.pl-panel.pl-page-chat .pl-page-chat-actions .pl-page-chat-confirm:hover {
  border-color: var(--pl-green);
  background: color-mix(in srgb, var(--pl-green) 20%, var(--pl-panel-1));
  color: var(--pl-green);
}

.pl-panel.pl-page-chat .pl-page-chat-actions,
.pl-panel.pl-page-chat .pl-page-chat-starters {
  display: flex;
  flex-wrap: wrap;
  gap: 4px;
}

.pl-panel.pl-page-chat .pl-page-chat-start {
  display: flex;
  flex-direction: column;
  gap: 8px;
  margin: 2px 0 4px;
}

.pl-panel.pl-page-chat .pl-page-chat-start-q {
  margin: 0;
  font-size: 12.5px;
  font-weight: 700;
  letter-spacing: 0.02em;
  color: var(--pl-text);
}

.pl-panel.pl-page-chat .pl-page-chat-starters {
  display: flex;
  flex-direction: column;
  flex-wrap: nowrap;
  gap: 6px;
}

.pl-panel.pl-page-chat .pl-page-chat-starter {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  width: 100%;
  margin: 0;
  padding: 10px 12px;
  text-align: left;
  cursor: pointer;
  border-radius: 12px;
  border: 1px solid color-mix(in srgb, var(--pl-sky) 40%, var(--pl-border));
  background: color-mix(in srgb, var(--pl-sky) 10%, var(--pl-panel-1));
  color: var(--pl-text);
  position: relative;
  overflow: visible;
  transition: border-color 150ms ease, background 150ms ease, transform 150ms ease;
}

.pl-panel.pl-page-chat .pl-page-chat-starter:hover,
.pl-panel.pl-page-chat .pl-page-chat-starter:focus-visible {
  border-color: var(--pl-sky);
  background: color-mix(in srgb, var(--pl-sky) 18%, var(--pl-panel-1));
  transform: translateY(-1px);
}

.pl-panel.pl-page-chat .pl-page-chat-starter-k {
  flex: 0 0 auto;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 22px;
  height: 22px;
  margin-top: 1px;
  border-radius: 999px;
  font-size: 11px;
  font-weight: 700;
  color: #fff;
  background: linear-gradient(135deg, var(--pl-blue), var(--pl-sky));
}

.pl-panel.pl-page-chat .pl-page-chat-starter-copy {
  display: flex;
  flex-direction: column;
  gap: 2px;
  min-width: 0;
}

.pl-panel.pl-page-chat .pl-page-chat-starter-copy strong {
  font-size: 13px;
  font-weight: 700;
  line-height: 1.25;
}

.pl-panel.pl-page-chat .pl-page-chat-starter-copy span {
  font-size: 11.5px;
  line-height: 1.35;
  color: var(--pl-muted);
}

.pl-panel.pl-page-chat .pl-btn.pl-btn-sm {
  box-shadow: none;
  transform: none;
}

.pl-panel.pl-page-chat .pl-btn.pl-btn-sm::after {
  content: none;
}

.pl-panel.pl-page-chat .pl-page-chat-actions .pl-btn-sm,
.pl-panel.pl-page-chat .pl-page-chat-starters .pl-btn-sm,
.pl-panel.pl-page-chat .pl-add-row .pl-btn-sm {
  min-height: 26px;
  padding: 2px 8px;
  font-size: 11px;
  font-weight: 600;
}

.pl-panel.pl-page-chat .pl-page-chat-starters .pl-btn-sm,
.pl-panel.pl-page-chat .pl-add-row .pl-btn-sm {
  background: color-mix(in srgb, var(--pl-sky) 12%, var(--pl-panel-1));
  border-color: color-mix(in srgb, var(--pl-sky) 45%, var(--pl-border));
  color: var(--pl-text);
}

.pl-panel.pl-page-chat .pl-page-chat-starters .pl-btn-sm:hover,
.pl-panel.pl-page-chat .pl-add-row .pl-btn-sm:hover {
  border-color: var(--pl-sky);
  background: color-mix(in srgb, var(--pl-sky) 20%, var(--pl-panel-1));
  color: var(--pl-text);
}

.pl-panel.pl-page-chat .pl-page-chat-actions .pl-btn-sm {
  background: var(--pl-panel-2);
  border-color: var(--pl-border);
  color: var(--pl-muted);
}

.pl-panel.pl-page-chat .pl-page-chat-actions .pl-btn-sm:hover {
  border-color: color-mix(in srgb, var(--pl-navy) 28%, var(--pl-border));
  background: var(--pl-panel-2);
  color: var(--pl-text);
}

.pl-panel.pl-page-chat .pl-add-row {
  margin-top: 0;
  padding-top: 8px;
  gap: 6px;
}

.pl-panel.pl-page-chat .pl-composer-text {
  width: 100%;
  min-height: 72px;
  margin-top: 0;
  resize: vertical;
}

.pl-panel.pl-page-chat .pl-swrow-label {
  margin-top: 2px;
  font-size: 11px;
}

.pl-panel.pl-page-chat .pl-swrow,
.pl-panel.pl-page-chat .pl-page-chat-swatches {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: flex-start;
  gap: 6px;
  margin-top: 4px;
  padding: 2px 0 0;
  border-bottom: none;
}

.pl-panel.pl-page-chat .pl-page-chat-swatches .pl-swatch {
  width: 16px;
  height: 16px;
  flex: 0 0 auto;
}

.pl-panel.pl-page-chat .pl-page-chat-swatches .pl-swatch::after {
  inset: -4px;
}

.pl-panel.pl-page-chat .pl-page-chat-swatches .pl-page-chat-pick {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  margin-left: 2px;
  padding-left: 8px;
  border-left: 1px solid var(--pl-border);
}

.pl-panel.pl-page-chat .pl-page-chat-swatches .pl-page-chat-wheel {
  position: relative;
  display: inline-flex;
  width: 22px;
  height: 22px;
  flex: 0 0 auto;
  border-radius: 50%;
  background:
    radial-gradient(
      circle at center,
      var(--pl-wheel-fill, var(--pl-panel-1)) 38%,
      transparent 40%
    ),
    conic-gradient(
      #ef4444 0deg,
      #eab308 60deg,
      #22c55e 120deg,
      #0ea5e9 180deg,
      #2563eb 240deg,
      #a855f7 300deg,
      #ef4444 360deg
    );
  box-shadow: 0 0 0 1px var(--pl-border);
  cursor: pointer;
}

.pl-panel.pl-page-chat .pl-page-chat-swatches .pl-page-chat-wheel input[type="color"] {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  padding: 0;
  border: 0;
  opacity: 0;
  cursor: pointer;
  appearance: none;
  -webkit-appearance: none;
}

.pl-panel.pl-page-chat .pl-page-chat-swatches .pl-page-chat-wheel:focus-within {
  box-shadow: 0 0 0 2px var(--pl-panel-1), 0 0 0 4px var(--pl-sky);
}

.pl-panel.pl-page-chat .pl-page-chat-hex {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  min-width: 0;
}

.pl-panel.pl-page-chat .pl-page-chat-hex-lbl {
  font-size: 10px;
  font-weight: 600;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--pl-faint);
}

.pl-panel.pl-page-chat .pl-page-chat-hex input {
  width: 7.2em;
  min-height: 28px;
  padding: 3px 7px;
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 12px;
  color: var(--pl-text);
  background: var(--pl-panel-1);
  border: 1px solid var(--pl-border);
  border-radius: 6px;
}

.pl-panel.pl-page-chat .pl-page-chat-hex input:focus {
  outline: none;
  border-color: var(--pl-sky);
  box-shadow: 0 0 0 2px color-mix(in srgb, var(--pl-sky) 20%, transparent);
}

.pl-panel.pl-page-chat .pl-page-chat-swatches .pl-page-chat-hex input {
  width: 5.8em;
  min-height: 24px;
  padding: 2px 6px;
  font-size: 11px;
}

.pl-panel.pl-page-chat .pl-page-chat-fileas {
  display: block;
  margin-top: 2px;
  font-size: 10px;
  font-weight: 600;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--pl-faint);
}

.pl-panel.pl-page-chat .pl-seg {
  display: flex;
  flex-wrap: wrap;
  gap: 4px;
  margin-bottom: 0;
}

.pl-panel.pl-page-chat .pl-seg .pl-btn-sm {
  min-height: 24px;
  padding: 1px 7px;
  font-size: 10.5px;
  font-weight: 600;
  background: var(--pl-panel-2);
  border-color: var(--pl-border);
  color: var(--pl-muted);
}

.pl-panel.pl-page-chat .pl-seg .pl-btn-sm:hover {
  border-color: color-mix(in srgb, var(--pl-navy) 28%, var(--pl-border));
  background: var(--pl-panel-2);
  color: var(--pl-text);
}

.pl-panel.pl-page-chat .pl-seg .pl-btn-sm[aria-pressed="true"] {
  background: color-mix(in srgb, var(--pl-sky) 14%, var(--pl-panel-1));
  border-color: var(--pl-sky);
  color: var(--pl-text);
}

.pl-panel.pl-page-chat .pl-page-chat-swatches .pl-swatch[aria-pressed="true"] {
  box-shadow: 0 0 0 2px var(--pl-panel-1), 0 0 0 4px var(--pl-sky);
}

.pl-panel.pl-page-chat .pl-post-row {
  display: flex;
  justify-content: flex-end;
  margin-top: 4px;
}

.pl-panel.pl-page-chat .pl-post-row .pl-btn-green {
  background: var(--pl-btn-green-grad);
}

.pl-app[data-pl-theme="dark"] .pl-panel.pl-page-chat .pl-page-chat-turn-user .pl-page-chat-bubble {
  background: var(--color-telemetry-strong, #047857);
  color: #ffffff;
}

@media (prefers-reduced-motion: reduce) {
  .pl-panel.pl-page-chat .pl-page-chat-log {
    scroll-behavior: auto;
  }

  .pl-panel.pl-page-chat .pl-btn-sm,
  .pl-panel.pl-page-chat .pl-ghost,
  .pl-panel.pl-page-chat .pl-swatch,
  .pl-panel.pl-page-chat .pl-page-chat-swatches .pl-page-chat-wheel,
  .pl-panel.pl-page-chat .pl-page-chat-hex input,
  .pl-panel.pl-page-chat .pl-toast {
    transition: none;
    animation: none;
  }
}

/* ── Guards ── */

.pl-detail-grid [hidden] {
  display: none !important;
}

@media (prefers-reduced-motion: reduce) {
  .pl-opt,
  .pl-opt-radio {
    transition: none;
  }
}

/* ── fix-studio.css: studio responsive collapse + touch targets + fixes ──
   Appended after studio.css / studio-v2.css / peek.css — same specificity,
   later cascade wins, so breakpoint overrides here supersede v2's
   1100/700px rules. Breakpoints:
     >= 1180px   3-col (left rail / stage / right rail), sticky center
     900–1180px  stage full-width on top, rails two side-by-side beneath
     < 900px     stage on top, rails one column
   Tokens: --pl-* only (both themes inherit automatically). */

/* Safety net for the overlay this sheet's rules touch. */
.pl-peek-overlay[hidden] {
  display: none !important;
}

/* The device sandbox scales to its container — never overflows it. */
.pl-studio-stage,
.pl-studio-center,
.pl-studio-rail-l,
.pl-studio-rail-r {
  min-width: 0;
}

.pl-studio-device {
  max-width: 100%;
}

.pl-studio-device .pl-studio-sandbox {
  min-width: 0;
  max-width: 100%;
}

/* ── 900–1180px: stage on top full-width, rails two-up beneath ─────────── */
@media (max-width: 1179.98px) {
  .pl-studio-stage {
    grid-template-columns: 1fr 1fr;
    grid-template-areas:
      "center center"
      "rail-l rail-r";
  }

  /* Sticky center is a 3-col-only behavior (overrides v2's 1101px rule). */
  .pl-studio-center {
    position: static;
  }

  /* Keep the sandbox center-stage but bounded, so its height stays
     moderate and the rails remain within a short scroll. */
  .pl-studio-device {
    width: min(520px, 100%);
  }
}

/* ── Under 900px: stage on top, rails single column ────────────────────── */
@media (max-width: 899.98px) {
  .pl-studio-stage {
    grid-template-columns: 1fr;
    grid-template-areas:
      "center"
      "rail-l"
      "rail-r";
  }

  .pl-studio-device {
    width: min(460px, 100%);
  }
}

/* ── Touch targets: every interactive chip/control >= 44px ─────────────── */
.pl-studio-scheme-chip,
.pl-studio-style-chip,
.pl-studio-pairing-card,
.pl-studio-toggle-row,
.pl-peek-btn {
  min-height: 44px;
}

.pl-peek-close {
  min-width: 44px;
  min-height: 44px;
}

.pl-studio-slider {
  min-height: 44px;
}

/* ── Token fix: --pl-panel is undefined; the URL pill sits on the
      panel-2 chrome bar, so panel-1 gives it the contrast step. ─────────── */
.pl-studio-device-url {
  background: var(--pl-panel-1);
}

/* ── Save gate open animation + resume banner ─────────────────────────────
   fix-savegate.css — appended after main.css and the earlier scratch files.

   1) Open animation: earlier rules animate `transform: scale(...)`, which
      clobbers any transform-based centering and leaves the card mid-flight
      if another rule composes a translate. Centering is moved onto
      `margin: auto` (transform-free, works with the overlay's flex box even
      when the card is taller than the viewport), and the entrance animates
      the standalone `scale`/`translate` properties so `transform` stays
      completely free.
   2) Styles for the planner resume banner (.pl-resume) introduced by
      planner/resume.rs. Tokens only; both themes inherit. */

.pl-save-overlay .pl-save-gate {
  margin: auto;
  animation: pl-save-gate-in 250ms ease-out;
}

@keyframes pl-save-gate-in {
  from {
    opacity: 0;
    scale: 0.95;
    translate: 0 8px;
  }
  to {
    opacity: 1;
    scale: 1;
    translate: 0 0;
  }
}

@media (prefers-reduced-motion: reduce) {
  .pl-save-overlay .pl-save-gate {
    animation: none;
  }
}

/* ── Resume banner (planner/resume.rs) ──────────────────────────────────── */

.pl-resume {
  position: fixed;
  top: 72px;
  left: 50%;
  translate: -50% 0;
  z-index: 70; /* under the save overlay (80) — saving trumps the banner */
  width: min(560px, calc(100vw - 32px));
  pointer-events: none; /* wrapper only; banners re-enable */
}

.pl-resume[hidden] {
  display: none !important;
}

.pl-resume-banner {
  pointer-events: auto;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 12px 12px 12px 16px;
  border-radius: 12px;
  background: var(--pl-panel-2);
  border: 1px solid var(--pl-border);
  box-shadow: var(--pl-modal-shadow);
  animation: pl-resume-in 250ms ease-out;
}

.pl-resume-banner[hidden] {
  display: none !important;
}

@keyframes pl-resume-in {
  from {
    opacity: 0;
    translate: 0 -8px;
  }
  to {
    opacity: 1;
    translate: 0 0;
  }
}

@media (prefers-reduced-motion: reduce) {
  .pl-resume-banner {
    animation: none;
  }
}

.pl-resume-msg {
  margin: 0;
  color: var(--pl-text);
  font-size: 14px;
  line-height: 1.5;
}

/* Dismiss ✕ — 44px minimum target */
.pl-resume-dismiss {
  flex: 0 0 auto;
  min-width: 44px;
  min-height: 44px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border: none;
  border-radius: 10px;
  background: transparent;
  color: var(--pl-text);
  font-size: 16px;
  line-height: 1;
  cursor: pointer;
}

.pl-resume-dismiss:hover {
  background: var(--pl-panel-1);
}

/* Start-fresh button — inherits .pl-btn look; enforce target size here */
.pl-resume-fresh {
  flex: 0 0 auto;
  min-height: 44px;
  min-width: 44px;
}

.pl-resume-dismiss:focus-visible,
.pl-resume-fresh:focus-visible {
  outline: 2px solid var(--pl-blue);
  outline-offset: 2px;
}

/* ── Tour overlay fixes (fix-tour.css) ─────────────────────────────────────
   Component-scoped additions for the planner how-to tour. Tokens only
   (--pl-*), so light and dark themes inherit automatically. */

/* Toggle guards: ring and tip are hidden-toggled every tour start/stop. */
.pl-tour-ring[hidden],
.pl-tour-tip[hidden] {
  display: none !important;
}

/* Comfortable interactive targets: Back / Next / Skip all reach 44px. */
.pl-tour-row .pl-btn,
.pl-tour-row .pl-tour-skip {
  min-height: 44px;
  min-width: 44px;
  padding: 10px 16px;
}

/* Visible keyboard focus on every tour control. */
.pl-tour-row .pl-btn:focus-visible,
.pl-tour-row .pl-tour-skip:focus-visible {
  outline: 2px solid var(--pl-blue);
  outline-offset: 2px;
  border-radius: 8px;
}

/* Reduced motion: the spotlight ring and tip appear and move instantly —
   no pulse, no slide. (Scrolling is already instant via JS in this mode.) */
@media (prefers-reduced-motion: reduce) {
  .pl-tour-ring,
  .pl-tour-tip {
    transition: none !important;
    animation: none !important;
  }
}

/* ── fix-theme.css — global planner theme polish (append-only batch) ──────
   1. --pl-panel alias: main.css + studio-v2.css reference var(--pl-panel),
      which was never defined. Alias it to --pl-panel-1 on .pl-app so both
      themes inherit the right value automatically (dark re-declares
      --pl-panel-1, and the alias resolves at use time).
   2. color-scheme: dark on the dark token block so native UI (scrollbars,
      form controls, popups) matches the theme.
   3. .pl-wiz-dot-btn: >=24px visual box, >=44px hit area via an expanded
      ::before layer (the button stays 24px on screen).
   4. .pl-wiz-chip-sel dark contrast: dark --pl-blue (#3b82f6) under 13px
      white text is ~3.7:1; mixing 72% blue over --pl-panel-1 lands ~5.4:1.
   5. .pl-pic-pill-btn / .pl-pic-pill-inspect: 44px minimum targets. */

.pl-app {
  --pl-panel: var(--pl-panel-1);
}

.pl-app[data-pl-theme="dark"] {
  color-scheme: dark;
}

/* Wizard progress dots: 24px visual, 44px hit area. */
.pl-wiz-dot-btn {
  width: 24px;
  height: 24px;
}

.pl-wiz-dot-btn::before {
  content: "";
  position: absolute;
  inset: -10px; /* 24px box + 10px on each side = 44px hit area */
  border-radius: 50%;
}

/* Selected wizard chip: keep the light-theme blue as-is (passes 4.5:1),
   darken the dark-theme fill so 13px white text passes 4.5:1. */
.pl-app[data-pl-theme="dark"] .pl-wiz-chip-sel {
  border-color: color-mix(in srgb, var(--pl-blue) 72%, var(--pl-panel-1));
  background: color-mix(in srgb, var(--pl-blue) 72%, var(--pl-panel-1));
}

/* Picture-region pill actions: 44px minimum targets. */
.pl-pic-pill-btn {
  min-height: 44px;
}

.pl-pic-pill-inspect {
  min-width: 44px;
  min-height: 44px;
}

/* ═════════════════════════════════════════════════════════════════════════
   CONSOLIDATED — Map view (chart stage, clusters, picture nodes, area tabs,
   flow confirm, edge canvas)

   Cascade-resolved rewrite. For every selector below this is the WINNING
   computed style as of main.css today (later block beats earlier at equal
   specificity; higher-specificity `.pl-app …` selectors win regardless of
   source order). No visual value has been changed — this is a refactor,
   not a redesign. Verified against live markup in
   crates/d3pth-web/src/planner/map_view.rs (grep, 2026-08-16).

   SOURCE BLOCKS FOLDED IN (see report for exact line ranges / disposition):
     - unmarked base layer (~2836-3363)              — .pl-app root sheet
     - "review fixes v5.2" (~6047-6907)               — area-tabs, pl-page-cell
     - "wizard v7" (8290-8584)                        — pl-chart-*, pl-pic-*
     - "map view fixes / fix-map.css" (~8945-9056)    — NOT in the given
       marker inventory; discovered during this pass. Appended after wizard
       v7/picturenodes v8 and is the FINAL word on .pl-pic-face aspect-ratio,
       .pl-pic-placeholder-fallback visibility, .pl-page-cell flow-handle
       anchor, and .pl-flow-hint's static-vs-absolute positioning.

   TOKENS: this scope defines no new custom properties. Every value below
   reads existing --pl-* / --font-* tokens declared upstream in .pl-app and
   .pl-app[data-pl-theme="dark"] (main.css ~2836-2946). Nothing to hoist.
   ═════════════════════════════════════════════════════════════════════════ */

/* ─────────────────────────────────────────────────────────────────────────
   SHARED BASE PRIMITIVES — used ON map-view markup but NOT owned by it
   (also rendered by gallery/detail views). Listed here only so the map
   view's cascade reads complete; do not delete their source rules as part
   of a map-only cleanup, and do not let another view's consolidation pass
   duplicate them a second time. Flagged individually in the report.
   ───────────────────────────────────────────────────────────────────────── */

.pl-node {
  position: relative;
  padding: 12px;
  background: var(--pl-panel-2);
  border: 1px solid var(--pl-border);
  border-radius: 12px;
  min-width: 180px;
  max-width: 280px;
  cursor: pointer;
  box-shadow: var(--pl-shadow-card);
  transition: all 150ms;
}

.pl-node:hover {
  border-color: var(--pl-blue);
  transform: translateY(-2px);
  box-shadow: var(--pl-shadow-float);
}

.pl-node-sel {
  border: 1px solid var(--pl-sky);
  box-shadow: 0 0 0 1px var(--pl-sky), var(--pl-shadow-float);
}

.pl-node-ghost {
  border: 2px dashed var(--pl-sky);
  background: color-mix(in srgb, var(--pl-sky) 6%, transparent);
}

/* Compatibility alias carried by the business node (data-nid="site"); its
   own box model is fully replaced by .pl-chart-biz below — only the
   flex-centering here still applies (it's never overridden). */
.pl-node-site {
  display: flex;
  align-items: center;
  justify-content: center;
}

.pl-node-site .pl-nid {
  text-align: center;
}

.pl-add-card {
  display: flex;
  align-items: center;
  justify-content: center;
  min-width: 180px;
  height: 60px;
  background: var(--pl-panel-1);
  border: 2px dashed var(--pl-border);
  border-radius: 12px;
  cursor: pointer;
  transition: all 150ms;
  color: var(--pl-muted);
  font-size: 14px;
  font-weight: 500;
}

.pl-add-card:hover {
  border-color: var(--pl-blue);
  background: color-mix(in srgb, var(--pl-blue) 6%, var(--pl-panel-1));
  color: var(--pl-text);
}

/* Bare fallback — always beaten by the scoped .pl-pic-caption .pl-nid /
   .pl-pic-caption .pl-nt rules below wherever a picture-node caption is
   involved, but still the only rule for .pl-node-site's centered id/name
   pair via the pl-zone-biz-* aliases (equal specificity, order-dependent —
   see the "shared base" note in the report). */
.pl-nid {
  font-size: 11px;
  font-family: var(--font-mono);
  color: var(--pl-faint);
  opacity: 0.7;
}

.pl-nt {
  font-size: 13px;
  font-weight: 600;
  color: var(--pl-text);
  margin-top: 4px;
}

/* Equal-specificity (0,2,0) descendant rules — win over bare .pl-nid/.pl-nt
   above wherever a plain .pl-node card wraps them (source order breaks the
   tie), and in turn get beaten property-by-property, not wholesale, by the
   .pl-pic-caption .pl-nid / .pl-pic-caption .pl-nt rules further down (also
   0,2,0, later in file): font-size/letter-spacing/color end up from the
   .pl-pic-caption rules, but display:block/margin-bottom:3px/text-
   transform:uppercase here are never touched by those and still apply —
   this is the real merged computed style for picture-node captions, not
   either rule read in isolation. */
.pl-node .pl-nid {
  display: block;
  margin-bottom: 3px;
  text-transform: uppercase;
}

.pl-node .pl-nt {
  display: block;
  margin-bottom: 3px;
}

/* Map-card chips must keep the glassglow family (--pl-chip-hue), not the
   old opaque stamp. Layout only here; paint comes from the glass pass. */
.pl-node .pl-chip {
  margin-top: 7px;
  display: inline-flex;
  background: color-mix(in srgb, var(--pl-chip-hue, var(--pl-sky)) 16%, var(--pl-glass-bg));
  backdrop-filter: blur(10px) saturate(1.3);
  -webkit-backdrop-filter: blur(10px) saturate(1.3);
  border: 1px solid color-mix(in srgb, var(--pl-chip-hue, var(--pl-sky)) 42%, var(--pl-glass-border));
  box-shadow: inset 0 1px 0 color-mix(in srgb, #ffffff 55%, transparent),
    0 0 14px -6px color-mix(in srgb, var(--pl-chip-hue, var(--pl-sky)) 40%, transparent);
  color: var(--pl-text);
}

.pl-badges {
  display: flex;
  gap: 6px;
  flex-wrap: wrap;
  align-items: center;
}

.pl-notes-dot {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 18px;
  height: 18px;
  border-radius: 50%;
  background: color-mix(in srgb, var(--pl-blue) 20%, transparent);
  border: 1px solid var(--pl-blue);
  color: var(--pl-blue);
  font-size: 10px;
  font-weight: 600;
  font-family: var(--font-mono);
}

/* .pl-empty and .pl-hint: base rules for both live outside all four given
   marker blocks (shared root-layer primitives, unmodified by anything in
   this scope). Map view uses .pl-empty only paired with the scoped
   .pl-chart-cluster-empty modifier above (that pairing is fully captured
   there); .pl-hint is used bare, no local override to reproduce. Not
   duplicated here — see report. */

/* ── Legacy tier scaffolding kept ONLY as tour-selector aliases (see
   map_view.rs comments at the pl-tier-list/pl-add-card call sites). Their
   box model is fully superseded by .pl-chart-cluster-grid / .pl-chart-add
   below; only these two bare declarations are never overridden. ────────── */

.pl-tier-label {
  display: block;
  text-align: center;
  margin: 0 0 8px;
  font-size: 10px;
  font-family: var(--font-mono);
  color: var(--pl-faint);
  text-transform: uppercase;
  letter-spacing: 0.05em;
}

.pl-tier-list {
  display: flex;
  gap: 12px;
  flex-wrap: wrap;
  justify-content: center;
}

.pl-area-lock {
  font-size: 11px;
  line-height: 1;
  filter: grayscale(1);
  opacity: 0.7;
}

/* ─────────────────────────────────────────────────────────────────────────
   MAP STAGE + EDGE CANVAS
   ───────────────────────────────────────────────────────────────────────── */

.pl-app .pl-map-stage {
  /* merged: base .pl-map-stage (position/background/border/shadow) +
     .pl-app .pl-map-stage override (display/gap/padding/overflow), the
     latter winning on every property it repeats (specificity 0,2,0 beats
     the base's 0,1,0). `flex: 1.35; min-width: 400px;` from the base rule
     are DEAD WEIGHT today — the old two-column .pl-detail grid that made
     .pl-map-stage a flex sibling no longer wraps it in map view (it's a
     direct child of .pl-app now); kept here for parity per the
     preserve-exactly instruction, flagged dead in the report. */
  position: relative;
  flex: 1.35;
  min-width: 400px;
  background: var(--pl-panel-1);
  border: 1px solid var(--pl-border);
  border-radius: 12px;
  box-shadow: var(--pl-shadow-card);
  display: flex;
  flex-direction: column;
  gap: 18px;
  padding: 16px;
  overflow-y: auto;
  overflow-x: hidden;
}

/* Base canvas rule — used directly (not every canvas sits inside
   .pl-chart-stage in every historical layout) and re-affirmed, same
   values, by the scoped rule directly below. */
.pl-edge-canvas {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  display: block;
  pointer-events: none;
  z-index: 0;
}

.pl-chart-stage .pl-edge-canvas {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  display: block;
  z-index: 0;
  pointer-events: none;
}

/* ─────────────────────────────────────────────────────────────────────────
   AREA TABS (Zone-2 quick filter — the ONLY surviving piece of the old
   three-zone "map zones" IA; pl-zone-biz*, pl-zone-pages, pl-zone-web,
   pl-web-*, pl-region-*, pl-page-grid siblings it shipped with are dead,
   see report)
   ───────────────────────────────────────────────────────────────────────── */

.pl-area-tabs {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  width: fit-content;
  max-width: 100%;
  padding: 6px;
  border-radius: 14px;
  background: var(--pl-glass-bg);
  border: 1px solid var(--pl-glass-border);
  -webkit-backdrop-filter: blur(10px);
  backdrop-filter: blur(10px);
  box-shadow: var(--pl-shadow-card);
}

.pl-area-tabs[hidden] {
  display: none !important;
}

.pl-area-tab {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  min-height: 40px;
  padding: 8px 14px;
  border-radius: 10px;
  border: 1px solid transparent;
  background: transparent;
  color: var(--pl-muted);
  font-size: 13px;
  font-weight: 600;
  cursor: pointer;
  transition: color 150ms, background-color 150ms, border-color 150ms;
}

.pl-area-tab:hover {
  color: var(--pl-text);
  border-color: var(--pl-border);
}

.pl-area-tab[aria-pressed="true"] {
  color: var(--pl-text);
  background: var(--pl-panel-2);
  border-color: color-mix(in srgb, var(--pl-sky) 45%, var(--pl-border));
  box-shadow: 0 0 0 1px color-mix(in srgb, var(--pl-sky) 35%, transparent);
}

.pl-area-tab:focus-visible {
  outline: 2px solid var(--pl-sky);
  outline-offset: 2px;
}

.pl-area-tab-count {
  font-family: var(--font-mono);
  font-size: 11px;
  line-height: 1;
  padding: 3px 7px;
  border-radius: 999px;
  background: var(--pl-block);
  color: var(--pl-faint);
}

/* .pl-area-tab-title has no dedicated rule anywhere in main.css — it
   inherits font styling from .pl-area-tab. Not a bug, nothing to move. */

/* ─────────────────────────────────────────────────────────────────────────
   CHART STAGE / FIELD / CLUSTERS
   ───────────────────────────────────────────────────────────────────────── */

.pl-chart-stage {
  position: relative;
  flex-shrink: 0;
  padding: 20px 16px 24px;
  border-radius: 12px;
  border: 1px solid var(--pl-border);
  background: color-mix(in srgb, var(--pl-panel-2) 45%, transparent);
  overflow: hidden;
}

.pl-chart-stage[hidden] {
  display: none !important;
}

.pl-chart-stage .pl-chart-label,
.pl-chart-field {
  position: relative;
  z-index: 1;
}

.pl-chart-label {
  margin-bottom: 14px;
}

.pl-chart-field {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 26px;
}

.pl-app .pl-chart-biz {
  width: 176px;
  min-width: 0;
  max-width: 176px;
}

.pl-chart-biz-caption {
  align-items: center;
  text-align: center;
}

.pl-chart-clusters {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-start;
  justify-content: center;
  gap: 22px;
  width: 100%;
}

.pl-chart-clusters[hidden] {
  display: none !important;
}

.pl-chart-cluster {
  display: flex;
  flex-direction: column;
  gap: 12px;
  flex: 1 1 260px;
  min-width: 240px;
  max-width: 100%;
  padding: 14px;
  border-radius: 10px;
  border: 1px dashed color-mix(in srgb, var(--pl-border) 85%, transparent);
  background: transparent;
  transition: opacity 150ms;
}

.pl-chart-cluster[hidden] {
  display: none !important;
}

.pl-chart-cluster-dim {
  opacity: 0.42;
}

.pl-chart-cluster-cap {
  display: flex;
  align-items: center;
  gap: 6px;
  font-family: var(--font-mono);
  font-size: 10px;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  color: var(--pl-faint);
}

.pl-chart-cluster-cap-title {
  color: var(--pl-muted);
}

.pl-chart-cluster-empty {
  margin: 0;
  font-size: 12px;
  color: var(--pl-faint);
}

.pl-chart-cluster-grid {
  display: flex;
  flex-wrap: wrap;
  justify-content: flex-start;
  gap: 14px;
  margin: 0;
  padding: 0;
  list-style: none;
}

.pl-chart-add {
  align-self: flex-start;
  height: auto;
  min-height: 44px;
}

.pl-page-cell {
  position: relative;
  display: flex;
  min-width: 0;
}

/* `.pl-page-grid .pl-node, .pl-page-grid .pl-add-card { width:100%; … }`
   (main.css ~6706) is DEAD: .pl-page-grid no longer exists in
   map_view.rs markup — the grid container is .pl-chart-cluster-grid now.
   Intentionally not reproduced here; see report. */

/* ─────────────────────────────────────────────────────────────────────────
   PICTURE NODES — face, image, placeholder, caption
   ───────────────────────────────────────────────────────────────────────── */

.pl-app .pl-pic-node {
  width: 168px;
  min-width: 152px;
  max-width: 168px;
  padding: 0;
  display: flex;
  flex-direction: column;
}

.pl-pic-node.pl-node-sel {
  transform: scale(1.035);
  z-index: 2;
}

.pl-pic-node:hover {
  transform: translateY(-2px);
}

.pl-pic-node.pl-node-sel:hover {
  transform: scale(1.035) translateY(-2px);
}

/* aspect-ratio winner: 8/5 (map-view-fixes) beats the plain 4/3 wizard-v7
   rule below it via specificity (.pl-app .pl-pic-face > .pl-pic-face). The
   bare rule still supplies every OTHER property (position/overflow/bg)
   that the fixes pass never touched. */
.pl-pic-face {
  position: relative;
  display: block;
  width: 100%;
  overflow: hidden;
  background: var(--pl-block);
}

.pl-app .pl-pic-face {
  aspect-ratio: 8 / 5;
  height: auto;
}

.pl-pic-img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: top;
}

.pl-app .pl-pic-img {
  z-index: 1;
}

.pl-pic-img-missing {
  display: none !important;
}

[data-pl-theme="dark"] .pl-pic-img {
  filter: brightness(0.92);
}

/* Neutral "picture coming" tile — requested pages, or the honest fallback
   when a real <img> 404s. Visible-by-default (flex) wins over the older
   display:none base; the :has(missing) rule below is now REDUNDANT (same
   computed value, flex, either way) but kept for parity/because nothing
   overrides it away — flag as safe-to-drop-but-harmless in the report. */
.pl-pic-placeholder {
  position: absolute;
  inset: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 4px;
  background: color-mix(in srgb, var(--pl-sky) 5%, var(--pl-block));
  border: 1px dashed color-mix(in srgb, var(--pl-sky) 35%, var(--pl-border));
}

.pl-app .pl-pic-placeholder-fallback {
  display: flex;
  z-index: 0;
}

/* Redundant with the rule above (both resolve to display:flex) — the
   original :has(.pl-pic-img-missing) condition is still true whenever it
   matters, it just no longer changes anything. Not deleted: preserve-
   exactly rule for this pass. */
.pl-pic-face:has(.pl-pic-img-missing) .pl-pic-placeholder-fallback {
  display: flex;
}

.pl-app .pl-pic-face:has(.pl-pic-img-loaded) .pl-pic-placeholder-fallback {
  display: none;
}

.pl-pic-placeholder-id {
  font-family: var(--font-mono);
  font-size: 11px;
  letter-spacing: 0.04em;
  color: var(--pl-muted);
}

.pl-pic-placeholder-label {
  font-size: 10px;
  color: var(--pl-faint);
}

.pl-pic-caption {
  display: flex;
  flex-direction: column;
  gap: 4px;
  padding: 8px 10px 10px;
}

.pl-app .pl-page-cell .pl-pic-caption {
  padding-right: 46px;
}

.pl-pic-caption .pl-nid {
  font-family: var(--font-mono);
  font-size: 10px;
  letter-spacing: 0.04em;
  color: var(--pl-faint);
}

.pl-pic-caption .pl-nt {
  font-size: 13px;
  font-weight: 600;
  color: var(--pl-text);
  line-height: 1.25;
}

.pl-pic-caption .pl-badges {
  margin-top: 2px;
}

/* ─────────────────────────────────────────────────────────────────────────
   FLOW HANDLE / HINT / CONFIRM

   Note: `.pl-pic-node .pl-flow-handle` (former wizard-v7 anchor: top-right
   of the card) is now UNREACHABLE — the flow handle is a `<span>` SIBLING
   of the `.pl-pic-node` `<button>` inside `<li class="pl-page-cell">`, not
   a descendant of it (map_view.rs:437-460), so that descendant selector
   never matches live markup. `.pl-app .pl-page-cell > .pl-flow-handle`
   (specificity 0,3,0) is both the structurally-correct AND the
   higher-specificity rule, so it's the sole winner below. Listed as a
   dead selector in the report, not as a missing class.
   ───────────────────────────────────────────────────────────────────────── */

.pl-flow-handle {
  position: absolute;
  left: 50%;
  bottom: -22px;
  transform: translateX(-50%);
  width: 44px;
  height: 44px;
  display: grid;
  place-items: center;
  background: none;
  border: none;
  padding: 0;
  cursor: grab;
  z-index: 2;
}

.pl-flow-handle::before {
  content: "";
  width: 14px;
  height: 14px;
  border-radius: 50%;
  background: linear-gradient(135deg, var(--pl-blue) 0%, var(--pl-sky) 100%);
  box-shadow: 0 2px 6px rgba(37, 99, 235, 0.4);
  transition: transform 150ms;
}

.pl-flow-handle:hover::before {
  transform: scale(1.25);
}

.pl-flow-handle:active {
  cursor: grabbing;
}

/* Final anchor for the flow handle on page cards: resets left/bottom/
   transform from the base rule above and re-anchors bottom-right of the
   li, riding the caption bar's corner instead of the artwork. */
.pl-app .pl-page-cell > .pl-flow-handle {
  top: auto;
  left: auto;
  right: 0;
  bottom: 0;
  transform: none;
  border-radius: 50%;
  z-index: 2;
}

.pl-app .pl-page-cell > .pl-flow-handle:focus-visible {
  outline: 2px solid var(--pl-sky);
  outline-offset: 2px;
}

.pl-page-cell > .pl-flow-handle[hidden] {
  display: none !important;
}

/* .pl-flow-handle--socket carries zero rules anywhere in main.css — applied
   in markup (map_view.rs:438) but currently a no-op modifier class. Not
   dead (it's live in the DOM), just unstyled; flagged for awareness. */

/* Drag hint: base rule (absolute/nowrap) is fully superseded — the
   unconditional `.pl-app .pl-flow-hint` override below applies at every
   viewport width despite its "narrow screens" source comment (the
   comment is stale, the rule itself carries no media guard). Matches the
   live markup: a plain <p> in normal flow right under the area tabs. */
.pl-flow-hint {
  position: absolute;
  font-size: 10px;
  color: var(--pl-faint);
  pointer-events: none;
  font-family: var(--font-mono);
  white-space: nowrap;
}

.pl-app .pl-flow-hint {
  position: static;
  margin: 0;
  white-space: normal;
  pointer-events: none;
}

.pl-flow-hint[hidden] {
  display: none !important;
}

.pl-flow-confirm[hidden] {
  display: none !important;
}

/* .pl-flow-confirm itself carries no visual rule beyond the [hidden] guard
   above — all its chrome (surface/padding/radius/position) comes from the
   shared .pl-tour-tip class it's always paired with in markup
   (map_view.rs:502, `class="pl-tour-tip pl-flow-confirm"`). .pl-tour-tip
   is also the tour overlay's own tip surface (tour.rs) — genuinely shared,
   not duplicated here. See report. */

/* ═════════════════════════════════════════════════════════════════════════
   REDUCED MOTION
   ═════════════════════════════════════════════════════════════════════════ */

@media (prefers-reduced-motion: reduce) {
  .pl-area-tab {
    transition: none !important;
  }

  .pl-pic-node,
  .pl-pic-node:hover,
  .pl-pic-node.pl-node-sel,
  .pl-pic-node.pl-node-sel:hover,
  .pl-chart-cluster {
    transition: none;
    transform: none;
  }
}

/* ═════════════════════════════════════════════════════════════════════════
   NAR — max-width: 640px (per the layout contract; this is the only
   breakpoint map view currently uses — no MID or WIDE rules exist for
   this scope's classes today, so those two bands are intentionally
   omitted rather than fabricated).
   ═════════════════════════════════════════════════════════════════════════ */

@media (max-width: 640px) {
  .pl-app .pl-area-tabs {
    flex-wrap: nowrap;
    width: 100%;
    max-width: 100%;
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
    scrollbar-width: none;
  }

  .pl-app .pl-area-tabs::-webkit-scrollbar {
    display: none;
  }

  .pl-app .pl-area-tab {
    flex: 0 0 auto;
    white-space: nowrap;
  }
}

/* ─────────────────────────────────────────────────────────────────────────
   consolidated-detail.css — cascade-winner consolidation for the planner
   DETAIL VIEW (detail grid, pic stage, pic zones, composer, decision
   cards, permissions, inspector, notes).

   Source of truth for this pass: crates/d3pth-web/src/planner/detail_view.rs
   (class inventory re-derived by grep, including dynamic `format!("pl-k-{}",
   note.kind)` / `format!("pl-{}", status)` class strings — those are LIVE
   even though no literal string match exists in the .rs file).

   This file is a REFACTOR, not a redesign: every rule below reproduces the
   exact winning computed style from main.css as of this pass (later block
   beats earlier at equal specificity; higher specificity beats source
   order regardless of position). Two known pre-existing cascade defects are
   preserved verbatim and flagged inline — see "CASCADE DEFECT" comments and
   the report for detail. Two known CONTRACT DEVIATIONS (z-index, one
   breakpoint) are also preserved verbatim and flagged — fixing either
   changes rendered output, which is out of scope for a lossless refactor.

   Tokens: this file introduces none of its own. All `--pl-*` tokens are
   declared once, app-wide, on `.pl-app` / `.pl-app[data-pl-theme="dark"]`
   in main.css (untouched, single source — do not duplicate here).
   ───────────────────────────────────────────────────────────────────────── */

/* ═══════════════════════════════════════════════════════════════════════
   BASE — chips, notes dot, kind/status chips (decision + notes)
   ═══════════════════════════════════════════════════════════════════════ */

/* Chip shell + suffix hues: glassglow pass (--pl-chip-hue). Opaque
   .pl-chip-* duplicates removed so map/detail stamps cannot beat glass. */

.pl-notes-dot {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 18px;
  height: 18px;
  border-radius: 50%;
  background: color-mix(in srgb, var(--pl-blue) 20%, transparent);
  border: 1px solid var(--pl-blue);
  color: var(--pl-blue);
  font-size: 10px;
  font-weight: 600;
  font-family: var(--font-mono);
}

/* Decision-note kind chip. note.kind drives a dynamic class
   `pl-k-{kind}` — every listed suffix is a live target even though none
   appear as a literal string in detail_view.rs. */
.pl-kchip {
  display: inline-flex;
  align-items: center;
  padding: 3px 7px;
  border-radius: 3px;
  font-family: var(--font-mono);
  font-size: 9px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  border: 1px solid;
  white-space: nowrap;
}

.pl-k-change {
  background: color-mix(in srgb, var(--pl-blue) var(--pl-chip-bg-mix), transparent);
  border-color: color-mix(in srgb, var(--pl-blue) var(--pl-chip-border-mix), transparent);
  color: var(--pl-blue);
}

.pl-k-question {
  background: color-mix(in srgb, var(--pl-sky) var(--pl-chip-bg-mix), transparent);
  border-color: color-mix(in srgb, var(--pl-sky) var(--pl-chip-border-mix), transparent);
  color: var(--pl-sky);
}

.pl-k-approve {
  background: color-mix(in srgb, var(--pl-green) var(--pl-chip-bg-mix), transparent);
  border-color: color-mix(in srgb, var(--pl-green) var(--pl-chip-border-mix), transparent);
  color: var(--pl-green);
}

.pl-k-reject {
  background: color-mix(in srgb, var(--pl-red) var(--pl-chip-bg-mix), transparent);
  border-color: color-mix(in srgb, var(--pl-red) var(--pl-chip-border-mix), transparent);
  color: var(--pl-red);
}

.pl-k-request {
  background: transparent;
  border: 1px dashed var(--pl-sky);
  color: var(--pl-sky);
}

.pl-k-decide {
  background: color-mix(in srgb, var(--pl-amber) var(--pl-chip-bg-mix), transparent);
  border-color: color-mix(in srgb, var(--pl-amber) var(--pl-chip-border-mix), transparent);
  color: var(--pl-amber);
}

.pl-k-logic {
  background: color-mix(in srgb, var(--pl-faint) var(--pl-chip-bg-mix), transparent);
  border-color: color-mix(in srgb, var(--pl-faint) var(--pl-chip-border-mix), transparent);
  color: var(--pl-faint);
}

.pl-k-permission {
  background: color-mix(in srgb, var(--pl-sky) var(--pl-chip-bg-mix), transparent);
  border-color: color-mix(in srgb, var(--pl-sky) var(--pl-chip-border-mix), transparent);
  color: var(--pl-sky);
}

/* Note status chip: "open" | "applied" | "queued" | default, literal in
   detail_view.rs (line ~1295). */
.pl-schip {
  display: inline-flex;
  align-items: center;
  padding: 3px 7px;
  border-radius: 3px;
  font-family: var(--font-mono);
  font-size: 9px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  border: 1px solid;
  white-space: nowrap;
}

.pl-s-open {
  background: color-mix(in srgb, var(--pl-sky) var(--pl-chip-bg-mix), transparent);
  border-color: color-mix(in srgb, var(--pl-sky) var(--pl-chip-border-mix), transparent);
  color: var(--pl-sky);
}

.pl-s-applied {
  background: color-mix(in srgb, var(--pl-green) var(--pl-chip-bg-mix), transparent);
  border-color: color-mix(in srgb, var(--pl-green) var(--pl-chip-border-mix), transparent);
  color: var(--pl-green);
}

.pl-s-queued {
  background: color-mix(in srgb, var(--pl-amber) var(--pl-chip-bg-mix), transparent);
  border-color: color-mix(in srgb, var(--pl-amber) var(--pl-chip-border-mix), transparent);
  color: var(--pl-amber);
}

/* ═══════════════════════════════════════════════════════════════════════
   BASE — pagenav tabs, breadcrumbs, figure captions
   ═══════════════════════════════════════════════════════════════════════ */

/* detail_view.rs's pagenav tabs set aria-pressed, never aria-selected —
   the base [aria-selected="true"] variant in main.css is inert for this
   element (it's live for the unrelated topbar .pl-tabs, out of scope). */
.pl-tab {
  min-height: 40px; /* base 30px, raised by the later single-prop rule */
  padding: 6px 12px;
  background: transparent;
  border: 1px solid transparent;
  border-radius: 6px;
  color: var(--pl-muted);
  cursor: pointer;
  font-size: 13px;
  font-weight: 500;
  position: relative; /* enables the ::after 44px hit-area expansion below */
  transition: color 150ms, border-color 150ms, background-color 150ms;
}

.pl-tab:hover {
  color: var(--pl-text);
  border-color: var(--pl-border);
}

.pl-tab[aria-pressed="true"] {
  background: var(--pl-panel-2);
  color: var(--pl-text);
}

/* Invisible hit-area expansion — visual box stays 40px tall, hit target
   grows by 12px on every side (>=44px effective, contract-compliant). */
.pl-tab::after {
  content: "";
  position: absolute;
  inset: -12px;
}

.pl-crumbs {
  display: flex;
  gap: 8px;
  align-items: center;
  font-size: 12px;
  margin-bottom: 12px;
  color: var(--pl-muted);
}

.pl-crumb-here {
  color: var(--pl-text);
  font-weight: 500;
}

.pl-pagenav {
  display: flex;
  gap: 8px;
  margin-top: 12px;
}

.pl-fig-head {
  font-size: 15px;
  font-weight: 600;
  color: var(--pl-text);
  margin-bottom: 4px;
}

.pl-fig-meta {
  font-size: 12px;
  color: var(--pl-muted);
  margin-bottom: 12px;
}

/* ═══════════════════════════════════════════════════════════════════════
   BASE — buttons (pl-btn / pl-btn-green / pl-btn-sm / pl-ghost)
   ═══════════════════════════════════════════════════════════════════════ */

.pl-btn {
  position: relative;
  overflow: hidden;
  min-height: 44px;
  padding: 8px 16px;
  background: var(--pl-btn-primary-grad);
  color: #ffffff;
  border: none;
  border-radius: 10px;
  font-size: 13px;
  font-weight: 600;
  cursor: pointer;
  box-shadow: var(--pl-btn-shadow);
  transition: transform 150ms ease, box-shadow 150ms ease;
  font-family: var(--font-sans);
}

.pl-btn::after {
  content: "";
  position: absolute;
  top: 0;
  left: -150%;
  width: 60%;
  height: 100%;
  background: var(--pl-sheen);
  transform: skewX(-20deg);
  transition: left 600ms ease;
  pointer-events: none;
}

.pl-btn:hover {
  transform: translateY(-1px);
  box-shadow: var(--pl-btn-shadow-hover);
}

.pl-btn:hover::after {
  left: 150%;
}

.pl-btn:active {
  transform: translateY(0);
  box-shadow: var(--pl-btn-shadow);
}

.pl-btn:focus-visible {
  outline: 2px solid var(--pl-sky);
  outline-offset: 2px;
}

.pl-btn-green {
  position: relative;
  overflow: hidden;
  min-height: 44px;
  padding: 8px 16px;
  background: var(--pl-btn-green-grad);
  color: #ffffff;
  border: none;
  border-radius: 10px;
  font-size: 13px;
  font-weight: 600;
  cursor: pointer;
  box-shadow: var(--pl-btn-green-shadow);
  transition: transform 150ms ease, box-shadow 150ms ease;
  font-family: var(--font-sans);
}

.pl-btn-green::after {
  content: "";
  position: absolute;
  top: 0;
  left: -150%;
  width: 60%;
  height: 100%;
  background: var(--pl-sheen);
  transform: skewX(-20deg);
  transition: left 600ms ease;
  pointer-events: none;
}

.pl-btn-green:hover {
  transform: translateY(-1px);
  box-shadow: var(--pl-btn-green-shadow-hover);
}

.pl-btn-green:hover::after {
  left: 150%;
}

.pl-btn-green:active {
  transform: translateY(0);
  box-shadow: var(--pl-btn-green-shadow);
}

.pl-btn-green:focus-visible {
  outline: 2px solid var(--pl-sky);
  outline-offset: 2px;
}

.pl-btn-sm {
  min-height: 34px;
  padding: 4px 12px;
  font-size: 12px;
  background: var(--pl-glass-bg);
  backdrop-filter: blur(10px) saturate(1.2);
  -webkit-backdrop-filter: blur(10px) saturate(1.2);
  color: var(--pl-muted);
  border: 1px solid var(--pl-glass-border);
  border-radius: 6px;
  cursor: pointer;
  transition: all 150ms;
}

@supports not ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
  .pl-btn-sm {
    background: var(--pl-panel-2);
  }
}

.pl-btn-sm:hover {
  border-color: var(--pl-blue);
  color: var(--pl-text);
  background: color-mix(in srgb, var(--pl-blue) 10%, var(--pl-glass-bg));
}

.pl-btn-sm:focus-visible {
  outline: 2px solid var(--pl-sky);
  outline-offset: 2px;
}

.pl-ghost {
  min-height: 44px;
  padding: 6px 12px;
  background: var(--pl-glass-bg);
  backdrop-filter: blur(10px) saturate(1.2);
  -webkit-backdrop-filter: blur(10px) saturate(1.2);
  border: 1px solid var(--pl-glass-border);
  color: var(--pl-text);
  border-radius: 6px;
  font-size: 13px;
  cursor: pointer;
  transition: all 150ms;
}

@supports not ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
  .pl-ghost {
    background: var(--pl-panel-2);
  }
}

.pl-ghost:hover {
  border-color: var(--pl-blue);
  background: color-mix(in srgb, var(--pl-blue) 10%, var(--pl-glass-bg));
}

.pl-ghost:focus-visible {
  outline: 2px solid var(--pl-sky);
  outline-offset: 2px;
}

/* ═══════════════════════════════════════════════════════════════════════
   BASE — segments, labels, swatches, form field (composer textarea)
   ═══════════════════════════════════════════════════════════════════════ */

/* Base .pl-seg, overridden inside the composer rail (higher specificity):
   display/flex-wrap/gap win from the scoped rule, margin-bottom survives
   from base (not redeclared by the winner). */
.pl-seg {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin-bottom: 12px;
}

.pl-lbl {
  display: block;
  font-size: 12px;
  font-weight: 500;
  color: var(--pl-text);
  margin-bottom: 6px;
}

/* Base .pl-swrow, overridden inside the composer rail: display/flex-wrap/
   align-items/justify-content(flex-start, was space-between)/gap/margin-top
   win from the scoped rule; padding and border-bottom survive from base. */
.pl-swrow {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: flex-start;
  gap: 8px;
  margin-top: 6px;
  padding: 8px 0;
  border-bottom: 1px solid var(--pl-border);
}

.pl-swrow:last-child {
  border-bottom: none;
}

.pl-swatch {
  display: inline-block;
  width: 18px;
  height: 18px;
  border-radius: 4px;
  border: 1px solid var(--pl-border);
  cursor: pointer;
  position: relative; /* enables the ::after 44px hit-area expansion below */
  transition: all 150ms;
}

.pl-swatch:hover {
  box-shadow: 0 0 0 2px var(--pl-sky);
}

.pl-swatch[aria-pressed="true"] {
  box-shadow: 0 0 0 2px var(--pl-panel-1), 0 0 0 4px var(--pl-sky);
}

.pl-swatch:focus-visible {
  outline: 2px solid var(--pl-sky);
  outline-offset: 2px;
}

.pl-swatch::after {
  content: "";
  position: absolute;
  inset: -12px;
}

/* Composer textarea (.pl-composer-text) inherits its field chrome from
   this generic selector, which also styles gallery/save-gate/style-studio
   inputs — SHARED, owned elsewhere, reproduced here read-only so this
   file documents the composer's actual computed style. Do not delete
   from main.css on this file's account. */
.pl-app textarea {
  font-family: var(--font-sans);
  color: var(--pl-text);
  background: var(--pl-panel-1);
  border: 1px solid var(--pl-border);
  border-radius: 6px;
  padding: 8px 12px;
  font-size: 13px;
}

.pl-app textarea:focus {
  outline: none;
  border-color: var(--pl-blue);
  box-shadow: 0 0 0 2px color-mix(in srgb, var(--pl-blue) 20%, transparent);
}

/* ═══════════════════════════════════════════════════════════════════════
   BASE — toast, empty, hint, choice items (legacy decision list)
   ═══════════════════════════════════════════════════════════════════════ */

.pl-toast {
  position: fixed;
  bottom: 20px;
  right: 20px;
  padding: 12px 16px;
  background: var(--pl-panel-2);
  border: 1px solid var(--pl-border);
  border-radius: 8px;
  color: var(--pl-text);
  font-size: 13px;
  box-shadow: var(--pl-shadow-float);
  z-index: 90; /* toast band */
  animation: toast-slide 300ms ease-out;
}

.pl-warn-toast {
  background: color-mix(in srgb, var(--pl-amber) 12%, var(--pl-panel-2));
  border: 1px solid var(--pl-amber, #f59e0b);
  color: var(--pl-amber);
}

@keyframes toast-slide {
  from {
    transform: translateX(400px);
    opacity: 0;
  }
  to {
    transform: translateX(0);
    opacity: 1;
  }
}

.pl-hint {
  font-size: 12px;
  color: var(--pl-faint);
  margin-top: 4px;
}

.pl-empty {
  padding: 40px 20px;
  text-align: center;
  color: var(--pl-muted);
  font-size: 14px;
}

/* pl-citem/-cm/-cid/-cnode: the legacy choice-list card. Still present in
   main.css; keep only if detail_view.rs still renders this list — verify
   before deleting from main.css (see report — grep shows it live). */
.pl-citem {
  background: var(--pl-panel-1);
  border: 1px solid var(--pl-border);
  border-radius: 8px;
  padding: 12px;
  margin-bottom: 8px;
  box-shadow: var(--pl-shadow-card);
  transition: all 150ms;
  cursor: pointer;
}

.pl-citem:hover {
  border-color: var(--pl-blue);
  background: color-mix(in srgb, var(--pl-blue) 6%, var(--pl-panel-1));
  box-shadow: var(--pl-shadow-float);
}

.pl-cm {
  font-size: 13px;
  font-weight: 500;
  color: var(--pl-text);
  margin-bottom: 4px;
}

.pl-cid {
  font-size: 11px;
  font-family: var(--font-mono);
  color: var(--pl-faint);
  opacity: 0.7;
}

.pl-cnode {
  display: flex;
  gap: 4px;
  margin-top: 6px;
  flex-wrap: wrap;
}

/* ═══════════════════════════════════════════════════════════════════════
   BASE — complex decision/apply row, permission matrix
   ═══════════════════════════════════════════════════════════════════════ */

.pl-ct {
  font-size: 13px;
  font-weight: 600;
  color: var(--pl-text);
  margin-bottom: 8px;
}

.pl-cx {
  display: flex;
  gap: 8px;
  align-items: center;
  padding: 8px 0;
  border-bottom: 1px solid var(--pl-border);
}

.pl-cx:last-child {
  border-bottom: none;
}

.pl-cx-sw {
  flex-shrink: 0;
}

.pl-res {
  font-size: 12px;
  color: var(--pl-muted);
  margin-top: 4px;
}

.pl-queue-note {
  background: color-mix(in srgb, var(--pl-amber) 6%, transparent);
  border: 1px solid color-mix(in srgb, var(--pl-amber) 30%, var(--pl-border));
  border-radius: 6px;
  padding: 8px 12px;
  font-size: 12px;
  color: var(--pl-amber);
  margin-top: 8px;
}

.pl-apply-row {
  display: flex;
  gap: 8px;
  align-items: center;
  padding: 12px;
  background: var(--pl-panel-1);
  border: 1px solid var(--pl-border);
  border-radius: 8px;
  margin-top: 8px;
  box-shadow: var(--pl-shadow-card);
}

.pl-apply-btn {
  flex: 1;
}

.pl-apply-cost {
  font-size: 12px;
  color: var(--pl-muted);
  white-space: nowrap;
  font-family: var(--font-mono);
}

.pl-pbar {
  height: 6px;
  background: var(--pl-border);
  border-radius: 6px;
  overflow: hidden;
  margin: 8px 0;
}

.pl-pbar-fill {
  height: 100%;
  background: linear-gradient(90deg, var(--pl-blue) 0%, var(--pl-sky) 50%, var(--pl-green) 100%);
  width: 0%;
  transition: width 200ms ease-out;
}

.pl-pmsg {
  font-size: 12px;
  color: var(--pl-muted);
  margin-top: 4px;
  text-align: center;
}

.pl-pmx {
  background: var(--pl-panel-1);
  border: 1px solid var(--pl-border);
  border-radius: 8px;
  padding: 12px;
  margin-bottom: 8px;
  box-shadow: var(--pl-shadow-card);
}

.pl-pmx-role {
  font-size: 12px;
  font-weight: 500;
  color: var(--pl-text);
  margin-bottom: 8px;
}

.pl-ptog {
  position: relative;
  display: inline-flex;
  align-items: center;
  width: 34px;
  height: 19px;
  background: var(--pl-border);
  border-radius: 19px;
  cursor: pointer;
  border: none;
  padding: 0;
  transition: background 200ms;
}

.pl-ptog::before {
  content: "";
  position: absolute;
  left: 2px;
  width: 13px;
  height: 13px;
  background: var(--pl-panel-1);
  border-radius: 50%;
  box-shadow: 0 1px 2px rgba(15, 23, 42, 0.3);
  transition: left 200ms;
}

.pl-ptog:hover {
  background: color-mix(in srgb, var(--pl-border) 120%, transparent);
}

.pl-ptog[aria-pressed="true"] {
  background: var(--pl-green);
}

.pl-ptog[aria-pressed="true"]::before {
  left: 19px;
}

.pl-ptog:focus-visible {
  outline: 2px solid var(--pl-sky);
  outline-offset: 2px;
}

/* Invisible hit-area expansion, same pattern as tab/swatch/inspect-close. */
.pl-ptog::after {
  content: "";
  position: absolute;
  inset: -12px;
}

.pl-pmx-note {
  font-size: 11px;
  color: var(--pl-faint);
}

/* ═══════════════════════════════════════════════════════════════════════
   BASE — inspector (trigger, overlay, card, zoom, attrs)
   ═══════════════════════════════════════════════════════════════════════ */

.pl-inspect-btn {
  position: absolute;
  top: 4px;
  right: 4px;
  width: 44px;
  height: 44px;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 0;
  border: 1px solid var(--pl-border);
  border-radius: 8px;
  background: var(--pl-glass-bg);
  color: var(--pl-muted);
  font-size: 15px;
  line-height: 1;
  cursor: pointer;
  opacity: 0;
  transform: translateY(-2px);
  transition: opacity 150ms ease, transform 150ms ease, border-color 150ms ease,
    color 150ms ease;
}

.pl-wregion:hover .pl-inspect-btn,
.pl-wregion:focus-within .pl-inspect-btn,
.pl-pic-zone-wrap:hover .pl-inspect-btn,
.pl-pic-zone-wrap:focus-within .pl-inspect-btn,
.pl-pic-zone-wrap .pl-inspect-btn:focus-visible,
.pl-inspect-btn:focus-visible {
  opacity: 1;
  transform: translateY(0);
}

.pl-inspect-btn:hover,
.pl-inspect-btn:focus-visible {
  border-color: var(--pl-sky);
  color: var(--pl-sky);
}

/* CONTRACT DEVIATION (z-index): the modal band is 79/80, but the winning
   computed z-index here is 60/61 (tour-overlay band, and 61 which is not
   a band value at all). Preserved verbatim — renumbering changes stacking
   order relative to whatever else in the app sits at those values, which
   is a behavior change out of scope for this refactor. Flagged in report. */
.pl-inspect-overlay {
  position: fixed;
  inset: 0;
  z-index: 60;
  background: var(--pl-modal-backdrop);
  backdrop-filter: blur(4px);
  -webkit-backdrop-filter: blur(4px);
}

.pl-inspector {
  position: fixed;
  z-index: 61;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  width: min(760px, calc(100vw - 32px));
  max-height: calc(100vh - 64px);
  overflow-y: auto;
  padding: 20px;
  border-radius: 14px;
  background: var(--pl-glass-bg);
  border: 1px solid var(--pl-glass-border);
  box-shadow: var(--pl-modal-shadow);
  backdrop-filter: blur(20px) saturate(1.3);
  -webkit-backdrop-filter: blur(20px) saturate(1.3);
}

@supports not
  ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
  .pl-inspector {
    background: var(--pl-panel-1);
  }
}

.pl-inspect-overlay[hidden],
.pl-inspector[hidden] {
  display: none !important; /* [hidden] guard, contract-required */
}

/* CASCADE DEFECT (preserved verbatim, flagged in report): a later
   same-specificity rule (`.pl-ptog, .pl-swatch, .pl-inspect-close, ...
   { position: relative }`) overrides this element's `position: absolute`
   to `relative`. top/right:12px then offset from the button's own
   normal-flow position instead of the .pl-inspector corner. This is very
   likely an unintended side effect of a shared "44px hit area" selector
   list that should not have included .pl-inspect-close. NOT fixed here —
   changing it changes the close button's rendered position (a behavior
   change, not a refactor). See report. */
.pl-inspect-close {
  position: relative;
  top: 12px;
  right: 12px;
  width: 32px;
  height: 32px;
  display: flex;
  align-items: center;
  justify-content: center;
  border: 1px solid var(--pl-border);
  border-radius: 8px;
  background: var(--pl-panel-2);
  color: var(--pl-muted);
  font-size: 13px;
  cursor: pointer;
  transition: color 150ms ease, border-color 150ms ease;
}

.pl-inspect-close:hover,
.pl-inspect-close:focus-visible {
  color: var(--pl-text);
  border-color: var(--pl-sky);
}

.pl-inspect-close::after {
  content: "";
  position: absolute;
  inset: -12px;
}

.pl-inspect-body {
  display: grid;
  grid-template-columns: minmax(0, 1.2fr) minmax(0, 1fr);
  gap: 20px;
  margin-top: 8px;
}

.pl-inspect-zoom {
  position: relative;
  min-height: 220px;
  padding: 16px;
  border: 1px dashed var(--pl-border);
  border-radius: 10px;
  background: var(--pl-panel-2);
  display: flex;
  align-items: center;
  justify-content: center;
  overflow: hidden;
}

.pl-inspect-zoom-inner {
  position: relative;
  transform: scale(2);
  transform-origin: center;
  font-family: var(--font-mono);
  font-size: 11px;
  width: 100%;
}

.pl-inspect-pin {
  position: absolute;
  transform: translate(-50%, -100%) scale(0.5);
  transform-origin: bottom center;
}

.pl-inspect-attrs {
  display: flex;
  flex-direction: column;
  gap: 10px;
  min-width: 0;
}

.pl-inspect-chip {
  align-self: flex-start;
  padding: 3px 8px;
  border-radius: 6px;
  border: 1px solid var(--pl-border);
  background: var(--pl-panel-2);
  color: var(--pl-faint);
  font-family: var(--font-mono);
  font-size: 11px;
}

.pl-inspect-blurb {
  margin: 0;
  color: var(--pl-muted);
  font-size: 13px;
  line-height: 1.5;
}

.pl-inspect-swatch-row {
  display: flex;
  align-items: center;
  gap: 8px;
}

.pl-inspect-swatch {
  width: 18px;
  height: 18px;
  border-radius: 5px;
  border: 1px solid var(--pl-border);
  flex-shrink: 0;
}

.pl-inspect-swatch-label {
  font-family: var(--font-mono);
  font-size: 11px;
  color: var(--pl-faint);
}

.pl-inspect-actions {
  display: flex;
  flex-direction: column;
  gap: 8px;
  margin-top: 4px;
}

.pl-inspect-actions .pl-btn {
  width: 100%;
  justify-content: center;
}

/* ═══════════════════════════════════════════════════════════════════════
   BASE — picture stage + click-zones (the detail mockup IS the picture)
   ═══════════════════════════════════════════════════════════════════════ */

/* Combined selector matches the one place detail_view.rs uses it
   (`class="pl-mockbox pl-pic-stage"`, line ~794). Winning merge: the
   `.pl-mockbox.pl-pic-stage` block (0,2,0) beats the bare `.pl-mockbox`
   base (0,1,0) for display/padding/min-height/overflow/border-radius;
   background/border/color/font-size survive unopposed from base;
   position:relative is additive from a later same-specificity rule.
   align-items/justify-content from the bare-.pl-mockbox base are inert
   once display becomes block — omitted here, no visual difference. */
.pl-mockbox.pl-pic-stage {
  position: relative;
  background: var(--pl-panel-1);
  border: 1px solid var(--pl-border);
  border-radius: 12px;
  padding: 0;
  min-height: 0;
  overflow: hidden;
  color: var(--pl-faint);
  font-size: 13px;
}

.pl-pic-stage .pl-mock-img {
  margin-bottom: 0;
  border: none;
  border-radius: 0;
}

.pl-pic-wrap {
  display: flex;
  flex-direction: column;
  gap: 10px;
}

.pl-pic-zone-wrap {
  position: absolute;
  z-index: 1; /* local stacking within .pl-pic-stage, not a page-level band */
}

.pl-pic-zone {
  position: relative;
  display: block;
  width: 100%;
  height: 100%;
  min-width: 40px;
  min-height: 40px;
  padding: 0;
  margin: 0;
  border: 1px solid transparent;
  border-radius: 6px;
  background: transparent;
  cursor: pointer;
  transition: background-color 150ms ease, border-color 150ms ease,
    box-shadow 150ms ease;
}

.pl-pic-zone:hover,
.pl-pic-zone:focus-visible {
  border-color: color-mix(in srgb, var(--pl-sky) 55%, transparent);
  background: color-mix(in srgb, var(--pl-sky) 10%, transparent);
  box-shadow: 0 0 0 1px color-mix(in srgb, var(--pl-sky) 35%, transparent);
}

.pl-pic-zone:focus-visible {
  outline: 2px solid var(--pl-sky);
  outline-offset: 2px;
}

/* Reuses .pl-wregion-sel / .pl-wregion-flash semantics on a transparent
   overlay button — intentional, do not "fix" into pl-zone-specific names. */
.pl-pic-zone.pl-wregion-sel {
  border-color: var(--pl-sky);
  background: color-mix(in srgb, var(--pl-sky) 14%, transparent);
}

.pl-pic-zone.pl-wregion-flash {
  animation: pl-pic-zone-flash 600ms ease-out;
}

@keyframes pl-pic-zone-flash {
  0% {
    background: color-mix(in srgb, var(--pl-amber) 35%, transparent);
    border-color: var(--pl-amber);
  }
  100% {
    background: transparent;
    border-color: transparent;
  }
}

.pl-pic-zone-label {
  position: absolute;
  left: 50%;
  bottom: calc(100% + 6px);
  transform: translateX(-50%) translateY(2px);
  padding: 4px 8px;
  border-radius: 6px;
  background: var(--pl-glass-bg);
  border: 1px solid var(--pl-glass-border);
  color: var(--pl-text);
  font-family: var(--font-sans);
  font-size: 11px;
  font-weight: 600;
  white-space: nowrap;
  pointer-events: none;
  opacity: 0;
  transition: opacity 150ms ease, transform 150ms ease;
  z-index: 2; /* local stacking within .pl-pic-stage, not a page-level band */
}

.pl-pic-zone:hover .pl-pic-zone-label,
.pl-pic-zone:focus-visible .pl-pic-zone-label {
  opacity: 1;
  transform: translateX(-50%) translateY(0);
}

.pl-pic-stage .pl-pin {
  z-index: 3; /* local stacking within .pl-pic-stage, not a page-level band */
}

.pl-pic-pills {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}

.pl-pic-pill {
  display: inline-flex;
  align-items: stretch;
  border: 1px solid var(--pl-border);
  border-radius: 999px;
  overflow: hidden;
  background: var(--pl-panel-2);
}

/* min-height wins here: 44px (fix-theme.css, later + same specificity)
   beats the original 40px in the pictureregions block. */
.pl-pic-pill-btn {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  padding: 0 14px;
  border: none;
  background: transparent;
  color: var(--pl-text);
  font-family: var(--font-sans);
  font-size: 13px;
  font-weight: 500;
  cursor: pointer;
  transition: background-color 150ms ease, color 150ms ease;
}

.pl-pic-pill-btn:hover,
.pl-pic-pill-btn:focus-visible {
  background: color-mix(in srgb, var(--pl-sky) 12%, transparent);
  color: var(--pl-sky);
}

/* min-width/min-height win here: 44px (fix-theme.css, later + same
   specificity) beats the original 40px in the pictureregions block. */
.pl-pic-pill-inspect {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 44px;
  min-height: 44px;
  padding: 0 12px;
  border: none;
  border-left: 1px solid var(--pl-border);
  background: transparent;
  color: var(--pl-muted);
  font-size: 13px;
  cursor: pointer;
  transition: background-color 150ms ease, color 150ms ease;
}

.pl-pic-pill-inspect:hover,
.pl-pic-pill-inspect:focus-visible {
  background: color-mix(in srgb, var(--pl-sky) 12%, transparent);
  color: var(--pl-sky);
}

.pl-pic-pill-btn:focus-visible,
.pl-pic-pill-inspect:focus-visible {
  outline: 2px solid var(--pl-sky);
  outline-offset: -2px;
}

.pl-pic-crop {
  position: relative;
  width: 100%;
  overflow: hidden;
  border-radius: 6px;
  background: var(--pl-panel-1);
}

.pl-pic-crop-inner {
  position: relative;
  width: 100%;
  transform-origin: 0 0;
}

.pl-pic-crop-img {
  display: block;
  width: 100%;
  height: auto;
}

.pl-pic-crop-hint {
  margin-top: 8px;
  text-align: center;
}

/* ═══════════════════════════════════════════════════════════════════════
   BASE — detail grid layout, decision option cards, composer alignment
   ═══════════════════════════════════════════════════════════════════════ */

/* Winning merge for .pl-detail: the doubled-class override
   `.pl-detail.pl-detail` (0,2,0) beats the bare `.pl-detail` base (0,1,0)
   for display (flex, was grid) and adds flex-direction/min-width. Because
   display is no longer grid, the base's grid-template-columns (both the
   unconditional value and its max-width:950px media variant) becomes
   inert — omitted here as dead-but-harmless. flex:1 and gap:16px survive
   from the base, not redeclared by the winner. The real column split now
   lives on .pl-detail-grid below. */
.pl-detail {
  display: flex;
  flex-direction: column;
  min-width: 0;
  flex: 1;
  gap: 16px;
}

.pl-detail-grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: 20px;
  align-items: start;
  min-width: 0;
}

.pl-detail-fig,
.pl-detail-rail {
  min-width: 0;
}

.pl-detail-rail {
  display: flex;
  flex-direction: column;
  gap: 16px;
}

.pl-dq {
  margin: 0 0 10px;
  font-size: 13px;
  line-height: 1.5;
  color: var(--pl-text);
}

.pl-opt-list {
  display: flex;
  flex-direction: column;
  gap: 10px;
  margin-bottom: 12px;
}

.pl-opt {
  display: flex;
  align-items: flex-start;
  gap: 12px;
  width: 100%;
  min-height: 44px;
  padding: 12px 14px;
  text-align: left;
  border: 1px solid var(--pl-border);
  border-radius: 10px;
  background: var(--pl-panel-2);
  color: var(--pl-text);
  cursor: pointer;
  transition: border-color 150ms ease, background 150ms ease;
}

.pl-opt:hover {
  border-color: var(--pl-sky);
}

.pl-opt:focus-visible {
  outline: 2px solid var(--pl-sky);
  outline-offset: 2px;
}

.pl-opt[aria-pressed="true"] {
  border-color: var(--pl-sky);
  background: var(--pl-panel-1);
}

.pl-opt-radio {
  flex: 0 0 auto;
  width: 16px;
  height: 16px;
  margin-top: 1px;
  border-radius: 50%;
  border: 2px solid var(--pl-border);
  background: transparent;
  transition: border-color 150ms ease, background 150ms ease,
    box-shadow 150ms ease;
}

.pl-opt[aria-pressed="true"] .pl-opt-radio {
  border-color: var(--pl-sky);
  background: var(--pl-sky);
  box-shadow: inset 0 0 0 3px var(--pl-panel-1);
}

.pl-opt-main {
  display: flex;
  flex-direction: column;
  gap: 4px;
  min-width: 0;
}

.pl-opt-head {
  display: flex;
  align-items: center;
  gap: 8px;
  flex-wrap: wrap;
}

.pl-opt-title {
  font-size: 13px;
  font-weight: 600;
  color: var(--pl-text);
}

.pl-rb {
  padding: 2px 8px;
  border-radius: 999px;
  border: 1px solid var(--pl-green);
  color: var(--pl-green);
  font-size: 10px;
  font-weight: 600;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  white-space: nowrap;
}

.pl-why {
  font-size: 12px;
  line-height: 1.5;
  color: var(--pl-muted);
}

.pl-opt-confirm {
  display: flex;
  justify-content: flex-end;
  align-items: center;
  flex-wrap: wrap;
  gap: 10px;
}

.pl-add-row {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin-top: 8px;
  padding-top: 10px;
  border-top: 1px dashed var(--pl-border);
}

/* Scoped, single-definition — only ever styled inside .pl-detail-rail. */
.pl-detail-rail .pl-composer-text {
  width: 100%;
  min-height: 88px;
  margin-top: 10px;
  resize: vertical;
}

.pl-swrow-label {
  display: block;
  margin-top: 10px;
  font-size: 12px;
  color: var(--pl-muted);
}

.pl-post-row {
  display: flex;
  justify-content: flex-end;
  margin-top: 10px;
}

/* ── Guards — every [hidden] toggleable in this scope ─────────────────── */
.pl-detail-grid [hidden] {
  display: none !important;
}

.pl-nudge[hidden],
.pl-inspect-overlay[hidden],
.pl-inspector[hidden] {
  display: none !important;
}

/* ═══════════════════════════════════════════════════════════════════════
   NAR — max-width: 640px (phone)
   ═══════════════════════════════════════════════════════════════════════ */

@media (max-width: 640px) {
  .pl-inspect-body {
    grid-template-columns: 1fr;
  }
}

/* ═══════════════════════════════════════════════════════════════════════
   MID — max-width: 980px (stack boundary)
   No detail-view rule in main.css currently keys off max-width:980px —
   the mobile-first, single-column base rules above already cover NAR+MID.
   Section kept per the layout contract's three-band structure.
   ═══════════════════════════════════════════════════════════════════════ */

/* ═══════════════════════════════════════════════════════════════════════
   CONTRACT DEVIATION — existing breakpoint is min-width:980px, not the
   contract's WIDE min-width:1180px. This is the picture/rail two-column
   split (.pl-detail-fig sticky left, .pl-detail-rail sticky right) —
   preserved verbatim; renumbering to 1180px would visibly change the
   layout between 980–1180px viewports, which is a behavior change out of
   scope for a lossless refactor. Flagged in report for a deliberate
   follow-up decision (redefine WIDE for rail-bearing views, or migrate
   this one breakpoint to 1180px on purpose).
   ═══════════════════════════════════════════════════════════════════════ */

@media (min-width: 980px) {
  .pl-detail-grid {
    grid-template-columns: minmax(0, 1fr) minmax(320px, 400px);
  }

  .pl-detail-fig {
    position: sticky;
    top: 16px;
  }

  .pl-detail-rail {
    position: sticky;
    top: 16px;
    max-height: calc(100vh - 32px);
    overflow-y: auto;
    overscroll-behavior: contain;
    padding-right: 4px;
  }
}

/* ═══════════════════════════════════════════════════════════════════════
   WIDE — min-width: 1180px (rails)
   No detail-view rule in main.css currently keys off min-width:1180px —
   see the CONTRACT DEVIATION block above. Section kept per the layout
   contract's three-band structure.
   ═══════════════════════════════════════════════════════════════════════ */

/* ═══════════════════════════════════════════════════════════════════════
   REDUCED MOTION — one consolidated block, contract-required guard
   ═══════════════════════════════════════════════════════════════════════ */

@media (prefers-reduced-motion: reduce) {
  .pl-tab,
  .pl-btn,
  .pl-btn::after,
  .pl-btn-green,
  .pl-btn-green::after,
  .pl-btn-sm,
  .pl-ghost,
  .pl-swatch,
  .pl-ptog,
  .pl-ptog::before,
  .pl-pbar-fill,
  .pl-toast,
  .pl-inspect-btn,
  .pl-inspect-zoom-inner,
  .pl-pic-zone,
  .pl-pic-zone.pl-wregion-flash,
  .pl-pic-crop-inner,
  .pl-pic-pill-btn,
  .pl-pic-pill-inspect,
  .pl-opt,
  .pl-opt-radio {
    transition: none;
    animation: none;
  }
}

/* ══════════════════════════════════════════════════════════════════════
   CONSOLIDATED — Style studio (rails/stage/peeks/tryon bar) + Gallery
   (cards/showcase/nudge)

   Generated by cascade-winner analysis of style/main.css. This is a
   REFACTOR, not a redesign: every declaration below is the value that
   currently wins the cascade in the live sheet (verified by specificity
   + source order, not just "last block wins"). Two exceptions, both
   forced by the Layout Contract's hard rules and called out inline with
   `DEVIATION:` comments — z-index values collapsed onto the approved
   z-scale bands, and three ad-hoc breakpoints (900px / 1100-1101px /
   700px / 899.98px / 1179.98px) folded into the contract's exactly-three
   NAR/MID/WIDE breakpoints. Everything else is byte-for-byte the
   winning computed value.

   Classes verified LIVE by grepping crates/d3pth-web/src/planner/
   (style_studio.rs, gallery.rs) at consolidation time. Classes that
   grepped to zero uses are NOT included here — see the deletion list in
   this agent's report instead of in this file.

   Source blocks consolidated (main.css line numbers as of this pass):
     4272-4669  Form controls (scoped to planner)      [gallery/nudge part only]
     4670-4687  planner round2 polish                  [gallery ul/ol reset]
     4689-5110  Gallery showcase v4                     [full]
     5111-5616  Style studio (original v5 layout)       [component styles only —
                                                          .pl-studio-grid/-left/-right
                                                          layout itself is dead]
     5840-6045  Peek pop-outs                           [full]
     6047-6907  review fixes v5.2 (orchestrator)         [gallery/nudge/tryon slice only —
                                                          tabs/swatch/save-gate/map-zone/
                                                          node-thumb-family/detail-view
                                                          slices are OUT of this scope]
     6908-7340  Style studio v2 (centerstage)            [full]
     7341-7357  Reduced motion (studio v2)                [merged into the single
                                                          reduced-motion block below]
     9282-9409  fix-studio.css (responsive + touch)       [studio/peek slice only —
                                                          save-gate slice is OUT]

   NOT included, despite appearing inside the assigned block ranges above
   (see report for full detail):
     - .pl-inspect-* / .pl-wregion            → detail_view.rs, not studio/gallery
     - .pl-save-* / .pl-warn-toast / .pl-tab / .pl-swatch / .pl-ptog / .pl-mockbox
                                               → save-gate / detail-view, not mine
     - .pl-zone-* / .pl-area-* / .pl-page-* / .pl-web-* / .pl-region-*
                                               → map_view.rs (map-zones-builder)
     - .pl-node-thumb, .pl-nt-hero/-cta/-grid/-cell/-form/-slot/-rows/-row/
       -line/-more/-req/-ai, .pl-node-thumb-sm, .pl-wire, .pl-g3, .pl-blk,
       .pl-hero-blk                            → grepped to ZERO uses, dead
   ══════════════════════════════════════════════════════════════════════ */

/* ── Tokens consumed (documentation only — declared elsewhere, not here) ──
   --pl-studio-primary / -partner / -paper / -ink / -accent2 / -font-body /
   -font-display / -radius / -space / -anim-ms / -shadow
     Inline custom props set by StudioTheme::vars() in style_studio.rs —
     the canonical "inline style for user-picked dynamic values" pattern.
   --th-accent
     Inline per-card custom prop set by gallery.rs on .pl-gallery-card,
     read by every .pl-th-* thumb primitive and the card's own accent bits.
   ────────────────────────────────────────────────────────────────────── */

/* ══════════════════════════════════════════════════════════════════════
   BASE — Gallery
   ══════════════════════════════════════════════════════════════════════ */

.pl-gallery {
  display: flex;
  flex-direction: column;
  align-items: center;
  max-width: 1000px;
  margin: 0 auto;
  padding: 0 16px;
}

/* Semantic lists inside the gallery render unbulleted. .pl-gallery-grid
   (below) restates the same three declarations at lower specificity —
   kept here once, consolidated, instead of twice. */
.pl-gallery ul,
.pl-gallery ol {
  list-style: none;
  margin: 0;
  padding: 0;
}

.pl-gallery-intro {
  width: 100%;
  max-width: 720px;
  margin: 0 auto 28px;
  text-align: center;
}

.pl-gallery-title {
  margin: 0 0 8px;
  font-family: var(--font-display);
  font-size: 22px;
  font-weight: 600;
  color: var(--pl-text);
  line-height: 1.3;
}

.pl-gallery-sub {
  margin: 0;
  font-size: 14px;
  color: var(--pl-muted);
  line-height: 1.5;
}

.pl-gallery-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
  gap: 20px;
  width: 100%;
}

.pl-gallery-grid > li {
  display: contents;
}

/* ── Card chrome ──────────────────────────────────────────────────────── */

.pl-gallery-card {
  display: flex;
  flex-direction: column;
  width: 100%;
  background: var(--pl-glass-bg);
  border: 1px solid var(--pl-glass-border);
  border-radius: 16px;
  padding: 16px;
  cursor: pointer;
  text-align: left;
  box-shadow: var(--pl-shadow-card);
  backdrop-filter: blur(10px);
  -webkit-backdrop-filter: blur(10px);
  transition: transform 200ms ease, box-shadow 200ms ease, border-color 200ms ease;
  font-family: var(--font-sans);
}

.pl-gallery-card[hidden] {
  display: none !important;
}

.pl-gallery-card:hover {
  transform: translateY(-3px);
  border-color: color-mix(in srgb, var(--th-accent, var(--pl-sky)) 55%, var(--pl-border));
  box-shadow: var(--pl-shadow-float);
}

.pl-gallery-card:focus-visible {
  outline: 2px solid var(--th-accent, var(--pl-sky));
  outline-offset: 2px;
}

.pl-gallery-card-sel {
  border: 2px solid var(--th-accent, var(--pl-sky));
  background: color-mix(in srgb, var(--th-accent, var(--pl-sky)) 8%, var(--pl-glass-bg));
  box-shadow: 0 0 0 1px color-mix(in srgb, var(--th-accent, var(--pl-sky)) 60%, transparent),
    var(--pl-shadow-float);
}

.pl-gallery-card:hover .pl-gallery-thumb {
  transform: translateY(-2px) scale(1.01);
}

/* ── Card body text ───────────────────────────────────────────────────── */

.pl-gallery-card-body {
  display: flex;
  flex-direction: column;
  gap: 3px;
}

.pl-gallery-card-eyebrow {
  font-family: var(--font-mono);
  font-size: 10px;
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: color-mix(in srgb, var(--th-accent, var(--pl-sky)) 75%, var(--pl-muted));
  margin-bottom: 2px;
}

.pl-gallery-card-name {
  font-family: var(--font-display);
  font-size: 18px;
  font-weight: 600;
  color: var(--pl-text);
  line-height: 1.25;
}

.pl-gallery-card-accent {
  display: block;
  width: 32px;
  height: 3px;
  border-radius: 2px;
  margin: 6px 0 8px;
  background: var(--th-accent, var(--pl-sky));
}

.pl-gallery-card-company {
  font-size: 12px;
  font-weight: 600;
  color: var(--pl-faint);
}

.pl-gallery-card-desc {
  font-size: 13px;
  color: var(--pl-muted);
  line-height: 1.45;
  margin-bottom: 4px;
}

.pl-gallery-card-foot {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  margin-top: 10px;
}

.pl-gallery-card-foot .pl-btn-ghost {
  font-size: 12px;
  padding: 6px 12px;
  pointer-events: none;
}

.pl-gallery-foot {
  width: 100%;
  max-width: 720px;
  margin: 24px auto 0;
  text-align: center;
  font-size: 13px;
  color: var(--pl-faint);
  line-height: 1.5;
}

/* ── Thumb frame + primitives ─────────────────────────────────────────── */

.pl-gallery-thumb {
  --th-accent-soft: color-mix(in srgb, var(--th-accent, var(--pl-sky)) 16%, var(--pl-block));
  --th-accent-mid: color-mix(in srgb, var(--th-accent, var(--pl-sky)) 40%, var(--pl-block));
  position: relative;
  width: 100%;
  height: auto;
  aspect-ratio: 8 / 5;
  background: var(--pl-block);
  border: 1px solid var(--pl-border);
  border-radius: 12px;
  padding: 10px;
  margin-bottom: 14px;
  display: flex;
  flex-direction: column;
  gap: 6px;
  overflow: hidden;
  transition: transform 200ms ease;
}

.pl-gallery-thumb[hidden] {
  display: none !important;
}

/* Stale v3 wireframe pseudo-bars must not paint over the v4 showcase
   thumbs — v4 introduced the .pl-th-* primitives, this rule (added in
   review fixes v5.2, same file, later cascade position) nulls the old
   ::before/::after content and is the winning rule for both. */
.pl-gallery-thumb::before,
.pl-gallery-thumb::after {
  content: none;
}

.pl-th-band {
  display: block;
  flex: 1 1 auto;
  min-height: 0;
  border-radius: 8px;
  background: linear-gradient(135deg, var(--th-accent-soft), var(--th-accent-mid));
}

.pl-th-row {
  display: flex;
  align-items: center;
  gap: 6px;
  flex: 0 0 auto;
}

.pl-th-tile {
  flex: 1 1 0;
  min-width: 0;
  height: 34px;
  border-radius: 6px;
  background: var(--pl-panel-1);
  border: 1px solid var(--pl-border);
}

.pl-th-pill {
  align-self: flex-start;
  flex: 0 0 auto;
  padding: 5px 12px;
  border-radius: 999px;
  font-size: 10px;
  font-weight: 600;
  color: #fff;
  background: var(--th-accent, var(--pl-sky));
  white-space: nowrap;
}

.pl-th-split {
  display: flex;
  gap: 4px;
  flex: 1 1 auto;
  min-height: 0;
}

.pl-th-split .pl-th-tile {
  height: auto;
  border-radius: 8px;
}

.pl-th-split .pl-th-tile:first-child {
  background: var(--pl-panel-2);
}

.pl-th-split .pl-th-tile:last-child {
  background: var(--th-accent-soft);
  border-color: color-mix(in srgb, var(--th-accent, var(--pl-sky)) 35%, var(--pl-border));
}

.pl-th-dot {
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--th-accent, var(--pl-sky));
  margin-left: auto;
  flex: 0 0 auto;
}

.pl-th-grid2 {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 6px;
  flex: 1 1 auto;
  min-height: 0;
}

.pl-th-grid2 .pl-th-tile,
.pl-th-grid2 .pl-th-row {
  height: auto;
}

.pl-th-stripe {
  flex: 1 1 0;
  min-width: 0;
  height: 100%;
  min-height: 18px;
  border-radius: 4px;
  background: var(--th-accent-mid);
}

/* ── Per-kind tuning: same primitives, different feel via nth-child ─────
   All 10 kinds verified live (grep TEMPLATE_KINDS match arms in gallery.rs):
   hauling, salon, ranch, contractor, clinic, restaurant, gym, bank,
   healthcare, gov. */

.pl-gallery-thumb[data-pl-kind="hauling"] .pl-th-row .pl-th-tile {
  background: var(--pl-panel-1);
}

.pl-gallery-thumb[data-pl-kind="salon"] .pl-th-grid2 .pl-th-tile {
  border-radius: 10px;
  background: linear-gradient(160deg, var(--th-accent-soft), var(--pl-panel-1));
}

.pl-gallery-thumb[data-pl-kind="ranch"] .pl-th-band {
  flex: 1 1 70%;
}

.pl-gallery-thumb[data-pl-kind="ranch"] .pl-th-row {
  flex: 0 0 22px;
}

.pl-gallery-thumb[data-pl-kind="ranch"] .pl-th-stripe:nth-child(2n) {
  background: var(--th-accent-soft);
}

.pl-gallery-thumb[data-pl-kind="contractor"] .pl-th-split {
  flex: 1 1 60%;
}

.pl-gallery-thumb[data-pl-kind="contractor"] .pl-th-row {
  flex: 0 0 34px;
}

.pl-gallery-thumb[data-pl-kind="clinic"] .pl-th-band {
  flex: 0 0 30%;
}

.pl-gallery-thumb[data-pl-kind="clinic"] .pl-th-grid2 .pl-th-row {
  min-height: 30px;
  border-radius: 6px;
  background: var(--pl-panel-1);
  border: 1px solid var(--pl-border);
}

.pl-gallery-thumb[data-pl-kind="restaurant"] {
  justify-content: space-evenly;
}

.pl-gallery-thumb[data-pl-kind="restaurant"] .pl-th-row {
  height: 10px;
  border-radius: 3px;
  background: var(--pl-panel-1);
  border: 1px solid var(--pl-border);
  padding: 0 8px;
}

.pl-gallery-thumb[data-pl-kind="gym"] .pl-th-grid2 {
  grid-template-columns: repeat(3, 1fr);
  grid-auto-rows: 1fr;
}

.pl-gallery-thumb[data-pl-kind="gym"] .pl-th-stripe:nth-child(3n) {
  background: var(--th-accent, var(--pl-sky));
}

.pl-gallery-thumb[data-pl-kind="bank"] .pl-th-row {
  height: 22px;
  border-radius: 5px;
  background: var(--pl-panel-1);
  border: 1px solid var(--pl-border);
}

.pl-gallery-thumb[data-pl-kind="bank"] .pl-th-pill {
  align-self: flex-end;
  margin-top: auto;
}

.pl-gallery-thumb[data-pl-kind="healthcare"] .pl-th-split {
  flex: 1 1 100%;
}

.pl-gallery-thumb[data-pl-kind="healthcare"] .pl-th-split .pl-th-tile:first-child {
  background: color-mix(in srgb, var(--th-accent, var(--pl-red)) 22%, var(--pl-panel-1));
  border-color: color-mix(in srgb, var(--th-accent, var(--pl-red)) 45%, var(--pl-border));
}

.pl-gallery-thumb[data-pl-kind="gov"] .pl-th-band {
  flex: 0 0 26%;
  border-radius: 6px;
}

.pl-gallery-thumb[data-pl-kind="gov"] .pl-th-row {
  height: 20px;
  border-radius: 4px;
  background: var(--pl-panel-1);
  border: 1px solid var(--pl-border);
}

/* Portables: unit/trailer split + fence-panel stripes + book pill. */
.pl-gallery-thumb[data-pl-kind="portables"] .pl-th-split {
  flex: 1 1 100%;
  min-height: 42px;
}

.pl-gallery-thumb[data-pl-kind="portables"] .pl-th-split .pl-th-tile:first-child {
  background: color-mix(in srgb, var(--th-accent, var(--pl-green)) 28%, var(--pl-panel-1));
}

.pl-gallery-thumb[data-pl-kind="portables"] .pl-th-row {
  gap: 4px;
}

.pl-gallery-thumb[data-pl-kind="portables"] .pl-th-stripe {
  height: 10px;
  border-radius: 2px;
}

.pl-gallery-thumb[data-pl-kind="portables"] .pl-th-pill {
  align-self: flex-end;
  margin-top: auto;
}

/* ── Picture marks: real generated mockups layered over the thumb ───────
   .pl-nt-img is shared with the (dead-in-this-scope) node-thumb family;
   kept here because gallery.rs is a live consumer (mockup_url() <img>). */

.pl-nt-img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: top center;
  z-index: 2;
  border-radius: inherit;
  background: var(--pl-panel-2);
}

.pl-nt-img-missing {
  display: none !important;
}

/* An opaque loaded image owns the thumb — primitives never bleed through. */
.pl-gallery-thumb:has(.pl-nt-img:not(.pl-nt-img-missing)) > :not(.pl-nt-img) {
  visibility: hidden;
}

.pl-gallery-thumb:has(.pl-nt-img-missing) > :not(.pl-nt-img) {
  visibility: visible;
}

[data-pl-theme="dark"] .pl-nt-img {
  filter: brightness(0.92);
}

/* ── Nudge card: fixed bottom-right slide-in, glass ──────────────────────
   Glass surface itself (background/backdrop-filter/border/box-shadow) is
   NOT in this file — it comes from the shared `.pl-panel, .pl-tour-tip,
   .pl-save-gate, .pl-nudge` glass-surfaces block at main.css:3596-3605,
   which is orchestrator-owned (out of this scope) and untouched here. */

.pl-nudge {
  position: fixed;
  bottom: 24px;
  right: 24px;
  max-width: 320px;
  border-radius: 12px;
  padding: 16px;
  /* DEVIATION: source value was z-index:70, not a valid z-scale band
     (bands are 0/10/20/40/60/79/80/90 — "nothing else"). Nudge is a
     dismissible corner notification, closest contract fit is the
     toast band. Flagged in report; revert to 70 if this reads wrong
     next to a real toast. */
  z-index: 90;
  animation: slideInUp 300ms ease-out;
  font-size: 13px;
  color: var(--pl-text);
  line-height: 1.5;
}

.pl-nudge[hidden] {
  display: none !important;
}

.pl-nudge-dismiss {
  position: absolute;
  top: 6px;
  right: 6px;
  width: 32px;
  height: 32px;
  display: grid;
  place-items: center;
  border-radius: 8px;
  color: var(--pl-muted);
  background: transparent;
  border: none;
  cursor: pointer;
}

.pl-nudge-dismiss::after {
  content: "";
  position: absolute;
  inset: -8px;
}

.pl-nudge-dismiss:hover {
  color: var(--pl-text);
  background: var(--pl-panel-2);
}

.pl-nudge-dismiss:focus-visible {
  outline: 2px solid var(--pl-sky);
  outline-offset: 2px;
}

@keyframes slideInUp {
  from {
    opacity: 0;
    transform: translateY(20px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

/* ══════════════════════════════════════════════════════════════════════
   BASE — Style studio (rails / stage / center sandbox / try-on bar)
   ══════════════════════════════════════════════════════════════════════ */

.pl-studio {
  display: block;
}

.pl-studio [hidden] {
  display: none !important;
}

/* ── Three-column stage: left rail / center device / right rail ─────────
   DEVIATION: studio-v2's own base rule used an unqueried 3-col grid with
   two override breakpoints (max-width:1100/1101px, then 700px), and
   fix-studio.css later re-cut those to 1179.98px / 899.98px, producing a
   real 3-tier collapse: >=1180 three-up, 900-1179 two-up (rails stacked
   under center), <900 one-up. The Layout Contract allows exactly three
   breakpoints (NAR<=640 / MID<=980 / WIDE>=1180) and no others, so the
   900-1179 two-up tier has no home. It is folded into WIDE below (rails
   stay 3-up down to 981px, one-up at 980px and under) rather than into
   MID (rails would prematurely collapse at 981px). This changes real
   behavior for the 981-1179px window — flagged prominently in the report
   for an explicit call, not applied silently. */
.pl-studio-stage {
  display: grid;
  grid-template-columns: 1fr;
  grid-template-areas:
    "center"
    "rail-l"
    "rail-r";
  gap: 18px;
  align-items: start;
  min-width: 0;
}

.pl-studio-rail-l {
  grid-area: rail-l;
  display: flex;
  flex-direction: column;
  gap: 12px;
  min-width: 0;
}

.pl-studio-rail-r {
  grid-area: rail-r;
  display: flex;
  flex-direction: column;
  gap: 12px;
  min-width: 0;
}

.pl-studio-center {
  grid-area: center;
  display: flex;
  flex-direction: column;
  gap: 12px;
  min-width: 0;
}

/* ── Compact panels: tight paddings, all controls stay visible ─────────── */

.pl-studio-rail-l .pl-panel,
.pl-studio-rail-r .pl-panel {
  border-radius: 10px;
  padding: 12px;
}

.pl-studio-rail-l .pl-panel-h,
.pl-studio-rail-r .pl-panel-h {
  margin-bottom: 0;
  font-size: 12.5px;
}

.pl-studio-panel {
  display: flex;
  flex-direction: column;
  gap: 4px;
}

.pl-studio-hint {
  margin: -2px 0 4px;
  font-size: 11px;
  line-height: 1.4;
  color: var(--pl-muted);
}

.pl-studio-subhint {
  margin: 6px 0 -2px;
  font-size: 10px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--pl-muted);
  opacity: 0.8;
}

/* ── Color wheel + palette ────────────────────────────────────────────── */

.pl-studio-wheel-wrap {
  display: flex;
  justify-content: center;
  padding: 2px 0 4px;
}

.pl-studio-wheel {
  width: 220px;
  height: 220px;
  border-radius: 50%;
  cursor: crosshair;
  touch-action: none;
  box-shadow: var(--pl-shadow-card);
}

.pl-studio-wheel:focus-visible {
  outline: 2px solid var(--pl-sky);
  outline-offset: 4px;
}

.pl-studio-palette-row {
  display: flex;
  gap: 6px;
  flex-wrap: wrap;
  margin-top: 6px;
}

.pl-studio-swatch {
  flex: 1 1 48px;
  min-width: 44px;
  height: 42px;
  border-radius: 7px;
  border: 1px solid var(--pl-border);
  display: flex;
  align-items: flex-end;
  padding: 3px;
}

.pl-studio-swatch small {
  display: inline-block;
  padding: 1px 4px;
  border-radius: 4px;
  background: rgba(0, 0, 0, 0.4);
  color: #ffffff;
  font-size: 9px;
  line-height: 1.3;
  white-space: nowrap;
}

/* ── Chip rows: scheme, button style, glass intensity ────────────────── */

.pl-studio-scheme-row,
.pl-studio-style-chips,
.pl-studio-glass-chips {
  display: flex;
  gap: 5px;
  flex-wrap: wrap;
  margin-top: 6px;
}

.pl-studio-scheme-chip,
.pl-studio-style-chip {
  padding: 5px 10px;
  /* fix-studio.css touch-target pass: >=44px hit area. */
  min-height: 44px;
  border-radius: 999px;
  border: 1px solid var(--pl-border);
  background: var(--pl-panel-2);
  color: var(--pl-muted);
  font-size: 11px;
  font-weight: 600;
  cursor: pointer;
  transition: all 150ms;
}

.pl-studio-scheme-chip:hover,
.pl-studio-style-chip:hover {
  border-color: var(--pl-studio-primary, var(--pl-blue));
  color: var(--pl-text);
}

.pl-studio-scheme-chip:focus-visible,
.pl-studio-style-chip:focus-visible,
.pl-studio-pairing-card:focus-visible,
.pl-studio-wheel:focus-visible,
.pl-studio-toggle-row:focus-visible {
  outline: 2px solid var(--pl-sky);
  outline-offset: 2px;
}

.pl-studio-scheme-chip[aria-checked="true"],
.pl-studio-style-chip[aria-checked="true"] {
  background: var(--pl-studio-primary);
  color: #ffffff;
  border-color: transparent;
  box-shadow: 0 4px 14px -6px color-mix(in srgb, var(--pl-studio-primary) 65%, transparent);
}

/* ── Type pairing cards ───────────────────────────────────────────────── */

.pl-studio-pairing-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 6px;
}

.pl-studio-pairing-card {
  text-align: left;
  display: flex;
  flex-direction: column;
  gap: 3px;
  padding: 8px 10px;
  /* fix-studio.css touch-target pass: >=44px hit area. */
  min-height: 44px;
  border: 1px solid var(--pl-border);
  border-radius: 9px;
  background: var(--pl-panel-2);
  cursor: pointer;
  transition: border-color 150ms, background 150ms;
}

.pl-studio-pairing-card[aria-checked="true"] {
  border-color: var(--pl-studio-primary);
  background: color-mix(in srgb, var(--pl-studio-primary) 12%, var(--pl-panel-2));
}

.pl-studio-pairing-name {
  font-size: 15px;
  font-weight: 700;
  color: var(--pl-text);
}

.pl-studio-pairing-sample {
  font-size: 11px;
  color: var(--pl-muted);
}

/* ── Radius slider + button specimens ────────────────────────────────── */

.pl-studio-radius-row {
  display: flex;
  flex-direction: column;
  gap: 4px;
  font-size: 11px;
  font-weight: 600;
  color: var(--pl-muted);
  margin-bottom: 0;
}

.pl-studio-slider {
  width: 100%;
  accent-color: var(--pl-studio-primary);
  /* fix-studio.css touch-target pass: >=44px hit area. */
  min-height: 44px;
}

.pl-studio-btn-row {
  display: flex;
  gap: 8px;
  flex-wrap: wrap;
  margin-top: 8px;
  padding-top: 8px;
  border-top: 1px dashed var(--pl-border);
}

.pl-studio-btn {
  min-height: 36px;
  padding: 8px 16px;
  font-size: 12px;
  font-weight: 600;
  font-family: var(--pl-studio-font-body, inherit);
  border-radius: var(--pl-studio-radius, 10px);
  border: 1px solid transparent;
  cursor: default;
  transition: transform 150ms, box-shadow 150ms;
}

.pl-studio-btn-ghost {
  background: transparent;
  color: var(--pl-studio-ink);
  border-color: var(--pl-border);
}

[data-pl-studio-btn="gradient"] .pl-studio-btn-primary {
  background: linear-gradient(92deg, var(--pl-studio-primary), var(--pl-studio-partner));
  color: #ffffff;
  box-shadow: 0 10px 22px -10px color-mix(in srgb, var(--pl-studio-primary) 60%, transparent);
}

[data-pl-studio-btn="gradient"] .pl-studio-btn-secondary {
  background: transparent;
  color: var(--pl-studio-primary);
  border-color: var(--pl-studio-primary);
}

[data-pl-studio-btn="solid"] .pl-studio-btn-primary {
  background: var(--pl-studio-primary);
  color: #ffffff;
}

[data-pl-studio-btn="solid"] .pl-studio-btn-secondary {
  background: var(--pl-studio-partner);
  color: #ffffff;
}

[data-pl-studio-btn="outline"] .pl-studio-btn-primary {
  background: transparent;
  color: var(--pl-studio-primary);
  border-color: var(--pl-studio-primary);
}

[data-pl-studio-btn="outline"] .pl-studio-btn-secondary {
  background: transparent;
  color: var(--pl-studio-ink);
  border-color: var(--pl-border);
}

[data-pl-studio-btn="soft"] .pl-studio-btn-primary {
  background: color-mix(in srgb, var(--pl-studio-primary) 18%, transparent);
  color: var(--pl-studio-primary);
}

[data-pl-studio-btn="soft"] .pl-studio-btn-secondary {
  background: color-mix(in srgb, var(--pl-studio-partner) 18%, transparent);
  color: var(--pl-studio-partner);
}

/* ── Feel: glass chips + gradient-hero switch ────────────────────────── */

.pl-studio-toggle-row {
  display: flex;
  align-items: center;
  gap: 10px;
  width: 100%;
  padding: 6px 0 0;
  margin-top: 2px;
  background: transparent;
  border: none;
  color: var(--pl-text);
  font-size: 13px;
  font-weight: 500;
  text-align: left;
  cursor: pointer;
  /* fix-studio.css touch-target pass: >=44px hit area. */
  min-height: 44px;
}

.pl-studio-toggle {
  position: relative;
  flex: 0 0 auto;
  width: 36px;
  height: 20px;
  border-radius: 999px;
  background: var(--pl-border);
  transition: background 150ms;
}

.pl-studio-toggle::after {
  content: "";
  position: absolute;
  top: 2px;
  left: 2px;
  width: 16px;
  height: 16px;
  border-radius: 50%;
  background: #ffffff;
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.35);
  transition: transform 150ms;
}

.pl-studio-toggle-row[aria-checked="true"] .pl-studio-toggle {
  background: var(--pl-studio-primary);
}

.pl-studio-toggle-row[aria-checked="true"] .pl-studio-toggle::after {
  transform: translateX(16px);
}

/* ── Device frame: browser chrome bar over the sandbox ───────────────── */

.pl-studio-device {
  width: min(460px, 100%);
  max-width: 100%;
  margin: 0 auto;
  border-radius: 18px;
  overflow: hidden;
  border: 1px solid var(--pl-border);
  background: var(--pl-panel-2);
  box-shadow: var(--pl-shadow-card);
}

.pl-studio-device-chrome {
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 9px 12px;
  background: var(--pl-panel-2);
  border-bottom: 1px solid var(--pl-border);
}

.pl-studio-device-dot {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: var(--pl-border);
}

.pl-studio-device-url {
  margin-left: 8px;
  padding: 3px 10px;
  border-radius: 999px;
  /* Token fix from fix-studio.css: --pl-panel is undefined; panel-1 gives
     the correct contrast step against the panel-2 chrome bar. */
  background: var(--pl-panel-1);
  color: var(--pl-muted);
  font-size: 10px;
  font-weight: 600;
  letter-spacing: 0.02em;
}

.pl-studio-device .pl-studio-sandbox {
  border: none;
  border-radius: 0;
  box-shadow: none;
  min-width: 0;
  max-width: 100%;
}

/* ── Sandbox: nav → hero → tiles → footer, spaced by density token ──────
   .pl-peek-stage widens this to 100% inside the peek pop-out; see the
   Peek section below. */

.pl-studio-sandbox {
  border-radius: 16px;
  overflow: hidden;
  border: 1px solid var(--pl-border);
  background: var(--pl-studio-paper);
  color: var(--pl-studio-ink);
  font-family: var(--pl-studio-font-body, inherit);
  box-shadow: var(--pl-studio-shadow, var(--pl-shadow-card));
  transition: box-shadow 150ms;
}

.pl-studio-sb-nav {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: calc(var(--pl-studio-space, 16px) * 0.875) calc(var(--pl-studio-space, 16px) * 1.125);
  border-bottom: 1px solid color-mix(in srgb, var(--pl-studio-ink) 10%, transparent);
}

.pl-studio-sb-brand {
  font-family: var(--pl-studio-font-display, inherit);
  font-weight: 800;
  font-size: 15px;
  color: var(--pl-studio-primary);
}

.pl-studio-sb-navlinks {
  display: flex;
  gap: 14px;
  font-size: 12px;
  opacity: 0.7;
}

.pl-studio-sb-hero {
  padding: calc(var(--pl-studio-space, 16px) * 2.5) calc(var(--pl-studio-space, 16px) * 1.25);
  text-align: center;
  background: var(--pl-studio-paper);
  transition: background 150ms, padding 150ms;
}

[data-pl-studio-gradient="true"] .pl-studio-sb-hero {
  background: linear-gradient(
    160deg,
    color-mix(in srgb, var(--pl-studio-primary) 16%, var(--pl-studio-paper)),
    var(--pl-studio-paper) 72%
  );
}

.pl-studio-sb-headline {
  margin: 0 0 8px;
  font-family: var(--pl-studio-font-display, inherit);
  font-size: 22px;
  font-weight: 700;
  line-height: 1.15;
}

.pl-studio-sb-sub {
  margin: 0 0 18px;
  font-size: 13px;
  opacity: 0.75;
}

.pl-studio-sb-cta {
  min-height: 40px;
}

.pl-studio-sb-tiles {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: calc(var(--pl-studio-space, 16px) * 0.625);
  padding: var(--pl-studio-space, 16px);
}

.pl-studio-sb-tile {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: calc(var(--pl-studio-space, 16px) * 0.375);
  padding: calc(var(--pl-studio-space, 16px) * 0.875) calc(var(--pl-studio-space, 16px) * 0.5);
  border-radius: calc(var(--pl-studio-radius, 10px) * 0.8);
  background: color-mix(in srgb, var(--pl-studio-ink) 5%, transparent);
  border: 1px solid color-mix(in srgb, var(--pl-studio-ink) 8%, transparent);
  font-size: 11px;
  text-align: center;
  transition: background 150ms, backdrop-filter 150ms, padding 150ms;
}

[data-pl-studio-glass="1"] .pl-studio-sb-tile {
  background: color-mix(in srgb, var(--pl-studio-paper) 55%, transparent);
  backdrop-filter: blur(6px) saturate(1.15);
  -webkit-backdrop-filter: blur(6px) saturate(1.15);
}

[data-pl-studio-glass="2"] .pl-studio-sb-tile {
  background: color-mix(in srgb, var(--pl-studio-paper) 38%, transparent);
  border-color: color-mix(in srgb, #ffffff 30%, transparent);
  box-shadow: 0 10px 26px -14px rgba(0, 0, 0, 0.3);
  backdrop-filter: blur(14px) saturate(1.3);
  -webkit-backdrop-filter: blur(14px) saturate(1.3);
}

.pl-studio-sb-tile-dot {
  width: 10px;
  height: 10px;
  border-radius: 50%;
  background: var(--pl-studio-accent2);
}

.pl-studio-sb-footer {
  padding: calc(var(--pl-studio-space, 16px) * 0.75) calc(var(--pl-studio-space, 16px) * 1.125);
  border-top: 1px solid color-mix(in srgb, var(--pl-studio-ink) 10%, transparent);
  font-size: 10px;
  opacity: 0.55;
  text-align: center;
}

/* ── Entrance animations: replayed on draft change via a bump-driven
   remove/reflow/add of .pl-studio-entrance-play (see studio_mini_page) ── */

@keyframes pl-studio-anim-fade {
  from { opacity: 0; }
  to { opacity: 1; }
}

@keyframes pl-studio-anim-rise {
  from { opacity: 0; transform: translateY(18px); }
  to { opacity: 1; transform: translateY(0); }
}

@keyframes pl-studio-anim-scale {
  from { opacity: 0; transform: scale(0.94); }
  to { opacity: 1; transform: scale(1); }
}

.pl-studio-sandbox.pl-studio-entrance-play[data-pl-studio-entrance="fade"] {
  animation: pl-studio-anim-fade var(--pl-studio-anim-ms, 320ms) ease-out;
}

.pl-studio-sandbox.pl-studio-entrance-play[data-pl-studio-entrance="rise"] {
  animation: pl-studio-anim-rise var(--pl-studio-anim-ms, 320ms) ease-out;
}

.pl-studio-sandbox.pl-studio-entrance-play[data-pl-studio-entrance="scale"] {
  animation: pl-studio-anim-scale var(--pl-studio-anim-ms, 320ms) ease-out;
}

/* ── Hover behaviors: sandbox CTA + Buttons panel specimen row ─────────── */

@keyframes pl-studio-anim-pulse {
  0%, 100% { transform: scale(1); }
  50% { transform: scale(1.045); }
}

[data-pl-studio-hover="lift"] .pl-studio-btn {
  transition: transform var(--pl-studio-anim-ms, 320ms) ease, box-shadow var(--pl-studio-anim-ms, 320ms) ease;
}

[data-pl-studio-hover="lift"] .pl-studio-btn:hover {
  transform: translateY(-2px);
}

[data-pl-studio-hover="sheen"] .pl-studio-btn {
  position: relative;
  overflow: hidden;
}

[data-pl-studio-hover="sheen"] .pl-studio-btn::after {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(115deg, transparent 35%, rgba(255, 255, 255, 0.4) 50%, transparent 65%);
  transform: translateX(-120%);
  transition: transform var(--pl-studio-anim-ms, 320ms) ease;
  pointer-events: none;
}

[data-pl-studio-hover="sheen"] .pl-studio-btn:hover::after {
  transform: translateX(120%);
}

[data-pl-studio-hover="pulse"] .pl-studio-btn:hover {
  animation: pl-studio-anim-pulse var(--pl-studio-anim-ms, 320ms) ease-in-out infinite;
}

/* ── Try-on actions + live caption ────────────────────────────────────── */

.pl-studio-actions {
  display: flex;
  /* justify-content:flex-end is the original v5 declaration; v2 never
     redeclares justify-content, so it survives the merge alongside v2's
     flex-direction/align-items/gap additions (confirmed: no other rule
     in the file touches .pl-studio-actions). */
  justify-content: flex-end;
  flex-direction: column;
  align-items: center;
  gap: 6px;
}

.pl-studio-live-caption {
  margin: 0;
  font-size: 11px;
  color: var(--pl-muted);
  text-align: center;
}

/* ── Try-on floating bar ──────────────────────────────────────────────── */

.pl-tryon-bar {
  position: fixed;
  left: 50%;
  bottom: 20px;
  transform: translateX(-50%);
  /* DEVIATION: source value was z-index:60 (the tour-overlay band). The
     try-on bar is the contract's own worked example of a "floating bar"
     (band 40) — corrected here so a tour tooltip can still outrank it.
     Flagged in report. */
  z-index: 40;
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 10px 16px;
  border-radius: 999px;
  background: var(--pl-glass-bg);
  backdrop-filter: blur(16px) saturate(1.3);
  -webkit-backdrop-filter: blur(16px) saturate(1.3);
  border: 1px solid var(--pl-glass-border);
  box-shadow: var(--pl-shadow-float, var(--pl-glass-shadow));
}

.pl-tryon-bar[hidden] {
  display: none !important;
}

@supports not ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
  .pl-tryon-bar {
    background: var(--pl-panel-2);
  }
}

.pl-tryon-msg {
  font-size: 12px;
  font-weight: 700;
  color: var(--pl-text);
  padding-right: 2px;
}

/* ══════════════════════════════════════════════════════════════════════
   BASE — Peek pop-outs (full-size single-setting previews)
   ══════════════════════════════════════════════════════════════════════ */

.pl-peek-overlay {
  position: fixed;
  inset: 0;
  /* DEVIATION: source values were pl-peek-overlay z:90 / .pl-peek
     inheriting its stacking context (no explicit z). The contract names
     "peeks" explicitly under its Modal rule → modal-backdrop 79 / modal
     80, not the toast band. Corrected to 79/80 below (see .pl-peek).
     Flagged in report — also note .pl-save-overlay/.pl-save-gate
     currently use 80/90 in main.css, same mismatch, NOT fixed here
     (save-gate is out of this scope's ownership). */
  z-index: 79;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 24px;
  background: var(--pl-modal-backdrop);
}

.pl-peek-overlay[hidden] {
  display: none !important;
}

.pl-peek {
  position: relative;
  z-index: 80;
  width: min(768px, 92vw);
  max-width: 92vw;
  max-height: min(88vh, 860px);
  display: flex;
  flex-direction: column;
  gap: 12px;
  padding: 18px;
  border-radius: 18px;
  overflow: auto;
  background: var(--pl-glass-bg);
  backdrop-filter: blur(16px) saturate(1.3);
  -webkit-backdrop-filter: blur(16px) saturate(1.3);
  border: 1px solid var(--pl-glass-border);
  box-shadow: var(--pl-modal-shadow, var(--pl-glass-shadow));
  animation: pl-peek-in 180ms ease-out;
}

.pl-peek[hidden] {
  display: none !important;
}

@supports not ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
  .pl-peek {
    background: var(--pl-panel-2);
  }
}

@keyframes pl-peek-in {
  from {
    opacity: 0;
    transform: translateY(10px) scale(0.98);
  }
  to {
    opacity: 1;
    transform: none;
  }
}

.pl-peek-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
}

.pl-peek-btn {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  min-width: 34px;
  min-height: 44px;
  padding: 5px 12px;
  border-radius: 999px;
  border: 1px solid var(--pl-border);
  background: var(--pl-panel-2);
  color: var(--pl-muted);
  font-size: 12px;
  font-weight: 600;
  white-space: nowrap;
  cursor: pointer;
  transition: border-color 150ms, color 150ms;
}

.pl-peek-btn:hover {
  border-color: var(--pl-studio-primary, var(--pl-blue));
  color: var(--pl-text);
}

.pl-peek-btn:focus-visible {
  outline: 2px solid var(--pl-sky);
  outline-offset: 2px;
}

.pl-peek-btn-eye {
  font-size: 14px;
  line-height: 1;
}

.pl-peek-top {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
}

.pl-peek-title {
  margin: 0;
  font-size: 13px;
  font-weight: 700;
  color: var(--pl-text);
}

.pl-peek-close {
  flex: 0 0 auto;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 44px;
  min-height: 44px;
  border-radius: 50%;
  border: 1px solid var(--pl-border);
  background: var(--pl-panel-2);
  color: var(--pl-muted);
  font-size: 14px;
  line-height: 1;
  cursor: pointer;
  transition: border-color 150ms, color 150ms;
}

.pl-peek-close:hover {
  border-color: var(--pl-studio-primary, var(--pl-blue));
  color: var(--pl-text);
}

.pl-peek-close:focus-visible {
  outline: 2px solid var(--pl-sky);
  outline-offset: 2px;
}

.pl-peek-chips {
  display: flex;
  gap: 6px;
  flex-wrap: wrap;
}

.pl-peek-chip {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 4px 10px;
  border-radius: 999px;
  border: 1px solid var(--pl-border);
  background: var(--pl-panel-2);
  color: var(--pl-text);
  font-size: 11px;
  font-weight: 600;
}

.pl-peek-chip-dot {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  border: 1px solid var(--pl-border);
  /* background comes inline from the picked hex (user-picked dynamic value) */
}

.pl-peek-stage {
  width: min(720px, 100%);
  margin: 0 auto;
}

.pl-peek-stage .pl-studio-sandbox {
  width: 100%;
}

/* ══════════════════════════════════════════════════════════════════════
   NAR — max-width: 640px (phone)
   ══════════════════════════════════════════════════════════════════════ */

@media (max-width: 640px) {
  .pl-peek-overlay {
    padding: 12px;
  }

  .pl-peek {
    padding: 14px;
  }
}

/* ══════════════════════════════════════════════════════════════════════
   MID — max-width: 980px (stack boundary)
   ══════════════════════════════════════════════════════════════════════ */

@media (max-width: 980px) {
  /* Rails stack to a single column; center loses its sticky offset.
     See the DEVIATION note on .pl-studio-stage above for why this
     boundary sits at 980 instead of the source's 899.98/700px values. */
  .pl-studio-stage {
    grid-template-columns: 1fr;
    grid-template-areas:
      "center"
      "rail-l"
      "rail-r";
  }

  .pl-studio-center {
    position: static;
  }

  .pl-studio-device {
    width: min(460px, 100%);
  }
}

/* ══════════════════════════════════════════════════════════════════════
   WIDE — min-width: 1180px (rails)
   ══════════════════════════════════════════════════════════════════════ */

@media (min-width: 1180px) {
  .pl-studio-stage {
    grid-template-columns: minmax(240px, 300px) minmax(420px, 1fr) minmax(240px, 300px);
    grid-template-areas: "rail-l center rail-r";
  }

  .pl-studio-center {
    position: sticky;
    top: 16px;
  }

  .pl-studio-device {
    width: min(520px, 100%);
  }

  /* Featured first card spans two grid columns. Source threshold was
     min-width:900px; bucketed to WIDE (see report) since auto-fill at
     minmax(300px,1fr) rarely produces 2 live columns before ~900-1000px
     anyway, so this only visibly changes anything in the narrow
     981-1179px sliver where the grid used to feature the card and no
     longer will. */
  .pl-gallery-grid > li:first-child > .pl-gallery-card {
    grid-column: span 2;
  }

  .pl-gallery-grid > li:first-child .pl-gallery-thumb {
    height: 210px;
    aspect-ratio: auto;
  }
}

/* ══════════════════════════════════════════════════════════════════════
   Reduced motion — consolidated (studio v5 + studio v2 + peek + gallery)
   ══════════════════════════════════════════════════════════════════════ */

@media (prefers-reduced-motion: reduce) {
  .pl-gallery-card,
  .pl-gallery-card:hover,
  .pl-gallery-thumb,
  .pl-gallery-card:hover .pl-gallery-thumb {
    transition: none;
    transform: none;
  }

  .pl-gallery-thumb *,
  .pl-nudge {
    animation: none !important;
  }

  .pl-studio-scheme-chip,
  .pl-studio-style-chip,
  .pl-studio-pairing-card,
  .pl-studio-toggle,
  .pl-studio-toggle::after,
  .pl-studio-btn,
  .pl-studio-sb-tile,
  .pl-studio-sb-hero,
  .pl-studio-sandbox,
  .pl-studio-sandbox.pl-studio-entrance-play,
  .pl-studio-btn::after {
    animation: none !important;
    transition: none !important;
  }

  [data-pl-studio-hover="lift"] .pl-studio-btn:hover {
    transform: none;
  }

  [data-pl-studio-hover="pulse"] .pl-studio-btn:hover {
    animation: none !important;
  }

  .pl-peek,
  .pl-peek-btn,
  .pl-peek-close {
    animation: none;
    transition: none;
  }
}

/* ═══════════════════════════════════════════════════════════════════════
   D3pth Planner — consolidated chrome & overlays
   Scope: tokens/themes, topbar, tour, wizard, save gate, resume banner,
   shared chips/buttons. Cascade-winner refactor of the following main.css
   marker blocks (see agent report for the full accounting):
     "The Nicer Theme" tokens · Root layout · Topbar controls · Theme
     toggle · Glass surfaces · Panel and buttons · Segments and labels ·
     Tour · Form controls (scoped to planner) · Make button · Save
     overlay/gate/actions · Build-your-own wizard · Responsive topbar v9 ·
     Save gate open animation + resume banner · Tour overlay fixes ·
     fix-theme.css (planner-token portion) · plus the topbar/save-gate/tab
     fixes embedded in "review fixes v5.2 (orchestrator)".
   This is a refactor, not a redesign: every winning computed style is
   preserved. The two intentional exceptions are (a) z-index values
   collapsed onto the project's z-scale bands, and (b) viewport
   breakpoints collapsed onto the project's NAR/MID/WIDE contract — both
   changes are called out inline and in the report, nothing else moved.
   ═══════════════════════════════════════════════════════════════════════ */

/* ── Tokens: LIGHT is default, declared on .pl-app ──────────────────────── */

.pl-app {
  /* Ground + surfaces */
  --pl-ground: linear-gradient(180deg, #f8fafc 0%, #eef4fb 50%, #dbeafe 100%);
  --pl-panel-1: #ffffff;
  --pl-panel-2: #f8fafc;
  --pl-border: #e2e8f0;
  --pl-track: #e2e8f0;
  --pl-block: #eef2f7;

  /* --pl-panel: alias — main.css and studio-v2.css both reference
     var(--pl-panel), which the original token block never defined. Alias
     to --pl-panel-1 so it resolves correctly in both themes (dark
     re-declares --pl-panel-1 below; the alias picks it up at use time).
     Cascade winner merged in from fix-theme.css. */
  --pl-panel: var(--pl-panel-1);

  /* Text */
  --pl-text: #0f172a;
  --pl-muted: #475569;
  --pl-faint: #64748b;

  /* Accents */
  --pl-blue: #2563eb;
  --pl-sky: #0ea5e9;
  --pl-green: #10b981;
  --pl-navy: #0b1f3a;
  --pl-amber: #d97706;
  --pl-red: #dc2626;
  --pl-violet: var(--pl-sky);

  /* Chip tint formula: bg = X at bg-mix% over transparent, border = X at border-mix% */
  --pl-chip-bg-mix: 10%;
  --pl-chip-border-mix: 40%;

  /* Elevation (reuses marketing shadow language) */
  --pl-shadow-card: 0 1px 2px rgba(15, 23, 42, 0.05),
    0 4px 10px -3px rgba(15, 23, 42, 0.09), 0 12px 28px -10px rgba(15, 23, 42, 0.07);
  --pl-shadow-float: 0 2px 6px -1px rgba(15, 23, 42, 0.08),
    0 14px 32px -10px rgba(15, 23, 42, 0.14),
    0 0 28px -6px color-mix(in srgb, var(--pl-blue) 24%, transparent);

  /* Glass surfaces (panel, tour tip, save gate, nudge) */
  --pl-glass-bg: rgba(255, 255, 255, 0.65);
  --pl-glass-border: rgba(255, 255, 255, 0.5);
  --pl-glass-shadow: 0 12px 32px -8px rgba(15, 23, 42, 0.18),
    0 2px 8px rgba(15, 23, 42, 0.08);
  --pl-modal-shadow: 0 20px 60px -12px rgba(15, 23, 42, 0.35),
    0 4px 16px rgba(15, 23, 42, 0.12);
  --pl-modal-backdrop: rgba(15, 23, 42, 0.4);

  /* Button anatomy (same brand gradient both themes — the "signature") */
  --pl-btn-primary-grad: linear-gradient(135deg, #2563eb, #0ea5e9);
  --pl-btn-green-grad: linear-gradient(135deg, #059669, #10b981);
  --pl-btn-shadow: 0 1px 2px rgba(15, 23, 42, 0.2), 0 4px 14px -4px rgba(37, 99, 235, 0.5);
  --pl-btn-shadow-hover: 0 2px 4px rgba(15, 23, 42, 0.22),
    0 8px 22px -4px rgba(37, 99, 235, 0.6);
  --pl-btn-green-shadow: 0 1px 2px rgba(15, 23, 42, 0.2),
    0 4px 14px -4px rgba(16, 185, 129, 0.5);
  --pl-btn-green-shadow-hover: 0 2px 4px rgba(15, 23, 42, 0.22),
    0 8px 22px -4px rgba(16, 185, 129, 0.6);
  --pl-sheen: linear-gradient(120deg, transparent, rgba(255, 255, 255, 0.55), transparent);

  display: flex;
  flex-direction: column;
  height: 100vh;
  background: var(--pl-ground);
  color: var(--pl-text);
  font-family: var(--font-sans);
  overflow: hidden;
}

/* ── Tokens: DARK — re-declares every custom property above ────────────── */

.pl-app[data-pl-theme="dark"] {
  --pl-ground: linear-gradient(160deg, #060f1e 0%, #0b1f3a 100%);
  --pl-panel-1: #0d2445;
  --pl-panel-2: #123256;
  --pl-border: #1e3a5f;
  --pl-track: #24466e;
  --pl-block: #16304f;

  --pl-text: #e6eef9;
  --pl-muted: #93a9c6;
  --pl-faint: #6b83a3;

  --pl-blue: #3b82f6;
  --pl-sky: #0ea5e9;
  --pl-green: #10b981;
  --pl-navy: #0b1f3a;
  --pl-amber: #f59e0b;
  --pl-red: #ef4444;
  --pl-violet: var(--pl-sky);

  --pl-chip-bg-mix: 12%;
  --pl-chip-border-mix: 100%;

  --pl-shadow-card: 0 1px 2px rgba(0, 0, 0, 0.3), 0 4px 10px -3px rgba(0, 0, 0, 0.35),
    0 12px 28px -10px rgba(0, 0, 0, 0.3);
  --pl-shadow-float: 0 2px 6px -1px rgba(0, 0, 0, 0.35), 0 14px 32px -10px rgba(0, 0, 0, 0.5),
    0 0 28px -6px color-mix(in srgb, var(--pl-sky) 30%, transparent);

  --pl-glass-bg: rgba(13, 36, 69, 0.62);
  --pl-glass-border: rgba(255, 255, 255, 0.08);
  --pl-glass-shadow: 0 12px 32px rgba(0, 0, 0, 0.5), 0 2px 8px rgba(0, 0, 0, 0.3);
  --pl-modal-shadow: 0 20px 48px rgba(0, 0, 0, 0.6);
  --pl-modal-backdrop: rgba(3, 9, 20, 0.82);

  --pl-btn-shadow: 0 1px 2px rgba(0, 0, 0, 0.3), 0 4px 14px -4px rgba(59, 130, 246, 0.5);
  --pl-btn-shadow-hover: 0 2px 4px rgba(0, 0, 0, 0.35), 0 8px 22px -4px rgba(59, 130, 246, 0.6);
  --pl-btn-green-shadow: 0 1px 2px rgba(0, 0, 0, 0.3), 0 4px 14px -4px rgba(16, 185, 129, 0.5);
  --pl-btn-green-shadow-hover: 0 2px 4px rgba(0, 0, 0, 0.35),
    0 8px 22px -4px rgba(16, 185, 129, 0.6);
  --pl-sheen: linear-gradient(120deg, transparent, rgba(255, 255, 255, 0.25), transparent);

  /* Cascade winner merged in from fix-theme.css: native UI (scrollbars,
     form controls, popups) matches the dark theme. */
  color-scheme: dark;
}

/* ── Root layout (planner shell) ─────────────────────────────────────────── */

.pl-topbar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 12px 16px;
  background: var(--pl-panel-1);
  border-bottom: 1px solid var(--pl-border);
  min-height: 56px;
  flex-shrink: 0;
  transition: background-color 200ms, border-color 200ms;
  /* Responsive wrap behavior in the MID/NAR media sections below. */
  flex-wrap: wrap;
  row-gap: 10px;
}

.pl-work {
  display: flex;
  flex: 1;
  overflow: hidden;
}

.pl-view[hidden] {
  display: none !important;
}

.pl-view {
  display: flex;
  flex: 1;
  overflow: auto;
  gap: 16px;
  padding: 16px;
}

/* ── Shared glass surfaces ────────────────────────────────────────────────
   Cross-owner selector list: .pl-panel (style_studio.rs) and .pl-nudge
   (gallery.rs) are NOT this agent's scope and are listed here only
   because they share this rule with .pl-tour-tip / .pl-save-gate, which
   ARE in scope. Preserved as one compound selector rather than split, so
   the rule stays byte-identical to what those other owners' sheets also
   need. Do not delete .pl-panel/.pl-nudge from here without checking with
   the owning agents. */

.pl-panel,
.pl-tour-tip,
.pl-save-gate,
.pl-nudge {
  background: var(--pl-glass-bg);
  backdrop-filter: blur(14px) saturate(1.3);
  -webkit-backdrop-filter: blur(14px) saturate(1.3);
  border: 1px solid var(--pl-glass-border);
  box-shadow: var(--pl-glass-shadow);
}

@supports not ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
  .pl-panel,
  .pl-tour-tip,
  .pl-save-gate,
  .pl-nudge {
    background: var(--pl-panel-2);
  }
}

/* ── Shared buttons ───────────────────────────────────────────────────────
   .pl-btn / .pl-btn-green / .pl-btn-sm / .pl-ghost — used across wizard,
   tour, gallery, detail view, resume banner, save gate and map view.
   Anatomy: gradient fill, layered glow shadow, skewed sheen sweep on
   hover (::after), lift on hover, compress on press. */

.pl-btn {
  position: relative;
  overflow: hidden;
  min-height: 44px;
  padding: 8px 16px;
  background: var(--pl-btn-primary-grad);
  color: #ffffff;
  border: none;
  border-radius: 10px;
  font-size: 13px;
  font-weight: 600;
  cursor: pointer;
  box-shadow: var(--pl-btn-shadow);
  transition: transform 150ms ease, box-shadow 150ms ease;
  font-family: var(--font-sans);
}

.pl-btn::after {
  content: "";
  position: absolute;
  top: 0;
  left: -150%;
  width: 60%;
  height: 100%;
  background: var(--pl-sheen);
  transform: skewX(-20deg);
  transition: left 600ms ease;
  pointer-events: none;
}

.pl-btn:hover {
  transform: translateY(-1px);
  box-shadow: var(--pl-btn-shadow-hover);
}

.pl-btn:hover::after {
  left: 150%;
}

.pl-btn:active {
  transform: translateY(0);
  box-shadow: var(--pl-btn-shadow);
}

.pl-btn:focus-visible {
  outline: 2px solid var(--pl-sky);
  outline-offset: 2px;
}

/* Same anatomy, emerald gradient */
.pl-btn-green {
  position: relative;
  overflow: hidden;
  min-height: 44px;
  padding: 8px 16px;
  background: var(--pl-btn-green-grad);
  color: #ffffff;
  border: none;
  border-radius: 10px;
  font-size: 13px;
  font-weight: 600;
  cursor: pointer;
  box-shadow: var(--pl-btn-green-shadow);
  transition: transform 150ms ease, box-shadow 150ms ease;
  font-family: var(--font-sans);
}

.pl-btn-green::after {
  content: "";
  position: absolute;
  top: 0;
  left: -150%;
  width: 60%;
  height: 100%;
  background: var(--pl-sheen);
  transform: skewX(-20deg);
  transition: left 600ms ease;
  pointer-events: none;
}

.pl-btn-green:hover {
  transform: translateY(-1px);
  box-shadow: var(--pl-btn-green-shadow-hover);
}

.pl-btn-green:hover::after {
  left: 150%;
}

.pl-btn-green:active {
  transform: translateY(0);
  box-shadow: var(--pl-btn-green-shadow);
}

.pl-btn-green:focus-visible {
  outline: 2px solid var(--pl-sky);
  outline-offset: 2px;
}

.pl-btn-sm {
  min-height: 34px;
  padding: 4px 12px;
  font-size: 12px;
  background: var(--pl-glass-bg);
  backdrop-filter: blur(10px) saturate(1.2);
  -webkit-backdrop-filter: blur(10px) saturate(1.2);
  color: var(--pl-muted);
  border: 1px solid var(--pl-glass-border);
  border-radius: 6px;
  cursor: pointer;
  transition: all 150ms;
}

@supports not ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
  .pl-btn-sm {
    background: var(--pl-panel-2);
  }
}

.pl-btn-sm:hover {
  border-color: var(--pl-blue);
  color: var(--pl-text);
  background: color-mix(in srgb, var(--pl-blue) 10%, var(--pl-glass-bg));
}

.pl-btn-sm:focus-visible {
  outline: 2px solid var(--pl-sky);
  outline-offset: 2px;
}

/* Ghost — glass chip, fills toward accent tint on hover */
.pl-ghost {
  min-height: 44px;
  padding: 6px 12px;
  background: var(--pl-glass-bg);
  backdrop-filter: blur(10px) saturate(1.2);
  -webkit-backdrop-filter: blur(10px) saturate(1.2);
  border: 1px solid var(--pl-glass-border);
  color: var(--pl-text);
  border-radius: 6px;
  font-size: 13px;
  cursor: pointer;
  transition: all 150ms;
}

@supports not ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
  .pl-ghost {
    background: var(--pl-panel-2);
  }
}

.pl-ghost:hover {
  border-color: var(--pl-blue);
  background: color-mix(in srgb, var(--pl-blue) 10%, var(--pl-glass-bg));
}

.pl-ghost:focus-visible {
  outline: 2px solid var(--pl-sky);
  outline-offset: 2px;
}

@media (prefers-reduced-motion: reduce) {
  .pl-btn,
  .pl-btn::after,
  .pl-btn-green,
  .pl-btn-green::after,
  .pl-btn-sm,
  .pl-ghost {
    transition: none;
  }
}

/* ── Shared segments & labels (tour + save gate) ─────────────────────────── */

.pl-seg {
  display: flex;
  gap: 8px;
  margin-bottom: 12px;
}

.pl-lbl {
  display: block;
  font-size: 12px;
  font-weight: 500;
  color: var(--pl-text);
  margin-bottom: 6px;
}

/* ── Topbar controls ────────────────────────────────────────────────────── */

.pl-demo-pill {
  display: inline-flex;
  align-items: center;
  padding: 6px 12px;
  background: var(--pl-panel-2);
  border: 1px solid var(--pl-border);
  border-radius: 12px;
  font-size: 12px;
  font-weight: 500;
  color: var(--pl-muted);
  cursor: default;
}

.pl-tabs {
  display: flex;
  gap: 8px;
  background: transparent;
  /* Responsive wrap/scroll behavior in the MID/NAR media sections below. */
  min-width: 0;
}

/* .pl-tab is shared: topbar view-switcher (mod.rs) and detail-view page
   nav (detail_view.rs) both use it. Markup emits aria-pressed, never
   aria-selected — the old base rule's `.pl-tab[aria-selected="true"]`
   variant never matches anything live; dropped as dead, replaced by the
   aria-pressed variant that actually wins in the running app. */
.pl-tab {
  position: relative; /* winner: 44px-hit-area batch (v5.2) */
  min-height: 40px; /* winner: v5.2's 40px beats the base rule's 30px */
  padding: 6px 12px;
  background: transparent;
  border: 1px solid transparent;
  border-radius: 6px;
  color: var(--pl-muted);
  cursor: pointer;
  font-size: 13px;
  font-weight: 500;
  transition: color 150ms, border-color 150ms, background-color 150ms;
}

.pl-tab:hover {
  color: var(--pl-text);
  border-color: var(--pl-border);
}

.pl-tab[aria-pressed="true"] {
  background: var(--pl-panel-2);
  color: var(--pl-text);
}

.pl-top-right {
  display: flex;
  align-items: center;
  gap: 12px;
  /* Responsive wrap behavior in the MID/NAR media sections below. */
  flex-wrap: wrap;
  row-gap: 8px;
}

.pl-credit-chip {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  padding: 6px 10px;
  background: var(--pl-panel-2);
  border: 1px solid var(--pl-border);
  border-radius: 6px;
  font-family: var(--font-mono);
  font-size: 11px;
  color: var(--pl-muted);
  font-weight: 500;
}

.pl-note-chip {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  padding: 6px 10px;
  background: var(--pl-panel-2);
  border: 1px solid var(--pl-border);
  border-radius: 6px;
  font-family: var(--font-mono);
  font-size: 11px;
  color: var(--pl-muted);
  font-weight: 500;
}

/* ── Theme toggle (topbar) ──────────────────────────────────────────────── */

.pl-theme-toggle {
  position: relative; /* winner: 44px-hit-area batch (v5.2) */
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 34px;
  min-height: 40px; /* winner: v5.2's 40px beats the base rule's 34px */
  padding: 6px;
  background: var(--pl-panel-2);
  border: 1px solid var(--pl-border);
  border-radius: 8px;
  color: var(--pl-muted);
  cursor: pointer;
  transition: all 150ms;
}

.pl-theme-toggle:hover {
  border-color: var(--pl-blue);
  color: var(--pl-text);
}

.pl-theme-toggle:focus-visible {
  outline: 2px solid var(--pl-sky);
  outline-offset: 2px;
}

/* ── Make button — topbar CTA, primary anatomy + size bump + glow pulse ── */

.pl-make-btn {
  position: relative;
  overflow: hidden;
  min-height: 48px;
  padding: 10px 22px;
  background: var(--pl-btn-primary-grad);
  color: #ffffff;
  font-weight: 600;
  border: none;
  border-radius: 10px;
  font-size: 14px;
  cursor: pointer;
  font-family: var(--font-sans);
  box-shadow: var(--pl-btn-shadow);
  transition: transform 150ms ease, box-shadow 150ms ease;
  animation: pl-make-glow 2.4s ease-in-out infinite;
}

.pl-make-btn::after {
  content: "";
  position: absolute;
  top: 0;
  left: -150%;
  width: 60%;
  height: 100%;
  background: var(--pl-sheen);
  transform: skewX(-20deg);
  transition: left 600ms ease;
  pointer-events: none;
}

@keyframes pl-make-glow {
  0%,
  100% {
    box-shadow: var(--pl-btn-shadow);
  }
  50% {
    box-shadow: var(--pl-btn-shadow-hover);
  }
}

.pl-make-btn:hover {
  transform: translateY(-1px);
  box-shadow: var(--pl-btn-shadow-hover);
}

.pl-make-btn:hover::after {
  left: 150%;
}

.pl-make-btn:active {
  transform: translateY(0);
  box-shadow: var(--pl-btn-shadow);
}

.pl-make-btn:focus-visible {
  outline: 2px solid var(--pl-sky);
  outline-offset: 2px;
}

@media (prefers-reduced-motion: reduce) {
  .pl-make-btn {
    animation: none;
    transition: none;
  }
  .pl-make-btn::after {
    transition: none;
  }
}

/* ── Tour ──────────────────────────────────────────────────────────────── */

.pl-tour-ring[hidden],
.pl-tour-tip[hidden] {
  display: none !important;
}

.pl-tour-ring {
  position: fixed;
  border: 2px solid var(--pl-sky);
  border-radius: 12px;
  box-shadow: 0 0 0 6000px var(--pl-modal-backdrop), 0 0 12px rgba(14, 165, 233, 0.4);
  pointer-events: none;
  /* z-scale: tour overlay band (was 999, off-scale). */
  z-index: 60;
  transition: all 300ms;
}

.pl-tour-tip {
  position: fixed;
  max-width: 320px;
  border-radius: 12px;
  padding: 16px;
  color: var(--pl-text);
  font-size: 13px;
  line-height: 1.5;
  /* z-scale: tour overlay band (was 1000, off-scale). */
  z-index: 60;
}

.pl-tour-step {
  font-size: 11px;
  font-family: var(--font-mono);
  color: var(--pl-faint);
  margin-bottom: 4px;
}

.pl-tour-say {
  font-size: 13px;
  color: var(--pl-text);
  margin-bottom: 12px;
  line-height: 1.5;
}

.pl-tour-row {
  display: flex;
  gap: 8px;
  margin-top: 8px;
}

.pl-tour-skip {
  flex: 1;
  min-height: 44px; /* winner: fix-tour.css's 44px beats the base rule's 34px */
  padding: 10px 16px; /* winner: fix-tour.css's 10px/16px beats the base rule's 4px/12px */
  background: transparent;
  border: 1px solid var(--pl-border);
  color: var(--pl-muted);
  border-radius: 6px;
  font-size: 12px;
  cursor: pointer;
  transition: all 150ms;
}

.pl-tour-skip:hover {
  border-color: var(--pl-blue);
  color: var(--pl-text);
}

/* Comfortable interactive targets: Back / Next / Skip all reach 44px.
   .pl-tour-row .pl-btn needs its own min-height bump (the shared .pl-btn
   rule above is already >=44px, so this is a no-op for .pl-btn today, but
   it's the winning declared rule and kept for parity with .pl-tour-skip). */
.pl-tour-row .pl-btn,
.pl-tour-row .pl-tour-skip {
  min-height: 44px;
  min-width: 44px;
  padding: 10px 16px;
}

/* Visible keyboard focus on every tour control — wins over the plain
   .pl-tour-skip:focus-visible rule below via a later, denser selector;
   .pl-btn:focus-visible already matches, this just adds the radius. */
.pl-tour-row .pl-btn:focus-visible,
.pl-tour-row .pl-tour-skip:focus-visible {
  outline: 2px solid var(--pl-blue);
  outline-offset: 2px;
  border-radius: 8px;
}

.pl-tour-skip:focus-visible {
  outline: 2px solid var(--pl-sky);
  outline-offset: 2px;
}

@media (prefers-reduced-motion: reduce) {
  .pl-tour-ring,
  .pl-tour-tip {
    transition: none !important;
    animation: none !important;
  }
}

/* ── Form controls (scoped to planner) ──────────────────────────────────── */

.pl-app button {
  font-family: var(--font-sans);
}

.pl-app input,
.pl-app textarea,
.pl-app select {
  font-family: var(--font-sans);
  color: var(--pl-text);
  background: var(--pl-panel-1);
  border: 1px solid var(--pl-border);
  border-radius: 6px;
  padding: 8px 12px;
  font-size: 13px;
}

.pl-app input:focus,
.pl-app textarea:focus,
.pl-app select:focus {
  outline: none;
  border-color: var(--pl-blue);
  box-shadow: 0 0 0 2px color-mix(in srgb, var(--pl-blue) 20%, transparent);
}

.pl-app input[type="radio"],
.pl-app input[type="checkbox"] {
  cursor: pointer;
  width: 18px;
  height: 18px;
}

/* ── Save gate ─────────────────────────────────────────────────────────────
   Three source blocks merged into this one rule set: the original base
   rules, "review fixes v5.2" (fixed/centered positioning + sizing), and
   fix-savegate.css (open animation + centering fix). Where two blocks set
   the same property, the comment says which one is the computed winner. */

.pl-save-overlay {
  position: fixed;
  inset: 0;
  background: var(--pl-modal-backdrop);
  backdrop-filter: blur(4px);
  -webkit-backdrop-filter: blur(4px);
  /* z-scale: modal backdrop band (was 80, off-scale for a backdrop). */
  z-index: 79;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 16px;
}

.pl-save-overlay[hidden] {
  display: none !important;
}

.pl-save-gate {
  border-radius: 16px;
  padding: 24px;
  /* max-width: v5.2's min(560px, 92vw) beats the base rule's flat 520px. */
  max-width: min(560px, 92vw);
  width: 100%;
  /* max-height/overflow-y: v5.2 additions, no base equivalent. */
  max-height: 88vh;
  overflow-y: auto;
  box-shadow: var(--pl-modal-shadow);
  /* position/top/left/transform: v5.2 additions — fixed+centered
     regardless of DOM nesting depth. */
  position: fixed;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  /* z-scale: modal band (was 90, off-scale). */
  z-index: 80;
  /* margin/animation: fix-savegate.css winners (originally authored on
     the higher-specificity ".pl-save-overlay .pl-save-gate" descendant
     selector so they'd beat this rule regardless of source order; written
     directly here since this file has no earlier competing declaration
     for these two properties). Replaces the old `animation: fadeInScale`
     (transform-based) which fix-savegate.css's own comment explains was
     clobbering the translate(-50%,-50%) centering transform above — the
     `@keyframes fadeInScale` is dropped as dead, nothing references it
     once this wins. */
  margin: auto;
  animation: pl-save-gate-in 250ms ease-out;
}

@keyframes pl-save-gate-in {
  from {
    opacity: 0;
    scale: 0.95;
    translate: 0 8px;
  }
  to {
    opacity: 1;
    scale: 1;
    translate: 0 0;
  }
}

@media (prefers-reduced-motion: reduce) {
  .pl-save-gate {
    animation: none;
  }
}

.pl-save-gate h2,
.pl-save-gate h3 {
  margin: 0 0 12px;
  color: var(--pl-text);
  font-size: 16px;
  font-weight: 600;
}

.pl-save-gate-body {
  display: grid;
  gap: 12px;
}

/* Save email input — full-width field */
.pl-save-email {
  width: 100%;
  padding: 12px;
  background: var(--pl-panel-1);
  border: 1px solid var(--pl-border);
  border-radius: 8px;
  color: var(--pl-text);
  font-family: var(--font-sans);
  font-size: 13px;
  box-sizing: border-box;
  transition: all 150ms;
}

.pl-save-email:focus {
  outline: none;
  border-color: var(--pl-blue);
  box-shadow: 0 0 0 2px color-mix(in srgb, var(--pl-blue) 20%, transparent);
}

.pl-save-email::placeholder {
  color: var(--pl-muted);
}

/* Save demo link — monospace, sky color, break long text */
.pl-save-demo-link {
  font-family: var(--font-mono);
  font-size: 12px;
  color: var(--pl-sky);
  word-break: break-all;
  white-space: pre-wrap;
  line-height: 1.4;
  padding: 12px;
  background: var(--pl-panel-1);
  border-radius: 6px;
  border: 1px solid color-mix(in srgb, var(--pl-sky) 20%, var(--pl-border));
  user-select: all;
}

/* Close ✕ — added by "review fixes v5.2"; save_gate.rs no longer renders
   a .pl-save-actions row (see report: that whole block is dead). */
.pl-save-close {
  position: absolute;
  top: 10px;
  right: 10px;
  width: 36px;
  height: 36px;
  display: grid;
  place-items: center;
  border-radius: 8px;
  color: var(--pl-muted);
  background: transparent;
  border: none;
  cursor: pointer;
}

.pl-save-close::after {
  content: "";
  position: absolute;
  inset: -8px;
}

.pl-save-close:hover {
  color: var(--pl-text);
  background: var(--pl-panel-2);
}

.pl-save-close:focus-visible {
  outline: 2px solid var(--pl-sky);
  outline-offset: 2px;
}

/* ── Resume banner (planner/resume.rs) ──────────────────────────────────── */

.pl-resume {
  position: fixed;
  top: 72px;
  left: 50%;
  translate: -50% 0;
  /* z-scale: floating bars band (was 70, off-scale). Still paints under
     the save-gate modal (79/80) and tour overlay (60 while ring/tip are
     visible together this rarely overlaps, but the band ordering keeps
     the save-gate winning if it ever does). */
  z-index: 40;
  width: min(560px, calc(100vw - 32px));
  pointer-events: none; /* wrapper only; banners re-enable */
}

.pl-resume[hidden] {
  display: none !important;
}

.pl-resume-banner {
  pointer-events: auto;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 12px 12px 12px 16px;
  border-radius: 12px;
  background: var(--pl-panel-2);
  border: 1px solid var(--pl-border);
  box-shadow: var(--pl-modal-shadow);
  animation: pl-resume-in 250ms ease-out;
}

.pl-resume-banner[hidden] {
  display: none !important;
}

@keyframes pl-resume-in {
  from {
    opacity: 0;
    translate: 0 -8px;
  }
  to {
    opacity: 1;
    translate: 0 0;
  }
}

@media (prefers-reduced-motion: reduce) {
  .pl-resume-banner {
    animation: none;
  }
}

.pl-resume-msg {
  margin: 0;
  color: var(--pl-text);
  font-size: 14px;
  line-height: 1.5;
}

/* Dismiss ✕ — 44px minimum target */
.pl-resume-dismiss {
  flex: 0 0 auto;
  min-width: 44px;
  min-height: 44px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border: none;
  border-radius: 10px;
  background: transparent;
  color: var(--pl-text);
  font-size: 16px;
  line-height: 1;
  cursor: pointer;
}

.pl-resume-dismiss:hover {
  background: var(--pl-panel-1);
}

/* Start-fresh button — inherits .pl-btn look; enforce target size here */
.pl-resume-fresh {
  flex: 0 0 auto;
  min-height: 44px;
  min-width: 44px;
}

.pl-resume-dismiss:focus-visible,
.pl-resume-fresh:focus-visible {
  outline: 2px solid var(--pl-blue);
  outline-offset: 2px;
}

/* ── Build-your-own wizard (pl-wiz-*) ─────────────────────────────────────
   Full-screen takeover. Tokens only (--pl-*); the stage additionally reads
   --pl-wiz-accent/-2/-3, set inline per-render from the current palette by
   wizard.rs. Glass surfaces mirror the save-gate/style-studio treatment. */

.pl-wizard {
  position: fixed;
  inset: 0;
  z-index: 80;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 16px;
  background: var(--pl-modal-backdrop);
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
}

.pl-wizard[hidden] {
  display: none !important;
}

.pl-wiz-shell {
  display: flex;
  flex-direction: column;
  width: min(1180px, 100%);
  height: min(880px, 100%);
  background: var(--pl-panel-1);
  border: 1px solid var(--pl-border);
  border-radius: 18px;
  box-shadow: var(--pl-modal-shadow);
  overflow: hidden;
}

/* ── Header ────────────────────────────────────────────────────────────── */

.pl-wiz-head {
  display: flex;
  align-items: baseline;
  gap: 10px;
  padding: 16px 20px 10px;
  border-bottom: 1px solid var(--pl-border);
  flex-shrink: 0;
}

.pl-wiz-step-label {
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--pl-faint);
}

.pl-wiz-title {
  flex: 1;
  margin: 0;
  font-size: 18px;
  font-weight: 700;
  color: var(--pl-text);
}

.pl-wiz-close {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 32px;
  height: 32px;
  border-radius: 8px;
  border: 1px solid var(--pl-border);
  background: var(--pl-panel-2);
  color: var(--pl-muted);
  cursor: pointer;
  font-size: 14px;
  transition: background 120ms, color 120ms;
}

.pl-wiz-close:hover {
  background: var(--pl-block);
  color: var(--pl-text);
}

.pl-wiz-close:focus-visible {
  outline: 2px solid var(--pl-blue);
  outline-offset: 2px;
}

.pl-wiz-banner {
  margin: 0;
  padding: 8px 20px;
  font-size: 12.5px;
  color: var(--pl-blue);
  background: color-mix(in srgb, var(--pl-blue) 8%, var(--pl-panel-1));
  border-bottom: 1px solid var(--pl-border);
  flex-shrink: 0;
}

/* ── Main: rail | stage ───────────────────────────────────────────────── */
/* DEAD: .pl-wiz-main (grid rail|stage wrapper) — wizard.rs now renders
   .pl-wiz-panes for this wrapper; no CSS for .pl-wiz-panes exists anywhere
   in main.css (see report — likely an unported rename, not a deliberate
   drop). Rule removed here per the dead-code instruction; flagged, not
   silently fixed. */

.pl-wiz-rail {
  overflow-y: auto;
  padding: 18px 20px 24px;
  border-right: 1px solid var(--pl-border);
}

.pl-wiz-rail-body {
  display: flex;
  flex-direction: column;
  gap: 10px;
  animation: pl-wiz-fade 150ms ease;
}

@keyframes pl-wiz-fade {
  from {
    opacity: 0;
    transform: translateY(4px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

.pl-wiz-q {
  margin: 0;
  font-size: 16px;
  font-weight: 700;
  color: var(--pl-text);
}

.pl-wiz-q-sm {
  font-size: 12.5px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--pl-muted);
  margin: 10px 0 0;
}

.pl-wiz-hint {
  margin: 0;
  font-size: 12.5px;
  line-height: 1.4;
  color: var(--pl-muted);
}

.pl-wiz-hint-notes {
  color: var(--pl-blue);
}

.pl-wiz-lbl {
  font-size: 12px;
  font-weight: 600;
  color: var(--pl-muted);
}

.pl-wiz-input {
  width: 100%;
  padding: 9px 11px;
  border-radius: 9px;
  border: 1px solid var(--pl-border);
  background: var(--pl-panel-2);
  color: var(--pl-text);
  font-size: 14px;
  min-height: 40px;
}

.pl-wiz-input:focus-visible {
  outline: 2px solid var(--pl-blue);
  outline-offset: 1px;
}

/* ── Option cards ─────────────────────────────────────────────────────── */

.pl-wiz-grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 8px;
}

.pl-wiz-opt {
  position: relative;
  display: flex;
  flex-direction: column;
  gap: 4px;
  align-items: flex-start;
  text-align: left;
  padding: 10px 12px;
  min-height: 40px;
  border-radius: 10px;
  border: 1px solid var(--pl-border);
  background: var(--pl-panel-2);
  color: var(--pl-text);
  cursor: pointer;
  transition: border-color 120ms, background 120ms, box-shadow 120ms;
}

.pl-wiz-opt:hover {
  border-color: var(--pl-blue);
}

.pl-wiz-opt:focus-visible {
  outline: 2px solid var(--pl-blue);
  outline-offset: 2px;
}

.pl-wiz-opt-rec {
  border-color: color-mix(in srgb, var(--pl-blue) 45%, var(--pl-border));
}

.pl-wiz-opt-sel {
  border-color: var(--pl-blue);
  background: color-mix(in srgb, var(--pl-blue) 8%, var(--pl-panel-2));
  box-shadow: 0 0 0 1px var(--pl-blue) inset;
}

.pl-wiz-opt-label {
  font-size: 13.5px;
  font-weight: 700;
}

.pl-wiz-opt-why {
  font-size: 11.5px;
  line-height: 1.35;
  color: var(--pl-muted);
}

.pl-wiz-badge {
  display: inline-flex;
  align-items: center;
  padding: 2px 7px;
  border-radius: 999px;
  font-size: 10px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.03em;
  color: #fff;
  background: var(--pl-btn-primary-grad, var(--pl-blue));
  align-self: flex-start;
}

.pl-wiz-badge-sm {
  font-size: 9.5px;
  padding: 2px 6px;
}

/* ── Color swatches ───────────────────────────────────────────────────── */

.pl-wiz-swatchrow {
  display: flex;
  gap: 3px;
}

.pl-wiz-swatch {
  width: 18px;
  height: 18px;
  border-radius: 5px;
  border: 1px solid var(--pl-glass-border);
  flex-shrink: 0;
}

.pl-wiz-swatch-sm {
  width: 14px;
  height: 14px;
  border-radius: 4px;
}

/* ── Fine-tune wheel ──────────────────────────────────────────────────── */

.pl-wiz-wheel-wrap {
  display: flex;
  justify-content: center;
  padding: 6px 0;
}

.pl-wiz-wheel {
  position: relative;
  width: 180px;
  height: 180px;
  border-radius: 50%;
  cursor: crosshair;
  touch-action: none;
  box-shadow: var(--pl-shadow-card);
  background:
    radial-gradient(circle, #fff 0%, rgba(255, 255, 255, 0) 62%),
    conic-gradient(from 90deg, #ff0000, #ffff00, #00ff00, #00ffff, #0000ff, #ff00ff, #ff0000);
}

.pl-wiz-wheel-thumb {
  position: absolute;
  width: 16px;
  height: 16px;
  margin-left: -8px;
  margin-top: -8px;
  border-radius: 50%;
  background: #fff;
  border: 2px solid var(--pl-text);
  box-shadow: 0 1px 4px rgba(0, 0, 0, 0.4);
  pointer-events: none;
}

/* ── Chips ────────────────────────────────────────────────────────────── */

.pl-wiz-chiprow {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
}

.pl-wiz-chip {
  position: relative;
  min-height: 40px;
  padding: 8px 14px;
  border-radius: 999px;
  border: 1px solid var(--pl-border);
  background: var(--pl-panel-2);
  color: var(--pl-text);
  font-size: 13px;
  font-weight: 600;
  cursor: pointer;
  transition: border-color 120ms, background 120ms, color 120ms;
}

.pl-wiz-chip:hover {
  border-color: var(--pl-blue);
}

.pl-wiz-chip:focus-visible {
  outline: 2px solid var(--pl-blue);
  outline-offset: 2px;
}

.pl-wiz-chip-rec::after {
  content: "";
  position: absolute;
  top: 4px;
  right: 4px;
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--pl-blue);
}

.pl-wiz-chip-sel {
  border-color: var(--pl-blue);
  background: var(--pl-blue);
  color: #fff;
}

/* Dark theme wins over the base border-color/background above (higher
   specificity: .pl-app[data-pl-theme="dark"] .pl-wiz-chip-sel, 0,3,0 vs
   0,1,0) — darkens the fill so 13px white text clears 4.5:1 contrast. */
.pl-app[data-pl-theme="dark"] .pl-wiz-chip-sel {
  border-color: color-mix(in srgb, var(--pl-blue) 72%, var(--pl-panel-1));
  background: color-mix(in srgb, var(--pl-blue) 72%, var(--pl-panel-1));
}

.pl-wiz-chip-sel.pl-wiz-chip-rec::after {
  background: #fff;
}

/* ── Toggle rows (pages / features) ──────────────────────────────────── */

.pl-wiz-togglelist {
  display: flex;
  flex-direction: column;
  gap: 6px;
}

.pl-wiz-toggle-row {
  display: flex;
  align-items: center;
  gap: 10px;
  min-height: 44px;
  padding: 8px 12px;
  border-radius: 10px;
  border: 1px solid var(--pl-border);
  background: var(--pl-panel-2);
  color: var(--pl-text);
  cursor: pointer;
  text-align: left;
  transition: border-color 120ms, background 120ms;
}

.pl-wiz-toggle-row:hover {
  border-color: var(--pl-blue);
}

.pl-wiz-toggle-row:focus-visible {
  outline: 2px solid var(--pl-blue);
  outline-offset: 2px;
}

.pl-wiz-toggle-box {
  flex-shrink: 0;
  width: 18px;
  height: 18px;
  border-radius: 5px;
  border: 1px solid var(--pl-border);
  background: var(--pl-panel-1);
}

.pl-wiz-toggle-on .pl-wiz-toggle-box {
  background: var(--pl-blue);
  border-color: var(--pl-blue);
  box-shadow: inset 0 0 0 3px var(--pl-panel-2);
}

.pl-wiz-toggle-text {
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 1px;
}

.pl-wiz-toggle-label {
  font-size: 13px;
  font-weight: 700;
}

.pl-wiz-toggle-why {
  font-size: 11.5px;
  color: var(--pl-muted);
}

/* ── Review step ──────────────────────────────────────────────────────── */

.pl-wiz-review-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 4px;
}

.pl-wiz-review-list li {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 9px 0;
  border-bottom: 1px solid var(--pl-border);
}

.pl-wiz-review-k {
  flex-shrink: 0;
  width: 84px;
  font-size: 11.5px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.03em;
  color: var(--pl-faint);
}

.pl-wiz-review-v {
  flex: 1;
  min-width: 0;
  font-size: 13px;
  color: var(--pl-text);
  overflow-wrap: break-word;
}

.pl-wiz-review-swatches {
  display: flex;
  gap: 3px;
}

.pl-wiz-edit {
  flex-shrink: 0;
  min-height: 32px;
  padding: 4px 10px;
  border-radius: 7px;
  border: 1px solid var(--pl-border);
  background: transparent;
  color: var(--pl-blue);
  font-size: 12px;
  font-weight: 700;
  cursor: pointer;
}

.pl-wiz-edit:hover {
  background: color-mix(in srgb, var(--pl-blue) 10%, transparent);
}

.pl-wiz-edit:focus-visible {
  outline: 2px solid var(--pl-blue);
  outline-offset: 2px;
}

/* ── Persistent center stage ──────────────────────────────────────────── */
/* DEAD: .pl-wiz-stage-wrap — wizard.rs now renders .pl-wiz-stage-dock for
   this wrapper; no CSS for .pl-wiz-stage-dock exists anywhere in main.css.
   Same likely-unported-rename as .pl-wiz-main above. Rule removed here. */

.pl-wiz-stage {
  --pl-wiz-accent: var(--pl-blue);
  --pl-wiz-accent-2: var(--pl-sky);
  --pl-wiz-accent-3: var(--pl-green);
  width: min(560px, 100%);
  border-radius: 14px;
  overflow: hidden;
  background: var(--pl-panel-1);
  border: 1px solid var(--pl-border);
  box-shadow: var(--pl-shadow-float);
}

.pl-wiz-chrome {
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 8px 10px;
  background: var(--pl-panel-2);
  border-bottom: 1px solid var(--pl-border);
}

.pl-wiz-cdot {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: var(--pl-track);
  flex-shrink: 0;
}

.pl-wiz-tabstrip {
  display: flex;
  gap: 4px;
  margin-left: 10px;
  overflow: hidden;
  flex-wrap: wrap;
}

.pl-wiz-tab {
  padding: 3px 9px;
  border-radius: 6px 6px 0 0;
  background: var(--pl-panel-1);
  border: 1px solid var(--pl-border);
  border-bottom: none;
  font-size: 10.5px;
  font-weight: 600;
  color: var(--pl-muted);
  white-space: nowrap;
  transition: background 200ms;
}

.pl-wiz-tab:first-child {
  color: var(--pl-wiz-accent);
}

.pl-wiz-page {
  display: flex;
  flex-direction: column;
}

.pl-wiz-nav {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 12px 16px;
  border-bottom: 1px solid var(--pl-border);
}

.pl-wiz-brand {
  font-weight: 800;
  font-size: 14px;
  color: var(--pl-wiz-accent);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.pl-wiz-navlinks {
  display: flex;
  gap: 10px;
  margin-left: auto;
}

.pl-wiz-navlinks span {
  width: 26px;
  height: 6px;
  border-radius: 3px;
  background: var(--pl-track);
}

.pl-wiz-navpill {
  padding: 5px 12px;
  border-radius: 999px;
  background: var(--pl-wiz-accent);
  color: #fff;
  font-size: 10.5px;
  font-weight: 700;
}

.pl-wiz-hero {
  display: flex;
  flex-direction: column;
  gap: 10px;
  padding: 26px 18px;
  transition: background 200ms;
}

.pl-wiz-hero-ph {
  height: 100px;
  border-radius: 10px;
  background: linear-gradient(135deg, var(--pl-wiz-accent), var(--pl-wiz-accent-2));
}

.pl-wiz-hero[data-pl-wiz-imagery="illustration"] .pl-wiz-hero-ph {
  background: var(--pl-block);
  background-image:
    radial-gradient(circle at 20% 30%, var(--pl-wiz-accent) 0 8px, transparent 9px),
    radial-gradient(circle at 70% 60%, var(--pl-wiz-accent-2) 0 12px, transparent 13px),
    linear-gradient(45deg, transparent 48%, var(--pl-wiz-accent-3) 49%, var(--pl-wiz-accent-3) 51%, transparent 52%);
}

.pl-wiz-hero[data-pl-wiz-imagery="3d"] .pl-wiz-hero-ph {
  background: var(--pl-block);
  background-image:
    radial-gradient(circle at 30% 35%, var(--pl-wiz-accent) 0 34px, transparent 35px),
    radial-gradient(circle at 72% 65%, var(--pl-wiz-accent-2) 0 22px, transparent 23px);
  box-shadow: inset 0 -8px 20px rgba(0, 0, 0, 0.12);
}

.pl-wiz-hero[data-pl-wiz-imagery="flat"] .pl-wiz-hero-ph {
  background: var(--pl-wiz-accent-3);
  background-image:
    linear-gradient(120deg, var(--pl-wiz-accent) 0 30%, transparent 30%),
    linear-gradient(-120deg, var(--pl-wiz-accent-2) 0 25%, transparent 25%);
}

.pl-wiz-hero-copy {
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.pl-wiz-hero-title {
  display: block;
  width: 70%;
  height: 16px;
  border-radius: 4px;
  background: var(--pl-text);
  opacity: 0.85;
}

.pl-wiz-hero-sub {
  display: block;
  width: 90%;
  height: 9px;
  border-radius: 4px;
  background: var(--pl-muted);
  opacity: 0.5;
}

.pl-wiz-hero-cta {
  display: block;
  width: 96px;
  height: 26px;
  margin-top: 4px;
  border-radius: 7px;
  background: var(--pl-wiz-accent);
}

.pl-wiz-body {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 10px;
  padding: 0 18px 20px;
}

.pl-wiz-blk {
  height: 54px;
  border-radius: 8px;
  background: var(--pl-block);
}

/* Layout-pack reshaping */

.pl-wiz-stage[data-pl-wiz-layout="bold"] .pl-wiz-hero {
  padding: 40px 18px;
}

.pl-wiz-stage[data-pl-wiz-layout="bold"] .pl-wiz-hero-ph {
  height: 130px;
}

.pl-wiz-stage[data-pl-wiz-layout="bold"] .pl-wiz-hero-title {
  height: 22px;
  width: 85%;
}

.pl-wiz-stage[data-pl-wiz-layout="editorial"] .pl-wiz-hero {
  flex-direction: row;
  align-items: center;
}

.pl-wiz-stage[data-pl-wiz-layout="editorial"] .pl-wiz-hero-ph {
  flex: 1;
  height: 120px;
}

.pl-wiz-stage[data-pl-wiz-layout="editorial"] .pl-wiz-hero-copy {
  flex: 1;
}

.pl-wiz-stage[data-pl-wiz-layout="minimal"] .pl-wiz-hero {
  align-items: center;
  text-align: center;
  padding: 34px 40px;
}

.pl-wiz-stage[data-pl-wiz-layout="minimal"] .pl-wiz-hero-ph {
  width: 60%;
}

.pl-wiz-stage[data-pl-wiz-layout="minimal"] .pl-wiz-hero-title,
.pl-wiz-stage[data-pl-wiz-layout="minimal"] .pl-wiz-hero-sub {
  width: 60%;
  align-self: center;
}

.pl-wiz-stage[data-pl-wiz-layout="minimal"] .pl-wiz-body {
  grid-template-columns: 1fr;
}

/* ── Bottom bar ───────────────────────────────────────────────────────── */

.pl-wiz-bottom {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 12px 20px;
  border-top: 1px solid var(--pl-border);
  flex-shrink: 0;
  flex-wrap: wrap;
}

.pl-wiz-dots {
  display: flex;
  gap: 6px;
}

.pl-wiz-dot-btn {
  /* width/height: 24px wins over an earlier 22px decl at equal specificity
     (fix-theme.css, appended later in source order) — 24px visual box,
     >=44px hit area via the ::before layer below. */
  width: 24px;
  height: 24px;
  padding: 0;
  border-radius: 50%;
  border: none;
  background: transparent;
  cursor: pointer;
  position: relative;
}

.pl-wiz-dot-btn::before {
  content: "";
  position: absolute;
  inset: -10px; /* 24px box + 10px each side = 44px hit area */
  border-radius: 50%;
}

.pl-wiz-dot-btn::after {
  content: "";
  position: absolute;
  inset: 8px;
  border-radius: 50%;
  background: var(--pl-track);
  transition: background 120ms, inset 120ms;
}

.pl-wiz-dot-btn:hover::after {
  background: var(--pl-muted);
}

.pl-wiz-dot-btn:focus-visible {
  outline: 2px solid var(--pl-blue);
  outline-offset: 2px;
}

.pl-wiz-dot-cur::after {
  inset: 6px;
  background: var(--pl-blue);
}

.pl-wiz-bottom-actions {
  display: flex;
  align-items: center;
  gap: 8px;
}

.pl-wiz-skip {
  font-size: 12.5px;
}

.pl-wiz-generate-btn {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  min-height: 40px;
  padding: 10px 20px;
  border: none;
  border-radius: 10px;
  background: var(--pl-btn-green-grad);
  color: #fff;
  font-weight: 700;
  font-size: 14px;
  cursor: pointer;
  box-shadow: var(--pl-btn-green-shadow);
  transition: box-shadow 120ms, transform 120ms;
}

.pl-wiz-generate-btn:hover {
  box-shadow: var(--pl-btn-green-shadow-hover);
}

.pl-wiz-generate-btn:focus-visible {
  outline: 2px solid var(--pl-green);
  outline-offset: 2px;
}

.pl-wiz-generate-btn:disabled {
  cursor: default;
  opacity: 0.85;
}

.pl-wiz-generating {
  animation: pl-wiz-pulse 900ms ease-in-out infinite;
}

@keyframes pl-wiz-pulse {
  0%, 100% {
    transform: scale(1);
  }
  50% {
    transform: scale(1.03);
  }
}

/* ── Escape confirm ───────────────────────────────────────────────────── */

.pl-wiz-confirm-overlay {
  position: fixed;
  inset: 0;
  z-index: 80; /* z-scale: modal band (was 90, off-scale — this is a modal
    dialog nested above the already-open .pl-wizard modal; DOM/paint order
    keeps it on top at the same band) */
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 16px;
  background: var(--pl-modal-backdrop);
}

.pl-wiz-confirm-overlay[hidden] {
  display: none !important;
}

.pl-wiz-confirm {
  width: min(360px, 100%);
  padding: 20px;
  border-radius: 14px;
  background: var(--pl-glass-bg);
  backdrop-filter: blur(14px) saturate(1.3);
  -webkit-backdrop-filter: blur(14px) saturate(1.3);
  border: 1px solid var(--pl-glass-border);
  box-shadow: var(--pl-glass-shadow);
  display: flex;
  flex-direction: column;
  gap: 14px;
}

.pl-wiz-confirm p {
  margin: 0;
  font-size: 14px;
  color: var(--pl-text);
  line-height: 1.4;
}

.pl-wiz-confirm-actions {
  display: flex;
  gap: 8px;
  justify-content: flex-end;
}

/* Responsive rules for this block moved to the consolidated NAR/MID media
   sections at the end of this file. Reduced-motion rule moved to the
   consolidated reduced-motion block at the end of this file. */


/* ═══════════════════════════════════════════════════════════════════════
   Responsive — exactly three sections per the layout contract (NAR/MID/
   WIDE). Source breakpoints are remapped onto this scale:
     topbar v9:  max-width:1080px -> MID (980px), max-width:760px -> NAR (640px)
     wizard:     max-width:900px  -> MID (980px), max-width:560px -> NAR (640px)
   This changes the exact trigger pixel for a handful of viewport widths
   (e.g. 641-760px keeps the mobile topbar treatment it already had, but
   761-980px now gets it too where it didn't before); no rule's CONTENT
   changed, only which of the three contract breakpoints it fires under.
   Flagged in the report as the one deliberate architecture change.
   ═══════════════════════════════════════════════════════════════════════ */

/* ── NAR — max-width: 640px ─────────────────────────────────────────────── */

@media (max-width: 640px) {
  .pl-demo-pill {
    flex: 1 1 100%;
    text-align: center;
  }

  .pl-tabs {
    flex: 1 1 100%;
    display: flex;
    flex-wrap: nowrap;
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
    scrollbar-width: none;
    gap: 6px;
    padding-bottom: 2px;
  }

  .pl-tabs::-webkit-scrollbar {
    display: none;
  }

  .pl-tabs .pl-tab {
    flex: 0 0 auto;
    white-space: nowrap;
    min-height: 44px;
  }

  .pl-top-right {
    flex: 1 1 100%;
    justify-content: stretch;
  }

  .pl-top-right > * {
    flex: 1 1 auto;
    min-height: 44px;
  }

  .pl-make-btn,
  .pl-build-btn {
    flex: 1 1 100%;
  }

  .pl-wiz-grid {
    grid-template-columns: 1fr;
  }

  .pl-wiz-review-k {
    width: 68px;
  }
}

/* ── MID — max-width: 980px ─────────────────────────────────────────────── */

@media (max-width: 980px) {
  .pl-topbar {
    justify-content: flex-start;
    column-gap: 12px;
  }

  .pl-top-right {
    flex: 1 1 100%;
    justify-content: flex-end;
  }

  .pl-wiz-rail {
    border-right: none;
    border-bottom: 1px solid var(--pl-border);
    max-height: 46vh;
  }
}

/* ── WIDE — min-width: 1180px ───────────────────────────────────────────── */
/* No WIDE-specific rules in this scope today (nothing here currently
   widens past its MID layout at >=1180px) — section kept empty rather
   than invented, per "refactor, not redesign". */

/* ── Reduced motion (consolidated) ────────────────────────────────────────
   Every prefers-reduced-motion rule from the blocks above, deduplicated.
   .pl-tour-ring/.pl-tour-tip and .pl-save-gate/.pl-resume-banner already
   carry their own small reduced-motion rules inline (kept there since
   each is single-purpose and colocated with its component); this block
   only holds the multi-component ones that don't belong to one owner. */

@media (prefers-reduced-motion: reduce) {
  .pl-wiz-rail-body {
    animation: none;
  }

  .pl-wiz-generating {
    animation: none;
  }

  .pl-wiz-hero-ph,
  .pl-wiz-tab {
    transition: none;
  }
}

/* ── Build-your-own wizard (pl-wiz-*) — v2 full layout replacement ────────
   Full-screen takeover. Tokens only (--pl-*); the stage additionally reads
   --pl-wiz-accent/-2/-3, set inline per-render from the current palette by
   wizard.rs.

   DOM (wizard.rs): .pl-wizard > .pl-wiz-shell > [.pl-wiz-head, .pl-wiz-banner?,
   .pl-wiz-panes > (.pl-wiz-stage-dock > WizStage, .pl-wiz-rail), .pl-wiz-bottom].

   Layout contract (single source of truth — see project CLAUDE.md):
     Breakpoints — NAR max-width:640px, MID max-width:980px, WIDE min-width:1180px.
     Z-scale — base 0 / raised 10 / sticky chrome 20 / floating 40 / tour 60 /
               modal backdrop 79, modal 80 / toast 90. One band per component.
     Modal rule — inset:0 flex-centered wrapper; shell width:min(Xpx,100vw-32px),
               max-height:calc(100dvh-32px); BELOW MID the shell is the ONLY
               scroll container (header/footer pinned, body scrolls).

   Below MID (and up to WIDE) this wizard follows the modal rule literally:
   header and footer are pinned flex-shrink:0 children of the shell, and
   .pl-wiz-panes is the shell's one scroll container. Within it the stage is
   docked (position:sticky, so it reads as a fixed preview strip) and the
   option rail flows and scrolls beneath it — there is no second scroll
   container anywhere below WIDE. At WIDE the panes switch to a two-column
   grid (rail-left / stage-right) and the rail regains its own scroller,
   matching the original desktop treatment. */

.pl-wizard {
  position: fixed;
  inset: 0;
  z-index: 80;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 16px;
  background: var(--pl-modal-backdrop);
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
}

.pl-wizard[hidden] {
  display: none !important;
}

/* ── Shell: glass surface, layered ambient+key shadow, modal-rule sizing ── */

.pl-wiz-shell {
  display: flex;
  flex-direction: column;
  width: min(1180px, 100vw - 32px);
  height: min(880px, calc(100dvh - 32px));
  max-height: calc(100dvh - 32px);
  background: var(--pl-glass-bg);
  backdrop-filter: blur(20px) saturate(1.4);
  -webkit-backdrop-filter: blur(20px) saturate(1.4);
  border: 1px solid var(--pl-glass-border);
  border-radius: 18px;
  box-shadow:
    /* key: tight, high-contrast contact shadow */
    0 8px 20px -8px rgba(15, 23, 42, 0.28),
    /* ambient: broad, soft cast shadow */
    var(--pl-modal-shadow),
    /* glass edge highlight */
    0 1px 0 0 color-mix(in srgb, #fff 20%, transparent) inset;
  overflow: hidden;
}

@supports not ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
  .pl-wiz-shell {
    background: var(--pl-panel-1);
  }
}

/* ── Header (pinned) ──────────────────────────────────────────────────── */

.pl-wiz-head {
  display: flex;
  align-items: baseline;
  gap: 10px;
  padding: 16px 20px 10px;
  border-bottom: 1px solid transparent;
  border-image: linear-gradient(
      90deg,
      transparent,
      color-mix(in srgb, var(--pl-blue) 35%, var(--pl-border)) 50%,
      transparent
    )
    1;
  flex-shrink: 0;
}

.pl-wiz-step-label {
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--pl-faint);
}

.pl-wiz-title {
  flex: 1;
  margin: 0;
  font-size: 18px;
  font-weight: 700;
  color: var(--pl-text);
}

.pl-wiz-close {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 44px;
  height: 44px;
  margin: -6px -8px -6px 0;
  border-radius: 10px;
  border: 1px solid var(--pl-border);
  background: var(--pl-panel-2);
  color: var(--pl-muted);
  cursor: pointer;
  font-size: 14px;
  transition: background 120ms, color 120ms;
}

.pl-wiz-close:hover {
  background: var(--pl-block);
  color: var(--pl-text);
}

.pl-wiz-close:focus-visible {
  outline: 2px solid var(--pl-blue);
  outline-offset: 2px;
}

.pl-wiz-banner {
  margin: 0;
  padding: 8px 20px;
  font-size: 12.5px;
  color: var(--pl-blue);
  background: color-mix(in srgb, var(--pl-blue) 8%, var(--pl-panel-1));
  border-bottom: 1px solid var(--pl-border);
  flex-shrink: 0;
}

/* ── Panes: stage (docked) + rail ─────────────────────────────────────── */
/* Base = below WIDE (covers NAR and MID and the gap up to 1180px): the
   shell's ONLY scroll container. Stage is sticky-docked at the top of it
   (reads as a fixed preview strip); the rail has no scroller of its own —
   it simply flows below the stage and scrolls with everything else. */

.pl-wiz-panes {
  flex: 1;
  min-height: 0;
  overflow-y: auto;
  display: flex;
  flex-direction: column;
}

.pl-wiz-stage-dock {
  position: sticky;
  top: 0;
  z-index: 10;
  flex-shrink: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 10px 16px 14px;
  background: var(--pl-ground);
  border-bottom: 1px solid var(--pl-border);
  aspect-ratio: 16 / 9;
  max-height: 34dvh;
  overflow: hidden;
}

.pl-wiz-rail {
  padding: 18px 20px 24px;
}

.pl-wiz-rail-body {
  display: flex;
  flex-direction: column;
  gap: 10px;
  animation: pl-wiz-fade 150ms ease;
}

@keyframes pl-wiz-fade {
  from {
    opacity: 0;
    transform: translateY(4px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

.pl-wiz-q {
  margin: 0;
  font-size: 16px;
  font-weight: 700;
  color: var(--pl-text);
}

.pl-wiz-q-sm {
  font-size: 12.5px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--pl-muted);
  margin: 10px 0 0;
}

.pl-wiz-hint {
  margin: 0;
  font-size: 12.5px;
  line-height: 1.4;
  color: var(--pl-muted);
}

.pl-wiz-hint-notes {
  color: var(--pl-blue);
}

.pl-wiz-lbl {
  font-size: 12px;
  font-weight: 600;
  color: var(--pl-muted);
}

.pl-wiz-input {
  width: 100%;
  padding: 9px 11px;
  border-radius: 9px;
  border: 1px solid var(--pl-border);
  background: var(--pl-panel-2);
  color: var(--pl-text);
  font-size: 14px;
  min-height: 44px;
}

.pl-wiz-input:focus-visible {
  outline: 2px solid var(--pl-blue);
  outline-offset: 1px;
}

/* ── Option cards ─────────────────────────────────────────────────────── */

.pl-wiz-grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 8px;
}

.pl-wiz-opt {
  position: relative;
  display: flex;
  flex-direction: column;
  gap: 4px;
  align-items: flex-start;
  text-align: left;
  padding: 10px 12px;
  min-height: 44px;
  border-radius: 10px;
  border: 1px solid var(--pl-border);
  background: var(--pl-panel-2);
  color: var(--pl-text);
  cursor: pointer;
  transition: border-color 120ms, background 120ms, box-shadow 120ms;
}

.pl-wiz-opt:hover {
  border-color: var(--pl-blue);
}

.pl-wiz-opt:focus-visible {
  outline: 2px solid var(--pl-blue);
  outline-offset: 2px;
}

/* Recommended card: soft accent glow, plus a gradient hairline border
   instead of a flat tint — reads as "chosen for you", not just tinted. */
.pl-wiz-opt-rec {
  border-color: transparent;
  background-image: linear-gradient(var(--pl-panel-2), var(--pl-panel-2)),
    linear-gradient(
      135deg,
      color-mix(in srgb, var(--pl-blue) 55%, transparent),
      color-mix(in srgb, var(--pl-sky) 40%, transparent)
    );
  background-origin: border-box;
  background-clip: padding-box, border-box;
  box-shadow: 0 0 16px -6px color-mix(in srgb, var(--pl-blue) 55%, transparent);
}

.pl-wiz-opt-sel {
  border-color: var(--pl-blue);
  background: color-mix(in srgb, var(--pl-blue) 8%, var(--pl-panel-2));
  box-shadow: 0 0 0 1px var(--pl-blue) inset;
}

.pl-wiz-opt-sel.pl-wiz-opt-rec {
  background-image: none;
  box-shadow: 0 0 0 1px var(--pl-blue) inset,
    0 0 20px -6px color-mix(in srgb, var(--pl-blue) 65%, transparent);
}

.pl-wiz-opt-label {
  font-size: 13.5px;
  font-weight: 700;
}

.pl-wiz-opt-why {
  font-size: 11.5px;
  line-height: 1.35;
  color: var(--pl-muted);
}

.pl-wiz-badge {
  display: inline-flex;
  align-items: center;
  padding: 2px 7px;
  border-radius: 999px;
  font-size: 10px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.03em;
  color: #fff;
  background: var(--pl-btn-primary-grad, var(--pl-blue));
  align-self: flex-start;
}

.pl-wiz-badge-sm {
  font-size: 9.5px;
  padding: 2px 6px;
}

/* ── Color swatches ───────────────────────────────────────────────────── */

.pl-wiz-swatchrow {
  display: flex;
  gap: 3px;
}

.pl-wiz-swatch {
  width: 18px;
  height: 18px;
  border-radius: 5px;
  border: 1px solid var(--pl-glass-border);
  flex-shrink: 0;
}

.pl-wiz-swatch-sm {
  width: 14px;
  height: 14px;
  border-radius: 4px;
}

/* ── Fine-tune wheel ──────────────────────────────────────────────────── */

.pl-wiz-wheel-wrap {
  display: flex;
  justify-content: center;
  padding: 6px 0;
}

.pl-wiz-wheel {
  position: relative;
  width: 180px;
  height: 180px;
  border-radius: 50%;
  cursor: crosshair;
  touch-action: none;
  box-shadow: var(--pl-shadow-card);
  background: radial-gradient(circle, #fff 0%, rgba(255, 255, 255, 0) 62%),
    conic-gradient(from 90deg, #ff0000, #ffff00, #00ff00, #00ffff, #0000ff, #ff00ff, #ff0000);
}

.pl-wiz-wheel-thumb {
  position: absolute;
  width: 16px;
  height: 16px;
  margin-left: -8px;
  margin-top: -8px;
  border-radius: 50%;
  background: #fff;
  border: 2px solid var(--pl-text);
  box-shadow: 0 1px 4px rgba(0, 0, 0, 0.4);
  pointer-events: none;
}

/* ── Chips ────────────────────────────────────────────────────────────── */

.pl-wiz-chiprow {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
}

.pl-wiz-chip {
  position: relative;
  min-height: 44px;
  padding: 8px 14px;
  border-radius: 999px;
  border: 1px solid var(--pl-border);
  background: var(--pl-panel-2);
  color: var(--pl-text);
  font-size: 13px;
  font-weight: 600;
  cursor: pointer;
  transition: border-color 120ms, background 120ms, color 120ms;
}

.pl-wiz-chip:hover {
  border-color: var(--pl-blue);
}

.pl-wiz-chip:focus-visible {
  outline: 2px solid var(--pl-blue);
  outline-offset: 2px;
}

.pl-wiz-chip-rec::after {
  content: "";
  position: absolute;
  top: 4px;
  right: 4px;
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--pl-blue);
  box-shadow: 0 0 6px -1px color-mix(in srgb, var(--pl-blue) 80%, transparent);
}

.pl-wiz-chip-sel {
  border-color: var(--pl-blue);
  background: var(--pl-blue);
  color: #fff;
}

.pl-wiz-chip-sel.pl-wiz-chip-rec::after {
  background: #fff;
  box-shadow: none;
}

/* ── Toggle rows (pages / features) ──────────────────────────────────── */

.pl-wiz-togglelist {
  display: flex;
  flex-direction: column;
  gap: 6px;
}

.pl-wiz-toggle-row {
  display: flex;
  align-items: center;
  gap: 10px;
  min-height: 44px;
  padding: 8px 12px;
  border-radius: 10px;
  border: 1px solid var(--pl-border);
  background: var(--pl-panel-2);
  color: var(--pl-text);
  cursor: pointer;
  text-align: left;
  transition: border-color 120ms, background 120ms;
}

.pl-wiz-toggle-row:hover {
  border-color: var(--pl-blue);
}

.pl-wiz-toggle-row:focus-visible {
  outline: 2px solid var(--pl-blue);
  outline-offset: 2px;
}

.pl-wiz-toggle-box {
  flex-shrink: 0;
  width: 18px;
  height: 18px;
  border-radius: 5px;
  border: 1px solid var(--pl-border);
  background: var(--pl-panel-1);
}

.pl-wiz-toggle-on .pl-wiz-toggle-box {
  background: var(--pl-blue);
  border-color: var(--pl-blue);
  box-shadow: inset 0 0 0 3px var(--pl-panel-2);
}

.pl-wiz-toggle-text {
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 1px;
}

.pl-wiz-toggle-label {
  font-size: 13px;
  font-weight: 700;
}

.pl-wiz-toggle-why {
  font-size: 11.5px;
  color: var(--pl-muted);
}

/* ── Review step ──────────────────────────────────────────────────────── */

.pl-wiz-review-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 4px;
}

.pl-wiz-review-list li {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 9px 0;
  border-bottom: 1px solid var(--pl-border);
}

.pl-wiz-review-k {
  flex-shrink: 0;
  width: 84px;
  font-size: 11.5px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.03em;
  color: var(--pl-faint);
}

.pl-wiz-review-v {
  flex: 1;
  min-width: 0;
  font-size: 13px;
  color: var(--pl-text);
  overflow-wrap: break-word;
}

.pl-wiz-review-swatches {
  display: flex;
  gap: 3px;
}

.pl-wiz-edit {
  flex-shrink: 0;
  min-height: 32px;
  padding: 4px 10px;
  border-radius: 7px;
  border: 1px solid var(--pl-border);
  background: transparent;
  color: var(--pl-blue);
  font-size: 12px;
  font-weight: 700;
  cursor: pointer;
}

.pl-wiz-edit:hover {
  background: color-mix(in srgb, var(--pl-blue) 10%, transparent);
}

.pl-wiz-edit:focus-visible {
  outline: 2px solid var(--pl-blue);
  outline-offset: 2px;
}

/* ── The stage (fake browser preview) — unchanged internals ─────────────── */

.pl-wiz-stage {
  --pl-wiz-accent: var(--pl-blue);
  --pl-wiz-accent-2: var(--pl-sky);
  --pl-wiz-accent-3: var(--pl-green);
  width: min(560px, 100%);
  border-radius: 14px;
  overflow: hidden;
  background: var(--pl-panel-1);
  border: 1px solid var(--pl-border);
  box-shadow: var(--pl-shadow-float);
}

.pl-wiz-chrome {
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 8px 10px;
  background: var(--pl-panel-2);
  border-bottom: 1px solid var(--pl-border);
}

.pl-wiz-cdot {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: var(--pl-track);
  flex-shrink: 0;
}

.pl-wiz-tabstrip {
  display: flex;
  gap: 4px;
  margin-left: 10px;
  overflow: hidden;
  flex-wrap: wrap;
}

.pl-wiz-tab {
  padding: 3px 9px;
  border-radius: 6px 6px 0 0;
  background: var(--pl-panel-1);
  border: 1px solid var(--pl-border);
  border-bottom: none;
  font-size: 10.5px;
  font-weight: 600;
  color: var(--pl-muted);
  white-space: nowrap;
  transition: background 200ms;
}

.pl-wiz-tab:first-child {
  color: var(--pl-wiz-accent);
}

.pl-wiz-page {
  display: flex;
  flex-direction: column;
}

.pl-wiz-nav {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 12px 16px;
  border-bottom: 1px solid var(--pl-border);
}

.pl-wiz-brand {
  font-weight: 800;
  font-size: 14px;
  color: var(--pl-wiz-accent);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.pl-wiz-navlinks {
  display: flex;
  gap: 10px;
  margin-left: auto;
}

.pl-wiz-navlinks span {
  width: 26px;
  height: 6px;
  border-radius: 3px;
  background: var(--pl-track);
}

.pl-wiz-navpill {
  padding: 5px 12px;
  border-radius: 999px;
  background: var(--pl-wiz-accent);
  color: #fff;
  font-size: 10.5px;
  font-weight: 700;
}

.pl-wiz-hero {
  display: flex;
  flex-direction: column;
  gap: 10px;
  padding: 26px 18px;
  transition: background 200ms;
}

.pl-wiz-hero-ph {
  height: 100px;
  border-radius: 10px;
  background: linear-gradient(135deg, var(--pl-wiz-accent), var(--pl-wiz-accent-2));
}

.pl-wiz-hero[data-pl-wiz-imagery="illustration"] .pl-wiz-hero-ph {
  background: var(--pl-block);
  background-image: radial-gradient(circle at 20% 30%, var(--pl-wiz-accent) 0 8px, transparent 9px),
    radial-gradient(circle at 70% 60%, var(--pl-wiz-accent-2) 0 12px, transparent 13px),
    linear-gradient(
      45deg,
      transparent 48%,
      var(--pl-wiz-accent-3) 49%,
      var(--pl-wiz-accent-3) 51%,
      transparent 52%
    );
}

.pl-wiz-hero[data-pl-wiz-imagery="3d"] .pl-wiz-hero-ph {
  background: var(--pl-block);
  background-image: radial-gradient(circle at 30% 35%, var(--pl-wiz-accent) 0 34px, transparent 35px),
    radial-gradient(circle at 72% 65%, var(--pl-wiz-accent-2) 0 22px, transparent 23px);
  box-shadow: inset 0 -8px 20px rgba(0, 0, 0, 0.12);
}

.pl-wiz-hero[data-pl-wiz-imagery="flat"] .pl-wiz-hero-ph {
  background: var(--pl-wiz-accent-3);
  background-image: linear-gradient(120deg, var(--pl-wiz-accent) 0 30%, transparent 30%),
    linear-gradient(-120deg, var(--pl-wiz-accent-2) 0 25%, transparent 25%);
}

.pl-wiz-hero-copy {
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.pl-wiz-hero-title {
  display: block;
  width: 70%;
  height: 16px;
  border-radius: 4px;
  background: var(--pl-text);
  opacity: 0.85;
}

.pl-wiz-hero-sub {
  display: block;
  width: 90%;
  height: 9px;
  border-radius: 4px;
  background: var(--pl-muted);
  opacity: 0.5;
}

.pl-wiz-hero-cta {
  display: block;
  width: 96px;
  height: 26px;
  margin-top: 4px;
  border-radius: 7px;
  background: var(--pl-wiz-accent);
}

.pl-wiz-body {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 10px;
  padding: 0 18px 20px;
}

.pl-wiz-blk {
  height: 54px;
  border-radius: 8px;
  background: var(--pl-block);
}

/* Layout-pack reshaping */

.pl-wiz-stage[data-pl-wiz-layout="bold"] .pl-wiz-hero {
  padding: 40px 18px;
}

.pl-wiz-stage[data-pl-wiz-layout="bold"] .pl-wiz-hero-ph {
  height: 130px;
}

.pl-wiz-stage[data-pl-wiz-layout="bold"] .pl-wiz-hero-title {
  height: 22px;
  width: 85%;
}

.pl-wiz-stage[data-pl-wiz-layout="editorial"] .pl-wiz-hero {
  flex-direction: row;
  align-items: center;
}

.pl-wiz-stage[data-pl-wiz-layout="editorial"] .pl-wiz-hero-ph {
  flex: 1;
  height: 120px;
}

.pl-wiz-stage[data-pl-wiz-layout="editorial"] .pl-wiz-hero-copy {
  flex: 1;
}

.pl-wiz-stage[data-pl-wiz-layout="minimal"] .pl-wiz-hero {
  padding: 34px 18px 20px;
}

.pl-wiz-stage[data-pl-wiz-layout="minimal"] .pl-wiz-hero-ph {
  height: 70px;
}

.pl-wiz-stage[data-pl-wiz-layout="minimal"] .pl-wiz-hero-title,
.pl-wiz-stage[data-pl-wiz-layout="minimal"] .pl-wiz-hero-sub {
  width: 60%;
}

.pl-wiz-stage[data-pl-wiz-layout="minimal"] .pl-wiz-body {
  grid-template-columns: 1fr;
}

/* Compact docked strip (below WIDE): the stage no longer sizes itself from
   fixed-px children — chrome/nav stay compact and the hero flexes to fill
   whatever room is left inside the dock's aspect/34dvh cap. The filler
   content grid is decorative only and is dropped at this size; nothing it
   shows is unique information (it never carries text or state). */

.pl-wiz-stage-dock .pl-wiz-stage {
  width: 100%;
  height: 100%;
  display: flex;
  flex-direction: column;
}

.pl-wiz-stage-dock .pl-wiz-chrome {
  flex-shrink: 0;
}

.pl-wiz-stage-dock .pl-wiz-page {
  flex: 1;
  min-height: 0;
  overflow: hidden;
}

.pl-wiz-stage-dock .pl-wiz-nav {
  flex-shrink: 0;
  padding: 8px 14px;
}

.pl-wiz-stage-dock .pl-wiz-hero {
  flex: 1;
  min-height: 0;
  padding: 10px 14px;
  gap: 6px;
}

.pl-wiz-stage-dock .pl-wiz-hero-ph {
  flex: 1;
  min-height: 0;
  height: auto;
}

.pl-wiz-stage-dock .pl-wiz-hero-copy {
  flex-shrink: 0;
  gap: 5px;
}

.pl-wiz-stage-dock .pl-wiz-body {
  display: none;
}

/* ── Bottom bar (pinned) ──────────────────────────────────────────────── */

.pl-wiz-bottom {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 12px 20px;
  border-top: 1px solid transparent;
  border-image: linear-gradient(
      90deg,
      transparent,
      color-mix(in srgb, var(--pl-blue) 35%, var(--pl-border)) 50%,
      transparent
    )
    1;
  flex-shrink: 0;
  flex-wrap: wrap;
}

.pl-wiz-dots {
  display: flex;
  gap: 6px;
}

.pl-wiz-dot-btn {
  position: relative;
  width: 24px;
  height: 24px;
  padding: 0;
  border-radius: 50%;
  border: none;
  background: transparent;
  cursor: pointer;
}

/* 24px visual box, 44px hit area via an expanded invisible layer. */
.pl-wiz-dot-btn::before {
  content: "";
  position: absolute;
  inset: -10px;
  border-radius: 50%;
}

.pl-wiz-dot-btn::after {
  content: "";
  position: absolute;
  inset: 8px;
  border-radius: 50%;
  background: var(--pl-track);
  transition: background 120ms, inset 120ms, box-shadow 120ms;
}

.pl-wiz-dot-btn:hover::after {
  background: var(--pl-muted);
}

.pl-wiz-dot-btn:focus-visible {
  outline: 2px solid var(--pl-blue);
  outline-offset: 2px;
}

/* Active step: soft accent glow, not just a color swap. */
.pl-wiz-dot-cur::after {
  inset: 6px;
  background: var(--pl-blue);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--pl-blue) 22%, transparent),
    0 0 12px -2px color-mix(in srgb, var(--pl-blue) 75%, transparent);
}

.pl-wiz-bottom-actions {
  display: flex;
  align-items: center;
  gap: 8px;
}

.pl-wiz-skip {
  font-size: 12.5px;
}

.pl-wiz-generate-btn {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  min-height: 44px;
  padding: 10px 20px;
  border: none;
  border-radius: 10px;
  background: var(--pl-btn-green-grad);
  color: #fff;
  font-weight: 700;
  font-size: 14px;
  cursor: pointer;
  box-shadow: var(--pl-btn-green-shadow);
  transition: box-shadow 120ms, transform 120ms;
}

.pl-wiz-generate-btn:hover {
  box-shadow: var(--pl-btn-green-shadow-hover);
}

.pl-wiz-generate-btn:focus-visible {
  outline: 2px solid var(--pl-green);
  outline-offset: 2px;
}

.pl-wiz-generate-btn:disabled {
  cursor: default;
  opacity: 0.85;
}

.pl-wiz-generating {
  animation: pl-wiz-pulse 900ms ease-in-out infinite;
}

@keyframes pl-wiz-pulse {
  0%,
  100% {
    transform: scale(1);
  }
  50% {
    transform: scale(1.03);
  }
}

/* ── Escape confirm ───────────────────────────────────────────────────── */

.pl-wiz-confirm-overlay {
  position: fixed;
  inset: 0;
  z-index: 90;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 16px;
  background: var(--pl-modal-backdrop);
}

.pl-wiz-confirm-overlay[hidden] {
  display: none !important;
}

.pl-wiz-confirm {
  width: min(360px, 100vw - 32px);
  max-height: calc(100dvh - 32px);
  padding: 20px;
  border-radius: 14px;
  background: var(--pl-glass-bg);
  backdrop-filter: blur(14px) saturate(1.3);
  -webkit-backdrop-filter: blur(14px) saturate(1.3);
  border: 1px solid var(--pl-glass-border);
  box-shadow: var(--pl-glass-shadow);
  display: flex;
  flex-direction: column;
  gap: 14px;
  overflow-y: auto;
}

@supports not ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
  .pl-wiz-confirm {
    background: var(--pl-panel-1);
  }
}

.pl-wiz-confirm p {
  margin: 0;
  font-size: 14px;
  color: var(--pl-text);
  line-height: 1.4;
}

.pl-wiz-confirm-actions {
  display: flex;
  gap: 8px;
  justify-content: flex-end;
}

/* ── WIDE (min-width:1180px): rail-left / stage-right, rail owns its own
   scroller again — the modal rule's single-scroller constraint is a
   below-MID requirement, and this is the original desktop treatment. ──── */

@media (min-width: 1180px) {
  .pl-wiz-panes {
    display: grid;
    grid-template-columns: minmax(320px, 420px) 1fr;
    grid-template-areas: "rail stage";
    overflow: visible;
  }

  .pl-wiz-rail {
    grid-area: rail;
    overflow-y: auto;
    max-height: 100%;
    border-right: 1px solid transparent;
    border-image: linear-gradient(
        180deg,
        transparent,
        color-mix(in srgb, var(--pl-blue) 30%, var(--pl-border)) 50%,
        transparent
      )
      1;
  }

  .pl-wiz-stage-dock {
    grid-area: stage;
    position: static;
    z-index: auto;
    aspect-ratio: auto;
    max-height: none;
    overflow: visible;
    padding: 24px;
    border-bottom: none;
    background: var(--pl-ground);
  }

  /* Restore the full (uncompacted) stage internals at WIDE. */
  .pl-wiz-stage-dock .pl-wiz-stage {
    width: min(560px, 100%);
    height: auto;
  }

  .pl-wiz-stage-dock .pl-wiz-page {
    flex: none;
    overflow: visible;
  }

  .pl-wiz-stage-dock .pl-wiz-nav {
    padding: 12px 16px;
  }

  .pl-wiz-stage-dock .pl-wiz-hero {
    flex: none;
    padding: 26px 18px;
    gap: 10px;
  }

  .pl-wiz-stage-dock .pl-wiz-hero-ph {
    flex: none;
    height: 100px;
  }

  .pl-wiz-stage-dock .pl-wiz-body {
    display: grid;
  }
}

/* ── NAR (max-width:640px): tighter grids ─────────────────────────────── */

@media (max-width: 640px) {
  .pl-wiz-grid {
    grid-template-columns: 1fr;
  }

  .pl-wiz-review-k {
    width: 68px;
  }

  .pl-wiz-stage-dock {
    max-height: 30dvh;
  }
}

/* ── Reduced motion ───────────────────────────────────────────────────── */

@media (prefers-reduced-motion: reduce) {
  .pl-wiz-rail-body {
    animation: none;
  }

  .pl-wiz-generating {
    animation: none;
  }

  .pl-wiz-hero-ph,
  .pl-wiz-tab {
    transition: none;
  }
}

/* Selected wizard chip in dark theme: darken the fill so 13px white text
   clears 4.5:1 (dark --pl-blue at full strength under white text is only
   ~3.7:1; mixed to 72% over --pl-panel-1 lands ~5.4:1). */
.pl-app[data-pl-theme="dark"] .pl-wiz-chip-sel {
  border-color: color-mix(in srgb, var(--pl-blue) 72%, var(--pl-panel-1));
  background: color-mix(in srgb, var(--pl-blue) 72%, var(--pl-panel-1));
}

/* ─────────────────────────────────────────────────────────────────────────
   card-grid.css — spatial architecture layer for planner card families.

   Scope: display/grid/flex/areas/gap/aspect-ratio/min-height/alignment ONLY.
   No colors, shadows, or --pl-* values invented — this file never sets a
   color/background/border/box-shadow. Selectors are doubled (.pl-x.pl-x)
   against every class that already carries a main.css rule, since this
   sheet is appended after main.css (and, per the concurrent scratch/*.css
   files in this dir, possibly after/before other scratch sheets too — the
   doubled specificity makes the win order-independent, not just append-
   order-dependent).

   Markup verified live against crates/d3pth-web/src/planner/{map_view,
   gallery,detail_view,wizard}.rs on 2026-08-16 — grep every selector below
   against those files before trusting main.css's existing rules for the
   same classes; the .rs markup is mid-refactor by other concurrent agents.
   ───────────────────────────────────────────────────────────────────────── */

/* ═══ 1 · .pl-pic-node caption — map_view.rs picture-node cards ═══════════
   Markup: <button class="pl-pic-node …"> {pl-pic-face} <span class=
   "pl-pic-caption"> <span class="pl-nid"> <span class="pl-nt">
   {page_badges() → <div class="pl-badges">} [<span class="pl-notes-dot">]
   </span></button>. Also used, with extra classes layered on, for the
   business/site node: <span class="pl-pic-caption pl-chart-biz-caption">
   <span class="pl-nid pl-zone-biz-kind"> <span class="pl-nt
   pl-zone-biz-name"> <span class="pl-zone-biz-counts"> — same base classes,
   so the rules below apply to both for free.

   .pl-pic-node cards live in a flex-wrap row (.pl-tier-list.pl-chart-
   cluster-grid → <li class="pl-page-cell"> display:flex, default
   align-items:stretch) so siblings in the same line already stretch to
   equal height today. The caption itself was a plain flex column with no
   flex-grow, so that extra stretched height collected as blank space AFTER
   the caption instead of pinning the badges row to the card's true bottom.
   Grid-locking eyebrow/title/badges rows and letting the caption fill the
   stretched card height fixes that: badges now land on the same baseline
   across every card in a row regardless of title line count. */

.pl-pic-caption.pl-pic-caption {
  flex: 1 1 auto; /* absorb the flex-row stretch instead of leaving a gap below */
  display: grid;
  grid-template-areas:
    "eyebrow"
    "title"
    "badges";
  grid-template-rows: auto 1fr auto; /* title row takes the slack, badges pin to the bottom */
}

.pl-pic-caption .pl-nid {
  grid-area: eyebrow;
  align-self: start;
}

.pl-pic-caption .pl-nt {
  grid-area: title;
  align-self: start;
}

.pl-pic-caption .pl-badges {
  grid-area: badges;
  align-self: end;
}

/* .pl-zone-biz-counts (business-node third caption line) and .pl-notes-dot
   (optional 4th caption child) are NOT in the founder's eyebrow/title/
   badges list, so no grid-area is assigned to either — grid auto-placement
   drops them into the first open cell (the badges row when it's otherwise
   empty, or a new implicit row after it), which is harmless and keeps
   their current relative order. Not styled further; flagged, not skipped,
   since both classes do exist in the markup. */

/* ═══ 2 · .pl-gallery-card internals — gallery.rs template cards ══════════
   Markup: <button class="pl-gallery-card"> <span class="pl-gallery-thumb">
   <span class="pl-gallery-card-body"> <span class="pl-gallery-card-
   eyebrow"> <span class="pl-gallery-card-name"> <span class="pl-gallery-
   card-accent"> <span class="pl-gallery-card-company"> <span class=
   "pl-gallery-card-desc"> <span class="pl-gallery-card-foot"> (the CTA:
   .pl-browse-btn + optional .pl-note-chip) </span></span></button>.

   .pl-gallery-grid is CSS Grid (auto-fill, default align-items:stretch),
   so cards in a row already match height. .pl-gallery-card-body had no
   flex-grow, so — same failure mode as family 1 — a card with a short
   description left blank space below its foot instead of the CTA landing
   on a shared baseline. Grid-locks the body's internal rows with the name
   ("title") row flexible so it (not the CTA) absorbs the row-stretch slack;
   .pl-gallery-card-foot always lands as the last row, flush with the card
   bottom — the technique-2 "CTA row aligns across siblings" outcome,
   delivered via the technique-1 grid instead of margin-top:auto since a
   named flexible row targets the slack at the title specifically rather
   than spreading it over every gap. */

.pl-gallery-card-body.pl-gallery-card-body {
  flex: 1 1 auto; /* fill the stretched card's remaining height */
  display: grid;
  grid-template-areas:
    "eyebrow"
    "title"
    "accent"
    "company"
    "blurb"
    "foot";
  grid-template-rows: auto 1fr auto auto auto auto;
}

.pl-gallery-card-body .pl-gallery-card-eyebrow {
  grid-area: eyebrow;
}

.pl-gallery-card-body .pl-gallery-card-name {
  grid-area: title;
  align-self: start;
}

.pl-gallery-card-body .pl-gallery-card-accent {
  grid-area: accent;
  align-self: start;
}

.pl-gallery-card-body .pl-gallery-card-company {
  grid-area: company;
}

.pl-gallery-card-body .pl-gallery-card-desc {
  grid-area: blurb;
}

.pl-gallery-card-body .pl-gallery-card-foot {
  grid-area: foot;
  align-self: end;
}

/* ═══ 3 · .pl-opt decision cards — detail_view.rs "one decision left" ═════
   Markup: <button class="pl-opt[ pl-opt-rec]"> <span class="pl-opt-radio">
   <span class="pl-opt-main"> <span class="pl-opt-head"> <span class=
   "pl-opt-title"> [<span class="pl-rb">] </span> <span class="pl-why">
   </span></button>.

   Was a flex row with no flex-grow on .pl-opt-main, so its width sat at
   content's shrink-to-fit size rather than reliably filling the row —
   fine when why-text is long, inconsistent when it's short. Grid-locks a
   fixed dot column + a flexible (1fr) text column so the text block always
   spans the same width regardless of copy length; .pl-opt-main keeps its
   own internal flex column for the head/why stack untouched. */

.pl-opt.pl-opt {
  display: grid;
  grid-template-columns: auto 1fr;
  grid-template-areas: "dot text";
  align-items: start;
}

.pl-opt .pl-opt-radio {
  grid-area: dot;
}

.pl-opt .pl-opt-main {
  grid-area: text;
  min-width: 0;
}

/* ═══ 4 · .pl-wiz-opt — wizard.rs opt_card()/inline palette option cards ══
   Markup (opt_card(), used for business-type/layout-pack steps): <button
   class="pl-wiz-opt[ pl-wiz-opt-sel][ pl-wiz-opt-rec]"> [<span class=
   "pl-wiz-badge">] <span class="pl-wiz-opt-label"> <span class="pl-wiz-
   opt-why"> </button>. The step-2 (color direction) options inline the
   same classes plus one extra: [<span class="pl-wiz-badge">] <span
   class="pl-wiz-swatchrow"> <span class="pl-wiz-opt-label"> <span
   class="pl-wiz-opt-why">.

   .pl-wiz-grid lays these out 2-up (CSS Grid, default align-items:stretch)
   so a recommended card (with a badge) and a plain one in the same row
   already match height — but the badge occupying real vertical space at
   the top pushed everything below it down by the badge's height, so the
   label/why baseline shifted between recommended and plain options. Grid-
   locks a reserved badge row (fixed height, present or not) plus a
   flexible why row that absorbs any row-stretch slack, so label always
   starts at the same y whether or not that particular card has a badge. */

.pl-wiz-opt.pl-wiz-opt {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  grid-template-areas:
    "badge"
    "swatches"
    "label"
    "why";
  grid-template-rows: 20px auto auto 1fr; /* badge row reserved even when the badge is absent */
}

.pl-wiz-opt .pl-wiz-badge {
  grid-area: badge;
  align-self: start;
}

.pl-wiz-opt .pl-wiz-swatchrow {
  grid-area: swatches;
  align-self: start;
}

.pl-wiz-opt .pl-wiz-opt-label {
  grid-area: label;
  align-self: start;
}

.pl-wiz-opt .pl-wiz-opt-why {
  grid-area: why; /* flexible cell absorbs row-stretch slack, text still starts at its top */
}

/* ═══ 5 · Aspect-ratio locks — zero shift while mockup PNGs stream ════════ */

/* 5a. Picture-node face (map_view.rs picture_face()): already 8/5 via
   main.css's late .pl-app .pl-pic-face rule — restated here, doubled, so
   it holds regardless of scratch-sheet load order, and extended onto the
   img box and the "picture coming" placeholder tile explicitly (both are
   position:absolute; inset:0 within the face today, so they already
   inherit the ratio geometrically — this makes it hold even if that
   positioning ever changes). */
.pl-pic-face.pl-pic-face {
  aspect-ratio: 8 / 5;
  height: auto;
}

.pl-pic-img.pl-pic-img {
  aspect-ratio: 8 / 5;
  object-fit: cover;
}

.pl-pic-placeholder.pl-pic-placeholder {
  aspect-ratio: 8 / 5;
}

/* 5b. Gallery thumbs (gallery.rs .pl-gallery-thumb, wrapping .pl-nt-img):
   main.css's "picturemark v6" block already locks the default thumb to
   8/5 (height:auto) — restated/doubled here for load-order safety. The
   first-card "hero" variant at ≥900px in main.css still hard-codes
   height:210px though, which breaks the ratio once that card spans 2 grid
   columns (double width, same fixed height). Overriding that specific
   compound selector — matched exactly, one class doubled for extra
   specificity margin, no new breakpoint introduced since this isn't one
   of the three contract breakpoints — keeps the hero thumb on the same
   8/5 ratio as every other card instead of going stubby at 2x width. */
.pl-gallery-thumb.pl-gallery-thumb {
  aspect-ratio: 8 / 5;
  height: auto;
}

.pl-gallery-grid > li:first-child .pl-gallery-thumb.pl-gallery-thumb {
  aspect-ratio: 8 / 5;
  height: auto;
}

.pl-nt-img.pl-nt-img {
  aspect-ratio: 8 / 5;
  object-fit: cover;
}

/* 5c. Wizard stage preview (wizard.rs .pl-wiz-stage-dock, wrapping the
   persistent <WizStage/> mock-browser). This box has no image to 404/load,
   but it DOES reflow: WizStage stays mounted across every wizard step, and
   its rendered height changes with data-pl-wiz-layout (bold/editorial/
   minimal reshape hero padding + block sizes) and with how many page tabs
   are selected — so picking a different layout pack at step 3 can visibly
   jump the whole dialog. .pl-wiz-stage-dock carries no other rule
   anywhere yet (main.css's only nearby rule targets the stale, no-longer-
   rendered .pl-wiz-stage-wrap/.pl-wiz-main class names), so this is
   deliberately conservative: a min-height floor at every width (never
   clips, never overlaps a sibling — it's a floor, not a ceiling) plus an
   explicit aspect-ratio at the widest contract breakpoint only, where the
   dock is reliably wide enough that the ratio-derived height comfortably
   covers the tallest observed content (~440px at the "bold" layout with a
   wrapped tab row) without risking overflow at narrower, less predictable
   widths. Deliberately does NOT add display/alignment here — this
   container's overall layout (row vs. stacked with .pl-wiz-rail) isn't one
   of the four requested card families and looks to be mid-build by
   whichever agent owns .pl-wiz-panes; reserving space is this file's job,
   arranging the pane is not. */
.pl-wiz-stage-dock.pl-wiz-stage-dock {
  min-height: 380px;
}

@media (min-width: 1180px) {
  .pl-wiz-stage-dock.pl-wiz-stage-dock {
    aspect-ratio: 4 / 3;
    min-height: 420px;
  }
}

/* ─────────────────────────────────────────────────────────────────────── */
/* Planner premium surface v1 — glassglow, shadow depth, glow, display type */
/* CSS-only overlay. Loads after the base planner stylesheets and re-skins */
/* existing chrome at the token/paint layer: color, shadow, blur, border,  */
/* type. No width/height/position/display/geometry changes anywhere here. */
/* Reuses the marketing shadow/glass/type language already in main.css    */
/* (backdrop-filter blur+saturate, @supports fallback, color-mix borders, */
/* --font-display) and extends the existing --pl-* token system.         */
/* ─────────────────────────────────────────────────────────────────────── */

/* ── 0. Tokens: elevation + glow, light default on .pl-app ─────────────── */

.pl-app {
  /* 3-step elevation scale — ambient contact shadow + a longer key throw.
     Cards sit lowest, floating chrome above content, modals deepest. */
  --pl-elev-1: 0 1px 2px rgba(15, 23, 42, 0.06), 0 6px 16px -6px rgba(15, 23, 42, 0.12);
  --pl-elev-2: 0 2px 6px -1px rgba(15, 23, 42, 0.1), 0 16px 36px -10px rgba(15, 23, 42, 0.18),
    0 0 24px -10px color-mix(in srgb, var(--pl-blue) 22%, transparent);
  --pl-elev-3: 0 4px 10px -2px rgba(15, 23, 42, 0.14), 0 28px 64px -16px rgba(15, 23, 42, 0.3),
    0 0 40px -12px color-mix(in srgb, var(--pl-blue) 18%, transparent);

  /* CTA glow — ring + soft diffuse throw, blue and green button families */
  --pl-cta-glow: 0 0 0 1px color-mix(in srgb, var(--pl-sky) 20%, transparent),
    0 0 26px -6px color-mix(in srgb, var(--pl-blue) 45%, transparent);
  --pl-cta-glow-hover: 0 0 0 1px color-mix(in srgb, var(--pl-sky) 32%, transparent),
    0 0 38px -4px color-mix(in srgb, var(--pl-blue) 58%, transparent);
  --pl-cta-glow-green: 0 0 0 1px color-mix(in srgb, var(--pl-green) 22%, transparent),
    0 0 26px -6px color-mix(in srgb, var(--pl-green) 45%, transparent);
  --pl-cta-glow-green-hover: 0 0 0 1px color-mix(in srgb, var(--pl-green) 34%, transparent),
    0 0 38px -4px color-mix(in srgb, var(--pl-green) 58%, transparent);

  /* Lighter ambient glow for recommended-state chips/badges (not a CTA) */
  --pl-rec-glow: 0 0 0 1px color-mix(in srgb, var(--pl-sky) 22%, transparent),
    0 0 14px -6px color-mix(in srgb, var(--pl-blue) 40%, transparent);

  /* One chrome geometry for topbar pills, page tabs, and icon buttons.
     Selected vs idle is fill/border, never a second component family. */
  --pl-chrome-h: 32px;
  --pl-chrome-radius: 999px;
  --pl-chrome-font: 12px;
  --pl-chrome-weight: 600;
  --pl-chrome-pad-x: 12px;
  --pl-chrome-bg: var(--pl-glass-bg);
  --pl-chrome-border: color-mix(in srgb, var(--pl-sky) 42%, var(--pl-glass-border));
  --pl-chrome-ink: var(--pl-text);
  --pl-chrome-glass: inset 0 1px 0 color-mix(in srgb, #ffffff 45%, transparent);
}

/* ── Tokens: dark — deeper spread, softer opacity, sky-tinted glow ──────── */

.pl-app[data-pl-theme="dark"] {
  --pl-elev-1: 0 1px 2px rgba(0, 0, 0, 0.35), 0 8px 20px -8px rgba(0, 0, 0, 0.45);
  --pl-elev-2: 0 2px 6px -1px rgba(0, 0, 0, 0.4), 0 20px 44px -12px rgba(0, 0, 0, 0.55),
    0 0 30px -10px color-mix(in srgb, var(--pl-sky) 28%, transparent);
  --pl-elev-3: 0 4px 12px -2px rgba(0, 0, 0, 0.5), 0 32px 72px -18px rgba(0, 0, 0, 0.65),
    0 0 46px -12px color-mix(in srgb, var(--pl-sky) 24%, transparent);

  --pl-cta-glow: 0 0 0 1px color-mix(in srgb, var(--pl-sky) 30%, transparent),
    0 0 28px -6px color-mix(in srgb, var(--pl-sky) 55%, transparent);
  --pl-cta-glow-hover: 0 0 0 1px color-mix(in srgb, var(--pl-sky) 45%, transparent),
    0 0 42px -4px color-mix(in srgb, var(--pl-sky) 68%, transparent);
  --pl-cta-glow-green: 0 0 0 1px color-mix(in srgb, var(--pl-green) 30%, transparent),
    0 0 28px -6px color-mix(in srgb, var(--pl-green) 55%, transparent);
  --pl-cta-glow-green-hover: 0 0 0 1px color-mix(in srgb, var(--pl-green) 45%, transparent),
    0 0 42px -4px color-mix(in srgb, var(--pl-green) 68%, transparent);

  --pl-rec-glow: 0 0 0 1px color-mix(in srgb, var(--pl-sky) 30%, transparent),
    0 0 16px -6px color-mix(in srgb, var(--pl-sky) 50%, transparent);
}

/* ── 1. GLASS: topbar, area-tabs, flow-confirm, try-on bar, nudge, save   */
/*    gate + inspector shells ──────────────────────────────────────────── */

.pl-topbar {
  background: var(--pl-glass-bg);
  border-bottom: 1px solid var(--pl-glass-border);
  backdrop-filter: blur(14px) saturate(1.3);
  -webkit-backdrop-filter: blur(14px) saturate(1.3);
  box-shadow: var(--pl-elev-2);
}

@supports not ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
  .pl-topbar {
    background: var(--pl-panel-1);
  }
}

.pl-area-tabs {
  backdrop-filter: blur(14px) saturate(1.3);
  -webkit-backdrop-filter: blur(14px) saturate(1.3);
}

@supports not ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
  .pl-area-tabs {
    background: var(--pl-panel-2);
  }
}

/* ── 2. SHADOW DEPTH: cards elev-1, floating bars elev-2, modals elev-3 ── */

.pl-panel,
.pl-gallery-card,
.pl-node,
.pl-wiz-opt,
.pl-area-tabs {
  box-shadow: var(--pl-elev-1);
}

.pl-node:hover {
  box-shadow: var(--pl-elev-2);
}

.pl-gallery-card:hover {
  box-shadow: var(--pl-elev-2);
}

.pl-topbar,
.pl-tryon-bar,
.pl-nudge,
.pl-tour-tip {
  box-shadow: var(--pl-elev-2);
}

.pl-save-gate,
.pl-inspector,
.pl-wiz-confirm {
  box-shadow: var(--pl-elev-3);
}

/* ── 3. GLOW: primary CTAs, selected picture-node ring, recommended     */
/*    chips; hover-lift with reduced-motion guards ─────────────────────── */

.pl-btn,
.pl-make-btn {
  box-shadow: var(--pl-btn-shadow), var(--pl-cta-glow);
}

.pl-btn:hover,
.pl-make-btn:hover {
  box-shadow: var(--pl-btn-shadow-hover), var(--pl-cta-glow-hover);
}

.pl-btn-green,
.pl-wiz-generate-btn {
  box-shadow: var(--pl-btn-green-shadow), var(--pl-cta-glow-green);
}

.pl-btn-green:hover,
.pl-wiz-generate-btn:hover {
  box-shadow: var(--pl-btn-green-shadow-hover), var(--pl-cta-glow-green-hover);
  transform: translateY(-1px);
}

/* pl-make-btn's own glow-pulse keyframes (main.css) alternate box-shadow
   between --pl-btn-shadow and --pl-btn-shadow-hover; re-declaring the same
   keyframe name here (last in cascade) folds the CTA glow into each pulse
   step instead of fighting the running animation. */
@keyframes pl-make-glow {
  0%,
  100% {
    box-shadow: var(--pl-btn-shadow), var(--pl-cta-glow);
  }
  50% {
    box-shadow: var(--pl-btn-shadow-hover), var(--pl-cta-glow-hover);
  }
}

/* Selected picture-node — layered ring (solid + soft outer) + elevation glow */
.pl-pic-node.pl-node-sel {
  box-shadow: 0 0 0 2px var(--pl-sky),
    0 0 0 6px color-mix(in srgb, var(--pl-sky) 22%, transparent), var(--pl-elev-2);
}

.pl-pic-node.pl-node-sel:hover {
  box-shadow: 0 0 0 2px var(--pl-sky),
    0 0 0 7px color-mix(in srgb, var(--pl-sky) 28%, transparent), var(--pl-elev-3);
}

/* Recommended chips / cards / badge — ambient glow, not a full CTA throw */
.pl-wiz-chip-rec,
.pl-wiz-opt-rec,
.pl-rb {
  box-shadow: var(--pl-rec-glow);
}

.pl-wiz-chip-sel.pl-wiz-chip-rec {
  box-shadow: none;
}

/* Hover-lift for the interactive chip/tab families that only transitioned
   color/border before — small lift + shadow step, matches the CTA anatomy */
.pl-wiz-chip,
.pl-wiz-opt,
.pl-area-tab {
  transition: border-color 120ms, background 120ms, color 120ms, transform 150ms ease,
    box-shadow 150ms ease;
}

.pl-wiz-chip:hover,
.pl-wiz-opt:hover,
.pl-area-tab:hover {
  transform: translateY(-1px);
  box-shadow: var(--pl-elev-1);
}

.pl-wiz-chip-sel:hover,
.pl-wiz-opt-sel:hover {
  box-shadow: var(--pl-elev-1), 0 0 0 1px var(--pl-blue) inset;
}

@media (prefers-reduced-motion: reduce) {
  .pl-btn,
  .pl-btn-green,
  .pl-make-btn,
  .pl-wiz-generate-btn,
  .pl-wiz-chip,
  .pl-wiz-opt,
  .pl-area-tab,
  .pl-node,
  .pl-gallery-card {
    transition: none;
  }

  .pl-make-btn {
    animation: none;
  }
}

/* ── 4. DISPLAY TYPE: view titles, wizard title, decision question,     */
/*    gallery hero heading — marketing serif, tightened tracking ──────── */

.pl-wiz-title,
.pl-gallery-title,
.pl-dq,
.pl-wiz-q,
.pl-fig-head h2 {
  font-family: var(--font-display);
  letter-spacing: -0.01em;
  text-wrap: balance;
}

/* ── 5. Gradient hairlines: 1px color-mix borders on hero cards ────────── */

.pl-gallery-card-sel {
  border: 2px solid transparent;
  border-image: linear-gradient(
      135deg,
      var(--pl-sky),
      var(--pl-blue),
      color-mix(in srgb, var(--pl-green) 55%, var(--pl-blue))
    )
    1;
}

.pl-node-site {
  border: 1px solid transparent;
  border-image: linear-gradient(
      135deg,
      color-mix(in srgb, var(--pl-blue) 75%, var(--pl-sky)),
      color-mix(in srgb, var(--pl-sky) 60%, transparent)
    )
    1;
}

/* ── Premium micro-interaction layer ─────────────────────────────────────
   1. Cursor-tracked glow-border ring (fx.rs writes --pl-mx/--pl-my)
   2. Slide-up accent overlay on gallery cards + wizard options
   3. Dynamic shadow elevation (rest -> hover/focus-visible -> active)
   4. Neo-brutalist "stamp" treatment, scoped to status chips only
   Tokens only — no literal colors added beyond var(--pl-ink, #hex)-style
   fallbacks for a token that doesn't exist yet. No width/height/display
   edits on any existing element; `position: relative` / `isolation` /
   `overflow: hidden` are added only where a ::before/::after overlay
   requires them as a containing/stacking box, and never move an element
   out of normal flow. */

/* ── 1. Glow-border cursor tracking ──────────────────────────────────────
   fx.rs attaches one delegated `pointermove` listener on `document` and
   writes --pl-mx / --pl-my (px, relative to the hovered element's own box)
   inline, coalesced to one write per animation frame. This paints a thin
   accent-tinted ring that follows the cursor, using the padding-box /
   border-box double-mask trick so only a ~1.5px band along the border
   reads — never a filled glow. `--nt-accent` (set inline by gallery cards
   from the plan's accent color) wins when present; every other tracked
   element falls back to --pl-blue. */

.pl-pic-node,
.pl-gallery-card,
.pl-wiz-opt,
.pl-opt {
  position: relative;
}

.pl-pic-node::after,
.pl-gallery-card::after,
.pl-wiz-opt::after,
.pl-opt::after {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: inherit;
  padding: 1.5px;
  opacity: 0;
  pointer-events: none;
  background: radial-gradient(
    140px circle at var(--pl-mx, 50%) var(--pl-my, 50%),
    color-mix(in srgb, var(--nt-accent, var(--pl-blue)) 70%, transparent) 0%,
    transparent 68%
  );
  -webkit-mask: linear-gradient(#fff 0 0) content-box, linear-gradient(#fff 0 0);
  -webkit-mask-composite: xor;
  mask: linear-gradient(#fff 0 0) content-box, linear-gradient(#fff 0 0);
  mask-composite: exclude;
  transition: opacity 200ms ease;
}

.pl-pic-node:hover::after,
.pl-pic-node:focus-visible::after,
.pl-gallery-card:hover::after,
.pl-gallery-card:focus-visible::after,
.pl-wiz-opt:hover::after,
.pl-wiz-opt:focus-visible::after,
.pl-opt:hover::after,
.pl-opt:focus-visible::after {
  opacity: 1;
}

/* Light theme: deeper, more saturated ring. */
.pl-app:not([data-pl-theme="dark"]) .pl-pic-node::after,
.pl-app:not([data-pl-theme="dark"]) .pl-gallery-card::after,
.pl-app:not([data-pl-theme="dark"]) .pl-wiz-opt::after,
.pl-app:not([data-pl-theme="dark"]) .pl-opt::after {
  background: radial-gradient(
    140px circle at var(--pl-mx, 50%) var(--pl-my, 50%),
    color-mix(in srgb, var(--nt-accent, var(--pl-blue)) 85%, black 8%) 0%,
    transparent 65%
  );
}

/* Dark theme: luminous rather than saturated — brighter, soft-glowing. */
.pl-app[data-pl-theme="dark"] .pl-pic-node::after,
.pl-app[data-pl-theme="dark"] .pl-gallery-card::after,
.pl-app[data-pl-theme="dark"] .pl-wiz-opt::after,
.pl-app[data-pl-theme="dark"] .pl-opt::after {
  background: radial-gradient(
    160px circle at var(--pl-mx, 50%) var(--pl-my, 50%),
    color-mix(in srgb, var(--nt-accent, var(--pl-blue)) 85%, white 15%) 0%,
    transparent 70%
  );
  filter: drop-shadow(
    0 0 5px color-mix(in srgb, var(--nt-accent, var(--pl-blue)) 55%, transparent)
  );
}

@media (prefers-reduced-motion: reduce) {
  .pl-pic-node::after,
  .pl-gallery-card::after,
  .pl-wiz-opt::after,
  .pl-opt::after {
    transition: none;
  }
}

/* ── 2. Slide-up overlay hover — gallery cards + wizard options ─────────
   A very low-alpha accent fill rises from the bottom edge on hover or
   keyboard focus-within. `isolation: isolate` gives each card its own
   stacking context so the overlay's negative z-index reliably paints
   behind that card's own text/image content (and nothing else's) without
   touching the z-index of anything the card doesn't own. */

.pl-gallery-card,
.pl-wiz-opt {
  overflow: hidden;
  isolation: isolate;
}

.pl-gallery-card::before,
.pl-wiz-opt::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  border-radius: inherit;
  background: linear-gradient(
    0deg,
    color-mix(in srgb, var(--nt-accent, var(--th-accent, var(--pl-blue))) 14%, transparent) 0%,
    transparent 65%
  );
  transform: translateY(100%);
  transition: transform 220ms ease-out;
  pointer-events: none;
}

.pl-gallery-card:hover::before,
.pl-gallery-card:focus-within::before,
.pl-wiz-opt:hover::before,
.pl-wiz-opt:focus-within::before {
  transform: translateY(0);
}

@media (prefers-reduced-motion: reduce) {
  .pl-gallery-card::before,
  .pl-wiz-opt::before {
    transform: none;
    opacity: 0;
    transition: opacity 220ms ease-out;
  }

  .pl-gallery-card:hover::before,
  .pl-gallery-card:focus-within::before,
  .pl-wiz-opt:hover::before,
  .pl-wiz-opt:focus-within::before {
    opacity: 1;
  }
}

/* ── 3. Dynamic shadow elevation ─────────────────────────────────────────
   Rest -> subtle card shadow (reuses --pl-shadow-card, the token already
   used everywhere else in this sheet). Hover/focus-visible -> lift + wider
   layered shadow + a faint accent glow; active settles halfway. 180ms ease
   throughout, a touch snappier than the 200-220ms glow/overlay above so
   the "physical" lift reads distinct from the ambient effects.

   `.pl-pic-node.pl-node-sel` already scales (main.css) and
   `.pl-gallery-card-sel` / `.pl-wiz-opt-sel` already carry their own ring
   box-shadow — every hover/active rule below is split into a plain variant
   and a `-sel` variant so this never clobbers those: the plain variant
   owns the transform, the `-sel` variant reuses the exact ring value from
   main.css and only appends the glow layer, leaving its own transform (or
   lack of one) untouched. */

.pl-opt,
.pl-wiz-opt:not(.pl-wiz-opt-sel) {
  box-shadow: var(--pl-shadow-card);
}

.pl-pic-node,
.pl-gallery-card,
.pl-opt,
.pl-wiz-opt {
  --pl-fx-glow: 0 0 24px -8px
    color-mix(in srgb, var(--nt-accent, var(--th-accent, var(--pl-blue))) 45%, transparent);
  transition: transform 180ms ease, box-shadow 180ms ease;
}

.pl-pic-node:hover:not(.pl-node-sel),
.pl-pic-node:focus-visible:not(.pl-node-sel) {
  transform: translateY(-4px);
  box-shadow: var(--pl-shadow-float), var(--pl-fx-glow);
}

.pl-pic-node.pl-node-sel:hover,
.pl-pic-node.pl-node-sel:focus-visible {
  /* transform intentionally untouched — keeps main.css's scale(1.035). */
  box-shadow: 0 0 0 1px var(--pl-sky), var(--pl-shadow-float), var(--pl-fx-glow);
}

.pl-pic-node:active:not(.pl-node-sel) {
  transform: translateY(-1px);
}

.pl-pic-node.pl-node-sel:active {
  transform: scale(1.035) translateY(-1px);
}

.pl-gallery-card:hover,
.pl-gallery-card:focus-visible {
  transform: translateY(-4px);
  box-shadow: var(--pl-shadow-float), var(--pl-fx-glow);
}

.pl-gallery-card-sel:hover,
.pl-gallery-card-sel:focus-visible {
  transform: translateY(-4px);
  box-shadow: 0 0 0 1px color-mix(in srgb, var(--th-accent, var(--pl-sky)) 60%, transparent),
    var(--pl-shadow-float), var(--pl-fx-glow);
}

.pl-gallery-card:active {
  transform: translateY(-1px);
}

.pl-opt:hover,
.pl-opt:focus-visible {
  transform: translateY(-4px);
  box-shadow: var(--pl-shadow-float), var(--pl-fx-glow);
}

.pl-opt:active {
  transform: translateY(-1px);
}

.pl-wiz-opt:hover:not(.pl-wiz-opt-sel),
.pl-wiz-opt:focus-visible:not(.pl-wiz-opt-sel) {
  transform: translateY(-4px);
  box-shadow: var(--pl-shadow-float), var(--pl-fx-glow);
}

.pl-wiz-opt-sel:hover,
.pl-wiz-opt-sel:focus-visible {
  transform: translateY(-4px);
  box-shadow: 0 0 0 1px var(--pl-blue) inset, var(--pl-shadow-float), var(--pl-fx-glow);
}

.pl-wiz-opt:active {
  transform: translateY(-1px);
}

@media (prefers-reduced-motion: reduce) {
  .pl-pic-node,
  .pl-gallery-card,
  .pl-opt,
  .pl-wiz-opt {
    transition: box-shadow 180ms ease;
  }

  .pl-pic-node:hover:not(.pl-node-sel),
  .pl-pic-node:focus-visible:not(.pl-node-sel),
  .pl-pic-node:active:not(.pl-node-sel),
  .pl-pic-node.pl-node-sel:active,
  .pl-gallery-card:hover,
  .pl-gallery-card:focus-visible,
  .pl-gallery-card:active,
  .pl-gallery-card-sel:hover,
  .pl-gallery-card-sel:focus-visible,
  .pl-opt:hover,
  .pl-opt:focus-visible,
  .pl-opt:active,
  .pl-wiz-opt:hover:not(.pl-wiz-opt-sel),
  .pl-wiz-opt:focus-visible:not(.pl-wiz-opt-sel),
  .pl-wiz-opt:active,
  .pl-wiz-opt-sel:hover,
  .pl-wiz-opt-sel:focus-visible {
    transform: none;
  }
}

/* ── 4. Status / kind chips: planner glass + logo hues ─────────────────
   One family for figure-head, map badges, notes, setup, review, wizard
   recommended, credit/note chrome. Translucent fill, saturate blur, 1px
   rim, soft glow. Purpose is hue-only (sky / green / navy). Type is logo
   ink/cream (--pl-text). No offset shadow, no sheen. Amber/violet/red
   are not in the mark — queued/warn/request map to sky. */

.pl-chip,
.pl-kchip,
.pl-schip,
.pl-rb,
.pl-wiz-badge,
.pl-credit-chip,
.pl-note-chip,
.pl-chip-feature,
.pl-chip-role,
.pl-chip-perm,
.pl-fig-head .pl-chip,
.pl-badges .pl-chip {
  --pl-chip-hue: var(--pl-sky);
  padding: 3px 8px;
  border-radius: 6px;
  font-family: var(--font-mono);
  font-size: 8.5px;
  font-weight: 600;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  background: color-mix(in srgb, var(--pl-chip-hue) 16%, var(--pl-glass-bg));
  backdrop-filter: blur(10px) saturate(1.3);
  -webkit-backdrop-filter: blur(10px) saturate(1.3);
  border: 1px solid color-mix(in srgb, var(--pl-chip-hue) 42%, var(--pl-glass-border));
  box-shadow: inset 0 1px 0 color-mix(in srgb, #ffffff 55%, transparent),
    0 0 14px -6px color-mix(in srgb, var(--pl-chip-hue) 40%, transparent);
  color: var(--pl-text);
  transition: box-shadow 150ms ease, border-color 150ms ease;
}

/* Map caption chips live under `.pl-node` (`.pl-pic-node`). `.pl-node .pl-chip`
   (display:inline-block + margin-top:7px) is 0,2,0 and used to beat the glass
   `.pl-chip` shell — that's why map cards kept the old stamp layout after
   figure-head went glass. `.pl-badges .pl-chip` is also 0,2,0 and later, so
   status rows get glass; journey-step ribbons are NOT inside `.pl-badges`. */
.pl-badges .pl-chip {
  display: inline-flex;
  margin-top: 0;
}

.pl-fig-head .pl-badges {
  margin-top: 6px;
}

.pl-credit-chip,
.pl-note-chip {
  padding: 6px 10px;
  font-size: 11px;
  letter-spacing: 0;
  text-transform: none;
  font-weight: 500;
}

@supports not ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
  .pl-chip,
  .pl-kchip,
  .pl-schip,
  .pl-rb,
  .pl-wiz-badge,
  .pl-credit-chip,
  .pl-note-chip,
  .pl-chip-feature,
  .pl-chip-role,
  .pl-chip-perm,
  .pl-fig-head .pl-chip,
  .pl-badges .pl-chip {
    background: color-mix(in srgb, var(--pl-chip-hue) 16%, var(--pl-panel-2));
  }
}

/* Sky — in-progress / ask / queued / warn (amber is not a logo hue). */
.pl-chip-draft,
.pl-chip-queued,
.pl-chip-request,
.pl-chip-decision,
.pl-chip-perm,
.pl-k-change,
.pl-k-question,
.pl-k-request,
.pl-k-decide,
.pl-k-permission,
.pl-s-open,
.pl-s-queued,
.pl-chip-feature,
.pl-chip-role,
.pl-setup-chip-progress {
  --pl-chip-hue: var(--pl-sky);
}

/* Green — lock / ready / applied / recommended. */
.pl-chip-lock,
.pl-chip-ai,
.pl-k-approve,
.pl-s-applied,
.pl-rb,
.pl-wiz-badge,
.pl-setup-chip-done {
  --pl-chip-hue: var(--pl-green);
}

/* Navy — later / empty / quiet / deny. */
.pl-chip-later,
.pl-chip-nomock,
.pl-k-logic,
.pl-k-reject,
.pl-s-saved,
.pl-setup-chip-notstarted,
.pl-setup-chip-later,
.pl-credit-chip,
.pl-note-chip {
  --pl-chip-hue: var(--pl-navy, #0b1f3a);
}

.pl-chip-request,
.pl-k-request {
  border-style: dashed;
}

.pl-node-ghost {
  border: 1px dashed color-mix(in srgb, var(--pl-sky) 55%, var(--pl-border));
  background: color-mix(in srgb, var(--pl-sky) 8%, var(--pl-glass-bg));
  box-shadow: inset 0 1px 0 color-mix(in srgb, #ffffff 40%, transparent);
}

.pl-chip-journey-step {
  --pl-chip-hue: var(--pl-green);
  padding: 3px 8px;
  border-radius: 6px;
  font-family: var(--font-mono);
  font-size: 8.5px;
  font-weight: 600;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  color: #e6eef9;
  background: color-mix(in srgb, var(--pl-green) 55%, var(--pl-navy, #0b1f3a));
  backdrop-filter: blur(10px) saturate(1.3);
  -webkit-backdrop-filter: blur(10px) saturate(1.3);
  border: 1px solid color-mix(in srgb, var(--pl-green) 50%, transparent);
  box-shadow: inset 0 1px 0 color-mix(in srgb, #ffffff 28%, transparent),
    0 0 12px -4px color-mix(in srgb, var(--pl-green) 45%, transparent);
}

.pl-chip-journey-step-alert {
  --pl-chip-hue: var(--pl-sky);
  background: color-mix(in srgb, var(--pl-sky) 55%, var(--pl-navy, #0b1f3a));
  border-color: color-mix(in srgb, var(--pl-sky) 50%, transparent);
  box-shadow: inset 0 1px 0 color-mix(in srgb, #ffffff 28%, transparent),
    0 0 12px -4px color-mix(in srgb, var(--pl-sky) 45%, transparent);
}

.pl-chip.pl-journey-toggle {
  padding: 4px 12px;
  min-height: 32px;
  border-radius: 999px;
  font-family: var(--font-sans);
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0;
  text-transform: none;
}

.pl-app[data-pl-theme="dark"] .pl-chip,
.pl-app[data-pl-theme="dark"] .pl-kchip,
.pl-app[data-pl-theme="dark"] .pl-schip,
.pl-app[data-pl-theme="dark"] .pl-rb,
.pl-app[data-pl-theme="dark"] .pl-wiz-badge,
.pl-app[data-pl-theme="dark"] .pl-credit-chip,
.pl-app[data-pl-theme="dark"] .pl-note-chip {
  box-shadow: inset 0 1px 0 color-mix(in srgb, #ffffff 14%, transparent),
    0 0 16px -6px color-mix(in srgb, var(--pl-chip-hue) 45%, transparent);
}

@media (prefers-reduced-motion: reduce) {
  .pl-chip,
  .pl-kchip,
  .pl-schip,
  .pl-rb,
  .pl-wiz-badge,
  .pl-credit-chip,
  .pl-note-chip,
  .pl-chip-journey-step,
  .pl-fig-head .pl-chip,
  .pl-badges .pl-chip {
    transition: none;
  }
}

/* ── fx.rs mount guard ────────────────────────────────────────────────── */
.pl-fx[hidden] {
  display: none !important;
}

/* ─────────────────────────────────────────────────────────────────────────
   D3pth Planner — chart edges v2. The lines themselves (layered glow +
   gradient core stroke), the beads riding them, and the endpoint "sockets"
   are all Canvas2D draws in map_view.rs — nothing here changes layout, the
   canvas element, or its stacking. This sheet only echoes that canvas
   socket glow onto the one DOM element an edge also touches: the ◉ flow
   handle (`.pl-flow-handle--socket`, applied alongside the existing
   `.pl-flow-handle` class map_view.rs already owns) — so the handle a
   reviewer drags reads as the same lit socket the line plugs into.
   Tokens only (--pl-*); light is the .pl-app default, dark comes free via
   the .pl-app[data-pl-theme="dark"] token re-declarations upstream.
   ───────────────────────────────────────────────────────────────────────── */

/* Ambient glow ring behind the handle dot, matching the canvas-drawn
   sockets at each edge endpoint. Absolute, centered on the handle's own
   14px dot via the same anchor the base rule uses — purely decorative, no
   box-size or layout change to the 44px hit target. */
.pl-app .pl-flow-handle--socket::after {
  content: "";
  position: absolute;
  top: 50%;
  left: 50%;
  width: 26px;
  height: 26px;
  border-radius: 50%;
  transform: translate(-50%, -50%) scale(0.85);
  background: radial-gradient(
    circle,
    color-mix(in srgb, var(--pl-blue) 55%, transparent) 0%,
    transparent 70%
  );
  opacity: 0;
  pointer-events: none;
  transition: opacity 180ms ease, transform 180ms ease;
  z-index: -1;
}

.pl-app .pl-flow-handle--socket:hover::after,
.pl-app .pl-flow-handle--socket:focus-visible::after,
.pl-app .pl-flow-handle--socket:active::after {
  opacity: 1;
  transform: translate(-50%, -50%) scale(1);
}

.pl-app .pl-flow-handle--socket:focus-visible {
  outline: 2px solid var(--pl-blue);
  outline-offset: 3px;
  border-radius: 50%;
}

@media (prefers-reduced-motion: reduce) {
  .pl-app .pl-flow-handle--socket::after {
    transition: none;
  }
}

/* Layer reconciliation: card-grid's 380px dock floor was written before
   wizard-v2 landed and out-prioritizes its 34dvh phone cap (min-height
   beats max-height). Below the MID boundary the wizard author's cap is
   the intent — the preview docks small, the options own the screen. */
@media (max-width: 980px) {
  .pl-wiz-shell .pl-wiz-stage-dock {
    min-height: 0;
  }
}

/* chart-roots.css — "front door" affordance for each area cluster's root
   page card (map_view.rs: PlannerMapView clusters).

   The chart's business/site picture-node is gone; every surface's FIRST
   page card (its homepage — Home / Dashboard / My jobs / My quotes) is now
   the area's entry point and the root that hierarchy edges fan out from
   (map_view.rs `run_map_edges`). map_view.rs marks that card with the
   `.pl-node-root` class (alongside its usual `.pl-node.pl-pic-node`
   classes); this file is the only thing that gives it a visual "front
   door" tell — a persistent ring one notch stronger than the ambient
   cursor-tracking glow every card already gets on hover/focus
   (`.pl-pic-node::after` in main.css).

   Deliberately uses `::before` + the padding/mask-exclude "ring band"
   trick (same technique as `.pl-pic-node::after`) instead of `box-shadow`:
   `.pl-node-sel` (selection) and the hover/active states already own
   `box-shadow` on this element in main.css, and box-shadow doesn't
   compose across separate rules — the last one wins outright, not layers.
   A root card can be selected at the same time as being the front door, so
   the root ring lives on its own pseudo-element/property instead of
   fighting that cascade. Colored with `--nt-accent` (the plan's own accent,
   already set inline per card) falling back to `--pl-blue`, same token
   convention as every other per-card accent use in main.css — never a new
   one-off color. Both themes: the light/dark split mirrors the
   `.pl-app[data-pl-theme="dark"]` pattern used everywhere else in this
   sheet (this app toggles an explicit attribute, not
   prefers-color-scheme). */

.pl-pic-node.pl-node-root {
  position: relative;
}

.pl-pic-node.pl-node-root::before {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: inherit;
  padding: 2px;
  pointer-events: none;
  background: linear-gradient(
    135deg,
    color-mix(in srgb, var(--nt-accent, var(--pl-blue)) 90%, transparent) 0%,
    color-mix(in srgb, var(--nt-accent, var(--pl-blue)) 40%, transparent) 100%
  );
  -webkit-mask: linear-gradient(#fff 0 0) content-box, linear-gradient(#fff 0 0);
  -webkit-mask-composite: xor;
  mask: linear-gradient(#fff 0 0) content-box, linear-gradient(#fff 0 0);
  mask-composite: exclude;
  filter: drop-shadow(
    0 0 5px color-mix(in srgb, var(--nt-accent, var(--pl-blue)) 45%, transparent)
  );
}

/* Light theme: a touch deeper/more saturated, matching the light-theme
   bump `.pl-pic-node::after` already applies on hover. */
.pl-app:not([data-pl-theme="dark"]) .pl-pic-node.pl-node-root::before {
  background: linear-gradient(
    135deg,
    color-mix(in srgb, var(--nt-accent, var(--pl-blue)) 92%, black 6%) 0%,
    color-mix(in srgb, var(--nt-accent, var(--pl-blue)) 45%, black 6%) 100%
  );
}

/* Dark theme: luminous rather than saturated, plus a slightly wider band —
   same relationship `.pl-pic-node::after` has to its light-theme sibling. */
.pl-app[data-pl-theme="dark"] .pl-pic-node.pl-node-root::before {
  padding: 2.25px;
  background: linear-gradient(
    135deg,
    color-mix(in srgb, var(--nt-accent, var(--pl-blue)) 92%, white 12%) 0%,
    color-mix(in srgb, var(--nt-accent, var(--pl-blue)) 45%, white 12%) 100%
  );
  filter: drop-shadow(
    0 0 7px color-mix(in srgb, var(--nt-accent, var(--pl-blue)) 55%, transparent)
  );
}

@media (prefers-reduced-motion: reduce) {
  .pl-pic-node.pl-node-root::before {
    filter: none;
  }
}

/* ── L0 "Your sites" overview (overview.rs) ──────────────────────────────
   Card grid: 1 col NAR (<=640px), 2 col MID (641-980px), 4 col WIDE
   (>=1180px) — 3 breakpoints per docs/PLANNER_LAYOUT.md, no others.
   Glass + elevation consistent with the premium layer: reuses --pl-elev-*
   / --pl-glass-* tokens when defined, falls back to plain shadows/tints
   otherwise so this sheet never hard-depends on load order.
   Peek modal: backdrop z-index 79 / modal z-index 80 per the layout
   contract's z-scale. Tokens only, [hidden] guards, 44px touch targets,
   prefers-reduced-motion respected throughout. */

.pl-overview {
  display: flex;
  flex-direction: column;
  gap: var(--spacing-lg, 1.5rem);
  padding: var(--spacing-lg, 1.5rem);
}

/* ── Card grid ───────────────────────────────────────────────────────── */

.pl-site-grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--spacing-md, 1rem);
  list-style: none;
  margin: 0;
  padding: 0;
}

@media (min-width: 641px) and (max-width: 980px) {
  .pl-site-grid {
    grid-template-columns: repeat(2, 1fr);
  }
}

@media (min-width: 1180px) {
  .pl-site-grid {
    grid-template-columns: repeat(4, 1fr);
  }
}

/* ── Card shell ──────────────────────────────────────────────────────── */

.pl-site-card {
  display: flex;
  flex-direction: column;
  border-radius: var(--radius-card, 0.75rem);
  background: var(--pl-glass-bg, var(--bg-raised, #fff));
  border: 1px solid var(--pl-glass-border, var(--border, rgba(15, 23, 42, 0.1)));
  box-shadow: var(--pl-elev-1, 0 1px 2px rgba(15, 23, 42, 0.06), 0 6px 16px -6px rgba(15, 23, 42, 0.12));
  overflow: hidden;
  transition: box-shadow 0.18s ease, transform 0.18s ease;
}

.pl-site-card:hover,
.pl-site-card:focus-within {
  box-shadow: var(--pl-elev-2, 0 2px 6px -1px rgba(15, 23, 42, 0.1), 0 16px 36px -10px rgba(15, 23, 42, 0.18));
  transform: translateY(-2px);
}

@media (prefers-reduced-motion: reduce) {
  .pl-site-card {
    transition: none;
  }
  .pl-site-card:hover,
  .pl-site-card:focus-within {
    transform: none;
  }
}

.pl-site-card-thumb {
  position: relative;
}

/* 8/5 face — reuses the shared pl-pic-face sheet for the img/placeholder
   internals; this sets only the card-local aspect ratio. */
.pl-site-thumb {
  display: block;
  width: 100%;
  aspect-ratio: 8 / 5;
}

.pl-site-lock {
  position: absolute;
  top: 0.5rem;
  right: 0.5rem;
  z-index: 10; /* Raised band — sits above the card's Base thumb face. */
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 1.75rem;
  height: 1.75rem;
  border-radius: 999px;
  background: var(--pl-modal-backdrop, rgba(15, 23, 42, 0.55));
  color: #fff;
  font-size: 0.9rem;
  line-height: 1;
}

.pl-site-card-body {
  display: flex;
  flex-direction: column;
  gap: 0.4rem;
  padding: 1rem;
}

.pl-site-card-title {
  margin: 0;
  font-size: 1.05rem;
  font-weight: 700;
  /* color: var(--text-primary) intentionally removed here — undefined
     Next-era token, always shadowed anyway by the doubled-selector
     override in fix2-overview.css (main.css, "1) Theme-token override"
     below), which is the sole source of this rule's color from now on. */
}

.pl-site-card-job {
  margin: 0;
  font-size: 0.9rem;
  /* color: var(--text-secondary) intentionally removed — see
     .pl-site-card-title above; same fix2-overview.css override applies. */
}

.pl-site-card-desc {
  margin: 0;
  font-size: 0.82rem;
  /* color: var(--text-tertiary) intentionally removed — see
     .pl-site-card-title above; same fix2-overview.css override applies. */
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

.pl-site-card-chips {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 6px;
  margin: 0;
}

.pl-chip-feature,
.pl-chip-role {
  background: color-mix(in srgb, var(--pl-blue, #3b82f6) 12%, transparent);
  border-color: color-mix(in srgb, var(--pl-blue, #3b82f6) 35%, transparent);
}

.pl-site-entry-hint {
  margin: 0.1rem 0 0;
  font-size: 0.78rem;
  font-style: italic;
  /* color: var(--text-tertiary) intentionally removed — see
     .pl-site-card-title above; same fix2-overview.css override applies. */
}

.pl-site-card-actions {
  display: flex;
  gap: 0.5rem;
  margin-top: 0.5rem;
}

.pl-site-open-btn,
.pl-site-peek-btn {
  min-height: 44px;
  flex: 1;
}

.pl-site-peek-btn {
  flex: 0 0 auto;
}

.pl-overview-foot {
  display: flex;
  justify-content: center;
  padding-top: 0.25rem;
}

.pl-see-map-btn {
  min-height: 44px;
}

/* ── Dark theme ──────────────────────────────────────────────────────── */

[data-pl-theme="dark"] .pl-site-card {
  background: var(--pl-glass-bg, rgba(15, 23, 42, 0.6));
  border-color: var(--pl-glass-border, rgba(255, 255, 255, 0.08));
  box-shadow: var(--pl-elev-1, 0 1px 2px rgba(0, 0, 0, 0.35), 0 8px 20px -8px rgba(0, 0, 0, 0.45));
}

[data-pl-theme="dark"] .pl-site-card:hover,
[data-pl-theme="dark"] .pl-site-card:focus-within {
  box-shadow: var(--pl-elev-2, 0 2px 6px -1px rgba(0, 0, 0, 0.4), 0 20px 44px -12px rgba(0, 0, 0, 0.55));
}

/* ═════════════════════════════════════════════════════════════════════════
   sitescope.css — L1 scoping for the plan map (map_view.rs)

   OWNER: map_view.rs agent. Tokens only (var(--pl-*)), [hidden] guards,
   44px touch targets, reduced-motion respected. Exactly the 3 layout-
   contract breakpoints (NAR ≤640 / MID 641-980 / WIDE 1180+) — see
   docs/PLANNER_LAYOUT.md. Nothing here touches classes owned by other
   scratch files (card-grid.css, chart-roots.css, picturenodes.css, …);
   every selector below is new (pl-chart-label-row, pl-doorway-rail,
   pl-doorway-chip, pl-chart-cluster-grid--scoped, pl-map-fullmap-link,
   pl-map-fullback-pill) or a scoped override of an existing one, applied
   only under those new selectors.
   ═════════════════════════════════════════════════════════════════════════ */

/* ── Chart heading row: title + "see everything" link ────────────────── */

.pl-chart-label-row {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 8px 14px;
  margin-bottom: 14px;
}

/* The label already carries margin-bottom:14px from main.css when it was
   the row itself — now it's a row child, so that margin would double up
   with the row's own gap/margin above. Zero it here, scoped to the row. */
.pl-chart-label-row .pl-chart-label {
  margin-bottom: 0;
}

.pl-map-fullmap-link {
  flex-shrink: 0;
  min-height: 32px;
  padding: 4px 10px;
  font-size: 12px;
  border-radius: 999px;
}

.pl-map-fullmap-link[hidden] {
  display: none !important;
}

/* ── Doorway rail: other surfaces, compact, inside the chart stage ──── */

.pl-doorway-rail {
  /* Base pl-area-tabs already supplies the glass pill-row chrome; this
     only trims it down for its new home inside pl-chart-field, above the
     scoped cluster, and gives it its own bottom margin instead of relying
     on pl-chart-field's row gap (which also separates it from the grid
     below at the same width). */
  width: 100%;
  max-width: 100%;
  justify-content: center;
  margin: 0 0 4px;
  padding: 5px;
  gap: 5px;
}

.pl-doorway-rail[hidden] {
  display: none !important;
}

.pl-doorway-chip {
  min-height: 44px;
  padding: 6px 12px;
  font-size: 12px;
  opacity: 0.88;
}

.pl-doorway-chip:hover {
  opacity: 1;
}

/* Doorway chips are never "pressed" (aria-pressed is always false — the
   scoped surface itself never appears here) but still need a visibly
   different resting look from a full-map tab so the rail doesn't read as
   another filter row. Slightly dimmer border + no pressed glow ever
   applies since aria-pressed=false always wins the base .pl-area-tab
   rule's default state already; nothing further to override there. */

/* ── Scoped-mode cluster grid: bigger cards, more breathing room ───────
   Homepage sits on its own row (`.pl-page-cell-root` spans every column);
   child pages fan out underneath. `--pl-tree-cols` is set per cluster
   from the child count so a 2-page portal is one centered child, not a
   stretched auto-fill grid. Same tree is used in full-map (without the
   --scoped size bump). */

.pl-chart-clusters.pl-chart-clusters {
  display: grid;
  grid-template-columns: 1fr;
  align-items: start;
  justify-content: stretch;
  gap: 28px;
  width: 100%;
}

@media (min-width: 1180px) {
  .pl-chart-clusters--full.pl-chart-clusters--full {
    grid-template-columns: 1fr 1fr;
    gap: 36px 32px;
  }
}

.pl-chart-cluster.pl-chart-cluster {
  flex: none;
  width: 100%;
  min-width: 0;
  max-width: 100%;
  gap: 16px;
  padding: 16px 16px 18px;
  border-radius: 14px;
  border: 1px solid color-mix(in srgb, var(--pl-border) 90%, transparent);
}

.pl-chart-cluster .pl-chart-cluster-cap {
  justify-content: center;
  font-size: 11px;
  letter-spacing: 0.08em;
}

.pl-chart-cluster-grid.pl-chart-cluster-grid {
  display: grid;
  grid-template-columns: repeat(var(--pl-tree-cols, 3), minmax(132px, 1fr));
  justify-content: center;
  justify-items: center;
  align-items: start;
  column-gap: 18px;
  row-gap: 52px;
  width: 100%;
  margin: 0;
  padding: 8px 0 4px;
  list-style: none;
}

.pl-chart-cluster-grid .pl-page-cell-root {
  grid-column: 1 / -1;
  justify-content: center;
}

.pl-chart-cluster-grid .pl-page-cell-root .pl-pic-node {
  width: 196px;
  min-width: 160px;
  max-width: min(220px, 100%);
}

.pl-chart-cluster-grid--scoped {
  grid-template-columns: repeat(var(--pl-tree-cols, 3), minmax(160px, 1fr));
  column-gap: 22px;
  row-gap: 64px;
}

.pl-chart-cluster-grid--scoped .pl-page-cell {
  justify-content: center;
}

.pl-app .pl-chart-cluster-grid--scoped .pl-pic-node {
  width: 188px;
  min-width: 0;
  max-width: 220px;
}

.pl-app .pl-chart-cluster-grid--scoped .pl-page-cell-root .pl-pic-node {
  width: 240px;
  max-width: 280px;
}

.pl-chart-add {
  align-self: center;
}

/* ── Full-map exit pill (floating-bar z-band 40, per PLANNER_LAYOUT.md) ──
   bottom: 76px, not 20px: .pl-copilot-launcher (copilot.rs) is a
   persistent, always-mounted floating bar pinned to the SAME corner
   (right: 20px, bottom: 20px, min-height: 44px, same z-band 40 — see
   main.css's copilot section). A shared bottom:20px put this pill's whole
   44px-tall hit area directly under the launcher's, which paints later in
   document order and wins the shared stacking context, so the launcher
   silently ate every click meant for this pill. This pill is the
   contextual one (full-map view only) so it steps aside: 20 (launcher's
   bottom) + 44 (launcher's height) + 12 (clearance) = 76, stacking above
   the launcher instead of moving the persistent, always-visible one. ── */

.pl-map-fullback-pill {
  position: fixed;
  right: 16px;
  bottom: 76px;
  z-index: 40;
  display: flex;
  align-items: center;
  gap: 6px;
  min-height: 44px;
  padding: 10px 16px;
  border-radius: 999px;
  background: var(--pl-glass-bg);
  border: 1px solid var(--pl-glass-border);
  color: var(--pl-text);
  font-size: 13px;
  font-weight: 600;
  box-shadow: var(--pl-shadow-float, var(--pl-glass-shadow));
  -webkit-backdrop-filter: blur(16px) saturate(1.3);
  backdrop-filter: blur(16px) saturate(1.3);
  cursor: pointer;
}

.pl-map-fullback-pill[hidden] {
  display: none !important;
}

.pl-map-fullback-pill:hover {
  border-color: color-mix(in srgb, var(--pl-sky) 45%, var(--pl-glass-border));
}

.pl-map-fullback-pill:focus-visible {
  outline: 2px solid var(--pl-sky);
  outline-offset: 2px;
}

@supports not ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
  .pl-map-fullback-pill {
    background: var(--pl-panel-2);
  }
}

/* ═════════════════════════════════════════════════════════════════════════
   NAR — max-width: 640px
   ═════════════════════════════════════════════════════════════════════════ */

@media (max-width: 640px) {
  .pl-chart-label-row {
    flex-direction: column;
    align-items: flex-start;
    gap: 6px;
  }

  .pl-doorway-rail {
    flex-wrap: nowrap;
    overflow-x: auto;
    justify-content: flex-start;
    -webkit-overflow-scrolling: touch;
    scrollbar-width: none;
  }

  .pl-doorway-rail::-webkit-scrollbar {
    display: none;
  }

  .pl-doorway-chip {
    flex: 0 0 auto;
    white-space: nowrap;
  }

  .pl-chart-cluster-grid--scoped {
    grid-template-columns: repeat(var(--pl-tree-cols, 2), minmax(0, 1fr));
    column-gap: 12px;
    row-gap: 40px;
  }

  .pl-chart-cluster-grid.pl-chart-cluster-grid {
    grid-template-columns: repeat(var(--pl-tree-cols, 2), minmax(0, 1fr));
    column-gap: 12px;
    row-gap: 40px;
  }

  .pl-app .pl-chart-cluster-grid--scoped .pl-pic-node,
  .pl-app .pl-chart-cluster-grid--scoped .pl-page-cell-root .pl-pic-node,
  .pl-chart-cluster-grid .pl-page-cell-root .pl-pic-node {
    width: min(160px, 100%);
    max-width: 100%;
  }

  .pl-map-fullback-pill {
    right: 12px;
    /* Same launcher-clearance reasoning as the base rule above, just
       tighter: .pl-copilot-launcher has no NAR override (stays right:
       20px/bottom: 20px/44px tall), so 20 + 44 + 8 = 72. */
    bottom: 72px;
    padding: 9px 14px;
    font-size: 12px;
  }
}

/* ═════════════════════════════════════════════════════════════════════════
   MID — min-width: 641px and max-width: 980px
   ═════════════════════════════════════════════════════════════════════════ */

@media (min-width: 641px) and (max-width: 980px) {
  .pl-chart-cluster-grid--scoped {
    grid-template-columns: repeat(var(--pl-tree-cols, 3), minmax(148px, 1fr));
    column-gap: 16px;
    row-gap: 52px;
  }
}

/* ═════════════════════════════════════════════════════════════════════════
   WIDE — min-width: 1180px
   ═════════════════════════════════════════════════════════════════════════ */

@media (min-width: 1180px) {
  .pl-chart-cluster-grid--scoped {
    grid-template-columns: repeat(var(--pl-tree-cols, 3), minmax(168px, 1fr));
    column-gap: 24px;
    row-gap: 72px;
  }

  .pl-doorway-rail {
    max-width: 760px;
    margin-left: auto;
    margin-right: auto;
  }
}

/* ── Reduced motion ────────────────────────────────────────────────────── */

@media (prefers-reduced-motion: reduce) {
  .pl-doorway-chip,
  .pl-map-fullmap-link,
  .pl-map-fullback-pill {
    transition: none !important;
  }
}

/* ─────────────────────────────────────────────────────────────────────────
   drawer.css — Saved-changes drawer (PlannerDrawer, detail_view.rs) +
   the "Save for later" control that appears on every AI suggestion surface
   (decision recommendations, apply-with-AI on a composed note).

   Layout contract: docs/PLANNER_LAYOUT.md
     - Breakpoints: NAR ≤640px, MID 641–980px, WIDE ≥1180px.
     - Z-bands: backdrop 79, drawer sheet 80 (Modal band) — same band as
       .pl-inspector / .pl-save-gate, never above Toast (90).
     - Modal scroll rule: header + footer pinned, body is the only scroll
       container. NAR collapses the sheet to a full-width bottom sheet
       (explicitly called for over the usual full-viewport modal, since the
       drawer is a running list the reviewer dips in and out of, not a
       one-shot form).
   Tokens only — every color/spacing/shadow below is a --pl-* custom
   property or an existing --radius-* token already defined in main.css's
   :root / [data-pl-theme="dark"] blocks; nothing is invented here.
   ───────────────────────────────────────────────────────────────────────── */

/* ═══ Save-for-later control (lives inline in detail_view's composer/notes/
   decision panels, not inside the drawer sheet itself) ═══════════════════ */

.pl-save-later-btn {
  border-color: var(--pl-border);
  background: var(--pl-panel-2);
  color: var(--pl-muted);
  white-space: nowrap;
}

.pl-save-later-btn:hover,
.pl-save-later-btn:focus-visible {
  color: var(--pl-text);
  border-color: var(--pl-blue);
}

/* New status-chip variant: "saved" (the existing sheet only ever styled
   open/applied). Muted/neutral — a saved change hasn't cost anything yet,
   so it shouldn't compete visually with "applied". */
.pl-schip.pl-s-saved {
  background: color-mix(in srgb, var(--pl-faint) var(--pl-chip-bg-mix), transparent);
  border-color: color-mix(in srgb, var(--pl-faint) var(--pl-chip-border-mix), transparent);
  color: var(--pl-muted);
}

/* ═══ Drawer shell ══════════════════════════════════════════════════════ */

.pl-drawer-overlay {
  position: fixed;
  inset: 0;
  z-index: 79; /* z-scale: modal backdrop band */
  background: var(--pl-modal-backdrop);
}

.pl-drawer-overlay[hidden] {
  display: none;
}

.pl-drawer {
  position: fixed;
  top: 0;
  right: 0;
  z-index: 80; /* z-scale: modal band */
  display: flex;
  flex-direction: column;
  width: min(400px, 100vw);
  max-height: 100dvh;
  background: var(--pl-panel-1);
  border-left: 1px solid var(--pl-border);
  box-shadow: var(--pl-modal-shadow);
}

.pl-drawer[hidden] {
  display: none;
}

.pl-drawer-head {
  flex-shrink: 0;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.75rem;
  padding: 1rem 1.25rem;
  border-bottom: 1px solid var(--pl-border);
}

.pl-drawer-head h2 {
  margin: 0;
  font-size: 1.05rem;
  font-weight: 700;
  color: var(--pl-text);
}

.pl-drawer-close {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 44px; /* NAR touch target min */
  height: 44px;
  border: none;
  background: transparent;
  color: var(--pl-muted);
  font-size: 1.1rem;
  cursor: pointer;
  border-radius: var(--radius-card);
}

.pl-drawer-close:hover,
.pl-drawer-close:focus-visible {
  color: var(--pl-text);
  background: var(--pl-panel-2);
}

.pl-drawer > .pl-toast {
  flex-shrink: 0;
  margin: 0.5rem 1.25rem 0;
}

.pl-drawer-body {
  flex: 1 1 auto;
  overflow-y: auto; /* modal scroll rule: body is the only scroll container */
  padding: 1rem 1.25rem;
  display: flex;
  flex-direction: column;
  gap: 0.75rem;
}

.pl-drawer-divider {
  margin: 0.25rem 0 0;
  padding-top: 0.75rem;
  border-top: 1px dashed var(--pl-border);
  font-size: 0.8rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--pl-faint);
}

.pl-drawer-list {
  display: flex;
  flex-direction: column;
  gap: 0.65rem;
  margin: 0;
  padding: 0;
  list-style: none;
}

.pl-drawer-item {
  display: flex;
  flex-direction: column;
  gap: 0.4rem;
  padding: 0.75rem;
  border: 1px solid var(--pl-border);
  border-radius: var(--radius-card);
  background: var(--pl-panel-2);
}

.pl-drawer-item-head {
  display: flex;
  align-items: center;
  gap: 0.4rem;
  flex-wrap: wrap;
}

.pl-drawer-item-page {
  font-size: 0.72rem;
  color: var(--pl-faint);
  font-family: ui-monospace, "SF Mono", Menlo, monospace;
}

.pl-drawer-item-title {
  margin: 0;
  font-weight: 600;
  color: var(--pl-text);
  font-size: 0.92rem;
}

.pl-drawer-item-detail {
  margin: 0;
  color: var(--pl-muted);
  font-size: 0.85rem;
  line-height: 1.4;
  /* Wide/long saved text scrolls inside its own box rather than pushing the
     drawer wider or overflowing the viewport (layout contract: wide
     content scrolls in its own container, never the body/page). */
  max-height: 4.6em;
  overflow-y: auto;
}

.pl-drawer-item-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.5rem;
  flex-wrap: wrap;
}

.pl-drawer-item-cost {
  font-size: 0.78rem;
  font-weight: 600;
  color: var(--pl-blue);
}

.pl-drawer-item-actions {
  display: flex;
  gap: 0.4rem;
}

.pl-drawer-foot {
  flex-shrink: 0;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.75rem;
  padding: 0.9rem 1.25rem;
  border-top: 1px solid var(--pl-border);
  background: var(--pl-panel-1);
}

.pl-drawer-total {
  font-size: 0.9rem;
  font-weight: 600;
  color: var(--pl-text);
}

/* ═══ MID (641–980px): drawer becomes an inset floating panel, not edge-
   pinned full-height — matches the inspector's own MID treatment. ═══════ */
@media (min-width: 641px) and (max-width: 980px) {
  .pl-drawer {
    top: 12px;
    right: 12px;
    bottom: 12px;
    max-height: calc(100dvh - 24px);
    width: min(360px, calc(100vw - 24px));
    border-radius: var(--radius-card);
    border: 1px solid var(--pl-border);
  }
}

/* ═══ NAR (≤640px): full-width bottom sheet, not a fullscreen takeover —
   the drawer is a running list the reviewer dips into, so leaving the
   mockup peeking above it keeps context. ═══════════════════════════════ */
@media (max-width: 640px) {
  .pl-drawer {
    top: auto;
    left: 0;
    right: 0;
    bottom: 0;
    width: 100%;
    max-height: 80dvh;
    border-left: none;
    border-top: 1px solid var(--pl-border);
    border-radius: var(--radius-card) var(--radius-card) 0 0;
  }

  .pl-drawer-foot {
    padding-bottom: max(0.9rem, env(safe-area-inset-bottom));
  }

  .pl-drawer-item-actions button,
  .pl-drawer-close,
  .pl-save-later-btn {
    min-height: 44px; /* touch target min */
  }
}

@media (prefers-reduced-motion: reduce) {
  .pl-drawer,
  .pl-drawer-overlay {
    transition: none;
  }
}

/* ─────────────────────────────────────────────────────────────────────────
   wizard-other.css — "Other…" free-text affordance for wizard.rs.

   Scope: modifiers ONLY, layered on the existing .pl-wiz-opt / .pl-wiz-chip /
   .pl-wiz-toggle-row base rules already in wizard-v2.css (this file never
   redefines their layout/sizing — just the dashed "add your own" treatment
   and the inline text input beneath each grid/row/chiprow). Tokens only,
   doubled selectors for append-order independence, 44px targets inherited
   from the base classes, reduced-motion respected via the shared
   transition durations already in wizard-v2.css (no new animation here).

   Markup: other_opt_card/other_chip/other_toggle_row + other_input() in
   crates/d3pth-web/src/planner/wizard.rs (business-type step's own
   "Something else" card was the precedent; those cards stay untouched).
   ───────────────────────────────────────────────────────────────────────── */

.pl-wiz-opt-other.pl-wiz-opt-other,
.pl-wiz-chip-other.pl-wiz-chip-other,
.pl-wiz-toggle-other.pl-wiz-toggle-other {
  border-style: dashed;
  border-color: var(--pl-border);
  background: transparent;
  color: var(--pl-muted);
}

.pl-wiz-opt-other.pl-wiz-opt-other:hover,
.pl-wiz-chip-other.pl-wiz-chip-other:hover,
.pl-wiz-toggle-other.pl-wiz-toggle-other:hover {
  border-color: var(--pl-blue);
  color: var(--pl-text);
}

.pl-wiz-opt-other.pl-wiz-opt-other .pl-wiz-opt-label,
.pl-wiz-chip-other.pl-wiz-chip-other,
.pl-wiz-toggle-other.pl-wiz-toggle-other .pl-wiz-toggle-label {
  font-weight: 600;
}

/* Active/selected "Other…" trigger: solid border, no fill, so it reads as
   "expanded" rather than "chosen" (the text typed below is the real choice). */
.pl-wiz-opt-other.pl-wiz-opt-other.pl-wiz-opt-sel,
.pl-wiz-toggle-other.pl-wiz-toggle-other.pl-wiz-toggle-on {
  border-style: solid;
  border-color: var(--pl-blue);
  background: color-mix(in srgb, var(--pl-blue) 6%, var(--pl-panel-2));
  color: var(--pl-text);
  box-shadow: none;
}

.pl-wiz-chip-other.pl-wiz-chip-other.pl-wiz-chip-sel {
  border-style: solid;
  border-color: var(--pl-blue);
  background: transparent;
  color: var(--pl-blue);
}

.pl-wiz-toggle-other.pl-wiz-toggle-other .pl-wiz-toggle-box {
  border-style: dashed;
}

/* Inline free-text input revealed under the grid/chiprow/togglelist. Reuses
   .pl-wiz-input sizing (44px min-height, same radius/border/padding) — this
   rule only adds the top gap so it doesn't touch the options above it. */
.pl-wiz-other-input.pl-wiz-other-input {
  margin-top: 8px;
}

@media (prefers-reduced-motion: reduce) {
  .pl-wiz-opt-other.pl-wiz-opt-other,
  .pl-wiz-chip-other.pl-wiz-chip-other,
  .pl-wiz-toggle-other.pl-wiz-toggle-other {
    transition: none;
  }
}

/* ── Breadcrumb header — the bar says WHERE you are. Left: mark + crumb
   trail + context tool chips. Right: status cluster + one primary CTA.
   Replaces the mode-tab row; old .pl-tabs rules are inert (class gone). */
.pl-topbar-crumbs {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  flex-wrap: wrap;
}

.pl-crumb-zone {
  display: flex;
  align-items: center;
  gap: 10px;
  min-width: 0;
  flex: 1 1 auto;
}

.pl-planner-mark {
  font-weight: 700;
  letter-spacing: -0.01em;
  white-space: nowrap;
  color: var(--pl-text-1, inherit);
}

.pl-planner-mark-sub {
  font-weight: 500;
  opacity: 0.55;
}

.pl-crumbs {
  display: flex;
  align-items: center;
  gap: 4px;
  min-width: 0;
  overflow-x: auto;
  scrollbar-width: none;
}

.pl-crumbs::-webkit-scrollbar {
  display: none;
}

.pl-crumb {
  border: 0;
  background: transparent;
  font: inherit;
  font-size: 14px;
  padding: 8px 10px;
  min-height: 44px;
  border-radius: 9px;
  cursor: pointer;
  white-space: nowrap;
  color: var(--pl-text-2, inherit);
}

.pl-crumb:hover {
  background: color-mix(in srgb, var(--pl-blue) 8%, transparent);
}

.pl-crumb:focus-visible {
  outline: 2px solid var(--pl-blue);
  outline-offset: 2px;
}

.pl-crumb[aria-current="true"] {
  color: var(--pl-text-1, inherit);
  font-weight: 650;
  cursor: default;
}

.pl-crumb[aria-current="true"]:hover {
  background: transparent;
}

.pl-crumb-sep {
  opacity: 0.35;
  user-select: none;
}

.pl-crumb-tools {
  display: flex;
  gap: 6px;
  padding-left: 8px;
  border-left: 1px solid var(--pl-border);
}

.pl-crumb-tool {
  border: 1px solid var(--pl-border);
  background: transparent;
  font: inherit;
  font-size: 12.5px;
  padding: 6px 10px;
  min-height: 34px;
  border-radius: 999px;
  cursor: pointer;
  white-space: nowrap;
  color: var(--pl-text-2, inherit);
}

.pl-crumb-tool:hover {
  border-color: var(--pl-blue);
  color: var(--pl-text-1, inherit);
}

.pl-crumb-tool:focus-visible {
  outline: 2px solid var(--pl-blue);
  outline-offset: 2px;
}

.pl-icon-btn {
  min-width: 44px;
  padding-left: 0;
  padding-right: 0;
  text-align: center;
}

.pl-drawer-chip {
  font-variant-numeric: tabular-nums;
}

.pl-crumbs .pl-crumb[hidden],
.pl-crumb-sep[hidden],
.pl-crumb-tools[hidden],
.pl-drawer-chip[hidden] {
  display: none !important;
}

@media (max-width: 980px) {
  .pl-crumb-zone {
    flex: 1 1 100%;
  }
  .pl-top-right {
    flex: 1 1 100%;
    justify-content: flex-end;
  }
}

@media (max-width: 640px) {
  .pl-planner-mark {
    display: none;
  }
  .pl-crumb-tools {
    display: none;
  }
  .pl-top-right > * {
    flex: 1 1 auto;
    min-height: 44px;
  }
  .pl-make-btn,
  .pl-build-btn {
    flex: 1 1 100%;
  }
}

/* ─────────────────────────────────────────────────────────────────────────
   saves.css — "My saved templates" picker (PlannerSaves, saves.rs).

   Layout contract: docs/PLANNER_LAYOUT.md
     - Breakpoints: NAR ≤640px, MID 641–980px, WIDE ≥1180px.
     - Z-bands: backdrop 79, dialog 80 (Modal band) — same band as
       .pl-save-gate / .pl-drawer / .pl-inspector, never above Toast (90).
     - Modal scroll rule: head is pinned, .pl-saves-body is the only scroll
       container. NAR collapses the dialog to a full-screen sheet (per the
       worked example in the contract), MID/WIDE keep it a centered
       floating card sized off content, same treatment as .pl-save-gate.
   Tokens only — every color/spacing/shadow below is a --pl-* custom
   property or an existing --radius-* token already defined in main.css's
   :root / [data-pl-theme="dark"] blocks; nothing is invented here. Row
   kind chips are the one exception by design: each chip's tint comes from
   the template's own --nt-accent, set inline per row from
   `d3pth_core::planner::template(kind).accent` (the same value gallery.rs
   feeds its showcase cards) — cheap, already-canonical, no new token. ────*/

.pl-saves-overlay {
  position: fixed;
  inset: 0;
  z-index: 79; /* z-scale: modal backdrop band */
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--pl-modal-backdrop);
  padding: 16px;
}

.pl-saves-overlay[hidden] {
  display: none;
}

.pl-saves {
  position: relative;
  z-index: 80; /* z-scale: modal band */
  display: flex;
  flex-direction: column;
  width: min(480px, 100vw - 32px);
  max-height: calc(100dvh - 32px);
  background: var(--pl-panel-1);
  border: 1px solid var(--pl-border);
  border-radius: var(--radius-card);
  box-shadow: var(--pl-modal-shadow);
  outline: none;
}

.pl-saves-head {
  flex-shrink: 0;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.75rem;
  padding: 1rem 1.25rem;
  border-bottom: 1px solid var(--pl-border);
}

.pl-saves-head h2 {
  margin: 0;
  font-size: 1.05rem;
  font-weight: 700;
  color: var(--pl-text);
}

.pl-saves-close {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 44px; /* NAR touch target min */
  height: 44px;
  border: none;
  background: transparent;
  color: var(--pl-muted);
  font-size: 1.1rem;
  line-height: 1;
  cursor: pointer;
  border-radius: var(--radius-card);
}

.pl-saves-close:hover,
.pl-saves-close:focus-visible {
  color: var(--pl-text);
  background: var(--pl-panel-2);
}

.pl-saves-body {
  flex: 1 1 auto;
  overflow-y: auto; /* modal scroll rule: body is the only scroll container */
  padding: 1rem 1.25rem 1.25rem;
  display: flex;
  flex-direction: column;
  gap: 0.75rem;
}

/* ═══ Loading / empty / error states — calm, client-voiced, one line of
   copy plus (where relevant) a single way forward. ═════════════════════ */

.pl-saves-loading {
  margin: 0;
  padding: 1.5rem 0.25rem;
  text-align: center;
  color: var(--pl-muted);
  font-size: 0.9rem;
}

.pl-saves-empty,
.pl-saves-error {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 0.75rem;
  padding: 0.25rem;
}

.pl-saves-empty p,
.pl-saves-error p {
  margin: 0;
  color: var(--pl-muted);
  font-size: 0.9rem;
  line-height: 1.5;
}

.pl-saves-error p[role="alert"] {
  color: var(--pl-red);
}

/* ═══ Row list ═══════════════════════════════════════════════════════════ */

.pl-saves-list {
  display: flex;
  flex-direction: column;
  gap: 0.6rem;
  margin: 0;
  padding: 0;
  list-style: none;
}

.pl-saves-row {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 0.5rem 0.75rem;
  min-height: 44px; /* touch target min */
  padding: 0.65rem 0.85rem;
  border: 1px solid var(--pl-border);
  border-radius: var(--radius-card);
  background: var(--pl-panel-2);
}

.pl-saves-row-main {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  flex-wrap: wrap;
  flex: 1 1 auto;
  min-width: 0;
}

.pl-saves-name {
  font-weight: 600;
  color: var(--pl-text);
  font-size: 0.92rem;
  overflow-wrap: anywhere;
}

.pl-saves-chip {
  flex-shrink: 0;
  padding: 0.15rem 0.5rem;
  border-radius: 999px;
  font-size: 0.72rem;
  font-weight: 600;
  white-space: nowrap;
  color: var(--nt-accent, var(--pl-blue));
  background: color-mix(in srgb, var(--nt-accent, var(--pl-blue)) var(--pl-chip-bg-mix), transparent);
  border: 1px solid color-mix(in srgb, var(--nt-accent, var(--pl-blue)) var(--pl-chip-border-mix), transparent);
}

.pl-saves-row-meta {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  flex-wrap: wrap;
  flex: 1 1 auto;
  min-width: 0;
  font-size: 0.78rem;
  color: var(--pl-faint);
}

.pl-saves-company {
  overflow-wrap: anywhere;
}

.pl-saves-updated {
  white-space: nowrap;
}

.pl-saves-open-btn {
  flex-shrink: 0;
  margin-left: auto;
  min-height: 44px; /* touch target min */
}

/* ═══ NAR (≤640px): full-screen sheet, not a centered card — per the
   layout contract's worked modal example. ══════════════════════════════ */
@media (max-width: 640px) {
  .pl-saves-overlay {
    padding: 0;
  }

  .pl-saves {
    width: 100vw;
    max-height: 100dvh;
    height: 100dvh;
    border-radius: 0;
    border: none;
  }

  .pl-saves-head {
    position: sticky;
    top: 0;
  }

  .pl-saves-row {
    flex-direction: column;
    align-items: flex-start;
  }

  .pl-saves-open-btn {
    margin-left: 0;
    width: 100%;
  }
}

@media (prefers-reduced-motion: reduce) {
  .pl-saves,
  .pl-saves-overlay {
    transition: none;
  }
}

/* Save-gate account additions: version name input + save-as-new/update
   segmented control (save_gate.rs), and the resume banner's "See all your
   saved versions" button (resume.rs). Tokens only — see
   docs/PLANNER_LAYOUT.md. Orchestrator folds this into main.css. */

/* Version name field — same shape as .pl-save-email so the two stack
   cleanly in the form grid. */
.pl-save-name {
  width: 100%;
  min-height: 44px;
  padding: 12px;
  background: var(--pl-panel-1);
  border: 1px solid var(--pl-border);
  border-radius: 8px;
  color: var(--pl-text);
  font-family: var(--font-sans);
  font-size: 13px;
  box-sizing: border-box;
  transition: all 150ms;
}

.pl-save-name:focus {
  outline: none;
  border-color: var(--pl-blue);
  box-shadow: 0 0 0 2px color-mix(in srgb, var(--pl-blue) 20%, transparent);
}

.pl-save-name::placeholder {
  color: var(--pl-muted);
}

/* Update-vs-new segmented control */
.pl-save-mode {
  display: flex;
  gap: 6px;
  padding: 4px;
  background: var(--pl-block);
  border: 1px solid var(--pl-border);
  border-radius: 10px;
}

.pl-save-mode-btn {
  flex: 1 1 0;
  min-height: 44px;
  padding: 8px 10px;
  background: transparent;
  border: none;
  border-radius: 7px;
  color: var(--pl-muted);
  font-family: var(--font-sans);
  font-size: 12px;
  font-weight: 600;
  line-height: 1.3;
  cursor: pointer;
  transition: all 150ms;
  overflow-wrap: anywhere;
}

.pl-save-mode-btn:hover {
  color: var(--pl-text);
}

.pl-save-mode-btn.pl-save-mode-active {
  background: var(--pl-panel-1);
  color: var(--pl-text);
  box-shadow: var(--pl-shadow-card);
}

.pl-save-mode-btn:focus-visible {
  outline: none;
  box-shadow: 0 0 0 2px color-mix(in srgb, var(--pl-blue) 40%, transparent);
}

@media (prefers-reduced-motion: reduce) {
  .pl-save-name,
  .pl-save-mode-btn {
    transition: none;
  }
}

/* "See all your saved versions" — sits in the welcome-back banner between
   the message and the dismiss control; ghost styling so it doesn't compete
   with the primary CTA elsewhere on the page. */
.pl-resume-saves-btn {
  min-height: 44px;
  padding: 0 14px;
  background: transparent;
  border: 1px solid var(--pl-border);
  border-radius: 8px;
  color: var(--pl-text);
  font-family: var(--font-sans);
  font-size: 12px;
  font-weight: 600;
  white-space: nowrap;
  cursor: pointer;
  transition: all 150ms;
}

.pl-resume-saves-btn:hover {
  border-color: var(--pl-blue);
  color: var(--pl-blue);
}

.pl-resume-saves-btn:focus-visible {
  outline: none;
  box-shadow: 0 0 0 2px color-mix(in srgb, var(--pl-blue) 40%, transparent);
}

@media (prefers-reduced-motion: reduce) {
  .pl-resume-saves-btn {
    transition: none;
  }
}

/* Narrow viewports (<640px): stack the segmented control's labels don't
   need special-casing (flex + overflow-wrap already wraps them), but the
   resume banner goes column so the new button doesn't crowd the dismiss X. */
@media (max-width: 640px) {
  .pl-resume-banner {
    flex-wrap: wrap;
  }

  .pl-resume-saves-btn {
    order: 1;
    flex: 1 1 auto;
  }
}

/* Saves picker: every phase block gets display via class rules, which beat
   the hidden attribute — the recurring trap. One guard covers all of them,
   and future pl-saves-* additions inherit it. */
.pl-saves-overlay [hidden],
.pl-saves-loading[hidden],
.pl-saves-empty[hidden],
.pl-saves-error[hidden],
.pl-saves-list[hidden] {
  display: none !important;
}

/* ── Overview card consistency: every card body is the same column of
   rows (title / job / desc / chips / access line / actions), and the
   action row is pinned to the bottom so the four "Open this site"
   buttons share one baseline no matter how the text or chips wrap. ── */
.pl-site-card.pl-site-card {
  display: flex;
  flex-direction: column;
  /* Visible so the Open-area hero-dot rail (inset -6px) is not clipped
     against the card edge. The thumb still clips itself. */
  overflow: visible;
}

.pl-site-card .pl-site-card-thumb {
  overflow: hidden;
  border-radius: var(--radius-card, 0.75rem) var(--radius-card, 0.75rem) 0 0;
}

.pl-site-card .pl-site-card-body {
  display: flex;
  flex-direction: column;
  flex: 1 1 auto;
  min-height: 0;
  gap: 8px;
  padding: 1rem 1rem 1.15rem;
}

.pl-site-card .pl-site-card-title,
.pl-site-card .pl-site-card-job,
.pl-site-card .pl-site-card-desc,
.pl-site-card .pl-site-card-chips,
.pl-site-card .pl-site-entry-hint {
  margin: 0;
}

/* Job line is the row that absorbs length differences — reserve two
   lines so a one-line job doesn't let its card sit taller content up. */
.pl-site-card .pl-site-card-job {
  min-height: 2.6em;
}

.pl-site-card .pl-site-card-chips {
  align-content: flex-start;
  /* One compact metric row — every card reserves the same height so
     wrapping never used to (Portal + pending) no longer pushes the
     Open-this-area buttons off a shared baseline. */
  min-height: 28px;
}

.pl-site-card .pl-site-entry-hint {
  font-size: 12.5px;
  font-style: normal;
  opacity: 0.72;
}

.pl-site-card .pl-site-card-actions {
  display: grid;
  grid-template-columns: 1fr;
  align-items: stretch;
  gap: 8px;
  margin-top: auto;
  padding-top: 12px;
}

.pl-site-card .pl-site-open-btn,
.pl-site-card .pl-site-peek-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  min-width: 0;
  min-height: 44px;
  flex: none;
  padding: 8px 12px;
  white-space: nowrap;
  text-align: center;
  box-sizing: border-box;
  line-height: 1.2;
}

/* Buttons that are disabled must read disabled — the drawer's Apply all
   kept its full green while inert. */
.pl-app .pl-btn:disabled,
.pl-app .pl-make-btn:disabled {
  opacity: 0.45;
  cursor: not-allowed;
  box-shadow: none;
  transform: none;
}

/* ═════════════════════════════════════════════════════════════════════════
   fix2-tour-gallery.css — planner/tour.rs + planner/gallery.rs

   OWNER: tour+gallery agent. Tokens only (var(--pl-*)), [hidden] guards,
   44px touch targets, reduced-motion respected. Doubled selectors
   (.pl-x.pl-x) so this wins regardless of stylesheet append order relative
   to main.css and other concurrent scratch/*.css files, per the card-grid
   .css convention (main.css:16605-16621).

   Scope of this file:
     1) Gallery-card thumb loaded-polarity fix (gallery.rs `thumb_img`,
        confirmed bug #4 above). The <img> now carries a real `loaded`
        class (on:load + mount-time `complete() && natural_width() > 0`
        check, mirroring map_view.rs's `picture_face`), so hide-the-
        wireframe must key off THAT instead of "image present and not
        (yet) flagged missing" — the old rule hid the CSS-only wireframe
        primitives (thumb_children()) the instant the <img> mounted, even
        before it had actually loaded, so a slow/offline image showed
        nothing for a beat instead of the honest wireframe.

   Dead-rule ledger for the orchestrator (safe to delete from main.css once
   this sheet is merged — fully superseded, nothing else references the old
   polarity):
     - main.css:6536-6539
         [comment: an opaque loaded image owns the thumb — primitives never
         bleed through]  (CSS comments cannot nest — quoting the original
         rule's own comment markers here closed THIS comment early and
         killed parsing for every rule after this block; markers removed.)
         .pl-gallery-thumb:has(.pl-nt-img:not(.pl-nt-img-missing)) > :not(.pl-nt-img),
         .pl-node-thumb:has(.pl-nt-img:not(.pl-nt-img-missing)) > :not(.pl-nt-img) {
           visibility: hidden;
         }
       — replaced by the `.pl-nt-img-loaded`-keyed rule below. (Note:
       `.pl-node-thumb` has no matching markup anywhere under
       crates/d3pth-web/src/planner/*.rs as of this pass — that half of the
       old rule is already dead code; kept here only for parity in case a
       future node-thumb face reuses `.pl-nt-img`.)
     - main.css:6544-6547's `.pl-gallery-thumb:has(.pl-nt-img-missing) …
       { visibility: visible; }` is UNCHANGED and still correct — not part
       of this ledger, left in place.
   ════════════════════════════════════════════════════════════════════ */

/* ── 1) Gallery-card thumb: hide wireframe only once the image is
   CONFIRMED loaded, not merely "not yet confirmed missing". ───────────── */

.pl-gallery-thumb.pl-gallery-thumb:has(.pl-nt-img-loaded) > :not(.pl-nt-img),
.pl-node-thumb.pl-node-thumb:has(.pl-nt-img-loaded) > :not(.pl-nt-img) {
  visibility: hidden;
}

/* ═════════════════════════════════════════════════════════════════════════
   fix2-overview.css — planner/overview.rs (L0 "Your sites")

   OWNER: overview.rs agent. Tokens only (var(--pl-*)), [hidden] guards,
   44px touch targets, reduced-motion respected. 3 layout-contract
   breakpoints (NAR ≤640 / MID 641-980 / WIDE 1180+) — docs/PLANNER_LAYOUT.md.
   Z-bands: peek backdrop 79 / peek modal 80 (Modal band), same as
   .pl-save-gate / .pl-drawer / .pl-inspector, never above Toast (90).

   Scope of this file:
     1) Theme-token override for .pl-site-card-title/-job/-desc/-entry-hint
        — main.css:17738-17783 reference undefined Next-era tokens
        (var(--text-primary/-secondary/-tertiary, <light-gray fallback>)),
        which resolve to nothing and fall back to a hardcoded light-theme
        gray, so dark overview text was unreadable. Fixed here by
        overriding those selectors from real --pl-text/--pl-muted/--pl-faint
        tokens (defined for both themes at main.css:2923-2925 / :2986-2988),
        using doubled-selector specificity so the override wins regardless
        of stylesheet load order — no !important needed. Area-card
        metrics (`.pl-site-stat`) live in this same block so they don't
        inherit the map/detail neo-brutalist chip stamps.
     2) Full peek-modal styling under .pl-ov-peek-* — overview.rs's peek
        modal used to share .pl-peek-overlay/.pl-peek-modal/.pl-peek-*
        class names with style_studio.rs's row peek pop-outs (two
        different components, colliding styles). The modal markup in
        overview.rs now uses .pl-ov-peek-* everywhere; this is that
        component's complete styling (ported from the now-dead
        main.css:17812-17936 block, which targeted the old shared names
        and also carried the same undefined-token bug — see dead-rule
        ledger below).
     3) Mobile reachability (main.css:18668, NAR 640px block): that block
        `display:none`s .pl-crumb-tools, making "Style studio" and
        "Change template" unreachable on phones. Restored here as a
        horizontally-scrollable row of its own under the crumbs, 44px
        targets, instead of hidden. Also bumps .pl-crumb-tool min-height
        to 44px globally (was 34px — confirmed hit-area finding).

   Dead-rule ledger for the orchestrator (safe to delete from main.css —
   fully superseded by this file, nothing else references the old names):
     - main.css:17812-17936  .pl-peek-overlay / .pl-peek-modal /
       .pl-peek-close / .pl-peek-title / .pl-peek-section / .pl-peek-heading
       / .pl-peek-pages / .pl-peek-page-row / .pl-peek-page-id /
       .pl-peek-page-title / .pl-peek-page-status / .pl-peek-features,
       .pl-peek-roles / .pl-peek-empty / the [data-pl-theme="dark"]
       .pl-peek-modal rule directly below it — orphaned now that
       overview.rs markup uses .pl-ov-peek-*; style_studio.rs's identically
       named classes are a DIFFERENT component and must keep their own
       rules (do not delete those).
   ════════════════════════════════════════════════════════════════════ */

/* ── 1) Theme-token override: site-card text + pages/notes chips ───────── */

.pl-site-card-title.pl-site-card-title {
  color: var(--pl-text);
}

.pl-site-card-job.pl-site-card-job {
  color: var(--pl-muted);
}

.pl-site-card-desc.pl-site-card-desc {
  color: var(--pl-faint);
}

.pl-site-entry-hint.pl-site-entry-hint {
  color: var(--pl-faint);
}

/* Overview metric row — a quiet pill language of its own, not the
   neo-brutalist status stamps used on map/detail page cards. Number
   + noun, same height on every card; `.pl-site-stat-nav` is a real
   <button> that jumps into the plan. Doubled selectors so this wins
   over the generic `.pl-chip` + stamp rules if a leftover class
   collides. */
.pl-site-card .pl-site-stat.pl-site-stat {
  display: inline-flex;
  align-items: baseline;
  flex-shrink: 0;
  gap: 5px;
  margin: 0;
  padding: 4px 10px;
  min-height: 28px;
  border-radius: 999px;
  border: 1px solid color-mix(in srgb, var(--pl-muted) 28%, var(--pl-border));
  background: color-mix(in srgb, var(--pl-muted) 8%, var(--pl-panel-1));
  box-shadow: none;
  color: var(--pl-muted);
  font-family: var(--font-sans);
  font-size: 12px;
  font-weight: 500;
  letter-spacing: 0;
  line-height: 1.2;
  text-transform: none;
  white-space: nowrap;
  transform: none;
}

.pl-site-card .pl-site-stat .pl-site-stat-n {
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  color: var(--pl-text);
}

.pl-site-card .pl-site-stat .pl-site-stat-k {
  font-size: 11.5px;
  font-weight: 500;
  color: var(--pl-muted);
}

button.pl-site-stat {
  appearance: none;
  -webkit-appearance: none;
  cursor: pointer;
}

.pl-site-card .pl-site-stat-nav:hover {
  border-color: color-mix(in srgb, var(--pl-blue) 45%, var(--pl-border));
  background: color-mix(in srgb, var(--pl-blue) 8%, var(--pl-panel-1));
}

.pl-site-card .pl-site-stat-nav:focus-visible {
  outline: 2px solid var(--pl-blue);
  outline-offset: 2px;
}

.pl-site-card .pl-site-stat-pending.pl-site-stat-pending {
  border-color: color-mix(in srgb, var(--pl-amber) 55%, var(--pl-border));
  background: color-mix(in srgb, var(--pl-amber) 14%, var(--pl-panel-1));
}

.pl-site-card .pl-site-stat-pending .pl-site-stat-n,
.pl-site-card .pl-site-stat-pending .pl-site-stat-k {
  color: var(--pl-amber);
}

.pl-site-card .pl-site-stat-pending:hover {
  border-color: var(--pl-amber);
  background: color-mix(in srgb, var(--pl-amber) 20%, var(--pl-panel-1));
}

.pl-site-card .pl-site-stat-notes.pl-site-stat-nav {
  border-color: color-mix(in srgb, var(--pl-sky) 45%, var(--pl-border));
  background: color-mix(in srgb, var(--pl-sky) 10%, var(--pl-panel-1));
}

.pl-site-card .pl-site-stat-notes.pl-site-stat-nav .pl-site-stat-n,
.pl-site-card .pl-site-stat-notes.pl-site-stat-nav .pl-site-stat-k {
  color: var(--pl-sky);
}

.pl-site-card .pl-site-stat-notes.pl-site-stat-nav:hover {
  border-color: var(--pl-sky);
  background: color-mix(in srgb, var(--pl-sky) 16%, var(--pl-panel-1));
}

@media (prefers-reduced-motion: reduce) {
  .pl-site-card .pl-site-stat.pl-site-stat,
  .pl-site-card .pl-site-stat-nav:hover,
  .pl-site-card .pl-site-stat-pending:hover {
    transform: none;
  }
}

/* ── 2) Peek modal — .pl-ov-peek-* (own namespace, no collision) ───────── */

.pl-ov-peek-overlay {
  position: fixed;
  inset: 0;
  z-index: 79; /* Modal Backdrop band. */
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--pl-modal-backdrop);
  padding: 1rem;
}

.pl-ov-peek-overlay[hidden] {
  display: none;
}

.pl-ov-peek-modal {
  position: relative;
  z-index: 80; /* Modal band. */
  width: min(560px, 100vw - 2rem);
  max-height: calc(100dvh - 2rem);
  overflow-y: auto;
  border-radius: var(--radius-card);
  background: var(--pl-panel-1);
  box-shadow: var(--pl-modal-shadow);
  padding: 1.5rem;
  display: flex;
  flex-direction: column;
  gap: 1rem;
}

@media (max-width: 640px) {
  .pl-ov-peek-overlay {
    padding: 0;
  }
  .pl-ov-peek-modal {
    width: 100vw;
    max-height: 100dvh;
    border-radius: 0;
  }
}

.pl-ov-peek-close {
  position: absolute;
  top: 0.75rem;
  right: 0.75rem;
  width: 44px;
  height: 44px;
  border: none;
  background: transparent;
  font-size: 1rem;
  cursor: pointer;
  color: var(--pl-muted);
}

.pl-ov-peek-title {
  margin: 0 2rem 0 0;
  font-size: 1.15rem;
  font-weight: 700;
  color: var(--pl-text);
}

.pl-ov-peek-section {
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
}

.pl-ov-peek-heading {
  margin: 0;
  font-size: 0.75rem;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--pl-faint);
}

.pl-ov-peek-pages {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 0.35rem;
}

.pl-ov-peek-page-row {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 0.5rem;
  font-size: 0.85rem;
  color: var(--pl-text);
}

.pl-ov-peek-page-id {
  font-family: var(--font-mono);
  color: var(--pl-faint);
  flex: 0 0 auto;
}

.pl-ov-peek-page-title {
  flex: 1 1 auto;
}

.pl-ov-peek-page-status {
  flex: 1 1 auto;
  justify-content: flex-end;
}

.pl-ov-peek-features,
.pl-ov-peek-roles {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-wrap: wrap;
  gap: 0.35rem;
}

.pl-ov-peek-empty {
  margin: 0;
  font-size: 0.85rem;
  color: var(--pl-faint);
}

/* ── 3) Mobile reachability: crumb tools + touch targets ────────────────── */

.pl-crumb-tool.pl-crumb-tool {
  min-height: 44px;
}

@media (max-width: 640px) {
  .pl-crumb-zone.pl-crumb-zone {
    flex-wrap: wrap;
  }

  /* Own line under the crumbs, horizontally scrollable, instead of
     main.css:18668's display:none. */
  .pl-crumb-tools.pl-crumb-tools {
    display: flex;
    flex: 1 1 100%;
    order: 3;
    margin-top: 6px;
    padding-left: 0;
    border-left: 0;
    overflow-x: auto;
    scrollbar-width: none;
  }

  .pl-crumb-tools.pl-crumb-tools::-webkit-scrollbar {
    display: none;
  }

  .pl-crumb-tools.pl-crumb-tools .pl-crumb-tool {
    flex: 0 0 auto;
  }

  .pl-crumb-tools[hidden] {
    display: none !important;
  }
}

@media (prefers-reduced-motion: reduce) {
  .pl-ov-peek-modal {
    scroll-behavior: auto;
  }
}

/* ── Clickable containers: the whole card opens the thing. The click
   lives on the container in markup (with a buttons-handle-themselves
   guard) because the primary buttons' ::after pseudos are already owned
   by the premium glow layer — a stretched-button pseudo can't win that
   fight. These rules just carry the affordance. ─────────────────────── */
.pl-site-card.pl-site-card,
.pl-gallery-card.pl-gallery-card,
.pl-saves-list li {
  cursor: pointer;
}

/* ==========================================================================
   Draft autosave toast (persist.rs) + nav wrapper (nav.rs)
   Scratch stylesheet — orchestrator merges into main.css. Uses --pl-* tokens
   already defined in main.css's :root / [data-pl-theme="dark"] blocks.
   Both components are near-invisible chrome: `.pl-nav` never shows anything
   (pure history/keyboard wiring); `.pl-persist` reuses main.css's existing
   `.pl-toast` (fixed, bottom-right, toast z-band 90) and only adds its own
   internal row layout + a 44px dismiss button, same pattern as the resume
   banner's `.pl-resume-dismiss`. Breakpoints: NAR <=640, MID 641-980,
   WIDE >=1180.
   ========================================================================== */

/* ── Nav wrapper (nav.rs): always hidden, zero footprint ─────────────────── */

.pl-nav[hidden] {
  display: none !important;
}

/* ── Draft-restored toast (persist.rs) ────────────────────────────────────
   `.pl-toast` (main.css) already supplies position:fixed, panel chrome,
   and z-index:90 (toast band). This file only lays out its contents. */

.pl-draft-toast {
  display: flex;
  align-items: center;
  gap: 12px;
  max-width: min(360px, calc(100vw - 32px));
}

.pl-draft-toast[hidden] {
  display: none !important;
}

.pl-draft-toast-msg {
  margin: 0;
  flex: 1 1 auto;
  color: var(--pl-text);
  font-size: 13px;
  line-height: 1.4;
}

/* 44px minimum touch target, same spec as .pl-resume-dismiss */
.pl-draft-toast-dismiss {
  flex: 0 0 auto;
  min-width: 44px;
  min-height: 44px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border: none;
  border-radius: 10px;
  background: transparent;
  color: var(--pl-text);
  font-size: 14px;
  line-height: 1;
  cursor: pointer;
}

.pl-draft-toast-dismiss:hover {
  background: var(--pl-panel-2);
}

.pl-draft-toast-dismiss:focus-visible {
  outline: 2px solid var(--pl-blue);
  outline-offset: 2px;
}

@media (max-width: 640px) {
  .pl-draft-toast {
    max-width: calc(100vw - 24px);
  }
}

/* wave-versions.css — saves.rs's per-row ⋯ actions (rename / duplicate /
   delete), the "Compare versions" sheet, and save_gate.rs's share-link
   checkbox + copy row. Scratch file for orchestrator to fold into
   main.css — see docs/PLANNER_LAYOUT.md for the z-scale/breakpoint/token
   contract this follows.

   Tokens only — every color/spacing/shadow below is a --pl-* custom
   property or an existing --radius-* token already defined in main.css's
   :root / [data-pl-theme="dark"] blocks; nothing is invented here.

   [hidden] guard note: elements toggled with `hidden=` that live inside
   `.pl-saves-overlay` are ALREADY covered by main.css's existing
   `.pl-saves-overlay [hidden] { display: none !important; }` descendant
   rule (saves.css region) — no extra guard needed for pl-saves-row-confirm/
   -normal/-rename/-compare-check below. `.pl-compare-overlay` is a NEW
   top-level sibling outside that subtree, so it gets its own guard here. */

/* ═══ Row-level error banner (rename/duplicate/delete failures) ══════════ */

.pl-saves-row-error {
  margin: 0;
  padding: 0.6rem 0.75rem;
  border-radius: var(--radius-card);
  background: color-mix(in srgb, var(--pl-red) 10%, var(--pl-panel-1));
  border: 1px solid color-mix(in srgb, var(--pl-red) 30%, var(--pl-border));
  color: var(--pl-red);
  font-size: 0.82rem;
  line-height: 1.4;
}

/* ═══ Toolbar: "Compare" toggle + "Compare versions" trigger ═════════════ */

.pl-saves-toolbar {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  flex-wrap: wrap;
}

.pl-saves-compare-toggle {
  display: flex;
  align-items: center;
  gap: 0.4rem;
  min-height: 44px;
  color: var(--pl-muted);
  font-size: 0.85rem;
  font-weight: 600;
  cursor: pointer;
  user-select: none;
}

.pl-saves-compare-toggle input[type="checkbox"] {
  width: 18px;
  height: 18px;
  accent-color: var(--pl-blue);
}

/* ═══ Row restructuring: normal / delete-confirm / rename share the same
   flex slot inside .pl-saves-row, toggled via `hidden` (main.css's
   .pl-saves-overlay [hidden] guard already applies here). ══════════════ */

.pl-saves-row-normal {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 0.5rem 0.75rem;
  flex: 1 1 auto;
  min-width: 0;
  width: 100%;
}

.pl-saves-compare-check {
  flex-shrink: 0;
  width: 20px;
  height: 20px;
  min-width: 20px;
  accent-color: var(--pl-blue);
}

.pl-saves-row-actions {
  display: flex;
  align-items: center;
  gap: 0.4rem;
  flex-shrink: 0;
  margin-left: auto;
}

/* ═══ ⋯ menu ══════════════════════════════════════════════════════════ */

.pl-saves-row-menu {
  position: relative;
}

.pl-saves-menu-btn {
  min-width: 44px;
  min-height: 44px;
  padding: 0 0.5rem;
  font-size: 1.1rem;
  line-height: 1;
}

.pl-saves-menu-list {
  position: absolute;
  top: calc(100% + 4px);
  right: 0;
  z-index: 81; /* one above the modal band, within the saves modal's own stack */
  display: flex;
  flex-direction: column;
  min-width: 180px;
  padding: 0.35rem;
  background: var(--pl-panel-1);
  border: 1px solid var(--pl-border);
  border-radius: var(--radius-card);
  box-shadow: var(--pl-shadow-float);
}

.pl-saves-menu-item {
  display: block;
  width: 100%;
  min-height: 44px;
  padding: 0.5rem 0.6rem;
  text-align: left;
  background: transparent;
  border: none;
  border-radius: 6px;
  color: var(--pl-text);
  font-family: var(--font-sans);
  font-size: 0.85rem;
  cursor: pointer;
  transition: background 120ms;
}

.pl-saves-menu-item:hover,
.pl-saves-menu-item:focus-visible {
  background: var(--pl-panel-2);
  outline: none;
}

.pl-saves-menu-item-danger {
  color: var(--pl-red);
}

/* ═══ Delete confirm (in-row) ═════════════════════════════════════════ */

.pl-saves-row-confirm {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  justify-content: space-between;
  gap: 0.5rem 0.75rem;
  width: 100%;
}

.pl-saves-row-confirm p {
  margin: 0;
  flex: 1 1 200px;
  color: var(--pl-text);
  font-size: 0.85rem;
  line-height: 1.4;
}

.pl-saves-row-confirm-actions {
  display: flex;
  gap: 0.4rem;
  flex-shrink: 0;
}

.pl-btn-danger {
  background: var(--pl-red);
  color: #fff;
  border-color: var(--pl-red);
}

.pl-btn-danger:hover {
  background: color-mix(in srgb, var(--pl-red) 85%, black);
}

/* ═══ Rename (in-row) ═════════════════════════════════════════════════ */

.pl-saves-row-rename {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 0.5rem;
  width: 100%;
}

.pl-saves-rename-input {
  flex: 1 1 180px;
  min-height: 44px;
  padding: 0 0.65rem;
  background: var(--pl-panel-1);
  border: 1px solid var(--pl-border);
  border-radius: 8px;
  color: var(--pl-text);
  font-family: var(--font-sans);
  font-size: 0.85rem;
}

.pl-saves-rename-input:focus {
  outline: none;
  border-color: var(--pl-blue);
  box-shadow: 0 0 0 2px color-mix(in srgb, var(--pl-blue) 20%, transparent);
}

.pl-saves-row-rename-actions {
  display: flex;
  gap: 0.4rem;
  flex-shrink: 0;
}

/* ═══ Compare sheet — same modal band as .pl-saves, a sibling overlay so
   it can sit visually above the picker (later in DOM order at the same
   z-index wins the paint order). ══════════════════════════════════════ */

.pl-compare-overlay {
  position: fixed;
  inset: 0;
  z-index: 80; /* z-scale: modal band, above .pl-saves-overlay's backdrop */
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--pl-modal-backdrop);
  padding: 16px;
}

.pl-compare-overlay[hidden] {
  display: none !important;
}

.pl-compare {
  position: relative;
  z-index: 81;
  display: flex;
  flex-direction: column;
  width: min(520px, 100vw - 32px);
  max-height: calc(100dvh - 32px);
  background: var(--pl-panel-1);
  border: 1px solid var(--pl-border);
  border-radius: var(--radius-card);
  box-shadow: var(--pl-modal-shadow);
  outline: none;
}

.pl-compare-body {
  flex: 1 1 auto;
  overflow-y: auto;
  padding: 1rem 1.25rem 1.25rem;
}

.pl-compare-list {
  margin: 0;
  padding: 0 0 0 1.1rem;
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
  color: var(--pl-text);
  font-size: 0.85rem;
  line-height: 1.5;
}

.pl-compare-list li {
  overflow-wrap: anywhere;
}

/* ═══ save_gate.rs: share-link checkbox + copyable view link ═══════════ */

.pl-save-share {
  display: flex;
  align-items: center;
  gap: 0.4rem;
  min-height: 44px;
  color: var(--pl-muted);
  font-size: 0.85rem;
  cursor: pointer;
  user-select: none;
}

.pl-save-share input[type="checkbox"] {
  width: 18px;
  height: 18px;
  accent-color: var(--pl-blue);
}

.pl-save-view-link {
  display: flex;
  flex-direction: column;
  gap: 0.4rem;
  margin-top: 0.5rem;
  padding: 0.75rem;
  background: var(--pl-panel-2);
  border: 1px solid var(--pl-border);
  border-radius: var(--radius-card);
}

.pl-save-view-link p {
  margin: 0;
  color: var(--pl-muted);
  font-size: 0.8rem;
  line-height: 1.4;
}

.pl-save-view-link-row {
  display: flex;
  align-items: center;
  gap: 0.5rem;
}

.pl-save-view-link-input {
  flex: 1 1 auto;
  min-width: 0;
  min-height: 44px;
  padding: 0 0.6rem;
  background: var(--pl-panel-1);
  border: 1px solid var(--pl-border);
  border-radius: 8px;
  color: var(--pl-text);
  font-family: var(--font-sans);
  font-size: 0.78rem;
  overflow: hidden;
  text-overflow: ellipsis;
}

.pl-save-view-link-input:focus {
  outline: none;
  border-color: var(--pl-blue);
}

/* ═══ NAR (≤640px) ═══════════════════════════════════════════════════ */
@media (max-width: 640px) {
  .pl-compare-overlay {
    padding: 0;
  }

  .pl-compare {
    width: 100vw;
    max-height: 100dvh;
    height: 100dvh;
    border-radius: 0;
    border: none;
  }

  .pl-saves-row-actions {
    width: 100%;
    justify-content: space-between;
    margin-left: 0;
  }

  .pl-saves-row-confirm,
  .pl-saves-row-rename {
    flex-direction: column;
    align-items: stretch;
  }

  .pl-saves-row-confirm-actions,
  .pl-saves-row-rename-actions {
    justify-content: stretch;
  }

  .pl-saves-row-confirm-actions .pl-btn,
  .pl-saves-row-rename-actions .pl-btn {
    flex: 1 1 0;
  }

  .pl-save-view-link-row {
    flex-direction: column;
    align-items: stretch;
  }
}

@media (prefers-reduced-motion: reduce) {
  .pl-saves-menu-item,
  .pl-saves-rename-input,
  .pl-save-view-link-input {
    transition: none;
  }
}

/* ─────────────────────────────────────────────────────────────────────────
   wave-detail.css — detail_view.rs: page prev/next nav, the L3 feature
   carousel rail, and the share-view "browsing only" ribbon.

   OWNER: detail_view.rs agent. Tokens only (var(--pl-*)), 44px touch
   targets, breakpoints 640/980/1180 only (none of that needed here — every
   new element reflows through the existing .pl-detail-grid stack, see
   main.css:11689 and :11882), reduced-motion respected. Doubled selectors
   (.pl-x.pl-x) so this wins regardless of stylesheet append order relative
   to main.css and other concurrent scratch/*.css files, per the card-grid
   .css convention (main.css:16605-16621).

   Markup verified live against detail_view.rs on 2026-08-16.
   ───────────────────────────────────────────────────────────────────────── */

/* ═══ 1 · Page prev/next nav — flanks .pl-pagenav ════════════════════════
   Markup: <div class="pl-pagenav-row"> <button class="pl-pagenav-arrow
   pl-pagenav-prev"> <nav class="pl-pagenav">…</nav> <button
   class="pl-pagenav-arrow pl-pagenav-next">
   ═══════════════════════════════════════════════════════════════════════ */

.pl-pagenav-row.pl-pagenav-row {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-top: 12px;
}

/* .pl-pagenav already carries `margin-top: 12px` from main.css for its old
   standalone position — inside the row that margin would double up under
   the row's own, so zero it out here and let the row own the spacing. */
.pl-pagenav-row .pl-pagenav.pl-pagenav {
  margin-top: 0;
  flex: 1;
  min-width: 0;
  overflow-x: auto;
}

.pl-pagenav-arrow.pl-pagenav-arrow {
  flex: 0 0 auto;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 44px;
  height: 44px;
  border-radius: 10px;
  border: 1px solid var(--pl-border);
  background: var(--pl-panel-1);
  color: var(--pl-text);
  font-size: 18px;
  line-height: 1;
  cursor: pointer;
  transition: border-color 150ms ease, background 150ms ease;
}

.pl-pagenav-arrow.pl-pagenav-arrow:hover:not(:disabled) {
  border-color: var(--pl-sky);
}

.pl-pagenav-arrow.pl-pagenav-arrow:focus-visible {
  outline: 2px solid var(--pl-sky);
  outline-offset: 2px;
}

.pl-pagenav-arrow.pl-pagenav-arrow:disabled {
  opacity: 0.35;
  cursor: not-allowed;
}

/* ═══ 2 · L3 feature catalog rail ═════════════════════════════════════════
   Markup: .pl-panel.pl-feat-panel > h3 + search + .pl-feat-empty +
   .pl-feat-sec* > .pl-feat-sec-head + .pl-feat-rail > .pl-feat-card*
   Owner: features_rail.rs. Carousel/dots/pick selectors are unchanged for
   e2e (flow16). New chrome is .pl-feat-* only — do not restyle .pl-rb.
   ═══════════════════════════════════════════════════════════════════════ */

.pl-feat-rail.pl-feat-rail {
  display: flex;
  flex-direction: column;
  gap: 14px;
}

.pl-feat-card.pl-feat-card {
  display: flex;
  flex-direction: column;
  gap: 8px;
  padding: 10px;
  border: 1px solid var(--pl-border);
  border-radius: 10px;
  background: var(--pl-panel-2);
}

.pl-feat-title.pl-feat-title {
  margin: 0;
  font-size: 13px;
  font-weight: 600;
  color: var(--pl-text);
}

.pl-feat-pic.pl-feat-pic {
  border-radius: 8px;
}

.pl-feat-carousel-ctrl.pl-feat-carousel-ctrl {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
}

.pl-feat-nav.pl-feat-nav {
  flex: 0 0 auto;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 44px;
  height: 44px;
  border-radius: 999px;
  border: 1px solid var(--pl-border);
  background: var(--pl-panel-1);
  color: var(--pl-text);
  font-size: 16px;
  line-height: 1;
  cursor: pointer;
  transition: border-color 150ms ease;
}

.pl-feat-nav.pl-feat-nav:hover:not(:disabled) {
  border-color: var(--pl-sky);
}

.pl-feat-nav.pl-feat-nav:focus-visible {
  outline: 2px solid var(--pl-sky);
  outline-offset: 2px;
}

.pl-feat-nav.pl-feat-nav:disabled {
  opacity: 0.35;
  cursor: not-allowed;
}

.pl-feat-dots.pl-feat-dots {
  display: flex;
  align-items: center;
  gap: 2px;
}

/* 44px touch target via padding around a small visible dot, same
   min-hit-area technique as .pl-wiz-dot-btn. */
.pl-feat-dot.pl-feat-dot {
  flex: 0 0 auto;
  width: 44px;
  height: 44px;
  padding: 0;
  border: 0;
  background: transparent;
  cursor: pointer;
  position: relative;
}

.pl-feat-dot.pl-feat-dot::after {
  content: "";
  position: absolute;
  top: 50%;
  left: 50%;
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: var(--pl-border);
  transform: translate(-50%, -50%);
  transition: background 150ms ease, transform 150ms ease;
}

.pl-feat-dot.pl-feat-dot-cur.pl-feat-dot-cur::after {
  background: var(--pl-green);
  transform: translate(-50%, -50%) scale(1.25);
}

.pl-feat-dot.pl-feat-dot:focus-visible {
  outline: 2px solid var(--pl-sky);
  outline-offset: 2px;
}

.pl-feat-pick-row.pl-feat-pick-row {
  display: flex;
  justify-content: flex-end;
  margin-top: 2px;
}

.pl-feat-search-lbl.pl-feat-search-lbl {
  display: flex;
  flex-direction: column;
  gap: 6px;
  margin: 0 0 12px;
}

.pl-feat-search-caption.pl-feat-search-caption {
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--pl-muted);
}

.pl-feat-search.pl-feat-search {
  width: 100%;
  min-height: 44px;
  padding: 8px 12px;
  border: 1px solid var(--pl-border);
  border-radius: 8px;
  background: var(--pl-panel-1);
  color: var(--pl-text);
  font-family: var(--font-sans);
  font-size: 13px;
}

.pl-feat-search.pl-feat-search:focus {
  outline: none;
  border-color: var(--pl-blue);
  box-shadow: 0 0 0 2px color-mix(in srgb, var(--pl-blue) 20%, transparent);
}

.pl-feat-empty.pl-feat-empty {
  margin: 0 0 12px;
  font-size: 13px;
  line-height: 1.45;
  color: var(--pl-muted);
}

.pl-feat-sec.pl-feat-sec {
  display: flex;
  flex-direction: column;
  gap: 10px;
  margin-bottom: 8px;
}

.pl-feat-sec.pl-feat-sec[hidden],
.pl-feat-rail.pl-feat-rail[hidden],
.pl-feat-empty.pl-feat-empty[hidden] {
  display: none !important;
}

.pl-feat-sec-head.pl-feat-sec-head {
  display: flex;
  align-items: center;
  gap: 8px;
  width: 100%;
  min-height: 44px;
  margin: 0;
  padding: 0 2px;
  border: 0;
  background: transparent;
  color: var(--pl-text);
  font-family: var(--font-sans);
  font-size: 13px;
  font-weight: 600;
  text-align: left;
  cursor: pointer;
}

.pl-feat-sec-head.pl-feat-sec-head:hover {
  color: var(--pl-sky);
}

.pl-feat-sec-head.pl-feat-sec-head:focus-visible {
  outline: 2px solid var(--pl-sky);
  outline-offset: 2px;
  border-radius: 6px;
}

.pl-feat-sec-title.pl-feat-sec-title {
  flex: 1 1 auto;
  min-width: 0;
}

.pl-feat-sec-chevron.pl-feat-sec-chevron {
  flex: 0 0 auto;
  display: inline-block;
  color: var(--pl-muted);
  font-size: 14px;
  line-height: 1;
  transition: transform 150ms ease;
}

.pl-feat-sec-chevron-open.pl-feat-sec-chevron-open {
  transform: rotate(180deg);
}

.pl-feat-card-head.pl-feat-card-head {
  display: flex;
  align-items: center;
  gap: 8px;
  flex-wrap: wrap;
}

.pl-feat-why.pl-feat-why {
  margin: 0;
  font-size: 12px;
  line-height: 1.5;
  color: var(--pl-muted);
}

@media (prefers-reduced-motion: reduce) {
  .pl-feat-dot.pl-feat-dot::after,
  .pl-pagenav-arrow.pl-pagenav-arrow,
  .pl-feat-nav.pl-feat-nav,
  .pl-feat-sec-chevron.pl-feat-sec-chevron {
    transition: none;
  }
}

/* ═══ 3 · Share-view gating ════════════════════════════════════════════════
   Markup: .pl-panel.pl-share-ribbon replaces the composer panel when
   state.share_view is true; disabled buttons across this file (composer
   post — folded into the ribbon swap, apply, save-for-later, perms
   toggles, decision confirm, variant pick) fall back to main.css's
   existing .pl-btn:disabled (main.css:19112) except the two button
   families that never carried a disabled style before this pass.
   ═══════════════════════════════════════════════════════════════════════ */

.pl-share-ribbon.pl-share-ribbon {
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: 44px;
  text-align: center;
  border: 1px dashed var(--pl-border);
  background: var(--pl-panel-2);
}

.pl-share-ribbon-text.pl-share-ribbon-text {
  margin: 0;
  font-size: 13px;
  color: var(--pl-muted);
}

.pl-ptog.pl-ptog:disabled {
  opacity: 0.4;
  cursor: not-allowed;
}

.pl-apply-btn.pl-apply-btn:disabled {
  opacity: 0.45;
  cursor: not-allowed;
  box-shadow: none;
}

/* ==========================================================================
   Activity sheet (activity.rs) + Command palette (palette.rs)
   Scratch stylesheet — orchestrator merges into main.css. Uses --pl-* tokens
   already defined in main.css's :root / [data-pl-theme="dark"] blocks.
   Z-bands per docs/PLANNER_LAYOUT.md: overlay 79 (Modal Backdrop), sheet/
   palette 80 (Modal). Breakpoints: NAR <=640, MID 641-980, WIDE >=1180.
   ========================================================================== */

/* ── Activity sheet: right sheet, same shell mechanics as .pl-drawer ────── */

.pl-activity-overlay {
  position: fixed;
  inset: 0;
  z-index: 79; /* z-scale: modal backdrop band */
  background: var(--pl-modal-backdrop);
}

.pl-activity-overlay[hidden] {
  display: none;
}

.pl-activity {
  position: fixed;
  top: 0;
  right: 0;
  z-index: 80; /* z-scale: modal band */
  display: flex;
  flex-direction: column;
  width: min(420px, 100vw);
  max-height: 100dvh;
  background: var(--pl-glass-bg);
  backdrop-filter: blur(14px) saturate(1.3);
  -webkit-backdrop-filter: blur(14px) saturate(1.3);
  border-left: 1px solid var(--pl-border);
  box-shadow: var(--pl-modal-shadow);
  outline: none;
}

.pl-activity[hidden] {
  display: none;
}

.pl-activity-head {
  flex-shrink: 0;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.75rem;
  padding: 1rem 1.25rem;
  border-bottom: 1px solid var(--pl-border);
}

.pl-activity-head h2 {
  margin: 0;
  font-size: 1.05rem;
  font-weight: 700;
  color: var(--pl-text);
}

.pl-activity-close {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 44px; /* NAR touch target min */
  height: 44px;
  border: none;
  background: transparent;
  color: var(--pl-muted);
  font-size: 1.1rem;
  cursor: pointer;
  border-radius: var(--radius-card);
}

.pl-activity-close:hover {
  background: var(--pl-block);
  color: var(--pl-text);
}

.pl-activity-tabs {
  flex-shrink: 0;
  display: flex;
  gap: 0.25rem;
  padding: 0 1.25rem;
  border-bottom: 1px solid var(--pl-border);
}

.pl-activity-tab {
  min-height: 44px;
  padding: 0 0.75rem;
  background: transparent;
  border: none;
  border-bottom: 2px solid transparent;
  color: var(--pl-muted);
  font-size: 0.9rem;
  font-weight: 600;
  cursor: pointer;
}

.pl-activity-tab:hover {
  color: var(--pl-text);
}

.pl-activity-tab[aria-selected="true"] {
  color: var(--pl-blue);
  border-bottom-color: var(--pl-blue);
}

.pl-activity-body {
  flex: 1;
  overflow-y: auto;
  padding: 0.5rem 0 1.25rem;
}

.pl-activity-panel {
  padding: 0 1.25rem;
}

.pl-activity-list {
  list-style: none;
  margin: 0;
  padding: 0.5rem 0 0;
  display: flex;
  flex-direction: column;
}

.pl-activity-row {
  display: flex;
  gap: 0.6rem;
  padding: 0.6rem 0;
  border-bottom: 1px solid var(--pl-border);
}

.pl-activity-row:last-child {
  border-bottom: none;
}

.pl-activity-dot {
  flex-shrink: 0;
  width: 8px;
  height: 8px;
  margin-top: 0.4rem;
  border-radius: 50%;
  background: var(--pl-blue);
}

.pl-activity-row-main {
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 0.15rem;
}

.pl-activity-text {
  margin: 0;
  font-size: 0.88rem;
  line-height: 1.4;
  color: var(--pl-text);
  overflow-wrap: break-word;
}

.pl-activity-time {
  font-size: 0.75rem;
  color: var(--pl-faint);
}

.pl-activity-time[hidden] {
  display: none;
}

/* ── Activity sheet: credits ledger ──────────────────────────────────────  */

.pl-activity-credits-summary {
  display: flex;
  gap: 1.5rem;
  padding: 0.75rem 0 1rem;
  border-bottom: 1px solid var(--pl-border);
  margin-bottom: 0.75rem;
}

.pl-activity-credits-figure {
  display: flex;
  flex-direction: column;
}

.pl-activity-credits-num {
  font-size: 1.4rem;
  font-weight: 700;
  color: var(--pl-text);
}

.pl-activity-credits-lbl {
  font-size: 0.72rem;
  text-transform: uppercase;
  letter-spacing: 0.03em;
  color: var(--pl-faint);
}

.pl-activity-ledger-wrap {
  overflow-x: auto;
}

.pl-activity-ledger {
  width: 100%;
  border-collapse: collapse;
  font-size: 0.85rem;
}

.pl-activity-ledger th {
  text-align: left;
  font-size: 0.72rem;
  text-transform: uppercase;
  letter-spacing: 0.03em;
  color: var(--pl-faint);
  padding: 0.4rem 0.5rem;
  border-bottom: 1px solid var(--pl-border);
}

.pl-activity-ledger td {
  padding: 0.5rem;
  color: var(--pl-text);
  border-bottom: 1px solid var(--pl-border);
  vertical-align: top;
}

.pl-activity-ledger th:nth-child(2),
.pl-activity-ledger th:nth-child(3),
.pl-activity-ledger td:nth-child(2),
.pl-activity-ledger td:nth-child(3) {
  text-align: right;
  white-space: nowrap;
}

.pl-activity-mismatch-row td {
  padding-top: 0;
  border-bottom: 1px solid var(--pl-border);
}

.pl-activity-mismatch {
  font-size: 0.78rem;
  color: var(--pl-amber);
}

@media (max-width: 640px) {
  .pl-activity {
    width: 100vw;
    height: 100dvh;
  }

  .pl-activity-head {
    position: sticky;
    top: 0;
    background: var(--pl-glass-bg);
    backdrop-filter: blur(14px) saturate(1.3);
    -webkit-backdrop-filter: blur(14px) saturate(1.3);
  }

  .pl-activity-tabs {
    position: sticky;
    top: 60px;
    background: var(--pl-glass-bg);
    backdrop-filter: blur(14px) saturate(1.3);
    -webkit-backdrop-filter: blur(14px) saturate(1.3);
    z-index: 1;
  }
}

/* ── Account sheet: profile / settings / billing (mirrors Activity) ─── */

.pl-account-overlay {
  position: fixed;
  inset: 0;
  z-index: 79;
  background: var(--pl-modal-backdrop);
}

.pl-account-overlay[hidden] {
  display: none !important;
}

.pl-account {
  position: fixed;
  top: 50%;
  left: 50%;
  z-index: 80;
  display: flex;
  flex-direction: column;
  width: min(480px, calc(100vw - 2rem));
  max-height: min(85dvh, 720px);
  transform: translate(-50%, -50%);
  background: var(--pl-glass-bg);
  backdrop-filter: blur(14px) saturate(1.3);
  -webkit-backdrop-filter: blur(14px) saturate(1.3);
  border: 1px solid var(--pl-border);
  border-radius: 16px;
  box-shadow: var(--pl-modal-shadow);
  outline: none;
}

.pl-account[hidden] {
  display: none !important;
}

.pl-account-head {
  flex-shrink: 0;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.75rem;
  padding: 1rem 1.25rem;
  border-bottom: 1px solid var(--pl-border);
}

.pl-account-head h2 {
  margin: 0;
  font-size: 1.05rem;
  font-weight: 700;
  color: var(--pl-text);
}

.pl-account-close {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 44px;
  height: 44px;
  border: none;
  background: transparent;
  color: var(--pl-muted);
  font-size: 1.1rem;
  cursor: pointer;
  border-radius: var(--radius-card);
}

.pl-account-close:hover {
  background: var(--pl-block);
  color: var(--pl-text);
}

.pl-account-tabs {
  flex-shrink: 0;
  display: flex;
  gap: 0.25rem;
  padding: 0 1.25rem;
  border-bottom: 1px solid var(--pl-border);
}

.pl-account-tab {
  min-height: 44px;
  padding: 0 0.75rem;
  background: transparent;
  border: none;
  border-bottom: 2px solid transparent;
  color: var(--pl-muted);
  font-size: 0.9rem;
  font-weight: 600;
  cursor: pointer;
}

.pl-account-tab:hover {
  color: var(--pl-text);
}

.pl-account-tab[aria-selected="true"] {
  color: var(--pl-blue);
  border-bottom-color: var(--pl-blue);
}

.pl-account-body {
  flex: 1 1 auto;
  overflow-y: auto;
  padding: 1rem 1.25rem 1.5rem;
}

.pl-account-body .pl-toast[hidden] {
  display: none !important;
}

.pl-account-panel[hidden] {
  display: none !important;
}

.pl-account-id {
  display: flex;
  align-items: center;
  gap: 12px;
  margin-bottom: 1rem;
}

.pl-account-avatar,
.pl-sidebar-avatar {
  flex-shrink: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 40px;
  height: 40px;
  border-radius: 50%;
  background: color-mix(in srgb, var(--pl-blue) var(--pl-chip-bg-mix), transparent);
  border: 1px solid color-mix(in srgb, var(--pl-blue) var(--pl-chip-border-mix), transparent);
  color: var(--pl-blue);
  font-size: 13px;
  font-weight: 700;
  letter-spacing: 0.02em;
}

.pl-sidebar-avatar {
  width: 24px;
  height: 24px;
  font-size: 10px;
}

.pl-account-id-copy {
  min-width: 0;
}

.pl-account-id-name {
  margin: 0;
  font-weight: 600;
  color: var(--pl-text);
}

.pl-account-id-email {
  margin: 2px 0 0;
  font-size: 12px;
  color: var(--pl-muted);
}

.pl-account-input {
  display: block;
  width: 100%;
  min-height: 44px;
  margin-bottom: 8px;
  padding: 8px 12px;
  border: 1px solid var(--pl-border);
  border-radius: 8px;
  background: var(--pl-panel-2);
  color: var(--pl-text);
  font-family: var(--font-sans);
  font-size: 14px;
}

.pl-account-hint {
  margin: 0 0 12px;
  font-size: 12px;
  line-height: 1.45;
  color: var(--pl-muted);
}

.pl-account-h3 {
  margin: 1.1rem 0 0.5rem;
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--pl-faint);
}

.pl-account-row {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 12px;
  margin-bottom: 12px;
}

.pl-account-row-label {
  margin: 0 0 2px;
  font-weight: 600;
  font-size: 13px;
  color: var(--pl-text);
}

.pl-account-check {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  font-size: 13px;
  color: var(--pl-text);
}

.pl-account-check input {
  margin-top: 3px;
}

.pl-account-check .pl-account-hint {
  display: block;
  margin: 4px 0 0;
}

.pl-account-balance {
  display: flex;
  align-items: baseline;
  gap: 8px;
  margin-bottom: 8px;
}

.pl-account-balance-num {
  font-size: 2rem;
  font-weight: 700;
  color: var(--pl-green);
  line-height: 1;
}

.pl-account-balance-lbl {
  font-size: 13px;
  color: var(--pl-muted);
}

.pl-account-packs {
  list-style: none;
  margin: 0 0 8px;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.pl-account-pack {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 12px;
  border: 1px solid var(--pl-border);
  border-radius: 10px;
  background: var(--pl-panel-2);
}

.pl-account-pack-name {
  margin: 0;
  font-weight: 600;
  font-size: 14px;
  color: var(--pl-text);
}

.pl-account-pack-meta {
  margin: 2px 0 4px;
  font-size: 12px;
  font-weight: 600;
  color: var(--pl-blue);
}

.pl-account-pack .pl-account-hint {
  margin: 0;
}

@media (max-width: 640px) {
  .pl-account {
    top: 0;
    left: 0;
    width: 100vw;
    height: 100dvh;
    max-height: 100dvh;
    transform: none;
    border-radius: 0;
  }
}

@media (prefers-reduced-motion: reduce) {
  .pl-activity,
  .pl-activity-overlay {
    transition: none !important;
  }
}

/* ── Command palette ──────────────────────────────────────────────────────  */

.pl-palette-overlay {
  position: fixed;
  inset: 0;
  z-index: 79; /* z-scale: modal backdrop band */
  display: flex;
  justify-content: center;
  background: var(--pl-modal-backdrop);
  padding: 16px;
  padding-top: 12vh;
}

.pl-palette-overlay[hidden] {
  display: none;
}

.pl-palette {
  position: relative;
  z-index: 80; /* z-scale: modal band */
  display: flex;
  flex-direction: column;
  width: min(560px, 100vw - 32px);
  max-height: min(60vh, 480px);
  background: var(--pl-panel-1);
  border: 1px solid var(--pl-border);
  border-radius: var(--radius-card);
  box-shadow: var(--pl-modal-shadow);
  overflow: hidden;
  outline: none;
}

.pl-palette[hidden] {
  display: none;
}

.pl-palette-search {
  flex-shrink: 0;
  display: flex;
  align-items: center;
  gap: 0.5rem;
  padding: 0.5rem 0.75rem;
  border-bottom: 1px solid var(--pl-border);
}

.pl-palette-search-icon {
  flex-shrink: 0;
  font-size: 0.95rem;
  opacity: 0.7;
}

.pl-palette-input {
  flex: 1;
  min-height: 44px;
  border: none;
  background: transparent;
  color: var(--pl-text);
  font-size: 0.95rem;
  outline: none;
}

.pl-palette-input::placeholder {
  color: var(--pl-faint);
}

.pl-palette-close {
  flex-shrink: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 36px;
  height: 36px;
  border: none;
  background: transparent;
  color: var(--pl-muted);
  cursor: pointer;
  border-radius: var(--radius-card);
}

.pl-palette-close:hover {
  background: var(--pl-block);
  color: var(--pl-text);
}

.pl-palette-list {
  list-style: none;
  margin: 0;
  padding: 0.4rem;
  overflow-y: auto;
  flex: 1;
}

.pl-palette-empty {
  padding: 1.5rem 0.75rem;
  text-align: center;
  color: var(--pl-faint);
  font-size: 0.85rem;
}

.pl-palette-empty[hidden] {
  display: none;
}

.pl-palette-item {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  min-height: 44px;
  padding: 0 0.6rem;
  border-radius: var(--radius-card);
  cursor: pointer;
  color: var(--pl-text);
}

.pl-palette-item[aria-selected="true"] {
  background: color-mix(in srgb, var(--pl-blue) 12%, transparent);
}

.pl-palette-item-group {
  flex-shrink: 0;
  font-size: 0.68rem;
  text-transform: uppercase;
  letter-spacing: 0.03em;
  color: var(--pl-faint);
  width: 4.5rem;
}

.pl-palette-item-label {
  min-width: 0;
  font-size: 0.9rem;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

@media (max-width: 640px) {
  .pl-palette-overlay {
    padding: 0;
    padding-top: 0;
    align-items: flex-start;
  }

  .pl-palette {
    width: 100vw;
    max-height: 100dvh;
    height: 100dvh;
    border-radius: 0;
    border: none;
  }
}

@media (prefers-reduced-motion: reduce) {
  .pl-palette,
  .pl-palette-overlay {
    transition: none !important;
  }
}

/* wave-meter.css — review-progress meters (overview cards + map view).
   Derived-only feature: no new state, just rendering for review_progress().
   Tokens: --pl-* only. Reduced-motion: no width transition. */

/* Overview card row — reserves height like the other rows even in the
   zero-state so the card baseline stays aligned across all cards. */
.pl-site-progress-row {
  display: flex;
  flex-direction: column;
  gap: 4px;
  min-height: 34px;
  justify-content: center;
}

.pl-site-progress-empty {
  margin: 0;
  font-size: 12px;
  color: var(--pl-muted);
}

.pl-site-progress-text {
  margin: 0;
  font-size: 12px;
  color: var(--pl-muted);
}

.pl-wave-bar {
  width: 100%;
  height: 4px;
  border-radius: 999px;
  background: var(--pl-track);
  overflow: hidden;
}

.pl-wave-bar-fill {
  height: 100%;
  border-radius: 999px;
  background: linear-gradient(90deg, var(--pl-green), var(--pl-sky));
  transition: width 0.25s ease;
}

@media (prefers-reduced-motion: reduce) {
  .pl-wave-bar-fill {
    transition: none;
  }
}

/* Map view — scoped chart heading progress text. */
.pl-mv-scope-progress {
  font-size: 12px;
  color: var(--pl-muted);
  margin-left: 8px;
}

.pl-mv-scope-progress[hidden] {
  display: none !important;
}

/* Map view — full-map cluster cap badge. */
.pl-mv-cluster-progress-badge {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 34px;
  height: 18px;
  padding: 0 6px;
  border-radius: 999px;
  font-size: 11px;
  line-height: 1;
  background: var(--pl-panel-2);
  color: var(--pl-muted);
  margin-left: 6px;
}

/* ────────────────────────────────────────────────────────────────────────
   Planner sidebar — Phase C (crates/d3pth-web/src/planner/sidebar.rs)

   Own file per the swarm rule (CSS in my named scratch file only). Not
   wired into main.css by me — main.css is orchestrator-only. This file is
   ready to merge as-is; the two lines under "FOR MAIN.CSS" at the bottom
   are the one cross-cutting change (content offset) that has to land in
   main.css itself rather than here, since it touches `.pl-topbar`/
   `.pl-work` selectors this agent doesn't own.

   Tokens only (--pl-*, --font-*) — no hardcoded colors. [hidden] guards
   throughout, not display toggles in JS. 44px touch targets in NAR.
   Reduced-motion honored on every transition/animation.
   ──────────────────────────────────────────────────────────────────────── */

/* ── Root rail ───────────────────────────────────────────────────────── */

.pl-sidebar {
  position: fixed;
  inset: 0 auto 0 0;
  z-index: 20; /* Sticky Chrome band, PLANNER_LAYOUT.md */
  display: flex;
  flex-direction: column;
  width: 240px;
  height: 100dvh;
  background: var(--pl-panel-1);
  border-right: 1px solid var(--pl-border);
  box-shadow: var(--pl-shadow-card);
  overflow-x: hidden;
  overflow-y: auto;
  transition: width 0.2s ease, transform 0.2s ease;
  font-family: var(--font-sans);
  color: var(--pl-text);
}

.pl-sidebar[data-pl-collapsed="true"] {
  width: 56px;
}

/* ── Top mark row ────────────────────────────────────────────────────── */

.pl-sidebar-top {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 14px 12px;
  border-bottom: 1px solid var(--pl-border);
  flex-shrink: 0;
}

.pl-sidebar-mark {
  font-size: 18px;
  line-height: 1;
  color: var(--pl-blue);
  flex-shrink: 0;
}

.pl-sidebar-mark-label {
  font-family: var(--font-display);
  font-weight: 600;
  font-size: 13px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* Compound with `.pl-btn-icon` so the later brand-pass
   `.pl-btn-icon { display: inline-flex }` cannot un-hide this on
   desktop, where the X does nothing (NAR drawer only). */
.pl-sidebar-mobile-close,
.pl-sidebar-mobile-close.pl-btn-icon {
  display: none;
  margin-left: auto;
  width: 32px;
  height: 32px;
  border: 0;
  background: transparent;
  color: var(--pl-muted);
  border-radius: 8px;
  cursor: pointer;
  font-size: 16px;
  line-height: 1;
}

.pl-sidebar-mobile-close:hover {
  background: var(--pl-panel-2);
  color: var(--pl-text);
}

/* ── Groups + labels ─────────────────────────────────────────────────── */

.pl-sidebar-group {
  padding: 10px 12px;
  border-bottom: 1px solid var(--pl-border);
  flex-shrink: 0;
  overflow: visible;
}

.pl-sidebar-group[hidden] {
  display: none !important;
}

.pl-sidebar-label {
  margin: 2px 8px 6px;
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--pl-faint);
}

.pl-sidebar-spacer {
  flex: 1 1 auto;
  min-height: 12px;
  min-width: 0;
  pointer-events: none;
}

.pl-sidebar-global {
  border-bottom: none;
  margin-top: auto;
}

.pl-sidebar-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 2px;
  overflow: visible;
}

.pl-sidebar-item {
  margin: 0;
  padding: 0;
}

/* ── Nav buttons (THIS SITE / GLOBAL rows) ──────────────────────────── */

.pl-sidebar-btn {
  display: flex;
  align-items: center;
  gap: 10px;
  width: 100%;
  min-height: 40px;
  padding: 8px;
  border: 0;
  border-radius: 8px;
  background: transparent;
  color: var(--pl-muted);
  font-family: var(--font-sans);
  font-size: 13px;
  text-align: left;
  cursor: pointer;
  white-space: nowrap;
}

.pl-sidebar-btn:hover {
  background: var(--pl-panel-2);
  color: var(--pl-text);
}

.pl-sidebar-btn:focus-visible {
  outline: 2px solid var(--pl-blue);
  outline-offset: -2px;
}

.pl-sidebar-btn[aria-current="true"] {
  background: color-mix(in srgb, var(--pl-blue) var(--pl-chip-bg-mix), transparent);
  color: var(--pl-blue);
  font-weight: 600;
}

.pl-sidebar-icon {
  flex-shrink: 0;
  width: 16px;
  height: 16px;
}

.pl-sidebar-label-text {
  overflow: hidden;
  text-overflow: ellipsis;
  flex: 1;
  min-width: 0;
}

.pl-sidebar-label-text[hidden] {
  display: none !important;
}

.pl-sidebar-badge {
  flex-shrink: 0;
  padding: 1px 7px;
  border-radius: 999px;
  font-size: 11px;
  font-weight: 600;
  background: color-mix(in srgb, var(--pl-amber) var(--pl-chip-bg-mix), transparent);
  border: 1px solid color-mix(in srgb, var(--pl-amber) var(--pl-chip-border-mix), transparent);
  color: var(--pl-amber);
}

.pl-sidebar-subhead {
  margin: 10px 8px 4px;
  font-size: 10px;
  font-weight: 600;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  color: var(--pl-faint);
}

.pl-sidebar-this-site .pl-dot-rail + .pl-sidebar-subhead {
  margin-top: 2px;
}

.pl-sidebar-subhead[hidden],
.pl-sidebar-ask-block[hidden] {
  display: none !important;
}

.pl-sidebar-btn.pl-sidebar-ask .pl-sidebar-icon {
  color: var(--pl-blue);
}

/* ── Site rows (YOUR SITES) — readiness ring + icon ─────────────────── */

.pl-sidebar-site-btn {
  padding: 6px 8px;
  flex: 1 1 auto;
  min-width: 0;
  min-height: 40px;
}

.pl-sidebar-site-item {
  overflow: visible;
}

.pl-sidebar-site-row {
  display: flex;
  align-items: center;
  gap: 2px;
  min-width: 0;
  position: relative;
  overflow: visible;
}

.pl-sidebar-site-caret {
  flex: 0 0 auto;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 40px;
  min-height: 40px;
  margin: 0;
  padding: 0;
  border: none;
  border-radius: 8px;
  background: transparent;
  color: var(--pl-muted);
  cursor: pointer;
}

.pl-sidebar-site-caret:hover {
  color: var(--pl-text);
  background: color-mix(in srgb, var(--pl-sky) 12%, transparent);
}

.pl-sidebar-site-caret[hidden] {
  display: none !important;
}

.pl-sidebar-site-caret-glyph {
  font-size: 11px;
  line-height: 1;
}

.pl-sidebar-site-count {
  flex: 0 0 auto;
  margin-left: 4px;
  font-size: 10.5px;
  font-weight: 600;
  color: var(--pl-faint);
}

.pl-sidebar-site-btn[aria-current="true"],
.pl-sidebar-page-btn[aria-current="true"] {
  background: color-mix(in srgb, var(--pl-sky) 10%, transparent);
  color: var(--pl-text);
  font-weight: 600;
  box-shadow: none;
}

/* Nested page jump tabs under each SITE AREAS surface (and THIS AREA
   Browse). `.pl-sidebar-list { display:flex }` would otherwise beat the
   HTML `hidden` attribute, so collapsed must `display:none !important`. */
.pl-sidebar-pages {
  padding: 6px 0 4px;
  overflow: visible;
}

.pl-sidebar-pages[hidden] {
  display: none !important;
}

.pl-sidebar-page-btn {
  min-height: 40px;
  padding: 4px 8px 4px 42px;
  font-size: 12.5px;
  font-weight: 400;
}

.pl-sidebar[data-pl-collapsed="true"] .pl-sidebar-page-btn {
  padding-left: 8px;
}

.pl-sidebar-this-site .pl-sidebar-page-btn {
  padding-left: 28px;
}

.pl-side-ring {
  --pl-ring-color: var(--pl-blue);
  flex-shrink: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 26px;
  height: 26px;
  border-radius: 50%;
  background: conic-gradient(
    var(--pl-ring-color) calc(var(--pl-ring-pct, 0) * 1%),
    var(--pl-border) 0
  );
}

.pl-side-ring-hole {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 20px;
  height: 20px;
  border-radius: 50%;
  background: var(--pl-panel-1);
  color: var(--pl-muted);
}

.pl-sidebar-btn[aria-current="true"] .pl-side-ring-hole {
  color: var(--pl-blue);
}

.pl-side-ring-icon {
  width: 12px;
  height: 12px;
}

/* ── Credits pill ────────────────────────────────────────────────────── */

.pl-sidebar-credits {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 2px;
  width: calc(100% - 16px);
  margin: 8px 8px 4px;
  padding: 7px 10px;
  border-radius: 999px;
  background: color-mix(in srgb, var(--pl-green) var(--pl-chip-bg-mix), transparent);
  border: 1px solid color-mix(in srgb, var(--pl-green) var(--pl-chip-border-mix), transparent);
  color: var(--pl-green);
  font-family: var(--font-sans);
  font-size: 12px;
  font-weight: 700;
  white-space: nowrap;
  overflow: hidden;
  cursor: pointer;
}

.pl-sidebar-credits:hover {
  filter: brightness(0.97);
}

.pl-sidebar-credits[aria-current="true"] {
  box-shadow: 0 0 0 2px color-mix(in srgb, var(--pl-green) 35%, transparent);
}

.pl-sidebar[data-pl-collapsed="true"] .pl-sidebar-credits {
  margin-inline: 6px;
  padding-inline: 0;
}

/* ── Collapse toggle (desktop only) ───────────────────────────────────
   Sits on the vertical seam, mid-rail — not the top corner. `position:
   fixed` so `.pl-sidebar`'s overflow-x:hidden (needed for the collapsed
   label clip) cannot slice the circle in half. `left` tracks the rail
   width; translate(-50%, -50%) centers the disc on that seam. */

.pl-sidebar-collapse-toggle {
  position: fixed;
  top: 50%;
  left: 240px;
  z-index: 21; /* Sticky Chrome, one notch above the rail */
  width: 24px;
  height: 24px;
  margin: 0;
  padding: 0;
  border-radius: 50%;
  border: 1px solid var(--pl-sidebar-edge, var(--pl-border));
  background: var(--pl-sidebar-ground, var(--pl-panel-1));
  color: var(--pl-faint);
  box-shadow: var(--pl-shadow-card);
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  transform: translate(-50%, -50%);
  opacity: 0.55;
  transition: left 0.2s ease, opacity 0.15s ease, color 0.15s ease,
    border-color 0.15s ease, background 0.15s ease;
}

.pl-sidebar-collapse-toggle::after {
  content: "";
  position: absolute;
  inset: -10px;
}

.pl-sidebar[data-pl-collapsed="true"] .pl-sidebar-collapse-toggle {
  left: 56px;
}

.pl-sidebar:hover .pl-sidebar-collapse-toggle,
.pl-sidebar-collapse-toggle:hover,
.pl-sidebar-collapse-toggle:focus-visible {
  opacity: 1;
  color: var(--pl-blue);
  border-color: var(--pl-blue);
  background: var(--pl-panel-1);
}

.pl-sidebar-collapse-toggle:focus-visible {
  outline: 2px solid var(--pl-blue);
  outline-offset: 1px;
}

.pl-sidebar-collapse-chevron {
  font-size: 14px;
  line-height: 1;
}

@media (prefers-reduced-motion: reduce) {
  .pl-sidebar-collapse-toggle {
    transition: none;
  }
}

/* ── Mobile hamburger + scrim + drawer (NAR) ────────────────────────── */

/* Compound with `.pl-btn-icon` so the later brand-pass
   `.pl-btn-icon { display: inline-flex }` cannot un-hide this on
   desktop. The hamburger only opens the NAR overlay drawer. */
.pl-sidebar-hamburger,
.pl-sidebar-hamburger.pl-btn-icon {
  display: none;
  position: fixed;
  top: 10px;
  left: 10px;
  z-index: 21;
  width: 40px;
  height: 40px;
  border-radius: 10px;
  border: 1px solid var(--pl-border);
  background: var(--pl-glass-bg);
  backdrop-filter: blur(8px);
  color: var(--pl-text);
  box-shadow: var(--pl-shadow-card);
  cursor: pointer;
  align-items: center;
  justify-content: center;
  font-size: 18px;
}

.pl-sidebar-scrim {
  display: none;
}

@media (max-width: 640px) {
  .pl-sidebar-hamburger,
  .pl-sidebar-hamburger.pl-btn-icon {
    display: inline-flex;
  }

  .pl-sidebar-mobile-close,
  .pl-sidebar-mobile-close.pl-btn-icon {
    display: inline-flex;
    align-items: center;
    justify-content: center;
  }

  .pl-sidebar-collapse-toggle {
    display: none;
  }

  .pl-sidebar {
    /* NAR ignores the collapsed preference entirely — hamburger overlay
       drawer only, per PLANNER_IA.md's mobile deltas. */
    width: min(320px, 82vw);
    transform: translateX(-100%);
    z-index: 80; /* Modal band while open — it's an overlay here, not
                    persistent chrome, per PLANNER_LAYOUT.md's Z-Scale. */
  }

  .pl-sidebar[data-pl-collapsed="true"] {
    width: min(320px, 82vw);
  }

  .pl-sidebar[data-pl-mobile-open="true"] {
    transform: translateX(0);
  }

  .pl-sidebar-scrim[hidden] {
    display: none !important;
  }

  .pl-sidebar-scrim {
    display: block;
    position: fixed;
    inset: 0;
    z-index: 79; /* Modal Backdrop band */
    background: var(--pl-modal-backdrop);
  }

  /* Touch targets ≥44px, PLANNER_LAYOUT.md checklist. */
  .pl-sidebar-btn,
  .pl-sidebar-hamburger,
  .pl-sidebar-mobile-close,
  .pl-sidebar-collapse-toggle {
    min-height: 44px;
    min-width: 44px;
  }
}

/* ── Reduced motion ──────────────────────────────────────────────────── */

@media (prefers-reduced-motion: reduce) {
  .pl-sidebar,
  .pl-sidebar-list * {
    transition: none !important;
  }
}

/* ────────────────────────────────────────────────────────────────────────
   FOR MAIN.CSS (orchestrator merge — not active from this file alone):

   .pl-topbar, .pl-work { margin-left: 240px; transition: margin-left .2s ease; }
   .pl-app[data-pl-sidebar-collapsed="true"] .pl-topbar,
   .pl-app[data-pl-sidebar-collapsed="true"] .pl-work { margin-left: 56px; }
   @media (max-width: 640px) {
     .pl-topbar, .pl-work { margin-left: 0; }
   }

   See sidebar.rs's bottom-of-file wiring notes for why this can't be
   self-contained in this file: it targets `.pl-topbar`/`.pl-work`,
   elements this agent doesn't own, and needs `data-pl-sidebar-collapsed`
   read from the same collapsed signal sidebar.rs owns — a one-line
   decision for whoever integrates (lift the signal, or use a sibling
   CSS selector off `.pl-sidebar[data-pl-collapsed]` instead).
   ──────────────────────────────────────────────────────────────────────── */

/* Herodot ambience canvas — crates/d3pth-web/src/planner/ambience.rs.
   Orchestrator: fold into main.css (owner of that file only). Do not add
   selectors here for anything other than `.pl-ambience-canvas`. */

.pl-ambience-canvas {
  position: fixed;
  inset: 0;
  z-index: 0; /* Base band — docs/PLANNER_LAYOUT.md's Z-Scale Bands table */
  pointer-events: none;
  width: 100%;
  height: 100%;
  display: block;
}

/* Style studio — cascade Phase A additions (scope selector, pin badge,
   "Follow the site look again", cascade toast, contrast guard, and the new
   Effects/Brand panels). Owned by style_studio.rs; NEW file, additive only
   — every selector below is a class introduced by this pass, nothing here
   redefines an existing `.pl-studio-*` rule already in main.css.

   Tokens only: --pl-*. 44px minimum touch targets on every interactive
   control. `[hidden]` is the only visibility mechanism (matches the
   DOM-shape-stable HYDRATION LAW pattern already used by the peek overlay
   and the try-on bar) — nothing here uses display:none as a JS-driven
   toggle target. Reduced-motion honored at the bottom. */

/* ── Scope selector ("This page / This site / Everything") ────────────── */

.pl-studio-scope-row {
  display: inline-flex;
  gap: 2px;
  padding: 3px;
  margin: 0 0 14px;
  border-radius: 999px;
  background: var(--pl-panel-2);
  border: 1px solid var(--pl-border);
}

.pl-studio-scope-btn {
  appearance: none;
  border: none;
  background: transparent;
  color: var(--pl-muted);
  font: inherit;
  font-size: 0.85rem;
  font-weight: 600;
  padding: 0 18px;
  min-height: 38px;
  border-radius: 999px;
  cursor: pointer;
  transition: background-color 0.15s ease, color 0.15s ease, box-shadow 0.15s ease;
}

.pl-studio-scope-btn:hover {
  color: var(--pl-text);
}

.pl-studio-scope-btn[aria-checked="true"] {
  background: var(--pl-panel-1);
  color: var(--pl-text);
  box-shadow: var(--pl-shadow-card);
}

.pl-studio-scope-btn:focus-visible {
  outline: 2px solid var(--pl-blue);
  outline-offset: 2px;
}

/* ── Pin badge + "Follow the site look again" ───────────────────────────── */

.pl-studio-pin-badge {
  position: absolute;
  top: 10px;
  right: 10px;
  display: inline-flex;
  align-items: center;
  gap: 5px;
  padding: 5px 12px;
  min-height: 28px;
  border-radius: 999px;
  background: var(--pl-green);
  color: #fff;
  font-size: 0.7rem;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  box-shadow: var(--pl-shadow-float);
  pointer-events: none;
}

.pl-studio-pin-badge::before {
  content: "";
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: #fff;
}

.pl-studio-device {
  position: relative;
}

.pl-studio-follow-link {
  appearance: none;
  border: none;
  background: none;
  padding: 10px 4px;
  min-height: 44px;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  color: var(--pl-blue);
  font: inherit;
  font-size: 0.85rem;
  font-weight: 600;
  cursor: pointer;
  align-self: center;
}

.pl-studio-follow-link:hover {
  text-decoration: underline;
}

.pl-studio-follow-link:focus-visible {
  outline: 2px solid var(--pl-blue);
  outline-offset: 2px;
  border-radius: 6px;
}

.pl-studio-follow-link::before {
  content: "↺";
  font-size: 0.95em;
}

/* Small inline "Pinned" marker next to a group panel's own header (Effects,
   Brand) — same voice as the big preview badge, smaller footprint. */
.pl-studio-group-pin {
  display: inline-flex;
  align-items: center;
  padding: 2px 8px;
  border-radius: 999px;
  background: color-mix(in srgb, var(--pl-green) 14%, transparent);
  color: var(--pl-green);
  font-size: 0.65rem;
  font-weight: 700;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  margin-left: auto;
}

/* ── Cascade toast ("N pages follow, M stay pinned") ────────────────────── */

.pl-studio-cascade-toast {
  position: sticky;
  bottom: 16px;
  z-index: 5;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  margin: 14px auto 0;
  padding: 12px 16px;
  max-width: 480px;
  border-radius: 12px;
  background: var(--pl-panel-1);
  border: 1px solid var(--pl-border);
  box-shadow: var(--pl-shadow-float);
  color: var(--pl-text);
  font-size: 0.85rem;
}

.pl-studio-cascade-toast-msg {
  flex: 1;
}

.pl-studio-cascade-toast-close {
  appearance: none;
  border: none;
  background: none;
  color: var(--pl-faint);
  font-size: 0.95rem;
  line-height: 1;
  width: 32px;
  height: 32px;
  min-width: 44px;
  min-height: 44px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  border-radius: 8px;
}

.pl-studio-cascade-toast-close:hover {
  color: var(--pl-text);
  background: var(--pl-panel-2);
}

.pl-studio-cascade-toast-close:focus-visible {
  outline: 2px solid var(--pl-blue);
  outline-offset: 2px;
}

/* ── Contrast guard ──────────────────────────────────────────────────────── */

.pl-studio-contrast-warning {
  margin-top: 12px;
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.pl-studio-contrast-row {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  padding: 10px 12px;
  border-radius: 10px;
  background: color-mix(in srgb, var(--pl-amber) 10%, var(--pl-panel-2));
  border: 1px solid color-mix(in srgb, var(--pl-amber) 35%, var(--pl-border));
}

.pl-studio-contrast-msg {
  color: var(--pl-text);
  font-size: 0.8rem;
  flex: 1 1 200px;
}

.pl-studio-contrast-actions {
  display: inline-flex;
  align-items: center;
  gap: 6px;
}

.pl-studio-contrast-fix {
  appearance: none;
  border: 1px solid color-mix(in srgb, var(--pl-amber) 45%, var(--pl-border));
  background: var(--pl-panel-1);
  color: var(--pl-text);
  font: inherit;
  font-size: 0.75rem;
  font-weight: 600;
  padding: 0 12px;
  min-height: 36px;
  border-radius: 999px;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  cursor: pointer;
}

.pl-studio-contrast-fix:hover {
  border-color: var(--pl-amber);
}

.pl-studio-contrast-fix:focus-visible,
.pl-studio-contrast-dismiss:focus-visible {
  outline: 2px solid var(--pl-blue);
  outline-offset: 2px;
}

.pl-studio-contrast-fix-dot {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  border: 1px solid rgba(15, 23, 42, 0.15);
  flex: none;
}

.pl-studio-contrast-dismiss {
  appearance: none;
  border: none;
  background: none;
  color: var(--pl-faint);
  width: 32px;
  height: 32px;
  min-width: 44px;
  min-height: 44px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border-radius: 8px;
  cursor: pointer;
}

.pl-studio-contrast-dismiss:hover {
  color: var(--pl-text);
  background: var(--pl-panel-1);
}

/* ── Brand group: filename field + generate-concepts row ─────────────────── */

.pl-studio-text-row {
  display: flex;
  flex-direction: column;
  gap: 6px;
  margin-top: 10px;
  font-size: 0.75rem;
  color: var(--pl-muted);
  font-weight: 600;
}

.pl-studio-text-input {
  min-height: 44px;
  padding: 0 12px;
  border-radius: 8px;
  border: 1px solid var(--pl-border);
  background: var(--pl-panel-1);
  color: var(--pl-text);
  font: inherit;
  font-size: 0.85rem;
  font-weight: 400;
}

.pl-studio-text-input:focus-visible {
  outline: 2px solid var(--pl-blue);
  outline-offset: 1px;
}

.pl-studio-logo-generate {
  margin-top: 10px;
}

/* ── Reduced motion ──────────────────────────────────────────────────────── */

@media (prefers-reduced-motion: reduce) {
  .pl-studio-scope-btn,
  .pl-studio-cascade-toast-close,
  .pl-studio-contrast-dismiss,
  .pl-studio-contrast-fix {
    transition: none;
  }
}

/* build-versions.css — "Sites & versions" timeline (saves.rs), restyling
   the account-scoped plan picker into the row layout from
   docs/planner-ia-mockups/sites-versions.png + mobile-sites-versions.png,
   plus the new Roll back action. Scratch file for the orchestrator to fold
   into main.css — see docs/PLANNER_LAYOUT.md for the z-scale/breakpoint/
   token contract this follows (NAR 640 / MID 980 / WIDE 1180).

   Tokens only — every color/spacing/shadow below is a --pl-* custom
   property or an existing --radius-* token already defined in main.css's
   :root / [data-pl-theme="dark"] blocks; nothing is invented here.

   Base overlay/dialog/list mechanics (.pl-saves-overlay, .pl-saves,
   .pl-saves-body, .pl-saves-list, .pl-saves-row-error, .pl-saves-toolbar,
   .pl-saves-compare-toggle, .pl-saves-row-menu/-menu-btn/-menu-list/-item,
   .pl-saves-row-confirm/-confirm-actions, .pl-saves-row-rename/-rename-*,
   .pl-btn-danger, .pl-compare-*) are ALREADY styled in main.css (folded in
   from an earlier scratch pass) and are reused as-is — this file only adds
   the NEW class names saves.rs's timeline restyle introduces. */

/* ═══ Header: title + new subhead ═════════════════════════════════════ */

.pl-versions-head {
  align-items: flex-start;
}

.pl-versions-head-text {
  display: flex;
  flex-direction: column;
  gap: 0.3rem;
  min-width: 0;
}

.pl-versions-subhead {
  margin: 0;
  color: var(--pl-muted);
  font-size: 0.85rem;
  line-height: 1.4;
}

/* ═══ Roll-back success toast — reuses the global .pl-toast look, just
   scoped/positioned inside the sheet body instead of main.css's usual
   fixed-viewport placement (this sheet is itself a floating card at
   MID/WIDE, so a viewport-fixed toast would drift off it at NAR). ═══════ */

.pl-versions-toast {
  position: static;
  margin: 0 0 0.75rem;
  animation: none;
}

/* ═══ Immutable-row explainer (persistent helper text, shown only once a
   signed-off row actually exists — see saves.rs's `hidden` guard). ══════ */

.pl-versions-explainer {
  margin: 0 0 0.75rem;
  padding: 0.6rem 0.75rem;
  border-radius: var(--radius-card);
  background: var(--pl-panel-2);
  border: 1px solid var(--pl-border);
  color: var(--pl-muted);
  font-size: 0.8rem;
  line-height: 1.4;
}

/* ═══ Timeline row ════════════════════════════════════════════════════ */

.pl-versions-row .pl-saves-row-normal {
  align-items: flex-start;
  gap: 0.75rem 1rem;
}

.pl-versions-icon {
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  width: 40px;
  height: 40px;
  border-radius: var(--radius-card);
  background: color-mix(in srgb, var(--nt-accent, var(--pl-blue)) 22%, var(--pl-panel-2));
  color: var(--nt-accent, var(--pl-blue));
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 1.05rem;
}

.pl-versions-row-body {
  display: flex;
  flex-direction: column;
  gap: 0.3rem;
  flex: 1 1 240px;
  min-width: 0;
}

.pl-versions-seal {
  display: inline-flex;
  align-items: center;
  gap: 0.3rem;
  padding: 0.15rem 0.55rem;
  border-radius: 999px;
  background: color-mix(in srgb, var(--pl-green) 16%, var(--pl-panel-2));
  color: var(--pl-green);
  font-size: 0.72rem;
  font-weight: 700;
  letter-spacing: 0.02em;
  white-space: nowrap;
}

.pl-versions-seal::before {
  content: "\2713";
}

.pl-versions-readiness {
  color: var(--pl-muted);
  font-size: 0.78rem;
  font-variant-numeric: tabular-nums;
}

/* ═══ Row actions: primary (Open, Roll back) always inline; the rest
   collapses between a dedicated-buttons strip (WIDE/MID) and the existing
   "More actions" ⋯ menu (NAR) — both groups are always rendered, this
   media query is the only thing that picks which one paints. ═══════════ */

.pl-versions-row-actions {
  align-items: center;
  gap: 0.4rem;
}

.pl-btn-rollback {
  background: var(--pl-blue);
  color: #fff;
  border-color: var(--pl-blue);
}

.pl-btn-rollback:hover:not(:disabled) {
  background: color-mix(in srgb, var(--pl-blue) 85%, black);
}

.pl-btn-rollback:disabled {
  opacity: 0.5;
  cursor: not-allowed;
}

.pl-btn-success {
  background: var(--pl-green);
  color: #fff;
  border-color: var(--pl-green);
}

.pl-btn-success:hover:not(:disabled) {
  background: color-mix(in srgb, var(--pl-green) 85%, black);
}

.pl-versions-actions-full {
  display: none;
  align-items: center;
  gap: 0.4rem;
}

.pl-versions-actions-compact {
  display: flex;
}

@media (min-width: 641px) {
  .pl-versions-actions-full {
    display: flex;
  }

  .pl-versions-actions-compact {
    display: none;
  }
}

/* ═══ Roll-back inline confirm (same shape as the existing delete
   confirm — title + honesty sentence, then Cancel / Roll back). ════════ */

.pl-versions-rollback-confirm-text {
  display: flex;
  flex-direction: column;
  gap: 0.2rem;
  flex: 1 1 240px;
  min-width: 0;
}

.pl-versions-rollback-confirm-title {
  margin: 0;
  color: var(--pl-text);
  font-weight: 600;
}

.pl-versions-rollback-confirm-text p {
  margin: 0;
  color: var(--pl-muted);
  font-size: 0.85rem;
  line-height: 1.4;
}

/* ═══ NAR (≤640px) — full-bleed rows, stacked meta, actions wrap. ═══════ */
@media (max-width: 640px) {
  .pl-versions-row .pl-saves-row-normal {
    flex-wrap: wrap;
  }

  .pl-versions-row-body {
    flex-basis: 100%;
  }

  .pl-versions-row-actions {
    width: 100%;
    flex-wrap: wrap;
  }

  .pl-versions-rollback-confirm-text {
    flex-basis: 100%;
  }
}

@media (prefers-reduced-motion: reduce) {
  .pl-versions-toast {
    animation: none;
  }
}

/* ── Sidebar layout offset (orchestrator integration): the rail is fixed;
   the topbar and work area shift right by its width. Collapse state lives
   on .pl-sidebar (first child of the app), so sibling selectors carry it. */
.pl-app .pl-topbar,
.pl-app main.pl-work {
  margin-left: 240px;
  transition: margin-left 0.2s ease;
}

.pl-sidebar[data-pl-collapsed="true"] ~ .pl-topbar,
.pl-sidebar[data-pl-collapsed="true"] ~ main.pl-work {
  margin-left: 56px;
}

@media (prefers-reduced-motion: reduce) {
  .pl-app .pl-topbar,
  .pl-app main.pl-work {
    transition: none;
  }
}

@media (max-width: 640px) {
  .pl-app .pl-topbar,
  .pl-app main.pl-work,
  .pl-sidebar[data-pl-collapsed="true"] ~ .pl-topbar,
  .pl-sidebar[data-pl-collapsed="true"] ~ main.pl-work {
    margin-left: 0;
  }
}

/* ─────────────────────────────────────────────────────────────────────────
   wave2-ideas.css — detail_view.rs: the L2 right-rail "Ideas" accordion
   (PLANNER_IA.md §L2 fixed rail order: composer · decision · Ideas ·
   features · notes; docs/planner-ia-mockups/ideas-rail.png + .recipe.json
   is the layout spec; IDEAS_TAXONOMY.md is the content contract).

   OWNER: detail_view.rs agent (wave 2, builds on wave-detail.css). Tokens
   only (var(--pl-*)), 44px touch targets, reduced-motion respected,
   [hidden] guards on every element this file gives a non-`none` `display`.
   Doubled selectors (.pl-x.pl-x) so this wins regardless of stylesheet
   append order relative to main.css and other concurrent scratch/*.css
   files, per the card-grid.css convention (main.css:16605-16621).

   Markup verified live against detail_view.rs's `idea_card_view` and the
   Ideas-accordion block in `PlannerDetailView` on 2026-08-16.

   Structure:
     .pl-panel.pl-ideas-panel
       > button.pl-ideas-acc-head[aria-expanded]
           > span.pl-ideas-acc-icon
           > span.pl-ideas-acc-title            ("Ideas for this page · N")
           > span.pl-ideas-acc-chevron[.pl-ideas-acc-chevron-open]
       > div.pl-ideas-body                      (only rendered while open)
           > div.pl-ideas-list
               > div.pl-idea-card*
                   > div.pl-idea-card-head
                       > span.pl-idea-angle.pl-idea-angle-{blue|green|red|
                                                            amber|sky}
                       > span.pl-idea-meta                ("STANDARD · 3cr")
                   > p.pl-idea-title
                   > p.pl-idea-pitch
                   > p.pl-idea-why
                   > div.pl-idea-actions
                       > button.pl-btn.pl-btn-sm.pl-save-later-btn
                       > button.pl-btn.pl-btn-sm            (Ask D3pth…)
                       > button.pl-btn.pl-btn-sm.pl-idea-preview-btn (opt.)
                       > button.pl-ghost.pl-idea-dismiss
           > button.pl-ghost.pl-ideas-shuffle   ("Show me a different
                                                  direction")
   ───────────────────────────────────────────────────────────────────────── */

/* ═══ 1 · Accordion head ══════════════════════════════════════════════════ */

.pl-ideas-panel.pl-ideas-panel {
  padding: 0;
  overflow: hidden;
}

.pl-ideas-acc-head.pl-ideas-acc-head {
  display: flex;
  align-items: center;
  gap: 10px;
  width: 100%;
  min-height: 44px;
  padding: 14px 16px;
  background: transparent;
  border: none;
  color: var(--pl-text);
  font-family: var(--font-sans);
  font-size: 14px;
  font-weight: 600;
  text-align: left;
  cursor: pointer;
}

.pl-ideas-acc-head.pl-ideas-acc-head[hidden] {
  display: none !important;
}

.pl-ideas-acc-head.pl-ideas-acc-head:hover {
  background: color-mix(in srgb, var(--pl-blue) 6%, transparent);
}

.pl-ideas-acc-head.pl-ideas-acc-head:focus-visible {
  outline: 2px solid var(--pl-sky);
  outline-offset: -2px;
}

.pl-ideas-acc-icon.pl-ideas-acc-icon {
  flex: 0 0 auto;
  color: var(--pl-sky);
  font-size: 14px;
  line-height: 1;
}

.pl-ideas-acc-title.pl-ideas-acc-title {
  flex: 1 1 auto;
  min-width: 0;
}

.pl-ideas-launch.pl-ideas-launch {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  padding: 0 16px 14px;
}

.pl-ideas-launch.pl-ideas-launch[hidden] {
  display: none !important;
}

.pl-ideas-acc-chevron.pl-ideas-acc-chevron {
  flex: 0 0 auto;
  display: inline-block;
  color: var(--pl-muted);
  font-size: 14px;
  line-height: 1;
  transition: transform 150ms ease;
}

.pl-ideas-acc-chevron.pl-ideas-acc-chevron-open.pl-ideas-acc-chevron-open {
  transform: rotate(180deg);
}

/* ═══ 2 · Body (only mounted while open — no [hidden] toggle to guard) ═══ */

.pl-ideas-body.pl-ideas-body {
  display: flex;
  flex-direction: column;
  gap: 12px;
  padding: 0 16px 16px;
}

.pl-ideas-list.pl-ideas-list {
  display: flex;
  flex-direction: column;
  gap: 12px;
}

.pl-ideas-shuffle.pl-ideas-shuffle {
  align-self: flex-start;
  font-size: 12px;
}

.pl-ideas-empty.pl-ideas-empty {
  display: flex;
  flex-direction: column;
  gap: 12px;
}

.pl-ideas-empty-copy.pl-ideas-empty-copy {
  margin: 0;
  font-size: 13px;
  line-height: 1.45;
  color: var(--pl-muted);
}

/* ═══ 3 · One idea card ════════════════════════════════════════════════════ */

.pl-idea-card.pl-idea-card {
  display: flex;
  flex-direction: column;
  gap: 6px;
  padding: 12px;
  border: 1px solid var(--pl-border);
  border-radius: 10px;
  background: var(--pl-panel-2);
}

.pl-idea-card-head.pl-idea-card-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
}

.pl-idea-meta.pl-idea-meta {
  flex: 0 0 auto;
  color: var(--pl-faint);
  font-family: var(--font-mono);
  font-size: 11px;
  white-space: nowrap;
}

.pl-idea-title.pl-idea-title {
  margin: 0;
  color: var(--pl-text);
  font-family: var(--font-display);
  font-size: 14px;
  font-weight: 600;
  line-height: 1.35;
}

.pl-idea-pitch.pl-idea-pitch {
  margin: 0;
  color: var(--pl-text);
  font-size: 13px;
  line-height: 1.5;
}

.pl-idea-why.pl-idea-why {
  margin: 0;
  color: var(--pl-muted);
  font-size: 12px;
  line-height: 1.5;
}

.pl-idea-actions.pl-idea-actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px;
  margin-top: 4px;
}

.pl-idea-actions.pl-idea-actions[hidden] {
  display: none !important;
}

/* Dismiss reads as a low-emphasis text link, not a fourth button — same
   44px minimum hit area as every other control here, just visually quiet. */
.pl-idea-dismiss.pl-idea-dismiss {
  margin-left: auto;
  min-height: 32px;
  padding: 4px 8px;
  background: transparent;
  border: none;
  color: var(--pl-faint);
  font-size: 12px;
  backdrop-filter: none;
  -webkit-backdrop-filter: none;
}

.pl-idea-dismiss.pl-idea-dismiss:hover {
  color: var(--pl-text);
  background: transparent;
}

/* ═══ 4 · Angle chip — reuses the .pl-chip type scale, adds one color per
   angle via the same color-mix + --pl-chip-*-mix tokens the status chips
   already use (main.css / planner-theme.css). ═══════════════════════════ */

.pl-idea-angle.pl-idea-angle {
  display: inline-flex;
  align-items: center;
  padding: 3px 7px;
  border-radius: 4px;
  border: 1px solid;
  font-family: var(--font-mono);
  font-size: 10px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  white-space: nowrap;
}

.pl-idea-angle-blue.pl-idea-angle-blue {
  color: var(--pl-blue);
  background: color-mix(in srgb, var(--pl-blue) var(--pl-chip-bg-mix), transparent);
  border-color: color-mix(in srgb, var(--pl-blue) var(--pl-chip-border-mix), transparent);
}

.pl-idea-angle-green.pl-idea-angle-green {
  color: var(--pl-green);
  background: color-mix(in srgb, var(--pl-green) var(--pl-chip-bg-mix), transparent);
  border-color: color-mix(in srgb, var(--pl-green) var(--pl-chip-border-mix), transparent);
}

.pl-idea-angle-amber.pl-idea-angle-amber {
  color: var(--pl-amber);
  background: color-mix(in srgb, var(--pl-amber) var(--pl-chip-bg-mix), transparent);
  border-color: color-mix(in srgb, var(--pl-amber) var(--pl-chip-border-mix), transparent);
}

.pl-idea-angle-sky.pl-idea-angle-sky {
  color: var(--pl-sky);
  background: color-mix(in srgb, var(--pl-sky) var(--pl-chip-bg-mix), transparent);
  border-color: color-mix(in srgb, var(--pl-sky) var(--pl-chip-border-mix), transparent);
}

.pl-idea-angle-red.pl-idea-angle-red {
  color: var(--pl-red);
  background: color-mix(in srgb, var(--pl-red) var(--pl-chip-bg-mix), transparent);
  border-color: color-mix(in srgb, var(--pl-red) var(--pl-chip-border-mix), transparent);
}

/* ═══ 5 · Reduced motion ═══════════════════════════════════════════════════ */

@media (prefers-reduced-motion: reduce) {
  .pl-ideas-acc-chevron.pl-ideas-acc-chevron {
    transition: none;
  }
}

/* ─────────────────────────────────────────────────────────────────────────
   wave2-setup.css — setup.rs: the "Site setup" hub (Phase H), its generic
   mini-interview overlay, and the dedicated AI-staff screen.
   docs/PLANNER_IA.md's "Site setup" section is the IA; docs/planner-ia-
   mockups/site-setup-hub.png + setup-interview.png + ai-staff.png (+ their
   .recipe.json siblings) are the layout spec; docs/COPY_DECK.md §6 is the
   string contract; docs/PLANNER_LAYOUT.md is the breakpoint/z-band contract
   (NAR ≤640px / MID 641–980px / WIDE ≥1180px; modal backdrop z 79).

   OWNER: setup.rs agent (wave 2). Tokens only (var(--pl-*)), 44px touch
   targets, reduced-motion respected, [hidden] guards on every element this
   file gives a non-`none` display. Doubled selectors (.pl-x.pl-x) so this
   wins regardless of stylesheet append order relative to main.css and
   other concurrent scratch/*.css files, per the card-grid.css convention.
   `.pl-btn` / `.pl-ghost` / `.pl-panel` / `.pl-share-ribbon` / `.pl-chip` /
   `.pl-wiz-opt` / `.pl-wiz-badge` / `.pl-wiz-opt-label` / `.pl-wiz-opt-why`
   / `.pl-wiz-input` are reused as-is from main.css — nothing here redefines
   them, only this screen's own new classes.

   Markup verified live against setup.rs's `PlannerSetup`/`hub_card`/
   `interview_overlay`/`interview_body`/`ai_staff_view` on 2026-08-16.

   Structure:
     div.pl-setup
       > div.pl-setup-hub[hidden]
           > div.pl-setup-head
               > div > h1.pl-setup-title + p.pl-setup-sub
               > button.pl-btn.pl-setup-continue-btn[hidden]
                                                    ("Continue: {domain}")
           > div.pl-panel.pl-share-ribbon           (share_view only)
           > p.pl-setup-guard                       (stacked-interview guard)
           > p.pl-setup-group-label                 ("Essentials")
           > div.pl-setup-grid.pl-setup-grid-essentials
               > button.pl-setup-card*4
                   > span.pl-setup-card-icon
                   > span.pl-setup-card-title
                   > span.pl-chip.pl-setup-chip-{notstarted|progress|done|later}
           > p.pl-setup-group-label                 ("When you're ready")
           > div.pl-setup-grid.pl-setup-grid-rest
               > button.pl-setup-card*8              (same shape)
       > div.pl-setup-interview-overlay[hidden]
           > div.pl-setup-interview[role=dialog]
               > header.pl-setup-interview-head
                   > div > p.pl-setup-eyebrow + p.pl-setup-step-label
                            + h1.pl-setup-q
                   > button.pl-setup-close            ("\u{2715}")
               > div.pl-setup-interview-body
                   (plain field:) div.pl-setup-field-wrap > input.pl-wiz-
                                  input.pl-setup-field-input
                   (options:)     div.pl-setup-opts > button.pl-wiz-opt*
                                  div.pl-setup-other-wrap
                                    > button.pl-setup-other-toggle[.pl-setup-
                                             other-open] > span + span.pl-
                                             setup-other-chevron
                                    > input.pl-wiz-input.pl-setup-other-input
                   button.pl-setup-decide-later      ("I'll decide later")
               > footer.pl-setup-interview-foot
                   > button.pl-ghost ("Back") + button.pl-btn ("Continue")
       > div.pl-setup-aistaff-overlay[hidden]
           > div.pl-setup-aistaff[role=dialog]
               > header.pl-setup-aistaff-head
                   > div > p.pl-setup-eyebrow + h1.pl-setup-q
                            + p.pl-setup-aistaff-explainer
                   > button.pl-setup-close
               > div.pl-setup-aistaff-rows
                   > div.pl-setup-agent-row*5
                       > div.pl-setup-agent-info > p.pl-setup-agent-title
                                                   + p.pl-setup-agent-purpose
                       > div.pl-setup-autonomy-seg[role=group]
                           > button.pl-setup-autonomy-btn[.pl-setup-
                                    autonomy-btn-sel]*4
               > footer.pl-setup-aistaff-foot > button.pl-btn ("Save")
   ───────────────────────────────────────────────────────────────────────── */

/* ═══ 1 · Root + hub scaffold ═══════════════════════════════════════════ */

.pl-setup.pl-setup {
  height: 100%;
  overflow: hidden;
}

.pl-setup-hub.pl-setup-hub {
  height: 100%;
  overflow-y: auto;
  padding: 24px 28px 40px;
  display: flex;
  flex-direction: column;
  gap: 4px;
}

.pl-setup-hub.pl-setup-hub[hidden] {
  display: none !important;
}

.pl-setup-head.pl-setup-head {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 16px;
  flex-wrap: wrap;
  margin-bottom: 20px;
}

.pl-setup-title.pl-setup-title {
  margin: 0;
  font-family: var(--font-display);
  font-size: 26px;
  line-height: 1.2;
  color: var(--pl-text);
}

.pl-setup-sub.pl-setup-sub {
  margin: 4px 0 0;
  font-family: var(--font-sans);
  font-size: 14px;
  color: var(--pl-muted);
}

.pl-setup-continue-btn.pl-setup-continue-btn {
  flex: 0 0 auto;
  min-height: 44px;
  white-space: nowrap;
}

.pl-setup-continue-btn.pl-setup-continue-btn[hidden] {
  display: none !important;
}

.pl-setup-guard.pl-setup-guard {
  margin: 0 0 16px;
  padding: 10px 14px;
  border-radius: 10px;
  background: color-mix(in srgb, var(--pl-amber) var(--pl-chip-bg-mix), transparent);
  border: 1px solid color-mix(in srgb, var(--pl-amber) var(--pl-chip-border-mix), transparent);
  color: var(--pl-text);
  font-family: var(--font-sans);
  font-size: 13px;
}

.pl-setup-group-label.pl-setup-group-label {
  margin: 8px 0 10px;
  font-family: var(--font-mono);
  font-size: 11px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--pl-faint);
}

/* ═══ 2 · Card grid ══════════════════════════════════════════════════════ */

.pl-setup-grid.pl-setup-grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: 12px;
  margin-bottom: 24px;
}

@media (min-width: 641px) and (max-width: 980px) {
  .pl-setup-grid.pl-setup-grid {
    grid-template-columns: repeat(2, 1fr);
  }
}

@media (min-width: 1180px) {
  .pl-setup-grid.pl-setup-grid {
    grid-template-columns: repeat(4, 1fr);
  }
}

.pl-setup-card.pl-setup-card {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 8px;
  height: 100%;
  min-height: 96px;
  padding: 16px;
  border-radius: 12px;
  background: var(--pl-panel-1);
  border: 1px solid var(--pl-border);
  color: var(--pl-text);
  text-align: left;
  cursor: pointer;
  box-shadow: var(--pl-shadow-card);
}

.pl-setup-card.pl-setup-card:hover {
  border-color: var(--pl-blue);
  background: color-mix(in srgb, var(--pl-blue) 6%, var(--pl-panel-1));
}

.pl-setup-card.pl-setup-card:focus-visible {
  outline: 2px solid var(--pl-sky);
  outline-offset: 2px;
}

.pl-setup-card.pl-setup-card:disabled {
  cursor: default;
  opacity: 0.6;
}

.pl-setup-card.pl-setup-card:disabled:hover {
  border-color: var(--pl-border);
  background: var(--pl-panel-1);
}

.pl-setup-card-icon.pl-setup-card-icon {
  font-size: 18px;
  color: var(--pl-faint);
}

.pl-setup-card-title.pl-setup-card-title {
  font-family: var(--font-sans);
  font-size: 14px;
  font-weight: 600;
  color: var(--pl-text);
}

.pl-setup-card > .pl-chip {
  margin-top: auto;
}

/* Status chips — same tint formula as main.css's `.pl-chip` family
   (color-mix at --pl-chip-bg-mix / --pl-chip-border-mix over the accent). */

.pl-chip.pl-setup-chip-notstarted {
  background: transparent;
  border-color: var(--pl-faint);
  color: var(--pl-faint);
}

.pl-chip.pl-setup-chip-progress {
  background: color-mix(in srgb, var(--pl-blue) var(--pl-chip-bg-mix), transparent);
  border-color: color-mix(in srgb, var(--pl-blue) var(--pl-chip-border-mix), transparent);
  color: var(--pl-blue);
}

.pl-chip.pl-setup-chip-done {
  background: color-mix(in srgb, var(--pl-green) var(--pl-chip-bg-mix), transparent);
  border-color: color-mix(in srgb, var(--pl-green) var(--pl-chip-border-mix), transparent);
  color: var(--pl-green);
}

.pl-chip.pl-setup-chip-later {
  background: color-mix(in srgb, var(--pl-amber) var(--pl-chip-bg-mix), transparent);
  border-color: color-mix(in srgb, var(--pl-amber) var(--pl-chip-border-mix), transparent);
  color: var(--pl-amber);
}

/* ═══ 3 · Generic mini-interview overlay (setup-interview.png: a centered
   single-question modal, NOT the wizard's split-pane shell) ═════════════ */

.pl-setup-interview-overlay.pl-setup-interview-overlay {
  position: fixed;
  inset: 0;
  z-index: 79;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 16px;
  background: var(--pl-modal-backdrop);
  backdrop-filter: blur(4px);
  -webkit-backdrop-filter: blur(4px);
}

.pl-setup-interview-overlay.pl-setup-interview-overlay[hidden] {
  display: none !important;
}

.pl-setup-interview.pl-setup-interview {
  width: 100%;
  max-width: 560px;
  max-height: calc(100vh - 32px);
  overflow-y: auto;
  display: flex;
  flex-direction: column;
  border-radius: 16px;
  background: var(--pl-panel-1);
  border: 1px solid var(--pl-border);
  box-shadow: var(--pl-modal-shadow);
}

.pl-setup-interview-head.pl-setup-interview-head {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 12px;
  padding: 24px 24px 16px;
}

.pl-setup-eyebrow.pl-setup-eyebrow {
  margin: 0;
  font-family: var(--font-mono);
  font-size: 10.5px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--pl-faint);
}

.pl-setup-step-label.pl-setup-step-label {
  margin: 4px 0 0;
  font-family: var(--font-mono);
  font-size: 10.5px;
  color: var(--pl-muted);
}

.pl-setup-q.pl-setup-q {
  margin: 8px 0 0;
  font-family: var(--font-display);
  font-size: 22px;
  line-height: 1.25;
  color: var(--pl-text);
}

.pl-setup-close.pl-setup-close {
  flex: 0 0 auto;
  width: 32px;
  height: 32px;
  min-height: 32px;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 8px;
  background: transparent;
  border: none;
  color: var(--pl-faint);
  font-size: 15px;
  cursor: pointer;
}

.pl-setup-close.pl-setup-close:hover {
  background: color-mix(in srgb, var(--pl-red) 10%, transparent);
  color: var(--pl-red);
}

.pl-setup-interview-body.pl-setup-interview-body {
  padding: 0 24px 8px;
  display: flex;
  flex-direction: column;
  gap: 10px;
}

.pl-setup-field-wrap.pl-setup-field-wrap {
  display: flex;
}

.pl-setup-field-input.pl-setup-field-input,
.pl-setup-other-input.pl-setup-other-input {
  width: 100%;
}

.pl-setup-opts.pl-setup-opts {
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.pl-setup-other-wrap.pl-setup-other-wrap {
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.pl-setup-other-toggle.pl-setup-other-toggle {
  display: flex;
  align-items: center;
  justify-content: space-between;
  min-height: 44px;
  padding: 10px 14px;
  border-radius: 10px;
  background: var(--pl-panel-2);
  border: 1px solid var(--pl-border);
  color: var(--pl-text);
  font-family: var(--font-sans);
  font-size: 14px;
  cursor: pointer;
}

.pl-setup-other-toggle.pl-setup-other-toggle:hover {
  border-color: var(--pl-blue);
}

.pl-setup-other-toggle.pl-setup-other-toggle:focus-visible {
  outline: 2px solid var(--pl-sky);
  outline-offset: 2px;
}

.pl-setup-other-chevron.pl-setup-other-chevron {
  color: var(--pl-faint);
  transition: transform 150ms ease;
}

.pl-setup-other-toggle.pl-setup-other-open .pl-setup-other-chevron {
  transform: rotate(180deg);
}

.pl-setup-decide-later.pl-setup-decide-later {
  align-self: center;
  min-height: 44px;
  padding: 4px 8px;
  background: transparent;
  border: none;
  color: var(--pl-muted);
  font-family: var(--font-sans);
  font-size: 13px;
  text-decoration: underline;
  text-underline-offset: 2px;
  cursor: pointer;
}

.pl-setup-decide-later.pl-setup-decide-later:hover {
  color: var(--pl-text);
}

.pl-setup-interview-foot.pl-setup-interview-foot {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 16px 24px 24px;
  border-top: 1px solid var(--pl-border);
  margin-top: 12px;
}

/* ═══ 4 · AI staff — dedicated list-rows screen (ai-staff.png) ══════════ */

.pl-setup-aistaff-overlay.pl-setup-aistaff-overlay {
  position: fixed;
  inset: 0;
  z-index: 79;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 16px;
  background: var(--pl-modal-backdrop);
  backdrop-filter: blur(4px);
  -webkit-backdrop-filter: blur(4px);
}

.pl-setup-aistaff-overlay.pl-setup-aistaff-overlay[hidden] {
  display: none !important;
}

.pl-setup-aistaff.pl-setup-aistaff {
  width: 100%;
  max-width: 820px;
  max-height: calc(100vh - 32px);
  overflow-y: auto;
  display: flex;
  flex-direction: column;
  border-radius: 16px;
  background: var(--pl-panel-1);
  border: 1px solid var(--pl-border);
  box-shadow: var(--pl-modal-shadow);
}

.pl-setup-aistaff-head.pl-setup-aistaff-head {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 12px;
  padding: 24px 24px 16px;
}

.pl-setup-aistaff-explainer.pl-setup-aistaff-explainer {
  margin: 10px 0 0;
  max-width: 68ch;
  font-family: var(--font-sans);
  font-size: 13.5px;
  line-height: 1.55;
  color: var(--pl-muted);
}

.pl-setup-aistaff-rows.pl-setup-aistaff-rows {
  display: flex;
  flex-direction: column;
  padding: 0 24px 8px;
}

.pl-setup-agent-row.pl-setup-agent-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  flex-wrap: wrap;
  padding: 16px 0;
  border-top: 1px solid var(--pl-border);
}

.pl-setup-aistaff-rows.pl-setup-aistaff-rows > .pl-setup-agent-row.pl-setup-agent-row:first-child {
  border-top: none;
}

.pl-setup-agent-info.pl-setup-agent-info {
  flex: 1 1 260px;
  min-width: 200px;
}

.pl-setup-agent-title.pl-setup-agent-title {
  margin: 0;
  font-family: var(--font-sans);
  font-size: 14.5px;
  font-weight: 600;
  color: var(--pl-text);
}

.pl-setup-agent-purpose.pl-setup-agent-purpose {
  margin: 4px 0 0;
  font-family: var(--font-sans);
  font-size: 12.5px;
  line-height: 1.4;
  color: var(--pl-muted);
}

.pl-setup-autonomy-seg.pl-setup-autonomy-seg {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
}

.pl-setup-autonomy-btn.pl-setup-autonomy-btn {
  min-height: 36px;
  padding: 8px 12px;
  border-radius: 8px;
  background: var(--pl-panel-2);
  border: 1px solid var(--pl-border);
  color: var(--pl-muted);
  font-family: var(--font-sans);
  font-size: 12.5px;
  font-weight: 600;
  cursor: pointer;
  white-space: nowrap;
}

.pl-setup-autonomy-btn.pl-setup-autonomy-btn:hover {
  border-color: var(--pl-blue);
  color: var(--pl-text);
}

.pl-setup-autonomy-btn.pl-setup-autonomy-btn:focus-visible {
  outline: 2px solid var(--pl-sky);
  outline-offset: 2px;
}

.pl-setup-autonomy-btn.pl-setup-autonomy-btn:disabled {
  cursor: default;
  opacity: 0.6;
}

.pl-setup-autonomy-btn.pl-setup-autonomy-btn-sel {
  background: var(--pl-btn-primary-grad);
  border-color: transparent;
  color: #fff;
}

.pl-setup-autonomy-btn.pl-setup-autonomy-btn-sel:hover {
  color: #fff;
}

.pl-setup-aistaff-foot.pl-setup-aistaff-foot {
  display: flex;
  justify-content: flex-end;
  padding: 16px 24px 24px;
  border-top: 1px solid var(--pl-border);
  margin-top: 12px;
}

/* ═══ 5 · NAR (≤640px): stack, fullscreen modals per the layout contract ══ */

@media (max-width: 640px) {
  .pl-setup-hub.pl-setup-hub {
    padding: 16px 16px 32px;
  }

  .pl-setup-head.pl-setup-head {
    flex-direction: column;
    align-items: stretch;
  }

  .pl-setup-continue-btn.pl-setup-continue-btn {
    width: 100%;
  }

  .pl-setup-interview-overlay.pl-setup-interview-overlay,
  .pl-setup-aistaff-overlay.pl-setup-aistaff-overlay {
    padding: 0;
  }

  .pl-setup-interview.pl-setup-interview,
  .pl-setup-aistaff.pl-setup-aistaff {
    max-width: 100%;
    height: 100%;
    max-height: 100%;
    border-radius: 0;
  }

  .pl-setup-agent-row.pl-setup-agent-row {
    flex-direction: column;
    align-items: flex-start;
  }

  .pl-setup-autonomy-seg.pl-setup-autonomy-seg {
    width: 100%;
  }

  .pl-setup-autonomy-btn.pl-setup-autonomy-btn {
    flex: 1 1 calc(50% - 6px);
  }
}

/* ═══ 6 · Reduced motion ═════════════════════════════════════════════════ */

@media (prefers-reduced-motion: reduce) {
  .pl-setup-other-chevron.pl-setup-other-chevron {
    transition: none;
  }
}

/* ─────────────────────────────────────────────────────────────────────────
   wavef-review.css — review.rs: "Review & handoff" (Phase F, the finish
   line). docs/PLANNER_IA.md's "Review & handoff" section is the IA;
   docs/planner-ia-mockups/review-handoff.png (+ .recipe.json) and
   signoff-sequence.png (+ .recipe.json) are the layout spec; docs/COPY_DECK.md
   §8/§10/§11/§12/§13 is the string contract; docs/PLANNER_LAYOUT.md is the
   breakpoint/z-band contract (NAR ≤640px / MID 641–980px / WIDE ≥1180px;
   modal backdrop z 79 / modal z 80, matching this file's confirm + postcard
   dialogs).

   OWNER: review.rs agent (wave F). Tokens only (var(--pl-*)), 44px touch
   targets, reduced-motion respected, [hidden] guards on every element this
   file gives a non-`none` display. Doubled selectors (.pl-x.pl-x) so this
   wins regardless of stylesheet append order relative to main.css and other
   concurrent scratch/*.css files, per the card-grid.css / wave2-setup.css
   convention. `.pl-panel` / `.pl-panel-h` / `.pl-btn` / `.pl-btn-green` /
   `.pl-btn-sm` / `.pl-ghost` / `.pl-chip` / `.pl-chip-later` / `.pl-hint` /
   `.pl-share-ribbon` / `.pl-share-ribbon-text` are reused as-is from
   main.css — nothing here redefines them, only this screen's own new
   classes.

   Markup verified live against review.rs's `PlannerReview` on 2026-08-16.

   Structure:
     div.pl-review
       > div.pl-panel.pl-share-ribbon[hidden]      (share_view only)
           > p.pl-share-ribbon-text
           > button.pl-ghost.pl-btn-sm
       > header.pl-review-head
           > h1.pl-review-title + p.pl-review-sub
       > div.pl-review-top
           > section.pl-panel.pl-review-readiness.pl-readiness-score
               > h2.pl-panel-h ("How ready is this?")
               > div.pl-review-ring-row
                   > div.pl-review-ring[style: --pl-review-pct]
                       > span.pl-review-ring-pct
                   > div.pl-review-state > p.pl-review-state-label
               > ul.pl-review-breakdown
                   > li.pl-review-breakdown-row*4
                       > span.pl-review-dot.pl-review-dot-{key}
                       > span.pl-review-breakdown-label
                       > button.pl-ghost.pl-btn-sm.pl-review-fix-btn ("Fix this")
           > section.pl-panel.pl-review-questions
               > h2.pl-panel-h ("Open questions")
               > p.pl-hint.pl-review-empty                (empty state)
               > ul.pl-review-oq-list
                   > li.pl-review-oq-row
                       > p.pl-review-oq-text > button.pl-review-oq-link
                       > span.pl-chip.pl-chip-later[hidden]
       > section.pl-panel.pl-review-recap
       > p.pl-review-signed-banner[hidden]
       > div.pl-review-actions
           > button.pl-btn.pl-btn-green.pl-signoff-btn
           > button.pl-ghost.pl-review-export-btn
           > button.pl-ghost.pl-review-share-btn
           > button.pl-ghost.pl-review-whatsnext-btn
       > a.pl-review-export-anchor[aria-hidden]          (download driver)
       > div.pl-review-overlay[hidden]                   (confirm sign-off)
           > div.pl-review-dialog[role=dialog]
               > h2.pl-review-dialog-h + p.pl-review-dialog-body
               > div.pl-review-dialog-actions
                   > button.pl-btn.pl-btn-green + button.pl-ghost
       > div.pl-review-overlay[hidden]                   (postcard)
           > div.pl-review-dialog.pl-review-postcard[role=dialog]
               > h2.pl-review-dialog-h
               > ul.pl-review-postcard-list
               > div.pl-review-dialog-actions > button.pl-btn
   ───────────────────────────────────────────────────────────────────────── */

/* ═══ 1 · Root + head ══════════════════════════════════════════════════ */

.pl-review.pl-review {
  height: 100%;
  overflow-y: auto;
  padding: 24px 28px 40px;
  display: flex;
  flex-direction: column;
  gap: 20px;
}

.pl-review-head.pl-review-head {
  display: flex;
  flex-direction: column;
  gap: 4px;
}

.pl-review-title.pl-review-title {
  font-family: var(--font-display);
  font-size: 1.9rem;
  color: var(--pl-text);
  margin: 0;
}

.pl-review-sub.pl-review-sub {
  color: var(--pl-muted);
  margin: 0;
  font-size: 0.95rem;
}

/* ═══ 2 · Top row: readiness + open questions ═════════════════════════ */

.pl-review-top.pl-review-top {
  display: grid;
  grid-template-columns: minmax(260px, 1fr) minmax(280px, 1.4fr);
  gap: 16px;
  align-items: start;
}

@media (max-width: 980px) {
  .pl-review-top.pl-review-top {
    grid-template-columns: 1fr;
  }
}

.pl-review-readiness.pl-review-readiness,
.pl-review-questions.pl-review-questions {
  display: flex;
  flex-direction: column;
  gap: 14px;
}

/* ── Ring ── */

.pl-review-ring-row.pl-review-ring-row {
  display: flex;
  align-items: center;
  gap: 16px;
}

.pl-review-ring.pl-review-ring {
  --pl-review-pct: 0;
  width: 92px;
  height: 92px;
  min-width: 92px;
  border-radius: 50%;
  position: relative;
  display: grid;
  place-items: center;
  background: conic-gradient(
    var(--pl-green) calc(var(--pl-review-pct) * 1%),
    var(--pl-border) 0
  );
}

.pl-review-ring.pl-review-ring::before {
  content: "";
  position: absolute;
  inset: 9px;
  border-radius: 50%;
  background: var(--pl-panel-1);
}

.pl-review-ring-pct.pl-review-ring-pct {
  position: relative;
  z-index: 1;
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 1.35rem;
  color: var(--pl-text);
}

.pl-review-state.pl-review-state {
  display: flex;
  flex-direction: column;
  gap: 2px;
}

.pl-review-state-label.pl-review-state-label {
  margin: 0;
  font-weight: 600;
  color: var(--pl-text);
}

/* ── Breakdown rows ── */

.pl-review-breakdown.pl-review-breakdown {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.pl-review-breakdown-row.pl-review-breakdown-row {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 6px 0;
  border-top: 1px solid var(--pl-border);
}

.pl-review-breakdown-row.pl-review-breakdown-row:first-child {
  border-top: none;
}

.pl-review-dot.pl-review-dot {
  width: 8px;
  height: 8px;
  min-width: 8px;
  border-radius: 50%;
  background: var(--pl-faint);
}

.pl-review-dot-unresolved_decisions.pl-review-dot-unresolved_decisions,
.pl-review-dot-undecided_domains.pl-review-dot-undecided_domains {
  background: var(--pl-amber);
}

.pl-review-dot-missing_assets.pl-review-dot-missing_assets {
  background: var(--pl-red);
}

.pl-review-dot-vague_notes.pl-review-dot-vague_notes {
  background: var(--pl-faint);
}

.pl-review-breakdown-label.pl-review-breakdown-label {
  flex: 1;
  font-size: 0.9rem;
  color: var(--pl-text);
}

.pl-review-fix-btn.pl-review-fix-btn {
  min-height: 32px;
  padding: 0 10px;
}

.pl-review-fix-btn.pl-review-fix-btn:disabled {
  visibility: hidden;
}

/* ── Open questions ── */

.pl-review-empty.pl-review-empty {
  margin: 0;
}

.pl-review-oq-list.pl-review-oq-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 10px;
  max-height: 360px;
  overflow-y: auto;
}

.pl-review-oq-row.pl-review-oq-row {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 10px;
  padding: 8px 0;
  border-top: 1px solid var(--pl-border);
}

.pl-review-oq-row.pl-review-oq-row:first-child {
  border-top: none;
}

.pl-review-oq-text.pl-review-oq-text {
  margin: 0;
  flex: 1;
}

.pl-review-oq-link.pl-review-oq-link {
  background: none;
  border: none;
  padding: 0;
  margin: 0;
  text-align: left;
  color: var(--pl-text);
  font-size: 0.92rem;
  line-height: 1.4;
  cursor: pointer;
  min-height: 24px;
}

.pl-review-oq-link.pl-review-oq-link:disabled {
  cursor: default;
  color: var(--pl-muted);
}

.pl-review-oq-link.pl-review-oq-link:not(:disabled):hover,
.pl-review-oq-link.pl-review-oq-link:not(:disabled):focus-visible {
  text-decoration: underline;
}

/* ═══ 3 · Recap + signed banner ═══════════════════════════════════════ */

.pl-review-recap.pl-review-recap {
  color: var(--pl-muted);
  font-size: 0.92rem;
}

.pl-review-recap.pl-review-recap p {
  margin: 0;
}

.pl-review-signed-banner.pl-review-signed-banner {
  margin: 0;
  padding: 10px 14px;
  border-radius: 10px;
  background: color-mix(in srgb, var(--pl-green) 12%, transparent);
  border: 1px solid color-mix(in srgb, var(--pl-green) 35%, transparent);
  color: var(--pl-green);
  font-weight: 600;
  font-size: 0.92rem;
}

/* ═══ 4 · Action row ═══════════════════════════════════════════════════ */

.pl-review-actions.pl-review-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
}

.pl-review-actions.pl-review-actions button {
  min-height: 44px;
}

.pl-review-export-anchor.pl-review-export-anchor {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
}

/* ═══ 5 · Confirm / postcard dialogs ══════════════════════════════════ */

.pl-review-overlay.pl-review-overlay {
  position: fixed;
  inset: 0;
  z-index: 79;
  display: flex;
  align-items: center;
  justify-content: center;
  background: rgba(15, 23, 42, 0.45);
  padding: 16px;
}

.pl-review-overlay.pl-review-overlay[hidden] {
  display: none;
}

.pl-review-dialog.pl-review-dialog {
  position: relative;
  z-index: 80;
  width: min(420px, 100%);
  max-height: calc(100dvh - 32px);
  overflow-y: auto;
  background: var(--pl-panel-1);
  border: 1px solid var(--pl-glass-border);
  border-radius: 14px;
  box-shadow: var(--pl-shadow-float);
  padding: 22px;
  display: flex;
  flex-direction: column;
  gap: 12px;
}

.pl-review-dialog-h.pl-review-dialog-h {
  margin: 0;
  font-family: var(--font-display);
  font-size: 1.3rem;
  color: var(--pl-text);
}

.pl-review-dialog-body.pl-review-dialog-body {
  margin: 0;
  color: var(--pl-muted);
  line-height: 1.5;
}

.pl-review-dialog-actions.pl-review-dialog-actions {
  display: flex;
  flex-direction: column;
  gap: 8px;
  margin-top: 4px;
}

.pl-review-dialog-actions.pl-review-dialog-actions button {
  min-height: 44px;
  width: 100%;
}

.pl-review-postcard-list.pl-review-postcard-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 8px;
  color: var(--pl-text);
  font-size: 0.92rem;
}

.pl-review-postcard-list.pl-review-postcard-list li {
  padding-left: 20px;
  position: relative;
}

.pl-review-postcard-list.pl-review-postcard-list li::before {
  content: "\2713";
  position: absolute;
  left: 0;
  color: var(--pl-green);
}

@media (max-width: 640px) {
  .pl-review.pl-review {
    padding: 16px 16px 32px;
  }

  .pl-review-dialog.pl-review-dialog {
    width: 100%;
  }
}

/* ═══ 6 · Reduced motion ═══════════════════════════════════════════════ */

@media (prefers-reduced-motion: reduce) {
  .pl-review-ring.pl-review-ring {
    transition: none;
  }
}

/* ─────────────────────────────────────────────────────────────────────────
   wavef-composer.css — composer.rs: the page-type picker → element composer
   → priced Generate modal (`PlannerComposer`). New surface, `docs/PAGE_TYPES.md`
   §4 + `page-type-picker.png` / `element-composer.png`.

   OWNER: composer.rs agent. Tokens only (var(--pl-*)), 44px touch targets,
   [hidden] guard on the overlay (component never unmounts the DOM, only
   toggles the attribute — HYDRATION LAW), reduced-motion respected. Doubled
   selectors (.pl-x.pl-x) so this wins regardless of stylesheet append order
   relative to main.css and other concurrent scratch/*.css files, per the
   card-grid.css convention (main.css:16605-16621).

   Markup verified live against composer.rs on 2026-08-16.
   ───────────────────────────────────────────────────────────────────────── */

/* ═══ 1 · Overlay + dialog shell ══════════════════════════════════════════
   Markup: <div class="pl-comp-overlay" [hidden]> <div class="pl-comp-dialog"
   role="dialog"> <button class="pl-comp-x">
   ═══════════════════════════════════════════════════════════════════════ */

.pl-comp-overlay.pl-comp-overlay {
  position: fixed;
  inset: 0;
  background: var(--pl-modal-backdrop);
  backdrop-filter: blur(4px);
  -webkit-backdrop-filter: blur(4px);
  z-index: 85;
  display: flex;
  align-items: flex-start;
  justify-content: center;
  overflow-y: auto;
  padding: 40px 16px;
}

.pl-comp-overlay.pl-comp-overlay[hidden] {
  display: none !important;
}

.pl-comp-dialog.pl-comp-dialog {
  position: relative;
  width: 100%;
  max-width: min(920px, 92vw);
  background: var(--pl-panel-1);
  border: 1px solid var(--pl-border);
  border-radius: 16px;
  box-shadow: var(--pl-modal-shadow);
  padding: 28px 28px 24px;
  box-sizing: border-box;
  animation: pl-comp-in 220ms ease-out;
}

@keyframes pl-comp-in {
  from {
    opacity: 0;
    transform: translateY(8px) scale(0.98);
  }
  to {
    opacity: 1;
    transform: translateY(0) scale(1);
  }
}

@media (prefers-reduced-motion: reduce) {
  .pl-comp-dialog.pl-comp-dialog {
    animation: none;
  }
}

.pl-comp-x.pl-comp-x {
  position: absolute;
  top: 16px;
  right: 16px;
  width: 44px;
  height: 44px;
  display: flex;
  align-items: center;
  justify-content: center;
  background: transparent;
  border: none;
  border-radius: 8px;
  color: var(--pl-faint);
  font-size: 15px;
  cursor: pointer;
  transition: background 150ms, color 150ms;
}

.pl-comp-x.pl-comp-x:hover {
  background: var(--pl-block);
  color: var(--pl-text);
}

.pl-comp-x.pl-comp-x:focus-visible {
  outline: 2px solid var(--pl-blue);
  outline-offset: 2px;
}

/* ═══ 2 · Header block (shared: picker / compose / success) ══════════════
   Markup: <p class="pl-comp-eyebrow"> <h2 class="pl-comp-h2"> <p class="pl-comp-sub">
   ═══════════════════════════════════════════════════════════════════════ */

.pl-comp-eyebrow.pl-comp-eyebrow {
  margin: 0 0 6px;
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--pl-faint);
}

.pl-comp-h2.pl-comp-h2 {
  margin: 0 0 6px;
  font-family: var(--font-sans);
  font-size: 22px;
  font-weight: 700;
  color: var(--pl-text);
  padding-right: 40px;
}

.pl-comp-sub.pl-comp-sub {
  margin: 0 0 20px;
  font-size: 13px;
  color: var(--pl-muted);
  line-height: 1.5;
}

/* ═══ 3 · Page-type picker grid ═══════════════════════════════════════════
   Markup: <div class="pl-comp-grid"> <button class="pl-comp-card"> <div
   class="pl-comp-icon pl-comp-icon-grid"> <span class="pl-comp-badge
   pl-comp-badge-rec"> <span class="pl-comp-card-name"> <span
   class="pl-comp-card-desc">
   ═══════════════════════════════════════════════════════════════════════ */

.pl-comp-grid.pl-comp-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(170px, 1fr));
  gap: 12px;
}

.pl-comp-card.pl-comp-card {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 8px;
  height: 100%;
  min-height: 44px;
  padding: 16px;
  background: var(--pl-panel-2);
  border: 1px solid var(--pl-border);
  border-radius: 10px;
  cursor: pointer;
  text-align: left;
  transition: border-color 150ms, transform 150ms, box-shadow 150ms;
}

.pl-comp-card.pl-comp-card:hover {
  border-color: var(--pl-blue);
  transform: translateY(-1px);
  box-shadow: var(--pl-shadow-card);
}

.pl-comp-card.pl-comp-card:focus-visible {
  outline: 2px solid var(--pl-blue);
  outline-offset: 2px;
}

.pl-comp-card-rec.pl-comp-card-rec {
  border-color: color-mix(in srgb, var(--pl-amber) 55%, var(--pl-border));
  background: color-mix(in srgb, var(--pl-amber) 8%, var(--pl-panel-2));
}

.pl-comp-card-name.pl-comp-card-name {
  font-size: 14px;
  font-weight: 600;
  color: var(--pl-text);
}

.pl-comp-card-desc.pl-comp-card-desc {
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 3;
  overflow: hidden;
  font-size: 12px;
  line-height: 1.45;
  color: var(--pl-muted);
}

/* Decorative layout-family glyph — abstract, not a literal icon font, so it
   never fights the client-voiced copy for attention (Doctrine 1). */
.pl-comp-icon.pl-comp-icon {
  width: 100%;
  height: 28px;
  display: grid;
  gap: 3px;
  opacity: 0.55;
}

.pl-comp-icon-grid.pl-comp-icon-grid {
  grid-template-columns: repeat(2, 1fr);
  grid-template-rows: repeat(2, 1fr);
}

.pl-comp-icon-grid.pl-comp-icon-grid::before,
.pl-comp-icon-grid.pl-comp-icon-grid::after {
  content: "";
  background: var(--pl-faint);
  border-radius: 2px;
}

.pl-comp-icon-split.pl-comp-icon-split {
  grid-template-columns: 1.6fr 1fr;
}

.pl-comp-icon-split.pl-comp-icon-split::before,
.pl-comp-icon-split.pl-comp-icon-split::after {
  content: "";
  background: var(--pl-faint);
  border-radius: 2px;
}

.pl-comp-icon-stacked-list.pl-comp-icon-stacked-list {
  grid-template-rows: repeat(3, 1fr);
}

.pl-comp-icon-stacked-list.pl-comp-icon-stacked-list::before,
.pl-comp-icon-stacked-list.pl-comp-icon-stacked-list::after {
  content: "";
  background: var(--pl-faint);
  border-radius: 2px;
}

.pl-comp-icon-header-plus-repeat.pl-comp-icon-header-plus-repeat {
  grid-template-rows: 0.6fr 1fr;
}

.pl-comp-icon-header-plus-repeat.pl-comp-icon-header-plus-repeat::before,
.pl-comp-icon-header-plus-repeat.pl-comp-icon-header-plus-repeat::after {
  content: "";
  background: var(--pl-faint);
  border-radius: 2px;
}

/* ═══ 4 · Recommended / Suggested badges ══════════════════════════════════
   Shared pill shape; two placements (picker card corner, element row head).
   ═══════════════════════════════════════════════════════════════════════ */

.pl-comp-badge.pl-comp-badge {
  display: inline-flex;
  align-items: center;
  padding: 2px 8px;
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  border-radius: 999px;
  color: var(--pl-amber);
  background: color-mix(in srgb, var(--pl-amber) var(--pl-chip-bg-mix), transparent);
  border: 1px solid color-mix(in srgb, var(--pl-amber) var(--pl-chip-border-mix), transparent);
  white-space: nowrap;
}

.pl-comp-badge-rec.pl-comp-badge-rec {
  position: absolute;
  top: 12px;
  right: 12px;
}

/* ═══ 5 · Element list rows ════════════════════════════════════════════════
   Markup: <div class="pl-comp-list"> <div class="pl-comp-row"> <button
   role="switch" class="pl-comp-switch"> <span class="pl-comp-switch-thumb">
   <div class="pl-comp-row-body"> <div class="pl-comp-row-head"> <span
   class="pl-comp-row-label"> <span class="pl-comp-row-id"> <p
   class="pl-comp-row-why"> <label class="pl-comp-shows-label"> <input
   class="pl-comp-shows-input"> <p class="pl-comp-dep-line">
   ═══════════════════════════════════════════════════════════════════════ */

.pl-comp-list.pl-comp-list {
  display: grid;
  gap: 8px;
}

.pl-comp-row.pl-comp-row {
  display: flex;
  gap: 12px;
  padding: 12px 14px;
  background: var(--pl-panel-2);
  border: 1px solid var(--pl-border);
  border-radius: 10px;
}

.pl-comp-row-suggested.pl-comp-row-suggested {
  border-color: color-mix(in srgb, var(--pl-amber) 55%, var(--pl-border));
  background: color-mix(in srgb, var(--pl-amber) 6%, var(--pl-panel-2));
}

.pl-comp-switch.pl-comp-switch {
  flex: 0 0 auto;
  width: 44px;
  height: 24px;
  padding: 2px;
  margin-top: 2px;
  background: var(--pl-track);
  border: 1px solid var(--pl-border);
  border-radius: 999px;
  cursor: pointer;
  display: flex;
  align-items: center;
  transition: background 150ms;
}

.pl-comp-switch.pl-comp-switch:disabled {
  cursor: default;
  opacity: 0.7;
}

.pl-comp-switch.pl-comp-switch:focus-visible {
  outline: 2px solid var(--pl-blue);
  outline-offset: 2px;
}

.pl-comp-switch-on.pl-comp-switch-on {
  background: var(--pl-green);
  border-color: var(--pl-green);
}

.pl-comp-switch-thumb.pl-comp-switch-thumb {
  width: 18px;
  height: 18px;
  border-radius: 50%;
  background: #fff;
  box-shadow: 0 1px 2px rgba(15, 23, 42, 0.3);
  transition: transform 150ms;
}

.pl-comp-switch-on.pl-comp-switch-on .pl-comp-switch-thumb.pl-comp-switch-thumb {
  transform: translateX(18px);
}

@media (prefers-reduced-motion: reduce) {
  .pl-comp-switch.pl-comp-switch,
  .pl-comp-switch-thumb.pl-comp-switch-thumb {
    transition: none;
  }
}

.pl-comp-row-body.pl-comp-row-body {
  flex: 1 1 auto;
  min-width: 0;
  display: grid;
  gap: 6px;
}

.pl-comp-row-head.pl-comp-row-head {
  display: flex;
  align-items: center;
  gap: 8px;
  flex-wrap: wrap;
}

.pl-comp-row-label.pl-comp-row-label {
  font-size: 13px;
  font-weight: 600;
  color: var(--pl-text);
}

.pl-comp-row-id.pl-comp-row-id {
  margin-left: auto;
  font-family: var(--font-mono);
  font-size: 10px;
  color: var(--pl-faint);
  white-space: nowrap;
}

.pl-comp-row-why.pl-comp-row-why {
  margin: 0;
  font-size: 12px;
  line-height: 1.5;
  color: var(--pl-muted);
}

.pl-comp-shows-label.pl-comp-shows-label {
  display: grid;
  gap: 4px;
  font-size: 10px;
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--pl-faint);
}

.pl-comp-shows-input.pl-comp-shows-input {
  min-height: 36px;
  padding: 8px 10px;
  background: var(--pl-panel-1);
  border: 1px solid var(--pl-border);
  border-radius: 6px;
  color: var(--pl-text);
  font-family: var(--font-sans);
  font-size: 13px;
  text-transform: none;
  letter-spacing: normal;
  font-weight: 400;
  box-sizing: border-box;
}

.pl-comp-shows-input.pl-comp-shows-input:focus {
  outline: none;
  border-color: var(--pl-blue);
  box-shadow: 0 0 0 2px color-mix(in srgb, var(--pl-blue) 20%, transparent);
}

.pl-comp-shows-input.pl-comp-shows-input::placeholder {
  color: var(--pl-faint);
}

.pl-comp-dep-line.pl-comp-dep-line {
  margin: 2px 0 0;
  font-size: 11px;
  line-height: 1.5;
  color: var(--pl-amber);
}

/* ═══ 6 · Collapse row, Other…, cap message, toast ════════════════════════
   Markup: <button class="pl-comp-more"> <div class="pl-comp-other"> <button
   class="pl-comp-other-toggle"> <div class="pl-comp-other-body"> <input
   class="pl-comp-other-input"> <p class="pl-comp-cap-msg"> <p class="pl-comp-toast">
   ═══════════════════════════════════════════════════════════════════════ */

.pl-comp-more.pl-comp-more {
  min-height: 40px;
  margin-top: 4px;
  padding: 8px 14px;
  background: transparent;
  border: 1px dashed var(--pl-border);
  border-radius: 8px;
  color: var(--pl-muted);
  font-size: 12px;
  text-align: left;
  cursor: pointer;
}

.pl-comp-more.pl-comp-more:hover {
  border-color: var(--pl-blue);
  color: var(--pl-text);
}

.pl-comp-other.pl-comp-other {
  margin-top: 10px;
}

.pl-comp-other-toggle.pl-comp-other-toggle {
  min-height: 40px;
  padding: 8px 14px;
  width: 100%;
  background: var(--pl-panel-2);
  border: 1px solid var(--pl-border);
  border-radius: 8px;
  color: var(--pl-muted);
  font-size: 13px;
  text-align: left;
  cursor: pointer;
}

.pl-comp-other-body.pl-comp-other-body {
  display: flex;
  gap: 8px;
  margin-top: 8px;
}

.pl-comp-other-input.pl-comp-other-input {
  flex: 1 1 auto;
  min-height: 40px;
  padding: 8px 10px;
  background: var(--pl-panel-1);
  border: 1px solid var(--pl-border);
  border-radius: 6px;
  color: var(--pl-text);
  font-family: var(--font-sans);
  font-size: 13px;
  box-sizing: border-box;
}

.pl-comp-other-input.pl-comp-other-input::placeholder {
  color: var(--pl-faint);
}

.pl-comp-cap-msg.pl-comp-cap-msg {
  margin: 10px 0 0;
  font-size: 12px;
  color: var(--pl-amber);
}

.pl-comp-toast.pl-comp-toast {
  margin: 10px 0 0;
  font-size: 12px;
  color: var(--pl-red);
}

/* ═══ 7 · Footer + success step ═══════════════════════════════════════════
   Markup: <div class="pl-comp-footer"> <button class="pl-comp-close-link">
   <button class="pl-btn"> · <div class="pl-comp-success"> <p
   class="pl-comp-success-msg">
   ═══════════════════════════════════════════════════════════════════════ */

.pl-comp-footer.pl-comp-footer {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  margin-top: 20px;
  padding-top: 16px;
  border-top: 1px solid var(--pl-border);
}

.pl-comp-close-link.pl-comp-close-link {
  min-height: 44px;
  padding: 0 8px;
  background: transparent;
  border: none;
  color: var(--pl-muted);
  font-size: 13px;
  cursor: pointer;
}

.pl-comp-close-link.pl-comp-close-link:hover {
  color: var(--pl-text);
}

.pl-comp-success.pl-comp-success {
  padding: 12px 0 4px;
}

.pl-comp-success-msg.pl-comp-success-msg {
  margin: 8px 0 0;
  padding: 14px 16px;
  background: color-mix(in srgb, var(--pl-green) 12%, var(--pl-panel-2));
  border: 1px solid color-mix(in srgb, var(--pl-green) 40%, var(--pl-border));
  border-radius: 8px;
  color: var(--pl-text);
  font-size: 14px;
  font-weight: 600;
}

/* ═══ 8 · Narrow viewports ═════════════════════════════════════════════════
   Mobile delta per PLANNER_IA.md: same content, one column, dialog fills
   the available width instead of centering in a fixed max-width card.
   ═══════════════════════════════════════════════════════════════════════ */

@media (max-width: 640px) {
  .pl-comp-dialog.pl-comp-dialog {
    max-width: 100%;
    padding: 22px 18px 20px;
  }

  .pl-comp-grid.pl-comp-grid {
    grid-template-columns: 1fr 1fr;
  }

  .pl-comp-row.pl-comp-row {
    flex-direction: column;
  }

  .pl-comp-switch.pl-comp-switch {
    margin-top: 0;
  }

  .pl-comp-footer.pl-comp-footer {
    flex-direction: column-reverse;
    align-items: stretch;
  }

  .pl-comp-footer.pl-comp-footer .pl-btn {
    width: 100%;
  }
}

/* ── AI copilot ("Ask D3pth") — crates/d3pth-web/src/planner/copilot.rs ──
   Tokens only (--pl-* custom properties already defined under `.pl-app` in
   main.css — see its :root / [data-pl-theme="dark"] blocks; nothing new is
   invented here). Idea cards inside the transcript reuse main.css's
   existing `.pl-idea-*` classes verbatim (same visual system as
   detail_view.rs's Ideas rail) — no new rules for those below.

   Z-bands (docs/PLANNER_LAYOUT.md): launcher = 40 (Floating Bars, pinned to
   a viewport edge); overlay/sheet = 79/80 (Modal Backdrop/Modal), same band
   every other planner-root sheet (Activity, Saves, Palette) uses. */

/* ── Launcher ─────────────────────────────────────────────────────────── */

.pl-copilot-launcher {
  position: fixed;
  right: 20px;
  bottom: 20px;
  z-index: 40; /* z-scale: floating-bar band */
  display: flex;
  align-items: center;
  gap: 8px;
  min-height: 44px; /* NAR touch target min */
  padding: 0 18px 0 14px;
  border: 1px solid var(--pl-glass-border);
  border-radius: 999px;
  background: var(--pl-glass-bg);
  backdrop-filter: blur(16px) saturate(1.3);
  -webkit-backdrop-filter: blur(16px) saturate(1.3);
  box-shadow: var(--pl-shadow-float, var(--pl-glass-shadow));
  color: var(--pl-text);
  font-size: 0.85rem;
  font-weight: 700;
  cursor: pointer;
  transition: transform 0.15s ease;
}

.pl-copilot-launcher:hover {
  transform: translateY(-1px);
}

.pl-copilot-launcher[hidden] {
  display: none !important;
}

@supports not ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
  .pl-copilot-launcher {
    background: var(--pl-panel-2, var(--pl-panel-1));
  }
}

.pl-copilot-launcher-icon {
  font-size: 1rem;
  line-height: 1;
}

/* ── Overlay + sheet ──────────────────────────────────────────────────── */

.pl-copilot-overlay {
  position: fixed;
  inset: 0;
  z-index: 79; /* z-scale: modal backdrop band */
  background: var(--pl-modal-backdrop);
}

.pl-copilot-overlay[hidden] {
  display: none;
}

.pl-copilot-sheet {
  position: fixed;
  top: 0;
  right: 0;
  z-index: 80; /* z-scale: modal band */
  display: flex;
  flex-direction: column;
  width: min(420px, 100vw);
  max-height: 100dvh;
  background: var(--pl-panel-1);
  border-left: 1px solid var(--pl-border);
  box-shadow: var(--pl-modal-shadow);
  outline: none;
}

.pl-copilot-sheet[hidden] {
  display: none;
}

.pl-copilot-head {
  flex-shrink: 0;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.75rem;
  padding: 1rem 1.25rem;
  border-bottom: 1px solid var(--pl-border);
}

.pl-copilot-head h2 {
  margin: 0;
  font-size: 1.05rem;
  font-weight: 700;
  color: var(--pl-text);
}

.pl-copilot-close {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 44px; /* NAR touch target min */
  height: 44px;
  border: none;
  background: transparent;
  color: var(--pl-muted);
  font-size: 1.1rem;
  cursor: pointer;
  border-radius: var(--radius-card);
}

.pl-copilot-close:hover {
  background: var(--pl-block);
  color: var(--pl-text);
}

/* ── Transcript ───────────────────────────────────────────────────────── */

.pl-copilot-body {
  flex: 1;
  overflow-y: auto;
  display: flex;
  flex-direction: column;
  gap: 0.6rem;
  padding: 1rem 1.25rem;
}

.pl-copilot-empty {
  margin: 0;
  padding: 0.5rem 0;
  color: var(--pl-faint);
  font-size: 0.88rem;
}

.pl-copilot-empty[hidden] {
  display: none;
}

.pl-copilot-turn {
  max-width: 92%;
  padding: 0.6rem 0.75rem;
  border-radius: var(--radius-card);
  font-size: 0.88rem;
  line-height: 1.45;
}

.pl-copilot-turn p {
  margin: 0;
}

.pl-copilot-turn-user {
  align-self: flex-end;
  background: var(--pl-blue);
  color: #ffffff;
}

.pl-copilot-turn-reply {
  align-self: flex-start;
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
  background: var(--pl-block);
  color: var(--pl-text);
}

.pl-copilot-turn-fallback {
  align-self: flex-start;
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
  background: var(--pl-block);
  border: 1px dashed var(--pl-border);
  color: var(--pl-text);
}

.pl-copilot-turn-action {
  align-self: flex-start;
}

.pl-copilot-ideas-list {
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
}

/* ── Quick-ask chips ──────────────────────────────────────────────────── */

.pl-copilot-chips {
  flex-shrink: 0;
  display: flex;
  flex-wrap: wrap;
  gap: 0.4rem;
  padding: 0.6rem 1.25rem;
  border-top: 1px solid var(--pl-border);
  max-height: 6.5rem;
  overflow-y: auto;
}

.pl-copilot-chip {
  min-height: 44px; /* NAR touch target min */
  padding: 0 0.75rem;
  border: 1px solid var(--pl-border);
  border-radius: 999px;
  background: var(--pl-panel-1);
  color: var(--pl-text);
  font-size: 0.78rem;
  font-weight: 600;
  cursor: pointer;
}

.pl-copilot-chip:hover {
  background: var(--pl-block);
}

/* ── Free-text input ──────────────────────────────────────────────────── */

.pl-copilot-input-row {
  flex-shrink: 0;
  display: flex;
  gap: 0.5rem;
  padding: 0.75rem 1.25rem;
  border-top: 1px solid var(--pl-border);
}

.pl-copilot-input {
  flex: 1;
  min-width: 0;
  min-height: 44px; /* NAR touch target min */
  padding: 0 0.75rem;
  border: 1px solid var(--pl-border);
  border-radius: var(--radius-card);
  background: var(--pl-panel-1);
  color: var(--pl-text);
  font-size: 0.88rem;
}

.pl-copilot-input:focus-visible {
  outline: 2px solid var(--pl-blue);
  outline-offset: 1px;
}

.pl-copilot-send {
  flex-shrink: 0;
  min-width: 44px;
  min-height: 44px;
  height: 44px;
  padding: 0 0 0.5px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border: none;
  border-radius: 10px;
  background: var(--pl-btn-green-grad);
  color: #ffffff;
  font-size: 1.1rem;
  line-height: 1;
  cursor: pointer;
  box-shadow: var(--pl-btn-green-shadow), var(--pl-cta-glow-green);
}

.pl-copilot-send:hover {
  filter: brightness(1.08);
}

/* ── NAR (phone): fullscreen sheet, same rule as Activity/Saves ─────────── */

@media (max-width: 640px) {
  .pl-copilot-sheet {
    width: 100vw;
    height: 100dvh;
  }

  .pl-copilot-head {
    position: sticky;
    top: 0;
    background: var(--pl-panel-1);
  }
}

/* ── Reduced motion ───────────────────────────────────────────────────── */

@media (prefers-reduced-motion: reduce) {
  .pl-copilot-launcher,
  .pl-copilot-sheet,
  .pl-copilot-overlay,
  .pl-copilot-send {
    transition: none !important;
  }
}

/* ═══ Feature duels — inline side-by-side compare ══════════════════════════
   Owner: detail_view.rs (feature_card / feature_duel).
   Markup: .pl-feat-pick-row > .pl-duel-open-btn (toggle, only rendered when
   the feature has >=2 variants) then, as a sibling of .pl-feat-pick-row,
   .pl-duel[hidden] > .pl-duel-pair > .pl-duel-panel* + .pl-duel-caption.
   `.pl-duel` is always in the DOM and toggled via the `hidden` attribute
   (never Show/if) — same discipline as tour.rs's idle rail, so SSR/hydrate
   DOM shape stays byte-identical.
   Tokens only, reused from main.css's palette (--pl-border, --pl-panel-1/2,
   --pl-text, --pl-sky) — nothing new introduced here.
   docs/planner-ia-mockups/feature-duel.png is the visual source.
   ═══════════════════════════════════════════════════════════════════════ */

.pl-duel-open-btn.pl-duel-open-btn {
  margin-left: auto;
}

.pl-duel.pl-duel {
  display: flex;
  flex-direction: column;
  gap: 8px;
  margin-top: 10px;
  padding-top: 10px;
  border-top: 1px dashed var(--pl-border);
}

.pl-duel-pair.pl-duel-pair {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 10px;
}

@media (max-width: 640px) {
  .pl-duel-pair.pl-duel-pair {
    grid-template-columns: 1fr;
  }
}

.pl-duel-panel.pl-duel-panel {
  display: flex;
  flex-direction: column;
  gap: 8px;
  padding: 8px;
  border: 1px solid var(--pl-border);
  border-radius: 8px;
  background: var(--pl-panel-1);
}

.pl-duel-tag.pl-duel-tag {
  align-self: flex-start;
  padding: 2px 8px;
  border: 1px solid var(--pl-sky);
  border-radius: 999px;
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--pl-sky);
}

.pl-duel-pic.pl-duel-pic {
  border-radius: 6px;
}

.pl-duel-pick-btn.pl-duel-pick-btn {
  align-self: stretch;
  justify-content: center;
}

.pl-duel-caption.pl-duel-caption {
  margin: 0;
  font-size: 12px;
  color: var(--pl-text-dim, var(--pl-text));
  opacity: 0.75;
}

@media (prefers-reduced-motion: reduce) {
  .pl-duel-open-btn.pl-duel-open-btn {
    transition: none;
  }
}

/* ═════════════════════════════════════════════════════════════════════════
   rem-journey.css — Journey lens (map_view.rs)

   OWNER: map_view.rs agent. Tokens only (var(--pl-*)), [hidden] guards,
   44px touch targets, reduced-motion respected. Every selector below is
   new (pl-journey-toggle, pl-journey-subhead, pl-chip-journey-step,
   pl-journey-missing*) — nothing here touches classes owned by other
   scratch files. Meant to be appended after main.css and every other
   concurrent scratch/*.css file, per the card-grid.css / sitescope.css
   convention (see the header comment on that file in main.css).

   PLANNER_IA.md §L1 / COPY_DECK.md §3: opt-in overlay, off by default —
   every rule here only ever affects markup that map_view.rs itself only
   mounts once the reviewer switches Journey lens on (`.then()`-gated in
   Rust, not just `[hidden]` here) — so "off" really is zero extra paint,
   not just zero-opacity DOM.
   ═════════════════════════════════════════════════════════════════════════ */

/* ── Toggle entry point (chart heading row) ──────────────────────────── */

.pl-journey-toggle {
  display: inline-flex;
  align-items: center;
  flex-shrink: 0;
  min-height: 32px;
  padding: 4px 12px;
  border-radius: 999px;
  font-family: var(--font-sans);
  font-size: 12px;
  font-weight: 600;
  background: transparent;
  border: 1px solid var(--pl-border);
  color: var(--pl-muted);
  cursor: pointer;
  transition: background 150ms, border-color 150ms, color 150ms;
}

.pl-journey-toggle:hover {
  border-color: color-mix(in srgb, var(--pl-green) 45%, var(--pl-border));
  color: var(--pl-text);
}

.pl-journey-toggle:focus-visible {
  outline: 2px solid var(--pl-green);
  outline-offset: 2px;
}

.pl-journey-toggle[aria-pressed="true"] {
  background: color-mix(in srgb, var(--pl-green) 16%, transparent);
  border-color: color-mix(in srgb, var(--pl-green) 55%, var(--pl-border));
  color: var(--pl-green);
}

.pl-journey-toggle[hidden] {
  display: none !important;
}

/* ── Subhead (COPY_DECK.md §3, verbatim) ──────────────────────────────── */

.pl-journey-subhead {
  margin: -8px 0 14px;
  font-size: 12.5px;
  color: var(--pl-muted);
}

.pl-journey-subhead[hidden] {
  display: none !important;
}

/* ── Stage-label ribbon on a matched picture-node ─────────────────────── */
/* Lives directly on `.pl-node` (already `position:relative`), NOT inside
   `.pl-pic-caption` — see the comment in map_view.rs on why. Sits over the
   face image's top-left corner like a corner tag. */

.pl-chip-journey-step {
  position: absolute;
  top: 6px;
  left: 6px;
  z-index: 1;
  display: inline-flex;
  align-items: center;
  padding: 3px 7px;
  border-radius: 4px;
  font-family: var(--font-mono);
  font-size: 8.5px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: #ffffff;
  background: color-mix(in srgb, var(--pl-green) 82%, black 8%);
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.35);
}

.pl-chip-journey-step-alert {
  background: color-mix(in srgb, var(--pl-red) 82%, black 8%);
}

/* ── Missing-step callout card ────────────────────────────────────────── */
/* A page-grid item like any other `.pl-page-cell` — sits in the same row
   as the real picture-nodes, "the map's way of surfacing a gap without a
   separate report screen" (PLANNER_IA.md §L1). */

.pl-journey-missing-cell {
  align-items: stretch;
}

.pl-journey-missing {
  display: flex;
  flex-direction: column;
  gap: 8px;
  width: 100%;
  padding: 12px;
  border-radius: 12px;
  background: color-mix(in srgb, var(--pl-red) 7%, var(--pl-panel-2));
  border: 1px solid color-mix(in srgb, var(--pl-red) 45%, var(--pl-border));
  box-shadow: var(--pl-shadow-card);
}

/* Scoped-mode picture-nodes fill their grid cell (sitescope.css); the
   missing card matches that so it doesn't sit narrower than its siblings. */
.pl-chart-cluster-grid--scoped .pl-journey-missing {
  min-width: 0;
}

.pl-journey-missing-badge {
  align-self: flex-start;
  font-family: var(--font-mono);
  font-size: 9px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--pl-red);
}

.pl-journey-missing-body {
  margin: 0;
  font-size: 12px;
  line-height: 1.45;
  color: var(--pl-text);
}

.pl-journey-add-btn {
  align-self: flex-start;
  min-height: 44px;
  padding: 8px 16px;
  border-radius: 8px;
  border: none;
  background: var(--pl-blue);
  color: #ffffff;
  font-family: var(--font-sans);
  font-size: 13px;
  font-weight: 600;
  cursor: pointer;
  transition: background 150ms;
}

.pl-journey-add-btn:hover {
  background: color-mix(in srgb, var(--pl-blue) 85%, black);
}

.pl-journey-add-btn:focus-visible {
  outline: 2px solid var(--pl-blue);
  outline-offset: 2px;
}

/* ── Reduced motion ────────────────────────────────────────────────────
   Nothing in this sheet animates on its own — the journey lens's motion
   (beads traveling the drawn curves) lives entirely in map_view.rs's
   canvas pass, which already honors `prefers-reduced-motion` (freezes
   `now` at 0, per `prefers_reduced_motion()`). This block only removes
   the transitions above, for the reviewers who also have them disabled. */
@media (prefers-reduced-motion: reduce) {
  .pl-journey-toggle,
  .pl-journey-add-btn {
    transition: none;
  }
}

/* ═════════════════════════════════════════════════════════════════════════
   NAR — max-width: 640px (PLANNER_LAYOUT.md breakpoints)
   ═════════════════════════════════════════════════════════════════════════ */

@media (max-width: 640px) {
  .pl-journey-toggle {
    min-height: 44px;
  }

  .pl-journey-subhead {
    margin-top: 0;
  }
}

/* ═════════════════════════════════════════════════════════════════════════
   Sidebar demarcation + herodot brand accents (appended section — cascade
   order is the override mechanism here: these rules intentionally sit at
   the END of the file so equal-specificity selectors win over the base
   sidebar rules near line 20009).

   1. Sidebar ground is now DISTINCT from the content panels in both themes
      (it used to be var(--pl-panel-1), identical to every card, so the
      seam between nav and work area was invisible).
   2. Contract classes for the brand pass: .pl-sidebar-logo, .pl-dot-rail,
      .pl-brand-dot. Ramp colors REUSE the existing planner accent tokens
      (--pl-blue / --pl-sky / --pl-green) — the same blue-sky-emerald ramp
      the ambience beads and the gradient at ~line 4181 already use. No new
      hex ramps introduced.
   All static — nothing in this section animates, so reduced-motion needs
   no carve-out. Pure CSS; no DOM shape involvement (HYDRATION LAW safe). */

/* ── 1. Sidebar ground — light theme ─────────────────────────────────── */
/* A subtly cooler tint than the white content panels: 5% brand blue mixed
   into panel-1. Hover/edge derive from the same mix so every sidebar
   surface stays coherent on the new ground. */

.pl-sidebar {
  --pl-sidebar-ground: color-mix(in srgb, var(--pl-blue) 5%, var(--pl-panel-1));
  --pl-sidebar-hover: color-mix(in srgb, var(--pl-blue) 10%, var(--pl-panel-1));
  --pl-sidebar-edge: color-mix(in srgb, var(--pl-blue) 16%, var(--pl-border));
  --pl-sidebar-edge-inset: rgba(255, 255, 255, 0.65);
  background: var(--pl-sidebar-ground);
  border-right-color: var(--pl-sidebar-edge);
  /* Crisp seam: 1px inner highlight just inside the (now stronger) border,
     composed with the existing card shadow. */
  box-shadow: inset -1px 0 0 var(--pl-sidebar-edge-inset), var(--pl-shadow-card);
}

/* ── 1b. Sidebar ground — dark theme ─────────────────────────────────── */
/* Deeper navy than the content panels: 28% black into panel-1 lands well
   below both --pl-panel-1 (#0d2445) and --pl-panel-2 (#123256), so the
   nav column reads as its own ground. Edge picks up --pl-sky, matching
   the dark theme's existing sky-glow shadow language. */

.pl-app[data-pl-theme="dark"] .pl-sidebar {
  --pl-sidebar-ground: color-mix(in srgb, #000000 28%, var(--pl-panel-1));
  --pl-sidebar-hover: color-mix(in srgb, #000000 12%, var(--pl-panel-2));
  --pl-sidebar-edge: color-mix(in srgb, var(--pl-sky) 25%, var(--pl-border));
  --pl-sidebar-edge-inset: color-mix(in srgb, var(--pl-sky) 14%, transparent);
}

/* Ring holes punch through to the sidebar ground, not panel-1, so site
   readiness rings don't carry a mismatched lighter disc on the new tint. */
.pl-sidebar .pl-side-ring-hole {
  background: var(--pl-sidebar-ground);
}

/* Hover states re-based on the new ground — the old var(--pl-panel-2)
   hover is nearly identical to the light tint and would vanish. */
.pl-sidebar-btn:hover {
  background: var(--pl-sidebar-hover);
}

.pl-sidebar-mobile-close:hover {
  background: var(--pl-sidebar-hover);
}

/* Section labels: a touch more contrast on the tinted ground (they were
   --pl-faint; mixing 18% ink in keeps the quiet register but clears
   4.5:1 on the new ground in both themes). */
.pl-sidebar-label {
  color: color-mix(in srgb, var(--pl-text) 18%, var(--pl-faint));
}

/* Active row: deepen the accent toward ink so the label clears 4.5:1 on
   the blue-tinted chip over the new ground (light: ~5.0:1, dark: ~4.9:1;
   pure --pl-blue was ~4.1:1 on the light tint). The token mix flips
   correctly in dark, where --pl-text is light and lifts the blue instead. */
.pl-sidebar-btn[aria-current="true"] {
  color: color-mix(in srgb, var(--pl-blue) 85%, var(--pl-text));
  overflow: visible;
  background: color-mix(in srgb, var(--pl-sky) 8%, transparent);
}

/* Mobile drawer (NAR, max-width 640 — the only drawer breakpoint in
   docs/PLANNER_LAYOUT.md; at 641-980 the sidebar stays a fixed column and
   all rules above already apply). The drawer keeps the same distinct
   ground + seam; while open it floats over the scrim, so it takes the
   float shadow for a crisper right edge against dimmed content. */
@media (max-width: 640px) {
  .pl-sidebar[data-pl-mobile-open="true"] {
    box-shadow: inset -1px 0 0 var(--pl-sidebar-edge-inset), var(--pl-shadow-float);
  }
}

/* ── 2. Brand contract classes ───────────────────────────────────────── */

/* Brand mark wrapper in the sidebar top row. 24px box with -4px block
   margin so the top row keeps its 44px rhythm (14px padding both sides
   plus an effective 16px lane). Ramp accent: a quiet blue-sky-emerald
   gradient chip behind the mark. Degrades to nothing when empty. */
.pl-sidebar-logo {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  width: 24px;
  height: 24px;
  margin-block: -4px;
  border-radius: 7px;
  color: var(--pl-blue);
  background: linear-gradient(
    135deg,
    color-mix(in srgb, var(--pl-blue) 14%, transparent),
    color-mix(in srgb, var(--pl-sky) 14%, transparent),
    color-mix(in srgb, var(--pl-green) 14%, transparent)
  );
  border: 1px solid color-mix(in srgb, var(--pl-sky) 35%, var(--pl-border));
}

.pl-sidebar-logo svg,
.pl-sidebar-logo img {
  display: block;
  width: 16px;
  height: 16px;
}

.pl-sidebar-logo:empty {
  display: none;
}

/* Herodot dot rail: short horizontal strip of small dots fading through
   the ramp. Anatomy: the existing 90deg blue-sky-green gradient (same as
   the progress bar at ~line 4181) revealed through a repeating radial dot
   mask — pure CSS, static, no animation. Unsupported-mask fallback shows
   a thin solid ramp strip, which still reads correctly. */
.pl-dot-rail {
  display: block;
  width: 56px;
  height: 6px;
  margin: 4px 0 8px;
  background: linear-gradient(90deg, var(--pl-blue) 0%, var(--pl-sky) 50%, var(--pl-green) 100%);
  -webkit-mask-image: radial-gradient(circle, #000 1.5px, transparent 1.9px);
  -webkit-mask-size: 8px 6px;
  -webkit-mask-repeat: repeat-x;
  -webkit-mask-position: left center;
  mask-image: radial-gradient(circle, #000 1.5px, transparent 1.9px);
  mask-size: 8px 6px;
  mask-repeat: repeat-x;
  mask-position: left center;
}

/* Single inline herodot accent dot for labels. Baseline-aligned: the
   bottom edge of an empty inline-block sits on the text baseline. */
.pl-brand-dot {
  display: inline-block;
  width: 6px;
  height: 6px;
  margin: 0 2px;
  border-radius: 50%;
  background: var(--pl-sky);
  vertical-align: baseline;
}

/* ── 3. Ambience presence knob (CSS-side only) ───────────────────────── */
/* Slight chroma boost on the herodot ambience canvas — presence bump for
   the Overview scatter without touching ambience.rs, its alpha ramps, or
   any draw code. Saturate only: leaves alpha and lightness alone, so the
   reduced-motion still frame is boosted identically. */
.pl-ambience-canvas {
  filter: saturate(1.2);
}

/* ── 4. Reviewer close-out: collapsed rail + L0 heading block ────────── */
/* Rails are unconditional markup in sidebar.rs (hydration-stable shape);
   in the 56px collapsed rail their section labels hide via the hidden
   attribute, so the rails must hide from CSS — display:block on
   .pl-dot-rail would otherwise defeat nothing-to-label geometry. */
.pl-sidebar[data-pl-collapsed="true"] .pl-dot-rail {
  display: none;
}

/* L0 "Whole site" heading block (overview.rs .pl-overview-head): company
   name as the title, herodot rail, one-line model subtitle. */
.pl-overview-head {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 8px;
  margin: 4px 4px 18px;
}

.pl-overview-title {
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 24px;
  line-height: 1.15;
  margin: 0;
  color: var(--pl-text);
  text-wrap: balance;
}

.pl-overview-sub {
  margin: 0;
  font-size: 13.5px;
  line-height: 1.5;
  color: var(--pl-faint);
}

@media (max-width: 640px) {
  .pl-overview-title {
    font-size: 20px;
  }

  .pl-overview-head {
    margin: 2px 2px 14px;
  }
}

/* Looking identity card (overview.rs): company, tap-to-call, service chips,
   live-site hint. Visible by default when genesis.looking is set; [hidden]
   when that object is missing. Tokens only (--pl-*, accent). */
.pl-app .pl-looking-id {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 0.65rem;
  padding: 1.25rem 1.4rem 1.35rem 1.55rem;
  border-radius: var(--radius-card, 0.75rem);
  background:
    linear-gradient(
      165deg,
      color-mix(in srgb, var(--pl-green) 14%, var(--pl-glass-bg, var(--pl-panel-1))),
      var(--pl-glass-bg, var(--pl-panel-1)) 42%
    );
  border: 1px solid color-mix(in srgb, var(--pl-green) 35%, var(--pl-glass-border, var(--pl-border)));
  box-shadow: var(--pl-shadow-card);
  position: relative;
  overflow: hidden;
}

.pl-app .pl-looking-id::before {
  content: "";
  position: absolute;
  left: 0;
  top: 0;
  bottom: 0;
  width: 4px;
  background: var(--pl-green);
}

.pl-app .pl-looking-id[hidden] {
  display: none !important;
}

.pl-app .pl-looking-id-kicker {
  margin: 0;
  font-size: 0.72rem;
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--pl-faint);
}

.pl-app .pl-looking-id-company {
  margin: 0;
  font-family: var(--font-display);
  font-size: 1.55rem;
  font-weight: 700;
  line-height: 1.15;
  color: var(--pl-text);
  letter-spacing: -0.02em;
}

.pl-app .pl-looking-id-tagline {
  margin: 0;
  font-size: 0.92rem;
  line-height: 1.45;
  color: var(--pl-muted);
}

.pl-app .pl-looking-id-tagline[hidden] {
  display: none !important;
}

.pl-app .pl-looking-id-phone {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: 44px;
  padding: 0 1.1rem;
  border-radius: 999px;
  font-weight: 600;
  font-size: 1rem;
  text-decoration: none;
  color: #fff;
  background: var(--pl-green);
  box-shadow: var(--pl-btn-green-shadow);
}

.pl-app .pl-looking-id-phone[hidden] {
  display: none !important;
}

.pl-app .pl-looking-id-phone:hover,
.pl-app .pl-looking-id-phone:focus-visible {
  background: color-mix(in srgb, var(--pl-green) 88%, var(--pl-navy));
}

.pl-app .pl-looking-id-phone:focus-visible {
  outline: 2px solid var(--pl-sky);
  outline-offset: 2px;
}

.pl-app .pl-looking-id-hours,
.pl-app .pl-looking-id-address {
  margin: 0;
  font-size: 0.88rem;
  line-height: 1.4;
  color: var(--pl-muted);
}

.pl-app .pl-looking-id-hours[hidden],
.pl-app .pl-looking-id-address[hidden] {
  display: none !important;
}

.pl-app .pl-looking-id-services {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  list-style: none;
  margin: 0;
  padding: 0;
}

.pl-app .pl-looking-id-chip {
  display: inline-flex;
  align-items: center;
  min-height: 28px;
  padding: 4px 10px;
  border-radius: 999px;
  font-size: 0.8rem;
  color: var(--pl-text);
  background: color-mix(in srgb, var(--pl-green) 12%, var(--pl-panel-2));
  border: 1px solid color-mix(in srgb, var(--pl-green) 40%, var(--pl-border));
}

.pl-app .pl-looking-id-hint {
  margin: 0.15rem 0 0;
  font-size: 0.82rem;
  color: var(--pl-faint);
}

.pl-app .pl-looking-id-hint[hidden] {
  display: none !important;
}

.pl-app .pl-looking-id-hint a {
  color: var(--pl-blue);
  text-decoration: none;
}

.pl-app .pl-looking-id-hint a:hover,
.pl-app .pl-looking-id-hint a:focus-visible {
  text-decoration: underline;
}

@media (prefers-reduced-motion: reduce) {
  .pl-app .pl-looking-id,
  .pl-app .pl-looking-id-phone,
  .pl-app .pl-looking-id-hint a {
    transition: none;
  }
}
/* ─────────────────────────────────────────────────────────────────────────
   seo-detail.css — detail_view.rs: the L2 right-rail "SEO for this page"
   accordion, sitting directly below the Ideas accordion (wave2-ideas.css
   is the visual reference; this file reuses its exact head/body rhythm).

   OWNER: detail_view.rs agent (SEO wave). Tokens only (var(--pl-*)), so
   both themes come from the .pl-app[data-pl-theme="dark"] token flip
   upstream — no per-theme overrides needed here. 44px touch target on the
   head, reduced-motion respected, [hidden] guards on every element this
   file gives a non-none display. Doubled selectors (.pl-x.pl-x) so this
   wins regardless of stylesheet append order relative to main.css and
   other concurrent scratch files, per the card-grid.css convention.

   Structure (see detail_view.rs's SEO block + seo_acc_body):
     .pl-panel.pl-seo-acc
       > button.pl-seo-acc-head[aria-expanded]
           > span.pl-seo-acc-icon
           > span.pl-seo-acc-title              ("SEO for this page · N")
           > span.pl-seo-acc-chevron[.pl-seo-acc-chevron-open]
       > div.pl-seo-body                        (only rendered while open)
           EITHER (public page):
           > div.pl-seo-card
               > div.pl-seo-field*              (title pattern / meta / H1)
                   > p.pl-seo-field-label
                   > p.pl-seo-field-value[.pl-seo-mono]
               > div.pl-seo-chip-row*           (keywords / schema.org)
                   > span.pl-seo-field-label
                   > span.pl-seo-chip.pl-seo-kw*
                   > span.pl-seo-chip.pl-seo-schema*
           > div.pl-seo-chan-list
               > div.pl-seo-chan-chip*          (priority-ordered)
                   > span.pl-seo-chan-name
                   > span.pl-seo-chan-note
           OR (portal page):
           > div.pl-seo-stance
               > p.pl-seo-stance-badge
               > p.pl-seo-stance-text
   ───────────────────────────────────────────────────────────────────────── */

/* ═══ 1 · Accordion shell (mirrors the Ideas head exactly) ═══════════════ */

.pl-seo-acc.pl-seo-acc {
  padding: 0;
  overflow: hidden;
}

.pl-seo-acc.pl-seo-acc[hidden] {
  display: none !important;
}

.pl-seo-acc-head.pl-seo-acc-head {
  display: flex;
  align-items: center;
  gap: 10px;
  width: 100%;
  min-height: 44px;
  padding: 14px 16px;
  background: transparent;
  border: none;
  color: var(--pl-text);
  font-family: var(--font-sans);
  font-size: 14px;
  font-weight: 600;
  text-align: left;
  cursor: pointer;
}

.pl-seo-acc-head.pl-seo-acc-head[hidden] {
  display: none !important;
}

.pl-seo-acc-head.pl-seo-acc-head:hover {
  background: color-mix(in srgb, var(--pl-blue) 6%, transparent);
}

.pl-seo-acc-head.pl-seo-acc-head:focus-visible {
  outline: 2px solid var(--pl-sky);
  outline-offset: -2px;
}

.pl-seo-acc-icon.pl-seo-acc-icon {
  flex: 0 0 auto;
  display: inline-block;
  color: var(--pl-green);
  font-size: 14px;
  line-height: 1;
}

.pl-seo-acc-title.pl-seo-acc-title {
  flex: 1 1 auto;
  min-width: 0;
}

.pl-seo-acc-chevron.pl-seo-acc-chevron {
  flex: 0 0 auto;
  display: inline-block;
  color: var(--pl-muted);
  font-size: 14px;
  line-height: 1;
  transition: transform 150ms ease;
}

.pl-seo-acc-chevron.pl-seo-acc-chevron-open.pl-seo-acc-chevron-open {
  transform: rotate(180deg);
}

/* ═══ 2 · Body (only mounted while open — no [hidden] toggle to guard,
   guarded anyway for symmetry with the shell) ═══════════════════════════ */

.pl-seo-body.pl-seo-body {
  display: flex;
  flex-direction: column;
  gap: 12px;
  padding: 0 16px 16px;
}

.pl-seo-body.pl-seo-body[hidden] {
  display: none !important;
}

/* ═══ 3 · The page rec card ══════════════════════════════════════════════ */

.pl-seo-card.pl-seo-card {
  display: flex;
  flex-direction: column;
  gap: 10px;
  padding: 12px;
  border: 1px solid var(--pl-border);
  border-radius: 10px;
  background: var(--pl-panel-2);
}

.pl-seo-card.pl-seo-card[hidden] {
  display: none !important;
}

.pl-seo-field.pl-seo-field {
  display: flex;
  flex-direction: column;
  gap: 3px;
}

.pl-seo-field-label.pl-seo-field-label {
  margin: 0;
  color: var(--pl-faint);
  font-family: var(--font-mono);
  font-size: 10px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  white-space: nowrap;
}

.pl-seo-field-value.pl-seo-field-value {
  margin: 0;
  color: var(--pl-text);
  font-size: 13px;
  line-height: 1.5;
  overflow-wrap: anywhere;
}

/* Title pattern keeps its {company}/{city}/{service} slots readable as
   literal fill-me slots, not prose. */
.pl-seo-mono.pl-seo-mono {
  font-family: var(--font-mono);
  font-size: 12px;
}

/* ═══ 4 · Keyword + schema chip rows (echo the .pl-schip/.pl-kchip chip
   grammar: mono, small caps, bordered pills) ════════════════════════════ */

.pl-seo-chip-row.pl-seo-chip-row {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 6px;
}

.pl-seo-chip-row.pl-seo-chip-row[hidden] {
  display: none !important;
}

.pl-seo-chip.pl-seo-chip {
  display: inline-flex;
  align-items: center;
  max-width: 100%;
  padding: 3px 8px;
  border: 1px solid var(--pl-border);
  border-radius: 999px;
  font-family: var(--font-mono);
  font-size: 11px;
  line-height: 1.4;
  white-space: normal;
  overflow-wrap: anywhere;
}

.pl-seo-chip.pl-seo-chip[hidden] {
  display: none !important;
}

.pl-seo-kw.pl-seo-kw {
  color: var(--pl-text);
  background: color-mix(in srgb, var(--pl-blue) 8%, transparent);
  border-color: color-mix(in srgb, var(--pl-blue) 30%, var(--pl-border));
}

.pl-seo-schema.pl-seo-schema {
  color: var(--pl-muted);
  background: color-mix(in srgb, var(--pl-navy) 8%, transparent);
  border-color: color-mix(in srgb, var(--pl-navy) 30%, var(--pl-border));
}

/* ═══ 5 · Per-channel note rows (priority order, top = #1) ══════════════ */

.pl-seo-chan-list.pl-seo-chan-list {
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.pl-seo-chan-list.pl-seo-chan-list[hidden] {
  display: none !important;
}

.pl-seo-chan-chip.pl-seo-chan-chip {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 4px;
  padding: 10px 12px;
  border: 1px solid var(--pl-border);
  border-radius: 10px;
  background: var(--pl-panel-2);
}

.pl-seo-chan-chip.pl-seo-chan-chip[hidden] {
  display: none !important;
}

.pl-seo-chan-name.pl-seo-chan-name {
  display: inline-flex;
  align-items: center;
  padding: 2px 7px;
  border: 1px solid color-mix(in srgb, var(--pl-green) 30%, var(--pl-border));
  border-radius: 3px;
  background: color-mix(in srgb, var(--pl-green) 8%, transparent);
  color: var(--pl-text);
  font-family: var(--font-mono);
  font-size: 9px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  white-space: nowrap;
}

.pl-seo-chan-note.pl-seo-chan-note {
  color: var(--pl-muted);
  font-size: 12px;
  line-height: 1.5;
  overflow-wrap: anywhere;
}

/* ═══ 6 · Portal stance card — deliberate, not an empty state ═══════════ */

.pl-seo-stance.pl-seo-stance {
  display: flex;
  flex-direction: column;
  gap: 6px;
  padding: 12px;
  border: 1px dashed color-mix(in srgb, var(--pl-amber) 45%, var(--pl-border));
  border-radius: 10px;
  background: color-mix(in srgb, var(--pl-amber) 6%, var(--pl-panel-2));
}

.pl-seo-stance.pl-seo-stance[hidden] {
  display: none !important;
}

.pl-seo-stance-badge.pl-seo-stance-badge {
  margin: 0;
  color: var(--pl-text);
  font-family: var(--font-mono);
  font-size: 10px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.06em;
}

.pl-seo-stance-text.pl-seo-stance-text {
  margin: 0;
  color: var(--pl-muted);
  font-size: 12px;
  line-height: 1.55;
}

/* ═══ 7 · Breakpoints ═══════════════════════════════════════════════════ */

/* <= 640: phone — tighter card padding, chips wrap harder. */
@media (max-width: 640px) {
  .pl-seo-acc-head.pl-seo-acc-head {
    padding: 12px 14px;
  }

  .pl-seo-body.pl-seo-body {
    padding: 0 14px 14px;
    gap: 10px;
  }

  .pl-seo-card.pl-seo-card,
  .pl-seo-chan-chip.pl-seo-chan-chip {
    padding: 10px;
  }

  .pl-seo-field-value.pl-seo-field-value {
    font-size: 12px;
  }

  .pl-seo-chan-note.pl-seo-chan-note {
    font-size: 11px;
  }
}

/* 641-980: the detail grid is single-column here (rail below the picture)
   — the rail is WIDER than on desktop, so notes can sit beside their
   channel chip instead of stacking. */
@media (min-width: 641px) and (max-width: 980px) {
  .pl-seo-chan-chip.pl-seo-chan-chip {
    flex-direction: row;
    align-items: baseline;
    gap: 10px;
  }

  .pl-seo-chan-name.pl-seo-chan-name {
    flex: 0 0 auto;
  }

  .pl-seo-chan-note.pl-seo-chan-note {
    flex: 1 1 auto;
    min-width: 0;
  }
}

/* 981-1180: two-column detail grid returns but the rail is narrow —
   stacked chan rows (the base layout) and slightly tighter chip gaps. */
@media (min-width: 981px) and (max-width: 1180px) {
  .pl-seo-chip-row.pl-seo-chip-row {
    gap: 5px;
  }

  .pl-seo-body.pl-seo-body {
    gap: 10px;
  }
}

/* ═══ 8 · Reduced motion ════════════════════════════════════════════════ */

@media (prefers-reduced-motion: reduce) {
  .pl-seo-acc-chevron.pl-seo-acc-chevron {
    transition: none;
  }
}

/* ─────────────────────────────────────────────────────────────────────────
   seo-review.css — review.rs: the "Search & discoverability" row
   (.pl-review-seo-row) on the Review & handoff screen, sitting inside
   .pl-review-top between the readiness breakdown panel and the open
   questions panel. Data is derived from d3pth_core::planner_seo::
   seo_blueprint; nothing here touches readiness styling.

   OWNER: seo web agent (this round). Tokens only (var(--pl-*)), doubled
   selectors (.pl-x.pl-x) so this wins regardless of stylesheet append
   order, per the card-grid.css / wavef-review.css convention. `.pl-panel`
   and `.pl-panel-h` are reused as-is from main.css. No animation is used,
   so there is nothing to guard for reduced motion; chips are inert li
   elements (title-attr tooltips), not touch targets.

   Both themes come from the --pl-* token re-declarations under
   .pl-app[data-pl-theme="dark"] upstream; the one place a raw alpha is
   mixed (chip priority badge) gets an explicit dark override below.

   Breakpoints (docs/PLANNER_LAYOUT.md vocabulary):
     NAR  ≤640px    — chips wrap full-width, tighter padding
     MID  641–980px — single-column pl-review-top (main.css), natural flow:
                      readiness, then this row, then open questions
     ≥981px         — pl-review-top is a 2-col grid (main.css); this row
                      spans both columns on its own grid row so the
                      readiness/questions pair stays side by side
     WIDE ≥1180px   — stance line and chips share one horizontal band

   Structure (verified against review.rs's PlannerReview):
     div.pl-review-top
       > section.pl-panel.pl-review-readiness  (not styled here)
       > section.pl-panel.pl-review-seo-row
           > h2.pl-panel-h ("Search & discoverability")
           > p.pl-review-seo-line
               > span.pl-seo-stance
               > span.pl-review-seo-pages
           > ul.pl-review-seo-chips
               > li.pl-seo-chan-chip[title]*5
                   > span.pl-seo-chan-prio
                   > span.pl-seo-chan-label
       > section.pl-panel.pl-review-questions  (placement only, below)
   ───────────────────────────────────────────────────────────────────────── */

/* ═══ 1 · Row panel + grid placement ═══════════════════════════════════ */

.pl-review-seo-row.pl-review-seo-row {
  display: flex;
  flex-direction: column;
  gap: 12px;
}

/* Wide review layout: main.css makes .pl-review-top a 2-col grid at
   ≥981px. Pin the pair to row 1 and span this row across row 2 so
   inserting it between them in the DOM does not break the side-by-side
   readiness/questions layout. The placements equal what auto-placement
   already produces, so they are inert if this row is ever absent. */
@media (min-width: 981px) {
  .pl-review-top > .pl-review-readiness.pl-review-readiness {
    grid-column: 1;
    grid-row: 1;
  }
  .pl-review-top > .pl-review-questions.pl-review-questions {
    grid-column: 2;
    grid-row: 1;
  }
  .pl-review-top > .pl-review-seo-row.pl-review-seo-row {
    grid-column: 1 / -1;
    grid-row: 2;
  }
}

/* ═══ 2 · Stance + coverage line ═══════════════════════════════════════ */

.pl-review-seo-line.pl-review-seo-line {
  margin: 0;
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 6px 14px;
}

.pl-review-seo-row .pl-seo-stance {
  color: var(--pl-text);
  font-weight: 600;
  font-size: 0.95rem;
}

.pl-review-seo-pages.pl-review-seo-pages {
  color: var(--pl-muted);
  font-size: 0.85rem;
}

/* ═══ 3 · Channel chips (priority order) ═══════════════════════════════ */

.pl-review-seo-chips.pl-review-seo-chips {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}

.pl-review-seo-row .pl-seo-chan-chip {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  padding: 5px 12px 5px 6px;
  border: 1px solid var(--pl-border);
  border-radius: 999px;
  background: var(--pl-panel-2);
  color: var(--pl-text);
  font-size: 0.85rem;
  line-height: 1.2;
  white-space: nowrap;
}

/* Priority 1 leads the row — give it the accent border so the eye reads
   the ordering without counting badges. */
.pl-review-seo-row .pl-seo-chan-chip:first-child {
  border-color: color-mix(in srgb, var(--pl-blue) 55%, var(--pl-border));
}

.pl-review-seo-row .pl-seo-chan-prio {
  display: inline-grid;
  place-items: center;
  width: 20px;
  height: 20px;
  min-width: 20px;
  border-radius: 50%;
  background: color-mix(in srgb, var(--pl-blue) 14%, transparent);
  color: var(--pl-blue);
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 0.72rem;
}

.pl-app[data-pl-theme="dark"] .pl-review-seo-row .pl-seo-chan-prio {
  background: color-mix(in srgb, var(--pl-sky) 24%, transparent);
  color: var(--pl-sky);
}

.pl-review-seo-row .pl-seo-chan-label {
  color: inherit;
}

/* ═══ 4 · Narrow (≤640px) ══════════════════════════════════════════════ */

@media (max-width: 640px) {
  .pl-review-seo-row.pl-review-seo-row {
    gap: 10px;
  }
  .pl-review-seo-chips.pl-review-seo-chips {
    gap: 6px;
  }
  .pl-review-seo-row .pl-seo-chan-chip.pl-review-seo-row .pl-seo-chan-chip {
    flex: 1 1 calc(50% - 6px);
    justify-content: flex-start;
    white-space: normal;
  }
}

/* ═══ 5 · Wide (≥1180px): one horizontal band ══════════════════════════ */

@media (min-width: 1180px) {
  .pl-review-seo-row.pl-review-seo-row {
    flex-direction: row;
    align-items: center;
    justify-content: space-between;
    gap: 18px;
  }
  .pl-review-seo-row.pl-review-seo-row > .pl-panel-h {
    margin: 0;
    white-space: nowrap;
  }
  .pl-review-seo-line.pl-review-seo-line {
    flex-direction: column;
    align-items: flex-start;
    gap: 2px;
  }
  .pl-review-seo-chips.pl-review-seo-chips {
    justify-content: flex-end;
  }
}

/* ── Topbar v2 — IA: crumbs · unsaved · ✦ Make it yours · theme/?/⌘K.
   Appended last so it beats the four earlier .pl-topbar restatements. ── */

.pl-app .pl-topbar.pl-topbar-crumbs {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  flex-wrap: nowrap;
  min-height: 52px;
  padding: 0 16px 0 20px;
  background: var(--pl-panel-1);
  border-bottom: 1px solid var(--pl-border);
  box-shadow: none;
  backdrop-filter: none;
  -webkit-backdrop-filter: none;
}

.pl-app .pl-crumb-zone {
  display: flex;
  align-items: center;
  gap: 10px;
  min-width: 0;
  flex: 1 1 auto;
}

.pl-app .pl-crumbs {
  display: flex;
  align-items: center;
  gap: 0;
  min-width: 0;
  overflow-x: auto;
  scrollbar-width: none;
}

.pl-app .pl-crumb {
  border: 0;
  background: transparent;
  font-family: var(--font-mono, ui-monospace, SFMono-Regular, Menlo, monospace);
  font-size: 11px;
  font-weight: 500;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  padding: 8px 2px;
  min-height: 0;
  border-radius: 4px;
  color: var(--pl-muted);
  cursor: pointer;
  white-space: nowrap;
}

.pl-app .pl-crumb:hover {
  background: transparent;
  color: var(--pl-text);
}

.pl-app .pl-crumb[aria-current="true"] {
  font-weight: 650;
  color: var(--pl-text);
  cursor: default;
}

.pl-app .pl-crumb[aria-current="true"]:hover {
  background: transparent;
}

.pl-app .pl-crumb-sep {
  padding: 0 8px;
  font-size: 11px;
  letter-spacing: 0;
  opacity: 0.35;
  user-select: none;
}

.pl-app .pl-unsaved-pill,
.pl-app .pl-drawer-chip {
  flex-shrink: 0;
  border: 1px solid color-mix(in srgb, var(--pl-sky) 48%, var(--pl-glass-border));
  background: color-mix(in srgb, var(--pl-sky) 12%, var(--pl-glass-bg));
  backdrop-filter: blur(10px) saturate(1.3);
  -webkit-backdrop-filter: blur(10px) saturate(1.3);
  color: var(--pl-text);
  font-family: var(--font-mono, ui-monospace, SFMono-Regular, Menlo, monospace);
  font-size: 10px;
  font-weight: 650;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  padding: 4px 8px;
  min-height: 0;
  border-radius: 999px;
  cursor: pointer;
  box-shadow: inset 0 1px 0 color-mix(in srgb, #ffffff 45%, transparent);
}

.pl-app .pl-drawer-chip {
  border-color: color-mix(in srgb, var(--pl-green) 50%, var(--pl-border));
  background: color-mix(in srgb, var(--pl-green) 12%, transparent);
  color: var(--pl-green);
}

.pl-app .pl-top-right {
  display: flex;
  align-items: center;
  gap: 10px;
  flex: 0 0 auto;
  flex-wrap: nowrap;
}

.pl-app .pl-looking-chip {
  display: inline-flex;
  align-items: center;
  height: 32px;
  padding: 0 12px;
  border-radius: 999px;
  font-family: var(--font-sans);
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.02em;
  color: color-mix(in srgb, var(--pl-blue) 55%, var(--pl-text));
  background: color-mix(in srgb, var(--pl-sky) 14%, var(--pl-glass-bg));
  backdrop-filter: blur(10px) saturate(1.2);
  -webkit-backdrop-filter: blur(10px) saturate(1.2);
  border: 1px solid color-mix(in srgb, var(--pl-sky) 48%, var(--pl-glass-border));
  box-shadow: inset 0 1px 0 color-mix(in srgb, #ffffff 45%, transparent);
  white-space: nowrap;
}

.pl-app .pl-looking-chip[hidden] {
  display: none !important;
}

.pl-app .pl-make-btn,
.pl-app .pl-top-right > .pl-btn.pl-btn-green:has(.pl-make-spark) {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  min-height: 32px;
  height: 32px;
  padding: 0 14px 0 12px;
  border: 0;
  border-radius: 999px;
  background: var(--pl-btn-green-grad);
  color: #fff;
  font-size: 12.5px;
  font-weight: 600;
  letter-spacing: 0.04em;
  box-shadow: var(--pl-btn-green-shadow), var(--pl-cta-glow-green);
  animation: none;
}

.pl-app .pl-make-btn::after,
.pl-app .pl-top-right > .pl-btn.pl-btn-green:has(.pl-make-spark)::after {
  display: none;
}

.pl-app .pl-make-btn:hover,
.pl-app .pl-make-btn:hover::after,
.pl-app .pl-top-right > .pl-btn.pl-btn-green:has(.pl-make-spark):hover {
  transform: none;
  box-shadow: var(--pl-btn-green-shadow-hover), var(--pl-cta-glow-green-hover);
  filter: brightness(1.07);
}

.pl-app .pl-make-spark {
  display: block;
  width: 56px;
  height: 6px;
  flex-shrink: 0;
  font-size: 0;
  line-height: 0;
  color: transparent;
  overflow: hidden;
  background: linear-gradient(90deg, var(--pl-blue) 0%, var(--pl-sky) 50%, var(--pl-green) 100%);
  -webkit-mask-image: radial-gradient(circle, #000 1.5px, transparent 1.9px);
  -webkit-mask-size: 8px 6px;
  -webkit-mask-repeat: repeat-x;
  -webkit-mask-position: left center;
  mask-image: radial-gradient(circle, #000 1.5px, transparent 1.9px);
  mask-size: 8px 6px;
  mask-repeat: repeat-x;
  mask-position: left center;
}

.pl-app .pl-icon-cluster {
  display: flex;
  align-items: center;
  gap: 8px;
}

.pl-app .pl-topbar .pl-icon-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 32px;
  min-width: 32px;
  height: 32px;
  padding: 0 0 0.5px;
  border-radius: 999px;
  border: 1px solid color-mix(in srgb, var(--pl-sky) 40%, var(--pl-glass-border));
  background: var(--pl-glass-bg);
  backdrop-filter: blur(10px) saturate(1.2);
  -webkit-backdrop-filter: blur(10px) saturate(1.2);
  color: var(--pl-muted);
  font-size: 14px;
  line-height: 1;
  cursor: pointer;
}

.pl-app .pl-topbar .pl-icon-btn:hover {
  color: var(--pl-text);
  border-color: color-mix(in srgb, var(--pl-sky) 62%, var(--pl-border));
}

.pl-app .pl-kbd-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: auto;
  min-width: 32px;
  min-height: 32px;
  height: 32px;
  padding: 0 10px 0.5px;
  border-radius: 999px;
  border: 1px solid color-mix(in srgb, var(--pl-sky) 40%, var(--pl-glass-border));
  background: var(--pl-glass-bg);
  backdrop-filter: blur(10px) saturate(1.2);
  -webkit-backdrop-filter: blur(10px) saturate(1.2);
  color: var(--pl-muted);
  font-family: var(--font-mono, ui-monospace, SFMono-Regular, Menlo, monospace);
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.04em;
  line-height: 1;
  text-transform: uppercase;
  cursor: pointer;
  white-space: nowrap;
}

.pl-app .pl-kbd-btn:hover {
  color: var(--pl-text);
  border-color: color-mix(in srgb, var(--pl-sky) 62%, var(--pl-border));
}

.pl-scratch {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  padding: 16px 20px;
  border: 1.5px solid color-mix(in srgb, var(--pl-sky) 45%, var(--pl-border));
  border-radius: 14px;
  background: color-mix(in srgb, var(--pl-sky) 5%, var(--pl-panel-1));
}

.pl-scratch[hidden] {
  display: none !important;
}

.pl-scratch-title {
  margin: 0;
  font-size: 15px;
  font-weight: 650;
}

.pl-scratch-sub {
  margin: 4px 0 0;
  font-size: 13px;
  color: var(--pl-muted);
}

.pl-scratch .pl-build-btn {
  flex: 0 0 auto;
  min-height: 44px;
  padding: 0 16px;
  border-radius: 10px;
}

.pl-scratch .pl-btn.pl-btn-green,
.pl-scratch .pl-btn-green.pl-build-btn {
  background: var(--pl-btn-green-grad);
  color: #fff;
  box-shadow: var(--pl-btn-green-shadow), var(--pl-cta-glow-green);
}

@media (max-width: 980px) {
  .pl-app .pl-topbar.pl-topbar-crumbs {
    flex-wrap: wrap;
    row-gap: 8px;
    padding: 8px 12px;
  }
  .pl-app .pl-crumb-zone {
    flex: 1 1 auto;
    min-width: 0;
  }
  .pl-app .pl-top-right {
    flex: 0 0 auto;
    justify-content: flex-end;
  }
}

@media (max-width: 640px) {
  .pl-app .pl-kbd-btn {
    display: none;
  }
  .pl-app .pl-make-label {
    position: absolute;
    width: 1px;
    height: 1px;
    overflow: hidden;
    clip: rect(0, 0, 0, 0);
  }
  .pl-app .pl-make-btn {
    width: 32px;
    min-width: 32px;
    padding: 0;
  }
  .pl-app .pl-top-right > *,
  .pl-app .pl-make-btn,
  .pl-app .pl-build-btn {
    flex: 0 0 auto !important;
    min-height: 32px;
  }
  .pl-scratch {
    flex-direction: column;
    align-items: stretch;
  }
}

/* ── L2 prior runs (replaces Notes on this page)
   Scoped under .pl-panel.pl-runs-panel so site-wide .pl-kchip / .pl-schip
   stay untouched. Filed runs keep .pl-citem for existing e2e locators;
   chat-thread titles are .pl-runs-chat so they don't inflate that count. */

.pl-panel.pl-runs-panel {
  min-width: 0;
}

.pl-panel.pl-runs-panel .pl-panel-h {
  margin: 0 0 8px;
}

.pl-panel.pl-runs-panel .pl-empty {
  padding: 24px 16px;
}

.pl-panel.pl-runs-panel .pl-runs-list {
  display: flex;
  flex-direction: column;
}

.pl-panel.pl-runs-panel .pl-citem {
  cursor: default;
}

.pl-panel.pl-runs-panel .pl-runs-meta {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 6px;
  margin-bottom: 6px;
}

.pl-panel.pl-runs-panel .pl-runs-text {
  margin: 0 0 8px;
  font-size: 13px;
  font-weight: 500;
  line-height: 1.45;
  color: var(--pl-text);
}

.pl-panel.pl-runs-panel .pl-runs-where {
  font-family: var(--font-mono);
  font-size: 11px;
  color: var(--pl-faint);
}

.pl-panel.pl-runs-panel .pl-runs-chat {
  background: var(--pl-panel-1);
  border: 1px dashed var(--pl-border);
  border-radius: 8px;
  padding: 10px 12px;
  margin-bottom: 8px;
}

.pl-panel.pl-runs-panel .pl-runs-chat-title {
  margin: 0;
  font-size: 13px;
  color: var(--pl-muted);
}

.pl-panel.pl-runs-panel .pl-schip.pl-s-need-you {
  background: color-mix(in srgb, var(--pl-amber) var(--pl-chip-bg-mix), transparent);
  border-color: color-mix(in srgb, var(--pl-amber) var(--pl-chip-border-mix), transparent);
  color: var(--pl-amber);
}

/* ── Ideas work tab (full pl-view; was overlay) ───────────────────────── */

.pl-view-ideas {
  display: flex;
  flex-direction: column;
  min-height: 0;
  height: 100%;
}

.pl-ideas-desk-overlay {
  display: none !important;
}

.pl-ideas-work,
.pl-ideas-desk {
  position: relative;
  inset: auto;
  top: auto;
  right: auto;
  z-index: auto;
  display: flex;
  flex-direction: column;
  width: 100%;
  max-width: 1100px;
  max-height: none;
  min-height: 0;
  margin: 0 auto;
  padding: 0 0 2rem;
  background: transparent;
  border: none;
  box-shadow: none;
  outline: none;
}

.pl-ideas-work[hidden],
.pl-ideas-desk[hidden] {
  display: none;
}

.pl-ideas-work-head {
  flex-shrink: 0;
  display: flex;
  flex-wrap: wrap;
  align-items: flex-start;
  justify-content: space-between;
  gap: 1rem 1.5rem;
  padding: 0.25rem 0 1rem;
  border-bottom: 1px solid var(--pl-border);
}

.pl-ideas-work-title h2 {
  margin: 0;
  font-family: var(--font-display);
  font-size: 1.55rem;
  font-weight: 700;
  color: var(--pl-text);
}

.pl-ideas-work-eyebrow {
  margin: 0 0 4px;
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--pl-muted);
}

.pl-ideas-work-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  align-items: center;
}

.pl-ideas-tabs {
  flex-shrink: 0;
  display: flex;
  flex-wrap: wrap;
  gap: 4px;
  margin: 12px 0 4px;
  padding: 4px;
  border-radius: 14px;
  background: color-mix(in srgb, var(--pl-panel-2) 88%, transparent);
  border: 1px solid var(--pl-border);
}

.pl-ideas-tab {
  min-height: 40px;
  padding: 0 12px;
  border: none;
  border-radius: 10px;
  background: transparent;
  color: var(--pl-muted);
  font-size: 12.5px;
  font-weight: 700;
  letter-spacing: 0.02em;
  cursor: pointer;
}

.pl-ideas-tab:hover {
  color: var(--pl-text);
  background: color-mix(in srgb, var(--pl-sky) 10%, transparent);
}

.pl-ideas-tab-on,
.pl-ideas-tab[aria-selected="true"] {
  color: var(--pl-text);
  background: color-mix(in srgb, var(--pl-sky) 18%, var(--pl-panel-1));
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--pl-sky) 45%, transparent);
}

.pl-ideas-tab-blurb {
  margin: 0 0 10px;
  font-size: 13px;
  line-height: 1.45;
  color: var(--pl-muted);
}

.pl-ideas-work-body {
  flex: 1 1 auto;
  overflow-y: auto;
  padding-right: 4px;
}

.pl-ideas-insights {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  align-items: stretch;
  gap: 14px;
}

.pl-ideas-insights:has(> .pl-ideas-desk-empty) {
  display: block;
}

.pl-ideas-insight {
  display: flex;
  flex-direction: column;
  height: 100%;
  min-height: 0;
  padding: 14px 16px;
  border-radius: 14px;
  border: 1px solid var(--pl-border);
  background: var(--pl-panel-1);
}

.pl-ideas-insight-head {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px;
  margin-bottom: 6px;
}

.pl-ideas-insight-title {
  margin: 0;
  font-size: 15px;
  font-weight: 700;
  text-transform: capitalize;
}

.pl-ideas-insight-blurb {
  margin: 0 0 10px;
  font-size: 13.5px;
  line-height: 1.5;
  color: var(--pl-text);
}

.pl-ideas-insight-cards {
  list-style: none;
  margin: 0 0 10px;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 10px;
}

.pl-ideas-insight-card {
  display: flex;
  flex-direction: column;
  gap: 4px;
  padding: 10px 12px;
  border-radius: 10px;
  background: color-mix(in srgb, var(--pl-sky) 8%, var(--pl-panel-2));
}

.pl-ideas-insight-card strong {
  font-size: 13.5px;
}

.pl-ideas-insight-card > span {
  font-size: 12.5px;
  color: var(--pl-muted);
}

.pl-ideas-seo {
  display: flex;
  flex-direction: column;
  gap: 14px;
}

.pl-ideas-seo-block {
  padding: 14px 16px;
  border-radius: 14px;
  border: 1px solid var(--pl-border);
  background: var(--pl-panel-1);
}

.pl-ideas-seo-block h4 {
  margin: 0 0 8px;
  font-size: 14px;
  font-weight: 700;
}

.pl-ideas-seo-channels {
  margin: 0;
  padding-left: 1.2rem;
  display: flex;
  flex-direction: column;
  gap: 12px;
}

.pl-ideas-seo-channels li {
  display: flex;
  flex-direction: column;
  gap: 4px;
}

.pl-ideas-seo-check {
  margin: 4px 0 0;
  padding-left: 1.1rem;
  font-size: 12.5px;
  color: var(--pl-muted);
}

.pl-ideas-seo-dl {
  display: grid;
  gap: 10px;
  margin: 0;
}

.pl-ideas-seo-dl dt {
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--pl-muted);
}

.pl-ideas-seo-dl dd {
  margin: 2px 0 0;
  font-size: 13.5px;
  line-height: 1.45;
}

.pl-ideas-patterns {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(260px, 1fr));
  gap: 12px;
}

.pl-ideas-notes {
  display: flex;
  flex-direction: column;
  gap: 10px;
  margin-bottom: 14px;
}

.pl-ideas-note {
  padding: 12px 14px;
  border-radius: 12px;
  border: 1px solid var(--pl-border);
  background: var(--pl-panel-1);
}

.pl-ideas-note-user {
  border-color: color-mix(in srgb, var(--pl-sky) 40%, var(--pl-border));
  background: color-mix(in srgb, var(--pl-sky) 10%, var(--pl-panel-1));
}

.pl-ideas-note-meta {
  margin: 0 0 4px;
  font-size: 11px;
  color: var(--pl-muted);
  text-transform: uppercase;
  letter-spacing: 0.06em;
}

.pl-ideas-note-body {
  margin: 0;
  font-size: 13.5px;
  line-height: 1.5;
  white-space: pre-wrap;
}

.pl-ideas-desk-head {
  flex-shrink: 0;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.75rem;
  padding: 1rem 0;
  border-bottom: 1px solid var(--pl-border);
}

.pl-ideas-desk-head h2 {
  margin: 0;
  font-size: 1.05rem;
  font-weight: 700;
}

.pl-ideas-desk-close {
  display: none;
}

.pl-ideas-desk-status,
.pl-ideas-desk-based {
  margin: 0;
  padding: 0.65rem 1.25rem 0;
  font-size: 13px;
  line-height: 1.45;
  color: var(--pl-muted);
}

.pl-ideas-desk-scope {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  padding: 0.85rem 1.25rem 0;
}

.pl-ideas-desk .pl-chip[aria-pressed="true"] {
  box-shadow: inset 0 0 0 1px var(--pl-sky);
}

.pl-ideas-desk-pick {
  padding: 0.75rem 1.25rem 0;
}

.pl-ideas-desk-pick[hidden] {
  display: none;
}

.pl-ideas-desk-pick-lbl {
  margin: 0 0 6px;
  font-size: 12px;
  font-weight: 600;
  color: var(--pl-faint);
}

.pl-ideas-desk-pick-row {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin-bottom: 10px;
}

.pl-ideas-desk-body {
  flex: 1 1 auto;
  min-height: 0;
  overflow-y: auto;
  padding: 1rem 1.25rem 1.25rem;
  display: flex;
  flex-direction: column;
  gap: 1.25rem;
}

.pl-ideas-desk-section {
  display: flex;
  flex-direction: column;
  gap: 10px;
}

.pl-ideas-desk-section[hidden] {
  display: none;
}

.pl-ideas-desk-h {
  margin: 0;
  font-size: 13px;
  font-weight: 700;
  letter-spacing: 0.02em;
  text-transform: uppercase;
  color: var(--pl-faint);
}

.pl-ideas-desk-suggest,
.pl-ideas-desk-leaders {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  align-items: stretch;
  gap: 12px;
}

.pl-ideas-desk-suggest:has(> .pl-ideas-desk-empty),
.pl-ideas-desk-leaders:has(> .pl-ideas-desk-empty) {
  display: block;
}

.pl-ideas-desk-empty,
.pl-ideas-desk-lead-note,
.pl-ideas-desk-bench-label,
.pl-ideas-desk-credits,
.pl-ideas-desk-reply {
  margin: 0;
  font-size: 13px;
  line-height: 1.45;
  color: var(--pl-muted);
}

.pl-ideas-desk-ask {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  gap: 8px;
}

.pl-ideas-desk-ask[hidden] {
  display: none;
}

.pl-ideas-desk-own-lbl {
  display: flex;
  flex-direction: column;
  gap: 6px;
  flex: 1 1 220px;
  font-size: 12px;
  font-weight: 600;
  color: var(--pl-faint);
}

.pl-ideas-desk-input {
  width: 100%;
  min-height: 44px;
  padding: 8px 12px;
  border: 1px solid var(--pl-border);
  border-radius: 8px;
  background: var(--pl-panel-2, var(--pl-panel-1));
  color: var(--pl-text);
  font-family: var(--font-sans);
  font-size: 14px;
}

.pl-ideas-desk-cites {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 12px;
}

.pl-ideas-desk-cite {
  display: flex;
  flex-direction: column;
  gap: 4px;
}

.pl-ideas-desk-cite-link {
  color: var(--pl-sky);
  font-weight: 600;
  text-decoration: underline;
  text-underline-offset: 2px;
}

.pl-ideas-desk-cite-meta {
  font-size: 12px;
  color: var(--pl-faint);
}

.pl-ideas-desk-cite-sum {
  margin: 0;
  font-size: 13px;
  line-height: 1.45;
  color: var(--pl-muted);
}

.pl-ideas-desk-leader {
  display: flex;
  flex-direction: column;
  height: 100%;
  min-height: 0;
  gap: 6px;
  padding: 12px;
  border: 1px solid var(--pl-border);
  border-radius: 10px;
  background: var(--pl-panel-2);
}

.pl-ideas-desk-leader-title {
  margin: 0;
  font-size: 14px;
  font-weight: 600;
  color: var(--pl-text);
}

.pl-ideas-desk-leader-pitch {
  margin: 0;
  font-size: 13px;
  line-height: 1.45;
  color: var(--pl-muted);
}

.pl-ideas-desk-foot {
  flex-shrink: 0;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  padding: 0.85rem 1.25rem;
  border-top: 1px solid var(--pl-border);
}

@media (max-width: 640px) {
  .pl-ideas-desk {
    width: 100vw;
    height: 100dvh;
    max-height: 100dvh;
  }
}

@media (prefers-reduced-motion: reduce) {
  .pl-ideas-desk,
  .pl-ideas-desk-overlay {
    transition: none !important;
  }
}

/* ═════════════════════════════════════════════════════════════════════════
   Planner button language — hero dots + ripple on the existing pl-btn
   family. No new gradient: rails reuse the 90deg blue→sky→emerald mask
   already on .pl-dot-rail. Glow stays --pl-cta-glow / --pl-cta-glow-green.
   ═════════════════════════════════════════════════════════════════════════ */

.pl-btn,
.pl-btn-green,
.pl-make-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  position: relative;
  overflow: hidden;
  letter-spacing: 0.04em;
}

.pl-btn .btn-ripple-canvas,
.pl-btn-green .btn-ripple-canvas,
.pl-make-btn .btn-ripple-canvas,
.pl-btn-ripple,
.pl-copilot-send .pl-btn-ripple,
.pl-copilot-send .btn-ripple-canvas {
  position: absolute;
  inset: 0;
  display: block;
  width: 100%;
  height: 100%;
  pointer-events: none;
  z-index: 0;
}

.pl-btn > :not(.pl-btn-ripple):not(.btn-ripple-canvas),
.pl-btn-green > :not(.pl-btn-ripple):not(.btn-ripple-canvas),
.pl-make-btn > :not(.pl-btn-ripple):not(.btn-ripple-canvas) {
  position: relative;
  z-index: 1;
}

/* 56×6 / 7-dot rail — same mask + ramp as sidebar .pl-dot-rail. */
.pl-btn > .pl-dot-rail,
.pl-btn-green > .pl-dot-rail,
.pl-make-btn > .pl-dot-rail,
.pl-btn-spark::before {
  display: block;
  width: 56px;
  height: 6px;
  margin: 0;
  flex-shrink: 0;
  background: linear-gradient(90deg, var(--pl-blue) 0%, var(--pl-sky) 50%, var(--pl-green) 100%);
  -webkit-mask-image: radial-gradient(circle, #000 1.5px, transparent 1.9px);
  -webkit-mask-size: 8px 6px;
  -webkit-mask-repeat: repeat-x;
  -webkit-mask-position: left center;
  mask-image: radial-gradient(circle, #000 1.5px, transparent 1.9px);
  mask-size: 8px 6px;
  mask-repeat: repeat-x;
  mask-position: left center;
}

.pl-btn,
.pl-btn-green,
.pl-make-btn {
  overflow: visible;
}

/* Current-nav perimeter: one rounded-rect SVG stroke. Round caps + a 0
   dash make circular beads that follow the 8px chip radius instead of
   four straight rails stacking in the corners. */
.pl-sidebar-btn {
  position: relative;
  overflow: visible;
}

.pl-hero-dot-defs {
  position: absolute;
  width: 0;
  height: 0;
  overflow: hidden;
}

.pl-hero-dot-a {
  stop-color: var(--pl-blue);
}

.pl-hero-dot-b {
  stop-color: var(--pl-sky);
}

.pl-hero-dot-c {
  stop-color: var(--pl-green);
}

.pl-hero-trace {
  display: block;
  position: absolute;
  left: 1px;
  right: 1px;
  top: 1px;
  bottom: 1px;
  width: auto;
  height: auto;
  overflow: visible;
  pointer-events: none;
  z-index: 3;
  opacity: 0;
}

.pl-hero-trace-svg {
  display: block;
  width: 100%;
  height: 100%;
  overflow: visible;
}

.pl-sidebar-btn[aria-current="true"] > .pl-hero-trace,
.pl-sidebar-site-row:has(> .pl-sidebar-btn[aria-current="true"]) > .pl-hero-trace {
  opacity: 1;
}

.pl-hero-trace-rect {
  fill: none;
  width: calc(100% - 4.5px);
  height: calc(100% - 4.5px);
  stroke: url(#pl-hero-dot-grad);
  stroke-width: 3px;
  stroke-linecap: round;
  stroke-linejoin: round;
  /* 0-length dash + round cap = a circle; 9px pitch, slightly airier
     than the 8px .pl-dot-rail so stacked current rows don't collide. */
  stroke-dasharray: 0.01 9;
  vector-effect: non-scaling-stroke;
  animation: pl-hero-dot-march 2.8s linear infinite;
}

@keyframes pl-hero-dot-march {
  to {
    stroke-dashoffset: -9px;
  }
}

/* Pressed chips are 18px stamps — a 2px bead perimeter covers the label.
   Page-chat starters are large enough to keep the edge beads. */
.pl-page-chat-starter:hover,
.pl-page-chat-starter:focus-visible {
  position: relative;
  overflow: visible;
  z-index: 2;
}

.pl-page-chat-starter:hover::before,
.pl-page-chat-starter:focus-visible::before {
  content: "";
  position: absolute;
  inset: 0;
  pointer-events: none;
  border-radius: inherit;
  z-index: 3;
  background-image:
    radial-gradient(circle, var(--pl-blue) 2.1px, transparent 2.4px),
    radial-gradient(circle, var(--pl-sky) 2.1px, transparent 2.4px),
    radial-gradient(circle, var(--pl-green) 2.1px, transparent 2.4px),
    radial-gradient(circle, var(--pl-sky) 2.1px, transparent 2.4px);
  background-size: 10px 6px, 6px 10px, 10px 6px, 6px 10px;
  background-repeat: repeat-x, repeat-y, repeat-x, repeat-y;
  background-position: 0 0, 100% 0, 0 100%, 0 0;
  animation: pl-hero-dot-march-bg 2.2s linear infinite;
}

@keyframes pl-hero-dot-march-bg {
  to {
    background-position: 10px 0, 100% 10px, -10px 100%, 0 -10px;
  }
}

/* Current page in the detail pagenav: same chrome pill as idle tabs. */
.pl-pagenav-chip {
  min-height: var(--pl-chrome-h, 32px);
  padding: 0 var(--pl-chrome-pad-x, 12px);
  border-radius: var(--pl-chrome-radius, 999px);
  font-family: var(--font-sans);
  font-size: var(--pl-chrome-font, 12px);
  font-weight: var(--pl-chrome-weight, 600);
}

@media (prefers-reduced-motion: reduce) {
  .pl-hero-trace-rect,
  .pl-page-chat-starter:hover::before,
  .pl-page-chat-starter:focus-visible::before {
    animation: none;
  }
}

.pl-sidebar-profile-credits {
  margin-left: auto;
  font-size: 11px;
  font-weight: 600;
  color: var(--pl-muted);
  letter-spacing: 0.02em;
}

.pl-sidebar-btn.pl-sidebar-account {
  gap: 8px;
}

.pl-btn-spark::before {
  content: "";
}

.pl-btn-spark-under {
  flex-direction: column;
  gap: 5px;
}

.pl-btn-spark-under::after {
  content: "";
  display: block;
  width: 56px;
  height: 6px;
  background: linear-gradient(90deg, var(--pl-blue) 0%, var(--pl-sky) 50%, var(--pl-green) 100%);
  -webkit-mask-image: radial-gradient(circle, #000 1.5px, transparent 1.9px);
  -webkit-mask-size: 8px 6px;
  -webkit-mask-repeat: repeat-x;
  -webkit-mask-position: left center;
  mask-image: radial-gradient(circle, #000 1.5px, transparent 1.9px);
  mask-size: 8px 6px;
  mask-repeat: repeat-x;
  mask-position: left center;
}

.pl-btn:hover > .pl-dot-rail,
.pl-btn-green:hover > .pl-dot-rail,
.pl-make-btn:hover > .pl-dot-rail,
.pl-btn:hover .pl-make-spark,
.pl-make-btn:hover .pl-make-spark,
.pl-btn-spark:hover::before,
.pl-btn-spark-under:hover::after {
  animation: pl-btn-spark-run 650ms ease-out;
}

@keyframes pl-btn-spark-run {
  from {
    -webkit-mask-position: -8px center;
    mask-position: -8px center;
  }
  to {
    -webkit-mask-position: 8px center;
    mask-position: 8px center;
  }
}

.pl-btn-sky {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  min-height: 44px;
  padding: 8px 16px;
  border-radius: 10px;
  letter-spacing: 0.04em;
  font-size: 13px;
  font-weight: 600;
  font-family: var(--font-sans);
  cursor: pointer;
  color: var(--pl-text);
  background: color-mix(in srgb, var(--pl-sky) 14%, var(--pl-glass-bg));
  backdrop-filter: blur(10px) saturate(1.2);
  -webkit-backdrop-filter: blur(10px) saturate(1.2);
  border: 1px solid color-mix(in srgb, var(--pl-sky) 48%, var(--pl-glass-border));
  box-shadow: inset 0 1px 0 color-mix(in srgb, #ffffff 45%, transparent);
}

.pl-btn-sky:hover {
  border-color: var(--pl-sky);
  background: color-mix(in srgb, var(--pl-sky) 20%, var(--pl-glass-bg));
}

.pl-btn-sky:focus-visible {
  outline: 2px solid var(--pl-sky);
  outline-offset: 2px;
}

.pl-btn-icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 36px;
  min-width: 36px;
  height: 36px;
  min-height: 36px;
  padding: 0 0 0.5px;
  border-radius: 50%;
  line-height: 1;
  font-size: 14px;
  font-weight: 500;
  cursor: pointer;
  color: var(--pl-muted);
  background: var(--pl-glass-bg);
  backdrop-filter: blur(10px) saturate(1.2);
  -webkit-backdrop-filter: blur(10px) saturate(1.2);
  border: 1px solid color-mix(in srgb, var(--pl-sky) 40%, var(--pl-glass-border));
}

.pl-btn-icon:hover {
  color: var(--pl-text);
  border-color: color-mix(in srgb, var(--pl-sky) 62%, var(--pl-border));
}

.pl-btn-icon:focus-visible {
  outline: 2px solid var(--pl-sky);
  outline-offset: 2px;
}

/* Last word: NAR-only open/close. Desktop collapse is the seam chevron.
   `!important` beats any later `.pl-btn-icon { display: inline-flex }` if
   those classes get re-added to the markup. */
.pl-sidebar-hamburger,
.pl-sidebar-mobile-close {
  display: none !important;
}

@media (max-width: 640px) {
  .pl-sidebar-hamburger,
  .pl-sidebar-mobile-close {
    display: inline-flex !important;
  }
}

.pl-seg {
  align-items: stretch;
}

.pl-seg > .pl-btn,
.pl-seg > .pl-btn-sm,
.pl-seg > .pl-ghost {
  flex: 1 1 0;
  min-width: 0;
}

.pl-seg [aria-pressed="true"],
.pl-seg [aria-checked="true"] {
  background: var(--pl-btn-green-grad);
  color: #fff;
  border-color: transparent;
  box-shadow: var(--pl-btn-green-shadow), var(--pl-cta-glow-green);
}

.pl-studio-scope-btn[aria-checked="true"] {
  background: var(--pl-btn-green-grad);
  color: #fff;
  box-shadow: var(--pl-btn-green-shadow), var(--pl-cta-glow-green);
}

.pl-comp-switch.pl-comp-switch {
  background: color-mix(in srgb, var(--pl-navy, #0b1f3a) 18%, var(--pl-glass-bg));
  border-color: color-mix(in srgb, var(--pl-navy, #0b1f3a) 28%, var(--pl-glass-border));
}

.pl-comp-switch-on.pl-comp-switch-on {
  background: var(--pl-green);
  border-color: var(--pl-green);
}

@media (prefers-reduced-motion: reduce) {
  .pl-btn:hover > .pl-dot-rail,
  .pl-btn-green:hover > .pl-dot-rail,
  .pl-make-btn:hover > .pl-dot-rail,
  .pl-btn:hover .pl-make-spark,
  .pl-make-btn:hover .pl-make-spark,
  .pl-btn-spark:hover::before,
  .pl-btn-spark-under:hover::after,
  .pl-btn-sky,
  .pl-btn-icon {
    animation: none;
    transition: none;
  }
}

/* Account / Activity right sheets: glass fill only — keep their own
   padding, width, and square edge. Do not inherit .pl-panel 16px/12px. */
.pl-account,
.pl-activity {
  background: var(--pl-glass-bg);
  backdrop-filter: blur(14px) saturate(1.3);
  -webkit-backdrop-filter: blur(14px) saturate(1.3);
}

.pl-account-head,
.pl-account-tabs,
.pl-activity-head,
.pl-activity-tabs {
  background: var(--pl-glass-bg);
  backdrop-filter: blur(14px) saturate(1.3);
  -webkit-backdrop-filter: blur(14px) saturate(1.3);
}

@supports not ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
  .pl-account,
  .pl-activity,
  .pl-account-head,
  .pl-account-tabs,
  .pl-activity-head,
  .pl-activity-tabs {
    background: var(--pl-panel-2);
  }
}

/* Copilot quick-asks: same glassglow .pl-chip, usable hit area. */
.pl-copilot-chips .pl-chip,
.pl-copilot-chips .pl-copilot-chip {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: 36px;
  padding: 0 12px;
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.03em;
  line-height: 1.2;
  text-transform: none;
  cursor: pointer;
  white-space: nowrap;
}

.pl-copilot-chips .pl-chip:hover,
.pl-copilot-chips .pl-copilot-chip:hover {
  border-color: color-mix(in srgb, var(--pl-chip-hue, var(--pl-sky)) 62%, var(--pl-glass-border));
}

.pl-copilot-chips .pl-chip:focus-visible,
.pl-copilot-chips .pl-copilot-chip:focus-visible {
  outline: 2px solid var(--pl-sky);
  outline-offset: 2px;
}

@media (max-width: 640px) {
  .pl-copilot-chips .pl-chip,
  .pl-copilot-chips .pl-copilot-chip {
    min-height: 44px;
  }
}

@media (prefers-reduced-motion: reduce) {
  .pl-account,
  .pl-activity,
  .pl-account-head,
  .pl-account-tabs,
  .pl-activity-head,
  .pl-activity-tabs,
  .pl-copilot-chips .pl-chip,
  .pl-copilot-chips .pl-copilot-chip {
    transition: none;
  }
}

/* Flow handle: sibling mounted .pl-brand-dot — hide the painted circle. */
.pl-flow-handle:has(.pl-brand-dot)::before {
  content: none;
  display: none;
}

/* Scratch “Build your own”: keep hero-dot emerald, not panel-1 fill. */
.pl-scratch .pl-btn.pl-btn-green,
.pl-app .pl-scratch .pl-btn-green.pl-build-btn {
  background: var(--pl-btn-green-grad);
  color: #fff;
  border-color: color-mix(in srgb, var(--pl-green) 55%, transparent);
  box-shadow: var(--pl-btn-green-shadow), var(--pl-cta-glow-green);
}

/* Site ingest — start from their current public site */
.pl-scratch-ingest {
  margin-top: 12px;
  border-color: color-mix(in srgb, var(--pl-amber) 40%, var(--pl-border));
  background: color-mix(in srgb, var(--pl-amber) 6%, var(--pl-panel-1));
}

.pl-setup-head-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  align-items: center;
}

.pl-ingest-hub-btn[hidden],
.pl-ingest-overlay[hidden] {
  display: none !important;
}

.pl-ingest-overlay {
  position: fixed;
  inset: 0;
  z-index: 81;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 16px;
  background: var(--pl-modal-backdrop);
  backdrop-filter: blur(4px);
  -webkit-backdrop-filter: blur(4px);
}

.pl-ingest {
  width: min(780px, 100%);
  max-height: min(88vh, 920px);
  overflow: auto;
  border-radius: 16px;
  border: 1.5px solid var(--pl-border);
  background: var(--pl-panel-1);
  box-shadow: var(--pl-modal-shadow, 0 18px 48px color-mix(in srgb, #000 28%, transparent));
  display: flex;
  flex-direction: column;
}

.pl-ingest-head,
.pl-ingest-foot {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 12px;
  padding: 20px 22px 12px;
}

.pl-ingest-foot {
  align-items: center;
  padding: 12px 22px 20px;
  border-top: 1px solid var(--pl-border);
}

.pl-ingest-body {
  padding: 0 22px 8px;
  flex: 1 1 auto;
  min-height: 0;
  overflow: auto;
}

.pl-ingest-sub,
.pl-ingest-tagline,
.pl-ingest-id,
.pl-ingest-meta,
.pl-ingest-status,
.pl-ingest-code,
.pl-ingest-hint {
  margin: 6px 0 0;
  font-size: 13px;
  line-height: 1.45;
  color: var(--pl-muted);
}

.pl-ingest-hint {
  margin-top: 12px;
}

.pl-ingest-label {
  display: block;
  margin-bottom: 6px;
  font-size: 13px;
  font-weight: 650;
}

.pl-ingest-error {
  margin: 0;
  color: var(--pl-red, #b42318);
  font-size: 14px;
}

.pl-ingest-company {
  margin: 4px 0 0;
  font-size: 20px;
}

.pl-ingest-h3 {
  margin: 16px 0 8px;
  font-size: 13px;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--pl-muted);
}

.pl-ingest-pages,
.pl-ingest-notes {
  margin: 0;
  padding: 0;
  list-style: none;
}

.pl-ingest-page {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  gap: 8px;
  padding: 10px 0;
  border-bottom: 1px solid var(--pl-border);
}

.pl-ingest-page-main {
  flex: 1 1 220px;
  min-width: 0;
}

.pl-ingest-page-title {
  display: block;
  font-weight: 650;
}

.pl-ingest-page-path {
  display: block;
  font-size: 12px;
  color: var(--pl-muted);
}

.pl-ingest-excerpt,
.pl-ingest-full,
.pl-ingest-int-op,
.pl-ingest-int-ev {
  margin: 6px 0 0;
  font-size: 12px;
  line-height: 1.45;
  color: var(--pl-muted);
}

.pl-ingest-excerpt {
  display: -webkit-box;
  -webkit-line-clamp: 3;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

.pl-ingest-details {
  margin-top: 6px;
  font-size: 12px;
}

.pl-ingest-details summary {
  cursor: pointer;
  font-weight: 650;
}

.pl-ingest-imgs {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(96px, 1fr));
  gap: 8px;
  margin: 8px 0 0;
}

.pl-ingest-imgs-row {
  grid-template-columns: repeat(auto-fill, minmax(72px, 1fr));
}

.pl-ingest-thumb {
  margin: 0;
}

.pl-ingest-thumb img {
  display: block;
  width: 100%;
  aspect-ratio: 1;
  object-fit: cover;
  border-radius: 8px;
  background: color-mix(in srgb, var(--pl-muted) 12%, transparent);
  border: 1px solid var(--pl-border);
}

.pl-ingest-thumb-cap {
  margin-top: 4px;
  font-size: 10px;
  line-height: 1.3;
  color: var(--pl-muted);
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

.pl-ingest-ints {
  margin: 0;
  padding: 0;
  list-style: none;
}

.pl-ingest-int {
  padding: 8px 0;
  border-bottom: 1px solid var(--pl-border);
}

.pl-ingest-int-ev {
  display: block;
}

.pl-ingest-disp {
  display: flex;
  gap: 4px;
}

.pl-ingest-disp-btn {
  min-height: 32px;
  padding: 0 10px;
  border-radius: 8px;
  border: 1px solid var(--pl-border);
  background: transparent;
  color: var(--pl-text);
  font-size: 12px;
}

.pl-ingest-disp-on {
  border-color: color-mix(in srgb, var(--pl-green) 55%, var(--pl-border));
  background: color-mix(in srgb, var(--pl-green) 12%, transparent);
}

.pl-ingest-chips {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  margin: 0;
}

.pl-ingest-notes li {
  margin: 0 0 6px;
  font-size: 13px;
  color: var(--pl-muted);
}

.pl-ingest-comp-btn {
  margin: 8px 0 16px;
}

/* ── Uniform card rhythm ────────────────────────────────────────────────
   Grid siblings stretch to one row height. Titles clamp to a reserved
   number of lines. Footer / badges / actions pin to the card bottom so a
   wrapping title never drops the CTA off a shared baseline.
   Owner: map_view.rs picture-nodes, ideas_desk.rs cards, setup hub,
   composer page-type picker. Later than the cluster-grid "align-items:
   start + fixed card width" block so these win. */

.pl-chart-cluster-grid.pl-chart-cluster-grid {
  align-items: stretch;
  justify-items: stretch;
}

.pl-chart-cluster-grid .pl-page-cell {
  width: 100%;
  min-width: 0;
  height: 100%;
  display: flex;
  flex-direction: column;
  align-items: stretch;
}

.pl-chart-cluster-grid--scoped .pl-page-cell {
  justify-content: stretch;
}

.pl-chart-cluster-grid .pl-page-cell-root {
  justify-content: center;
}

.pl-app .pl-chart-cluster-grid .pl-page-cell:not(.pl-page-cell-root) > .pl-pic-node,
.pl-app .pl-chart-cluster-grid--scoped .pl-page-cell:not(.pl-page-cell-root) > .pl-pic-node {
  width: 100%;
  max-width: none;
  min-width: 0;
  height: 100%;
  flex: 1 1 auto;
}

.pl-app .pl-chart-cluster-grid .pl-page-cell-root > .pl-pic-node,
.pl-app .pl-chart-cluster-grid--scoped .pl-page-cell-root > .pl-pic-node {
  width: min(240px, 100%);
  max-width: min(280px, 100%);
  margin-inline: auto;
  height: 100%;
}

.pl-pic-caption .pl-nt {
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 2;
  overflow: hidden;
  min-height: calc(1.25em * 2);
}

.pl-pic-caption .pl-badges {
  min-height: 22px;
  align-content: flex-start;
}

.pl-journey-missing {
  height: 100%;
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.pl-journey-missing .pl-journey-add-btn {
  margin-top: auto;
}

.pl-idea-card.pl-ideas-desk-card {
  height: 100%;
  min-height: 0;
}

.pl-ideas-desk-card .pl-idea-title,
.pl-ideas-desk-leader-title {
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 2;
  overflow: hidden;
  min-height: calc(1.35em * 2);
}

.pl-ideas-desk-card .pl-idea-pitch,
.pl-ideas-desk-leader-pitch {
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 3;
  overflow: hidden;
  flex: 1 1 auto;
  min-height: calc(1.5em * 2);
}

.pl-ideas-desk-card .pl-idea-why {
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 2;
  overflow: hidden;
}

.pl-ideas-desk-card .pl-idea-why[hidden] {
  display: none !important;
}

.pl-ideas-insight .pl-ideas-desk-cites {
  margin-top: auto;
}

.pl-ideas-desk-card .pl-ideas-desk-ask,
.pl-ideas-desk-leader .pl-ideas-desk-ask {
  margin-top: auto;
}

.pl-ideas-insight-card {
  height: auto;
}

.pl-ideas-insight-card strong {
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 2;
  overflow: hidden;
}

.pl-ideas-insight-card > span {
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 3;
  overflow: hidden;
}

.pl-ideas-insight-card .pl-ideas-desk-ask {
  margin-top: auto;
}

.pl-setup-grid.pl-setup-grid {
  align-items: stretch;
}

.pl-comp-grid.pl-comp-grid {
  align-items: stretch;
}

.pl-comp-card-name.pl-comp-card-name {
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 2;
  overflow: hidden;
}

.pl-comp-card-desc.pl-comp-card-desc {
  flex: 1 1 auto;
}

@media (max-width: 900px) {
  .pl-ideas-desk-suggest,
  .pl-ideas-desk-leaders,
  .pl-ideas-insights {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}

@media (max-width: 640px) {
  .pl-ideas-desk-suggest,
  .pl-ideas-desk-leaders,
  .pl-ideas-insights {
    grid-template-columns: 1fr;
  }
}

/* ── Planner chrome (last word) ─────────────────────────────────────────
   One pill geometry. Page tabs used to swap .pl-chip-later / .pl-chip-draft
   and inherit two stamp families. They are now .pl-pagenav-chip; selected
   is aria-pressed only. Topbar looking-chip / kbd share the same tokens. */
.pl-app .pl-looking-chip,
.pl-app .pl-pagenav-chip,
.pl-app .pl-topbar .pl-kbd-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  box-sizing: border-box;
  height: var(--pl-chrome-h);
  min-height: var(--pl-chrome-h);
  padding: 0 var(--pl-chrome-pad-x);
  border-radius: var(--pl-chrome-radius);
  font-family: var(--font-sans);
  font-size: var(--pl-chrome-font);
  font-weight: var(--pl-chrome-weight);
  letter-spacing: 0.02em;
  background: color-mix(in srgb, var(--pl-sky) 10%, var(--pl-chrome-bg));
  border: 1px solid var(--pl-chrome-border);
  color: var(--pl-chrome-ink);
  box-shadow: var(--pl-chrome-glass);
  backdrop-filter: blur(10px) saturate(1.2);
  -webkit-backdrop-filter: blur(10px) saturate(1.2);
}

.pl-app .pl-pagenav-chip {
  gap: 6px;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  cursor: pointer;
  white-space: nowrap;
}

.pl-app .pl-pagenav-chip::before {
  content: none !important;
  background-image: none !important;
}

.pl-app .pl-pagenav-chip[aria-pressed="true"] {
  background: color-mix(in srgb, var(--pl-sky) 20%, var(--pl-chrome-bg));
  border-color: color-mix(in srgb, var(--pl-sky) 70%, var(--pl-glass-border));
  color: color-mix(in srgb, var(--pl-blue) 40%, var(--pl-text));
}

.pl-app .pl-pagenav-chip:hover,
.pl-app .pl-pagenav-chip:focus-visible {
  border-color: color-mix(in srgb, var(--pl-sky) 62%, var(--pl-border));
}

.pl-app .pl-pagenav-chip:focus-visible {
  outline: 2px solid var(--pl-sky);
  outline-offset: 2px;
}

.pl-app .pl-pagenav-arrow {
  position: relative;
  width: var(--pl-chrome-h);
  height: var(--pl-chrome-h);
  min-width: var(--pl-chrome-h);
  min-height: var(--pl-chrome-h);
  border-radius: 10px;
  background: color-mix(in srgb, var(--pl-sky) 10%, var(--pl-chrome-bg));
  border: 1px solid var(--pl-chrome-border);
  color: var(--pl-chrome-ink);
  box-shadow: var(--pl-chrome-glass);
}

.pl-app .pl-pagenav-arrow::after {
  content: "";
  position: absolute;
  inset: -6px;
}

.pl-app .pl-topbar .pl-icon-btn {
  width: var(--pl-chrome-h);
  min-width: var(--pl-chrome-h);
  height: var(--pl-chrome-h);
  min-height: var(--pl-chrome-h);
  border-radius: var(--pl-chrome-radius);
  border: 1px solid var(--pl-chrome-border);
  background: var(--pl-chrome-bg);
}

.pl-login {
  min-height: 100svh;
  display: grid;
  place-items: center;
  padding: 2rem 1.25rem;
  background: var(--bg, #f7f4ee);
}

.pl-login .login-card {
  width: min(100%, 22rem);
}

.pl-login-kicker {
  margin: 0 0 0.35rem;
  font-family: var(--font-mono);
  font-size: 0.7rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--color-muted, #64748b);
}

.pl-login-h {
  margin: 0 0 0.5rem;
  font-size: 1.35rem;
  line-height: 1.2;
}

.pl-login-lede {
  margin: 0 0 1.25rem;
  color: var(--color-muted, #64748b);
  font-size: 0.92rem;
  line-height: 1.45;
}

.pl-app[data-credits="off"] .pl-sidebar-profile-credits,
.pl-app[data-credits="off"] .pl-credit-chip,
.pl-app[data-credits="off"] .pl-apply-cost,
.pl-app[data-credits="off"] .pl-drawer-item-cost {
  display: none;
}

/* Client signup (/portal/signup) */
.su-page {
  width: 100%;
  padding: 2.75rem 1.25rem 4.5rem;
  background: color-mix(in srgb, var(--color-panel) 72%, #fff);
  border-top: 1px solid var(--color-border);
  color: var(--color-text);
}

.su-grid {
  max-width: 72rem;
  margin: 0 auto;
  display: grid;
  gap: 2.25rem;
}

@media (min-width: 880px) {
  .su-grid {
    grid-template-columns: minmax(0, 1fr) minmax(0, 1.08fr);
    gap: 3rem;
    align-items: start;
  }
}

.su-copy {
  max-width: 36rem;
}

.su-copy .su-title,
.su-success .su-title {
  margin: 0 0 0.85rem;
  font-family: var(--font-display);
  font-size: clamp(1.7rem, 3vw, 2.35rem);
  font-weight: 600;
  letter-spacing: -0.02em;
  line-height: 1.2;
  color: var(--color-chrome);
}

.su-copy p {
  margin: 0 0 1rem;
  line-height: 1.55;
  color: var(--color-text);
}

.su-copy ul {
  margin: 0 0 1.25rem;
  padding-left: 1.2rem;
  color: var(--color-text);
}

.su-copy li {
  margin: 0.4rem 0;
  line-height: 1.5;
}

.su-card {
  background: #ffffff;
  color: var(--color-text);
  border: 1px solid var(--color-chrome);
  border-radius: var(--radius-card);
  box-shadow: var(--shadow-card);
  padding: 0 1.35rem 1.7rem;
  overflow: hidden;
}

.su-mast {
  margin: 0 -1.35rem 1.15rem;
  padding: 1.15rem 1.35rem 1rem;
  background: var(--color-chrome);
  color: #ffffff;
}

.su-mast-brand,
.su-success .su-mast-brand {
  margin: 0 0 0.2rem;
  font-family: var(--font-display);
  font-size: 1.15rem;
  letter-spacing: 0.06em;
  color: #ffffff;
}

.su-success .su-mast-brand {
  color: var(--color-chrome);
}

.su-mast-sub {
  margin: 0;
  font-size: 0.8rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: #c4a36a;
}

.su-lede {
  margin: 0 0 1.1rem;
  font-size: 0.9rem;
  line-height: 1.5;
  color: var(--color-text-muted);
}

.su-set {
  margin: 0 0 1.15rem;
  padding: 0.85rem 0 0;
  border: 0;
  border-top: 1px solid var(--color-border);
}

.su-legend {
  padding: 0 0.4rem 0 0;
  font-size: 0.75rem;
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--color-chrome);
}

.su-form {
  display: block;
  margin: 0;
}

.su-field {
  display: grid;
  gap: 0.35rem;
  margin: 0 0 0.95rem;
}

.su-label {
  font-size: 0.875rem;
  font-weight: 600;
  color: var(--color-text);
}

.su-optional {
  font-weight: 500;
  color: var(--color-text-faint);
}

.su-hint {
  margin: 0;
  font-size: 0.75rem;
  font-family: var(--font-mono);
  color: var(--color-text-faint);
}

.su-field input,
.su-field select,
.su-field textarea {
  display: block;
  width: 100%;
  box-sizing: border-box;
  padding: 0.65rem 0.75rem;
  background: #ffffff;
  color: var(--color-text);
  border: 1px solid var(--color-border);
  border-radius: 0.4rem;
  font: inherit;
  font-size: 0.9375rem;
  line-height: 1.4;
  appearance: auto;
  color-scheme: light;
}

.su-field textarea {
  min-height: 6.5rem;
  resize: vertical;
}

.su-field input:focus,
.su-field select:focus,
.su-field textarea:focus,
.su-check input:focus-visible {
  outline: 2px solid var(--color-accent-strong);
  outline-offset: 2px;
  border-color: var(--color-accent-strong);
}

.su-error {
  margin: 0.35rem 0 0.85rem;
  color: var(--color-danger);
  font-size: 0.875rem;
  line-height: 1.45;
}

.su-check {
  display: flex;
  align-items: flex-start;
  gap: 0.65rem;
  margin: 0.35rem 0 1rem;
  font-size: 0.875rem;
  line-height: 1.45;
  color: var(--color-text);
}

.su-check input[type="checkbox"] {
  width: 1.125rem;
  height: 1.125rem;
  margin: 0.15rem 0 0;
  flex-shrink: 0;
  accent-color: var(--color-accent-strong);
  background: #ffffff;
  color-scheme: light;
}

.su-submit {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  margin: 0.35rem 0 0;
  padding: 0.7rem 1.1rem;
  border-radius: 0.4rem;
  border: 1px solid var(--color-chrome);
  background: var(--color-chrome);
  color: #ffffff;
  font: inherit;
  font-size: 0.9375rem;
  font-weight: 600;
  text-decoration: none;
  cursor: pointer;
  transition: background 120ms ease, border-color 120ms ease;
}

.su-submit:hover {
  background: var(--color-chrome-2);
  border-color: var(--color-chrome-2);
  color: #ffffff;
}

.su-submit:disabled {
  opacity: 0.6;
  cursor: not-allowed;
}

.su-signin {
  margin: 1rem 0 0;
  text-align: center;
  font-size: 0.875rem;
}

.su-success {
  padding-top: 1.5rem;
}

.su-success p {
  margin: 0 0 1rem;
  line-height: 1.55;
  color: var(--color-text);
}

.su-success .su-submit {
  margin-top: 0.5rem;
}

@media (prefers-reduced-motion: reduce) {
  .su-page .su-submit {
    transition: none;
  }
}



