
/* ══════════════════════════════════════════════════════════
   GAME DEV STUDIO — Clean Modern UI
   ══════════════════════════════════════════════════════════ */

:root {
  --bg-primary: #16161a;
  --bg-secondary: #1c1c22;
  --surface: #232329;
  --surface-alt: #2a2a32;
--text-primary: #ededf0;
  --text-secondary: #94949e;
  --text-dim: #5c5c68;
  --gold: #818cf8;
  --gold-dim: #6366f1;
  --gold-glow: rgba(129,140,248,0.10);
--danger: #3d1c1c;
  --danger-bright: #ef4444;
  --border: rgba(255,255,255,0.08);
  --border-hover: rgba(255,255,255,0.15);
  --font-display: 'Outfit', sans-serif;
  --font-body: 'Outfit', sans-serif;
--transition-med: 0.25s cubic-bezier(.4,0,.2,1);
  --transition-fast: 0.12s cubic-bezier(.4,0,.2,1);
  --cursor-default: default;
--radius-sm: 8px;
  --radius-md: 12px;
  --radius-lg: 16px;
--shadow-md: 0 4px 16px rgba(0,0,0,0.4);
  --shadow-lg: 0 12px 48px rgba(0,0,0,0.5);
}

/* ── Theme infrastructure — themes are defined as classes on <html> ── */
/* Add themes as: html.theme-NAME { --bg-primary: ...; --gold: ...; etc } */

* { margin: 0; padding: 0; box-sizing: border-box; }

body {
  letter-spacing: -0.01em;
  font-family: var(--font-body);
  background: var(--bg-wallpaper, none) center/cover no-repeat var(--bg-primary);
  color: var(--text-primary);
  overflow: hidden;
  height: 100vh;
  width: 100vw;
  user-select: none;
  -webkit-user-select: none;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-rendering: optimizeLegibility;
}

/* ── Desktop ── */
#desktop { position: relative; width: 100vw; height: 100vh; overflow: hidden; }

/* ── Route indicator ── */
#routeIndicator {
  position: fixed; bottom: 12px; left: 16px; z-index: 50;
  font-size: 11px; font-weight: 500; color: var(--text-dim);
  font-family: 'JetBrains Mono', monospace;
  opacity: 0.4; pointer-events: none;
}

/* ── Desktop items ── */
.desktop-item {
  position: absolute; width: 90px;
  display: flex; flex-direction: column; align-items: center; gap: 6px;
  padding: 8px 4px; border: 1px solid transparent;
  transition: border-color var(--transition-fast), background var(--transition-fast), opacity 0.18s ease-out, transform 0.18s ease-out;
  cursor: pointer;
}
.desktop-item.dragging { opacity: 0.7; z-index: 99999; transition: none !important; pointer-events: none; will-change: transform, opacity; }

/* Click-to-deselect should feel instant. The base .desktop-item CSS
 * transitions border-color / background / box-shadow over 0.2-0.3s, which
 * when .selected is removed plays a visible fade-out. This class is added
 * for a single frame around the selection-state change to make it snap. */
.desktop-item.instant-deselect,
.desktop-item.instant-deselect .item-icon,
.desktop-item.instant-deselect .item-name {
  transition: none !important;
  animation: none !important;
}

/* ── Wallpaper contrast ──
 * When a custom theme carries a background image, icons + labels sit on top
 * of arbitrary pixels. We add a glass tile behind each item so they stay
 * readable regardless of wallpaper content. Tile tint inverts between modes:
 * light wallpaper (mostly bright pixels) → dark tile; dark wallpaper → light.
 * Mode is set by applyTheme() from the sampled luminance of the uploaded image. */
html[data-wallpaper-mode] .desktop-item {
  background: rgba(0, 0, 0, 0.32);
  backdrop-filter: blur(14px) saturate(130%);
  -webkit-backdrop-filter: blur(14px) saturate(130%);
  border: 1px solid rgba(255, 255, 255, 0.08);
  box-shadow: 0 4px 14px rgba(0, 0, 0, 0.3);
}
html[data-wallpaper-mode="light"] .desktop-item {
  background: rgba(0, 0, 0, 0.38);
  border-color: rgba(255, 255, 255, 0.1);
}
html[data-wallpaper-mode="dark"] .desktop-item {
  background: rgba(255, 255, 255, 0.14);
  border-color: rgba(255, 255, 255, 0.12);
}
html[data-wallpaper-mode] .desktop-item .item-name {
  color: #ffffff !important;
  text-shadow: 0 1px 3px rgba(0, 0, 0, 0.7);
}
html[data-wallpaper-mode="dark"] .desktop-item .item-name {
  text-shadow: 0 1px 2px rgba(0, 0, 0, 0.5);
}
html[data-wallpaper-mode] .desktop-item .item-icon {
  filter: drop-shadow(0 2px 4px rgba(0, 0, 0, 0.5));
}
html[data-wallpaper-mode="light"] .desktop-item:hover {
  background: rgba(0, 0, 0, 0.48);
}
html[data-wallpaper-mode="dark"] .desktop-item:hover {
  background: rgba(255, 255, 255, 0.22);
}
/* Freshly-dropped items: freeze all visual transitions so the item settles
 * instantly at drop, and the subsequent click-to-deselect doesn't animate
 * the background/border/shadow fadeout either. Lift-on-hover is also
 * neutralised (cursor is still on the drop location and :hover matches
 * immediately otherwise). Class clears on first mouse-off or timeout. */
.desktop-item.drop-stay,
.desktop-item.drop-stay .item-icon,
.desktop-item.drop-stay .item-name {
  transition: none !important;
  animation: none !important;
}
.desktop-item.drop-stay:hover { transform: none !important; }
.desktop-item.drop-stay:hover .item-icon { transform: none !important; filter: saturate(0.85) !important; }
.desktop-item.item-enter { opacity: 0; transform: translateY(8px) scale(0.95); }
.desktop-item.item-exit { opacity: 0; transform: scale(0.92) translateY(-4px); pointer-events: none; }
.desktop-item.drop-target {
  border-color: rgba(129,140,248,0.5); background: rgba(129,140,248,0.12);
  transform: scale(1.08);
  box-shadow: 0 0 20px rgba(129,140,248,0.15);
  transition: all 0.15s cubic-bezier(.22,1,.36,1);
}

.item-icon { width: 48px; height: 48px; display: flex; align-items: center; justify-content: center; }
.item-icon svg { width: 100%; height: 100%; }

.item-name { font-size: 11px; font-weight: 500; color: var(--text-secondary); text-align: center; line-height: 1.3; word-break: break-word; max-width: 82px; }
.desktop-item:hover .item-name, .desktop-item.selected .item-name { color: var(--text-primary); }
.item-name-input { font-size: 11px; font-weight: 500; font-family: var(--font-body); color: var(--text-primary); background: var(--surface); border: 1px solid var(--gold-dim); border-radius: 6px; padding: 2px 6px; text-align: center; outline: none; width: 82px; }

/* ── Context Menu ── */
#contextMenu {
  display: none; position: fixed; z-index: 8000; min-width: 200px;
  opacity: 0; transform: scale(0.97) translateY(-4px);
  transition: opacity 0.15s, transform 0.15s;
}
#contextMenu.visible { display: block; opacity: 1; transform: scale(1) translateY(0); }
.ctx-item { display: flex; align-items: center; gap: 10px; font-size: 13px; color: var(--text-primary); cursor: pointer; transition: background var(--transition-fast); }
.ctx-item:hover { background: rgba(255,255,255,0.06); }
.ctx-item .ctx-icon { width: 16px; height: 16px; opacity: 0.4; display: flex; align-items: center; justify-content: center; }
.ctx-item:hover .ctx-icon { opacity: 0.7; }
.ctx-separator { height: 1px; background: var(--border); margin: 2px 8px; }
.ctx-item.danger { color: var(--danger-bright); }
.ctx-item.danger:hover { background: rgba(229,72,77,0.1); }
.ctx-item .ctx-shortcut { margin-left: auto; font-size: 10px; color: var(--text-dim); font-family: 'JetBrains Mono', monospace; opacity: 0.5; }

/* ── Selection rect ── */
#selectionRect { position: fixed; border: 1.5px solid rgba(124,138,255,0.35); background: rgba(124,138,255,0.06); pointer-events: none; z-index: 7000; display: none; border-radius: 4px; }

/* ── Toast ── */
#toast { position: fixed; bottom: 20px; left: 50%; transform: translateX(-50%) translateY(12px); background: var(--surface-alt); border: 1px solid var(--border-hover); border-radius: 8px; padding: 8px 16px; font-size: 12px; font-weight: 500; color: var(--text-secondary); z-index: 9500; opacity: 0; transition: opacity 0.2s, transform 0.2s; pointer-events: none; box-shadow: 0 4px 20px rgba(0,0,0,0.4); }
#toast.show { opacity: 1; transform: translateX(-50%) translateY(0); }

/* ── Folder Window ── */
.folder-window {
  position: fixed; z-index: 6000;
  background: var(--bg-secondary);
  border: 1px solid var(--border-hover);
  border-radius: 12px;
  box-shadow: 0 16px 64px rgba(0,0,0,0.5);
  display: flex; flex-direction: column;
  min-width: 400px; min-height: 250px;
  overflow: hidden;
  animation: windowOpen 0.2s cubic-bezier(.4,0,.2,1) both;
  transition: outline 0.15s ease, outline-offset 0.15s ease;
  outline: 2px solid transparent;
  outline-offset: -2px;
}
@keyframes windowOpen {
  from { opacity: 0; transform: scale(0.95) translateY(8px); }
  to { opacity: 1; transform: scale(1) translateY(0); }
}
.folder-window .win-titlebar {
  height: 40px; padding: 0 14px;
  background: var(--surface);
  border-bottom: 1px solid var(--border);
  border-radius: 12px 12px 0 0;
  display: flex; align-items: center; gap: 10px;
  cursor: grab;
}
.folder-window .win-titlebar:active { cursor: grabbing; }
.folder-window .win-title {
  font-size: 13px; font-weight: 600; letter-spacing: -0.01em;
  color: var(--text-primary); flex: 1;
}
.folder-window .win-close {
  width: 24px; height: 24px; border-radius: 6px; border: none;
  background: transparent; color: var(--text-dim); font-size: 13px;
  display: flex; align-items: center; justify-content: center;
  cursor: pointer; transition: all var(--transition-fast);
}
.folder-window .win-close:hover { background: var(--danger-bright); color: #fff; }
.folder-window .win-body {
  letter-spacing: -0.01em;
  flex: 1; padding: 16px 20px; overflow-y: auto;
  display: flex; flex-wrap: wrap; gap: 8px; align-content: flex-start;
}
.folder-window .win-resize {
  position: absolute; bottom: 0; right: 0; width: 16px; height: 16px;
  cursor: nwse-resize;
}
.folder-window .win-resize::after {
  content: ''; position: absolute; bottom: 4px; right: 4px;
  width: 8px; height: 8px;
  border-right: 2px solid var(--border-hover);
  border-bottom: 2px solid var(--border-hover);
  opacity: 0.4;
}
.folder-window .win-resize:hover::after { opacity: 1; border-color: var(--gold-dim); }
.folder-window .win-item {
  width: 80px; display: flex; flex-direction: column; align-items: center; gap: 4px;
  padding: 8px 4px; border-radius: 8px; border: 1px solid transparent;
  cursor: pointer; transition: all var(--transition-fast);
}
.folder-window .win-item:hover { background: rgba(255,255,255,0.04); }
.folder-window .win-item.selected { border-color: var(--gold-dim); background: var(--gold-glow); }
.folder-window .win-item.drop-target {
  border-color: rgba(129,140,248,0.5); background: rgba(129,140,248,0.12);
  transform: scale(1.08); box-shadow: 0 0 16px rgba(129,140,248,0.15);
  transition: all 0.15s cubic-bezier(.22,1,.36,1);
}
.folder-window .win-item .item-icon { width: 40px; height: 40px; }
.folder-window .win-item .item-name { font-size: 10px; color: var(--text-secondary); }
.folder-window .win-empty { color: var(--text-dim); font-size: 13px; padding: 24px; text-align: center; width: 100%; font-style: italic; opacity: 0.7; }
.folder-window .win-sel-rect { position: absolute; border: 1px solid rgba(124,138,255,0.3); background: rgba(124,138,255,0.06); pointer-events: none; z-index: 1; display: none; }

/* ── Slab Editor ── */
#slabEditor {
  display: none; position: fixed; inset: 0; z-index: 8500;
  background: #111115;
}
#slabEditor.open { display: block; animation: slabFadeIn 0.2s ease both; }
@keyframes slabFadeIn { from { opacity: 0; } to { opacity: 1; } }
#slabEditor { background: #111115; }

.slab-canvas-wrap {
  position: absolute; inset: 0;
  overflow: hidden; cursor: var(--cursor-default);
}

#slabStaticCanvas, #slabInteractiveCanvas {
  position: absolute; top: 0; left: 0;
}

