/* ============================================================
   PixelGif — editor styling
   Wears the PixelGif identity via theme.css tokens (no raw
   literals). Cyber-noir base shared structurally with the Swerve
   family; cyan = primary UI, magenta = active/selected/focus,
   teal = status only. Glow is reserved for focal/active elements.
   ============================================================ */

*,
*::before,
*::after { box-sizing: border-box; }

body {
  background:
    radial-gradient(120% 80% at 80% -10%, color-mix(in srgb, var(--pg-accent) 10%, transparent), transparent 60%),
    linear-gradient(135deg, var(--pg-bg-1) 0%, var(--pg-bg) 55%, var(--pg-surface) 100%);
  background-repeat: no-repeat;
  color: var(--pg-text);
  font-family: var(--pg-font-ui);
  margin: 0;
  overflow-x: hidden;
  position: relative;
  min-height: 100vh;
}

/* --- Accessibility helpers --- */
.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;
}
:focus-visible {
  outline: 2px solid var(--pg-focus);
  outline-offset: 2px;
  border-radius: var(--pg-radius-sm);
}

/* ============================================================
   App header
   ============================================================ */
.navbar {
  position: sticky;
  top: 0;
  width: 100%;
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: var(--pg-space-4);
  background: color-mix(in srgb, var(--pg-bg-1) 72%, transparent);
  backdrop-filter: blur(10px);
  border-bottom: 1px solid var(--pg-border);
  box-shadow: var(--pg-shadow-sm);
  z-index: var(--pg-z-header);
  padding: var(--pg-space-2) var(--pg-space-8);
}
.nav-brand { display: flex; align-items: center; gap: var(--pg-space-4); min-width: 0; }
.navbar .brand {
  font-family: var(--pg-font-ui);
  font-size: var(--pg-text-xl);
  font-weight: var(--pg-weight-display);
  letter-spacing: -0.02em;
  color: var(--pg-text);
  text-decoration: none;
}
.navbar .brand::first-letter { color: var(--pg-accent); }
.nav-meta {
  display: flex;
  align-items: center;
  gap: var(--pg-space-6);
}
.nav-tagline {
  font-family: var(--pg-font-mono);
  font-size: var(--pg-text-xs);
  font-weight: var(--pg-weight-medium);
  letter-spacing: var(--pg-tracking-label);
  text-transform: uppercase;
  color: var(--pg-muted);
}

/* Status pill — repurposed as the export ready/encoding/done signal */
.status-pill {
  display: inline-flex;
  align-items: center;
  gap: var(--pg-space-2);
  font-family: var(--pg-font-mono);
  font-size: var(--pg-text-xs);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--pg-status);
  border: 1px solid color-mix(in srgb, var(--pg-status) 35%, transparent);
  background: color-mix(in srgb, var(--pg-status) 8%, transparent);
  padding: 0.3rem 0.6rem;
  border-radius: var(--pg-radius-sm);
}
.status-dot {
  width: 7px; height: 7px;
  border-radius: 50%;
  background: var(--pg-status);
  box-shadow: 0 0 8px var(--pg-status);
  animation: pg-pulse 2s var(--pg-ease) infinite;
}
@keyframes pg-pulse { 0%,100% { opacity: 1; } 50% { opacity: 0.35; } }

/* ============================================================
   Hero — lightweight family "face"
   ============================================================ */
.pg-hero {
  max-width: var(--pg-container);
  margin: 0 auto;
  padding: clamp(2.5rem, 6vw, 4.5rem) var(--pg-space-6) clamp(2rem, 4vw, 3rem);
  text-align: left;
}
.pg-eyebrow {
  display: inline-flex;
  align-items: center;
  gap: var(--pg-space-3);
  margin: 0 0 var(--pg-space-4);
  font-family: var(--pg-font-mono);
  font-size: var(--pg-text-xs);
  font-weight: var(--pg-weight-medium);
  letter-spacing: var(--pg-tracking-label);
  text-transform: uppercase;
  color: var(--pg-muted);
}
.pg-eyebrow::before {
  content: "";
  width: 28px; height: 2px;
  background: linear-gradient(90deg, var(--pg-accent), var(--pg-accent-2));
  border-radius: 2px;
}
.pg-hero-title {
  margin: 0 0 var(--pg-space-4);
  max-width: 18ch;
  font-size: var(--pg-text-3xl);
  font-weight: var(--pg-weight-display);
  line-height: 1.05;
  letter-spacing: -0.02em;
  color: var(--pg-text);
}
.pg-hero-sub {
  margin: 0 0 var(--pg-space-6);
  max-width: 56ch;
  color: var(--pg-muted);
  font-size: var(--pg-text-lg);
  line-height: 1.55;
}
.pg-cta {
  display: inline-flex;
  align-items: center;
  gap: var(--pg-space-2);
  padding: 0.7rem 1.3rem;
  background: var(--pg-accent);
  color: var(--pg-on-accent);
  font-weight: var(--pg-weight-bold);
  text-decoration: none;
  border: 1px solid transparent;
  border-radius: var(--pg-radius-full);
  box-shadow: var(--pg-glow);
  transition: transform var(--pg-dur) var(--pg-ease),
              background var(--pg-dur) var(--pg-ease),
              gap var(--pg-dur) var(--pg-ease);
}
.pg-cta:hover { background: var(--pg-accent-hi); transform: translateY(-2px); gap: var(--pg-space-3); }
.pg-cta span { transition: transform var(--pg-dur) var(--pg-ease); }
.pg-cta:hover span { transform: translateY(2px); }

/* ============================================================
   Editor shell  (layout geometry unchanged — Phase C reworks this)
   ============================================================ */
.container {
  display: flex;
  flex-direction: column;
  max-width: calc(100vw - 40px);
  width: 100%;
  min-height: calc(100vh - 80px);
  margin: 0 auto;
  background: color-mix(in srgb, var(--pg-surface) 35%, transparent);
  border: 1px solid var(--pg-border);
  border-radius: var(--pg-radius-lg);
  backdrop-filter: blur(12px);
  box-shadow: var(--pg-shadow-lg);
  overflow: visible;
  position: relative;
}

.sidebar-left {
  width: 200px;
  background: color-mix(in srgb, var(--pg-surface) 70%, transparent);
  border-right: 1px solid var(--pg-border);
  position: absolute;
  top: 0; bottom: 0; left: 0;
  z-index: var(--pg-z-sidebar-l);
  display: flex;
  flex-direction: column;
}
.static-tools {
  position: sticky;
  top: 0;
  background: color-mix(in srgb, var(--pg-surface) 80%, transparent);
  padding: var(--pg-space-4);
  z-index: var(--pg-z-sticky);
}
.tool-controls {
  display: flex;
  flex-direction: row;
  justify-content: space-between;
  gap: 1px;
  flex-wrap: nowrap;
  width: 100%;
  margin-top: var(--pg-space-2);
}
.scrollable-tools {
  flex: 1;
  overflow-y: auto;
  padding: var(--pg-space-4);
  padding-top: 0;
  padding-bottom: var(--pg-space-8);
}
.scrollable-tools::-webkit-scrollbar,
.scrollable-controls::-webkit-scrollbar { width: 8px; }
.scrollable-tools::-webkit-scrollbar-track,
.scrollable-controls::-webkit-scrollbar-track { background: var(--pg-bg); }
.scrollable-tools::-webkit-scrollbar-thumb,
.scrollable-controls::-webkit-scrollbar-thumb { background: var(--pg-accent); border-radius: 4px; }
.scrollable-tools::-webkit-scrollbar-thumb:hover,
.scrollable-controls::-webkit-scrollbar-thumb:hover { background: var(--pg-accent-hi); }

.image-tools-container,
.frame-image-tools-container,
.trace-tools-container,
.zoom-tools-container,
.rotation-tools-container,
.text-tools-container,
.color-palette {
  margin-top: var(--pg-space-4);
  padding: var(--pg-space-2);
  background: color-mix(in srgb, var(--pg-surface-2) 55%, transparent);
  border: 1px solid var(--pg-border);
  border-radius: var(--pg-radius-sm);
}
.palette-grid { display: grid; grid-template-columns: repeat(5, 1fr); gap: 5px; }
.color-swatch {
  width: 22px; height: 22px;
  border: 2px solid var(--pg-border);
  border-radius: var(--pg-radius-sm);
  cursor: pointer;
  transition: transform var(--pg-dur) var(--pg-ease), border-color var(--pg-dur) var(--pg-ease);
}
.color-swatch:hover { transform: scale(1.12); border-color: var(--pg-accent); }
.color-swatch:focus-visible { outline: 2px solid var(--pg-focus); outline-offset: 2px; }

.sidebar-right {
  width: 200px;
  max-width: 200px;
  background: color-mix(in srgb, var(--pg-surface) 70%, transparent);
  border-left: 1px solid var(--pg-border);
  position: absolute;
  top: 0; bottom: 0; right: 0;
  z-index: var(--pg-z-sidebar-r);
  height: 100%;
  display: flex;
  flex-direction: column;
}
.static-controls {
  position: sticky;
  top: 0;
  background: color-mix(in srgb, var(--pg-surface) 80%, transparent);
  padding: var(--pg-space-4);
  z-index: var(--pg-z-sticky);
}
.scrollable-controls {
  flex: 1;
  overflow-y: auto;
  padding: var(--pg-space-4);
  padding-top: 0;
  padding-bottom: var(--pg-space-8);
}

/* S14 — desktop: keep every control reachable. The sidebars are absolute
   columns spanning the full container, and the container grows with the
   canvas/frames column — so at common window heights the inner scrollers'
   windows (and their scrollbars) extended below the fold: lower controls
   were effectively unreachable and the thumb looked detached mid-page.
   Cap each sidebar at the viewport and let the whole column scroll as one
   list. DOM untouched (the static/scrollable split is load-bearing for the
   C2 mobile sheets); ≤768px keeps the C1 column layout. */
@media (min-width: 769px) {
  .sidebar-left,
  .sidebar-right {
    bottom: auto;
    height: min(100%, calc(100vh - 80px));
    overflow-y: auto;
    overscroll-behavior: contain;
    border-bottom: 1px solid var(--pg-border);
  }
  /* Left tool header keeps its sticky pin — it now sticks against the
     sidebar scroller, so pencil/eraser stay handy while adjusting sliders.
     The right header is far too tall to pin; it scrolls with the column. */
  .static-controls { position: static; }
  /* Content scrolls beneath the pinned header now — opaque backdrop so
     scrolled labels don't ghost through the 80%-translucent surface. */
  .static-tools {
    background: color-mix(in srgb, var(--pg-surface) 88%, var(--pg-bg));
  }
  .scrollable-tools,
  .scrollable-controls {
    flex: none;
    overflow-y: visible;
  }
  .sidebar-left::-webkit-scrollbar,
  .sidebar-right::-webkit-scrollbar { width: 8px; }
  .sidebar-left::-webkit-scrollbar-track,
  .sidebar-right::-webkit-scrollbar-track { background: var(--pg-bg); }
  .sidebar-left::-webkit-scrollbar-thumb,
  .sidebar-right::-webkit-scrollbar-thumb { background: var(--pg-accent); border-radius: 4px; }
  .sidebar-left::-webkit-scrollbar-thumb:hover,
  .sidebar-right::-webkit-scrollbar-thumb:hover { background: var(--pg-accent-hi); }
}

.main-content {
  flex: 1;
  display: flex;
  justify-content: center;
  align-items: center;
  padding: var(--pg-space-8);
  position: relative;
  z-index: 0;
  flex-direction: column;
}

/* ============================================================
   Canvas
   ============================================================ */
canvas {
  border: 2px solid var(--pg-border-hi);
  border-radius: var(--pg-radius-sm);
  image-rendering: pixelated;
  background: transparent;
  box-shadow: var(--pg-shadow-md);
  touch-action: none;
}
.canvas-wrapper { display: inline-block; position: relative; }