/* ── Floating UI elements ── */
.slab-close-btn {
  position: absolute; top: 12px; right: 12px; z-index: 102;
  width: 32px; height: 32px; border-radius: 8px; border: 1px solid var(--border);
  background: var(--surface); color: var(--text-dim); font-size: 15px;
  display: flex; align-items: center; justify-content: center;
  cursor: pointer; transition: all var(--transition-fast);
}
.slab-close-btn:hover { background: var(--danger-bright); color: #fff; border-color: transparent; box-shadow: 0 0 16px rgba(239,68,68,0.3); }

.slab-title-float {
  position: absolute; top: 58px; left: 16px; z-index: 102;
  font-size: 11px; font-weight: 500; letter-spacing: 0.04em;
  color: var(--text-dim); opacity: 0.4;
  pointer-events: none;
  text-transform: uppercase;
}

.slab-zoom-float {
  position: absolute; bottom: 12px; left: 12px; z-index: 102;
  font-size: 11px; font-weight: 500; color: var(--text-dim); font-variant-numeric: tabular-nums;
  font-family: 'JetBrains Mono', monospace;
  background: rgba(22,22,28,0.85); padding: 4px 10px; border-radius: 6px;
  border: 1px solid rgba(255,255,255,0.06);
  box-shadow: 0 0 12px rgba(129,140,248,0.05);
  backdrop-filter: blur(8px);
}

/* ── Top toolbar (Excalidraw-style) ── */
.slab-toolbar {
  position: absolute; top: 12px; left: 50%; transform: translateX(-50%);
  display: flex; gap: 1px; z-index: 102;
  background: var(--surface);
  border: 1px solid var(--border-hover); border-radius: 12px;
  padding: 4px 6px;
  box-shadow: 0 4px 24px rgba(0,0,0,0.35);
}
.slab-tool-btn {
  width: 36px; height: 36px; border-radius: 8px; border: none;
  background: transparent; color: var(--text-dim);
  display: flex; align-items: center; justify-content: center;
  cursor: pointer; transition: all var(--transition-fast);
  font-size: 14px; flex-shrink: 0; position: relative;
}
.slab-tool-btn:hover { background: rgba(255,255,255,0.06); color: var(--text-secondary); }
.slab-tool-btn:active { transform: scale(0.9); transition: transform 0.06s; }
.slab-tool-btn.active { background: var(--gold-glow); color: var(--gold); }
.tool-key {
  position: absolute; bottom: 2px; right: 3px;
  font-size: 9px; font-family: 'JetBrains Mono', monospace;
  color: var(--text-dim); opacity: 0.5; line-height: 1;
  pointer-events: none; font-weight: 500;
}
.slab-tool-btn.active .tool-key { color: var(--gold); opacity: 0.8; }
.slab-tool-sep {
  width: 1px; background: var(--border); margin: 6px 2px; flex-shrink: 0;
}

/* ── Right sidebar options panel ── */
.slab-options-panel {
  position: absolute; right: 12px; top: 60px; z-index: 102;
  width: 184px;
  background: var(--surface);
  border: 1px solid var(--border-hover); border-radius: 12px;
  padding: 12px;
  box-shadow: 0 4px 24px rgba(0,0,0,0.35);
  opacity: 0; transform: translateX(12px) scale(0.98);
  transition: opacity 0.2s cubic-bezier(.22,1,.36,1), transform 0.2s cubic-bezier(.22,1,.36,1);
  pointer-events: none;
  max-height: calc(100vh - 100px);
  overflow-y: auto;
}
.slab-options-panel.visible {
  opacity: 1; transform: translateX(0) scale(1);
  pointer-events: auto;
}

.slab-opt-label {
  font-size: 9px; font-weight: 500; color: var(--text-dim); text-transform: uppercase;
  letter-spacing: 0.08em; padding: 6px 0 4px; white-space: nowrap;
}

.slab-opt-colors {
  display: flex; flex-wrap: wrap; gap: 4px; padding: 2px 0;
}
.slab-opt-color {
  width: 20px; height: 20px; border-radius: 6px; border: 2px solid transparent;
  cursor: pointer; transition: all 0.1s;
}
.slab-opt-color:hover { transform: scale(1.15); box-shadow: 0 0 0 2px rgba(255,255,255,0.1); }
.slab-opt-color.active { border-color: var(--text-primary); box-shadow: 0 0 0 1px var(--bg-primary); }
.slab-opt-color.none-color {
  background: transparent;
  position: relative;
}
.slab-opt-color.none-color::after {
  content: ''; position: absolute; inset: 2px;
  border: 1px solid var(--text-dim); border-radius: 2px;
}
.slab-opt-color.none-color::before {
  content: ''; position: absolute; top: 50%; left: -1px; right: -1px; height: 1px;
  background: var(--danger-bright); transform: rotate(-45deg);
}

.slab-opt-widths {
  display: flex; gap: 4px; padding: 4px 0;
  align-items: center;
}
.slab-width-btn {
  width: 28px; height: 28px; border-radius: 6px; border: 1px solid var(--border);
  background: transparent; cursor: pointer;
  display: flex; align-items: center; justify-content: center;
  transition: all var(--transition-fast);
}
.slab-width-btn:hover { border-color: var(--border-hover); background: rgba(255,255,255,0.03); }
.slab-width-btn.active { background: var(--gold-glow); border-color: var(--gold-dim); box-shadow: 0 0 8px rgba(129,140,248,0.12); }
.slab-width-dot {
  border-radius: 50%; background: var(--text-primary);
}

.slab-opt-sep {
  height: 1px; background: var(--border); margin: 6px 0;
}

/* scrollbar for options panel */
.slab-options-panel::-webkit-scrollbar { width: 4px; }
.slab-options-panel::-webkit-scrollbar-track { background: transparent; }
.slab-options-panel::-webkit-scrollbar-thumb { background: var(--border); border-radius: 2px; }

/* ── Laser fade ── */
.laser-trail { position: absolute; top: 0; left: 0; pointer-events: none; z-index: 99; }

.slab-node-layer {
  position: absolute; top: 0; left: 0;
  transform-origin: 0 0;
}

.slab-text-node {
  position: absolute;
  min-width: 60px;
  background: rgba(30, 30, 38, 0.9);
  border: 1px solid var(--border);
  border-radius: 8px;
  padding: 12px 16px;
  color: var(--text-primary);
  font-size: 15px;
  line-height: 1.6;
  cursor: grab;
  overflow-wrap: break-word;
  word-break: break-word;
  transition: all var(--transition-fast);
}
.slab-text-node.transparent {
  background: transparent;
  border-color: transparent;
}
.slab-text-node.transparent:hover { border-color: rgba(255,255,255,0.06); border-style: dashed; }
.slab-text-node.eraser-marked { border-color: rgba(229,72,77,0.5) !important; background: rgba(229,72,77,0.06) !important; }
.slab-text-node:hover { border-color: var(--border-hover); }
.slab-text-node.selected {
  border-color: var(--gold-dim);
  box-shadow: 0 0 0 2px rgba(124,138,255,0.15);
}
.slab-text-node.editing {
  cursor: text;
  user-select: text;
  -webkit-user-select: text;
  box-shadow: 0 0 0 2px rgba(52,211,153,0.3), 0 4px 20px rgba(52,211,153,0.08);
  border-color: rgba(52,211,153,0.2);
}
.slab-text-node .node-content {
  outline: none;
  min-height: 20px;
  font-family: var(--font-body);
  font-size: 16px;
  line-height: 1.6;
  color: var(--text-primary);
}
.slab-text-node .node-content h1 { font-size: 24px; line-height: 1.3; color: var(--text-primary); margin-bottom: 6px; font-weight: 700; letter-spacing: -0.02em; }
.slab-text-node .node-content h2 { font-size: 19px; line-height: 1.3; color: var(--text-primary); margin-bottom: 4px; font-weight: 600; letter-spacing: -0.01em; }
.slab-text-node .node-content h3 { font-size: 16px; font-weight: 600; color: var(--text-secondary); margin-bottom: 4px; }
.slab-text-node .node-content strong { color: var(--gold); font-weight: 600; }
.slab-text-node .node-content em { color: var(--text-secondary); font-style: italic; }

/* ── Resize handle ── */
.slab-text-node .node-resize {
  position: absolute; bottom: -4px; right: -4px; width: 12px; height: 12px;
  cursor: nwse-resize; opacity: 0; transition: opacity 0.15s;
}
.slab-text-node:hover .node-resize, .slab-text-node.selected .node-resize { opacity: 1; }
.slab-text-node .node-resize::after {
  content: ''; position: absolute; bottom: 2px; right: 2px;
  width: 6px; height: 6px;
  border-right: 2px solid var(--text-dim);
  border-bottom: 2px solid var(--text-dim);
}

/* ── Foton click ripple (BEHIND files, subtle) ──
 * Rendered as DOM divs so we can layer them under the file icons (z:1),
 * unlike cursor + label which stay above. Subtler than the canvas version:
 * single thin ring expanding to 50px, max alpha ~0.35, ease-out cubic. */
.foton-ripple {
  position: fixed;
  width: 8px; height: 8px;
  border-radius: 50%;
  border: 1px solid hsla(var(--rip-hue, 220), 75%, 60%, 0.55);
  pointer-events: none;
  z-index: 1;
  animation: foton-ripple-anim 600ms cubic-bezier(0.22, 1, 0.36, 1) forwards;
  will-change: transform, opacity;
}
@keyframes foton-ripple-anim {
  0%   { transform: scale(0.5); opacity: 0.35; }
  60%  { opacity: 0.18; }
  100% { transform: scale(7); opacity: 0; }
}
@media (prefers-reduced-motion: reduce) {
  .foton-ripple { animation-duration: 1ms; opacity: 0; }
}

/* ── Foton mouse-rate badge (L1) ── */
.foton-mouse-badge {
  position: fixed; left: 14px; bottom: 60px; z-index: 8400;
  font: 600 9px/1 'JetBrains Mono', ui-monospace, monospace;
  letter-spacing: 0.06em;
  padding: 3px 7px; border-radius: 4px;
  color: var(--text-secondary);
  background: rgba(20,20,24,0.7);
  border: 1px solid var(--border);
  backdrop-filter: blur(6px);
  pointer-events: none;
  opacity: 0; transition: opacity 0.18s ease;
}
.foton-mouse-badge[data-tier="high"] { color: hsl(150, 60%, 65%); border-color: hsla(150, 60%, 55%, 0.35); }
.foton-mouse-badge[data-tier="mid"]  { color: hsl(45, 75%, 65%);  border-color: hsla(45, 75%, 55%, 0.35); }
.foton-mouse-badge[data-tier="low"]  { color: hsl(0, 60%, 65%);   border-color: hsla(0, 60%, 55%, 0.35); }

/* ── Co-op cursors (FOTON-PULSAR predictor-driven) ── */
/* No CSS transition: predictor smooths in JS at rAF cadence so we stay
 * sub-frame accurate. Position via transform: translate3d for GPU layer
 * (zero reflow, zero paint cost). will-change hints the compositor. */
.remote-cursor {
  position: fixed; left: 0; top: 0; z-index: 8600; pointer-events: none;
  will-change: transform, opacity;
  transform: translate3d(0, 0, 0);
  transition: opacity 180ms ease;
}
.remote-cursor::after {
  content: attr(data-name);
  position: absolute; left: 14px; top: 14px;
  font-size: 10px; font-weight: 500; padding: 2px 8px; border-radius: 6px;
  white-space: nowrap; color: #fff;
  background: rgba(0,0,0,0.6);
  backdrop-filter: blur(8px);
  border: 1px solid rgba(255,255,255,0.06);
}

/* ── Presence stickers (peer emoji on file icons) ── */
.presence-stickers {
  position: absolute;
  top: -8px; right: -10px;
  display: flex; flex-direction: row-reverse;
  z-index: 50; pointer-events: none;
}
.presence-sticker {
  width: 24px; height: 24px; border-radius: 50%;
  display: inline-flex; align-items: center; justify-content: center;
  font-size: 13px; line-height: 1;
  background: hsl(var(--p-hue, 0), 65%, 22%);
  border: 2px solid hsl(var(--p-hue, 0), 75%, 60%);
  box-shadow: 0 4px 10px rgba(0,0,0,0.55), 0 0 8px hsla(var(--p-hue, 0), 90%, 60%, 0.45);
  margin-left: -8px;
  animation: stickerPop 0.22s cubic-bezier(.34,1.56,.64,1);
}
.presence-sticker:first-child { margin-left: 0; }
.presence-sticker.presence-sticker-more {
  background: var(--surface-alt);
  border-color: var(--text-dim);
  font-size: 10px; font-weight: 600; color: var(--text-secondary);
  box-shadow: 0 4px 10px rgba(0,0,0,0.5);
}
@keyframes stickerPop {
  0% { opacity: 0; transform: scale(0.4) translateY(-4px); }
  60% { transform: scale(1.12) translateY(0); }
  100% { opacity: 1; transform: scale(1) translateY(0); }
}

/* ── Presence bar (me + peers) ── */
#presence-bar {
  position: fixed; left: 14px; bottom: 14px; z-index: 8500;
  display: flex; flex-direction: column; align-items: flex-start; gap: 6px;
  pointer-events: none;
}
#presence-bar > * { pointer-events: auto; }
#peer-list {
  display: flex; flex-direction: column; gap: 4px;
  padding: 6px;
  background: var(--surface);
  border: 1px solid var(--border-hover);
  border-radius: var(--radius-md);
  box-shadow: var(--shadow-md);
  max-height: 40vh; overflow-y: auto;
  min-width: 180px;
}
#peer-list[hidden] { display: none; }
.peer-row {
  display: inline-flex; align-items: center; gap: 8px;
  padding: 4px 8px; border-radius: 8px;
  font: 500 12px/1.2 var(--font-body); color: var(--text-secondary);
}
.peer-row .peer-emoji {
  width: 22px; height: 22px; display: inline-flex; align-items: center; justify-content: center;
  border-radius: 50%; font-size: 13px; flex-shrink: 0;
  background: hsl(var(--p-hue, 0), 60%, 22%);
  border: 1px solid hsl(var(--p-hue, 0), 70%, 55%);
  box-shadow: inset 0 0 8px hsla(var(--p-hue, 0), 80%, 60%, 0.25);
}
.peer-row .peer-name { color: var(--text-primary); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; max-width: 160px; }
#me-pill {
  display: inline-flex; align-items: center; gap: 9px;
  padding: 5px 14px 5px 5px; border-radius: 999px;
  background: var(--surface);
  border: 1px solid var(--border-hover);
  color: var(--text-primary);
  font: 600 13px/1 var(--font-body);
  cursor: pointer;
  box-shadow: var(--shadow-md);
  transition: transform var(--transition-fast), border-color var(--transition-fast), box-shadow var(--transition-fast);
}
#me-pill:hover {
  border-color: hsl(var(--me-hue, 237), 70%, 55%);
  transform: translateY(-1px);
  box-shadow: var(--shadow-md), 0 0 12px hsla(var(--me-hue, 237), 70%, 55%, 0.25);
}
#me-pill .me-emoji {
  width: 26px; height: 26px; display: inline-flex; align-items: center; justify-content: center;
  border-radius: 50%; font-size: 15px;
  background: hsl(var(--me-hue, 237), 70%, 28%);
  border: 1px solid hsl(var(--me-hue, 237), 70%, 60%);
  box-shadow: 0 0 10px hsla(var(--me-hue, 237), 80%, 60%, 0.4);
  overflow: hidden;
}
#me-pill .me-emoji svg { width: 22px; height: 22px; display: block; }
.peer-emoji svg { width: 20px; height: 20px; display: block; }
.presence-sticker svg { width: 20px; height: 20px; display: block; }
#me-pill .me-name { letter-spacing: -0.01em; max-width: 180px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
#me-pill .me-edit-hint {
  font-size: 10px; color: var(--text-dim); font-weight: 500;
  padding-left: 4px; border-left: 1px solid var(--border);
  opacity: 0; transition: opacity var(--transition-fast);
}
#me-pill:hover .me-edit-hint { opacity: 1; }
#me-pill .me-rtt {
  font: 500 10px/1 'JetBrains Mono', ui-monospace, monospace;
  letter-spacing: 0.04em;
  padding-left: 6px; margin-left: 2px; border-left: 1px solid var(--border);
  cursor: pointer;
  transition: filter var(--transition-fast);
}
#me-pill .me-rtt:hover { filter: brightness(1.4); }
#me-pill .me-rtt[data-tier="good"] { color: hsl(150, 60%, 65%); }
#me-pill .me-rtt[data-tier="ok"]   { color: hsl(45, 75%, 65%); }
#me-pill .me-rtt[data-tier="bad"]  { color: hsl(0, 70%, 65%); }
.peer-row .peer-fresh {
  padding-left: 6px;
  font: 500 10px/1 'JetBrains Mono', ui-monospace, monospace;
  color: var(--text-dim);
  letter-spacing: 0.04em;
}
.peer-row .peer-fresh[data-tier="good"] { color: hsl(150, 60%, 60%); }
.peer-row .peer-fresh[data-tier="ok"]   { color: hsl(45, 75%, 60%); }
.peer-row .peer-fresh[data-tier="bad"]  { color: hsl(0, 60%, 60%); }

/* Phase 6 — currently-followed peer marker. The amber "↳" matches the
 * follow-chip in the WM chrome so the visual link is obvious. */
.peer-row[data-following="1"] {
  outline: 1px solid rgba(240, 168, 92, 0.45);
  outline-offset: -1px;
  background: rgba(240, 168, 92, 0.06);
}
.peer-row .peer-following-mark {
  margin-left: auto;
  font-family: 'JetBrains Mono', ui-monospace, monospace;
  color: #f4d6a3;
  opacity: 0.85;
  font-size: 13px;
}

/* Right-click follow menu — minimal glass card. Sits above the
 * presence bar (z-index just above). */
#gds-peer-menu {
  position: fixed;
  z-index: 9100;
  min-width: 220px;
  background: rgba(20, 20, 28, 0.94);
  border: 1px solid rgba(255, 255, 255, 0.08);
  border-radius: 10px;
  padding: 4px;
  font-family: 'Inter', system-ui, sans-serif;
  font-size: 13px;
  color: rgba(232, 234, 246, 0.88);
  box-shadow: 0 18px 40px -12px rgba(0, 0, 0, 0.5);
  backdrop-filter: blur(20px) saturate(140%);
  -webkit-backdrop-filter: blur(20px) saturate(140%);
}
.gds-peer-menu-item {
  padding: 8px 12px;
  border-radius: 6px;
  cursor: pointer;
  white-space: nowrap;
  user-select: none;
  transition: background-color 100ms;
}
.gds-peer-menu-item:hover { background: rgba(124, 138, 255, 0.16); color: #eef0ff; }
.peer-row .peer-pps {
  margin-left: auto;
  font: 500 9px/1 'JetBrains Mono', ui-monospace, monospace;
  color: hsla(var(--p-hue, 0), 40%, 65%, 0.9);
  letter-spacing: 0.04em;
  padding: 2px 5px; border-radius: 3px;
  background: hsla(var(--p-hue, 0), 45%, 22%, 0.45);
}
.coach-spark {
  margin-top: 6px; width: 100%; height: 24px; display: block;
  color: currentColor;
}
.coach-metric[data-tier="good"] .coach-spark { color: hsl(150, 60%, 55%); }
.coach-metric[data-tier="mid"] .coach-spark  { color: hsl(45, 75%, 55%); }
.coach-metric[data-tier="low"] .coach-spark  { color: hsl(0, 60%, 55%); }

/* ── Identity modal ── */
#identity-modal {
  position: fixed; inset: 0; z-index: 9700;
  display: none; align-items: center; justify-content: center;
  background: rgba(0,0,0,0.55);
  backdrop-filter: blur(6px);
  animation: fadeIn 0.18s ease-out;
}
#identity-modal[data-open="1"] { display: flex; }
#identity-modal .id-card {
  width: min(480px, calc(100vw - 32px));
  background: var(--surface);
  border: 1px solid var(--border-hover);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-lg);
  padding: 24px;
  display: flex; flex-direction: column; gap: 18px;
}
#identity-modal .id-header {
  display: flex; align-items: center; justify-content: space-between;
}
#identity-modal h2 {
  font: 600 16px/1.2 var(--font-display); color: var(--text-primary);
  letter-spacing: -0.02em; margin: 0;
}
#identity-modal .id-close {
  background: transparent; border: 0; color: var(--text-dim);
  cursor: pointer; padding: 4px; border-radius: 6px; line-height: 0;
  transition: color var(--transition-fast), background var(--transition-fast);
}
#identity-modal .id-close:hover { color: var(--text-primary); background: var(--surface-alt); }
#identity-modal .id-preview {
  display: flex; align-items: center; gap: 14px;
  padding: 14px 16px; border-radius: var(--radius-md);
  background: var(--bg-secondary);
  border: 1px solid var(--border);
}
#identity-modal .id-preview-avatar {
  width: 56px; height: 56px; flex-shrink: 0;
  border-radius: 50%; display: inline-flex; align-items: center; justify-content: center;
  font-size: 28px;
  background: hsl(var(--id-hue, 237), 70%, 28%);
  border: 1px solid hsl(var(--id-hue, 237), 70%, 60%);
  box-shadow: 0 0 18px hsla(var(--id-hue, 237), 80%, 60%, 0.4), inset 0 0 12px hsla(var(--id-hue, 237), 80%, 60%, 0.2);
  transition: background var(--transition-med), border-color var(--transition-med), box-shadow var(--transition-med);
}
#identity-modal .id-preview-meta { display: flex; flex-direction: column; gap: 4px; }
#identity-modal .id-preview-name { font: 600 16px/1 var(--font-body); color: var(--text-primary); }
#identity-modal .id-preview-id { font: 400 11px/1 var(--font-body); color: var(--text-dim); letter-spacing: 0.02em; }
#identity-modal .id-field { display: flex; flex-direction: column; gap: 6px; }
#identity-modal .id-field label {
  font: 500 11px/1 var(--font-body); color: var(--text-secondary);
  letter-spacing: 0.06em; text-transform: uppercase;
}
#identity-modal .id-field input[type="text"] {
  background: var(--bg-secondary);
  border: 1px solid var(--border);
  color: var(--text-primary);
  padding: 9px 12px; border-radius: var(--radius-sm);
  font: 500 13px/1.2 var(--font-body); outline: none;
  transition: border-color var(--transition-fast);
}
#identity-modal .id-field input[type="text"]:focus { border-color: hsl(var(--id-hue, 237), 70%, 55%); }
#identity-modal .emoji-picker {
  display: grid; grid-template-columns: repeat(10, 1fr); gap: 4px;
  padding: 8px; border-radius: var(--radius-sm);
  background: var(--bg-secondary); border: 1px solid var(--border);
  max-height: 140px; overflow-y: auto;
}
#identity-modal .emoji-pick {
  background: transparent; border: 1px solid transparent; border-radius: 6px;
  cursor: pointer; padding: 4px; font-size: 18px; line-height: 1;
  transition: background var(--transition-fast), border-color var(--transition-fast), transform var(--transition-fast);
}
#identity-modal .emoji-pick:hover { background: var(--surface-alt); transform: scale(1.1); }
#identity-modal .emoji-pick.selected { background: var(--surface-alt); border-color: hsl(var(--id-hue, 237), 70%, 55%); }
#identity-modal .id-create-avatar-btn {
  display: inline-flex; align-items: center; gap: 6px;
  margin-top: 8px;
  padding: 8px 14px; border-radius: 8px;
  background: transparent;
  border: 1px dashed var(--border-hover);
  color: var(--text-secondary);
  font: 500 12px var(--font-body); letter-spacing: 0.02em;
  cursor: pointer;
  transition: all 0.15s;
}
#identity-modal .id-create-avatar-btn:hover {
  border-style: solid;
  border-color: hsl(var(--id-hue, 237), 70%, 55%);
  color: var(--text-primary);
  background: rgba(124,138,255,0.08);
}
#identity-modal .hue-slider {
  -webkit-appearance: none; appearance: none;
  width: 100%; height: 14px; border-radius: 7px;
  background: linear-gradient(90deg,
    hsl(0,70%,55%), hsl(45,70%,55%), hsl(90,70%,55%), hsl(135,70%,55%),
    hsl(180,70%,55%), hsl(225,70%,55%), hsl(270,70%,55%), hsl(315,70%,55%), hsl(360,70%,55%));
  outline: none; cursor: pointer;
  border: 1px solid var(--border);
}
#identity-modal .hue-slider::-webkit-slider-thumb {
  -webkit-appearance: none; appearance: none;
  width: 18px; height: 18px; border-radius: 50%;
  background: hsl(var(--id-hue, 237), 70%, 55%);
  border: 2px solid #fff;
  box-shadow: 0 0 6px rgba(0,0,0,0.5);
  cursor: grab;
}
#identity-modal .hue-slider::-moz-range-thumb {
  width: 18px; height: 18px; border-radius: 50%;
  background: hsl(var(--id-hue, 237), 70%, 55%);
  border: 2px solid #fff;
  box-shadow: 0 0 6px rgba(0,0,0,0.5);
  cursor: grab;
}
#identity-modal .id-actions { display: flex; gap: 8px; justify-content: flex-end; }
#identity-modal .id-btn {
  font: 600 12px/1 var(--font-body);
  padding: 9px 18px; border-radius: var(--radius-sm);
  cursor: pointer; transition: all var(--transition-fast);
  letter-spacing: 0.02em;
}
#identity-modal .id-btn-secondary {
  background: transparent; border: 1px solid var(--border-hover); color: var(--text-secondary);
}
#identity-modal .id-btn-secondary:hover { color: var(--text-primary); border-color: var(--text-dim); }
#identity-modal .id-btn-primary {
  background: hsl(var(--id-hue, 237), 70%, 55%); border: 1px solid hsl(var(--id-hue, 237), 70%, 65%);
  color: #fff; box-shadow: 0 4px 14px hsla(var(--id-hue, 237), 70%, 50%, 0.35);
}
#identity-modal .id-btn-primary:hover { transform: translateY(-1px); box-shadow: 0 6px 18px hsla(var(--id-hue, 237), 70%, 50%, 0.5); }
#identity-modal .id-btn-primary:disabled { opacity: 0.5; cursor: not-allowed; transform: none; box-shadow: none; }
@keyframes fadeIn { from { opacity: 0; } to { opacity: 1; } }