/* Checkerboard reveals transparent pixels on the drawing surface */
#drawingCanvas {
  background-color: var(--pg-check-base);
  background-image:
    linear-gradient(45deg, var(--pg-check-sq) 25%, transparent 25%),
    linear-gradient(-45deg, var(--pg-check-sq) 25%, transparent 25%),
    linear-gradient(45deg, transparent 75%, var(--pg-check-sq) 75%),
    linear-gradient(-45deg, transparent 75%, var(--pg-check-sq) 75%);
  background-size: 16px 16px;
  background-position: 0 0, 0 8px, 8px -8px, -8px 0;
}
#previewCanvas {
  box-shadow: var(--pg-shadow-sm); /* lighter than the base canvas rule's md */
}
.preview-canvas-wrapper { display: inline-block; position: relative; background: var(--pg-paper); }

/* The small right-side preview is retired — the MAIN canvas is now the live preview.
   #previewCanvas + #previewFrameNumber stay in the DOM (the engine binds them by id and
   paints #previewCanvas as the clean composite the main-canvas FX overlay samples; m12's
   readout mirrors #previewFrameNumber) but are hidden from view. */
#previewCanvasWrapper,
#previewFrameNumber { display: none; }

/* Live hover pixel-coordinate readout (populated by src/m3-canvas-aids) */
.pg-coords {
  font-family: var(--pg-font-mono);
  font-size: var(--pg-text-xs);
  letter-spacing: 0.06em;
  color: var(--pg-dim);
  margin-top: var(--pg-space-2);
  min-height: 1.1em;
}

/* ============================================================
   Buttons
   ============================================================ */
.tool-button,
.frame-button {
  background: var(--pg-surface-2);
  color: var(--pg-text);
  font-family: inherit;
  border: 1px solid var(--pg-border);
  padding: var(--pg-space-2);
  border-radius: var(--pg-radius-sm);
  cursor: pointer;
  transition: transform var(--pg-dur) var(--pg-ease),
              border-color var(--pg-dur) var(--pg-ease),
              background var(--pg-dur) var(--pg-ease);
  text-align: center;
  font-size: 1rem;
  width: 2rem; height: 2rem;
  display: flex;
  justify-content: center;
  align-items: center;
}
.tool-button:hover,
.frame-button:hover { border-color: var(--pg-accent); transform: translateY(-2px); }

.tool-button.disabled,
.frame-button.disabled { background: var(--pg-surface); color: var(--pg-dim); cursor: not-allowed; opacity: 0.5; }
.tool-button.disabled:hover,
.frame-button.disabled:hover { transform: none; border-color: var(--pg-border); }

/* Active tool / selected state — magenta identity accent */
.tool-button.active {
  background: color-mix(in srgb, var(--pg-accent-2) 18%, var(--pg-surface-2));
  border-color: var(--pg-accent-2);
  color: var(--pg-text);
  box-shadow: var(--pg-glow-2);
}

/* Primary action pills — solid accent fill that inverts on hover */
#saveColorBtn,
#exportBtn,
#copyPrevTextBtn {
  background: var(--pg-accent);
  color: var(--pg-on-accent);
  border: 1px solid transparent;
  width: 140px;
  padding: 0.5rem;
  border-radius: var(--pg-radius-full);
  cursor: pointer;
  font-family: var(--pg-font-ui);
  font-weight: var(--pg-weight-bold);
  transition: transform var(--pg-dur) var(--pg-ease), background var(--pg-dur) var(--pg-ease);
  text-align: center;
  font-size: 0.9rem;
  margin: 0 auto 0.5rem;
  display: block;
  /* Long labels (e.g. "Copy Prev Settings") exceed the 140px pill inside the
     200px sidebar — wrap instead of clipping. .tool-button's fixed 2rem
     height would clip the second line, so release it here (S14). */
  white-space: normal;
  line-height: 1.25;
  height: auto;
  min-height: 2rem;
}
#saveColorBtn:hover,
#exportBtn:hover,
#copyPrevTextBtn:hover { background: var(--pg-accent-hi); transform: translateY(-2px); }
#exportBtn { box-shadow: var(--pg-glow); }

/* M30 — #exportBtn relocated into the nav meta cluster (desktop): a compact inline
   pill instead of the sidebar's 140px centered block. ID+class outranks #exportBtn.
   Keeps the accent fill + glow + hover from the rules above. */
#exportBtn.pg-nav-export {
  width: auto;
  height: auto;
  min-height: 32px;
  margin: 0;
  padding: 0.4rem 0.9rem;
  display: inline-flex;
  align-items: center;
  gap: 0.35rem;
  font-size: var(--pg-text-xs);
  white-space: nowrap;
}
#exportBtn.pg-nav-export::before {
  content: "\2193"; /* ↓ download hint, nav-only (mobile sheet stays label-only) */
  font-size: 0.9em;
  line-height: 1;
}

/* Destructive actions */
#resetProjectBtn,
#removeTextBtn {
  background: transparent;
  color: var(--pg-danger);
  border: 1px solid color-mix(in srgb, var(--pg-danger) 50%, transparent);
  width: 140px;
  padding: 0.5rem;
  border-radius: var(--pg-radius-full);
  cursor: pointer;
  font-family: var(--pg-font-ui);
  font-weight: var(--pg-weight-bold);
  transition: transform var(--pg-dur) var(--pg-ease), background var(--pg-dur) var(--pg-ease);
  text-align: center;
  font-size: 0.9rem;
  margin: 0 auto 0.5rem;
  display: block;
  white-space: normal;
  line-height: 1.25;
  height: auto;
  min-height: 2rem;
}
#resetProjectBtn:hover,
#removeTextBtn:hover { background: color-mix(in srgb, var(--pg-danger) 15%, transparent); transform: translateY(-2px); }

.preview-controls,
.frame-controls {
  display: flex;
  flex-direction: row;
  justify-content: space-between;
  gap: 1px;
  flex-wrap: nowrap;
  width: 100%;
  margin-top: var(--pg-space-2);
}
.frame-controls-static {
  display: flex;
  flex-direction: row;
  justify-content: center;
  gap: 1px;
  flex-wrap: nowrap;
  width: 140px;
  margin: 0 auto;
}
.preview-frame-number {
  background: var(--pg-accent);
  color: var(--pg-on-accent);
  border-radius: 50%;
  width: 20px; height: 20px;
  display: flex;
  justify-content: center;
  align-items: center;
  font-size: 0.8rem;
  font-weight: bold;
  margin: 0.5rem auto;
}

/* ============================================================
   Live-loop playback bar (directly under the main canvas) — M12
   ============================================================ */
/* Media-player controls: circular secondary prev/next + a prominent filled,
   glowing play/pause (the focal control) + a tabular frame readout. SVG icons
   (crisp on any platform; the two ◀/▶ used to share a glyph). */
.pg-playbar {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: var(--pg-space-3);
  margin-top: var(--pg-space-3);
}
.pg-playbar-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 2.5rem;
  height: 2.5rem;
  padding: 0;
  background: var(--pg-surface-2);
  color: var(--pg-muted);
  border: 1px solid var(--pg-border);
  border-radius: var(--pg-radius-full);
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
  transition:
    color var(--pg-dur) var(--pg-ease),
    border-color var(--pg-dur) var(--pg-ease),
    background var(--pg-dur) var(--pg-ease),
    box-shadow var(--pg-dur) var(--pg-ease),
    transform var(--pg-dur) var(--pg-ease);
}
.pg-playbar-btn svg { width: 1.05rem; height: 1.05rem; fill: currentColor; display: block; }
.pg-playbar-btn:hover {
  color: var(--pg-accent);
  border-color: var(--pg-border-hi);
  background: var(--pg-surface);
  transform: translateY(-1px);
}
.pg-playbar-btn:active { transform: translateY(0) scale(0.95); }

/* Play / pause — the primary, focal control: filled brand cyan with a soft glow,
   stepping up to magenta (the live-paint accent) while playing. */
.pg-playbar-toggle {
  width: 2.85rem;
  height: 2.85rem;
  background: var(--pg-accent);
  border-color: transparent;
  color: var(--pg-on-accent);
  box-shadow: 0 2px 12px color-mix(in srgb, var(--pg-accent) 40%, transparent);
}
.pg-playbar-toggle svg { width: 1.3rem; height: 1.3rem; }
.pg-playbar-toggle:hover {
  background: var(--pg-accent-hi);
  color: var(--pg-on-accent);
  transform: translateY(-1px);
  box-shadow: 0 5px 18px color-mix(in srgb, var(--pg-accent) 55%, transparent);
}
.pg-playbar-toggle.is-playing {
  background: var(--pg-accent-2);
  box-shadow: 0 2px 12px color-mix(in srgb, var(--pg-accent-2) 45%, transparent);
}
.pg-playbar-toggle.is-playing:hover {
  background: var(--pg-accent-2-hi);
  box-shadow: 0 5px 18px color-mix(in srgb, var(--pg-accent-2) 60%, transparent);
}
/* Icon swap: ▶ when idle, ⏸ while playing (driven by m12's .is-playing toggle). */
.pg-playbar-toggle .pg-ico-pause { display: none; }
.pg-playbar-toggle.is-playing .pg-ico-play { display: none; }
.pg-playbar-toggle.is-playing .pg-ico-pause { display: block; }

.pg-playbar-frame {
  margin-left: var(--pg-space-1);
  font-family: var(--pg-font-mono);
  font-size: var(--pg-text-sm);
  font-variant-numeric: tabular-nums;
  letter-spacing: 0.03em;
  color: var(--pg-muted);
  min-width: 4.5ch;
  text-align: center;
}
.pg-playbar-frame .pg-frame-cur { color: var(--pg-text); font-weight: 700; }

/* The new under-canvas bar is the single playback control; keep the old ⏮⏹⏵⏭
   nodes in the DOM (the engine binds them by id at load) but hide them. The small
   #previewCanvas + its frame number stay as a secondary thumbnail. */
.preview-controls { display: none; }

/* On mobile the playback bar is a PERSISTENT slim dock fixed just above the
   tab-bar — so back / play-pause / forward + the frame readout are reachable in
   ANY tab and at any zoom (it used to sit under the canvas and hide while a sheet
   was open). The sheet's bottom + the content padding clear it (see below). */
body.pg-shell .pg-playbar {
  position: fixed;
  left: 0;
  right: 0;
  bottom: var(--pg-tabbar-h);
  height: var(--pg-playbar-h);
  z-index: var(--pg-z-tabbar);
  margin: 0;
  gap: var(--pg-space-2);
  padding: 0 var(--pg-space-2);
  background: var(--pg-surface);
  border-top: 1px solid var(--pg-border);
}

/* ============================================================
   Frames timeline
   ============================================================ */
.frame {
  border: 2px solid var(--pg-border);
  margin: var(--pg-space-2);
  cursor: grab;
  transition: transform var(--pg-dur) var(--pg-ease), border-color var(--pg-dur) var(--pg-ease);
  border-radius: var(--pg-radius-sm);
  position: relative;
}
.frame:hover { transform: translateY(-2px); border-color: var(--pg-accent); }
.frame.active { border-color: var(--pg-accent-2); box-shadow: var(--pg-glow-2); }
.frame-number {
  position: absolute;
  top: -10px; left: -10px;
  background: var(--pg-accent);
  color: var(--pg-on-accent);
  border-radius: 50%;
  width: 20px; height: 20px;
  display: flex;
  justify-content: center;
  align-items: center;
  font-size: 0.8rem;
  font-weight: bold;
}

/* ============================================================
   Inputs, sliders, toggles
   ============================================================ */
#colorPicker,
#imageInput,
#frameImageInput,
#frameTextInput,
#frameTextColorPicker {
  border: 1px solid var(--pg-border);
  border-radius: var(--pg-radius-sm);
  margin-bottom: 0.5rem;
  cursor: pointer;
}
#colorPicker,
#frameTextColorPicker { width: 40px; height: 40px; padding: 2px; background: var(--pg-surface-2); }
#imageInput,
#frameImageInput,
#frameTextInput {
  width: 140px;
  height: auto;
  padding: 0.3rem;
  background: var(--pg-bg);
  color: var(--pg-text);
  margin: 0 auto 0.5rem;
  display: block;
}

#frameDuration {
  background: var(--pg-bg);
  border: 1px solid var(--pg-border);
  border-radius: var(--pg-radius-sm);
  padding: 0.3rem;
  color: var(--pg-text);
  width: 140px;
  margin: 0 auto 0.5rem;
  display: block;
}
#frameDurationLabel {
  font-family: var(--pg-font-mono);
  font-size: var(--pg-text-xs);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--pg-muted);
  text-align: center;
  margin: 0 auto 0.2rem;
  width: 140px;
  white-space: nowrap;
  display: block;
}
#frameDurationWarning,
#frameLimitWarning {
  color: var(--pg-danger);
  font-size: 0.8rem;
  text-align: center;
  margin: 0 auto 0.5rem;
  display: none;
  width: 140px;
}