/* ── Foton hardware coach ── */
#coach-modal {
  position: fixed; inset: 0; z-index: 9750;
  display: none; align-items: center; justify-content: center;
  background: rgba(0,0,0,0.55);
  backdrop-filter: blur(6px);
  animation: fadeIn 0.18s ease-out;
}
#coach-modal[data-open="1"] { display: flex; }
.coach-card {
  width: min(560px, calc(100vw - 32px));
  background: var(--surface);
  border: 1px solid var(--border-hover);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-lg);
  padding: 24px;
  display: flex; flex-direction: column; gap: 18px;
  max-height: 86vh; overflow-y: auto;
}
.coach-header { display: flex; align-items: center; justify-content: space-between; }
.coach-header h2 {
  font: 600 16px/1.2 var(--font-display); color: var(--text-primary);
  letter-spacing: -0.02em; margin: 0;
}
.coach-close {
  background: transparent; border: 0; color: var(--text-dim);
  cursor: pointer; padding: 4px; border-radius: 6px; line-height: 0;
  transition: color var(--transition-fast), background var(--transition-fast);
}
.coach-close:hover { color: var(--text-primary); background: var(--surface-alt); }
.coach-grid {
  display: grid; grid-template-columns: 1fr 1fr; gap: 10px;
}
.coach-metric {
  background: var(--bg-secondary);
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  padding: 12px 14px;
  display: flex; flex-direction: column; gap: 4px;
  position: relative;
}
.coach-metric::before {
  content: ''; position: absolute; left: 0; top: 12px; bottom: 12px; width: 3px;
  border-radius: 0 3px 3px 0;
  background: var(--text-dim);
}
.coach-metric[data-tier="good"]::before { background: hsl(150, 60%, 55%); }
.coach-metric[data-tier="mid"]::before  { background: hsl(45, 75%, 55%); }
.coach-metric[data-tier="low"]::before  { background: hsl(0, 60%, 55%); }
.coach-label {
  font: 500 10px/1.2 var(--font-body); letter-spacing: 0.08em; text-transform: uppercase;
  color: var(--text-dim);
}
.coach-value {
  font: 600 18px/1.1 'JetBrains Mono', ui-monospace, monospace;
  color: var(--text-primary);
  letter-spacing: -0.01em;
}
.coach-detail {
  font: 400 11px/1.3 var(--font-body); color: var(--text-secondary);
}
.coach-detail a {
  color: hsl(220, 70%, 70%);
  text-decoration: underline;
  text-decoration-color: hsla(220, 70%, 70%, 0.4);
  text-underline-offset: 2px;
  cursor: pointer;
}
.coach-detail a:hover { color: hsl(220, 80%, 80%); text-decoration-color: hsla(220, 80%, 80%, 0.8); }
.coach-recs {
  background: var(--bg-secondary);
  border: 1px solid hsla(45, 70%, 50%, 0.25);
  border-left: 3px solid hsl(45, 75%, 55%);
  border-radius: var(--radius-md);
  padding: 12px 16px;
}
.coach-recs-title {
  font: 600 11px/1 var(--font-body); letter-spacing: 0.06em; text-transform: uppercase;
  color: hsl(45, 75%, 70%); margin-bottom: 8px;
}
.coach-recs ul { list-style: none; padding: 0; margin: 0; display: flex; flex-direction: column; gap: 6px; }
.coach-recs li {
  font: 400 12px/1.45 var(--font-body); color: var(--text-secondary);
  padding-left: 14px; position: relative;
}
.coach-recs li::before {
  content: '→'; position: absolute; left: 0; color: hsl(45, 75%, 60%);
  font-weight: 600;
}

/* ── Setup wizard ── */
#setup-wizard {
  position: fixed; inset: 0; z-index: 9800;
  display: none; align-items: center; justify-content: center;
  background: radial-gradient(circle at 50% 30%, hsla(var(--wiz-hue, 237), 50%, 18%, 0.6), rgba(8,8,12,0.95) 70%);
  backdrop-filter: blur(10px);
  animation: fadeIn 0.3s ease-out;
}
#setup-wizard[data-open="1"] { display: flex; }
#setup-wizard .wiz-card {
  width: min(560px, calc(100vw - 32px));
  background: rgba(20,20,24,0.85);
  border: 1px solid hsl(var(--wiz-hue, 237), 60%, 35%);
  border-radius: var(--radius-lg);
  box-shadow: 0 20px 80px hsla(var(--wiz-hue, 237), 60%, 30%, 0.4), var(--shadow-lg);
  padding: 32px 36px 28px;
  display: flex; flex-direction: column; gap: 22px;
  position: relative;
  overflow: hidden;
}
#setup-wizard .wiz-card::before {
  content: ''; position: absolute; inset: 0; pointer-events: none;
  background: radial-gradient(circle at 50% 0%, hsla(var(--wiz-hue, 237), 70%, 50%, 0.15), transparent 60%);
}
#setup-wizard .wiz-progress {
  display: flex; gap: 6px; margin-bottom: 4px;
}
#setup-wizard .wiz-progress span {
  flex: 1; height: 3px; border-radius: 2px;
  background: var(--surface-alt);
  transition: background var(--transition-med);
}
#setup-wizard .wiz-progress span.done { background: hsl(var(--wiz-hue, 237), 70%, 55%); }
#setup-wizard .wiz-progress span.active {
  background: linear-gradient(90deg, hsl(var(--wiz-hue, 237), 70%, 55%), hsl(var(--wiz-hue, 237), 70%, 35%));
}
#setup-wizard .wiz-step { display: flex; flex-direction: column; gap: 14px; }
#setup-wizard .wiz-eyebrow {
  font: 500 11px/1 var(--font-body); color: hsl(var(--wiz-hue, 237), 60%, 70%);
  letter-spacing: 0.18em; text-transform: uppercase;
}
#setup-wizard h1 {
  font: 600 26px/1.15 var(--font-display); color: var(--text-primary);
  letter-spacing: -0.025em; margin: 0;
}
#setup-wizard p.wiz-lede {
  font: 400 14px/1.5 var(--font-body); color: var(--text-secondary);
  margin: 0; max-width: 44ch;
}
#setup-wizard .wiz-hue-grid {
  display: grid; grid-template-columns: repeat(8, 1fr); gap: 8px;
  margin-top: 8px;
}
#setup-wizard .wiz-hue-swatch {
  aspect-ratio: 1; border-radius: 50%; cursor: pointer;
  border: 2px solid transparent;
  transition: transform var(--transition-fast), border-color var(--transition-fast), box-shadow var(--transition-fast);
}
#setup-wizard .wiz-hue-swatch:hover { transform: scale(1.1); }
#setup-wizard .wiz-hue-swatch.selected {
  border-color: #fff;
  box-shadow: 0 0 16px currentColor;
}
#setup-wizard .wiz-input {
  background: rgba(0,0,0,0.3);
  border: 1px solid hsl(var(--wiz-hue, 237), 50%, 30%);
  color: var(--text-primary);
  padding: 14px 18px; border-radius: var(--radius-md);
  font: 500 16px/1.2 var(--font-body); outline: none;
  transition: border-color var(--transition-fast), box-shadow var(--transition-fast);
}
#setup-wizard .wiz-input:focus {
  border-color: hsl(var(--wiz-hue, 237), 70%, 55%);
  box-shadow: 0 0 0 3px hsla(var(--wiz-hue, 237), 70%, 50%, 0.18);
}
#setup-wizard .wiz-emoji-grid {
  display: grid; grid-template-columns: repeat(10, 1fr); gap: 6px;
  padding: 10px; border-radius: var(--radius-md);
  background: rgba(0,0,0,0.3); border: 1px solid var(--border);
  max-height: 220px; overflow-y: auto;
}
#setup-wizard .wiz-emoji-grid button {
  background: transparent; border: 1px solid transparent; border-radius: 8px;
  cursor: pointer; padding: 6px; font-size: 22px; line-height: 1;
  transition: background var(--transition-fast), border-color var(--transition-fast), transform var(--transition-fast);
}
#setup-wizard .wiz-emoji-grid button:hover { background: rgba(255,255,255,0.05); transform: scale(1.15); }
#setup-wizard .wiz-emoji-grid button.selected {
  background: hsla(var(--wiz-hue, 237), 70%, 50%, 0.15);
  border-color: hsl(var(--wiz-hue, 237), 70%, 55%);
}
#setup-wizard .wiz-preview {
  display: flex; align-items: center; gap: 14px;
  padding: 12px 16px; border-radius: var(--radius-md);
  background: rgba(0,0,0,0.25); border: 1px solid var(--border);
  margin-top: 4px;
}
#setup-wizard .wiz-preview-avatar {
  width: 44px; height: 44px; border-radius: 50%;
  display: inline-flex; align-items: center; justify-content: center; font-size: 22px;
  background: hsl(var(--wiz-hue, 237), 70%, 28%);
  border: 1px solid hsl(var(--wiz-hue, 237), 70%, 60%);
  box-shadow: 0 0 14px hsla(var(--wiz-hue, 237), 80%, 60%, 0.5);
}
#setup-wizard .wiz-preview-name { font: 600 15px/1 var(--font-body); color: var(--text-primary); }
#setup-wizard .wiz-actions {
  display: flex; justify-content: space-between; align-items: center;
  margin-top: 4px;
}
#setup-wizard .wiz-back, #setup-wizard .wiz-next {
  font: 600 13px/1 var(--font-body); padding: 11px 22px;
  border-radius: var(--radius-md); cursor: pointer;
  transition: all var(--transition-fast); letter-spacing: 0.02em;
}
#setup-wizard .wiz-back {
  background: transparent; border: 1px solid var(--border-hover); color: var(--text-secondary);
}
#setup-wizard .wiz-back:hover { color: var(--text-primary); border-color: var(--text-dim); }
#setup-wizard .wiz-back[hidden] { visibility: hidden; }
#setup-wizard .wiz-next {
  background: hsl(var(--wiz-hue, 237), 70%, 55%);
  border: 1px solid hsl(var(--wiz-hue, 237), 70%, 65%);
  color: #fff;
  box-shadow: 0 6px 20px hsla(var(--wiz-hue, 237), 70%, 50%, 0.45);
}
#setup-wizard .wiz-next:hover { transform: translateY(-1px); box-shadow: 0 10px 28px hsla(var(--wiz-hue, 237), 70%, 50%, 0.6); }
#setup-wizard .wiz-next:disabled { opacity: 0.45; cursor: not-allowed; transform: none; box-shadow: none; }
#setup-wizard .wiz-skip {
  font: 500 11px/1 var(--font-body); color: var(--text-dim);
  text-decoration: underline;
  text-decoration-color: rgba(255,255,255,0.15);
  text-underline-offset: 3px;
  margin-right: auto; margin-left: 12px;
  cursor: pointer;
  transition: color var(--transition-fast);
}
#setup-wizard .wiz-skip:hover { color: var(--text-secondary); text-decoration-color: rgba(255,255,255,0.4); }

/* ── YouTube embed ── */
.yt-embed {
  position: relative; width: 100%; padding-bottom: 56.25%;
  margin: 8px 0; border-radius: 6px; overflow: hidden;
  background: #000;
}
.yt-embed iframe {
  position: absolute; inset: 0; width: 100%; height: 100%;
  border: none; border-radius: 6px;
}

/* ── Wiki-links ── */
.wiki-link {
  color: var(--gold); text-decoration: none; cursor: pointer;
  border-bottom: 1px dashed transparent;
  background-image: linear-gradient(rgba(124,138,255,0.4), rgba(124,138,255,0.4));
  background-size: 0% 1px;
  background-position: center bottom;
  background-repeat: no-repeat;
  transition: all 0.25s ease;
}
.wiki-link:hover { color: #9aa4ff; background-size: 100% 1px; }
.wiki-link.broken { color: var(--danger-bright); border-color: var(--danger-bright); opacity: 0.7; }

/* ── Connection ports ── */
.node-port {
  position: absolute; width: 10px; height: 10px; border-radius: 50%;
  background: var(--gold-dim); border: 2px solid var(--bg-primary);
  opacity: 0; transition: all 0.15s;
  cursor: crosshair; z-index: 5;
}
.slab-text-node:hover .node-port,
.slab-text-node.selected .node-port { opacity: 0.6; }
.node-port:hover { opacity: 1; transform: scale(1.5); background: var(--gold); box-shadow: 0 0 12px rgba(129,140,248,0.3); }
.node-port.top { top: -5px; left: 50%; margin-left: -5px; }
.node-port.bottom { bottom: -5px; left: 50%; margin-left: -5px; }
.node-port.left { left: -5px; top: 50%; margin-top: -5px; }
.node-port.right { right: -5px; top: 50%; margin-top: -5px; }

/* ── Alignment guides ── */
.align-guide {
  position: absolute; pointer-events: none; z-index: 200;
  background: rgba(124, 138, 255, 0.4);
  box-shadow: 0 0 6px rgba(124, 138, 255, 0.3);
}
.align-guide.horizontal { height: 1px; left: 0; right: 0; }
.align-guide.vertical { width: 1px; top: 0; bottom: 0; }

/* ── Theme picker window ── */
.theme-picker {
  position: fixed; z-index: 7000;
  background: var(--bg-secondary);
  border: 1px solid var(--border-hover);
  border-radius: 14px;
  box-shadow: 0 20px 60px rgba(0,0,0,0.5);
  width: 460px; min-height: 200px; max-height: 80vh;
  overflow: hidden;
  display: flex; flex-direction: column;
  animation: windowOpen 0.2s cubic-bezier(.4,0,.2,1) both;
}
.theme-picker .tp-header {
  display: flex; align-items: center; padding: 14px 18px;
  border-bottom: 1px solid var(--border);
  cursor: grab; flex-shrink: 0;
}
.theme-picker .tp-header:active { cursor: grabbing; }
.theme-picker .tp-title {
  font-size: 13px; font-weight: 600; color: var(--text-primary); flex: 1;
}
.theme-picker .tp-close {
  width: 24px; height: 24px; border-radius: 6px; border: none;
  background: transparent; color: var(--text-dim); font-size: 13px;
  display: flex; align-items: center; justify-content: center;
  cursor: pointer; transition: all 0.15s;
}
.theme-picker .tp-close:hover { background: #ef4444; color: #fff; transform: scale(1.15); }
.theme-picker .tp-body {
  letter-spacing: -0.01em;
  padding: 18px;
  display: flex; flex-direction: column; gap: 20px;
  overflow-y: auto;
}
.tp-section-title {
  font: 600 10px/1 var(--font-body);
  letter-spacing: 0.14em; text-transform: uppercase;
  color: var(--text-dim); margin: 0 0 10px 2px;
}
.tp-grid {
  display: grid; grid-template-columns: 1fr 1fr; gap: 10px;
}
.theme-card {
  border-radius: 10px; border: 2px solid var(--border);
  padding: 14px; cursor: pointer;
  transition: all 0.15s;
  display: flex; flex-direction: column; gap: 8px;
}
.theme-card:hover { border-color: var(--border-hover); }
.theme-card.active { border-color: var(--gold); box-shadow: 0 0 0 1px var(--gold-dim); }
.theme-card-swatches {
  display: flex; gap: 4px; height: 24px; border-radius: 6px; overflow: hidden;
}
.theme-card-swatch { flex: 1; }
.theme-card-name {
  font-size: 12px; font-weight: 600; color: var(--text-primary);
}
.theme-card-desc {
  font-size: 10px; color: var(--text-dim); line-height: 1.3;
}
.cursor-card {
  border-radius: 10px; border: 2px solid var(--border);
  padding: 12px 10px; cursor: pointer;
  transition: all 0.15s;
  display: flex; flex-direction: column; align-items: center; gap: 8px;
  position: relative; min-height: 84px;
  background: linear-gradient(180deg, rgba(255,255,255,0.015), transparent);
}
.cursor-card:hover { border-color: var(--border-hover); transform: translateY(-1px); }
.cursor-card.active { border-color: var(--gold); box-shadow: 0 0 0 1px var(--gold-dim); }
.cursor-card-preview {
  width: 56px; height: 56px;
  display: flex; align-items: center; justify-content: center;
  position: relative;
}
.cursor-card-preview canvas {
  width: 56px; height: 56px; display: block;
}
.cursor-card-name {
  font-size: 11px; font-weight: 600; color: var(--text-primary);
  letter-spacing: 0.01em;
}
.tp-add-section {
  padding: 12px; border: 1px dashed var(--border-hover); border-radius: 10px;
  text-align: center; color: var(--text-dim); font-size: 12px;
  cursor: pointer; transition: all 0.15s;
  min-height: 84px;
  display: flex; align-items: center; justify-content: center;
  flex-direction: column; gap: 4px;
}
.tp-add-section.full { grid-column: 1 / -1; min-height: 0; }
.tp-add-section:hover { border-color: var(--gold-dim); color: var(--text-secondary); }
.tp-add-section .tp-add-icon {
  font-size: 18px; line-height: 1;
}

body.mobile .theme-picker {
  width: min(94vw, 460px);
  left: 50% !important;
  top: 8vh !important;
  transform: translateX(-50%);
  max-height: 84vh;
}
body.mobile .theme-picker .tp-body { padding: 14px; }
body.mobile .cursor-card { min-height: 92px; }
body.mobile .cursor-card-preview canvas { width: 52px; height: 52px; }
body.mobile .tp-grid { gap: 8px; }

/* ══════════════════════════════════════════════════════════════════════
 * IVORY BAUHAUS THEME — editorial light theme
 * Activated by html.theme-ivory class. Scoped to that selector so it
 * cleanly turns off when user picks another theme.
 * ══════════════════════════════════════════════════════════════════════ */
html.theme-ivory, html.theme-ivory body {
  background: #eee7d6 !important;
  --bg-primary: #eee7d6;
  --bg-secondary: #e2daca;
  --surface: #e2daca;
  --text-primary: #17140f;
  --text-secondary: #3a352b;
  --text-dim: #7a7266;
  --gold: #8a2a1c;
  --gold-dim: #b44b38;
  --border: rgba(23,20,15,0.12);
  --border-hover: rgba(23,20,15,0.25);
}
html.theme-ivory body::before {
  content: ''; position: fixed; inset: 0; pointer-events: none; z-index: 0;
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='200' height='200'><filter id='n'><feTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='2' seed='4'/><feColorMatrix values='0 0 0 0 0.09  0 0 0 0 0.08  0 0 0 0 0.06  0 0 0 0.08 0'/></filter><rect width='200' height='200' filter='url(%23n)'/></svg>");
  mix-blend-mode: multiply; opacity: 0.35;
}
html.theme-ivory #desktop { background: transparent; }
html.theme-ivory .desktop-item .item-name {
  color: #3a352b !important;
  font-family: 'Outfit', 'Inter', sans-serif !important;
  font-size: 11px !important;
  font-weight: 500 !important;
  letter-spacing: 0.04em !important;
  text-transform: uppercase;
}
html.theme-ivory .desktop-item:hover .item-name,
html.theme-ivory .desktop-item.selected .item-name { color: #17140f !important; }
html.theme-ivory .desktop-item.selected {
  border-color: #17140f !important;
  background: rgba(23,20,15,0.06) !important;
}
html.theme-ivory .desktop-item:hover { border-color: rgba(23,20,15,0.25) !important; }
html.theme-ivory .desktop-item:hover .item-icon,
html.theme-ivory .desktop-item.selected .item-icon {
  transform: none !important;
  filter: none !important;
  box-shadow: none !important;
}

/* ── AI cursor designer ─────────────────────────────────────────────── */
.ai-designer {
  position: fixed; inset: 0; z-index: 9400;
  display: flex; align-items: center; justify-content: center;
}
.ai-designer .acd-backdrop {
  position: absolute; inset: 0;
  background: rgba(8, 8, 12, 0.66);
  backdrop-filter: blur(6px);
  animation: fadeIn 0.25s ease both;
}
@keyframes acdPopIn { from { transform: translateY(12px) scale(0.98); opacity: 0; } to { transform: none; opacity: 1; } }
.ai-designer .acd-panel {
  position: relative;
  width: min(960px, 92vw); height: min(640px, 86vh);
  background: var(--bg-secondary);
  border: 1px solid var(--border-hover);
  border-radius: 18px;
  box-shadow: 0 24px 80px rgba(0,0,0,0.55);
  display: flex; flex-direction: column;
  overflow: hidden;
  animation: acdPopIn 0.28s cubic-bezier(.22,1,.36,1) both;
}
.acd-header {
  display: flex; align-items: center; gap: 12px;
  padding: 14px 18px;
  border-bottom: 1px solid var(--border);
}
.acd-header .acd-badge {
  font-size: 10px; font-weight: 700; letter-spacing: 0.14em;
  text-transform: uppercase; color: var(--gold);
  padding: 4px 8px; border-radius: 999px;
  background: hsla(237, 70%, 55%, 0.14);
  border: 1px solid hsla(237, 70%, 60%, 0.25);
}
.acd-header .acd-name {
  flex: 1; border: none; outline: none; background: transparent;
  color: var(--text-primary); font-size: 15px; font-weight: 600;
  padding: 6px 8px; border-radius: 6px;
  transition: background 0.15s;
}
.acd-header .acd-name:focus, .acd-header .acd-name:hover {
  background: rgba(255,255,255,0.04);
}
.acd-close {
  width: 28px; height: 28px; border-radius: 8px; border: none;
  background: transparent; color: var(--text-dim); font-size: 14px;
  cursor: pointer; transition: all 0.15s;
  display: flex; align-items: center; justify-content: center;
}
.acd-close:hover { background: #ef4444; color: #fff; }
.acd-body {
  flex: 1; display: grid; grid-template-columns: 1.1fr 1fr;
  overflow: hidden;
}
.acd-chat {
  display: flex; flex-direction: column;
  border-right: 1px solid var(--border);
  overflow: hidden;
}
.acd-messages {
  flex: 1; overflow-y: auto; padding: 18px;
  display: flex; flex-direction: column; gap: 10px;
}
.acd-msg {
  max-width: 85%;
  padding: 10px 14px; border-radius: 14px;
  font-size: 13px; line-height: 1.45;
  color: var(--text-primary);
  white-space: pre-wrap; word-wrap: break-word;
}
.acd-msg.assistant {
  align-self: flex-start;
  background: rgba(255,255,255,0.045);
  border: 1px solid var(--border);
  border-radius: 14px 14px 14px 4px;
}
.acd-msg.user {
  align-self: flex-end;
  background: hsla(237, 70%, 55%, 0.16);
  border: 1px solid hsla(237, 70%, 60%, 0.25);
  border-radius: 14px 14px 4px 14px;
  color: var(--text-primary);
}
.acd-msg.loading {
  font-style: italic; color: var(--text-dim);
  background: transparent; border: none;
}
.acd-msg.error {
  background: rgba(239,68,68,0.1);
  border-color: rgba(239,68,68,0.3);
  color: #fca5a5; font-size: 12px;
}
.acd-input-row {
  display: flex; gap: 8px; padding: 12px;
  border-top: 1px solid var(--border);
  align-items: flex-end;
}
.acd-input {
  flex: 1; background: var(--surface); border: 1px solid var(--border);
  border-radius: 10px;
  color: var(--text-primary);
  font-size: 13px; font-family: var(--font-body);
  padding: 10px 12px; resize: none; outline: none;
  min-height: 40px; max-height: 140px;
  transition: border-color 0.15s;
}
.acd-input:focus { border-color: var(--gold-dim); }
.acd-send {
  background: var(--gold); color: #0c0c14;
  border: none; border-radius: 10px;
  padding: 10px 16px; font-size: 13px; font-weight: 600;
  cursor: pointer; transition: all 0.15s;
  white-space: nowrap;
  box-shadow: 0 4px 14px hsla(237, 70%, 55%, 0.35);
}
.acd-send:hover:not(:disabled) { transform: translateY(-1px); box-shadow: 0 6px 18px hsla(237, 70%, 55%, 0.5); }
.acd-send:disabled { opacity: 0.4; cursor: not-allowed; }
.acd-preview {
  display: flex; flex-direction: column; align-items: center;
  padding: 24px; gap: 16px;
  background:
    radial-gradient(1200px 300px at 50% 0%, rgba(124,138,255,0.06), transparent 60%),
    var(--bg-primary);
  overflow: hidden;
}
.acd-dual-previews {
  flex: 1; display: grid; grid-template-columns: 1fr 1fr; gap: 12px;
  width: 100%; min-height: 0;
}
.acd-preview-col {
  display: flex; flex-direction: column; align-items: center; gap: 8px;
  min-width: 0;
}
.acd-preview-col-label {
  font: 600 10px/1 var(--font-body);
  letter-spacing: 0.14em; text-transform: uppercase;
  color: var(--text-dim);
}
.acd-preview-big {
  flex: 1; display: flex; align-items: center; justify-content: center;
  width: 100%; min-height: 0;
  background:
    linear-gradient(135deg, rgba(0,0,0,0.15), transparent),
    repeating-conic-gradient(rgba(255,255,255,0.018) 0% 25%, transparent 0% 50%) 50% 50% / 24px 24px;
  border-radius: 14px;
  border: 1px solid var(--border);
  overflow: hidden;
  position: relative;
}
.acd-preview-big svg {
  width: 140px; height: 140px;
  filter: drop-shadow(0 6px 20px rgba(0,0,0,0.45));
}
.acd-preview-big.empty { color: var(--text-dim); font-size: 11px; letter-spacing: 0.06em; text-transform: uppercase; }
.acd-preview-mini {
  display: flex; align-items: center; gap: 10px;
  color: var(--text-dim); font-size: 11px;
}
.acd-preview-tiny svg { width: 24px; height: 24px; vertical-align: middle; }
.acd-status {
  font-size: 11px; color: var(--text-dim);
  text-align: center; letter-spacing: 0.04em;
}
.acd-footer {
  display: flex; align-items: center; justify-content: space-between;
  padding: 12px 18px;
  border-top: 1px solid var(--border);
  background: var(--bg-primary);
}
.acd-footer .hint { font-size: 11px; color: var(--text-dim); }
.acd-footer .actions { display: flex; gap: 8px; }
.acd-btn {
  padding: 8px 16px; border-radius: 8px; border: 1px solid var(--border);
  background: transparent; color: var(--text-secondary);
  font-size: 13px; font-weight: 500; cursor: pointer;
  transition: all 0.15s;
}
.acd-btn:hover { border-color: var(--border-hover); color: var(--text-primary); }
.acd-btn.primary {
  background: var(--gold); color: #0c0c14; border-color: var(--gold);
  font-weight: 600;
}
.acd-btn.primary:hover { background: hsl(237, 80%, 65%); }
.acd-btn.primary:disabled {
  background: var(--surface); color: var(--text-dim);
  border-color: var(--border); box-shadow: none; cursor: not-allowed;
  opacity: 0.5;
}

@media (max-width: 760px) {
  .ai-designer .acd-panel {
    width: 100vw; height: 100vh; border-radius: 0;
  }
  .acd-body { grid-template-columns: 1fr; grid-template-rows: 1fr 1fr; }
  .acd-chat { border-right: none; border-bottom: 1px solid var(--border); }
  .acd-preview-big svg { width: 160px; height: 160px; }
}

/* ── Recycle bin drag animation ── */
.recycle-bin {
  position: relative;
  transition: transform 0.2s cubic-bezier(.34,1.56,.64,1), filter 0.3s ease;
}
.recycle-bin .item-icon {
  transition: transform 0.3s cubic-bezier(.34,1.56,.64,1);
}

/* ══════════════════════════════════════════════════════════
   FLOW EDITOR — Ensō-inspired, rebuilt properly
   ══════════════════════════════════════════════════════════ */
#flowEditor {
  display: none; position: fixed; inset: 0; z-index: 8500;
  background: #16161a;
}
#flowEditor.open { display: block; animation: editorFadeIn 0.3s ease both; }

.flow-writing-area {
  position: absolute; inset: 0;
  display: flex; justify-content: center;
  overflow: hidden;
}
#flowTextarea {
  width: 100%; max-width: 620px; height: 100%;
  background: transparent; border: none; outline: none; resize: none;
  /* position:relative so z-index applies — keeps the caret above the
   * mirror layer when censor mode is active. */
  position: relative; z-index: 2;
  font-family: 'EB Garamond', Georgia, 'Times New Roman', serif;
  font-size: 28px; line-height: 1.8; color: #ebe7dc;
  padding: 0 40px 40vh 40px;
  padding-top: 50vh;
  caret-color: #34d399;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-rendering: optimizeLegibility;
  text-rendering: geometricPrecision;
  overflow-y: scroll;
  scrollbar-width: none;
  letter-spacing: 0.01em;
}
#flowTextarea::-webkit-scrollbar { display: none; }
#flowTextarea::placeholder { color: rgba(255,255,255,0.08); font-style: italic; letter-spacing: 0.03em; }
#flowTextarea::selection { background: transparent; }
/* Censor mode (partial OR private) — textarea text becomes transparent so the
 * mirror layer below renders the censored version. Caret stays visible so
 * the user can still see where they're typing. */
#flowTextarea.censor-active {
  color: transparent !important;
}
#flowEditor.light #flowTextarea.censor-active { color: transparent !important; }

/* Mirror layer — sits behind the (transparent) textarea text and renders the
 * censored / partially-visible version. Spaces and newlines pass through;
 * non-whitespace chars become discs (●). When inactive: display:none. */
.flow-mirror {
  position: absolute; top: 0; left: 50%; transform: translateX(-50%);
  width: 100%; max-width: 620px; height: 100%;
  font-family: 'EB Garamond', Georgia, 'Times New Roman', serif;
  font-size: 28px; line-height: 1.8;
  padding: 50vh 40px 40vh 40px;
  letter-spacing: 0.01em;
  color: rgba(255,255,255,0.15);
  white-space: pre-wrap;
  word-wrap: break-word;
  overflow-y: scroll;
  scrollbar-width: none;
  pointer-events: none;
  z-index: 1;
  display: none;
  box-sizing: border-box;
  -webkit-font-smoothing: antialiased;
  text-rendering: geometricPrecision;
}
.flow-mirror::-webkit-scrollbar { display: none; }
.flow-mirror.active { display: block; }
.flow-mirror .visible-line {
  color: #ebe7dc;
}
#flowEditor.light .flow-mirror { color: rgba(0,0,0,0.12); }
#flowEditor.light .flow-mirror .visible-line { color: #1a1a1a; }

/* Overlay fade — covers top portion, text scrolls up underneath */
.flow-fade-overlay {
  position: absolute; top: 0; left: 0; right: 0; z-index: 2;
  pointer-events: none;
  height: 48vh;
  background: linear-gradient(
    to bottom,
    #16161a 0%,
    #16161a 40%,
    rgba(22,22,26,0.96) 58%,
    rgba(22,22,26,0.85) 70%,
    rgba(22,22,26,0.55) 82%,
    rgba(22,22,26,0.20) 92%,
    rgba(22,22,26,0) 100%
  );
}
.flow-fade-span { display: none; }

/* Light mode fade */
#flowEditor.light .flow-fade-overlay {
  background: linear-gradient(
    to bottom,
    #fafaf8 0%, #fafaf8 40%,
    rgba(250,250,248,0.96) 58%,
    rgba(250,250,248,0.85) 70%,
    rgba(250,250,248,0.55) 82%,
    rgba(250,250,248,0.20) 92%,
    rgba(250,250,248,0) 100%
  );
}

/* UI layer — Ensō-style: visible on mouse move, hidden on typing */
.flow-ui {
  position: absolute; inset: 0; z-index: 3;
  pointer-events: none;
  opacity: 0;
  transition: opacity 0.5s ease;
}

/* Top-right toolbar */
.flow-toolbar {
  position: absolute; top: 16px; right: 16px;
  display: flex; gap: 6px; align-items: center;
}
.flow-tool-btn {
  width: 36px; height: 36px; border-radius: 8px;
  border: 1px solid rgba(255,255,255,0.08);
  background: rgba(255,255,255,0.04);
  color: rgba(255,255,255,0.5);
  display: flex; align-items: center; justify-content: center;
  cursor: pointer; transition: all 0.2s; font-size: 16px;
}
.flow-tool-btn:hover { color: rgba(255,255,255,0.85); background: rgba(255,255,255,0.08); }
.flow-tool-btn svg { width: 18px; height: 18px; pointer-events: none; }
#flowEditor.light .flow-tool-btn {
  border-color: rgba(0,0,0,0.06); background: rgba(0,0,0,0.03); color: rgba(0,0,0,0.35);
}
#flowEditor.light .flow-tool-btn:hover { color: rgba(0,0,0,0.7); background: rgba(0,0,0,0.06); }

/* Always-visible persistent bar */
.flow-persistent {
  position: absolute; bottom: 14px; left: 28px; z-index: 4;
  display: flex; align-items: center; gap: 14px;
  pointer-events: none;
}
.flow-wordcount {
  font-size: 18px; font-weight: 300; color: rgba(255,255,255,0.15);
  font-family: 'JetBrains Mono', monospace;
  font-variant-numeric: tabular-nums;
  letter-spacing: 0.05em;
}
#flowEditor.light .flow-wordcount { color: rgba(0,0,0,0.15); }
.flow-coffeeshop-indicator {
  font-size: 10px; font-weight: 600; color: #34d399; opacity: 0;
  letter-spacing: 0.05em;
  transition: opacity 0.3s;
}
.flow-coffeeshop-indicator.active { opacity: 1; }

/* ══════════════════════════════════════════════════════════════════════
   Privacy Controls — mobile, default-collapsed to right edge
   ──────────────────────────────────────────────────────────────────────
   Stays out of the way until summoned. Two elements cooperate:
     ─ .flow-privacy-stash   — small circular glass button on right edge,
                               always visible, shows current mode icon.
     ─ .flow-privacy-seg     — the 3-segment pill. Off-screen right by
                               default (data-collapsed="1"). Slides in
                               on stash-tap or right-edge swipe-in.
   After a segment commit, seg auto-collapses (400ms).
   Hidden on desktop (keyboard Shift+Shift still works there). */

/* Stash handle — bottom-right, glass, same vertical anchor as the pill. */
.flow-privacy-stash {
  display: none;  /* mobile-only */
  position: absolute;
  right: calc(14px + env(safe-area-inset-right, 0));
  bottom: calc(22px + env(safe-area-inset-bottom, 0) + var(--foton-kb-lift, 0px));
  z-index: 5;
  width: 44px; height: 44px;
  padding: 0;
  background: rgba(20, 20, 24, 0.72);
  backdrop-filter: blur(22px) saturate(1.4);
  -webkit-backdrop-filter: blur(22px) saturate(1.4);
  border: 1px solid rgba(255, 255, 255, 0.08);
  border-radius: 999px;
  color: rgba(255, 255, 255, 0.78);
  box-shadow: 0 8px 22px rgba(0, 0, 0, 0.45),
              inset 0 1px 0 rgba(255, 255, 255, 0.08);
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
  transition: opacity 220ms cubic-bezier(.4, 0, .2, 1),
              transform 220ms cubic-bezier(.4, 0, .2, 1),
              background 240ms, border-color 240ms, color 240ms;
}
body.mobile #flowEditor .flow-privacy-stash { display: inline-flex; align-items: center; justify-content: center; }
.flow-privacy-stash svg { width: 20px; height: 20px; }
.flow-privacy-stash:active { transform: scale(0.92); }
.flow-privacy-stash[data-mode="partial"] {
  color: rgba(230, 178, 124, 0.95);
  border-color: rgba(204, 148, 94, 0.35);
  background: rgba(48, 34, 24, 0.72);
}
.flow-privacy-stash[data-mode="private"] {
  color: rgba(168, 178, 255, 0.95);
  border-color: rgba(124, 138, 255, 0.38);
  background: rgba(32, 34, 58, 0.78);
}
/* When seg is open, the stash fades away so the pill owns the edge. */
.flow-privacy-stash[data-open="1"] {
  opacity: 0;
  pointer-events: none;
  transform: translateX(12px);
}

/* Segmented control — off-screen right when collapsed. */
.flow-privacy-seg {
  display: none;
  position: absolute;
  right: calc(12px + env(safe-area-inset-right, 0));
  bottom: calc(22px + env(safe-area-inset-bottom, 0) + var(--foton-kb-lift, 0px));
  z-index: 6;
  padding: 4px;
  background: rgba(20, 20, 24, 0.82);
  backdrop-filter: blur(28px) saturate(1.4);
  -webkit-backdrop-filter: blur(28px) saturate(1.4);
  border: 1px solid rgba(255, 255, 255, 0.06);
  border-radius: 999px;
  box-shadow: 0 12px 34px rgba(0, 0, 0, 0.55),
              inset 0 1px 0 rgba(255, 255, 255, 0.06);
  gap: 0;
  touch-action: none;
  user-select: none;
  -webkit-user-select: none;
  transform-origin: calc(100% - 26px) 50%;
  transition: transform 320ms cubic-bezier(.32, .72, 0, 1),
              opacity 260ms cubic-bezier(.4, 0, .2, 1);
}
body.mobile #flowEditor .flow-privacy-seg { display: inline-flex; align-items: center; }
/* Collapsed: tucked off the right edge + slightly shrunk. The scale/x
 * combo gives a subtle "folding into the stash" feel, not a flat slide. */
.flow-privacy-seg[data-collapsed="1"] {
  transform: translateX(calc(100% + 32px)) scale(0.6);
  opacity: 0;
  pointer-events: none;
}
.flow-privacy-seg[data-collapsed="0"] {
  transform: translateX(0) scale(1);
  opacity: 1;
  pointer-events: auto;
}

.flow-privacy-seg .fps-seg {
  position: relative;
  flex: 0 0 auto;
  min-width: 88px; height: 44px;
  padding: 0 14px;
  display: inline-flex; align-items: center; justify-content: center; gap: 6px;
  background: transparent;
  border: 0;
  border-radius: 999px;
  color: rgba(255, 255, 255, 0.58);
  font: 600 12px/1 var(--font-body, 'DM Sans', ui-sans-serif);
  letter-spacing: 0.03em;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
  transition: color 180ms cubic-bezier(.4, 0, .2, 1),
              transform 180ms cubic-bezier(.4, 0, .2, 1);
  z-index: 2;   /* above the sliding thumb */
}
.flow-privacy-seg .fps-seg svg {
  width: 16px; height: 16px;
  opacity: 0.85;
  transition: opacity 180ms;
}
.flow-privacy-seg .fps-seg .fps-label {
  font-weight: 600;
  white-space: nowrap;
}
.flow-privacy-seg .fps-seg[aria-checked="true"] {
  color: #fff;
}
.flow-privacy-seg .fps-seg[aria-checked="true"] svg { opacity: 1; }

/* Sliding thumb — absolute-positioned pill behind the active seg. */
.flow-privacy-seg .fps-thumb {
  position: absolute;
  top: 4px; bottom: 4px;
  left: 4px;
  width: 88px;
  border-radius: 999px;
  background: linear-gradient(180deg, rgba(255, 255, 255, 0.13), rgba(255, 255, 255, 0.06));
  border: 1px solid rgba(255, 255, 255, 0.12);
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.4),
              inset 0 1px 0 rgba(255, 255, 255, 0.12);
  transition: transform 280ms cubic-bezier(.32, .72, 0, 1),
              background 240ms, border-color 240ms;
  z-index: 1;
  pointer-events: none;
}
.flow-privacy-seg[data-pos="0"] .fps-thumb { transform: translateX(0); }
.flow-privacy-seg[data-pos="1"] .fps-thumb {
  transform: translateX(88px);
  background: linear-gradient(180deg, rgba(204, 148, 94, 0.32), rgba(204, 148, 94, 0.18));
  border-color: rgba(204, 148, 94, 0.38);
}
.flow-privacy-seg[data-pos="2"] .fps-thumb {
  transform: translateX(176px);
  background: linear-gradient(180deg, rgba(124, 138, 255, 0.38), rgba(124, 138, 255, 0.22));
  border-color: rgba(124, 138, 255, 0.45);
}
.flow-privacy-seg.dragging .fps-thumb { transition: transform 90ms linear; }