/* Frame-timing aids (m21): live fps/loop readout + speed presets */
.pg-frame-timing {
  margin: 0 auto 0.4rem;
  font-family: var(--pg-font-mono);
  font-size: var(--pg-text-xs);
  letter-spacing: 0.04em;
  color: var(--pg-muted);
  text-align: center;
}
.pg-speed-presets {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: var(--pg-space-1);
  margin: 0 auto 0.75rem;
  max-width: 200px;
}
.pg-speed-presets button {
  flex: 0 0 auto;
  padding: var(--pg-space-1) var(--pg-space-2);
  font-family: var(--pg-font-mono);
  font-size: var(--pg-text-xs);
  color: var(--pg-muted);
  background: var(--pg-bg);
  border: 1px solid var(--pg-border);
  border-radius: var(--pg-radius-full);
  cursor: pointer;
  transition: color var(--pg-dur) var(--pg-ease), border-color var(--pg-dur) var(--pg-ease);
}
.pg-speed-presets button:hover { color: var(--pg-text); border-color: var(--pg-accent-2); }
.pg-speed-presets button.is-active {
  color: var(--pg-on-accent);
  background: var(--pg-accent);
  border-color: transparent;
}
.pg-speed-presets button:focus-visible { outline: 2px solid var(--pg-focus); outline-offset: 2px; }
@media (max-width: 768px) {
  .pg-speed-presets button { min-height: var(--pg-touch-target); padding: 0 var(--pg-space-3); }
}

input[type="range"] {
  width: 140px;
  background: var(--pg-bg);
  border: 1px solid var(--pg-border);
  border-radius: var(--pg-radius-sm);
  padding: 0.25rem;
  color: var(--pg-text);
  margin: 0 auto 0.5rem;
  display: block;
  -webkit-appearance: none;
  appearance: none;
  touch-action: none;
}
input[type="range"]::-webkit-slider-thumb {
  -webkit-appearance: none;
  appearance: none;
  width: 16px; height: 16px;
  background: var(--pg-accent);
  border-radius: 50%;
  cursor: pointer;
}
input[type="range"]::-moz-range-thumb {
  width: 16px; height: 16px;
  background: var(--pg-accent);
  border: none;
  border-radius: 50%;
  cursor: pointer;
}
.slider-label {
  font-family: var(--pg-font-mono);
  font-size: var(--pg-text-xs);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--pg-muted);
  text-align: center;
  margin: 0.2rem auto;
  /* Full container width + wrap — fixed 140px nowrap clipped long labels
     ("Include Overlay in GIF") at the panel edge (S14). */
  width: 100%;
  white-space: normal;
  display: block;
}

.toggle-container {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 140px;
  margin: 0 auto 0.5rem;
  position: relative;
}
/* Visually-hidden (NOT display:none) so the toggle stays keyboard-focusable */
#imagePosition,
#includeOverlay,
#frameImagePosition {
  position: absolute;
  width: 1px; height: 1px;
  opacity: 0;
  pointer-events: none;
}
.toggle-label {
  display: flex;
  width: 140px; height: 30px;
  background: var(--pg-bg);
  border: 1px solid var(--pg-border);
  border-radius: var(--pg-radius-full);
  position: relative;
  cursor: pointer;
  transition: border-color var(--pg-dur) var(--pg-ease);
}
.toggle-label::before {
  content: "";
  position: absolute;
  top: 2px; left: 2px;
  width: 66px; height: 24px;
  background: var(--pg-accent);
  border-radius: var(--pg-radius-full);
  transition: transform var(--pg-dur) var(--pg-ease);
}
#imagePosition:checked + .toggle-label::before,
#includeOverlay:checked + .toggle-label::before,
#frameImagePosition:checked + .toggle-label::before { transform: translateX(66px); }
#imagePosition:focus-visible + .toggle-label,
#includeOverlay:focus-visible + .toggle-label,
#frameImagePosition:focus-visible + .toggle-label { outline: 2px solid var(--pg-focus); outline-offset: 2px; }
.toggle-text {
  position: absolute;
  top: 50%;
  transform: translateY(-50%);
  font-family: var(--pg-font-mono);
  font-size: 0.62rem;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--pg-muted);
  pointer-events: none;
}
.toggle-text.below, .toggle-text.off { left: 14px; }
.toggle-text.above, .toggle-text.on { right: 14px; }
/* The label UNDER the moving pill is the selected one — give it dark on-accent
   text (readable on the cyan pill); the other label keeps the muted track colour
   (readable on the dark track). The pill sits left when unchecked, right (translateX)
   when checked, so below/off are active when unchecked and above/on when checked. */
#imagePosition:not(:checked) + .toggle-label .toggle-text.below,
#imagePosition:checked + .toggle-label .toggle-text.above,
#includeOverlay:not(:checked) + .toggle-label .toggle-text.off,
#includeOverlay:checked + .toggle-label .toggle-text.on,
#frameImagePosition:not(:checked) + .toggle-label .toggle-text.below,
#frameImagePosition:checked + .toggle-label .toggle-text.above { color: var(--pg-on-accent); }

/* ============================================================
   Grid controls (m29): the slimmed pixel-size picker sits in a
   row with a compact grid-lines On/Off toggle, under the palette.
   ============================================================ */
.grid-controls {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--pg-space-2);
  margin-bottom: 0.5rem;
}
.grid-ctl-label {
  font-family: var(--pg-font-mono);
  font-size: var(--pg-text-xs);
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--pg-muted);
}
/* Slim the size picker to hug its number instead of spanning the column. */
.grid-controls .grid-size {
  width: auto;
  min-width: 56px;
  flex: 0 0 auto;
  margin: 0;
}
/* Visually-hidden (NOT display:none) so the toggle stays keyboard-focusable */
#showGridToggle {
  position: absolute;
  width: 1px; height: 1px;
  opacity: 0;
  pointer-events: none;
}
/* Compact toggle variant — narrower than the full 140px pill so it fits the row. */
.toggle-container.is-compact {
  width: 84px;
  margin: 0;
}
.toggle-container.is-compact .toggle-label { width: 84px; }
.toggle-container.is-compact .toggle-label::before { width: 40px; }
#showGridToggle:checked + .toggle-label::before { transform: translateX(40px); }
#showGridToggle:focus-visible + .toggle-label { outline: 2px solid var(--pg-focus); outline-offset: 2px; }
#showGridToggle:not(:checked) + .toggle-label .toggle-text.off,
#showGridToggle:checked + .toggle-label .toggle-text.on { color: var(--pg-on-accent); }

/* ============================================================
   Panel titles  (mono, machine-label grammar)
   ============================================================ */
.panel-title {
  font-family: var(--pg-font-mono);
  font-size: var(--pg-text-sm);
  font-weight: var(--pg-weight-bold);
  letter-spacing: var(--pg-tracking-label);
  text-transform: uppercase;
  color: var(--pg-muted);
  margin: 0 0 1rem;
}
.panel-subtitle {
  font-family: var(--pg-font-mono);
  font-size: var(--pg-text-xs);
  font-weight: var(--pg-weight-medium);
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--pg-muted);
  margin: 0.5rem 0;
}

/* Group titles inside the Adjust tool cards — cyan, mirrors .pg-fx-title so the
   multi-control groups (image overlay / frame image / frame text) read as named
   sections instead of one flat slider stack with duplicated X/Y/Rotation labels. */
.tool-group-title {
  margin: 0 0 var(--pg-space-2);
  font-family: var(--pg-font-mono);
  font-size: var(--pg-text-xs);
  font-weight: var(--pg-weight-bold);
  letter-spacing: var(--pg-tracking-label);
  text-transform: uppercase;
  color: var(--pg-accent);
  text-align: center;
}

/* Collapsible category chevron (m20). Hidden by default; shown on desktop, where
   the categories become click-to-expand. The triangle points down when expanded. */
.pg-collapse-chevron {
  display: none;
  width: 0;
  height: 0;
  border-left: 5px solid transparent;
  border-right: 5px solid transparent;
  border-top: 6px solid currentColor;
  opacity: 0.75;
  transition: transform var(--pg-dur) var(--pg-ease);
}

/* ============================================================
   Collapsible control categories — desktop Adjust column (m20, S32).
   Mobile (<769px) keeps everything expanded; the sheets are tuned separately.
   ============================================================ */
@media (min-width: 769px) {
  .image-tools-container > .tool-group-title,
  .frame-image-tools-container > .tool-group-title,
  .text-tools-container > .tool-group-title {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: var(--pg-space-2);
    cursor: pointer;
    -webkit-user-select: none;
    user-select: none;
    transition: color var(--pg-dur) var(--pg-ease);
  }
  .tool-group-title[role='button']:hover { color: var(--pg-accent-hi); }
  .tool-group-title[role='button']:focus-visible {
    outline: 2px solid var(--pg-focus);
    outline-offset: 2px;
    border-radius: var(--pg-radius-sm);
  }
  .pg-collapse-chevron { display: block; }
  .tool-group-title[aria-expanded='false'] .pg-collapse-chevron { transform: rotate(-90deg); }
  /* !important: some controls carry ID-level display rules (#imageInput,
     #frameTextInput, #removeTextBtn…) that outweigh this collapse selector. */
  .pg-collapsed > :not(.tool-group-title) { display: none !important; }
  .pg-collapsed > .tool-group-title { margin-bottom: 0; }
}

/* ============================================================
   Confirmation dialog
   ============================================================ */
.confirmation-dialog {
  position: fixed;
  top: 50%; left: 50%;
  transform: translate(-50%, -50%);
  background: var(--pg-surface);
  border: 1px solid var(--pg-border);
  padding: 20px;
  border-radius: var(--pg-radius-md);
  box-shadow: var(--pg-shadow-lg);
  z-index: var(--pg-z-modal);
  text-align: center;
  display: none;
}
.confirmation-dialog p { font-size: 1rem; margin-bottom: 1rem; color: var(--pg-text); }
.confirmation-dialog button {
  margin: 0 10px;
  padding: 6px 16px;
  border-radius: var(--pg-radius-sm);
  cursor: pointer;
  color: var(--pg-text);
  font-family: var(--pg-font-ui);
  border: 1px solid var(--pg-border);
}
#confirmYes { background: var(--pg-danger); color: var(--pg-on-accent); border-color: transparent; }
#confirmYes:hover { filter: brightness(1.1); }
#confirmNo { background: var(--pg-accent); color: var(--pg-on-accent); border-color: transparent; }
#confirmNo:hover { background: var(--pg-accent-hi); }

/* ============================================================
   Utility
   ============================================================ */
.field {
  width: 100%;
  padding: 0.5rem;
  margin-bottom: 0.5rem;
  border-radius: var(--pg-radius-sm);
  background: var(--pg-bg);
  color: var(--pg-text);
  border: 1px solid var(--pg-border);
}
#frameList.frame-list { display: flex; flex-wrap: wrap; }

/* --- M2: image / PFP import --- */
.pg-import-bar { display: flex; align-items: center; justify-content: center; gap: 0.75rem; margin: 0 0 0.5rem; flex-wrap: wrap; }
.pg-import-btn {
  background: var(--pg-accent);
  color: var(--pg-on-accent);
  font-weight: var(--pg-weight-bold);
  border: 1px solid transparent;
  border-radius: var(--pg-radius-full);
  padding: 0.55rem 0.95rem;
  cursor: pointer;
  font-family: var(--pg-font-ui);
  transition: transform var(--pg-dur) var(--pg-ease), background var(--pg-dur) var(--pg-ease);
}
.pg-import-btn:hover { background: var(--pg-accent-hi); transform: translateY(-2px); }
.pg-import-tip { color: var(--pg-muted); font-size: var(--pg-text-sm); }
.pg-drop-hint {
  position: absolute;
  inset: 0;
  display: none;
  align-items: center;
  justify-content: center;
  background: color-mix(in srgb, var(--pg-bg) 78%, transparent);
  border: 2px dashed var(--pg-accent);
  color: var(--pg-accent-hi);
  font-weight: var(--pg-weight-bold);
  font-size: 1.15rem;
  border-radius: var(--pg-radius);
  pointer-events: none;
  z-index: var(--pg-z-hint);
}
.pg-drop-hint.visible { display: flex; }