/* Panic flash — whole editor briefly pulses toward private accent. */
.flow-privacy-seg.panic { animation: fps-panic-pulse 380ms ease-out; }
@keyframes fps-panic-pulse {
  0%   { box-shadow: 0 10px 30px rgba(0, 0, 0, 0.5),
                     inset 0 1px 0 rgba(255, 255, 255, 0.06),
                     0 0 0 0 rgba(124, 138, 255, 0.55); }
  60%  { box-shadow: 0 10px 30px rgba(0, 0, 0, 0.5),
                     inset 0 1px 0 rgba(255, 255, 255, 0.06),
                     0 0 0 22px rgba(124, 138, 255, 0.0); }
  100% { box-shadow: 0 10px 30px rgba(0, 0, 0, 0.5),
                     inset 0 1px 0 rgba(255, 255, 255, 0.06); }
}
/* Censor wave overlay — a soft gradient mask that sweeps down when
 * entering a censored mode, and up when leaving. Uses backdrop-filter
 * to blur the text behind as it passes. */
.flow-censor-wave {
  position: absolute;
  top: 0; left: 0; right: 0;
  height: 0;
  z-index: 4;  /* above mirror + fade; below flow-ui and privacy-seg */
  pointer-events: none;
  background: linear-gradient(
    180deg,
    rgba(22, 22, 26, 0.0) 0%,
    rgba(22, 22, 26, 0.65) 60%,
    rgba(22, 22, 26, 0.9)  100%
  );
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
  opacity: 0;
}
.flow-censor-wave.sweep-down { animation: fcw-sweep-down 620ms cubic-bezier(.32, .72, 0, 1) forwards; }
.flow-censor-wave.sweep-up   { animation: fcw-sweep-up   480ms cubic-bezier(.4, 0, .2, 1) forwards; }
@keyframes fcw-sweep-down {
  0%   { height: 0;    opacity: 0;   }
  8%   { opacity: 1;   }
  100% { height: 100%; opacity: 0;   }
}
@keyframes fcw-sweep-up {
  0%   { height: 100%; opacity: 1;   top: auto; bottom: 0; }
  100% { height: 0;    opacity: 0;   top: auto; bottom: 0; }
}
#flowEditor.light .flow-censor-wave {
  background: linear-gradient(
    180deg,
    rgba(250, 250, 248, 0.0) 0%,
    rgba(250, 250, 248, 0.70) 60%,
    rgba(250, 250, 248, 0.92) 100%
  );
}

/* Ambient privacy glow — subtle colored edge on editor while in a
 * censored mode. Apple Focus-mode vibe. */
#flowEditor.privacy-partial::after,
#flowEditor.privacy-private::after {
  content: '';
  position: absolute; inset: 0;
  pointer-events: none;
  z-index: 6;
  border-radius: inherit;
  box-shadow: inset 0 0 0 1px rgba(255,255,255,0.02),
              inset 0 0 32px rgba(204, 148, 94, 0.08);
  transition: box-shadow 420ms ease;
}
#flowEditor.privacy-private::after {
  box-shadow: inset 0 0 0 1px rgba(124, 138, 255, 0.18),
              inset 0 0 48px rgba(124, 138, 255, 0.14);
}

@media (prefers-reduced-motion: reduce) {
  .flow-privacy-seg .fps-thumb { transition-duration: 1ms !important; }
  .flow-privacy-seg { transition-duration: 1ms !important; }
  .flow-privacy-stash { transition-duration: 1ms !important; }
  .flow-censor-wave.sweep-down,
  .flow-censor-wave.sweep-up { animation-duration: 1ms !important; opacity: 0 !important; }
  .flow-privacy-seg.panic { animation: none; }
}

/* Fadeable hint */
.flow-hint {
  position: absolute; bottom: 14px; right: 28px;
}
.flow-coffeeshop-hint {
  font-size: 11px; color: rgba(255,255,255,0.12);
  font-family: 'Outfit', sans-serif;
  font-style: italic;
  transition: opacity 0.3s;
}
.flow-coffeeshop-hint.hidden { opacity: 0; }

/* Light mode overrides for persistent */
#flowEditor.light .flow-coffeeshop-hint { color: rgba(0,0,0,0.1); }

/* ── Light mode ── */
#flowEditor.light {
  background: #fafaf8;
}
#flowEditor.light #flowTextarea {
  color: #2c2c2c;
  caret-color: #22a66e;
}
#flowEditor.light #flowTextarea::placeholder { color: rgba(0,0,0,0.08); }
#flowEditor.light .flow-fade-overlay {
  background: linear-gradient(
    to bottom,
    #fafaf8 0%, #fafaf8 40%,
    rgba(250,250,248,0.97) 55%,
    rgba(250,250,248,0.90) 68%,
    rgba(250,250,248,0.75) 80%,
    rgba(250,250,248,0.45) 90%,
    rgba(250,250,248,0) 100%
  );
}
#flowEditor.light .flow-tool-btn { color: rgba(0,0,0,0.2); }
#flowEditor.light .flow-tool-btn:hover { color: rgba(0,0,0,0.5); }
#flowEditor.light .flow-streak-glow {
  background: radial-gradient(ellipse at 50% 100%, rgba(22,166,110,0.03) 0%, transparent 70%);
}
#flowEditor.light .flow-breathing-dot { background: rgba(22,166,110,0.4); }
#flowEditor.light #flowTextarea.coffeeshop { color: rgba(0,0,0,0.15); }

/* Streak glow — edge glow when writing continuously */
.flow-streak-glow {
  position: absolute; inset: 0; z-index: 1; pointer-events: none;
  opacity: 0; transition: opacity 0.8s ease-in;
  background: radial-gradient(ellipse at 50% 100%, rgba(52,211,153,0.02) 0%, transparent 70%);
}
.flow-streak-glow.active {
  opacity: 1;
  transition: opacity 2s ease-out;
}

/* Breathing dot */
.flow-breathing {
  position: absolute; bottom: 48px; right: 28px; z-index: 3;
  pointer-events: none; opacity: 0.08;
}
.flow-breathing-dot {
  width: 4px; height: 4px; border-radius: 50%;
  background: rgba(52,211,153,0.5);
  animation: flowBreathe 12s ease-in-out infinite;
}
@keyframes flowBreathe {
  0%, 100% { transform: scale(1); opacity: 0.4; }
  50% { transform: scale(2); opacity: 1; }
}

/* Session separator (rendered in textarea content) */

/* ══════════════════════════════════════════════════════════
   NOTE EDITOR — clean reading/writing surface
   ──────────────────────────────────────────────────────────
   Design: single centered column (760px max) on a warm-black
   canvas. No heavy chrome — just a floating close/preview chip
   top-right, a tiny word-count bottom-right, and a chrome that
   fades while typing (Ensō). Title is an editable H1 inline at
   the top of the document, not in a toolbar. Sans-serif Inter
   throughout — serious, readable, Obsidian-grade.
   ══════════════════════════════════════════════════════════ */

/* Local, scoped token layer.
 *
 * Phase 2 (multi-instance) hoists every token onto `.note-editor-host`,
 * a class shared by the legacy fullscreen `#noteEditor` AND every cloned
 * `.wm-note-pane` mounted inside a tiling pane. Layout-specific rules
 * (display, position, z-index, background) stay scoped to each mode. */
.note-editor-host {
  --nd-bg:        #111113;                 /* warm near-black canvas */
/* paper card (barely there) */
  --nd-text:      #e8e6e0;                 /* off-white, reduces eye-strain */
  --nd-text-dim:  rgba(232,230,224,0.58);  /* muted secondary */
  --nd-text-fade: rgba(232,230,224,0.32);  /* comment / marker level */
  --nd-accent:    #8a94ff;                 /* indigo, harmonises with app */
  --nd-accent-dim:rgba(138,148,255,0.35);
  --nd-rule:      rgba(255,255,255,0.05);  /* hairline separators */
  --nd-doc-max:   760px;
  --nd-body-font: 'Inter', -apple-system, BlinkMacSystemFont, system-ui, 'Segoe UI', sans-serif;
  --nd-mono-font: 'JetBrains Mono', ui-monospace, SFMono-Regular, Menlo, monospace;

  /* Paper vs canvas: the CANVAS is the wider dark surround. The PAPER is
   * a slightly lighter card floating in the middle, wearing the document
   * column. Gives the eye a place to land and signals "this is where
   * words live". Subtle — 6% lightness shift — so it reads as materiality
   * rather than a box. */
  --nd-canvas:      #0c0c0e;
  --nd-paper:       #14141a;
  --nd-paper-edge:  rgba(255, 255, 255, 0.045);
  --nd-paper-glow:  rgba(138, 148, 255, 0.05);

  flex-direction: column;
}

/* Legacy single-pane mode — full-viewport overlay above the desktop. */
#noteEditor {
  display: none; position: fixed; inset: 0; z-index: 8500;
  background: var(--nd-canvas);
}
#noteEditor.open { display: flex; animation: editorFadeIn 0.28s cubic-bezier(.32,.72,0,1) both; }

/* WM-pane mode — fills its pane content area inside the tiling host. */
.wm-note-pane {
  display: flex;
  position: absolute;
  inset: 0;
  background: var(--nd-canvas);
  /* The WM pane already exposes a close affordance in its tab strip;
   * the chip-row close inside the cloned editor would be redundant.
   * Preview toggle stays — there is no WM equivalent. */
}
.wm-note-pane .note-chip-row .note-close-btn { display: none; }
/* Inside a WM pane, the doc area takes the visible space + scrolls
 * naturally with no fullscreen positioning fights. */
.wm-note-pane .note-body { position: relative; }

/* Body-level marker — the WM app shell adds this when the tiling host
 * is active, so we can hide every legacy fullscreen surface that would
 * otherwise sit on top.
 *
 * The `:not(.wm-hosted)` qualifier matters for the slab + flow editors:
 * those singletons are TRANSPLANTED into a WM pane, where they keep
 * their `.open` class (legacy openX() set it). Hosted instances must
 * stay visible — only NON-hosted opens are stale legacy state. */
body.gds-wm-active #desktop,
body.gds-wm-active #routeIndicator,
body.gds-wm-active #noteEditor.open:not(.wm-hosted),
body.gds-wm-active #slabEditor.open:not(.wm-hosted),
body.gds-wm-active #flowEditor.open:not(.wm-hosted) { display: none !important; }
body.gds-wm-active #wm-root { display: block; }

/* Transplanted singleton editors fit their pane container instead of
 * covering the viewport. The position + z-index reset cancels the
 * legacy `position: fixed; inset: 0; z-index: 8500` so the WM pane
 * stack stays the source of truth for compositing order. */
.wm-hosted {
  position: absolute !important;
  inset: 0 !important;
  z-index: auto !important;
  /* Overflow stays whatever the editor wants (slab uses overflow:hidden
   * inside its canvas wrapper; flow uses scrollable textarea). The
   * WM pane content area itself has overflow:hidden so the editor
   * can't bleed past pane boundaries. */
}

/* WM root — the tiling host's mount point. Sits between the desktop
 * (z 4998) and chrome surfaces like the presence bar (z ≥ 8499) so
 * floating peer cursors continue to read above. */
#wm-root[hidden] { display: none; }
#wm-root {
  position: fixed;
  inset: 0;
  z-index: 8400;
  background: var(--nd-canvas, #0c0c0e);
  contain: layout style paint;
}

/* WM chrome — workspaces bar + follow-peer indicator. Floats top-center
 * so it doesn't steal pane real estate. Pointer events on for the bar
 * itself; transparent gap underneath lets pane interactions through. */
.gds-wm-chrome {
  position: absolute;
  top: 6px;
  left: 50%;
  transform: translateX(-50%);
  z-index: 8500;
  display: flex; gap: 8px; align-items: center;
  pointer-events: auto;
}

/* Always-visible "Exit tile mode" button.  Sits to the right of the
 * workspace bar inside the chrome.  Same pill aesthetic as the
 * workspace chips so it doesn't read as alien chrome. */
.gds-wm-exit-btn {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 4px 10px 4px 8px;
  background: rgba(20, 20, 28, 0.78);
  border: 1px solid rgba(255, 255, 255, 0.08);
  border-radius: 999px;
  backdrop-filter: blur(18px) saturate(140%);
  -webkit-backdrop-filter: blur(18px) saturate(140%);
  color: rgba(255, 255, 255, 0.78);
  font-family: 'Inter', system-ui, sans-serif;
  font-size: 12px;
  letter-spacing: 0.005em;
  cursor: pointer;
  transition: background 120ms ease, color 120ms ease, border-color 120ms ease;
}
.gds-wm-exit-btn:hover {
  background: rgba(40, 40, 52, 0.9);
  color: #fff;
  border-color: rgba(255, 255, 255, 0.18);
}
.gds-wm-exit-btn:focus-visible {
  outline: 2px solid rgba(120, 180, 255, 0.6);
  outline-offset: 2px;
}
.gds-wm-exit-btn svg { display: block; }
.gds-wm-exit-label { font-weight: 500; }

/* Bento UX: single-tab leaves drop their tab strip so the tile reads
 * as a clean document slab. Multi-tab leaves keep the strip. Uses
 * :has() — Chromium 105+ / Firefox 121+ / Safari 15.4+. Older
 * browsers fall through and just show a degenerate strip with one
 * chip, which is the v0 behavior. */
.gds-wm-pane-inner > .gds-wm-tab-strip:has(> .gds-wm-tab:only-child) {
  display: none;
}

/* Tiny floating hint that surfaces after the FIRST Esc when an
 * editor / autocomplete swallowed the keypress. Tells the user a
 * second Esc will exit. Auto-dismisses after the double-tap window
 * (1200ms by default). */
.gds-wm-esc-hint {
  position: fixed;
  bottom: 24px;
  left: 50%;
  transform: translateX(-50%);
  z-index: 9999;
  padding: 8px 14px;
  background: rgba(20, 20, 28, 0.92);
  color: #fff;
  border: 1px solid rgba(255, 255, 255, 0.1);
  border-radius: 8px;
  backdrop-filter: blur(18px) saturate(140%);
  -webkit-backdrop-filter: blur(18px) saturate(140%);
  font-family: 'Inter', system-ui, sans-serif;
  font-size: 13px;
  letter-spacing: 0.005em;
  pointer-events: none;
  animation: gds-wm-esc-hint-fade 200ms ease-out;
}
@keyframes gds-wm-esc-hint-fade {
  from { opacity: 0; transform: translate(-50%, 6px); }
  to   { opacity: 1; transform: translate(-50%, 0); }
}
.gds-wm-workspaces {
  display: inline-flex; gap: 4px; align-items: center;
  padding: 4px 6px;
  background: rgba(20, 20, 28, 0.78);
  border: 1px solid rgba(255, 255, 255, 0.06);
  border-radius: 999px;
  backdrop-filter: blur(18px) saturate(140%);
  -webkit-backdrop-filter: blur(18px) saturate(140%);
  font-family: 'Inter', system-ui, sans-serif;
  font-size: 12px;
  letter-spacing: 0.005em;
}
.gds-wm-workspace-chip {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 4px 10px;
  border-radius: 999px;
  color: rgba(232, 234, 246, 0.78);
  cursor: pointer;
  user-select: none;
  transition: background-color 120ms, color 120ms;
}
.gds-wm-workspace-chip:hover { background: rgba(124, 138, 255, 0.12); color: #eef0ff; }
.gds-wm-workspace-chip.is-active {
  background: rgba(124, 138, 255, 0.22);
  color: #eef0ff;
  box-shadow: inset 0 0 0 1px rgba(124, 138, 255, 0.45);
}
.gds-wm-workspace-chip .kbd {
  font-family: 'JetBrains Mono', ui-monospace, monospace;
  font-size: 10.5px;
  opacity: 0.55;
  padding: 1px 4px;
  background: rgba(255, 255, 255, 0.05);
  border-radius: 4px;
}
.gds-wm-workspace-chip .close {
  margin-left: 2px;
  width: 16px; height: 16px;
  display: inline-flex; align-items: center; justify-content: center;
  border-radius: 999px;
  font-size: 14px; line-height: 1;
  color: rgba(232, 234, 246, 0.45);
  cursor: pointer;
}
.gds-wm-workspace-chip .close:hover { color: #ff9b9b; background: rgba(255, 80, 80, 0.18); }
.gds-wm-workspace-add {
  display: inline-flex; align-items: center; justify-content: center;
  width: 26px; height: 26px;
  border-radius: 999px;
  color: rgba(232, 234, 246, 0.55);
  cursor: pointer;
  font-size: 14px;
  margin-left: 2px;
  transition: background-color 120ms, color 120ms;
}
.gds-wm-workspace-add:hover { background: rgba(124, 138, 255, 0.16); color: #eef0ff; }

/* Follow-peer status chip — sits to the right of the workspace bar
 * inside .gds-wm-chrome. Tinted amber so it reads as "external state
 * driving you" rather than just another workspace. */
.gds-wm-follow-chip {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 4px 8px 4px 10px;
  background: rgba(240, 168, 92, 0.12);
  border: 1px solid rgba(240, 168, 92, 0.32);
  border-radius: 999px;
  color: #f4d6a3;
  font-family: 'Inter', system-ui, sans-serif;
  font-size: 12px;
  cursor: pointer;
  backdrop-filter: blur(18px) saturate(140%);
  -webkit-backdrop-filter: blur(18px) saturate(140%);
}
.gds-wm-follow-chip .gds-wm-follow-arrow {
  font-family: 'JetBrains Mono', ui-monospace, monospace;
  opacity: 0.7;
}
.gds-wm-follow-chip .gds-wm-follow-name { font-weight: 600; }
.gds-wm-follow-chip .gds-wm-follow-stop {
  width: 18px; height: 18px;
  display: inline-flex; align-items: center; justify-content: center;
  border-radius: 999px;
  background: transparent; border: 0; color: inherit;
  cursor: pointer;
  font-size: 14px; line-height: 1;
}
.gds-wm-follow-chip .gds-wm-follow-stop:hover { background: rgba(240, 168, 92, 0.20); }
body.gds-wm-following .gds-wm-host { box-shadow: inset 0 0 0 1px rgba(240, 168, 92, 0.45); }

/* WM toggle button removed — see N1. Replacement: per-document
 * split-right button (.gds-split-right-btn) defined further below. */

/* Phase 10 — undo/redo chips inside .gds-wm-chrome. Disabled state
 * dims and disables clicks. */
.gds-wm-history-bar {
  display: inline-flex; gap: 2px; align-items: center;
  padding: 4px 4px;
  background: rgba(20, 20, 28, 0.78);
  border: 1px solid rgba(255, 255, 255, 0.06);
  border-radius: 999px;
  backdrop-filter: blur(18px) saturate(140%);
  -webkit-backdrop-filter: blur(18px) saturate(140%);
}
.gds-wm-history-chip {
  width: 28px; height: 28px;
  display: inline-flex; align-items: center; justify-content: center;
  border: 0; background: transparent;
  color: rgba(232, 234, 246, 0.78);
  cursor: pointer;
  border-radius: 999px;
  font-size: 14px; line-height: 1;
  font-family: 'JetBrains Mono', ui-monospace, monospace;
  transition: background-color 120ms, color 120ms;
}
.gds-wm-history-chip:hover:not([disabled]) {
  background: rgba(124, 138, 255, 0.14);
  color: #eef0ff;
}
.gds-wm-history-chip[disabled] {
  opacity: 0.32;
  cursor: not-allowed;
}

/* Phase 10 — first-run onboarding overlay. Centered glass card with
 * the essential shortcuts; dismissed via "Got it" button or Esc. */
#gds-wm-onboarding {
  position: fixed;
  inset: 0;
  z-index: 9400;
  display: flex; align-items: center; justify-content: center;
  background: rgba(8, 9, 14, 0.55);
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
  animation: gdsWmOnbFade 220ms cubic-bezier(.22,1,.36,1);
}
@keyframes gdsWmOnbFade { from { opacity: 0; } to { opacity: 1; } }
#gds-wm-onboarding .card {
  width: min(440px, 90vw);
  background: rgba(18, 19, 28, 0.96);
  border: 1px solid rgba(255, 255, 255, 0.08);
  border-radius: 14px;
  padding: 28px 28px 22px;
  font-family: 'Inter', system-ui, sans-serif;
  color: rgba(232, 234, 246, 0.92);
  box-shadow: 0 28px 60px -20px rgba(0, 0, 0, 0.5);
}
#gds-wm-onboarding .title {
  font-size: 18px;
  font-weight: 600;
  letter-spacing: -0.01em;
  margin: 0 0 8px;
}
#gds-wm-onboarding .sub {
  font-size: 13.5px;
  color: rgba(188, 192, 210, 0.78);
  margin: 0 0 18px;
  line-height: 1.5;
}
#gds-wm-onboarding .shortcuts {
  list-style: none;
  margin: 0 0 18px;
  padding: 0;
  display: flex; flex-direction: column; gap: 8px;
}
#gds-wm-onboarding .shortcuts li {
  display: flex; gap: 12px; align-items: baseline;
  font-size: 13px;
}
#gds-wm-onboarding .shortcuts kbd {
  font-family: 'JetBrains Mono', ui-monospace, monospace;
  font-size: 11.5px;
  padding: 2px 6px;
  background: rgba(255, 255, 255, 0.05);
  border: 1px solid rgba(255, 255, 255, 0.08);
  border-radius: 4px;
  color: rgba(232, 234, 246, 0.92);
  white-space: nowrap;
  min-width: 110px;
  text-align: center;
}
#gds-wm-onboarding .shortcuts span { color: rgba(188, 192, 210, 0.85); }
#gds-wm-onboarding .actions {
  display: flex; justify-content: flex-end; gap: 8px;
}
#gds-wm-onboarding button.primary {
  background: rgba(124, 138, 255, 0.20);
  border: 1px solid rgba(124, 138, 255, 0.45);
  color: #eef0ff;
  padding: 7px 16px;
  border-radius: 7px;
  font-family: inherit;
  font-size: 13px;
  font-weight: 500;
  cursor: pointer;
  transition: background-color 120ms;
}
#gds-wm-onboarding button.primary:hover {
  background: rgba(124, 138, 255, 0.28);
}

/* ── Document body: scrolls the whole writing area. ── */
.note-body {
  flex: 1;
  position: relative;
  overflow-y: auto;
  overflow-x: hidden;
  scroll-behavior: smooth;
  /* Small-caps-quality font rendering. */
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-rendering: optimizeLegibility;
  font-feature-settings: "kern" 1, "liga" 1, "calt" 1, "ss01" 1;
}
.note-body::-webkit-scrollbar { width: 8px; }
.note-body::-webkit-scrollbar-track { background: transparent; }
.note-body::-webkit-scrollbar-thumb { background: rgba(255,255,255,0.04); border-radius: 8px; }
.note-body::-webkit-scrollbar-thumb:hover { background: rgba(255,255,255,0.09); }

/* The paper card — the floating writing surface. Everything the user
 * types lives inside this box: title, CM6 editor, preview. The card
 * itself has a subtle tint lift from canvas (barely 6% lighter), a
 * hairline edge, and a large soft drop shadow that makes it read as a
 * physical piece of paper resting on the dark desk.
 *
 * Width target: doc-column (760px) + horizontal padding (56px each side) = 872px.
 * We add a small outer margin so the edge is visible against the canvas.
 */
.note-doc {
  position: relative;
  background: var(--nd-paper);
  border: 1px solid var(--nd-paper-edge);
  /* Sharp corners — Obsidian-style. Gives the surface a "serious
   * editor" feel; rounded corners stay on buttons + panels. */
  border-radius: 0;
  box-shadow:
    0 24px 60px rgba(0, 0, 0, 0.36),
    0 2px 12px rgba(0, 0, 0, 0.18),
    inset 0 1px 0 rgba(255, 255, 255, 0.03);
  max-width: calc(var(--nd-doc-max) + 112px);  /* doc column + padding */
  margin: 18px auto 40vh;  /* gap under toolbar, breathing room below */
  padding: 64px 56px 80px;  /* tight top, generous bottom for end-of-doc feel */
  font-family: var(--nd-body-font);
  font-size: 17px;
  line-height: 1.7;
  color: var(--nd-text);
  letter-spacing: -0.003em;
}
/* Subtle column accent at the very left edge of the paper — signals
 * "this is the writing surface" without another full border. */
.note-doc::before {
  content: "";
  position: absolute;
  left: 0; top: 24px; bottom: 24px;
  width: 2px;
  background: linear-gradient(180deg,
    transparent 0%,
    var(--nd-paper-glow) 12%,
    var(--nd-paper-glow) 88%,
    transparent 100%);
  border-radius: 2px;
  pointer-events: none;
}

/* Editable H1 title — inline, prominent, no chrome around it. */
.note-doc-title {
  display: block;
  font-family: var(--nd-body-font);
  font-size: 42px;
  font-weight: 700;
  line-height: 1.12;
  letter-spacing: -0.02em;
  color: var(--nd-text);
  background: transparent;
  border: none; outline: none;
  padding: 0;
  margin: 0 0 28px;
  width: 100%;
  resize: none;
  overflow: hidden;
  min-height: 1.12em;
  caret-color: var(--nd-accent);
}
.note-doc-title:empty::before {
  content: attr(data-placeholder);
  color: var(--nd-text-fade);
  pointer-events: none;
}

/* The writing surface — a textarea, but dressed to feel like typewriter
 * paper. Auto-grows via JS (set height to scrollHeight on input). */
.note-textarea {
  display: block;
  width: 100%;
  min-height: 60vh;
  background: transparent;
  border: 0; outline: none; resize: none;
  padding: 0;
  margin: 0;
  font-family: var(--nd-body-font);
  font-size: 17px;
  line-height: 1.7;
  color: var(--nd-text);
  letter-spacing: -0.003em;
  caret-color: var(--nd-accent);
  tab-size: 2;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-rendering: geometricPrecision;
}
.note-textarea::placeholder {
  color: var(--nd-text-fade);
  font-style: italic;
  letter-spacing: 0.005em;
}
.note-textarea::selection { background: rgba(138,148,255,0.22); }

/* CodeMirror 6 mount host. The `.cm-editor` root CM6 injects here is
 * themed in boot.mjs (transparent background, Inter typography, 760px
 * writing column). This rule just guarantees the host is a clean block
 * container with no intrinsic sizing — CM6 handles everything else. */
.note-cm-host {
  display: block;
  width: 100%;
  /* CM6 needs a non-zero height when `.cm-scroller` has overflow:visible
   * so the caret can live below the last line (48vh padding from theme). */
  min-height: 60vh;
}
.note-cm-host .cm-editor {
  /* CM6 root is allowed to escape its nominal box vertically — scroll is
   * owned by .note-body. */
  height: auto;
}
.note-cm-host .cm-editor.cm-focused {
  outline: none;
}
/* The cm-content inherits the document's reading width via the theme
 * `&` block; padding-horizontal comes from `.note-doc` parent (56px). */

/* ── Preview panel — renders markdown. Swaps with textarea (full-area,
 * not split). Same column constraints so the reading width stays
 * consistent whether you're writing or reading. ── */
.note-preview-panel {
  display: none;
  position: relative;
  background: var(--nd-paper);
  border: 1px solid var(--nd-paper-edge);
  /* Sharp corners — Obsidian-style. Gives the surface a "serious
   * editor" feel; rounded corners stay on buttons + panels. */
  border-radius: 0;
  box-shadow:
    0 24px 60px rgba(0, 0, 0, 0.36),
    0 2px 12px rgba(0, 0, 0, 0.18),
    inset 0 1px 0 rgba(255, 255, 255, 0.03);
  max-width: calc(var(--nd-doc-max) + 112px);
  margin: 18px auto 40vh;
  padding: 64px 56px 80px;
  font-family: var(--nd-body-font);
  font-size: 17px;
  line-height: 1.7;
  color: var(--nd-text);
  letter-spacing: -0.003em;
}
.note-preview-panel.visible { display: block; animation: noteFadeSwap 260ms cubic-bezier(.32,.72,0,1) both; }

.note-preview-panel h1 {
  font-family: var(--nd-body-font);
  font-size: 38px; font-weight: 700; letter-spacing: -0.02em;
  margin: 0 0 20px; line-height: 1.14; color: var(--nd-text);
}
.note-preview-panel h2 {
  font-family: var(--nd-body-font);
  font-size: 26px; font-weight: 600; letter-spacing: -0.01em;
  margin: 40px 0 12px; line-height: 1.24; color: var(--nd-text);
}
.note-preview-panel h3 {
  font-family: var(--nd-body-font);
  font-size: 20px; font-weight: 600; letter-spacing: -0.005em;
  margin: 28px 0 8px; line-height: 1.3; color: var(--nd-text);
}
.note-preview-panel p { margin: 0 0 1.1em; color: var(--nd-text); }
.note-preview-panel strong { font-weight: 600; color: var(--nd-text); }
.note-preview-panel em { font-style: italic; color: var(--nd-text); }
.note-preview-panel code {
  font-family: var(--nd-mono-font);
  font-size: 0.88em;
  background: rgba(255,255,255,0.06);
  padding: 2px 6px;
  border-radius: 4px;
  color: #d9c6a2;  /* warm amber for inline code */
}
.note-preview-panel pre {
  background: rgba(255,255,255,0.035);
  border: 1px solid var(--nd-rule);
  padding: 18px 20px;
  border-radius: 10px;
  margin: 1em 0 1.4em;
  overflow-x: auto;
}
.note-preview-panel pre code {
  background: none; padding: 0;
  font-size: 0.92em;
  color: var(--nd-text);
  line-height: 1.55;
}
.note-preview-panel ul, .note-preview-panel ol {
  padding-left: 1.6em; margin: 0.2em 0 1em;
}
.note-preview-panel li { margin: 0.2em 0; }
.note-preview-panel blockquote {
  border-left: 2px solid var(--nd-accent-dim);
  padding: 0.1em 0 0.1em 16px;
  margin: 1em 0 1.4em;
  color: var(--nd-text-dim);
  font-style: italic;
}
.note-preview-panel .wiki-link {
  color: var(--nd-accent);
  text-decoration: none;
  border-bottom: 1px solid var(--nd-accent-dim);
  cursor: pointer;
  transition: border-color 180ms, color 180ms;
}
.note-preview-panel .wiki-link:hover {
  color: #a3aaff;
  border-bottom-color: var(--nd-accent);
}
.note-preview-panel hr {
  border: 0;
  border-top: 1px solid var(--nd-rule);
  margin: 2em 0;
}

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

/* ── Floating chrome — close + preview toggle top-right as glass chips.
 * Auto-fades after typing (Ensō feel); reveal on mousemove via JS. ── */
.note-chip-row {
  position: absolute;
  top: 18px; right: 22px;
  z-index: 10;
  display: flex;
  gap: 8px;
  opacity: 1;
  transition: opacity 500ms ease;
}
.note-editor-host.chrome-hidden .note-chip-row { opacity: 0; pointer-events: none; }

.note-chip {
  width: 36px; height: 36px;
  display: flex; align-items: center; justify-content: center;
  border-radius: 999px;
  background: rgba(255,255,255,0.04);
  backdrop-filter: blur(16px) saturate(1.3);
  -webkit-backdrop-filter: blur(16px) saturate(1.3);
  border: 1px solid rgba(255,255,255,0.06);
  color: var(--nd-text-dim);
  cursor: pointer;
  transition: background 180ms, color 180ms, border-color 180ms, transform 180ms;
  -webkit-tap-highlight-color: transparent;
}
.note-chip svg { width: 16px; height: 16px; pointer-events: none; }
.note-chip:hover {
  background: rgba(255,255,255,0.08);
  color: var(--nd-text);
  border-color: rgba(255,255,255,0.12);
}
.note-chip:active { transform: scale(0.94); }
.note-chip[data-active="1"] {
  background: rgba(138,148,255,0.14);
  color: var(--nd-accent);
  border-color: rgba(138,148,255,0.32);
}
.note-close-btn.note-chip:hover {
  color: #ffa3a3;
  border-color: rgba(239,68,68,0.35);
  background: rgba(239,68,68,0.08);
}

/* ── Tiny status strip, bottom-right — word count, typing ghost, save. ── */
.note-status {
  position: absolute;
  bottom: 16px; right: 22px;
  z-index: 9;
  display: flex;
  align-items: center;
  gap: 14px;
  font-family: var(--nd-mono-font);
  font-size: 11px;
  color: var(--nd-text-fade);
  letter-spacing: 0.04em;
  pointer-events: none;
  opacity: 1;
  transition: opacity 500ms ease;
}
.note-editor-host.chrome-hidden .note-status { opacity: 0; }
.note-status .note-info { white-space: nowrap; }
.note-status .note-saved { color: var(--nd-text-fade); }
.note-status .note-saved[data-state="saved"] { color: rgba(138,148,255,0.55); }
.note-status .note-typing { color: var(--nd-text-dim); }
.note-info {
  font-size: 11px; font-weight: 500; color: var(--text-dim);
  font-family: 'JetBrains Mono', monospace;
}
.note-typing {
  margin-left: auto; margin-right: 12px;
  font: 500 11px/1 var(--font-body);
  color: var(--text-secondary);
  display: inline-flex; align-items: center; gap: 6px;
  opacity: 0; transition: opacity 0.18s ease;
}
.note-typing[data-active="1"] { opacity: 1; }

/* Ghost caret — peer's text-cursor in a note we both have open. */
.note-ghost-caret {
  position: fixed; top: 0; left: 0;
  width: 2px;
  background: hsl(var(--gc-hue, 220), 75%, 60%);
  pointer-events: none;
  z-index: 9100;  /* above note editor body, below modals */
  transition: transform 100ms ease-out, height 100ms;
  will-change: transform;
}
.note-ghost-caret .ngc-bar {
  display: block; width: 100%; height: 100%;
  background: inherit;
  box-shadow: 0 0 6px hsla(var(--gc-hue, 220), 80%, 60%, 0.4);
}
.note-ghost-caret .ngc-tag {
  position: absolute; top: -16px; left: -3px;
  font-size: 11px; line-height: 14px;
  background: hsl(var(--gc-hue, 220), 65%, 22%);
  border: 1px solid hsl(var(--gc-hue, 220), 75%, 55%);
  border-radius: 3px;
  padding: 0 4px;
  color: #fff;
  white-space: nowrap;
}
.note-typing .typing-dots {
  display: inline-flex; gap: 2px;
}
.note-typing .typing-dots span {
  width: 3px; height: 3px; border-radius: 50%;
  background: currentColor;
  animation: typingBob 1.2s infinite ease-in-out;
}
.note-typing .typing-dots span:nth-child(2) { animation-delay: 0.15s; }
.note-typing .typing-dots span:nth-child(3) { animation-delay: 0.3s; }
@keyframes typingBob {
  0%, 60%, 100% { transform: translateY(0); opacity: 0.4; }
  30% { transform: translateY(-2px); opacity: 1; }
}
.note-toggle-btn.active { background: var(--gold-glow); color: var(--gold); border-color: var(--gold-dim); }

/* ══════════════════════════════════════════════════════════
   OBSIDIAN VIEW MODE
   ══════════════════════════════════════════════════════════ */
#obsidianView {
  display: none; position: fixed; inset: 0; z-index: 8400;
  background: var(--bg-primary);
  flex-direction: row;
}
#obsidianView.open { display: flex; animation: editorFadeIn 0.25s ease both; }

.obs-sidebar {
  width: 260px; min-width: 200px; max-width: 400px;
  background: var(--bg-secondary);
  border-right: 1px solid var(--border);
  display: flex; flex-direction: column;
  overflow: hidden;
}
/* sidebar header removed — clean look */

.obs-tree {
  flex: 1; overflow-y: auto; padding: 12px 0;
}
.obs-tree-item {
  display: flex; align-items: center; gap: 6px;
  padding: 4px 16px; font-size: 13px; color: var(--text-secondary);
  cursor: pointer; transition: all var(--transition-fast);
  user-select: none;
}
.obs-tree-item:hover { background: rgba(255,255,255,0.04); color: var(--text-primary); }
.obs-tree-item.active { background: var(--gold-glow); color: var(--gold); }
.obs-tree-item .obs-icon { width: 16px; height: 16px; opacity: 0.5; flex-shrink: 0; display: flex; align-items: center; justify-content: center; }
.obs-tree-item:hover .obs-icon { opacity: 0.8; }
.obs-tree-item .obs-arrow {
  width: 14px; height: 14px; flex-shrink: 0; opacity: 0.3;
  transition: transform 0.15s; display: flex; align-items: center; justify-content: center;
}
.obs-tree-item .obs-arrow.expanded { transform: rotate(90deg); }
/* Empty folder: arrow visually present so the row stays in the visual tree
 * grid, but dimmed enough to read as "settled" — kills the false affordance
 * of a clickable chevron above an empty list. */
.obs-tree-item .obs-arrow.empty { opacity: 0.18; }
.obs-tree-item .obs-name { flex: 1; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.obs-tree-children { padding-left: 16px; }
.obs-tree-children.collapsed { display: none; }

.obs-tree::-webkit-scrollbar { width: 4px; }
.obs-tree::-webkit-scrollbar-track { background: transparent; }
.obs-tree::-webkit-scrollbar-thumb { background: var(--border); border-radius: 2px; }

.obs-content {
  flex: 1; display: flex; align-items: center; justify-content: center;
  color: var(--text-dim); font-size: 14px;
}

/* Obsidian-embedded editor mode: when the sidebar is open and the user
 * picks a file, we re-use the FULL slab/note/flow editors (with all their
 * tools, previews, streak indicators, etc.) but constrain them to the
 * right pane so the sidebar stays visible. Sidebar width = 260px, matched
 * to .obs-sidebar above. z-index lifted so editor sits above the obsView
 * background but below modals (which are 9000+).
 */
body.obs-embedded #slabEditor,
body.obs-embedded #noteEditor,
body.obs-embedded #flowEditor {
  left: 260px;
  z-index: 8410;
}

/* ══════════════════════════════════════════════════════════
   FOTON MOBILE — phone-optimized layout
   ══════════════════════════════════════════════════════════
   Activated by body.mobile (detection in JS). Everything below is scoped
   so it only fires on touch devices; desktop CSS stays untouched.

   Design principles:
   - Tap targets >= 44px (Apple HIG).
   - Safe area insets for notch + home bar.
   - Grid-based desktop (free x,y positioning doesn't fit tiny viewports).
   - Full-screen editors — no floating windows or embedded panes.
   - Cursor glow canvas hidden (no mouse → no glow).
   - Presence bar positioned clear of iOS home bar. */

body.mobile {
  /* Prevent pull-to-refresh and double-tap zoom eating interactions. */
  overscroll-behavior: none;
  touch-action: manipulation;
  -webkit-tap-highlight-color: transparent;
}

/* Hide the cursor trail canvas — no mouse, no trail. Also the mouse-rate
 * badge makes no sense when touchscreen is the input. */
body.mobile #cursorGlowCanvas,
body.mobile .foton-mouse-badge {
  display: none !important;
}

/* Desktop: re-layout the item grid. Items keep their real x/y for desktop
 * users' cursor projection to work, but mobile users see them in a clean
 * grid via CSS-grid positioning. We use a scrollable flex-wrap instead of
 * position: absolute so items always fit the narrow viewport. */
body.mobile #desktop {
  position: fixed;
  inset: env(safe-area-inset-top, 0) 0 env(safe-area-inset-bottom, 0) 0;
  padding: 56px 16px 120px 16px; /* top = route bar; bottom = presence bar */
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(84px, 1fr));
  gap: 16px 12px;
  overflow-y: auto;
  align-content: start;
}
body.mobile .desktop-item {
  position: static !important;   /* override absolute x,y */
  top: auto !important;
  left: auto !important;
  right: auto !important;
  bottom: auto !important;
  width: auto; height: auto;
  min-height: 90px;
  -webkit-user-select: none; user-select: none;
}
body.mobile .desktop-item .item-icon {
  width: 52px; height: 52px; font-size: 28px;
}
body.mobile .desktop-item .item-name {
  font-size: 12px;
}
body.mobile #routeIndicator {
  top: env(safe-area-inset-top, 8px); left: 12px;
  font-size: 12px; padding: 6px 12px;
  background: rgba(20,20,24,0.85);
  backdrop-filter: blur(8px);
  border-radius: 8px;
  z-index: 9;
}