/* --- M3: animation preset engine --- */
.pg-fx {
  margin: 0.5rem 0 0.75rem;
  padding: 0.75rem;
  display: flex;
  flex-direction: column;
  gap: 0.4rem;
  border: 1px solid var(--pg-border);
  border-radius: var(--pg-radius-sm);
  background: var(--pg-surface-2);
}
.pg-fx-title {
  margin: 0 0 0.15rem;
  font-family: var(--pg-font-mono);
  font-size: var(--pg-text-xs);
  font-weight: var(--pg-weight-bold);
  letter-spacing: var(--pg-tracking-label);
  text-transform: uppercase;
  color: var(--pg-accent);
}
.pg-fx-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.6rem;
  font-size: var(--pg-text-sm);
  color: var(--pg-muted);
}
.pg-fx-row > span { flex: 0 0 auto; }
.pg-fx-row .field {
  flex: 1 1 auto;
  width: auto;
  max-width: 58%;
  margin-bottom: 0;
}
.pg-fx-row input[type="range"] {
  flex: 1 1 auto;
  max-width: 58%;
  accent-color: var(--pg-accent);
}
.pg-fx-status {
  margin: 0.2rem 0 0;
  min-height: 1.1em;
  font-family: var(--pg-font-mono);
  font-size: var(--pg-text-xs);
  color: var(--pg-status);
}
/* Overlay canvas that renders pixel/generative effects over the live preview */
.pg-fx-overlay {
  position: absolute;
  display: none;
  pointer-events: none;
  image-rendering: pixelated;
  border-radius: var(--pg-radius-sm);
  z-index: var(--pg-z-fx-overlay);
}
/* The MAIN-canvas effect mirror (m4) reuses .pg-fx-overlay but also carries the
   checkerboard so it fully masks the live draw surface beneath it — no double-image
   when a transform effect offsets the frame, and transparent pixels read as the
   editor checkerboard (matching #drawingCanvas). */
#pgMainFxOverlay {
  background-color: var(--pg-check-base);
  background-image:
    linear-gradient(45deg, var(--pg-check-sq) 25%, transparent 25%),
    linear-gradient(-45deg, var(--pg-check-sq) 25%, transparent 25%),
    linear-gradient(45deg, transparent 75%, var(--pg-check-sq) 75%),
    linear-gradient(-45deg, transparent 75%, var(--pg-check-sq) 75%);
  background-size: 16px 16px;
  background-position: 0 0, 0 8px, 8px -8px, -8px 0;
}
/* Determinate export progress (shown only during encode) */
.pg-fx-progress {
  display: none;
  width: 100%;
  height: 6px;
  margin: 0.15rem 0 0;
  border: none;
  border-radius: var(--pg-radius-full);
  background: var(--pg-bg);
  overflow: hidden;
  appearance: none;
  -webkit-appearance: none;
}
.pg-fx-progress::-webkit-progress-bar { background: var(--pg-bg); border-radius: var(--pg-radius-full); }
.pg-fx-progress::-webkit-progress-value { background: var(--pg-accent); border-radius: var(--pg-radius-full); }
.pg-fx-progress::-moz-progress-bar { background: var(--pg-accent); border-radius: var(--pg-radius-full); }
#exportBtn:disabled { opacity: 0.6; cursor: progress; }

/* ============================================================
   Responsive
   ============================================================ */
/* The add/copy/delete trio now lives in the Frames tab (#sheetFrames). The empty
   placeholder kept in .main-content (so the engine's load-time
   '.main-content .frame-controls' query still resolves) and the moved trio are
   both hidden by default; the mobile block reveals the #sheetFrames one. */
.main-content .frame-controls,
#sheetFrames .frame-controls { display: none; }

/* ------------------------------------------------------------
   Mobile shell — single column, canvas-first (Phase C / C1).
   The @media query is inherently reactive; src/m5-responsive.ts only undoes
   the engine's one-shot DOM reparent so these rules own the layout.
   ------------------------------------------------------------ */
@media (max-width: 768px) {
  /* Slim top bar: tighter vertical padding + hide the tagline so the navbar is a
     single compact row (brand + status pill + donate), reclaiming vertical space.
     The pinned canvas adapts automatically via m6's --pg-app-bar-h measurement. */
  .navbar { padding: var(--pg-space-2) var(--pg-space-3); flex-wrap: wrap; gap: var(--pg-space-2); }
  .navbar .brand { font-size: var(--pg-text-lg); }
  .nav-meta { gap: var(--pg-space-2); }
  .nav-tagline { display: none; }
  /* M30 — fit the nav "Save GIF" button on the slim single-row mobile bar: drop the
     decorative status pill (nothing writes to it) and collapse the inert "coming soon"
     credits pill to its 👛 icon so brand + credits + Save GIF share one row. */
  #statusPill { display: none; }
  .pg-wallet-btn.is-soon { padding: 0.4rem 0.55rem; gap: 0; }
  .pg-wallet-btn.is-soon > span:last-child { display: none; }
  #exportBtn.pg-nav-export { padding: 0.4rem 0.7rem; }
  .pg-pack-label { display: none; } /* slim navbar: paw + arrow only */
  .pg-pack { padding: 0 var(--pg-space-2); gap: var(--pg-space-1); }
  /* Mobile: the canvas sits right below, so the hero CTA is redundant. */
  .pg-cta { display: none; }

  /* Slim hero — keep the brand, drop the paragraph, reach the canvas fast. */
  .pg-hero { padding: clamp(1.25rem, 6vw, 2rem) var(--pg-space-4) var(--pg-space-4); }
  .pg-hero-title { font-size: var(--pg-text-xl); }
  .pg-hero-sub { display: none; }

  /* Single column: canvas first, then tools, then preview / export / frames. */
  .container { min-height: auto; max-width: 100%; }
  .content-wrapper { display: flex; flex-direction: column; gap: var(--pg-space-3); }
  .main-content { order: 1; padding: var(--pg-space-3); align-items: center; justify-content: flex-start; }
  .sidebar-left { order: 2; }
  .sidebar-right { order: 3; }
  .sidebar-left,
  .sidebar-right {
    /* static (not relative) so the engine's GSAP left/right:-150 entrance
       can't shove the column off-screen on mobile (left/right are ignored). */
    position: static;
    width: 100%;
    border: none;
    border-bottom: 1px solid var(--pg-border);
  }
  /* Canvas keeps its native 256px backing — NEVER CSS-scaled (handleDraw maps
     taps via a fixed pixelSize). But Canvas Zoom grows the BACKING (256×zoom, up
     to 1280px), which used to overflow the screen with no way to pan and (when
     pinned) bury the control sheet. So on mobile the wrapper is a bounded scroll
     VIEWPORT: an oversized canvas pans inside it (two-finger, m13) instead of
     overflowing. `safe center` centres a canvas that fits the box yet keeps the
     top-left reachable when it overflows; the `max(260px, …)` floor guarantees
     the unzoomed 256 canvas never needlessly scrolls. */
  .canvas-wrapper {
    display: grid;
    place-content: safe center;
    max-width: 100%;
    max-height: max(260px, calc(100svh - var(--pg-app-bar-h, 4rem) - 13rem));
    overflow: auto;
    overscroll-behavior: contain;
    -webkit-overflow-scrolling: touch;
  }

  .static-controls,
  .static-tools { position: relative; }
  .static-tools {
    width: 100%;
    display: flex;
    flex-direction: column;
    align-items: center;
    padding: var(--pg-space-2);
    margin-bottom: var(--pg-space-2);
  }
  .static-tools .panel-title { display: none; }
  .tool-controls { width: auto; justify-content: center; flex-wrap: wrap; margin-bottom: var(--pg-space-2); }
  #colorPicker,
  #frameTextColorPicker { margin: 0 auto 0.5rem; }
  .scrollable-tools { padding: var(--pg-space-2); }
  .scrollable-tools .slider-label { font-size: var(--pg-text-sm); margin: 0.1rem auto; }
  .image-tools-container,
  .frame-image-tools-container,
  .trace-tools-container,
  .zoom-tools-container,
  .rotation-tools-container,
  .text-tools-container { margin-top: var(--pg-space-2); padding: var(--pg-space-1); }

  /* Reveal the add/copy/delete trio that moved into the Frames tab and PIN it to
     the top so it stays usable while the frame grid scrolls under it. The
     --pg-surface background (matching the sheet) covers frames scrolling behind. */
  #sheetFrames .frame-controls {
    display: flex;
    width: auto;
    justify-content: center;
    gap: var(--pg-space-2);
    position: sticky;
    top: 0;
    z-index: 2;
    margin: 0 0 var(--pg-space-2);
    padding-block: var(--pg-space-2);
    background: var(--pg-surface);
  }
  .frame-controls-static { display: none; }

  /* The small preview canvas is retired (the MAIN canvas is the live preview) — keep
     it hidden even where m11 relocates the block into the Frames tab. Only the frame
     duration travels with the frames now; it centres via auto margins. */
  #sheetFrames .preview-canvas-wrapper { display: none; }

  /* Frames wrap into an aligned grid and scroll VERTICALLY inside the sheet (the
     .pg-sheet-active panel owns the bounded height + overflow-y). overflow-x is
     visible and the top/left padding give the .frame-number badge's -10px corner
     overhang room — the old overflow-x:auto scroller clipped both axes and cut
     the number off. */
  #frameList.frame-list {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(72px, 1fr));
    justify-items: center;
    align-content: start;
    overflow-x: visible;
    gap: var(--pg-space-4) var(--pg-space-3);
    padding: var(--pg-space-3) var(--pg-space-2) var(--pg-space-2) var(--pg-space-3);
  }
  #frameList.frame-list .frame { margin: 0; }

  /* --- Touch ergonomics: >= 44px targets, no iOS focus-zoom --- */
  .tool-button,
  .frame-button {
    min-width: var(--pg-touch-target);
    min-height: var(--pg-touch-target);
    font-size: 1.2rem;
  }
  /* (.pg-playbar-btn keeps its own circular media-control sizing.) */
  .color-swatch { width: 38px; height: 38px; }
  .field,
  #frameDuration,
  select,
  input[type='number'] {
    min-height: var(--pg-touch-target);
    font-size: 16px; /* >= 16px prevents iOS Safari zoom-on-focus */
  }
  input[type='range'] { width: 100%; }

  /* Effects panel: stack full-width instead of the cramped label-beside-control. */
  .pg-fx-row { flex-wrap: wrap; }
  .pg-fx-row .field,
  .pg-fx-row input[type='range'] { flex: 1 1 100%; max-width: 100%; }

  /* Toggles back to a comfortable size (the engine shrinks them to 24px). */
  .toggle-container { width: 120px; }
  .toggle-label { width: 120px; height: var(--pg-touch-target); }
  .toggle-label::before { width: 56px; height: calc(var(--pg-touch-target) - 8px); }
  #imagePosition:checked + .toggle-label::before,
  #includeOverlay:checked + .toggle-label::before,
  #frameImagePosition:checked + .toggle-label::before { transform: translateX(56px); }
  .toggle-text { font-size: var(--pg-text-xs); }
  .toggle-text.below, .toggle-text.off { left: 12px; }
  .toggle-text.above, .toggle-text.on { right: 12px; }

  /* The hover-only pixel coordinate readout is dead weight on touch. */
  .pg-coords { display: none; }
}

/* ------------------------------------------------------------
   Footer (S16) — version + provenance
   ------------------------------------------------------------ */
.pg-footer {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  align-items: center;
  gap: var(--pg-space-2);
  padding: var(--pg-space-8) var(--pg-space-4);
  font-family: var(--pg-font-mono);
  font-size: var(--pg-text-xs);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--pg-muted);
  text-align: center;
}
.pg-footer a {
  color: var(--pg-muted);
  text-decoration: none;
  border-bottom: 1px solid var(--pg-border);
  transition: color var(--pg-dur) var(--pg-ease), border-color var(--pg-dur) var(--pg-ease);
}
.pg-footer a:hover { color: var(--pg-accent); border-color: var(--pg-accent); }
.pg-footer a:focus-visible { outline: 2px solid var(--pg-focus); outline-offset: 2px; }
.pg-footer-ver { color: var(--pg-accent); }
.pg-footer a.pg-footer-feedback { color: var(--pg-accent-2); border-bottom-color: rgba(247, 37, 133, 0.5); }
.pg-footer a.pg-footer-feedback:hover { color: var(--pg-accent-2-hi); border-color: var(--pg-accent-2-hi); }
@media (max-width: 768px) {
  /* Clear the fixed bottom tab-bar + iOS safe area. */
  .pg-footer { padding-bottom: calc(76px + env(safe-area-inset-bottom)); }
}