/* Full-screen editors — no embedded mode on mobile (screen real estate too
 * precious). Obs-embedded override reset on mobile below. */
body.mobile #slabEditor,
body.mobile #noteEditor,
body.mobile #flowEditor {
  inset: 0 !important;
  left: 0 !important;
}

/* ════════════════════════════════════════════════════════════════════════
   Mobile slab UI — Apple-tier touch-first layout
   ════════════════════════════════════════════════════════════════════════
   Replaces the desktop top toolbar (which would eat ~40% of phone height
   including its options panel) with:
     ─ Bottom-floating dock: pill, 60px tall, scrollable horizontally
       Tools 56x56 (≥44 HIG), active tool scaled + tinted accent
     ─ Floating undo (bottom-left), close (top-right), zoom badge (top-left)
     ─ Color/stroke bottom-sheet: slides up over the dock when draw tool
       is active OR user long-presses the active tool
     ─ Hide-on-draw: dock fades to 30% opacity when a stroke is in progress
       so the canvas isn't covered. Floating buttons fade similarly.
   Visual style: glassmorphic (backdrop-filter blur), accent tint when
   active. Spring-animated tap feedback. */

/* Hide all desktop slab chrome on mobile. */
body.mobile #slabEditor .slab-toolbar,
body.mobile #slabEditor .slab-options-panel,
body.mobile #slabEditor .slab-zoom-float,
body.mobile #slabEditor .slab-title-float,
body.mobile #slabEditor .slab-close-btn {
  display: none !important;
}

/* Dock — pill anchored bottom, scrollable, blurred. */
body.mobile .slab-mobile-dock {
  display: flex;
  position: fixed;
  left: 50%;
  bottom: calc(20px + env(safe-area-inset-bottom, 0));
  transform: translateX(-50%);
  z-index: 9000;
  padding: 6px;
  background: rgba(28, 28, 34, 0.85);
  backdrop-filter: blur(28px) saturate(1.4);
  -webkit-backdrop-filter: blur(28px) saturate(1.4);
  border: 1px solid rgba(255, 255, 255, 0.06);
  border-radius: 999px;
  box-shadow: 0 10px 30px rgba(0, 0, 0, 0.5),
              inset 0 1px 0 rgba(255, 255, 255, 0.06);
  gap: 4px;
  max-width: calc(100vw - 96px);  /* leave room for undo/close floats */
  overflow-x: auto;
  overflow-y: hidden;
  scrollbar-width: none;
  transition: opacity 220ms cubic-bezier(.4, 0, .2, 1);
}
body.mobile .slab-mobile-dock::-webkit-scrollbar { display: none; }
body.mobile .slab-mobile-dock.drawing { opacity: 0.18; pointer-events: none; }

body.mobile .smd-tool {
  flex: 0 0 auto;
  width: 52px; height: 52px;
  border-radius: 999px;
  background: transparent;
  border: 0;
  color: var(--text-secondary);
  display: flex; align-items: center; justify-content: center;
  cursor: pointer;
  position: relative;
  transition: transform 140ms cubic-bezier(.4, 0, .2, 1),
              background 140ms,
              color 140ms;
  -webkit-tap-highlight-color: transparent;
  user-select: none;
}
body.mobile .smd-tool svg { width: 24px; height: 24px; }
body.mobile .smd-tool:active { transform: scale(0.92); }
body.mobile .smd-tool[data-active="1"] {
  background: var(--gold-glow);
  color: var(--gold);
  transform: scale(1.05);
}
body.mobile .smd-tool[data-active="1"]::after {
  content: '';
  position: absolute;
  bottom: 4px; left: 50%; transform: translateX(-50%);
  width: 4px; height: 4px; border-radius: 50%;
  background: var(--gold);
}

/* Active-color dot on draw tool — small disc at bottom-right of icon. */
body.mobile .smd-tool .smd-color-dot {
  position: absolute;
  right: 8px; bottom: 8px;
  width: 10px; height: 10px;
  border-radius: 50%;
  border: 2px solid rgba(28, 28, 34, 0.85);
  background: currentColor;
  pointer-events: none;
}

/* Floating buttons (close, undo, zoom). Same glass aesthetic. */
body.mobile .slab-mobile-float {
  position: fixed;
  z-index: 9001;
  width: 44px; height: 44px;
  background: rgba(28, 28, 34, 0.85);
  backdrop-filter: blur(20px) saturate(1.3);
  -webkit-backdrop-filter: blur(20px) saturate(1.3);
  border: 1px solid rgba(255, 255, 255, 0.06);
  border-radius: 999px;
  box-shadow: 0 6px 20px rgba(0, 0, 0, 0.45);
  display: flex; align-items: center; justify-content: center;
  color: var(--text-secondary);
  cursor: pointer;
  transition: transform 140ms, opacity 220ms;
  -webkit-tap-highlight-color: transparent;
}
body.mobile .slab-mobile-float:active { transform: scale(0.92); }
body.mobile .slab-mobile-float.drawing { opacity: 0.18; pointer-events: none; }

body.mobile .smf-close {
  top: calc(env(safe-area-inset-top, 0) + 12px);
  right: 12px;
}
body.mobile .smf-undo {
  bottom: calc(20px + env(safe-area-inset-bottom, 0));
  left: 12px;
}
body.mobile .smf-zoom {
  top: calc(env(safe-area-inset-top, 0) + 12px);
  left: 12px;
  width: auto; height: 32px; padding: 0 12px;
  font: 600 12px/1 'JetBrains Mono', ui-monospace, monospace;
  letter-spacing: 0.04em;
}

/* Color/stroke bottom sheet — slides up above the dock. */
body.mobile .slab-color-sheet {
  position: fixed;
  left: 12px; right: 12px;
  bottom: calc(96px + env(safe-area-inset-bottom, 0));
  z-index: 9000;
  background: rgba(28, 28, 34, 0.92);
  backdrop-filter: blur(28px) saturate(1.4);
  -webkit-backdrop-filter: blur(28px) saturate(1.4);
  border: 1px solid rgba(255, 255, 255, 0.06);
  border-radius: 22px;
  padding: 16px 16px 20px;
  box-shadow: 0 14px 40px rgba(0, 0, 0, 0.55);
  transform: translateY(140%);
  opacity: 0;
  pointer-events: none;
  transition: transform 260ms cubic-bezier(.32, .72, 0, 1),
              opacity 200ms;
}
body.mobile .slab-color-sheet[data-open="1"] {
  transform: translateY(0);
  opacity: 1;
  pointer-events: auto;
}
body.mobile .slab-color-sheet .scs-row {
  display: flex; gap: 10px; flex-wrap: wrap;
  align-items: center; justify-content: center;
}
body.mobile .slab-color-sheet .scs-color {
  width: 36px; height: 36px;
  border-radius: 50%;
  border: 2px solid transparent;
  cursor: pointer;
  transition: transform 140ms, border-color 140ms;
  -webkit-tap-highlight-color: transparent;
}
body.mobile .slab-color-sheet .scs-color[data-active="1"] {
  border-color: rgba(255, 255, 255, 0.85);
  transform: scale(1.12);
}
body.mobile .slab-color-sheet .scs-width {
  flex: 1; min-width: 0;
  appearance: none;
  height: 36px;
  background: transparent;
  cursor: pointer;
}
body.mobile .slab-color-sheet .scs-width::-webkit-slider-runnable-track {
  height: 6px; border-radius: 3px;
  background: rgba(255, 255, 255, 0.12);
}
body.mobile .slab-color-sheet .scs-width::-webkit-slider-thumb {
  appearance: none;
  width: 24px; height: 24px;
  border-radius: 50%;
  background: var(--gold);
  border: 3px solid rgba(28, 28, 34, 1);
  box-shadow: 0 2px 6px rgba(0, 0, 0, 0.5);
  margin-top: -9px;
}
body.mobile .slab-color-sheet .scs-label {
  font: 500 10px/1 var(--font-body);
  color: var(--text-dim);
  letter-spacing: 0.12em; text-transform: uppercase;
  margin: 0 0 6px;
}
body.mobile .slab-color-sheet .scs-grip {
  width: 36px; height: 4px;
  background: rgba(255, 255, 255, 0.18);
  border-radius: 2px;
  margin: 0 auto 12px;
}

body.mobile #slabEditor .slab-toolbar {
  /* Top bar should not collide with notch. */
  top: env(safe-area-inset-top, 8px) !important;
}
body.mobile #flowEditor .flow-ui {
  padding-top: env(safe-area-inset-top, 0);
}

/* CRITICAL: the `.flow-ui` div covers the whole editor (inset: 0, z:3).
 * On desktop, JS toggles pointer-events: auto on mousemove so hover works.
 * On mobile there's no mousemove, so the openFlow fade-in briefly sets
 * pointer-events: auto and traps every tap — the iOS keyboard never
 * opens because the textarea below never receives the touch. Force the
 * container to stay transparent-to-input on mobile; re-enable only the
 * actual interactive children (toolbar buttons). */
body.mobile #flowEditor .flow-ui { pointer-events: none !important; }
body.mobile #flowEditor .flow-ui .flow-tool-btn { pointer-events: auto; }

/* ══════════════════════════════════════════════════════════
   Mobile note editor — same document feel, thumb-friendly
   ══════════════════════════════════════════════════════════ */
body.mobile .note-editor-host .note-doc {
  /* Tighter padding for the smaller canvas, but keep the generous
   * top so the H1 doesn't collide with the notch + floating chips. */
  padding: calc(env(safe-area-inset-top, 0) + 72px) 22px
           calc(28vh + env(safe-area-inset-bottom, 0) + var(--foton-kb-lift, 0px));
  max-width: 100%;
}
body.mobile .note-editor-host .note-doc-title {
  font-size: 30px;
  line-height: 1.14;
  margin-bottom: 22px;
}
body.mobile .note-editor-host .note-textarea {
  font-size: 17px;       /* ≥16px prevents iOS zoom-on-focus */
  line-height: 1.66;
}
body.mobile .note-editor-host .note-preview-panel {
  padding: calc(env(safe-area-inset-top, 0) + 72px) 22px
           calc(28vh + env(safe-area-inset-bottom, 0));
  max-width: 100%;
  font-size: 17px;
}
body.mobile .note-editor-host .note-preview-panel h1 { font-size: 28px; }
body.mobile .note-editor-host .note-preview-panel h2 { font-size: 22px; margin-top: 30px; }
body.mobile .note-editor-host .note-preview-panel h3 { font-size: 18px; margin-top: 22px; }

/* Chip row — float higher + larger targets (44×44). */
body.mobile .note-editor-host .note-chip-row {
  top: calc(env(safe-area-inset-top, 0) + 10px);
  right: 12px;
  gap: 10px;
}
body.mobile .note-editor-host .note-chip {
  width: 44px; height: 44px;
  background: rgba(20, 20, 24, 0.78);
  backdrop-filter: blur(20px) saturate(1.3);
  -webkit-backdrop-filter: blur(20px) saturate(1.3);
  border: 1px solid rgba(255, 255, 255, 0.08);
  box-shadow: 0 6px 18px rgba(0, 0, 0, 0.45);
}
body.mobile .note-editor-host .note-chip svg { width: 19px; height: 19px; }

/* Status strip — bottom-center on mobile so it floats above the keyboard
 * lift and doesn't fight thumb territory on the right. */
body.mobile .note-editor-host .note-status {
  left: 50%; right: auto;
  bottom: calc(14px + env(safe-area-inset-bottom, 0) + var(--foton-kb-lift, 0px));
  transform: translateX(-50%);
  padding: 6px 12px;
  background: rgba(20, 20, 24, 0.6);
  backdrop-filter: blur(14px);
  -webkit-backdrop-filter: blur(14px);
  border-radius: 999px;
  pointer-events: none;
  font-size: 11px;
}

/* ── Mobile flow — minimal chrome, tap-to-cycle mode pill ── */
body.mobile #flowEditor .flow-persistent {
  /* Bottom-anchor: word count + mode indicator pill */
  bottom: calc(14px + env(safe-area-inset-bottom, 0));
  font-size: 12px;
  padding: 8px 14px;
  background: rgba(20, 20, 24, 0.6);
  backdrop-filter: blur(14px);
  -webkit-backdrop-filter: blur(14px);
  border-radius: 999px;
}
/* Old text-based indicator is replaced by the glass segmented control
 * (.flow-privacy-seg). Keep it hidden on mobile so we don't double up. */
body.mobile #flowEditor .flow-coffeeshop-indicator { display: none; }
body.mobile #flowEditor .flow-coffeeshop-hint { display: none; }
body.mobile #flowEditor .flow-toolbar {
  /* Move toolbar to bottom-right corner with safe area, smaller targets */
  top: calc(env(safe-area-inset-top, 0) + 10px);
  right: 10px;
  gap: 6px;
}
body.mobile #flowEditor .flow-tool-btn {
  width: 38px; height: 38px;
  background: rgba(28, 28, 34, 0.78);
  backdrop-filter: blur(20px);
  -webkit-backdrop-filter: blur(20px);
  border-radius: 999px;
  border: 1px solid rgba(255, 255, 255, 0.05);
}

body.mobile #noteTextarea,
body.mobile #flowTextarea {
  /* Larger line-height for finger-land line-break tolerance; padding-bottom
   * gives room for iOS keyboard accessory bar PLUS the actual keyboard via
   * --foton-kb-lift (computed from VisualViewport). Falls back to 20vh if
   * the keyboard API isn't available. */
  font-size: 16px;  /* ≥16px prevents iOS zoom-on-focus */
  padding-bottom: calc(20vh + var(--foton-kb-lift, 0px) + env(safe-area-inset-bottom, 0));
}

/* Obsidian view: sidebar becomes a slide-in drawer on mobile. Closed by
 * default; open via a hamburger in the corner or a swipe from the left edge. */
body.mobile #obsidianView {
  flex-direction: row;
}
body.mobile .obs-sidebar {
  position: absolute;
  top: 0; left: 0; bottom: 0;
  width: 78vw; max-width: 320px;
  z-index: 2;
  transform: translateX(-100%);
  transition: transform 220ms cubic-bezier(.2,.9,.3,1);
  box-shadow: 2px 0 24px rgba(0,0,0,0.4);
  padding-top: env(safe-area-inset-top, 0);
}
body.mobile #obsidianView.obs-drawer-open .obs-sidebar {
  transform: translateX(0);
}
body.mobile .obs-drawer-scrim {
  position: absolute; inset: 0; z-index: 1;
  background: rgba(0,0,0,0.4);
  opacity: 0;
  pointer-events: none;
  transition: opacity 220ms;
}
body.mobile #obsidianView.obs-drawer-open .obs-drawer-scrim {
  opacity: 1;
  pointer-events: auto;
}
body.mobile .obs-content {
  width: 100%;
}
/* Hamburger button in obsidian view — only visible on mobile. */
body.mobile .obs-drawer-toggle {
  position: fixed; top: env(safe-area-inset-top, 12px); left: 12px;
  z-index: 3;
  width: 40px; height: 40px;
  background: rgba(20,20,24,0.85);
  backdrop-filter: blur(8px);
  border: 1px solid var(--border);
  border-radius: 10px;
  display: flex; align-items: center; justify-content: center;
  color: var(--text-primary);
  cursor: pointer;
}
.obs-drawer-toggle { display: none; }  /* hidden on desktop */

/* Override obs-embedded mode on mobile — there's no room for a sidebar
 * alongside an editor. */
body.mobile.obs-embedded #slabEditor,
body.mobile.obs-embedded #noteEditor,
body.mobile.obs-embedded #flowEditor {
  left: 0 !important;
}

/* Presence bar — lift above iOS home bar. Peer list opens UP from me-pill. */
body.mobile #presence-bar {
  left: 12px;
  bottom: calc(14px + env(safe-area-inset-bottom, 0));
}

/* Online/offline dot on me-pill. Animated pulse when online; solid gray
 * when offline so the user knows collaboration is paused. */
.me-online-dot {
  display: inline-block;
  width: 7px; height: 7px; border-radius: 50%;
  margin-right: 6px;
  background: var(--text-dim);
  box-shadow: 0 0 0 0 rgba(52, 211, 153, 0);
  transition: background 200ms;
}
.me-online-dot[data-online="1"] {
  background: hsl(150, 60%, 55%);
  animation: onlinePulse 2.4s ease-out infinite;
}
@keyframes onlinePulse {
  0% { box-shadow: 0 0 0 0 hsla(150, 60%, 55%, 0.5); }
  70% { box-shadow: 0 0 0 6px hsla(150, 60%, 55%, 0); }
  100% { box-shadow: 0 0 0 0 hsla(150, 60%, 55%, 0); }
}

/* Accessibility: honor user's motion preference. Disable the cursor glow
 * canvas + heavy animations + transitions. We preserve functional state
 * changes (opacity on show/hide), just strip decorative motion. */
@media (prefers-reduced-motion: reduce) {
  #cursorGlowCanvas { display: none; }
  .remote-cursor { transition: none !important; }
  .me-online-dot { animation: none !important; }
  .presence-sticker { animation: none !important; }
  .note-ghost-caret { transition: none !important; }
  #setup-wizard, #identity-modal, #coach-modal { animation: none !important; }
}

/* Context menu on mobile — bigger, scroll-safe. */
body.mobile #contextMenu {
  min-width: 200px; font-size: 15px;
}
body.mobile .ctx-item {
  padding: 14px 16px; font-size: 14px;
}

/* Modals (wizard, identity, coach) — full screen on tiny viewports. */
@media (max-width: 520px) {
  body.mobile #identity-modal .id-card,
  body.mobile #setup-wizard .wiz-card,
  body.mobile #coach-modal .coach-card {
    width: 100%; max-width: none; height: 100vh;
    border-radius: 0; border: none;
    padding-top: calc(24px + env(safe-area-inset-top, 0));
    padding-bottom: calc(24px + env(safe-area-inset-bottom, 0));
  }
}

/* ══════════════════════════════════════════════════════════
   PREMIUM MICRO-ANIMATIONS
   ══════════════════════════════════════════════════════════ */

/* Stagger entrance — scoped to .item-enter so the animation runs ONLY on
 * first mount. Without this gate, removing .selected causes the CSS
 * cascade to fall back from .selected's selectPulse to the baseline
 * animation rule, which the browser restarts because animation-name
 * changed. That manifested as the drop/entrance animation replaying on
 * click-to-deselect — exactly the bug we kept failing to fix. */
.desktop-item.item-enter {
  animation: itemFadeIn 0.4s cubic-bezier(.22,1,.36,1) both;
}
@keyframes itemFadeIn {
  from { opacity: 0; transform: translateY(8px) scale(0.95); }
  to { opacity: 1; transform: translateY(0) scale(1); }
}

.desktop-item:active {
  transform: translateY(0) scale(0.96);
  transition: transform 0.08s cubic-bezier(.4,0,1,1);
}

/* Selection pulse */
.desktop-item.selected {
  animation: selectPulse 0.3s cubic-bezier(.22,1,.36,1);
}
@keyframes selectPulse {
  0% { box-shadow: 0 0 0 0 rgba(129,140,248,0.3); }
  50% { box-shadow: 0 0 0 6px rgba(129,140,248,0); }
  100% { box-shadow: none; }
}

/* Context menu entrance */
@keyframes menuSlideIn {
  from { opacity: 0; transform: scale(0.95) translateY(-6px); }
  to { opacity: 1; transform: scale(1) translateY(0); }
}
#contextMenu.visible {
  animation: menuSlideIn 0.15s cubic-bezier(.22,1,.36,1) both;
}

/* Context menu item stagger */
@keyframes ctxItemIn {
  from { opacity: 0; transform: translateX(-4px); }
  to { opacity: 1; transform: translateX(0); }
}
#contextMenu.visible .ctx-item {
  animation: ctxItemIn 0.15s cubic-bezier(.22,1,.36,1) both;
  animation-delay: calc(var(--i, 0) * 0.025s);
}

/* Window open with spring */
@keyframes windowSpring {
  0% { opacity: 0; transform: scale(0.92) translateY(12px); }
  60% { transform: scale(1.01) translateY(-2px); }
  100% { opacity: 1; transform: scale(1) translateY(0); }
}
.folder-window { animation: windowSpring 0.35s cubic-bezier(.22,1,.36,1) both; }
.theme-picker { animation: windowSpring 0.35s cubic-bezier(.22,1,.36,1) both; }

/* Toast spring entrance */
@keyframes toastSpring {
  0% { opacity: 0; transform: translateX(-50%) translateY(16px) scale(0.95); }
  60% { transform: translateX(-50%) translateY(-3px) scale(1.01); }
  100% { opacity: 1; transform: translateX(-50%) translateY(0) scale(1); }
}
#toast.show { animation: toastSpring 0.4s cubic-bezier(.22,1,.36,1) both; }

/* Toast exit */
@keyframes toastExit {
  to { opacity: 0; transform: translateX(-50%) translateY(8px) scale(0.97); }
}
#toast.hide { animation: toastExit 0.3s cubic-bezier(.4,0,1,1) forwards; }

/* Subtle breathing glow on focused elements */
@keyframes subtleGlow {
  0%, 100% { box-shadow: 0 0 0 1px rgba(129,140,248,0.1); }
  50% { box-shadow: 0 0 0 1px rgba(129,140,248,0.2), 0 0 12px rgba(129,140,248,0.04); }
}

/* Selection rect refined */
#selectionRect { border-radius: 6px; backdrop-filter: blur(2px); box-shadow: inset 0 0 12px rgba(124,138,255,0.05); }

/* Context menu item slide */
.ctx-item { transition: background 0.1s, padding-left 0.15s; }
.ctx-item:hover { padding-left: 14px; }

/* Folder window glass effect */
.folder-window { backdrop-filter: blur(20px); background: rgba(17,17,20,0.92); }

/* Toast glass */
#toast { backdrop-filter: blur(12px); background: rgba(24,24,27,0.9); border: 1px solid rgba(255,255,255,0.06); }


/* ══════════════════════════════════════════════════════════
   STATE-OF-THE-ART — Ambient, Motion, Depth
   ══════════════════════════════════════════════════════════ */

/* Ambient gradient mesh background */
body::before {
  content: '';
  position: fixed; inset: 0; z-index: -1;
  background:
    radial-gradient(ellipse 80% 60% at 20% 80%, rgba(129,140,248,0.05) 0%, transparent 60%),
    radial-gradient(ellipse 60% 80% at 80% 20%, rgba(168,85,247,0.04) 0%, transparent 60%),
    radial-gradient(ellipse 50% 50% at 50% 50%, rgba(52,211,153,0.025) 0%, transparent 70%);
  pointer-events: none;
  animation: ambientShift 30s ease-in-out infinite alternate;
}
@keyframes ambientShift {
  0% { opacity: 1; }
  50% { opacity: 0.6; }
  100% { opacity: 1; }
}

/* Cursor glow follower disabled 2026-04-20 — user found it distracting.
 * Element kept out of layout; its IIFE early-returns below. */
#cursorGlowCanvas { display: none; }

/* ── Enhanced desktop items ── */
.desktop-item {
  border-radius: 14px;
  transition: transform 0.25s cubic-bezier(.22,1,.36,1),
              border-color 0.2s,
              background 0.2s,
              box-shadow 0.3s;
}
.desktop-item:hover {
  background: rgba(255,255,255,0.025);
  border-color: rgba(255,255,255,0.06);
  box-shadow: 0 4px 20px rgba(0,0,0,0.2), 0 0 0 1px rgba(255,255,255,0.03);
  transform: translateY(-2px);
  will-change: transform;
}
.desktop-item.selected {
  background: rgba(129,140,248,0.06);
  border-color: rgba(129,140,248,0.2);
  box-shadow: 0 0 0 1px rgba(129,140,248,0.15), 0 4px 16px rgba(129,140,248,0.06);
}
.desktop-item .item-name {
  font-size: 11px; font-weight: 500; letter-spacing: 0.01em;
  transition: color 0.2s;
}
.desktop-item .item-icon {
  filter: saturate(0.85);
  transition: transform 0.3s cubic-bezier(.22,1,.36,1), filter 0.3s;
}
.desktop-item:hover .item-icon {
  filter: saturate(1.1) brightness(1.1);
  transform: scale(1.08) translateY(-3px);
}
.desktop-item:hover .item-name {
  text-shadow: 0 1px 3px rgba(0,0,0,0.3);
}
.desktop-item.selected .item-icon {
  filter: saturate(1.2) brightness(1.15) drop-shadow(0 2px 8px rgba(129,140,248,0.2));
  animation: selectedBreath 3s ease-in-out infinite alternate;
}
@keyframes selectedBreath {
  0% { filter: saturate(1.2) brightness(1.15) drop-shadow(0 2px 8px rgba(129,140,248,0.15)); }
  100% { filter: saturate(1.2) brightness(1.15) drop-shadow(0 2px 12px rgba(129,140,248,0.3)); }
}

/* Stagger entrance — JS sets --item-index. Scoped to .item-enter so it
 * only biases the initial mount animation, not future state-change
 * animations like selectPulse. */
.desktop-item.item-enter { animation-delay: calc(var(--item-index, 0) * 0.04s); }

/* ── Enhanced context menu ── */
#contextMenu {
  backdrop-filter: blur(24px) saturate(1.4);
  background: rgba(28,28,34,0.88);
  border: 1px solid rgba(255,255,255,0.08);
  border-radius: 14px;
  box-shadow:
    0 8px 40px rgba(0,0,0,0.5),
    0 0 0 1px rgba(255,255,255,0.04),
    inset 0 1px 0 rgba(255,255,255,0.04);
  padding: 5px;
}
.ctx-item {
  border-radius: 8px;
  font-weight: 450;
  gap: 10px;
  padding: 8px 12px;
  transition: background 0.1s, transform 0.15s cubic-bezier(.22,1,.36,1);
}
.ctx-item:hover {
  background: rgba(129,140,248,0.08);
  transform: translateX(2px);
}
.ctx-item.danger:hover { background: rgba(239,68,68,0.1); }
.ctx-separator { margin: 3px 8px; background: rgba(255,255,255,0.06); height: 1px; }

/* ── Enhanced folder windows ── */
.folder-window {
  backdrop-filter: blur(24px) saturate(1.3);
  background: rgba(26,26,32,0.92);
  border-radius: 16px;
  border: 1px solid rgba(255,255,255,0.08);
  box-shadow:
    0 20px 60px rgba(0,0,0,0.5),
    0 0 0 1px rgba(255,255,255,0.03),
    inset 0 1px 0 rgba(255,255,255,0.04),
    inset 0 1px 0 rgba(255,255,255,0.05),
    inset 0 -1px 0 rgba(0,0,0,0.2);
}
.folder-window .win-titlebar {
  background: transparent;
  border-bottom: 1px solid rgba(255,255,255,0.04);
  height: 44px;
  border-radius: 16px 16px 0 0;
  padding: 0 16px;
  position: relative;
}
.folder-window .win-titlebar::after {
  content: '\00B7  \00B7  \00B7';
  position: absolute;
  left: 50%;
  transform: translateX(-50%);
  font-size: 8px;
  color: rgba(255,255,255,0.08);
  letter-spacing: 3px;
  pointer-events: none;
}
.folder-window .win-title {
  font-size: 13px; font-weight: 600; letter-spacing: -0.01em;
}
.folder-window .win-close {
  width: 12px; height: 12px; border-radius: 50%;
  background: rgba(255,255,255,0.08); border: none;
  font-size: 0; transition: all 0.15s;
  position: relative;
}
.folder-window .win-close:hover { background: #ef4444; transform: scale(1.15); }
.folder-window .win-close::before, .folder-window .win-close::after {
  content: ''; position: absolute; top: 50%; left: 50%;
  width: 6px; height: 1px; background: transparent;
  transform: translate(-50%,-50%) rotate(45deg);
  transition: background 0.15s;
}
.folder-window .win-close::after { transform: translate(-50%,-50%) rotate(-45deg); }
.folder-window .win-close:hover::before, .folder-window .win-close:hover::after { background: white; }

.folder-window .win-item {
  border-radius: 10px;
  transition: all 0.15s cubic-bezier(.22,1,.36,1);
}
.folder-window .win-item:hover {
  background: rgba(255,255,255,0.04);
  transform: translateY(-1px);
}
.folder-window .win-item:hover .item-icon {
  transform: translateY(-2px) scale(1.05);
  transition: transform 0.2s cubic-bezier(.22,1,.36,1);
}

/* ── Enhanced toast ── */
#toast {
  backdrop-filter: blur(16px) saturate(1.3);
  background: rgba(32,32,38,0.9);
  border: 1px solid rgba(255,255,255,0.06);
  border-radius: 10px;
  padding: 10px 20px;
  font-weight: 500;
  box-shadow: 0 8px 32px rgba(0,0,0,0.4), 0 0 0 1px rgba(255,255,255,0.03);
  border-left: 2px solid var(--gold-dim);
}

/* ── Enhanced slab toolbar ── */
.slab-toolbar {
  backdrop-filter: blur(20px) saturate(1.3);
  background: rgba(28,28,34,0.88);
  border: 1px solid rgba(255,255,255,0.08);
  border-radius: 14px;
  box-shadow: 0 4px 24px rgba(0,0,0,0.35), inset 0 1px 0 rgba(255,255,255,0.04);
  padding: 5px 8px;
}
.slab-tool-btn {
  border-radius: 8px;
  transition: all 0.15s cubic-bezier(.22,1,.36,1);
}
.slab-tool-btn:hover {
  background: rgba(255,255,255,0.06);
  transform: translateY(-1px);
}
.slab-tool-btn.active {
  background: rgba(129,140,248,0.12);
  box-shadow: 0 0 12px rgba(129,140,248,0.08);
}
.slab-tool-btn.active::after {
  content: '';
  position: absolute;
  bottom: 3px;
  left: 50%;
  transform: translateX(-50%);
  width: 4px;
  height: 4px;
  border-radius: 50%;
  background: var(--gold);
  opacity: 0.6;
}

/* ── Enhanced options panel ── */
.slab-options-panel {
  backdrop-filter: blur(20px) saturate(1.3);
  background: rgba(28,28,34,0.88);
  border: 1px solid rgba(255,255,255,0.08);
  border-radius: 14px;
  box-shadow: 0 4px 24px rgba(0,0,0,0.35), inset 0 1px 0 rgba(255,255,255,0.04);
}

/* ── Enhanced text nodes ── */
.slab-text-node {
  border-radius: 10px;
  backdrop-filter: blur(8px);
  background: rgba(30,30,38,0.88);
  box-shadow: 0 2px 8px rgba(0,0,0,0.2);
  transition: all 0.2s cubic-bezier(.22,1,.36,1);
}
.slab-text-node:hover {
  box-shadow: 0 4px 16px rgba(0,0,0,0.3), 0 0 0 1px rgba(255,255,255,0.06);
  transform: translateY(-1px);
}
.slab-text-node.selected {
  box-shadow: 0 0 0 2px rgba(129,140,248,0.25), 0 4px 20px rgba(129,140,248,0.08);
}

/* ── Enhanced theme picker ── */
.theme-picker {
  backdrop-filter: blur(24px) saturate(1.3);
  background: rgba(17,17,20,0.88);
  border: 1px solid rgba(255,255,255,0.08);
  border-radius: 18px;
  box-shadow: 0 24px 80px rgba(0,0,0,0.5), 0 0 0 1px rgba(255,255,255,0.03);
}
.theme-card {
  border-radius: 12px;
  transition: all 0.2s cubic-bezier(.22,1,.36,1);
  border: 1px solid rgba(255,255,255,0.04);
}
.theme-card:hover {
  border-color: rgba(255,255,255,0.1);
  transform: translateY(-2px);
  box-shadow: 0 4px 16px rgba(0,0,0,0.3), inset 0 1px 0 rgba(255,255,255,0.06);
}
.theme-card.active {
  border-color: var(--gold-dim);
  box-shadow: 0 0 0 1px var(--gold-dim), 0 0 20px rgba(129,140,248,0.06);
}

@keyframes fadeIn { from { opacity: 0; } to { opacity: 0.25; } }

/* ── Route indicator refined ── */
#routeIndicator {
  font-size: 11px; font-weight: 400;
  opacity: 0.25;
  letter-spacing: 0.02em;
  animation: fadeIn 1s ease 0.5s both;
}

/* ── Obsidian view enhanced ── */
.obs-sidebar {
  background: rgba(22,22,28,0.95);
  backdrop-filter: blur(12px);
  border-right: 1px solid rgba(255,255,255,0.04);
}
.obs-tree-item {
  border-radius: 6px; margin: 1px 8px;
  padding: 5px 12px;
  font-weight: 450;
  transition: all 0.12s;
}
.obs-tree-item:hover {
  background: rgba(255,255,255,0.04);
}
.obs-tree-item.active {
  background: rgba(129,140,248,0.08);
  color: var(--gold);
  border-left: 2px solid var(--gold);
  padding-left: 10px;
}

/* (Old .note-header / .note-footer "enhanced" overrides removed — the
 * note editor no longer uses a header/footer bar; chrome is a floating
 * chip row + tiny status strip, both styled in the main Note Editor
 * block above.) */

/* ── Refined scrollbars everywhere ── */
::-webkit-scrollbar { width: 7px; }
::-webkit-scrollbar-track { background: transparent; }
::-webkit-scrollbar-thumb { background: rgba(255,255,255,0.06); border-radius: 4px; }
::-webkit-scrollbar-thumb:hover { background: rgba(255,255,255,0.12); }

/* ── Connection port glow ── */
.node-port { transition: all 0.2s cubic-bezier(.22,1,.36,1); }
.node-port:hover {
  box-shadow: 0 0 12px rgba(129,140,248,0.3);
  background: var(--gold) !important;
  transform: scale(1.5);
}

/* ── Recycle bin refined ── */
.recycle-bin:hover .item-icon { filter: saturate(1.5) brightness(1.2); }

/* Recycle bin breathing when not empty */
.recycle-bin.has-items .item-icon {
  animation: binBreathe 6s ease-in-out infinite;
}
@keyframes binBreathe {
  0%, 100% { filter: none; }
  50% { filter: brightness(1.05) drop-shadow(0 0 4px rgba(255,255,255,0.03)); }
}

/* ── Trash shockwave ring ── */
.trash-shockwave {
  position: fixed; pointer-events: none; z-index: 4998;
  border-radius: 50%;
  border: 1.5px solid rgba(229, 72, 77, 0.4);
  box-shadow: 0 0 12px rgba(229, 72, 77, 0.15), inset 0 0 12px rgba(229, 72, 77, 0.08);
  animation: shockwaveExpand 0.6s cubic-bezier(.22,1,.36,1) forwards;
}
@keyframes shockwaveExpand {
  0%   { width: 20px; height: 20px; opacity: 0.8; }
  100% { width: 180px; height: 180px; opacity: 0; }
}

/* ── Screen shake ── */
@keyframes microShake {
  0%   { transform: translate(0, 0); }
  15%  { transform: translate(-1.5px, 0.5px); }
  30%  { transform: translate(1px, -1px); }
  45%  { transform: translate(-0.5px, 1.5px); }
  60%  { transform: translate(1px, 0px); }
  75%  { transform: translate(-0.5px, -0.5px); }
  100% { transform: translate(0, 0); }
}
body.shake-active { animation: microShake 0.35s ease-out; }

@keyframes editorFadeIn { from { opacity: 0; } to { opacity: 1; } }


/* ── Skeleton loader for note panes (Tier 3 polish) ──────────────────
   Three pulsing bars in the body host while /api/notes/{id} is in
   flight. Removed by NoteEditor._clearSkeleton() once CM6 mounts so
   the editor view takes over an empty host. */
.ne-skeleton {
  display: flex;
  flex-direction: column;
  gap: 12px;
  padding: 24px 0;
  pointer-events: none;
  user-select: none;
}
.ne-skeleton-bar {
  height: 14px;
  border-radius: 6px;
  background: linear-gradient(
    90deg,
    rgba(255, 255, 255, 0.04) 0%,
    rgba(255, 255, 255, 0.10) 50%,
    rgba(255, 255, 255, 0.04) 100%
  );
  background-size: 220% 100%;
  animation: skeletonShimmer 1.4s ease-in-out infinite;
}
@keyframes skeletonShimmer {
  0%   { background-position: 100% 0; }
  100% { background-position: -100% 0; }
}

/* ── Toast retry affordance ──
   When a toast is given an onClick (e.g. retry), reveal it as
   clickable instead of a passive notification. Subtle ring + pointer. */
#toast.actionable {
  cursor: pointer;
  outline: 1px solid rgba(138, 148, 255, 0.55);
  outline-offset: 2px;
}
#toast.actionable:hover {
  background: rgba(36, 36, 44, 0.95);
}

/* ── Empty desktop hint (D10) ──
   Surfaces when the desktop has zero items AND the wizard has been
   dismissed. Toggled via .gds-empty-desktop on body. */
.gds-empty-desktop-hint {
  position: fixed;
  left: 50%;
  bottom: calc(env(safe-area-inset-bottom, 0px) + 88px);
  transform: translateX(-50%);
  font-family: 'Inter', system-ui, sans-serif;
  font-size: 13px;
  letter-spacing: 0.01em;
  color: rgba(232, 230, 224, 0.45);
  background: rgba(28, 28, 34, 0.55);
  backdrop-filter: blur(10px) saturate(120%);
  border: 1px solid rgba(255, 255, 255, 0.06);
  border-radius: 999px;
  padding: 8px 16px;
  pointer-events: none;
  z-index: 60;
  opacity: 0;
  animation: emptyHintFade 600ms ease-out 800ms forwards;
}
body:not(.gds-empty-desktop) .gds-empty-desktop-hint { display: none; }
@keyframes emptyHintFade {
  from { opacity: 0; transform: translate(-50%, 6px); }
  to   { opacity: 1; transform: translate(-50%, 0); }
}

/* ── Split-right button (N3) — single floating control top-right of
 * viewport, only visible when a document is open. Click → quick-open
 * picker that lands selection in a pane to the right (Hyprland-style
 * binary split). Replaces the old presence-bar tile-mode toggle: tile
 * mode is now a side-effect of splitting, not a global mode the user
 * has to remember. */
#gds-split-right-btn {
  position: fixed;
  top: calc(env(safe-area-inset-top, 0px) + 16px);
  right: calc(env(safe-area-inset-right, 0px) + 18px);
  width: 36px; height: 36px;
  /* The legacy single-pane editors (#noteEditor / #slabEditor /
   * #flowEditor) all sit at z-index 8500 with `inset: 0`. Without an
   * explicit stacking context here the button paints UNDER them — a
   * note open in legacy mode swallowed every click on this button. */
  z-index: 9000;
  display: none;             /* shown via body.gds-doc-open below */
  align-items: center; justify-content: center;
  padding: 0;
  background: rgba(20, 20, 28, 0.62);
  border: 1px solid rgba(255, 255, 255, 0.08);
  border-radius: 10px;
  color: rgba(232, 234, 246, 0.7);
  cursor: pointer;
  backdrop-filter: blur(14px) saturate(120%);
  -webkit-backdrop-filter: blur(14px) saturate(120%);
  transition: background-color 140ms, border-color 140ms,
              color 140ms, transform 90ms;
}
body.gds-doc-open #gds-split-right-btn { display: inline-flex; }
#gds-split-right-btn:hover {
  background: rgba(124, 138, 255, 0.18);
  border-color: rgba(124, 138, 255, 0.38);
  color: #eef0ff;
  transform: scale(1.04);
}
#gds-split-right-btn:active { transform: scale(0.94); }
#gds-split-right-btn svg { width: 18px; height: 18px; }