/* ------------------------------------------------------------
   Phase C / C2 — mobile bottom-sheet shell (JS-enhanced: body.pg-shell,
   set by src/m6-mobile-sheets.ts only at <=768px). Progressive enhancement
   over the C1 @media column above; without JS that column is the fallback.
   ------------------------------------------------------------ */
.pg-tabbar { display: none; }
.pg-sheet-backdrop { display: none; }

body.pg-shell .pg-tabbar {
  display: flex;
  position: fixed;
  left: 0; right: 0; bottom: 0;
  z-index: var(--pg-z-tabbar);
  gap: var(--pg-space-1);
  padding: var(--pg-space-1) var(--pg-space-2);
  padding-bottom: max(var(--pg-space-1), env(safe-area-inset-bottom));
  background: var(--pg-surface);
  border-top: 1px solid var(--pg-border);
}
body.pg-shell .pg-tab {
  flex: 1 1 0;
  display: flex; flex-direction: column; align-items: center; gap: 2px;
  min-height: var(--pg-touch-target);
  padding: var(--pg-space-1);
  background: none;
  border: 1px solid transparent;
  border-radius: var(--pg-radius-sm);
  color: var(--pg-muted);
  font-family: var(--pg-font-ui);
  cursor: pointer;
}
body.pg-shell .pg-tab-ico { font-size: 1.2rem; line-height: 1; }
body.pg-shell .pg-tab-label { font-size: var(--pg-text-xs); }
body.pg-shell .pg-tab[aria-selected='true'] {
  color: var(--pg-accent-2);
  background: var(--pg-surface-2);
  border-color: var(--pg-border-hi);
}

/* The four sidebar groups are hidden until opened as a sheet. */
body.pg-shell .static-tools,
body.pg-shell .scrollable-tools,
body.pg-shell .static-controls,
body.pg-shell .scrollable-controls { display: none; }
body.pg-shell .sidebar-left,
body.pg-shell .sidebar-right {
  border: none;
  /* The sidebars carry a base z-index:10 and are flex items here — a flex item
     with a z-index makes a stacking context that would TRAP the fixed sheet's
     z-index below the body-level backdrop. Drop it so the sheet stacks at root. */
  z-index: auto;
}

/* The editor's glass .container has backdrop-filter:blur, which makes it a
   CONTAINING BLOCK for fixed descendants — that would anchor the fixed sheet +
   pinned canvas to .container instead of the viewport. Drop it in the shell so
   they position against the viewport. (Over the solid dark bg the blur is
   invisible anyway.) The GSAP entrance transform — even at its identity end state
   — would ALSO make these a containing block (and anchor the fixed playback dock
   to .main-content, which scrolls), so clear it on mobile for the whole shell, not
   just on sheet-open as m6 did. !important beats GSAP's inline transform; the
   opacity fade still plays. */
body.pg-shell .container,
body.pg-shell .main-content {
  transform: none !important;
}
body.pg-shell .container {
  backdrop-filter: none;
  -webkit-backdrop-filter: none;
}

/* Leave room for the fixed tab-bar below the canvas (incl. iOS home-indicator
   inset, live now that the viewport meta sets viewport-fit=cover). */
body.pg-shell .main-content {
  /* Clear the bottom dock (tab-bar + persistent playback bar) so in-flow content
     (the canvas + below) isn't hidden behind it when no sheet is open. */
  padding-bottom: calc(var(--pg-tabbar-h) + var(--pg-playbar-h) + var(--pg-space-4));
  /* Desktop gives .main-content z-index:0 — a stacking context that would TRAP
     the pinned canvas's z-index below the body-level sheet backdrop (same trap
     as the sidebars above). Drop it so the pin stacks at root. */
  z-index: auto;
}

/* Active group slides up above the tab-bar as a bottom sheet. */
body.pg-shell .pg-sheet-active {
  display: block;
  position: fixed;
  left: 0; right: 0;
  /* Anchored top AND bottom → a fixed lower-half panel whose height never
     depends on content (max-height alone let tall groups escape to the top).
     The canvas pins to the top above it; tall groups scroll WITHIN the sheet. */
  top: 50vh;
  bottom: calc(var(--pg-tabbar-h) + var(--pg-playbar-h)); /* clear the tab-bar + the persistent playback dock */
  z-index: var(--pg-z-sheet);
  overflow-y: auto;
  /* Keep the scroll INSIDE the sheet: don't chain to the page behind it (the
     "grabbing the background" when you scroll/overscroll the controls). */
  overscroll-behavior: contain;
  -webkit-overflow-scrolling: touch;
  /* A visible scrollbar on the side so you can scroll cleanly without dragging on
     the sliders. scrollbar-gutter reserves its lane so it never overlaps a control. */
  scrollbar-width: thin; /* Firefox */
  scrollbar-color: var(--pg-accent) transparent;
  scrollbar-gutter: stable;
  margin: 0;
  padding: var(--pg-space-6) var(--pg-space-4) var(--pg-space-6);
  background: var(--pg-surface);
  border-top: 1px solid var(--pg-border-hi);
  border-radius: var(--pg-radius-lg) var(--pg-radius-lg) 0 0;
  box-shadow: var(--pg-shadow-lg);
  animation: pg-sheet-up var(--pg-dur) var(--pg-ease);
}
/* Grabbable cyan scrollbar (Chromium/Android; iOS keeps its overlay bar). Wider
   than the desktop sidebars so it's easy to drag with a thumb; the thumb is inset
   via a transparent border so the touch target stays generous. */
body.pg-shell .pg-sheet-active::-webkit-scrollbar { width: 10px; }
body.pg-shell .pg-sheet-active::-webkit-scrollbar-track {
  background: color-mix(in srgb, var(--pg-bg) 55%, transparent);
  border-radius: 5px;
}
body.pg-shell .pg-sheet-active::-webkit-scrollbar-thumb {
  background: var(--pg-accent);
  border-radius: 6px;
  border: 2px solid transparent;
  background-clip: padding-box;
}
body.pg-shell .pg-sheet-active::-webkit-scrollbar-thumb:active { background: var(--pg-accent-hi); }
/* Grabber handle — signals a dismissible bottom sheet. */
body.pg-shell .pg-sheet-active::before {
  content: '';
  position: absolute;
  top: var(--pg-space-2);
  left: 50%;
  transform: translateX(-50%);
  width: 40px;
  height: 4px;
  border-radius: var(--pg-radius-full);
  background: var(--pg-border-hi);
}
@keyframes pg-sheet-up { from { transform: translateY(100%); } to { transform: translateY(0); } }

/* While a sheet is open, pin the canvas to the top — ABOVE the backdrop (so it
   stays bright) and above the sheet (so it stays drawable even where they
   overlap on short/landscape viewports) — so edits are visible live.
   translateX only (never scale) keeps the engine's tap→pixel mapping correct.
   !important on the transform: the engine runs gsap.fromTo('#canvasWrapper',
   {scale}) juice on frame add/select/navigate; run while the sheet is closed it
   leaves an inline identity-matrix transform (no translate) that would override
   this centering and shove the pinned canvas off-screen to the right. Author
   !important beats GSAP's inline (non-important) transform, restoring centering
   AND keeping the pinned canvas unscaled. */
body.pg-shell.pg-sheet-open .canvas-wrapper,
body.pg-shell.pg-layers-open .canvas-wrapper {
  position: fixed;
  top: calc(var(--pg-app-bar-h, 4rem) + var(--pg-space-2)); /* clear the real app bar (m6 measures it; navbar wraps taller on narrow mobile) + a small gap */
  /* Full-width bounded box between the app bar and the sheet top (50vh): a zoomed
     canvas pans INSIDE it (m13) and can never cover the sheet, which the old
     content-sized wrapper did once it grew to 1280px. The canvas centres via the
     grid above; transform:none beats GSAP's inline entrance transform (no shove). */
  left: var(--pg-space-2);
  right: var(--pg-space-2);
  max-height: calc(50vh - var(--pg-app-bar-h, 4rem) - var(--pg-space-4));
  overflow: auto;
  -webkit-overflow-scrolling: touch;
  transform: none !important;
  z-index: var(--pg-z-canvas-pin);
  margin: 0;
}

body.pg-shell.pg-sheet-open .pg-sheet-backdrop {
  display: block;
  position: fixed;
  /* Start BELOW the pinned canvas so the canvas stays bright AND interactive
     (you can draw with a sheet open); the scrim covers only the gap + behind
     the sheet, and catches outside-taps to dismiss. */
  top: 40vh;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: var(--pg-z-scrim);
  background: color-mix(in srgb, var(--pg-bg) 40%, transparent);
}

/* ============================================================
   Donate (☕ header button + modal — src/m9-donate.ts)
   ============================================================ */
.pg-donate-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 34px;
  height: 34px;
  padding: 0;
  background: none;
  border: 1px solid transparent;
  border-radius: var(--pg-radius-sm);
  font-size: var(--pg-text-base);
  line-height: 1;
  cursor: pointer;
  filter: grayscale(1) opacity(0.65);
  transition: filter var(--pg-dur) var(--pg-ease), border-color var(--pg-dur) var(--pg-ease),
    transform var(--pg-dur) var(--pg-ease);
}
.pg-donate-btn:hover {
  filter: none;
  border-color: var(--pg-accent-2);
  transform: translateY(-2px);
}

.pg-donate-backdrop {
  position: fixed;
  inset: 0;
  z-index: var(--pg-z-modal);
  background: color-mix(in srgb, var(--pg-bg) 65%, transparent);
}
.pg-donate-modal {
  position: fixed;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  z-index: var(--pg-z-modal);
  width: min(92vw, 340px);
  max-height: 90vh;
  overflow-y: auto;
  padding: var(--pg-space-6);
  background: var(--pg-surface);
  border: 1px solid var(--pg-border-hi);
  border-radius: var(--pg-radius-lg);
  box-shadow: var(--pg-shadow-lg);
  text-align: center;
}
.pg-donate-eyebrow {
  margin: 0 0 var(--pg-space-2);
  font-family: var(--pg-font-mono);
  font-size: var(--pg-text-xs);
  letter-spacing: var(--pg-tracking-label);
  text-transform: uppercase;
  color: var(--pg-muted);
}
.pg-donate-title {
  margin: 0 0 var(--pg-space-2);
  font-size: var(--pg-text-xl);
  font-weight: var(--pg-weight-display);
  color: var(--pg-text);
}
.pg-donate-sub {
  margin: 0 0 var(--pg-space-4);
  font-size: var(--pg-text-sm);
  color: var(--pg-muted);
}
.pg-donate-tabs {
  display: inline-flex;
  gap: var(--pg-space-1);
  margin: 0 auto var(--pg-space-4);
  padding: var(--pg-space-1);
  background: var(--pg-bg-1);
  border: 1px solid var(--pg-border);
  border-radius: var(--pg-radius-full);
}
.pg-donate-tab {
  min-height: var(--pg-touch-target);
  padding: 0 var(--pg-space-6);
  font-family: var(--pg-font-mono);
  font-size: var(--pg-text-xs);
  font-weight: var(--pg-weight-medium);
  letter-spacing: var(--pg-tracking-label);
  color: var(--pg-muted);
  background: none;
  border: none;
  border-radius: var(--pg-radius-full);
  cursor: pointer;
  transition: background var(--pg-dur) var(--pg-ease), color var(--pg-dur) var(--pg-ease);
}
.pg-donate-tab:hover { color: var(--pg-text); }
.pg-donate-tab.is-active {
  /* magenta = active / selected, per palette */
  color: var(--pg-on-accent);
  background: var(--pg-accent-2);
}
.pg-donate-panel[hidden] { display: none; }
.pg-donate-qr {
  display: block;
  margin: 0 auto var(--pg-space-3);
  border-radius: var(--pg-radius-sm);
  /* the SVG bakes its own white quiet zone — no border needed */
}
.pg-donate-net {
  margin: 0 0 var(--pg-space-2);
  font-family: var(--pg-font-mono);
  font-size: var(--pg-text-xs);
  letter-spacing: var(--pg-tracking-label);
  text-transform: uppercase;
  color: var(--pg-status); /* teal: status-grade info */
}
.pg-donate-addr {
  display: block;
  margin: 0 0 var(--pg-space-4);
  padding: var(--pg-space-2);
  font-family: var(--pg-font-mono);
  font-size: var(--pg-text-xs);
  word-break: break-all;
  color: var(--pg-text);
  background: var(--pg-bg-1);
  border: 1px solid var(--pg-border);
  border-radius: var(--pg-radius-sm);
  user-select: all;
}
.pg-donate-actions {
  display: flex;
  gap: var(--pg-space-2);
  justify-content: center;
}
.pg-donate-copy,
.pg-donate-close {
  min-height: var(--pg-touch-target);
  padding: var(--pg-space-2) var(--pg-space-4);
  font-family: var(--pg-font-ui);
  font-size: var(--pg-text-sm);
  font-weight: var(--pg-weight-medium);
  border-radius: var(--pg-radius-full);
  cursor: pointer;
  transition: background var(--pg-dur) var(--pg-ease), border-color var(--pg-dur) var(--pg-ease);
}
.pg-donate-copy {
  color: var(--pg-on-accent);
  background: var(--pg-accent);
  border: 1px solid transparent;
}
.pg-donate-copy:hover { background: var(--pg-accent-hi); }
.pg-donate-copy.pg-copied {
  color: var(--pg-on-accent);
  background: var(--pg-status);
}
.pg-donate-close {
  color: var(--pg-muted);
  background: none;
  border: 1px solid var(--pg-border);
}
.pg-donate-close:hover { border-color: var(--pg-accent-2); color: var(--pg-text); }

/* === Doginal Dog loader (src/m18-dog-library.ts) — mirrors the donate modal === */
.pg-dog-backdrop {
  position: fixed;
  inset: 0;
  z-index: var(--pg-z-modal);
  background: color-mix(in srgb, var(--pg-bg) 65%, transparent);
}
.pg-dog-modal {
  position: fixed;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  z-index: var(--pg-z-modal);
  width: min(94vw, 380px);
  max-height: 92vh;
  overflow-y: auto;
  padding: var(--pg-space-6);
  background: var(--pg-surface);
  border: 1px solid var(--pg-border-hi);
  border-radius: var(--pg-radius-lg);
  box-shadow: var(--pg-shadow-lg);
  text-align: center;
}
.pg-dog-eyebrow {
  margin: 0 0 var(--pg-space-2);
  font-family: var(--pg-font-mono);
  font-size: var(--pg-text-xs);
  letter-spacing: var(--pg-tracking-label);
  text-transform: uppercase;
  color: var(--pg-muted);
}
.pg-dog-title {
  margin: 0 0 var(--pg-space-2);
  font-size: var(--pg-text-xl);
  font-weight: var(--pg-weight-display);
  color: var(--pg-text);
}
.pg-dog-sub {
  margin: 0 0 var(--pg-space-4);
  font-size: var(--pg-text-sm);
  color: var(--pg-muted);
}
.pg-dog-row {
  display: flex;
  gap: var(--pg-space-4);
  align-items: center;
  text-align: left;
  margin: 0 0 var(--pg-space-3);
}
.pg-dog-row[hidden] { display: none; } /* class display:flex would otherwise beat [hidden] */
.pg-dog-preview {
  flex: 0 0 auto;
  width: 100px;
  height: 100px;
  border-radius: var(--pg-radius-sm);
  border: 1px solid var(--pg-border);
  image-rendering: pixelated;
  /* checkerboard shows through a transparent (background-removed) dog */
  background: repeating-conic-gradient(var(--pg-bg-1) 0% 25%, var(--pg-surface) 0% 50%) 0 / 16px 16px;
}
.pg-dog-fields { flex: 1 1 auto; min-width: 0; }
.pg-dog-label {
  display: block;
  margin: 0 0 var(--pg-space-1);
  font-size: var(--pg-text-xs);
  color: var(--pg-muted);
}
.pg-dog-numrow { display: flex; gap: var(--pg-space-2); margin: 0 0 var(--pg-space-3); }
.pg-dog-num { flex: 1 1 auto; min-width: 0; }
.pg-dog-random {
  flex: 0 0 auto;
  width: var(--pg-touch-target);
  min-height: var(--pg-touch-target);
  font-size: var(--pg-text-base);
  background: var(--pg-bg-1);
  border: 1px solid var(--pg-border);
  border-radius: var(--pg-radius-md);
  cursor: pointer;
  transition: border-color var(--pg-dur) var(--pg-ease);
}
.pg-dog-random:hover { border-color: var(--pg-accent-2); }
.pg-dog-bg {
  display: flex;
  gap: var(--pg-space-1);
  padding: var(--pg-space-1);
  background: var(--pg-bg-1);
  border: 1px solid var(--pg-border);
  border-radius: var(--pg-radius-full);
}
.pg-dog-bgopt {
  flex: 1 1 0;
  min-height: var(--pg-touch-target);
  font-family: var(--pg-font-ui);
  font-size: var(--pg-text-xs);
  font-weight: var(--pg-weight-medium);
  color: var(--pg-muted);
  background: none;
  border: none;
  border-radius: var(--pg-radius-full);
  cursor: pointer;
  transition: background var(--pg-dur) var(--pg-ease), color var(--pg-dur) var(--pg-ease);
}
.pg-dog-bgopt:hover { color: var(--pg-text); }
.pg-dog-bgopt.is-active { color: var(--pg-on-accent); background: var(--pg-accent-2); }

/* Dog dialog — source tabs (By number / Starter Dogs) */
.pg-dog-tabs {
  display: flex;
  gap: var(--pg-space-1);
  margin: 0 0 var(--pg-space-4);
  padding: var(--pg-space-1);
  background: var(--pg-bg-1);
  border: 1px solid var(--pg-border);
  border-radius: var(--pg-radius-full);
}
.pg-dog-tab {
  flex: 1 1 0;
  min-height: var(--pg-touch-target);
  font-family: var(--pg-font-ui);
  font-size: var(--pg-text-sm);
  font-weight: var(--pg-weight-medium);
  color: var(--pg-muted);
  background: none;
  border: none;
  border-radius: var(--pg-radius-full);
  cursor: pointer;
  transition: background var(--pg-dur) var(--pg-ease), color var(--pg-dur) var(--pg-ease);
}
.pg-dog-tab:hover { color: var(--pg-text); }
.pg-dog-tab.is-active { color: var(--pg-on-accent); background: var(--pg-accent-2); }

/* Starter Dogs — colour swatches + style thumbnails */
.pg-dog-colors { display: flex; flex-wrap: wrap; gap: var(--pg-space-2); }
.pg-dog-swatch {
  width: 28px;
  height: 28px;
  border-radius: var(--pg-radius-full);
  border: 2px solid transparent;
  box-shadow: 0 0 0 1px var(--pg-border);
  cursor: pointer;
  padding: 0;
}
.pg-dog-swatch:hover { box-shadow: 0 0 0 1px var(--pg-accent-2); }
.pg-dog-swatch.is-active { border-color: var(--pg-accent-2); }
.pg-dog-styles {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(60px, 1fr));
  gap: var(--pg-space-2);
  margin: 0 0 var(--pg-space-3);
  max-height: 184px;
  overflow-y: auto;
}
.pg-dog-styles[hidden] { display: none; } /* class display:grid would otherwise beat [hidden] */
.pg-dog-thumb {
  aspect-ratio: 1 / 1;
  border-radius: var(--pg-radius-sm);
  border: 1px solid var(--pg-border);
  background: var(--pg-bg-1);
  cursor: pointer;
  overflow: hidden;
  padding: 0;
}
.pg-dog-thumb img { width: 100%; height: 100%; object-fit: cover; image-rendering: pixelated; display: block; }
.pg-dog-thumb canvas { width: 100%; height: 100%; image-rendering: pixelated; display: block; }
.pg-bg-grid[hidden] { display: none; } /* class display:grid would otherwise beat [hidden] */
.pg-bg-photo img { image-rendering: auto; } /* photographic bg thumbs render smooth, not pixelated */
/* Let the backgrounds grid grow so the modal (max-height 92vh, overflow auto) is the
   SINGLE scroller — every background is reachable on mobile + desktop without a
   nested grid/modal scroll fight. (S34, with image backgrounds the list got long.) */
#pgContentModal .pg-bg-grid { max-height: none; }
.pg-dog-thumb.is-active { border-color: var(--pg-accent-2); box-shadow: 0 0 0 1px var(--pg-accent-2); }
.pg-dog-hint {
  margin: 0 0 var(--pg-space-4);
  font-size: var(--pg-text-xs);
  color: var(--pg-muted);
  min-height: 1.2em;
}
.pg-dog-hint.is-error { color: var(--pg-accent-2); }
.pg-dog-actions { display: flex; gap: var(--pg-space-2); justify-content: center; }
.pg-dog-load,
.pg-dog-close {
  min-height: var(--pg-touch-target);
  padding: var(--pg-space-2) var(--pg-space-5);
  font-family: var(--pg-font-ui);
  font-size: var(--pg-text-sm);
  font-weight: var(--pg-weight-medium);
  border-radius: var(--pg-radius-full);
  cursor: pointer;
  transition: background var(--pg-dur) var(--pg-ease), border-color var(--pg-dur) var(--pg-ease);
}
.pg-dog-load {
  color: var(--pg-on-accent);
  background: var(--pg-accent);
  border: 1px solid transparent;
}
.pg-dog-load:hover { background: var(--pg-accent-hi); }
.pg-dog-load:disabled { opacity: 0.5; cursor: default; }
.pg-dog-close {
  color: var(--pg-muted);
  background: none;
  border: 1px solid var(--pg-border);
}
.pg-dog-close:hover { border-color: var(--pg-accent-2); color: var(--pg-text); }

/* Content library — Palettes tab (named hex sets → engine colour tray) */
.pg-pal-list {
  display: flex;
  flex-direction: column;
  gap: var(--pg-space-3);
  margin: 0 0 var(--pg-space-3);
  max-height: 184px;
  overflow-y: auto;
}
.pg-pal-row { display: flex; flex-direction: column; gap: var(--pg-space-2); }
.pg-pal-head { display: flex; align-items: center; justify-content: space-between; gap: var(--pg-space-2); }
.pg-pal-name {
  font-family: var(--pg-font-ui);
  font-size: var(--pg-text-sm);
  font-weight: var(--pg-weight-medium);
  color: var(--pg-text);
}
.pg-pal-use {
  padding: var(--pg-space-1) var(--pg-space-3);
  font-family: var(--pg-font-ui);
  font-size: var(--pg-text-xs);
  font-weight: var(--pg-weight-medium);
  color: var(--pg-muted);
  background: none;
  border: 1px solid var(--pg-border);
  border-radius: var(--pg-radius-full);
  cursor: pointer;
  transition: color var(--pg-dur) var(--pg-ease), border-color var(--pg-dur) var(--pg-ease);
}
.pg-pal-use:hover { color: var(--pg-text); border-color: var(--pg-accent-2); }
.pg-pal-swatches { display: flex; flex-wrap: wrap; gap: var(--pg-space-2); }
.pg-pal-swatch {
  width: 28px;
  height: 28px;
  padding: 0;
  border: 1px solid var(--pg-border);
  border-radius: var(--pg-radius-sm);
  cursor: pointer;
  transition: transform var(--pg-dur) var(--pg-ease), border-color var(--pg-dur) var(--pg-ease);
}
.pg-pal-swatch:hover { transform: scale(1.12); border-color: var(--pg-accent); }
.pg-pal-swatch:focus-visible { outline: 2px solid var(--pg-focus); outline-offset: 2px; }

/* Content library — Captions tab (one-tap text presets) */
.pg-cap-pos { display: flex; gap: var(--pg-space-2); margin: 0 0 var(--pg-space-3); }
.pg-cap-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(84px, 1fr));
  gap: var(--pg-space-2);
  margin: 0 0 var(--pg-space-3);
}
.pg-cap-btn {
  min-height: var(--pg-touch-target);
  padding: var(--pg-space-2) var(--pg-space-3);
  font-family: var(--pg-font-ui);
  font-size: var(--pg-text-sm);
  font-weight: var(--pg-weight-medium);
  color: var(--pg-text);
  background: var(--pg-bg-1);
  border: 1px solid var(--pg-border);
  border-radius: var(--pg-radius-sm);
  cursor: pointer;
  transition: border-color var(--pg-dur) var(--pg-ease), color var(--pg-dur) var(--pg-ease);
}
.pg-cap-btn:hover { border-color: var(--pg-accent-2); color: var(--pg-accent-2); }
/* Dog dialog — community / "join the pack" footer */
.pg-dog-pack {
  display: flex;
  align-items: center;
  gap: var(--pg-space-3);
  justify-content: center;
  margin: var(--pg-space-5) 0 0;
  padding: var(--pg-space-3) 0 0;
  border-top: 1px solid var(--pg-border);
}
.pg-dog-packlogo { display: inline-flex; flex: 0 0 auto; }
.pg-dog-packlogo img { display: block; height: 38px; width: auto; opacity: 0.95; }
.pg-dog-packlogo:hover img { opacity: 1; }
.pg-dog-packlinks { display: flex; flex-direction: column; gap: 2px; text-align: left; }
.pg-dog-packtag {
  font-family: var(--pg-font-mono);
  font-size: var(--pg-text-xs);
  letter-spacing: var(--pg-tracking-label);
  text-transform: uppercase;
  color: var(--pg-muted);
}
.pg-dog-packrow { font-size: var(--pg-text-sm); color: var(--pg-muted); }
.pg-dog-packrow a { color: var(--pg-accent); }
.pg-dog-packrow a:hover { color: var(--pg-accent-hi); }

/* Navbar — "Join the pack" community link (mirrors Swerve's pack CTA) */
.pg-pack {
  display: inline-flex;
  align-items: center;
  gap: var(--pg-space-2);
  min-height: var(--pg-touch-target);
  padding: 0 var(--pg-space-3);
  font-family: var(--pg-font-ui);
  font-size: var(--pg-text-sm);
  font-weight: var(--pg-weight-medium);
  color: var(--pg-text);
  text-decoration: none;
  background: var(--pg-bg-1);
  border: 1px solid var(--pg-border);
  border-radius: var(--pg-radius-full);
  transition: border-color var(--pg-dur) var(--pg-ease), transform var(--pg-dur) var(--pg-ease);
}
.pg-pack:hover { border-color: var(--pg-accent-2); transform: translateY(-1px); }
.pg-pack-arr { color: var(--pg-accent); }


/* On touch (no hover), don't let decorative :hover transforms stick after a tap. */
@media (hover: none) {
  .tool-button:hover,
  .frame-button:hover,
  .pg-import-btn:hover,
  .color-swatch:hover { transform: none; }
}

/* ============================================================
   Reduced motion — kill decorative animation & transforms
   ============================================================ */
@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation-duration: 0.001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.001ms !important;
    scroll-behavior: auto !important;
  }
  .tool-button:hover,
  .frame-button:hover,
  .frame:hover,
  .pg-cta:hover,
  .pg-import-btn:hover,
  #exportBtn:hover,
  #saveColorBtn:hover,
  #copyPrevTextBtn:hover,
  #resetProjectBtn:hover,
  #removeTextBtn:hover { transform: none; }
}

/* === M23 — per-frame Layers inspector ===================================== */
/* Per-frame Frame image + Frame text controls live in the inspector now; they
   remain in #sheetAdjust only as the engine's binding home — hidden there, shown
   when the inspector borrows them into a layer row. */
#sheetAdjust .frame-image-tools-container,
#sheetAdjust .text-tools-container { display: none; }
.tool-group-hint {
  margin: 0 0 var(--pg-space-2);
  font-size: var(--pg-text-xs);
  color: var(--pg-dim);
  line-height: 1.4;
}

/* Trigger badge on each frame thumbnail (frame container is position:relative). */
.pg-frame-layers-btn {
  position: absolute;
  top: 2px;
  right: 2px;
  z-index: 2;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 22px;
  height: 22px;
  padding: 0;
  border: 1px solid var(--pg-border);
  border-radius: var(--pg-radius-sm);
  background: color-mix(in srgb, var(--pg-bg-1) 78%, transparent);
  color: var(--pg-accent);
  cursor: pointer;
  opacity: 0.75;
  transition: opacity var(--pg-dur) var(--pg-ease), border-color var(--pg-dur) var(--pg-ease);
}
.pg-frame-layers-btn svg { width: 14px; height: 14px; fill: currentColor; }
.pg-frame-layers-btn:hover,
.pg-frame-layers-btn:focus-visible {
  opacity: 1;
  border-color: var(--pg-accent-2);
  outline: none;
}
/* Bigger tap target on touch devices. */
@media (hover: none) {
  .pg-frame-layers-btn { width: 26px; height: 26px; opacity: 0.9; }
  .pg-frame-layers-btn svg { width: 16px; height: 16px; }
}

/* Panel — a NON-covering dock so the canvas stays visible + live while editing.
   Desktop: docked to the right edge (centre canvas + left tools stay visible).
   Mobile (below): a bottom sheet with the canvas pinned to the top. */
.pg-layers-backdrop { display: none; } /* desktop: no scrim — canvas stays interactive */
.pg-layers-panel {
  position: fixed;
  top: calc(var(--pg-app-bar-h, 4rem) + var(--pg-space-2));
  right: var(--pg-space-2);
  bottom: var(--pg-space-2);
  width: min(92vw, 340px);
  overflow-y: auto;
  padding: 0 var(--pg-space-6) var(--pg-space-6);
  background: var(--pg-surface);
  border: 1px solid var(--pg-border-hi);
  border-radius: var(--pg-radius-lg);
  box-shadow: var(--pg-shadow-lg);
  z-index: var(--pg-z-modal);
  animation: pg-layers-in var(--pg-dur) var(--pg-ease);
}
.pg-layers-panel[hidden] { display: none; }
@keyframes pg-layers-in { from { opacity: 0; transform: translateX(8px); } to { opacity: 1; transform: none; } }
/* Transform-free entrance for the mobile sheet: no translate residual can push the
   panel off-screen if the animation doesn't re-fire on a [hidden] toggle. */
@keyframes pg-layers-fade { from { opacity: 0; } to { opacity: 1; } }
/* Per-layer animation picker (S43) — compact select in a layer row's action strip. */
.pg-layer-fx {
  background: var(--pg-bg-1);
  color: var(--pg-text);
  border: 1px solid var(--pg-border);
  border-radius: var(--pg-radius-sm);
  padding: var(--pg-space-1) var(--pg-space-2);
  font-size: var(--pg-text-xs);
  font-family: var(--pg-font-ui);
  min-height: 32px;
  cursor: pointer;
}
.pg-layer-fx:focus-visible { outline: 2px solid var(--pg-focus); outline-offset: 1px; }
/* Sticky header so Close stays reachable when the borrowed controls make the panel scroll. */
.pg-layers-head {
  position: sticky;
  top: 0;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--pg-space-3);
  margin: 0 0 var(--pg-space-4);
  padding: var(--pg-space-4) 0 var(--pg-space-3);
  background: var(--pg-surface);
  z-index: 1;
}
.pg-layers-title {
  margin: 0;
  font-size: var(--pg-text-lg);
  font-weight: var(--pg-weight-display);
  color: var(--pg-text);
}
.pg-layers-close {
  flex: 0 0 auto;
  width: 2rem;
  height: 2rem;
  font-size: var(--pg-text-base);
  line-height: 1;
  background: var(--pg-bg-1);
  color: var(--pg-muted);
  border: 1px solid var(--pg-border);
  border-radius: var(--pg-radius-sm);
  cursor: pointer;
  transition: border-color var(--pg-dur) var(--pg-ease), color var(--pg-dur) var(--pg-ease);
}
.pg-layers-close:hover { border-color: var(--pg-accent-2); color: var(--pg-text); }
.pg-layers-list { display: flex; flex-direction: column; gap: var(--pg-space-2); }

.pg-layer-row {
  display: flex;
  flex-wrap: wrap; /* action buttons drop to their own line instead of overflowing the card */
  align-items: center;
  gap: var(--pg-space-2) var(--pg-space-3);
  padding: var(--pg-space-3);
  background: var(--pg-bg-1);
  border: 1px solid var(--pg-border);
  border-radius: var(--pg-radius-md);
}
.pg-layer-row.is-empty { opacity: 0.78; }
.pg-layer-row.is-active-layer {
  border-color: var(--pg-accent-2);
  box-shadow: inset 0 0 0 1px var(--pg-accent-2);
}
.pg-layer-row.is-hidden-layer { opacity: 0.55; }
.pg-layer-row.is-hidden-layer .pg-layer-thumb,
.pg-layer-row.is-hidden-layer .pg-layer-ico { filter: grayscale(1); }
.pg-layer-ico,
.pg-layer-thumb {
  flex: 0 0 auto;
  width: 36px;
  height: 36px;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 1.1rem;
  border-radius: var(--pg-radius-sm);
}
.pg-layer-thumb {
  object-fit: cover;
  image-rendering: pixelated;
  border: 1px solid var(--pg-border);
  background: repeating-conic-gradient(var(--pg-bg-1) 0% 25%, var(--pg-surface) 0% 50%) 0 / 12px 12px;
}
.pg-layer-meta { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.pg-layer-name { font-size: var(--pg-text-sm); font-weight: var(--pg-weight-medium); color: var(--pg-text); white-space: nowrap; }
.pg-layer-state {
  font-size: var(--pg-text-xs);
  color: var(--pg-muted);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
/* Actions span the full row width on their own line below the name, and wrap among
   themselves — so 5 buttons (eye/edit/↑/↓/remove) never overflow the card. */
.pg-layer-actions {
  flex: 1 0 100%;
  display: flex;
  flex-wrap: wrap;
  gap: var(--pg-space-2);
  justify-content: flex-start;
}
.pg-layer-btn {
  min-height: 2rem;
  padding: 0 var(--pg-space-3);
  font-size: var(--pg-text-xs);
  font-weight: var(--pg-weight-medium);
  border-radius: var(--pg-radius-sm);
  border: 1px solid var(--pg-border);
  background: var(--pg-surface-2);
  color: var(--pg-text);
  cursor: pointer;
  transition: border-color var(--pg-dur) var(--pg-ease), background var(--pg-dur) var(--pg-ease);
}
.pg-layer-btn:hover { border-color: var(--pg-accent); }
.pg-layer-btn.is-remove { color: var(--pg-danger); }
.pg-layer-btn.is-remove:hover { border-color: var(--pg-danger); }
.pg-layer-btn.is-ghost { background: transparent; color: var(--pg-muted); }
.pg-layer-btn.is-icon { min-width: 2rem; padding: 0 var(--pg-space-2); font-weight: var(--pg-weight-bold); }
.pg-layer-btn.is-add {
  background: var(--pg-accent);
  color: var(--pg-on-accent);
  border-color: transparent;
  font-weight: var(--pg-weight-bold);
}
.pg-layer-btn.is-add:hover { background: var(--pg-accent-hi); border-color: transparent; }
.pg-layers-footer {
  display: flex;
  flex-wrap: wrap;
  gap: var(--pg-space-2);
  margin-top: var(--pg-space-3);
  padding-top: var(--pg-space-3);
  border-top: 1px solid var(--pg-border);
}

/* Inline expand area that hosts a reparented engine control group. */
.pg-layer-edit {
  margin: calc(var(--pg-space-2) * -1) 0 0;
  padding: var(--pg-space-3);
  background: var(--pg-bg-1);
  border: 1px solid var(--pg-border);
  border-top: none;
  border-radius: 0 0 var(--pg-radius-md) var(--pg-radius-md);
}
.pg-layer-edit[hidden] { display: none; }
/* Borrowed groups: normalize spacing so the sidebar/sheet layout doesn't leak in. */
.pg-layer-edit .frame-image-tools-container,
.pg-layer-edit .text-tools-container { margin: 0; padding: 0; border: none; background: none; }
/* The layer's Animate picker at the top of its Edit drawer. */
.pg-layer-edit-anim {
  display: flex;
  align-items: center;
  gap: var(--pg-space-2);
  margin: 0 0 var(--pg-space-3);
  padding: 0 0 var(--pg-space-2);
  border-bottom: 1px solid var(--pg-border);
}
.pg-layer-edit-anim label {
  font-size: var(--pg-text-xs);
  color: var(--pg-dim);
  text-transform: uppercase;
  letter-spacing: var(--pg-tracking-label);
  font-family: var(--pg-font-mono);
}
.pg-layer-edit-anim .pg-layer-fx { flex: 1; min-height: var(--pg-touch-target); }

.pg-layers-note {
  margin: var(--pg-space-4) 0 0;
  font-size: var(--pg-text-xs);
  color: var(--pg-dim);
  text-align: center;
}

/* Mobile: bottom sheet + canvas pinned to the top (the existing m6 pin, extended
   to body.pg-layers-open below). Mirrors .pg-sheet-active geometry; sits below the
   canvas-pin so the pinned canvas stays bright + drawable. */
@media (max-width: 768px) {
  .pg-layers-panel {
    top: 50vh;
    left: 0;
    right: 0;
    bottom: calc(var(--pg-tabbar-h) + var(--pg-playbar-h));
    width: auto;
    border: none;
    border-top: 1px solid var(--pg-border-hi);
    border-radius: var(--pg-radius-lg) var(--pg-radius-lg) 0 0;
    padding: 0 var(--pg-space-4) var(--pg-space-6);
    z-index: var(--pg-z-sheet);
    overscroll-behavior: contain;
    /* No slide-up transform here: the panel is shown by toggling [hidden] (not a
       class), which doesn't re-fire a CSS animation, so pg-sheet-up stranded the
       panel at translateY(100%) — off the bottom of the screen with its controls
       unreachable. A transform-free opacity fade can't strand it. */
    animation: pg-layers-fade var(--pg-dur) var(--pg-ease);
  }
  /* Lower scrim only (canvas pinned above stays visible); tap to close. */
  .pg-layers-backdrop:not([hidden]) {
    display: block;
    position: fixed;
    top: 40vh;
    left: 0;
    right: 0;
    bottom: 0;
    z-index: var(--pg-z-scrim);
    background: color-mix(in srgb, var(--pg-bg) 40%, transparent);
  }
}

@media (prefers-reduced-motion: reduce) {
  .pg-frame-layers-btn { transition: none; }
  .pg-layers-panel { animation: none; }
}

/* ── Doginal Dogs Create suite overrides (keep when refreshing this port) ──
   Hide the roadmap teaser models in the AI model selector until more provider
   keys are configured (the optgroup only ever contains not-yet-live models,
   so this unhides itself model by model as keys are added), and hide the
   wallet pill while it is in its "Credits · coming soon" disabled state
   (the is-soon class is removed the day credits go live, so it comes back). */
optgroup[label="Coming soon"] { display: none; }
.pg-wallet-btn.is-soon { display: none; }

/* ── DD gif panel redesign (branch gif-panels-redesign, 2026-07-13) ──────────
   Part of the suite overrides: keep this whole section (plus the index.html
   dock restructure and /gif/dd-panels.js) when refreshing the port from the
   PixelGif repo. Applies the DD mockup v2 design grammar to the two docks:
   spray-dot titles and group labels, unified group cards, slim sliders,
   gradient Save GIF in a sticky export card, single frame trio. */

:root { --dd-grad: linear-gradient(100deg, #4cc9f0 0%, #e8452c 50%, #8b5cf6 100%); }

/* Panel titles — mockup .ptitle: gradient square + glow, brighter text. */
.panel-title {
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: var(--pg-text-xs);
  letter-spacing: 0.18em;
  color: var(--pg-text);
}
.panel-title::before {
  content: '';
  flex: none;
  width: 9px;
  height: 9px;
  border-radius: 3px;
  background: var(--dd-grad);
  box-shadow: 0 0 10px -1px var(--pg-accent);
}

/* Group labels — mockup .plabel: mono micro caps with an accent spray dot. */
.dd-plabel,
.panel-subtitle {
  display: flex;
  align-items: center;
  gap: 6px;
  margin: 0 0 0.5rem;
  font-family: var(--pg-font-mono);
  font-size: 10px;
  font-weight: var(--pg-weight-bold);
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--pg-dim);
  text-align: left;
}
.dd-plabel::before,
.panel-subtitle::before {
  content: '';
  flex: none;
  width: 5px;
  height: 5px;
  border-radius: 50%;
  background: var(--pg-accent);
  opacity: 0.7;
}
.panel-subtitle { margin-top: 0.75rem; }
.dd-plabel-danger { color: color-mix(in srgb, var(--pg-danger) 75%, var(--pg-muted)); }
.dd-plabel-danger::before { background: var(--pg-danger); }

/* Group cards — one shared surface for every dock section. */
.dd-group {
  margin-top: var(--pg-space-4);
  padding: var(--pg-space-3);
  background: rgba(255, 255, 255, 0.02);
  border: 1px solid var(--pg-border);
  border-radius: 10px;
}
.color-palette,
.image-tools-container,
.pg-fx {
  background: rgba(255, 255, 255, 0.02);
  border-radius: 10px;
  padding: var(--pg-space-3);
}
/* Flatten the old per-slider boxes inside the aids group. */
.dd-aids .trace-tools-container,
.dd-aids .zoom-tools-container,
.dd-aids .rotation-tools-container {
  margin-top: var(--pg-space-3);
  padding: 0;
  background: none;
  border: none;
}
.dd-aids .grid-controls { margin-bottom: 0; }
.dd-aids .slider-label { text-align: left; margin: 0 0 0.25rem; }

/* Left dock: color picker + Save Color share one row. */
.dd-swatch-row {
  display: flex;
  align-items: center;
  gap: var(--pg-space-2);
  margin-top: var(--pg-space-3);
}
.dd-swatch-row #colorPicker { margin: 0; flex: none; }
.dd-swatch-row #saveColorBtn { flex: 1; width: auto; margin: 0; }

/* Reset lives at the very bottom of the Adjust column in a danger card. */
.dd-danger {
  margin-top: var(--pg-space-6);
  padding: var(--pg-space-3);
  background: color-mix(in srgb, var(--pg-danger) 6%, transparent);
  border: 1px solid color-mix(in srgb, var(--pg-danger) 30%, transparent);
  border-radius: 10px;
}
.dd-danger #resetProjectBtn { width: 100%; margin: 0; }

/* Reference layer accordion header reads as a group label, chevron at the end. */
.image-tools-container > .tool-group-title {
  font-size: 10px;
  letter-spacing: 0.16em;
  color: var(--pg-dim);
  text-align: left;
}
@media (min-width: 769px) {
  .image-tools-container > .tool-group-title { justify-content: flex-start; }
  .image-tools-container > .tool-group-title .pg-collapse-chevron { margin-left: auto; }
}

/* Slim graffiti sliders — thin rounded track, white thumb with accent ring. */
input[type="range"] {
  width: 100%;
  height: 6px;
  padding: 0;
  border: none;
  border-radius: var(--pg-radius-full);
  background: var(--pg-surface-2);
  margin: 0.35rem auto 0.75rem;
}
input[type="range"]::-webkit-slider-thumb {
  width: 15px;
  height: 15px;
  background: #fff;
  border: 2px solid var(--pg-accent);
  margin-top: 0;
}
input[type="range"]::-moz-range-thumb {
  width: 11px;
  height: 11px;
  background: #fff;
  border: 2px solid var(--pg-accent);
}

/* Right dock: fps chips fill the row, mockup pill look. */
.pg-speed-presets {
  flex-wrap: nowrap;
  width: 100%;
  max-width: none;
  margin: 0 0 0.9rem;
}
.pg-speed-presets button {
  flex: 1 1 0;
  padding: 5px 2px;
  border-radius: 7px;
  background: var(--pg-surface-2);
}

/* Frame duration reads as a group label + mono field. */
#frameDurationLabel {
  display: flex;
  align-items: center;
  gap: 6px;
  width: 100%;
  margin: 0 0 0.3rem;
  font-size: 10px;
  letter-spacing: 0.16em;
  color: var(--pg-dim);
  text-align: left;
  white-space: normal;
}
#frameDurationLabel::before {
  content: '';
  flex: none;
  width: 5px;
  height: 5px;
  border-radius: 50%;
  background: var(--pg-accent);
  opacity: 0.7;
}
#frameDuration {
  width: 100%;
  margin: 0 0 0.75rem;
  font-family: var(--pg-font-mono);
}
.pg-frame-timing { margin: 0 0 0.75rem; text-align: left; }

/* Effects group: collapsible on desktop (dd-panels.js, m20 contract). */
.pg-fx { margin: var(--pg-space-4) 0 0; }
.pg-fx-title {
  display: flex;
  align-items: center;
  gap: 6px;
  font-size: 10px;
  letter-spacing: 0.16em;
  color: var(--pg-dim);
}
.pg-fx-title::before {
  content: '';
  flex: none;
  width: 5px;
  height: 5px;
  border-radius: 50%;
  background: var(--pg-accent);
  opacity: 0.7;
}
.pg-fx-title .pg-collapse-chevron { margin-left: auto; }
@media (min-width: 769px) {
  .pg-fx-title { cursor: pointer; -webkit-user-select: none; user-select: none; }
  .pg-fx-title:hover { color: var(--pg-muted); }
  .pg-fx-title:focus-visible {
    outline: 2px solid var(--pg-focus);
    outline-offset: 2px;
    border-radius: var(--pg-radius-sm);
  }
  .pg-fx.pg-collapsed > :not(.pg-fx-title) { display: none !important; }
  /* The engine's generic m20 rule (.pg-collapsed > :not(.tool-group-title))
     would hide the fx title too — it is not a .tool-group-title. */
  .pg-fx.pg-collapsed > .pg-fx-title { display: flex !important; }
  .pg-fx.pg-collapsed { padding-bottom: var(--pg-space-3); }
  .pg-fx-title[aria-expanded='false'] .pg-collapse-chevron { transform: rotate(-90deg); }
}

/* Export card — accent border; sticky dock at the column bottom on desktop
   (dd-panels.js re-homes it as the last child of .sidebar-right there). */
.dd-export-card { border-color: var(--pg-border-hi); }
.dd-export-card .slider-label { text-align: left; margin: 0.5rem 0 0.3rem; }
.dd-export-card .toggle-container { margin: 0 0 0.5rem; justify-content: flex-start; }
#exportBtn.dd-export-gif {
  display: block;
  width: 100%;
  margin: 0.5rem 0 0;
  padding: 0.65rem 0;
  background: var(--dd-grad);
  color: #04060d;
  font-weight: var(--pg-weight-display);
  font-size: 0.95rem;
  border: none;
  border-radius: 10px;
  box-shadow: 0 10px 24px -8px rgba(76, 201, 240, 0.6);
}
#exportBtn.dd-export-gif::after { content: ' \2193'; }
#exportBtn.dd-export-gif:hover { background: var(--dd-grad); filter: brightness(1.1); }
.dd-export-card .pg-fx-progress { margin: 0.5rem 0 0; }
@media (min-width: 769px) {
  .sidebar-right > .dd-export-card {
    position: sticky;
    bottom: var(--pg-space-2);
    z-index: var(--pg-z-sticky);
    margin: var(--pg-space-2) var(--pg-space-3);
    background: color-mix(in srgb, var(--pg-surface) 94%, var(--pg-bg));
    box-shadow: var(--pg-shadow-md);
  }
}

/* One frame trio: desktop joins mobile in using the Frames-tab trio so the
   add/dup/delete buttons sit WITH the frame list they act on. */
@media (min-width: 769px) {
  .frame-controls-static { display: none; }
  #sheetFrames .frame-controls {
    display: flex;
    width: auto;
    justify-content: center;
    gap: var(--pg-space-2);
    position: sticky;
    top: 0;
    z-index: 1;
    margin: 0 0 var(--pg-space-2);
    padding: var(--pg-space-2) 0;
    background: color-mix(in srgb, var(--pg-surface) 94%, var(--pg-bg));
  }
  /* A little more room for the fx rows and the export card. */
  .sidebar-right { width: 232px; max-width: 232px; }
}
