:root{
    --toolbar-bg:#23201b; --toolbar-text:#fff;
    --paper:#f4efe6; --paper-2:#efe8db; --ink:#23201b; --ink-soft:#6b6357;
    --line:#d8cfbf; --line-2:#c8bda8;
    --accent:#e0613a; --accent-deep:#b8451f; --teal:#2f6f6a;
    --chrome:#fbf8f2; --chrome-edge:#e7ddcc;
    --node-bg:#ffffff; --node-ink:#23201b;
    --canvas-dot:#d8cfbf;
    --stage-glow:rgba(255,255,255,.5);
    --link:#b8451f;
    /* Universal hover tint: overlays the ink colour, so it darkens light
       surfaces and lightens dark surfaces — always a visible delta. */
    --hover:color-mix(in srgb, var(--ink) 12%, transparent);
    --hover-strong:color-mix(in srgb, var(--ink) 20%, transparent);
    --shadow:0 2px 4px rgba(40,30,15,.06),0 8px 24px rgba(40,30,15,.10);
    --shadow-lg:0 10px 40px rgba(40,30,15,.18);
    --r:14px;
    --sans:"Bricolage Grotesque",system-ui,sans-serif;
    --serif:"Fraunces",Georgia,serif;
  }
  /* ===== Themes ===== */
  :root[data-theme="dark"]{
    --toolbar-bg:#f3f3f3; --toolbar-text:#1e1e1e;
    --paper:#1e1e1e; --paper-2:#252526; --ink:#d4d4d4; --ink-soft:#9d9d9d;
    --line:#3c3c3c; --line-2:#4a4a4a;
    --accent:#3794ff; --accent-deep:#1f6fdc; --teal:#4ec9b0;
    --chrome:#252526; --chrome-edge:#3c3c3c;
    --node-bg:#2d2d2d; --node-ink:#d4d4d4;
    --canvas-dot:#3a3a3a;
    --stage-glow:rgba(255,255,255,.04);
    --link:#79b8ff;
    --shadow:0 2px 4px rgba(0,0,0,.30),0 8px 24px rgba(0,0,0,.45);
    --shadow-lg:0 12px 40px rgba(0,0,0,.55);
  }
  :root[data-theme="light-owl"]{   /* Light Owl — github.com/sdras/night-owl-vscode-theme */
    --toolbar-bg:#403f53; --toolbar-text:#fbfbfb;
    --paper:#fbfbfb; --paper-2:#f0f0f0; --ink:#403f53; --ink-soft:#90a7b2;
    --line:#ececec; --line-2:#d9d9d9;
    --accent:#2aa298; --accent-deep:#1f7d75; --teal:#0c969b;
    --chrome:#f0f0f0; --chrome-edge:#e0e0e0;
    --node-bg:#ffffff; --node-ink:#403f53;
    --canvas-dot:#d9d9d9;
    --stage-glow:rgba(255,255,255,.6);
    --link:#288ed7;
    --shadow:0 1px 3px rgba(64,63,83,.10),0 8px 24px rgba(64,63,83,.08);
    --shadow-lg:0 12px 40px rgba(64,63,83,.16);
  }
  :root[data-theme="night-owl"]{   /* Night Owl — github.com/sdras/night-owl-vscode-theme */
    --toolbar-bg:#d6deeb; --toolbar-text:#011627;
    --paper:#011627; --paper-2:#0b2942; --ink:#d6deeb; --ink-soft:#5f7e97;
    --line:#1d3b53; --line-2:#2c5574;
    --accent:#7e57c2; --accent-deep:#6440a5; --teal:#7fdbca;
    --chrome:#011627; --chrome-edge:#1d3b53;
    --node-bg:#0b2942; --node-ink:#d6deeb;
    --canvas-dot:#1d3b53;
    --stage-glow:rgba(126,87,194,.06);
    --link:#82aaff;
    --shadow:0 2px 4px rgba(0,0,0,.30),0 8px 24px rgba(0,0,0,.45);
    --shadow-lg:0 12px 40px rgba(0,0,0,.55);
  }
  :root[data-theme="dracula"]{
    --toolbar-bg:#f8f8f2; --toolbar-text:#282a36;
    --paper:#282a36; --paper-2:#21222c; --ink:#f8f8f2; --ink-soft:#a3a8c0;
    --line:#44475a; --line-2:#6272a4;
    --accent:#ff79c6; --accent-deep:#e857af; --teal:#8be9fd;
    --chrome:#21222c; --chrome-edge:#44475a;
    --node-bg:#44475a; --node-ink:#f8f8f2;
    --canvas-dot:#44475a;
    --stage-glow:rgba(189,147,249,.06);
    --link:#8be9fd;
    --shadow:0 2px 4px rgba(0,0,0,.30),0 8px 24px rgba(0,0,0,.45);
    --shadow-lg:0 12px 40px rgba(0,0,0,.55);
  }
  :root[data-theme="nord"]{
    --toolbar-bg:#eceff4; --toolbar-text:#2e3440;
    --paper:#2e3440; --paper-2:#3b4252; --ink:#eceff4; --ink-soft:#a9b1bf;
    --line:#434c5e; --line-2:#4c566a;
    --accent:#88c0d0; --accent-deep:#5e81ac; --teal:#a3be8c;
    --chrome:#3b4252; --chrome-edge:#434c5e;
    --node-bg:#434c5e; --node-ink:#eceff4;
    --canvas-dot:#434c5e;
    --stage-glow:rgba(143,188,187,.05);
    --link:#88c0d0;
    --shadow:0 2px 4px rgba(0,0,0,.25),0 8px 24px rgba(0,0,0,.40);
    --shadow-lg:0 12px 40px rgba(0,0,0,.55);
  }
  :root[data-theme="catppuccin-dark"]{   /* Catppuccin Mocha — https://github.com/catppuccin/catppuccin */
    --toolbar-bg:#f5e0dc; --toolbar-text:#1e1e2e;
    --paper:#1e1e2e; --paper-2:#181825; --ink:#cdd6f4; --ink-soft:#a6adc8;
    --line:#313244; --line-2:#45475a;
    --accent:#cba6f7; --accent-deep:#a674e0; --teal:#94e2d5;
    --chrome:#181825; --chrome-edge:#313244;
    --node-bg:#313244; --node-ink:#cdd6f4;
    --canvas-dot:#313244;
    --stage-glow:rgba(203,166,247,.05);
    --link:#89b4fa;
    --shadow:0 2px 4px rgba(0,0,0,.30),0 8px 24px rgba(0,0,0,.45);
    --shadow-lg:0 12px 40px rgba(0,0,0,.55);
  }
  :root[data-theme="catppuccin-light"]{   /* Catppuccin Latte — https://github.com/catppuccin/catppuccin */
    --toolbar-bg:#4c4f69; --toolbar-text:#eff1f5;
    --paper:#eff1f5; --paper-2:#e6e9ef; --ink:#4c4f69; --ink-soft:#6c6f85;
    --line:#ccd0da; --line-2:#bcc0cc;
    --accent:#8839ef; --accent-deep:#6c2bc7; --teal:#179299;
    --chrome:#e6e9ef; --chrome-edge:#ccd0da;
    --node-bg:#ffffff; --node-ink:#4c4f69;
    --canvas-dot:#ccd0da;
    --stage-glow:rgba(136,57,239,.04);
    --link:#1e66f5;
    --shadow:0 1px 3px rgba(76,79,105,.12),0 8px 24px rgba(76,79,105,.12);
    --shadow-lg:0 12px 40px rgba(76,79,105,.18);
  }
  :root[data-theme="rose-pine-moon"]{   /* Rosé Pine Moon — https://rosepinetheme.com */
    --toolbar-bg:#e0def4; --toolbar-text:#232136;
    --paper:#232136; --paper-2:#2a273f; --ink:#e0def4; --ink-soft:#908caa;
    --line:#393552; --line-2:#44415a;
    --accent:#c4a7e7; --accent-deep:#a57dd5; --teal:#9ccfd8;
    --chrome:#2a273f; --chrome-edge:#393552;
    --node-bg:#393552; --node-ink:#e0def4;
    --canvas-dot:#2a283e;
    --stage-glow:rgba(196,167,231,.05);
    --link:#c4a7e7;
    --shadow:0 2px 4px rgba(0,0,0,.30),0 8px 24px rgba(0,0,0,.45);
    --shadow-lg:0 12px 40px rgba(0,0,0,.55);
  }
  :root[data-theme="rose-pine-dawn"]{   /* Rosé Pine Dawn — https://rosepinetheme.com */
    --toolbar-bg:#575279; --toolbar-text:#faf4ed;
    --paper:#faf4ed; --paper-2:#f2e9e1; --ink:#575279; --ink-soft:#797593;
    --line:#f2e9e1; --line-2:#dfdad9;
    --accent:#907aa9; --accent-deep:#7a6494; --teal:#56949f;
    --chrome:#faf4ed; --chrome-edge:#f2e9e1;
    --node-bg:#fffaf3; --node-ink:#575279;
    --canvas-dot:#dfdad9;
    --stage-glow:rgba(144,122,169,.04);
    --link:#907aa9;
    --shadow:0 1px 3px rgba(87,82,121,.12),0 8px 24px rgba(87,82,121,.12);
    --shadow-lg:0 12px 40px rgba(87,82,121,.18);
  }
  :root[data-theme="github-dark"]{
    --toolbar-bg:#f0f6fc; --toolbar-text:#0d1117;
    --paper:#0d1117; --paper-2:#161b22; --ink:#e6edf3; --ink-soft:#8b949e;
    --line:#30363d; --line-2:#3d444d;
    --accent:#58a6ff; --accent-deep:#1f6feb; --teal:#3fb950;
    --chrome:#161b22; --chrome-edge:#30363d;
    --node-bg:#161b22; --node-ink:#e6edf3;
    --canvas-dot:#30363d;
    --stage-glow:rgba(88,166,255,.05);
    --link:#58a6ff;
    --shadow:0 2px 4px rgba(0,0,0,.30),0 8px 24px rgba(0,0,0,.45);
    --shadow-lg:0 12px 40px rgba(0,0,0,.55);
  }
  :root[data-theme="github-light"]{
    --toolbar-bg:#24292f; --toolbar-text:#ffffff;
    --paper:#ffffff; --paper-2:#f6f8fa; --ink:#1f2328; --ink-soft:#656d76;
    --line:#d0d7de; --line-2:#afb8c1;
    --accent:#0969da; --accent-deep:#0a5cc0; --teal:#1a7f37;
    --chrome:#f6f8fa; --chrome-edge:#d0d7de;
    --node-bg:#ffffff; --node-ink:#1f2328;
    --canvas-dot:#d8dee4;
    --stage-glow:rgba(9,105,218,.04);
    --link:#0969da;
    --shadow:0 1px 3px rgba(31,35,40,.12),0 8px 24px rgba(31,35,40,.12);
    --shadow-lg:0 12px 40px rgba(31,35,40,.18);
  }
  :root[data-theme="slate-steel"]{   /* Slate & Steel — enterprise cloud monitoring */
    --toolbar-bg:#f8fafc; --toolbar-text:#0f172a;
    --paper:#0f172a; --paper-2:#1e293b; --ink:#cbd5e1; --ink-soft:#64748b;
    --line:#334155; --line-2:#3e4c63;
    --accent:#38bdf8; --accent-deep:#0284c7; --teal:#2dd4bf;
    --chrome:#1e293b; --chrome-edge:#334155;
    --node-bg:#1e293b; --node-ink:#cbd5e1;
    --canvas-dot:#334155;
    --stage-glow:rgba(56,189,248,.05);
    --link:#38bdf8;
    --shadow:0 2px 4px rgba(0,0,0,.30),0 8px 24px rgba(0,0,0,.45);
    --shadow-lg:0 12px 40px rgba(0,0,0,.55);
  }
:root[data-theme="vscode-onedark"]{   /* VSCode One Dark Pro */
    --toolbar-bg:#abb2bf; --toolbar-text:#282c34;
    --paper:#282c34; --paper-2:#21252b; --ink:#abb2bf; --ink-soft:#5c6370;
    --line:#3e4451; --line-2:#4a5261;
    --accent:#98c379; --accent-deep:#50a14f; --teal:#61afef;
    --chrome:#21252b; --chrome-edge:#3e4451;
    --node-bg:#2c323d; --node-ink:#abb2bf;
    --canvas-dot:#3e4451;
    --stage-glow:rgba(152,195,121,.05);
    --link:#61afef;
    --shadow:0 2px 4px rgba(0,0,0,.30),0 8px 24px rgba(0,0,0,.45);
    --shadow-lg:0 12px 40px rgba(0,0,0,.55);
  }
:root[data-theme="monokai-pro"]{   /* VSCode Monokai Pro */
    --toolbar-bg:#fcfcfa; --toolbar-text:#2d2a2e;
    --paper:#2d2a2e; --paper-2:#19181a; --ink:#fcfcfa; --ink-soft:#727072;
    --line:#403e41; --line-2:#504d52;
    --accent:#a9dc76; --accent-deep:#6ca030; --teal:#ffd866;
    --chrome:#19181a; --chrome-edge:#403e41;
    --node-bg:#363337; --node-ink:#fcfcfa;
    --canvas-dot:#403e41;
    --stage-glow:rgba(169,220,118,.05);
    --link:#ff6188;
    --shadow:0 2px 4px rgba(0,0,0,.35),0 8px 24px rgba(0,0,0,.50);
    --shadow-lg:0 12px 40px rgba(0,0,0,.60);
  }
:root[data-theme="amazon-aws"]{   /* Amazon AWS Console */
    --toolbar-bg:#f9fafb; --toolbar-text:#111827;
    --paper:#161e2e; --paper-2:#1f2937; --ink:#d1d5db; --ink-soft:#6b7280;
    --line:#374151; --line-2:#455160;
    --accent:#ff9900; --accent-deep:#ec7211; --teal:#93c5fd;
    --chrome:#1f2937; --chrome-edge:#374151;
    --node-bg:#232f3e; --node-ink:#d1d5db;
    --canvas-dot:#374151;
    --stage-glow:rgba(255,153,0,.05);
    --link:#ff9900;
    --shadow:0 2px 4px rgba(0,0,0,.30),0 8px 24px rgba(0,0,0,.45);
    --shadow-lg:0 12px 40px rgba(0,0,0,.55);
  }
:root[data-theme="synthwave"]{   /* Synthwave '84 Sunset */
    --toolbar-bg:#e2d9f3; --toolbar-text:#1a102f;
    --paper:#1a102f; --paper-2:#281b45; --ink:#e2d9f3; --ink-soft:#9a84b4;
    --line:#483267; --line-2:#5a4080;
    --accent:#00f5d4; --accent-deep:#00c4ac; --teal:#ff71ce;
    --chrome:#281b45; --chrome-edge:#483267;
    --node-bg:#281b45; --node-ink:#e2d9f3;
    --canvas-dot:#483267;
    --stage-glow:rgba(255,113,206,.06);
    --link:#ff71ce;
    --shadow:0 2px 4px rgba(0,0,0,.40),0 8px 24px rgba(0,0,0,.55);
    --shadow-lg:0 12px 40px rgba(0,0,0,.65);
  }
:root[data-theme="matrix-green"]{   /* Matrix Green terminal */
    --toolbar-bg:#d7ffe0; --toolbar-text:#04140b;
    --paper:#030705; --paper-2:#07140b; --ink:#9ef7b2; --ink-soft:#347744;
    --line:#123a1f; --line-2:#1b4b2b;
    --accent:#39ff88; --accent-deep:#1fbf5f; --teal:#a9ffc0;
    --chrome:#07140b; --chrome-edge:#123a1f;
    --node-bg:#0b2414; --node-ink:#9ef7b2;
    --canvas-dot:#123a1f;
    --stage-glow:rgba(57,255,136,.06);
    --link:#39ff88;
    --shadow:0 2px 4px rgba(0,0,0,.40),0 8px 24px rgba(0,0,0,.55);
    --shadow-lg:0 12px 40px rgba(0,0,0,.65);
  }
:root[data-theme="solarized"]{   /* Solarized Classic */
    --toolbar-bg:#073642; --toolbar-text:#fdf6e3;
    --paper:#fdf6e3; --paper-2:#eee8d5; --ink:#657b83; --ink-soft:#93a1a1;
    --line:#eee8d5; --line-2:#d8d2be;
    --accent:#268bd2; --accent-deep:#206ea4; --teal:#2aa198;
    --chrome:#eee8d5; --chrome-edge:#d8d2be;
    --node-bg:#ffffff; --node-ink:#657b83;
    --canvas-dot:#d8d2be;
    --stage-glow:rgba(38,139,210,.05);
    --link:#268bd2;
    --shadow:0 1px 3px rgba(7,54,66,.12),0 8px 24px rgba(7,54,66,.10);
    --shadow-lg:0 12px 40px rgba(7,54,66,.18);
  }
:root[data-theme="scholar-parchment"]{   /* Scholar Parchment */
    --toolbar-bg:#053327; --toolbar-text:#faf8f3;
    --paper:#faf8f3; --paper-2:#f1ece1; --ink:#2c2c2a; --ink-soft:#5a5a56;
    --line:#e2ddd3; --line-2:#d4cdbe;
    --accent:#0a4d3c; --accent-deep:#063a2e; --teal:#c5a059;
    --chrome:#f1ece1; --chrome-edge:#e2ddd3;
    --node-bg:#ffffff; --node-ink:#2c2c2a;
    --canvas-dot:#e2ddd3;
    --stage-glow:rgba(197,160,89,.06);
    --link:#0a4d3c;
    --shadow:0 1px 3px rgba(44,44,42,.10),0 8px 24px rgba(44,44,42,.08);
    --shadow-lg:0 12px 40px rgba(44,44,42,.16);
  }
:root[data-theme="paper-ink"]{   /* Paper & Ink editorial */
    --toolbar-bg:#111111; --toolbar-text:#fcfbf7;
    --paper:#fcfbf7; --paper-2:#f1efe9; --ink:#343434; --ink-soft:#77736b;
    --line:#ddd9d0; --line-2:#cec9bd;
    --accent:#27364b; --accent-deep:#1b2636; --teal:#5c6b7a;
    --chrome:#f1efe9; --chrome-edge:#ddd9d0;
    --node-bg:#ffffff; --node-ink:#343434;
    --canvas-dot:#ddd9d0;
    --stage-glow:rgba(39,54,75,.05);
    --link:#27364b;
    --shadow:0 1px 3px rgba(52,52,52,.10),0 8px 24px rgba(52,52,52,.08);
    --shadow-lg:0 12px 40px rgba(52,52,52,.16);
  }
:root[data-theme="mint-graphite"]{   /* Mint Graphite */
    --toolbar-bg:#18251f; --toolbar-text:#f7fbf9;
    --paper:#f7fbf9; --paper-2:#e6f3ee; --ink:#34423c; --ink-soft:#71827a;
    --line:#d8e8e1; --line-2:#c6dbd1;
    --accent:#0f9f75; --accent-deep:#0b7e5c; --teal:#34d399;
    --chrome:#e6f3ee; --chrome-edge:#d8e8e1;
    --node-bg:#ffffff; --node-ink:#34423c;
    --canvas-dot:#d8e8e1;
    --stage-glow:rgba(15,159,117,.05);
    --link:#0f9f75;
    --shadow:0 1px 3px rgba(52,66,60,.10),0 8px 24px rgba(52,66,60,.08);
    --shadow-lg:0 12px 40px rgba(52,66,60,.16);
  }
:root[data-theme="carbon-amber"]{   /* Carbon & Amber CAD */
    --toolbar-bg:#ffd066; --toolbar-text:#121212;
    --paper:#121212; --paper-2:#1a1400; --ink:#d4af37; --ink-soft:#8c6a00;
    --line:#332600; --line-2:#4a3a00;
    --accent:#ffb000; --accent-deep:#c98f00; --teal:#ffd066;
    --chrome:#1a1400; --chrome-edge:#332600;
    --node-bg:#1f1800; --node-ink:#d4af37;
    --canvas-dot:#332600;
    --stage-glow:rgba(255,176,0,.06);
    --link:#ffb000;
    --shadow:0 2px 4px rgba(0,0,0,.40),0 8px 24px rgba(0,0,0,.55);
    --shadow-lg:0 12px 40px rgba(0,0,0,.65);
  }
:root[data-theme="cyber-quantum"]{   /* Cyber-Quantum */
    --toolbar-bg:#e2f8ff; --toolbar-text:#0a101d;
    --paper:#0a101d; --paper-2:#10192c; --ink:#e2f8ff; --ink-soft:#62879b;
    --line:#1b3b4d; --line-2:#28526b;
    --accent:#00f0ff; --accent-deep:#00b8c4; --teal:#ff0055;
    --chrome:#10192c; --chrome-edge:#1b3b4d;
    --node-bg:#10192c; --node-ink:#e2f8ff;
    --canvas-dot:#1b3b4d;
    --stage-glow:rgba(0,240,255,.07);
    --link:#00f0ff;
    --shadow:0 2px 4px rgba(0,0,0,.40),0 8px 24px rgba(0,0,0,.55);
    --shadow-lg:0 12px 40px rgba(0,0,0,.65);
  }
:root[data-theme="blueprint"]{   /* Architectural Blueprint */
    --toolbar-bg:#e0f2fe; --toolbar-text:#005596;
    --paper:#005596; --paper-2:#004478; --ink:#e0f2fe; --ink-soft:#7dd3fc;
    --line:#4080b0; --line-2:#5797c2;
    --accent:#ffffff; --accent-deep:#c9e3f5; --teal:#7dd3fc;
    --chrome:#004478; --chrome-edge:#4080b0;
    --node-bg:#004478; --node-ink:#e0f2fe;
    --canvas-dot:#4080b0;
    --stage-glow:rgba(255,255,255,.08);
    --link:#7dd3fc;
    --shadow:0 2px 4px rgba(0,0,0,.35),0 8px 24px rgba(0,0,0,.50);
    --shadow-lg:0 12px 40px rgba(0,0,0,.60);
  }
:root[data-theme="obsidian"]{   /* Obsidian Terminal */
    --toolbar-bg:#ffffff; --toolbar-text:#000000;
    --paper:#000000; --paper-2:#18181b; --ink:#a1a1aa; --ink-soft:#52525b;
    --line:#27272a; --line-2:#333338;
    --accent:#ffffff; --accent-deep:#d4d4d8; --teal:#e4e4e7;
    --chrome:#18181b; --chrome-edge:#27272a;
    --node-bg:#18181b; --node-ink:#a1a1aa;
    --canvas-dot:#27272a;
    --stage-glow:rgba(255,255,255,.05);
    --link:#ffffff;
    --shadow:0 2px 4px rgba(0,0,0,.50),0 8px 24px rgba(0,0,0,.65);
    --shadow-lg:0 12px 40px rgba(0,0,0,.75);
  }
:root[data-theme="swiss-crimson"]{   /* Swiss Crimson */
    --toolbar-bg:#000000; --toolbar-text:#f4f4f4;
    --paper:#f4f4f4; --paper-2:#e6e6e6; --ink:#111111; --ink-soft:#666666;
    --line:#d1d1d1; --line-2:#c0c0c0;
    --accent:#d90429; --accent-deep:#a60320; --teal:#2f2f2f;
    --chrome:#e6e6e6; --chrome-edge:#d1d1d1;
    --node-bg:#ffffff; --node-ink:#111111;
    --canvas-dot:#d1d1d1;
    --stage-glow:rgba(217,4,41,.05);
    --link:#d90429;
    --shadow:0 1px 3px rgba(17,17,17,.10),0 8px 24px rgba(17,17,17,.08);
    --shadow-lg:0 12px 40px rgba(17,17,17,.16);
  }
:root[data-theme="nordic-sage"]{   /* Nordic Pine & Sage */
    --toolbar-bg:#1b2621; --toolbar-text:#f3f5f3;
    --paper:#f3f5f3; --paper-2:#e4eae6; --ink:#2d3a34; --ink-soft:#687770;
    --line:#d5ddd8; --line-2:#c3cdc7;
    --accent:#3b604d; --accent-deep:#2c4a3a; --teal:#52b788;
    --chrome:#e4eae6; --chrome-edge:#d5ddd8;
    --node-bg:#ffffff; --node-ink:#2d3a34;
    --canvas-dot:#d5ddd8;
    --stage-glow:rgba(59,96,77,.05);
    --link:#3b604d;
    --shadow:0 1px 3px rgba(45,58,52,.10),0 8px 24px rgba(45,58,52,.08);
    --shadow-lg:0 12px 40px rgba(45,58,52,.16);
  }
:root[data-theme="deep-ocean"]{   /* Deep Ocean Phosphor */
    --toolbar-bg:#e6fffa; --toolbar-text:#06181d;
    --paper:#06181d; --paper-2:#0d282e; --ink:#a3e5d9; --ink-soft:#3b7a70;
    --line:#113836; --line-2:#1a4a45;
    --accent:#10b981; --accent-deep:#0b8e61; --teal:#5eead4;
    --chrome:#0d282e; --chrome-edge:#113836;
    --node-bg:#0d282e; --node-ink:#a3e5d9;
    --canvas-dot:#113836;
    --stage-glow:rgba(16,185,129,.06);
    --link:#10b981;
    --shadow:0 2px 4px rgba(0,0,0,.40),0 8px 24px rgba(0,0,0,.55);
    --shadow-lg:0 12px 40px rgba(0,0,0,.65);
  }
:root[data-theme="google-material"]{   /* Google Material You */
    --toolbar-bg:#e3e2e6; --toolbar-text:#1f1f1f;
    --paper:#1f1f1f; --paper-2:#2d2d2d; --ink:#e3e2e6; --ink-soft:#8e918f;
    --line:#444746; --line-2:#56595a;
    --accent:#a8c7fa; --accent-deep:#7fa8e8; --teal:#81d4fa;
    --chrome:#2d2d2d; --chrome-edge:#444746;
    --node-bg:#2d2d2d; --node-ink:#e3e2e6;
    --canvas-dot:#444746;
    --stage-glow:rgba(168,199,250,.05);
    --link:#a8c7fa;
    --shadow:0 2px 4px rgba(0,0,0,.35),0 8px 24px rgba(0,0,0,.50);
    --shadow-lg:0 12px 40px rgba(0,0,0,.60);
  }
:root[data-theme="github-modern"]{   /* GitHub Modern (dark dimmed) */
    --toolbar-bg:#cdd9e5; --toolbar-text:#22272e;
    --paper:#22272e; --paper-2:#2d333b; --ink:#adbac7; --ink-soft:#768390;
    --line:#444c56; --line-2:#545d68;
    --accent:#539bf5; --accent-deep:#316dca; --teal:#3fb950;
    --chrome:#2d333b; --chrome-edge:#444c56;
    --node-bg:#2d333b; --node-ink:#adbac7;
    --canvas-dot:#444c56;
    --stage-glow:rgba(83,155,245,.05);
    --link:#539bf5;
    --shadow:0 2px 4px rgba(0,0,0,.30),0 8px 24px rgba(0,0,0,.45);
    --shadow-lg:0 12px 40px rgba(0,0,0,.55);
  }
:root[data-theme="sakura-drift"]{   /* Eos Sakura Drift */
    --toolbar-bg:#2c1e23; --toolbar-text:#fff9fa;
    --paper:#fff9fa; --paper-2:#ffebf0; --ink:#4a3e43; --ink-soft:#9e8890;
    --line:#f7d6df; --line-2:#efc3ce;
    --accent:#ff758f; --accent-deep:#e35472; --teal:#8d86c9;
    --chrome:#ffebf0; --chrome-edge:#f7d6df;
    --node-bg:#ffffff; --node-ink:#4a3e43;
    --canvas-dot:#f7d6df;
    --stage-glow:rgba(255,117,143,.05);
    --link:#ff758f;
    --shadow:0 1px 3px rgba(74,62,67,.10),0 8px 24px rgba(74,62,67,.08);
    --shadow-lg:0 12px 40px rgba(74,62,67,.16);
  }
:root[data-theme="aurora-frost"]{   /* Nordic Aurora Frost */
    --toolbar-bg:#e0fbfc; --toolbar-text:#0b132b;
    --paper:#0b132b; --paper-2:#1c2541; --ink:#c0d6df; --ink-soft:#486581;
    --line:#1c2541; --line-2:#2a3a5e;
    --accent:#70e000; --accent-deep:#54a800; --teal:#64dfdf;
    --chrome:#1c2541; --chrome-edge:#1c2541;
    --node-bg:#1c2541; --node-ink:#c0d6df;
    --canvas-dot:#1c2541;
    --stage-glow:rgba(112,224,0,.06);
    --link:#70e000;
    --shadow:0 2px 4px rgba(0,0,0,.35),0 8px 24px rgba(0,0,0,.50);
    --shadow-lg:0 12px 40px rgba(0,0,0,.60);
  }
:root[data-theme="espresso"]{   /* Velvet Espresso & Caramel */
    --toolbar-bg:#faedcd; --toolbar-text:#1a1412;
    --paper:#1a1412; --paper-2:#281e19; --ink:#e3d5ca; --ink-soft:#8c7a6b;
    --line:#382b24; --line-2:#473731;
    --accent:#d4a373; --accent-deep:#b08350; --teal:#bc6c25;
    --chrome:#281e19; --chrome-edge:#382b24;
    --node-bg:#281e19; --node-ink:#e3d5ca;
    --canvas-dot:#382b24;
    --stage-glow:rgba(212,163,115,.06);
    --link:#d4a373;
    --shadow:0 2px 4px rgba(0,0,0,.40),0 8px 24px rgba(0,0,0,.55);
    --shadow-lg:0 12px 40px rgba(0,0,0,.65);
  }
:root[data-theme="arctic-glass"]{   /* Arctic Glass */
    --toolbar-bg:#102a43; --toolbar-text:#f4faff;
    --paper:#f4faff; --paper-2:#e9f5fb; --ink:#274154; --ink-soft:#6b8496;
    --line:#d6eaf4; --line-2:#c4deeb;
    --accent:#149bd7; --accent-deep:#0f7cac; --teal:#38bdf8;
    --chrome:#e9f5fb; --chrome-edge:#d6eaf4;
    --node-bg:#ffffff; --node-ink:#274154;
    --canvas-dot:#d6eaf4;
    --stage-glow:rgba(20,155,215,.05);
    --link:#149bd7;
    --shadow:0 1px 3px rgba(39,65,84,.10),0 8px 24px rgba(39,65,84,.08);
    --shadow-lg:0 12px 40px rgba(39,65,84,.16);
  }
:root[data-theme="copper-lab"]{   /* Copper Laboratory */
    --toolbar-bg:#fff8f2; --toolbar-text:#1b1715;
    --paper:#1b1715; --paper-2:#29201c; --ink:#e4d7ce; --ink-soft:#927c70;
    --line:#463128; --line-2:#573d32;
    --accent:#d97745; --accent-deep:#b45b30; --teal:#e89a70;
    --chrome:#29201c; --chrome-edge:#463128;
    --node-bg:#29201c; --node-ink:#e4d7ce;
    --canvas-dot:#463128;
    --stage-glow:rgba(217,119,69,.06);
    --link:#d97745;
    --shadow:0 2px 4px rgba(0,0,0,.40),0 8px 24px rgba(0,0,0,.55);
    --shadow-lg:0 12px 40px rgba(0,0,0,.65);
  }
:root[data-theme="forest-night"]{   /* Forest Night */
    --toolbar-bg:#f4fff8; --toolbar-text:#101b17;
    --paper:#101b17; --paper-2:#172720; --ink:#d5e5dc; --ink-soft:#71897d;
    --line:#294138; --line-2:#345448;
    --accent:#63c174; --accent-deep:#4a9e5d; --teal:#76d98a;
    --chrome:#172720; --chrome-edge:#294138;
    --node-bg:#172720; --node-ink:#d5e5dc;
    --canvas-dot:#294138;
    --stage-glow:rgba(99,193,116,.06);
    --link:#63c174;
    --shadow:0 2px 4px rgba(0,0,0,.35),0 8px 24px rgba(0,0,0,.50);
    --shadow-lg:0 12px 40px rgba(0,0,0,.60);
  }
:root[data-theme="cobalt"]{   /* Cobalt Studio */
    --toolbar-bg:#d7e3ff; --toolbar-text:#0b1530;
    --paper:#0b1530; --paper-2:#121f42; --ink:#d7e3ff; --ink-soft:#7082a8;
    --line:#263b6b; --line-2:#304a87;
    --accent:#4f8cff; --accent-deep:#3a6dd6; --teal:#78a9ff;
    --chrome:#121f42; --chrome-edge:#263b6b;
    --node-bg:#121f42; --node-ink:#d7e3ff;
    --canvas-dot:#263b6b;
    --stage-glow:rgba(79,140,255,.06);
    --link:#4f8cff;
    --shadow:0 2px 4px rgba(0,0,0,.35),0 8px 24px rgba(0,0,0,.50);
    --shadow-lg:0 12px 40px rgba(0,0,0,.60);
  }
:root[data-theme="lavender-mist"]{   /* Lavender Mist */
    --toolbar-bg:#211a32; --toolbar-text:#faf8ff;
    --paper:#faf8ff; --paper-2:#f0ebfa; --ink:#403a52; --ink-soft:#817a94;
    --line:#e4ddf2; --line-2:#d6cee8;
    --accent:#7956c8; --accent-deep:#6041a6; --teal:#b69cff;
    --chrome:#f0ebfa; --chrome-edge:#e4ddf2;
    --node-bg:#ffffff; --node-ink:#403a52;
    --canvas-dot:#e4ddf2;
    --stage-glow:rgba(121,86,200,.05);
    --link:#7956c8;
    --shadow:0 1px 3px rgba(64,58,82,.10),0 8px 24px rgba(64,58,82,.08);
    --shadow-lg:0 12px 40px rgba(64,58,82,.16);
  }
:root[data-theme="ruby-night"]{   /* Ruby Night */
    --toolbar-bg:#ffd4dc; --toolbar-text:#151314;
    --paper:#151314; --paper-2:#24191c; --ink:#e8dddf; --ink-soft:#8e7a7e;
    --line:#43242b; --line-2:#57313a;
    --accent:#f43f5e; --accent-deep:#c62b47; --teal:#ff7187;
    --chrome:#24191c; --chrome-edge:#43242b;
    --node-bg:#24191c; --node-ink:#e8dddf;
    --canvas-dot:#43242b;
    --stage-glow:rgba(244,63,94,.07);
    --link:#f43f5e;
    --shadow:0 2px 4px rgba(0,0,0,.40),0 8px 24px rgba(0,0,0,.55);
    --shadow-lg:0 12px 40px rgba(0,0,0,.65);
  }
:root[data-theme="sandstone"]{   /* Sandstone */
    --toolbar-bg:#2d2118; --toolbar-text:#fbf6ee;
    --paper:#fbf6ee; --paper-2:#f3e7d4; --ink:#51463a; --ink-soft:#8a7967;
    --line:#e8d8c2; --line-2:#dcc9ae;
    --accent:#b45309; --accent-deep:#924308; --teal:#e99a55;
    --chrome:#f3e7d4; --chrome-edge:#e8d8c2;
    --node-bg:#ffffff; --node-ink:#51463a;
    --canvas-dot:#e8d8c2;
    --stage-glow:rgba(180,83,9,.06);
    --link:#b45309;
    --shadow:0 1px 3px rgba(81,70,58,.10),0 8px 24px rgba(81,70,58,.08);
    --shadow-lg:0 12px 40px rgba(81,70,58,.16);
  }
:root[data-theme="electric-indigo"]{   /* Electric Indigo */
    --toolbar-bg:#e9e2ff; --toolbar-text:#0e0a22;
    --paper:#0e0a22; --paper-2:#191238; --ink:#dcd7ff; --ink-soft:#7770a5;
    --line:#33255b; --line-2:#42336f;
    --accent:#8b5cf6; --accent-deep:#6f3ed4; --teal:#a78bfa;
    --chrome:#191238; --chrome-edge:#33255b;
    --node-bg:#191238; --node-ink:#dcd7ff;
    --canvas-dot:#33255b;
    --stage-glow:rgba(139,92,246,.07);
    --link:#8b5cf6;
    --shadow:0 2px 4px rgba(0,0,0,.40),0 8px 24px rgba(0,0,0,.55);
    --shadow-lg:0 12px 40px rgba(0,0,0,.65);
  }
:root[data-theme="teal-paper"]{   /* Teal Paper */
    --toolbar-bg:#12322f; --toolbar-text:#f7fcfb;
    --paper:#f7fcfb; --paper-2:#e6f2f0; --ink:#304744; --ink-soft:#6f8581;
    --line:#d4e7e3; --line-2:#c2dcd6;
    --accent:#0f766e; --accent-deep:#0b5a54; --teal:#2dd4bf;
    --chrome:#e6f2f0; --chrome-edge:#d4e7e3;
    --node-bg:#ffffff; --node-ink:#304744;
    --canvas-dot:#d4e7e3;
    --stage-glow:rgba(15,118,110,.05);
    --link:#0f766e;
    --shadow:0 1px 3px rgba(48,71,68,.10),0 8px 24px rgba(48,71,68,.08);
    --shadow-lg:0 12px 40px rgba(48,71,68,.16);
  }
:root[data-theme="steel-orange"]{   /* Steel & Orange */
    --toolbar-bg:#d9dee3; --toolbar-text:#171a1d;
    --paper:#171a1d; --paper-2:#23282d; --ink:#d9dee3; --ink-soft:#7d8790;
    --line:#353b40; --line-2:#454c54;
    --accent:#f97316; --accent-deep:#d15c0b; --teal:#ff9a55;
    --chrome:#23282d; --chrome-edge:#353b40;
    --node-bg:#23282d; --node-ink:#d9dee3;
    --canvas-dot:#353b40;
    --stage-glow:rgba(249,115,22,.06);
    --link:#f97316;
    --shadow:0 2px 4px rgba(0,0,0,.40),0 8px 24px rgba(0,0,0,.55);
    --shadow-lg:0 12px 40px rgba(0,0,0,.65);
  }
:root[data-theme="cosmic-rose"]{   /* Cosmic Rose */
    --toolbar-bg:#ffd6ec; --toolbar-text:#100c1b;
    --paper:#100c1b; --paper-2:#20142a; --ink:#e4d9ea; --ink-soft:#86708f;
    --line:#38223f; --line-2:#482c52;
    --accent:#f472b6; --accent-deep:#d44e97; --teal:#f9a8d4;
    --chrome:#20142a; --chrome-edge:#38223f;
    --node-bg:#20142a; --node-ink:#e4d9ea;
    --canvas-dot:#38223f;
    --stage-glow:rgba(244,114,182,.07);
    --link:#f472b6;
    --shadow:0 2px 4px rgba(0,0,0,.40),0 8px 24px rgba(0,0,0,.55);
    --shadow-lg:0 12px 40px rgba(0,0,0,.65);
  }
:root[data-theme="plasma-crimson"]{   /* Plasma Crimson */
    --toolbar-bg:#ffe8ed; --toolbar-text:#12080c;
    --paper:#12080c; --paper-2:#1f0e14; --ink:#f5d0d8; --ink-soft:#a56b78;
    --line:#4a1a28; --line-2:#5f2233;
    --accent:#ff2d55; --accent-deep:#d10f36; --teal:#ff5c7a;
    --chrome:#1f0e14; --chrome-edge:#4a1a28;
    --node-bg:#1f0e14; --node-ink:#f5d0d8;
    --canvas-dot:#4a1a28;
    --stage-glow:rgba(255,45,85,.08);
    --link:#ff2d55;
    --shadow:0 2px 4px rgba(0,0,0,.45),0 8px 24px rgba(0,0,0,.60);
    --shadow-lg:0 12px 40px rgba(0,0,0,.70);
  }
:root[data-theme="neon-noir"]{   /* Neon Noir */
    --toolbar-bg:#ffffff; --toolbar-text:#0a0a0f;
    --paper:#0a0a0f; --paper-2:#12121c; --ink:#c8c8d4; --ink-soft:#5a5a70;
    --line:#1f1f2e; --line-2:#2a2a3e;
    --accent:#00ff9f; --accent-deep:#00cc7e; --teal:#a0ffd0;
    --chrome:#12121c; --chrome-edge:#1f1f2e;
    --node-bg:#12121c; --node-ink:#c8c8d4;
    --canvas-dot:#1f1f2e;
    --stage-glow:rgba(0,255,159,.07);
    --link:#00ff9f;
    --shadow:0 2px 4px rgba(0,0,0,.45),0 8px 24px rgba(0,0,0,.60);
    --shadow-lg:0 12px 40px rgba(0,0,0,.70);
  }
:root[data-theme="desert-oasis"]{   /* Desert Oasis */
    --toolbar-bg:#2c2116; --toolbar-text:#fdf6e9;
    --paper:#fdf6e9; --paper-2:#f5e8d0; --ink:#4a3c2a; --ink-soft:#8a7a62;
    --line:#e8d5b5; --line-2:#dcc59e;
    --accent:#d97706; --accent-deep:#b45f05; --teal:#f59e0b;
    --chrome:#f5e8d0; --chrome-edge:#e8d5b5;
    --node-bg:#ffffff; --node-ink:#4a3c2a;
    --canvas-dot:#e8d5b5;
    --stage-glow:rgba(217,119,6,.06);
    --link:#d97706;
    --shadow:0 1px 3px rgba(74,60,42,.10),0 8px 24px rgba(74,60,42,.08);
    --shadow-lg:0 12px 40px rgba(74,60,42,.16);
  }
:root[data-theme="ice-crystal"]{   /* Ice Crystal */
    --toolbar-bg:#0c1e36; --toolbar-text:#f0f9ff;
    --paper:#f0f9ff; --paper-2:#e0f2fe; --ink:#1e3a5f; --ink-soft:#5b7a9a;
    --line:#bae6fd; --line-2:#a4d9f5;
    --accent:#0ea5e9; --accent-deep:#0b84bc; --teal:#38bdf8;
    --chrome:#e0f2fe; --chrome-edge:#bae6fd;
    --node-bg:#ffffff; --node-ink:#1e3a5f;
    --canvas-dot:#bae6fd;
    --stage-glow:rgba(14,165,233,.05);
    --link:#0ea5e9;
    --shadow:0 1px 3px rgba(30,58,95,.10),0 8px 24px rgba(30,58,95,.08);
    --shadow-lg:0 12px 40px rgba(30,58,95,.16);
  }
:root[data-theme="ember-forge"]{   /* Ember Forge */
    --toolbar-bg:#fff5eb; --toolbar-text:#140e0a;
    --paper:#140e0a; --paper-2:#221610; --ink:#e8d5c4; --ink-soft:#9a7a62;
    --line:#3d2418; --line-2:#4e2d1e;
    --accent:#ef4444; --accent-deep:#c92828; --teal:#f87171;
    --chrome:#221610; --chrome-edge:#3d2418;
    --node-bg:#221610; --node-ink:#e8d5c4;
    --canvas-dot:#3d2418;
    --stage-glow:rgba(239,68,68,.08);
    --link:#ef4444;
    --shadow:0 2px 4px rgba(0,0,0,.45),0 8px 24px rgba(0,0,0,.60);
    --shadow-lg:0 12px 40px rgba(0,0,0,.70);
  }
:root[data-theme="violet-circuit"]{   /* Violet Circuit */
    --toolbar-bg:#f5f0ff; --toolbar-text:#0f0a1a;
    --paper:#0f0a1a; --paper-2:#1a1230; --ink:#d4c8f0; --ink-soft:#7a6a9a;
    --line:#2e1f4a; --line-2:#3b2960;
    --accent:#a855f7; --accent-deep:#8b33de; --teal:#c084fc;
    --chrome:#1a1230; --chrome-edge:#2e1f4a;
    --node-bg:#1a1230; --node-ink:#d4c8f0;
    --canvas-dot:#2e1f4a;
    --stage-glow:rgba(168,85,247,.08);
    --link:#a855f7;
    --shadow:0 2px 4px rgba(0,0,0,.45),0 8px 24px rgba(0,0,0,.60);
    --shadow-lg:0 12px 40px rgba(0,0,0,.70);
  }
:root[data-theme="moss-stone"]{   /* Moss & Stone */
    --toolbar-bg:#1a2416; --toolbar-text:#f4f6f0;
    --paper:#f4f6f0; --paper-2:#e8eedc; --ink:#2e3a2a; --ink-soft:#6a7a62;
    --line:#d4dcc8; --line-2:#c2ccb4;
    --accent:#4d7c0f; --accent-deep:#3a5e0b; --teal:#84cc16;
    --chrome:#e8eedc; --chrome-edge:#d4dcc8;
    --node-bg:#ffffff; --node-ink:#2e3a2a;
    --canvas-dot:#d4dcc8;
    --stage-glow:rgba(77,124,15,.06);
    --link:#4d7c0f;
    --shadow:0 1px 3px rgba(46,58,42,.10),0 8px 24px rgba(46,58,42,.08);
    --shadow-lg:0 12px 40px rgba(46,58,42,.16);
  }
:root[data-theme="twilight-amber"]{   /* Twilight Amber */
    --toolbar-bg:#fff8ec; --toolbar-text:#16120c;
    --paper:#16120c; --paper-2:#241e14; --ink:#e8dcc8; --ink-soft:#9a8a6a;
    --line:#3a3020; --line-2:#4a3d2a;
    --accent:#fbbf24; --accent-deep:#d19f12; --teal:#fcd34d;
    --chrome:#241e14; --chrome-edge:#3a3020;
    --node-bg:#241e14; --node-ink:#e8dcc8;
    --canvas-dot:#3a3020;
    --stage-glow:rgba(251,191,36,.07);
    --link:#fbbf24;
    --shadow:0 2px 4px rgba(0,0,0,.40),0 8px 24px rgba(0,0,0,.55);
    --shadow-lg:0 12px 40px rgba(0,0,0,.65);
  }
:root[data-theme="ocean-depth"]{   /* Ocean Depth */
    --toolbar-bg:#e8f4fa; --toolbar-text:#06141c;
    --paper:#06141c; --paper-2:#0c1e28; --ink:#b8d8e8; --ink-soft:#4a7a90;
    --line:#0e2a38; --line-2:#163e52;
    --accent:#22d3ee; --accent-deep:#18aec7; --teal:#67e8f9;
    --chrome:#0c1e28; --chrome-edge:#0e2a38;
    --node-bg:#0c1e28; --node-ink:#b8d8e8;
    --canvas-dot:#0e2a38;
    --stage-glow:rgba(34,211,238,.07);
    --link:#22d3ee;
    --shadow:0 2px 4px rgba(0,0,0,.40),0 8px 24px rgba(0,0,0,.55);
    --shadow-lg:0 12px 40px rgba(0,0,0,.65);
  }
:root[data-theme="charcoal-gold"]{   /* Charcoal Gold */
    --toolbar-bg:#f5f0e6; --toolbar-text:#121212;
    --paper:#121212; --paper-2:#1c1c18; --ink:#d4d0c8; --ink-soft:#8a8678;
    --line:#2e2e28; --line-2:#3c3c34;
    --accent:#eab308; --accent-deep:#c29304; --teal:#facc15;
    --chrome:#1c1c18; --chrome-edge:#2e2e28;
    --node-bg:#1c1c18; --node-ink:#d4d0c8;
    --canvas-dot:#2e2e28;
    --stage-glow:rgba(234,179,8,.07);
    --link:#eab308;
    --shadow:0 2px 4px rgba(0,0,0,.40),0 8px 24px rgba(0,0,0,.55);
    --shadow-lg:0 12px 40px rgba(0,0,0,.65);
  }
:root[data-theme="soft-clay"]{   /* Soft Clay */
    --toolbar-bg:#2a1e18; --toolbar-text:#fbf6f2;
    --paper:#fbf6f2; --paper-2:#f5e8e0; --ink:#4a3a32; --ink-soft:#8a7468;
    --line:#e8d8cc; --line-2:#dcc8b8;
    --accent:#c2410c; --accent-deep:#9c340a; --teal:#fb923c;
    --chrome:#f5e8e0; --chrome-edge:#e8d8cc;
    --node-bg:#ffffff; --node-ink:#4a3a32;
    --canvas-dot:#e8d8cc;
    --stage-glow:rgba(194,65,12,.06);
    --link:#c2410c;
    --shadow:0 1px 3px rgba(74,58,50,.10),0 8px 24px rgba(74,58,50,.08);
    --shadow-lg:0 12px 40px rgba(74,58,50,.16);
  }
:root[data-theme="azure-horizon"]{   /* Azure Horizon */
    --toolbar-bg:#e8f4ff; --toolbar-text:#0a1420;
    --paper:#0a1420; --paper-2:#121e30; --ink:#c0d8f0; --ink-soft:#5a7a9a;
    --line:#1a2e48; --line-2:#234063;
    --accent:#3b82f6; --accent-deep:#2e66d6; --teal:#60a5fa;
    --chrome:#121e30; --chrome-edge:#1a2e48;
    --node-bg:#121e30; --node-ink:#c0d8f0;
    --canvas-dot:#1a2e48;
    --stage-glow:rgba(59,130,246,.07);
    --link:#3b82f6;
    --shadow:0 2px 4px rgba(0,0,0,.40),0 8px 24px rgba(0,0,0,.55);
    --shadow-lg:0 12px 40px rgba(0,0,0,.65);
  }
:root[data-theme="jade-temple"]{   /* Jade Temple */
    --toolbar-bg:#e8fff4; --toolbar-text:#0a1612;
    --paper:#0a1612; --paper-2:#12241c; --ink:#c0e0d4; --ink-soft:#4a8a72;
    --line:#1a3a2e; --line-2:#234c3c;
    --accent:#10b981; --accent-deep:#0c9668; --teal:#34d399;
    --chrome:#12241c; --chrome-edge:#1a3a2e;
    --node-bg:#12241c; --node-ink:#c0e0d4;
    --canvas-dot:#1a3a2e;
    --stage-glow:rgba(16,185,129,.07);
    --link:#10b981;
    --shadow:0 2px 4px rgba(0,0,0,.40),0 8px 24px rgba(0,0,0,.55);
    --shadow-lg:0 12px 40px rgba(0,0,0,.65);
  }
:root[data-theme="magenta-pulse"]{   /* Magenta Pulse */
    --toolbar-bg:#fff0ff; --toolbar-text:#140a16;
    --paper:#140a16; --paper-2:#221022; --ink:#e8d0e8; --ink-soft:#9a6a9a;
    --line:#3a1a3a; --line-2:#4a234a;
    --accent:#ec4899; --accent-deep:#c82e7b; --teal:#f472b6;
    --chrome:#221022; --chrome-edge:#3a1a3a;
    --node-bg:#221022; --node-ink:#e8d0e8;
    --canvas-dot:#3a1a3a;
    --stage-glow:rgba(236,72,153,.08);
    --link:#ec4899;
    --shadow:0 2px 4px rgba(0,0,0,.45),0 8px 24px rgba(0,0,0,.60);
    --shadow-lg:0 12px 40px rgba(0,0,0,.70);
  }
:root[data-theme="graphite-terminal"]{   /* Graphite Terminal */
    --toolbar-bg:#e8e8e8; --toolbar-text:#1a1a1a;
    --paper:#1a1a1a; --paper-2:#242424; --ink:#b8b8b8; --ink-soft:#6a6a6a;
    --line:#333333; --line-2:#424242;
    --accent:#60a5fa; --accent-deep:#4585e0; --teal:#93c5fd;
    --chrome:#242424; --chrome-edge:#333333;
    --node-bg:#242424; --node-ink:#b8b8b8;
    --canvas-dot:#333333;
    --stage-glow:rgba(96,165,250,.06);
    --link:#60a5fa;
    --shadow:0 2px 4px rgba(0,0,0,.40),0 8px 24px rgba(0,0,0,.55);
    --shadow-lg:0 12px 40px rgba(0,0,0,.65);
  }
:root[data-theme="honeycomb"]{   /* Honeycomb */
    --toolbar-bg:#2a1e0a; --toolbar-text:#fffbeb;
    --paper:#fffbeb; --paper-2:#fef3c7; --ink:#4a3a1a; --ink-soft:#8a7a4a;
    --line:#f5e6b0; --line-2:#ebd98e;
    --accent:#f59e0b; --accent-deep:#cc8108; --teal:#fbbf24;
    --chrome:#fef3c7; --chrome-edge:#f5e6b0;
    --node-bg:#ffffff; --node-ink:#4a3a1a;
    --canvas-dot:#f5e6b0;
    --stage-glow:rgba(245,158,11,.07);
    --link:#f59e0b;
    --shadow:0 1px 3px rgba(74,58,26,.10),0 8px 24px rgba(74,58,26,.08);
    --shadow-lg:0 12px 40px rgba(74,58,26,.16);
  }
:root[data-theme="frosted-pine"]{   /* Frosted Pine */
    --toolbar-bg:#e8f8ec; --toolbar-text:#0c1610;
    --paper:#0c1610; --paper-2:#122018; --ink:#c0d8c8; --ink-soft:#5a8a6a;
    --line:#1a3a28; --line-2:#234c34;
    --accent:#34d399; --accent-deep:#27ac7d; --teal:#6ee7b7;
    --chrome:#122018; --chrome-edge:#1a3a28;
    --node-bg:#122018; --node-ink:#c0d8c8;
    --canvas-dot:#1a3a28;
    --stage-glow:rgba(52,211,153,.07);
    --link:#34d399;
    --shadow:0 2px 4px rgba(0,0,0,.40),0 8px 24px rgba(0,0,0,.55);
    --shadow-lg:0 12px 40px rgba(0,0,0,.65);
  }
:root[data-theme="quantum-violet"]{   /* Quantum Violet */
    --toolbar-bg:#f0ecff; --toolbar-text:#0e0a18;
    --paper:#0e0a18; --paper-2:#18122a; --ink:#d0c8e8; --ink-soft:#7a6a9a;
    --line:#2a1e48; --line-2:#38295e;
    --accent:#8b5cf6; --accent-deep:#6f3ee0; --teal:#a78bfa;
    --chrome:#18122a; --chrome-edge:#2a1e48;
    --node-bg:#18122a; --node-ink:#d0c8e8;
    --canvas-dot:#2a1e48;
    --stage-glow:rgba(139,92,246,.08);
    --link:#8b5cf6;
    --shadow:0 2px 4px rgba(0,0,0,.45),0 8px 24px rgba(0,0,0,.60);
    --shadow-lg:0 12px 40px rgba(0,0,0,.70);
  }
:root[data-theme="copper-rust"]{   /* Copper Rust */
    --toolbar-bg:#fff5ec; --toolbar-text:#16120e;
    --paper:#16120e; --paper-2:#241a12; --ink:#e0d0c0; --ink-soft:#9a7a62;
    --line:#3a2a1e; --line-2:#4a3728;
    --accent:#ea580c; --accent-deep:#c04309; --teal:#fb923c;
    --chrome:#241a12; --chrome-edge:#3a2a1e;
    --node-bg:#241a12; --node-ink:#e0d0c0;
    --canvas-dot:#3a2a1e;
    --stage-glow:rgba(234,88,12,.08);
    --link:#ea580c;
    --shadow:0 2px 4px rgba(0,0,0,.40),0 8px 24px rgba(0,0,0,.55);
    --shadow-lg:0 12px 40px rgba(0,0,0,.65);
  }
:root[data-theme="lunar-silver"]{   /* Lunar Silver */
    --toolbar-bg:#f0f4f8; --toolbar-text:#0e1014;
    --paper:#0e1014; --paper-2:#181c22; --ink:#c8d0d8; --ink-soft:#6a7888;
    --line:#2a3038; --line-2:#383f49;
    --accent:#94a3b8; --accent-deep:#74828f; --teal:#cbd5e1;
    --chrome:#181c22; --chrome-edge:#2a3038;
    --node-bg:#181c22; --node-ink:#c8d0d8;
    --canvas-dot:#2a3038;
    --stage-glow:rgba(148,163,184,.06);
    --link:#94a3b8;
    --shadow:0 2px 4px rgba(0,0,0,.35),0 8px 24px rgba(0,0,0,.50);
    --shadow-lg:0 12px 40px rgba(0,0,0,.60);
  }
*{box-sizing:border-box}
  html,body{margin:0;height:100%;overflow:hidden;font-family:var(--sans);color:var(--ink);background:var(--paper)}
  button{font-family:inherit;cursor:pointer}

  /* ===== App shell ===== */
  /* Three rows: a top header, the main content, and a status bar. Both bars
     span only the tracks to the right of the sidebar (they start beside it,
     not above/below it); .side spans all three rows and .stage is placed
     explicitly so nothing is left to auto-placement. */
  .app{display:grid;grid-template-columns:auto 1fr;grid-template-rows:auto auto minmax(0,1fr) auto;height:calc(100vh / var(--ui-zoom, 1));height:calc(100dvh / var(--ui-zoom, 1))}
  .topbar{grid-column:2 / -1;grid-row:1}
  .side{grid-column:1;grid-row:1 / 5}
  .stage{grid-column:2;grid-row:3}
  .statusbar{grid-column:2 / -1;grid-row:4}
  #tabStrip{grid-column:2/-1;grid-row:2;display:flex;align-items:flex-end;gap:6px;padding:4px 12px 0;overflow:hidden}
  #tabStrip.hidden{display:none}   /* collapsed row = auto 0, so the stage takes its place */
  #tabRow{display:flex;gap:4px;overflow-x:auto;scrollbar-width:none;flex:1;min-width:0;align-items:flex-end}
  #tabRow::-webkit-scrollbar{display:none}
  #tabRow .tab{display:flex;align-items:center;gap:6px;max-width:200px;min-width:0;padding:5px 8px 6px 10px;border:1px solid var(--line);border-bottom:none;border-radius:10px 10px 0 0;background:var(--paper-2);cursor:pointer;font-family:inherit;font-size:12px;color:var(--ink-soft);position:relative;top:1px;transition:background-color .2s ease,color .2s ease,border-color .2s ease}
  #tabRow .tab:hover{color:var(--ink)}
  #tabRow .tab.active{background:var(--paper);color:var(--ink);font-weight:600;border-color:var(--line-2)}
  #tabRow .tab-title{white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
  #tabRow .tab-close{width:16px;height:16px;flex:0 0 auto;display:inline-flex;align-items:center;justify-content:center;border-radius:4px;font-size:10px;line-height:1;color:var(--ink-soft)}
  #tabRow .tab-close:hover{background:var(--hover);color:var(--ink)}
  .tab-new{flex:0 0 auto;width:30px;height:26px;border:1px dashed var(--line-2);background:none;color:var(--ink-soft);border-radius:8px 8px 0 0;cursor:pointer;font-size:16px;line-height:1;font-family:inherit}
  .tab-new:hover{color:var(--accent);border-color:var(--accent)}
  /* Floating shells and single-column layouts have no top strip row —
     the tab strip stays hidden there unless tabbed workspace is enabled. */
body.ui-classic:not(.tabs-on) #tabStrip, body.ui-rail:not(.tabs-on) #tabStrip, body.ui-zen:not(.tabs-on) #tabStrip, body.ui-mirror:not(.tabs-on) #tabStrip, body.ui-deck:not(.tabs-on) #tabStrip, body.ui-dock:not(.tabs-on) #tabStrip, body.ui-split:not(.tabs-on) #tabStrip, body.ui-minimal:not(.tabs-on) #tabStrip, body.ui-outline:not(.tabs-on) #tabStrip{display:none}
body.ui-rail.tabs-on .app{grid-template-rows:auto minmax(0,1fr)}
body.ui-rail.tabs-on #tabStrip{display:flex;grid-column:3/-1;grid-row:1}
body.ui-rail.tabs-on .side{grid-row:1/3}
body.ui-rail.tabs-on .topbar{grid-row:1/3}
body.ui-rail.tabs-on .stage{grid-column:3;grid-row:2}
body.ui-rail.tabs-on.md-ready .app{grid-template-rows:auto minmax(0,1fr)}
body.ui-rail.tabs-on.md-ready #tabStrip{grid-column:3/-1;grid-row:1}
body.ui-rail.tabs-on.md-ready #mdPane{grid-column:3;grid-row:2}
body.ui-rail.tabs-on.md-ready .stage{grid-column:4;grid-row:2}
body.ui-classic.tabs-on .app{grid-template-rows:auto minmax(0,1fr)}
body.ui-classic.tabs-on #tabStrip{display:flex;grid-column:2;grid-row:1}
body.ui-classic.tabs-on .side{grid-row:1/3}
body.ui-classic.tabs-on .stage{grid-column:2;grid-row:2}
body.ui-classic.tabs-on.md-ready .app{grid-template-rows:auto minmax(0,1fr)}
body.ui-classic.tabs-on.md-ready #tabStrip{grid-column:2/-1;grid-row:1}
body.ui-classic.tabs-on.md-ready #mdPane{grid-column:2;grid-row:2}
body.ui-classic.tabs-on.md-ready .stage{grid-column:3;grid-row:2}
  body.focus-mode #tabStrip{display:none}   /* focus is canvas-only */
  body.shared-view #tabStrip{display:none}  /* shared banner view is single-map */
  #tabRow .tab.active .tab-close{color:var(--ink-soft)}
  /* Markdown mode: split pane (editor | live map) */
  body.md-ready .app{grid-template-columns:auto auto minmax(0,1fr)}   /* md pane takes the middle track once it exists */
  #mdPane{width:0;overflow:hidden;position:relative;display:flex;flex-direction:column;min-width:0;min-height:0;background:var(--paper);border-right:1px solid var(--line);transition:width .22s cubic-bezier(.4,0,.2,1);grid-column:2;grid-row:3}
  body.md-ready .stage{grid-column:3;grid-row:3}
  body.md-mode #mdPane{width:var(--md-w,40vw)}
  body.md-resizing #mdPane{transition:none}                            /* no easing while dragging the divider */
  @media (prefers-reduced-motion: reduce){ #mdPane{transition:none} }
  #mdPane .md-head{display:flex;align-items:center;gap:8px;padding:8px 12px;border-bottom:1px solid var(--line);font-size:12px;font-weight:600;color:var(--ink-soft)}
  #mdPane .md-pos{margin-left:auto;font-size:11px;font-weight:400;color:var(--ink-soft);font-variant-numeric:tabular-nums}
  /* markdown editor formatting toolbar */
  #mdPane .md-toolbar{display:flex;flex-wrap:wrap;align-items:center;gap:2px;padding:4px 8px;border-bottom:1px solid var(--line);background:var(--paper)}
  #mdPane .md-toolbar button{min-width:26px;height:26px;padding:0 6px;border:1px solid transparent;background:transparent;color:var(--ink-soft);cursor:pointer;border-radius:6px;font-size:12px;font-weight:600;line-height:1;display:inline-flex;align-items:center;justify-content:center}
  #mdPane .md-toolbar button:hover{background:var(--paper-2,rgba(127,127,127,.12));color:var(--ink);border-color:var(--line)}
  #mdPane .md-toolbar button s{text-decoration:line-through}
  #mdPane .md-toolbar .md-sep{width:1px;height:16px;background:var(--line);margin:0 4px}
  #mdPane.md-preview .md-toolbar{display:none}
  #mdPane .md-close{border:none;background:transparent;cursor:pointer;font-size:15px;line-height:1;color:var(--ink-soft);padding:2px 7px;border-radius:6px}
  #mdPane .md-close:hover{background:var(--paper-2,rgba(0,0,0,.05))}
  #mdPane .md-body{display:flex;flex:1;min-height:0;overflow:hidden}
  #mdPane .md-gutter{flex:0 0 auto;box-sizing:border-box;padding:12px 6px 12px 8px;text-align:right;overflow:hidden;user-select:none;background:var(--paper);border-right:1px solid var(--line);color:var(--ink-soft);font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;font-size:13px;line-height:20px}
  #mdPane .md-gutter .gl{height:20px;display:flex;align-items:center;justify-content:flex-end;gap:1px}
  #mdPane .md-gutter .gl.active{color:var(--accent);font-weight:700}
  #mdPane .md-gutter .gl-fold{flex:0 0 12px;width:12px;height:16px;display:inline-flex;align-items:center;justify-content:center;font-size:9px;line-height:1;border-radius:3px;cursor:pointer;color:var(--ink-soft);opacity:.7}
  #mdPane .md-gutter .gl-fold:empty{cursor:default}
  #mdPane .md-gutter .gl-fold:not(:empty):hover{background:color-mix(in srgb, var(--ink-soft) 20%, transparent);opacity:1}
  #mdPane .md-gutter .gl-num{min-width:1.6em}
  #mdPane .md-code{position:relative;flex:1;min-width:0;overflow:hidden}
  #mdPane .md-hl,#mdEditor{position:absolute;inset:0;margin:0;box-sizing:border-box;padding:12px 14px;border:0;font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;font-size:13px;line-height:20px;white-space:pre;tab-size:2}
  #mdPane .md-hl{overflow:hidden;pointer-events:none;color:var(--ink)}
  /* Scroll-sync targets a plain inner wrapper via transform, not the outer .md-hl/.md-gutter
     (which must stay put so their own overflow:hidden keeps clipping the visible window). */
  #mdPane .md-hl-inner,#mdPane .md-gutter-inner{will-change:transform}
  #mdPane .md-hl .hl-line{min-height:20px}
  /* active-line highlight: a real background on the actual row div — it's always exactly
     where the caret is, in or out of view, with no separate pixel math to keep in sync
     while clicking or scrolling (that used to drift; this can't). */
  #mdPane .md-hl .hl-line.active{background:var(--paper-2,rgba(127,127,127,.10))}
  #mdPane .md-fold-chip{display:inline-block;margin-left:6px;padding:0 7px;border-radius:8px;background:color-mix(in srgb, var(--ink-soft) 16%, transparent);color:var(--ink-soft);font-size:11px;font-style:normal}
  #mdPane .md-hl{z-index:1}
  #mdEditor{z-index:2}
  /* rendered preview */
  #mdPane .md-prev-btn{margin-left:2px;border:1px solid var(--line);background:transparent;color:var(--ink-soft);cursor:pointer;font-size:11px;font-weight:600;padding:2px 9px;border-radius:6px}
  #mdPane .md-prev-btn.on{background:var(--accent);color:#fff;border-color:var(--accent)}
  #mdPane .md-wrap-btn{margin-left:2px;border:1px solid var(--line);background:transparent;color:var(--ink-soft);cursor:pointer;font-size:11px;font-weight:600;padding:2px 9px;border-radius:6px}
  #mdPane .md-wrap-btn.on{background:var(--accent);color:#fff;border-color:var(--accent)}
  #mdPane.md-preview .md-wrap-btn{display:none}
  /* Word wrap: the textarea and highlight overlay share this rule so switching both to
     pre-wrap at once keeps them pixel-aligned (identical font/width/padding/text, so the
     browser wraps them the same way). The gutter's rows are normally a fixed 20px each
     (one line = one row); once wrapped, a line can span several visual rows, so
     mdSyncGutterRowHeights() overrides each .gl row's height in JS to match its
     corresponding .hl-line's actual (now possibly taller) rendered height. */
  #mdPane.md-wrap .md-hl,#mdPane.md-wrap #mdEditor{white-space:pre-wrap;overflow-wrap:anywhere}
  #mdPane .md-pdf-btn{display:none;border:1px solid var(--line);background:transparent;color:var(--ink-soft);cursor:pointer;font-size:11px;font-weight:600;padding:2px 9px;border-radius:6px}
  #mdPane .md-pdf-btn:hover{background:var(--paper-2,rgba(127,127,127,.12));color:var(--ink)}
  #mdPane.md-preview .md-pos{display:none}
  #mdPane.md-preview .md-pdf-btn{display:inline-flex;margin-left:auto}
  #mdPane .md-prev{position:absolute;inset:0;display:none;overflow:auto;padding:16px 22px;background:var(--paper);color:var(--ink);z-index:4;line-height:1.6;text-align:left}
  #mdPane.md-preview .md-prev{display:block}
  #mdPane.md-preview .md-hl,#mdPane.md-preview #mdEditor,#mdPane.md-preview .md-gutter{display:none}
  #mdPane .md-prev h1,#mdPane .md-prev h2,#mdPane .md-prev h3{margin:.6em 0 .3em;line-height:1.25}
  #mdPane .md-prev h1{font-size:1.6em;border-bottom:1px solid var(--line);padding-bottom:.2em}
  #mdPane .md-prev h2{font-size:1.3em;border-bottom:1px solid var(--line);padding-bottom:.2em}
  #mdPane .md-prev h3{font-size:1.1em}
  #mdPane .md-prev p,#mdPane .md-prev ul,#mdPane .md-prev ol,#mdPane .md-prev blockquote{margin:.5em 0}
  #mdPane .md-prev pre.mp-code{background:var(--paper-2,rgba(127,127,127,.10));padding:10px 12px;border-radius:8px;overflow:auto;font-size:12.5px}
  #mdPane .md-prev code{font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace}
  #mdPane .md-prev table{border-collapse:collapse;font-size:.95em}
  #mdPane .md-prev th,#mdPane .md-prev td{border:1px solid var(--line);padding:5px 9px}
  #mdPane .md-prev th{background:var(--paper-2,rgba(127,127,127,.12));font-weight:700;text-align:left}
  #mdPane .md-prev blockquote{border-left:3px solid var(--line);margin-left:0;padding:.2em 0 .2em 12px;color:var(--ink-soft)}
  #mdPane .md-prev img{max-width:100%}
  #mdPane .md-prev hr{border:0;border-top:1px solid var(--line);margin:1em 0}
  #mdPane .md-prev a{color:#3b82f6}
  #mdPane .md-prev math{font-size:1.04em}
  #mdPane .md-prev math[display="block"]{display:block;margin:.6em auto;text-align:center}
  /* horizontal-rule divider node */
  .node.hr-node{min-width:54px;box-shadow:none}
  .node.hr-node .node-hr{display:block;width:54px;height:0;border-top:2px solid var(--ink-soft,#98a2b3);opacity:.6}
  #mdEditor{overflow:auto;resize:none;outline:none;background:transparent;color:transparent;caret-color:var(--ink)}
  #mdEditor::selection{background:color-mix(in srgb, var(--accent) 28%, transparent)}
  /* markdown syntax colors — driven by theme variables, so they follow the theme */
  #mdPane .hl-head{color:var(--accent);font-weight:700}
  #mdPane .hl-comment{color:var(--ink-soft);opacity:.6;font-style:italic}
  #mdPane .hl-code,#mdPane .hl-fence,#mdPane .hl-code-inline{color:var(--accent-deep,var(--accent))}
  #mdPane .hl-strong{color:var(--ink);font-weight:700}
  #mdPane .hl-em{color:var(--ink);font-style:italic}
  #mdPane .hl-link,#mdPane .hl-img{color:#3b82f6}
  #mdPane .hl-bullet,#mdPane .hl-task{color:var(--accent);font-weight:700}
  #mdPane .hl-quote{color:var(--ink-soft);font-style:italic}
  #mdPane .hl-punc{color:var(--ink-soft)}
  #mdPane .hl-hmark{color:var(--ink-soft);font-weight:700}
  #mdPane .hl-strike{color:var(--ink-soft);text-decoration:line-through}
  #mdPane .hl-hr{color:var(--ink-soft)}
  #mdPane .hl-tag{color:#22a06b}
  #mdPane .hl-url{color:#3b82f6;text-decoration:underline}
  #mdPane .md-resize{position:absolute;top:0;right:0;width:7px;height:100%;cursor:col-resize;z-index:6}
  .tb#mdToggle.on{background:var(--accent);color:#fff}

  /* ===== Sidebar ===== */
  .side{width:268px;min-height:0;position:relative;background:var(--chrome);border-right:1px solid var(--chrome-edge);display:flex;flex-direction:column;transition:width .22s cubic-bezier(.4,0,.2,1),background-color .3s ease,border-color .3s ease}
  .side.collapsed{width:36px;border:none}                 /* icon rail instead of fully gone */
  .side.resizing{transition:none}
  .side.collapsed .brand{display:none !important}  /* never bleed into the slim rail */
  .side.collapsed .side-tabs,
  .side.collapsed .side-pane,
  .side.collapsed .side-foot,
  .side.collapsed .side-resize{display:none !important}
  /* Collapsed state = slim rail with the reopen button, so the sidebar can
     never get "lost". The same ☰ button sits in the brand header, beside
     the MindSpark title. */
  .side-rail{display:none;width:36px;flex:1 0 auto;justify-content:center;align-items:center}
  .side.collapsed .side-rail{display:flex}
  .side-rail .tb{background:none;border:none}
  /* Drag handle on the sidebar's right edge (desktop only) */
  .side-resize{position:absolute;top:0;right:-4px;width:8px;height:100%;cursor:col-resize;z-index:10;opacity:0;transition:opacity .15s}
  .side-resize:hover,.side-resize:active{opacity:.55;background:var(--accent)}
  .side-tabs{display:flex;gap:2px;padding:0 10px 10px}
  .side-tab{flex:1;padding:7px 6px;border:none;background:none;border-radius:9px;font-family:inherit;font-size:12.5px;font-weight:600;color:var(--ink-soft);cursor:pointer;display:flex;align-items:center;justify-content:center;gap:6px;white-space:nowrap}
  .side-tab:hover{background:var(--hover);color:var(--ink)}
  .side-tab.active{background:var(--paper-2);color:var(--ink)}
  .side-pane{flex:1;min-height:0;display:flex;flex-direction:column}
  /* Tab switching is class-based (never inline styles) so the collapsed-rail
     rules below always win: `.side-pane:not(.active)` is hidden, the active
     pane is shown, and `.side.collapsed` (declared later + !important) hides
     everything inside the slim rail. */
  .side-pane.active{display:flex}
  .side-pane:not(.active){display:none}
  /* Template list inside the sidebar Templates tab */
  .tpl-side-hdr{font-size:10.5px;text-transform:uppercase;letter-spacing:.1em;color:var(--accent);font-weight:700;padding:12px 8px 4px}
  .tpl-side-item{display:flex;align-items:center;gap:10px;width:100%;text-align:left;padding:8px 10px;border:none;background:none;border-radius:10px;cursor:pointer;font-family:inherit;color:var(--ink);margin:1px 0}
  .tpl-side-item:hover{background:var(--hover)}
  .tpl-side-ic{width:30px;height:30px;flex-shrink:0;display:flex;align-items:center;justify-content:center;color:#fff;border-radius:8px;font-size:14px}
  .tpl-side-meta{display:flex;flex-direction:column;line-height:1.3;min-width:0}
  .tpl-side-meta b{font-weight:600;font-size:13px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
  .tpl-side-meta i{font-style:normal;color:var(--ink-soft);font-size:11.5px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
  @media (prefers-reduced-motion: reduce){ .side, #viewport{transition:none !important} }
  .brand{display:flex;align-items:center;gap:10px;padding:18px 18px 14px}
  .brand .mark{flex:0 0 auto; filter:drop-shadow(0 1px 3px rgba(40,30,15,.2))}
  .brand h1{font-family:var(--serif);font-weight:900;font-size:22px;margin:0;letter-spacing:-.5px}
  .brand h1 span{color:var(--accent)}
  .brand #newMap,
  .brand #toggleSide{width:32px;height:32px;flex:0 0 auto;font-size:16px}
  .brand #newMap{margin-left:auto}
  .brand #newMap:hover,
  .brand #toggleSide:hover{background:var(--hover)}
  .side-scroll{flex:1;min-height:0;overflow-y:auto;padding:6px 10px 12px}
  .side-label{font-size:11px;text-transform:uppercase;letter-spacing:.12em;color:var(--ink-soft);padding:10px 8px 6px;font-weight:700}
  .map-item{display:flex;align-items:center;gap:8px;padding:9px 10px;border-radius:10px;margin:2px 0;cursor:pointer;position:relative}
  .map-item:hover{background:var(--hover)}
  .map-item.active{background:var(--chrome);box-shadow:var(--shadow)}
  .map-item .dot{width:8px;height:8px;border-radius:50%;flex:0 0 auto}
  .map-item .nm{flex:1;font-size:14px;font-weight:500;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
  .map-item .row-menu{opacity:0;border:none;background:none;color:var(--ink-soft);padding:2px 5px;border-radius:6px;font-size:17px;line-height:1;flex:0 0 auto;cursor:pointer;transition:opacity .12s}
  .map-item:hover .row-menu, .map-item.active .row-menu{opacity:.65}
  .map-item .row-menu:hover{opacity:1;background:var(--line);color:var(--ink)}
  @media (pointer:coarse){ .map-item .row-menu{opacity:.6} }   /* always tappable on touch */
  .row-pop{position:fixed;background:var(--paper,#fff);border:1px solid var(--chrome-edge,#d0d7de);border-radius:10px;box-shadow:var(--shadow,0 8px 28px rgba(0,0,0,.16));padding:5px;min-width:152px;z-index:400;display:flex;flex-direction:column;gap:2px}
  .row-pop.flip-up{ /* kept for compat, positioning now handled in JS via fixed coords */ }
  .row-pop button{display:flex;align-items:center;gap:9px;width:100%;text-align:left;border:none;background:none;color:var(--ink);font-size:13.5px;padding:8px 10px;border-radius:7px;cursor:pointer;font-family:inherit}
  .row-pop button:hover{background:var(--hover)}
  .row-pop button.danger{color:var(--accent-deep,#b8451f)}
  .row-pop button.danger:hover{background:rgba(184,69,31,.10)}
  .row-pop .rp-ic{width:16px;text-align:center;opacity:.85;font-size:14px}
  .side-foot{padding:12px 16px;padding-bottom:calc(12px + env(safe-area-inset-bottom, 0px));border-top:1px solid var(--chrome-edge);font-size:11.5px;color:var(--ink-soft);line-height:1.5}
  .side-foot b{color:var(--ink)}
  .qotd-sep{height:1px;background:var(--chrome-edge);margin:12px -16px 0;opacity:.9}
  .side-foot:has(#qotd[hidden]) .qotd-sep{display:none}
  .qotd{position:relative;margin-top:12px;padding:8px 10px 8px 10px;border-left:2px solid var(--accent);background:color-mix(in srgb, var(--accent) 7%, transparent);border-radius:0 8px 8px 0}
  .qotd[hidden]{display:none}
  .qotd-text{font-size:12px;line-height:1.45;color:var(--ink);font-style:italic;white-space:pre-wrap;word-break:break-word}
  .qotd-text::before{content:'“'} .qotd-text::after{content:'”'}
  .qotd-author{margin-top:4px;font-size:10.5px;color:var(--ink-soft);text-align:right;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
  .qotd-author::before{content:'— '}
  .qotd-refresh{position:absolute;top:4px;right:4px;width:20px;height:20px;display:grid;place-items:center;border:none;background:transparent;color:var(--ink-soft);border-radius:6px;cursor:pointer;font-size:12px;line-height:1;opacity:0;transition:opacity .15s, background-color .15s}
  .qotd:hover .qotd-refresh{opacity:1}
  .qotd-refresh:hover{background:var(--hover);color:var(--ink)}
  .side.collapsed .qotd{display:none}

  /* ===== Canvas region ===== */
  .stage{position:relative;overflow:hidden;background:
    radial-gradient(circle at 1px 1px,var(--canvas-dot) 1px,transparent 0);
    background-size:26px 26px;background-color:var(--paper)}
  .stage:before{content:"";position:absolute;inset:0;pointer-events:none;
    background:radial-gradient(ellipse at 50% 0%,var(--stage-glow),transparent 60%)}
  #viewport{position:absolute;inset:0;transform-origin:0 0}
  #edges{position:absolute;left:0;top:0;overflow:visible;pointer-events:none}

  /* ===== Top header — full-width bar, mirrors the status bar's strip look ===== */
  .topbar{display:flex;align-items:center;gap:8px;padding:5px 10px;background:var(--chrome);border-bottom:1px solid var(--chrome-edge);z-index:30;flex-wrap:wrap;row-gap:4px;min-width:0}
  .tb-group{display:flex;align-items:center;gap:2px;padding:0;background:none;border:none;border-radius:0;box-shadow:none}
  .tb{border:none;background:none;color:var(--ink);width:36px;height:34px;border-radius:8px;display:grid;place-items:center;font-size:16px;white-space:nowrap}
  .tb:hover{background:var(--hover)}
  .tb:disabled{opacity:.32;cursor:default}
  .tb.wide{width:auto;padding:0 12px;font-size:13.5px;font-weight:600;gap:7px}
  .tb.primary{background:var(--accent);color:#fff}
  .tb.primary:hover{background:var(--accent-deep)}
  .title-edit{font-family:var(--serif);font-weight:600;font-size:19px;border:none;background:transparent;color:var(--ink);padding:6px 12px;min-width:120px;max-width:340px;border-radius:9px;outline:none}
  .title-edit:hover,.title-edit:focus{background:var(--chrome)}
  /* Hairline separator between topbar clusters (outside any .tb-group) */
  .tb-sep{width:1px;height:26px;background:var(--chrome-edge);flex:0 0 auto}
  .spacer{flex:1}
  .search-wrap{display:flex;align-items:center;background:none;border:none;border-radius:0;box-shadow:none;overflow:hidden;width:0;transition:width .22s,background-color .3s ease,border-color .3s ease,color .3s ease}
  .search-wrap.open{width:230px;background:var(--paper-2);border-radius:9px}
  .search-wrap.open.replace-mode{width:420px}
  .search-wrap input{border:none;background:none;outline:none;font-family:inherit;font-size:12px;color:var(--ink);padding:9px 12px;width:100%;min-width:0}
  .search-wrap #replace,.search-wrap .search-act{display:none}
  .search-wrap.replace-mode #replace{display:block;border-left:1px solid var(--chrome-edge)}
  .search-wrap.replace-mode .search-act{display:inline-flex}
  .search-count{font-size:11px;color:var(--ink-soft);white-space:nowrap;padding:0 8px;flex-shrink:0}
  .search-toggle{border:none;background:none;cursor:pointer;color:var(--ink-soft);font-size:14px;padding:8px 10px;flex-shrink:0;border-radius:0}
  .search-toggle:hover{background:var(--hover);color:var(--ink)}
  .search-act{border:none;background:none;cursor:pointer;color:var(--accent);font-size:12px;font-weight:600;padding:8px 11px;flex-shrink:0;font-family:inherit;align-items:center}
  .search-act:hover{background:var(--hover)}
  .node.match{outline:2.5px solid var(--accent);outline-offset:2px}
  .node.match-current{outline:3px solid var(--accent);outline-offset:2px;box-shadow:0 0 0 6px color-mix(in srgb, var(--accent) 22%, transparent)}
  .node.dim{opacity:.32;transition:opacity .15s}
  .save-pill{font-size:12px;color:var(--ink-soft);background:var(--chrome);border:1px solid var(--chrome-edge);border-radius:20px;padding:6px 13px;box-shadow:var(--shadow);font-weight:500;display:flex;align-items:center;gap:6px}
  .save-pill .ring{width:8px;height:8px;border-radius:50%;background:var(--teal)}
  .save-pill.saving .ring{background:var(--accent);animation:pulse 1s infinite}
  @keyframes pulse{50%{opacity:.3}}

  /* ===== Bottom controls — one "overview" card =====
     Minimap and zoom controls live inside the status bar as a single chip.
     Hovering it expands the breadcrumb (see .breadcrumb.shown). Collapses to
     a stub via the chevron (state persisted in JS). */
  .overview{flex:0 0 auto;display:flex;align-items:center;gap:7px;padding:2px 6px;border-radius:8px}
  .overview:hover{background:var(--hover)}
  .overview .minimap{position:static;border-radius:6px;box-shadow:none}
  .zoom-row{display:flex;align-items:center;gap:3px}
  .zoom-row button{border:none;background:none;width:28px;height:26px;border-radius:7px;font-size:15px;color:var(--ink);flex:0 0 auto;display:grid;place-items:center}
  .zoom-row button:hover{background:var(--hover)}
  #zoomSlider{flex:1;min-width:0;width:70px;accent-color:var(--accent);height:16px;margin:0;cursor:pointer}
  .zoom-val{font-size:11px;text-align:center;color:var(--ink-soft);font-weight:600;padding:3px 4px;border-radius:5px;cursor:pointer;min-width:38px;outline:none;flex:0 0 auto}
  .zoom-val:hover{background:var(--hover);color:var(--ink)}
  .zoom-val[contenteditable="true"]{background:#fff;box-shadow:0 0 0 2px var(--accent);color:var(--ink)}
  .overview-toggle{border:none;background:none;color:var(--ink-soft);font-size:11px;width:22px;height:22px;flex:0 0 auto;border-radius:6px;cursor:pointer;display:grid;place-items:center;transition:transform .18s}
  .overview-toggle:hover{background:var(--hover);color:var(--ink)}
  .overview.collapsed{padding:2px}
  .overview.collapsed .minimap,
  .overview.collapsed .zoom-row{display:none}
  .overview.collapsed .overview-toggle{transform:rotate(-90deg)}

  /* ===== Status bar — bottom strip under the canvas ===== */
  .statusbar{display:flex;align-items:center;gap:14px;padding:5px 14px;background:var(--chrome);border-top:1px solid var(--chrome-edge);min-height:34px;font-family:var(--sans)}
  .statusbar .hint{
    display:flex;align-items:center;gap:6px;position:static;margin:0;
    background:none;border:none;box-shadow:none;border-radius:0;padding:0;
    font-size:12px;color:var(--ink-soft);max-width:70%;line-height:1.5;flex:1;min-width:0;
  }
  .statusbar .hint b{color:var(--ink);font-weight:600}
  /* The hint's text lives in its own span so it can shrink and ellipsize as a
     single unit — the bar shrinks when the overview collapses (the chip is
     content-sized), so without this the text would re-wrap into a ragged
     multi-line mess every time the overview is toggled. */
  .statusbar .hint .hint-text{white-space:nowrap;overflow:hidden;text-overflow:ellipsis;min-width:0}
  .statusbar .hint .close{border:none;background:none;color:var(--ink-soft);font-size:14px;line-height:1;padding:2px 5px;border-radius:5px;cursor:pointer;flex:0 0 auto}
  .statusbar .hint .close:hover{background:var(--hover);color:var(--ink)}
  .statusbar .save-pill,
  .statusbar .token-total{font-size:11.5px;padding:4px 11px;box-shadow:none}
  .statusbar .user-pill{height:28px;font-size:12px}
  .statusbar .user-pill img{width:20px;height:20px}
  .sb-right{margin-left:auto;display:flex;align-items:center;gap:10px;flex:0 0 auto}
  .hint b{color:var(--ink);font-weight:600}
  .hint kbd{font-family:var(--sans);background:var(--paper-2);border:1px solid var(--line);border-radius:5px;padding:1px 6px;font-size:11px;font-weight:600;color:var(--ink)}
  .hint .close{float:right;margin-left:8px;cursor:pointer;color:var(--ink-soft);border:none;background:none;font-size:14px}

  /* ===== Nodes ===== */
  .node{position:absolute;background:var(--node-bg);border:1.5px solid var(--line);border-radius:12px;padding:9px 15px;font-size:15px;font-weight:500;line-height:1.35;box-shadow:var(--shadow);width:max-content;max-width:240px;min-width:34px;user-select:none;transition:background-color .3s ease,color .3s ease,box-shadow .15s,border-color .15s,transform .06s;white-space:pre-wrap;overflow-wrap:anywhere;word-break:break-word;display:flex;align-items:center;justify-content:center;text-align:center;box-sizing:border-box}
  .node:hover{box-shadow:var(--shadow-lg)}
  .node.root{font-family:var(--serif);font-weight:600;font-size:19px;padding:12px 22px;border-width:0}
  .node.sel{outline:2.5px solid var(--accent);outline-offset:2px}
  .node.editing{cursor:text;user-select:text;outline:none !important;box-shadow:none}
  .node.editing .node-text{outline:none}
  .node.dim{opacity:.28}
  .node.match{outline:2.5px solid var(--teal);outline-offset:2px}
  .node .badge{display:none}  /* legacy, no longer rendered */
  /* Zebra striping — XMind-style alternating tint by tree depth. Only affects
     uncoloured nodes: the root and user-picked card colours carry inline
     background styles that win over these classes. Subtle color-mix so the
     stripes follow every theme, and they ride the theme-switch transition. */
  :root{
    --zebra-1:color-mix(in srgb, var(--node-bg) 93%, var(--accent));
    --zebra-2:color-mix(in srgb, var(--node-bg) 93%, var(--teal));
  }
  .node[data-depth="1"],.node[data-depth="3"],.node[data-depth="5"],
  .node[data-depth="7"]{background:var(--zebra-1)}
  .node[data-depth="2"],.node[data-depth="4"],.node[data-depth="6"],
  .node[data-depth="8"]{background:var(--zebra-2)}
  /* Hover-only "created/last edited" watermark — sits just above the node (not inside it,
     which used to collide with the node's own vertically-centered text on shorter nodes)
     so it never overlaps the actual content. */
  .node .node-watermark{
    position:absolute; left:0; right:0; bottom:100%; margin-bottom:3px;
    pointer-events:none; overflow:hidden;
    font-family:var(--sans); font-size:9px; font-weight:600; letter-spacing:.02em;
    color:var(--ink-soft); opacity:0;
    transition:opacity .18s ease;
    white-space:nowrap; text-overflow:ellipsis;
    text-align:center;
  }
  .node:hover .node-watermark{opacity:.85}
  .node.editing .node-watermark{opacity:0 !important}   /* never fight with the caret while typing */
  /* Formula nodes ("=SUM(children)" etc): a small fx badge marks the node as a live
     calculation, and the result shows in a tabular-numeral style so a column of computed
     values lines up like a spreadsheet. The title tooltip (native, on hover) reveals the
     actual formula text. */
  .node.formula-node{position:relative}
  .node.formula-node::before{
    content:'\0192x'; position:absolute; top:-7px; left:-7px;
    width:16px; height:16px; border-radius:50%;
    background:var(--accent); color:#fff;
    font-size:9px; font-weight:700; font-style:normal;
    display:flex; align-items:center; justify-content:center;
    box-shadow:0 1px 3px rgba(0,0,0,.25);
    pointer-events:none;
  }
  .node.formula-node .node-text{font-variant-numeric:tabular-nums}
  .node.formula-error{border-color:#e5484d}
  .node.formula-error::before{background:#e5484d}
  .node.formula-error .node-text{color:#e5484d}
  /* Frontmatter node (a skill.md's YAML name/description block, etc.): a small badge marks
     it as metadata rather than regular outline content — the table itself is the normal
     block-node table rendering, this is purely a visual "what is this" hint. */
  .node.frontmatter-node{position:relative}
  .node.frontmatter-node::before{
    content:'YAML'; position:absolute; top:-9px; left:8px;
    padding:1px 5px; border-radius:4px;
    background:var(--teal); color:#fff;
    font-size:8px; font-weight:700; font-style:normal; letter-spacing:.03em;
    box-shadow:0 1px 3px rgba(0,0,0,.25);
    pointer-events:none;
  }
  /* Formula function autocomplete popup (Excel-style "=SU" -> suggests SUM) */
  .formula-ac{
    position:fixed; z-index:1200; min-width:220px; max-width:320px; max-height:220px;
    overflow-y:auto; background:var(--chrome); border:1px solid var(--line);
    border-radius:8px; box-shadow:var(--shadow-lg); padding:4px; font-family:var(--sans);
  }
  .formula-ac-row{
    display:flex; flex-direction:column; gap:1px; padding:5px 8px; border-radius:5px;
    cursor:pointer; line-height:1.3;
  }
  .formula-ac-row.active,.formula-ac-row:hover{background:var(--accent); }
  .formula-ac-row.active .formula-ac-sig,.formula-ac-row:hover .formula-ac-sig,
  .formula-ac-row.active .formula-ac-desc,.formula-ac-row:hover .formula-ac-desc{color:#fff}
  .formula-ac-sig{font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;font-size:12.5px;font-weight:700;color:var(--ink)}
  .formula-ac-desc{font-size:11px;color:var(--ink-soft)}

  /* ===== Quick-action handles on nodes (appear on hover) ===== */
  .node .handle{
    position:absolute; width:22px; height:22px; border-radius:50%;
    display:flex; align-items:center; justify-content:center;
    font-size:15px; font-weight:600; line-height:1; cursor:pointer;
    user-select:none; box-shadow:0 2px 5px rgba(0,0,0,.22);
    border:2px solid var(--node-bg, #fff); opacity:0; transition:opacity .12s, transform .1s;
    z-index:8;
  }
  .node:hover .handle{opacity:1}
  .node .handle:hover{transform:scale(1.15)}
  .node.editing .handle{display:none}

  /* Collapse / expand — at the outer edge, always visible (subtle) */
  .node .h-collapse{
    background:var(--node-bg, #fff); color:var(--ink); border:1.5px solid var(--line-2);
    width:18px; height:18px; font-size:13px; opacity:.8;
    right:-10px; top:50%; margin-top:-9px;
  }
  .node:hover .h-collapse{opacity:1}
  .node .h-collapse.collapsed{background:var(--accent);color:#fff;border-color:var(--accent);opacity:1}
  .node.left .h-collapse{left:-10px;right:auto}

  /* Add child — outer edge (right for right-side / root, left for left-side) */
  .node .h-child{background:var(--accent);color:#fff;right:-32px;top:50%;margin-top:-11px}
  .node.left .h-child{left:-32px;right:auto}

  /* Add sibling — below the node, centered */
  .node .h-sibling{background:var(--teal);color:#fff;bottom:-30px;left:50%;margin-left:-11px}

  /* Resize grip — bottom-right corner, visible only on selected nodes */
  .node .resize-grip{
    position:absolute; right:-2px; bottom:-2px; width:14px; height:14px;
    cursor:nwse-resize; opacity:0; pointer-events:none; transition:opacity .12s;
    background:
      linear-gradient(135deg, transparent 40%, var(--accent) 40%, var(--accent) 55%, transparent 55%,
                              transparent 65%, var(--accent) 65%, var(--accent) 80%, transparent 80%);
    border-bottom-right-radius:12px;
  }
  .node.sel .resize-grip{opacity:.9; pointer-events:auto}
  .node .resize-grip:hover{opacity:1}
  .node.editing .resize-grip{display:none}

  /* Drop-target highlight while drag-and-drop reparenting. The three modes
     need to be clearly distinguishable at a glance during a fast drag, not
     just technically different — before/after (sibling insertion) previously
     had only a bare 3px line hugging the node's own edge, much weaker than
     the child-nest treatment below it. Strengthened to a thicker line that
     extends past the node's own width (box-shadow spread, not just blur) so
     it reads as a real insertion marker, plus a background tint so there's
     more than one signal to notice mid-drag. */
  .node.drop-before{
    box-shadow:0 -5px 0 3px var(--accent), var(--shadow);
    background:color-mix(in srgb, var(--accent) 12%, var(--node-bg)) !important;
  }
  .node.drop-after{
    box-shadow:0 5px 0 3px var(--accent), var(--shadow);
    background:color-mix(in srgb, var(--accent) 12%, var(--node-bg)) !important;
  }
  /* File-drop target — deliberately distinct from .drop-target above.
     That one means "nest as child" during node dragging; this one means
     "attach the image you are holding". Using the same visual would
     promise the wrong action. */
  .node.file-drop{
    outline:3px dashed var(--teal, #2f6f6a); outline-offset:5px;
    box-shadow:0 0 0 6px color-mix(in srgb, var(--teal, #2f6f6a) 22%, transparent);
  }
  .node.drop-target{
    outline:3px dashed var(--accent); outline-offset:5px;
    background:linear-gradient(0deg,
      color-mix(in srgb, var(--accent) 22%, var(--node-bg)),
      color-mix(in srgb, var(--accent) 22%, var(--node-bg))) !important;
    box-shadow:0 0 0 6px color-mix(in srgb, var(--accent) 20%, transparent);
  }

  /* Notes indicator — small page-icon at the top-right of nodes with a note */
  .node .notes-mark{
    position:absolute; top:-9px; right:-9px;
    width:22px; height:22px; border-radius:4px;
    background:var(--sticky, #fff7b0); border:1.5px solid var(--sticky-edge, #f2e27a);
    display:flex; align-items:center; justify-content:center;
    font-size:11px; cursor:pointer; z-index:6;
    box-shadow:0 1px 3px rgba(0,0,0,.18); transform:rotate(-6deg);
  }
  .node .notes-mark:hover{transform:rotate(0deg) scale(1.12)}
  .node.left .notes-mark{right:auto; left:-9px}

  /* List rendering inside a node */
  .node-text-list .list-marker{display:inline-block; min-width:1.6em; opacity:.7; user-select:none}

  /* Alignment-picker glyphs */
  .align-icon{display:inline-block; font-family:monospace; font-size:13px; line-height:1}
  .align-icon.align-left{text-align:left}
  .align-icon.align-center{text-align:center}
  .align-icon.align-right{text-align:right}

  /* ===== Notes editor — styled as a sticky note ===== */
  :root{ --sticky:#fff7b0; --sticky-edge:#f2e27a; --sticky-ink:#4a431f; }
  :root[data-theme="dark"], :root[data-theme="night-owl"], :root[data-theme="dracula"], :root[data-theme="catppuccin-dark"],
  :root[data-theme="rose-pine-moon"], :root[data-theme="nord"], :root[data-theme="github-dark"],
  :root[data-theme="slate-steel"], :root[data-theme="vscode-onedark"], :root[data-theme="monokai-pro"], :root[data-theme="amazon-aws"],
  :root[data-theme="synthwave"], :root[data-theme="matrix-green"],
  :root[data-theme="carbon-amber"], :root[data-theme="cyber-quantum"], :root[data-theme="blueprint"], :root[data-theme="obsidian"],
  :root[data-theme="deep-ocean"], :root[data-theme="google-material"], :root[data-theme="github-modern"], :root[data-theme="aurora-frost"],
  :root[data-theme="espresso"], :root[data-theme="copper-lab"], :root[data-theme="forest-night"], :root[data-theme="cobalt"],
  :root[data-theme="ruby-night"], :root[data-theme="electric-indigo"], :root[data-theme="steel-orange"], :root[data-theme="cosmic-rose"],
  :root[data-theme="plasma-crimson"], :root[data-theme="neon-noir"], :root[data-theme="ember-forge"], :root[data-theme="violet-circuit"],
  :root[data-theme="twilight-amber"], :root[data-theme="ocean-depth"], :root[data-theme="charcoal-gold"], :root[data-theme="azure-horizon"],
  :root[data-theme="jade-temple"], :root[data-theme="magenta-pulse"], :root[data-theme="graphite-terminal"], :root[data-theme="frosted-pine"],
  :root[data-theme="quantum-violet"], :root[data-theme="copper-rust"], :root[data-theme="lunar-silver"]{
    --sticky:#3a3520; --sticky-edge:#5c5430; --sticky-ink:#f3ecc4;
  }
  .notes-popup{
    position:fixed; z-index:1100;
    background:var(--sticky);
    color:var(--sticky-ink);
    border-radius:4px 4px 6px 6px;
    box-shadow:0 14px 34px rgba(0,0,0,.34), 0 2px 5px rgba(0,0,0,.16);
    width:340px; max-width:92vw;
    border:1px solid var(--sticky-edge);
    border-top:none;
    font-family:var(--sans);
    overflow:hidden;
    transform:rotate(-1deg);          /* slight sticky-note tilt */
    transform-origin:top center;
  }
  .notes-popup::before{
    content:''; display:block; height:8px;
    background:linear-gradient(180deg, color-mix(in srgb, var(--sticky-edge) 80%, #000 6%), var(--sticky-edge));
  }
  .notes-popup .np-toolbar{
    display:flex; align-items:center; gap:1px;
    padding:7px 9px;
    border-bottom:1px solid color-mix(in srgb, var(--sticky-edge) 70%, transparent);
    background:color-mix(in srgb, var(--sticky-edge) 30%, var(--sticky));
  }
  .notes-popup .np-toolbar button{
    border:none; background:transparent; cursor:pointer;
    width:32px; height:30px; border-radius:6px;
    font-family:inherit; font-size:13px; color:var(--sticky-ink);
    display:inline-flex; align-items:center; justify-content:center;
  }
  .notes-popup .np-toolbar button:hover{background:color-mix(in srgb, var(--sticky-ink) 12%, transparent)}
  .notes-popup .np-toolbar button b,
  .notes-popup .np-toolbar button i,
  .notes-popup .np-toolbar button s{font-family:var(--serif); font-size:14px}
  .notes-popup .np-toolbar button i{font-style:italic}
  .notes-popup .np-div{width:1px; height:20px; background:color-mix(in srgb, var(--sticky-edge) 80%, transparent); margin:0 4px}
  .notes-popup .np-editor{
    padding:14px 16px; min-height:170px; max-height:50vh; overflow-y:auto;
    font-family:var(--sans); font-size:14px; line-height:1.6;
    color:var(--sticky-ink); outline:none; background:transparent;
  }
  .notes-popup .np-editor:empty:before{
    content:attr(data-placeholder); color:color-mix(in srgb, var(--sticky-ink) 50%, transparent); pointer-events:none;
  }
  .notes-popup .np-editor h1{font-size:20px; margin:.4em 0 .3em; font-family:var(--serif); font-weight:700}
  .notes-popup .np-editor h2{font-size:16px; margin:.4em 0 .3em; font-family:var(--serif); font-weight:600}
  .notes-popup .np-editor p{margin:.3em 0}
  .notes-popup .np-editor ul,
  .notes-popup .np-editor ol{margin:.3em 0; padding-left:1.6em}
  .notes-popup .np-editor a{color:var(--link); text-decoration:underline}
  .notes-popup .np-actions{
    display:flex; gap:8px; padding:10px 12px;
    border-top:1px solid color-mix(in srgb, var(--sticky-edge) 70%, transparent);
    background:color-mix(in srgb, var(--sticky-edge) 22%, var(--sticky));
    align-items:center;
  }
  .notes-popup button{
    padding:7px 14px; border-radius:7px; border:1px solid var(--sticky-edge);
    background:color-mix(in srgb, var(--sticky-edge) 25%, var(--sticky)); cursor:pointer;
    font-family:inherit; font-size:13px; font-weight:500; color:var(--sticky-ink);
  }
  .notes-popup .np-actions > button:hover{background:color-mix(in srgb, var(--sticky-ink) 12%, transparent)}
  .notes-popup button.primary{background:var(--accent); color:#fff; border-color:var(--accent)}
  .notes-popup button.primary:hover{background:var(--accent-deep)}
  .notes-popup .np-clear{margin-right:auto; color:var(--ink-soft); border-color:transparent; background:transparent}
  .notes-popup .np-clear:hover{color:var(--accent-deep); background:var(--hover)}

  /* ===== Map style variants (applied to viewport[data-style]) ===== */
  #viewport[data-style="modern"]{--edge-color:var(--line-2);--edge-width:2.2}
  #viewport[data-style="classic"] .node{border-radius:4px; border-width:1.5px}
  #viewport[data-style="classic"]{--edge-color:var(--line-2);--edge-width:1.6}
  #viewport[data-style="classic"] .node.root{border-radius:6px}
  #viewport[data-style="bubble"]  .node{border-radius:999px; padding:11px 22px; border-width:0; box-shadow:var(--shadow-lg)}
  #viewport[data-style="bubble"] {--edge-color:var(--accent);--edge-width:3}
  #viewport[data-style="bubble"]  .node.root{padding:14px 26px}
  #viewport[data-style="sketch"]  .node{border-radius:3px; border-width:2px; border-color:var(--ink); box-shadow:none}
  #viewport[data-style="sketch"]  .node.root{border-width:0}
  #viewport[data-style="sketch"] {--edge-color:var(--ink-soft);--edge-width:1.6}
  #viewport[data-style="dashed"]   {--edge-color:var(--line-2);--edge-width:2.2}
  #viewport[data-style="dashed"]   .node{border-radius:14px}
  #viewport[data-style="minimal"]  {--edge-color:var(--line-2);--edge-width:1.1}
  #viewport[data-style="minimal"]  .node{border-radius:6px; border-width:1px; box-shadow:none}
  #viewport[data-style="minimal"]  .node.root{border-radius:8px}
  #viewport[data-style="zigzag"]   {--edge-color:var(--line-2);--edge-width:2}
  #viewport[data-style="zigzag"]   .node{border-radius:2px; border-width:2px; box-shadow:none}
  #viewport[data-style="zigzag"]   .node.root{border-radius:2px}
  #viewport[data-style="neon"]     {--edge-color:var(--accent);--edge-width:2.4}
  #viewport[data-style="neon"]     .node{border-radius:10px; border-width:1px; border-color:color-mix(in srgb, var(--accent) 55%, transparent); box-shadow:0 0 0 1px color-mix(in srgb, var(--accent) 18%, transparent), 0 0 16px color-mix(in srgb, var(--accent) 38%, transparent)}
  #viewport[data-style="neon"]     .node.root{box-shadow:0 0 0 1px color-mix(in srgb, var(--accent) 32%, transparent), 0 0 26px color-mix(in srgb, var(--accent) 55%, transparent)}
  #viewport[data-style="neon"]     #edges path{filter:drop-shadow(0 0 3px color-mix(in srgb, var(--accent) 65%, transparent))}

  /* Cascades the pencil font to every part of the app that already
     references --sans/--serif (sidebar, modals, buttons, topbar, and
     nodes/edges too, since those never had their own font override) —
     not a per-component override, the same two variables everything
     already uses. This is now the ONLY thing "Back to School" controls
     via color/font variables — no palette override, see below. */
  :root[data-look="handwritten"]{ --sans:"Caveat",cursive; --serif:"Caveat",cursive; }

  /* ===== "Back to School" look and feel — font + chrome texture only =====
     Deliberately does NOT touch .node/.nodebar border-radius or #viewport's
     --edge-color/--edge-width: card shape and branch style are Map Style's
     job exclusively (Modern/Classic/Bubble/Sketch), independent of which
     Look and Feel is active — picking "Back to School" must never lock out
     or override a Map Style choice. Canvas texture uses var(--paper)/
     var(--line) as already defined by whichever Colour Theme is active, not
     a hardcoded palette — Back to School no longer sets colors at all, so
     the ruled paper automatically follows Light/Dark/Nord/etc.
     font-size on .node: NOT a shape override (no border-radius/transform
     here), just legibility compensation — handwriting fonts need more size
     than a geometric sans for equivalent readability. */
  :root[data-look="handwritten"] .node{ font-size:1.2em; }
  :root[data-look="handwritten"] .stage{
    background-image:repeating-linear-gradient(var(--paper) 0px, var(--paper) 27px, var(--line) 28px);
    background-size:100% 28px; background-color:var(--paper);
  }
  :root[data-look="handwritten"] .nodebar{
    font-weight:700; font-size:1.15em;
    border-radius:16px 9px 16px 9px;
    border:2px solid var(--ink); box-shadow:none;
  }
  /* Sidebar — thicker ink-colored edge instead of the default hairline */
  :root[data-look="handwritten"] .side{border-right:2px solid var(--ink)}
  /* Modal cards (citation form, due-date form, etc.) — same sketchy-border
     language as the toolbar, for visual consistency across the app */
  :root[data-look="handwritten"] .vf-card{
    border-radius:20px 8px 20px 8px; border:2px solid var(--ink); box-shadow:var(--shadow-lg);
  }
  :root[data-look="handwritten"] .vf-card h2{font-weight:700}
  /* Remaining containers audited and covered in this pass — context menus,
     pickers, the donation card, export/template popups, search box, minimap.
     Grouped since they share the same underlying structure (chrome/node-bg
     background, chrome-edge border, rounded corners) — same sketchy-border
     language as the rest of the app, not restyled individually from scratch. */
  :root[data-look="handwritten"] .row-pop,
  :root[data-look="handwritten"] .picker,
  :root[data-look="handwritten"] .donate-card,
  :root[data-look="handwritten"] .export-pop{
    border-radius:16px 6px 16px 6px; border:2px solid var(--ink);
  }
  :root[data-look="handwritten"] .donate-card{ border-radius:20px 8px 20px 8px; }
  :root[data-look="handwritten"] .search-wrap{ border-radius:14px 6px 14px 6px; border:2px solid var(--ink); }
  :root[data-look="handwritten"] .minimap{ border-radius:12px 4px 12px 4px; border:2px solid var(--ink); }
  :root[data-look="handwritten"] .toast{ border-radius:14px 5px 14px 5px; border:2px solid var(--ink); font-weight:500; }

  /* ===== "At Coffee Shop" look and feel — same principles, lighter touch =====
     Font-only color/font override, same as Back to School — no palette
     override here either. Differentiated from Back to School through
     restraint, not a new color: a lighter 1.5px border (vs 2px) and a
     quieter diagonal-hatch canvas texture instead of overt ruled-paper
     lines.
     Nunito (not a handwriting font, deliberately) needs no font-size
     compensation on .node — unlike Caveat/Patrick Hand, it's designed to
     read well at normal body-text size, so there's no bump here at all.
     That also means this look carries much less risk of the
     overflow/overlap class of bug a size bump can cause elsewhere (nodes
     growing taller than manually-set sizes, edges drawn against stale
     measurements) — not eliminated everywhere, but not something this
     specific look needs to fight. Nunito genuinely has a bold weight
     (unlike Patrick Hand's single weight), so emphasis below uses
     font-weight:700 directly instead of a size-based workaround. */
  :root[data-look="coffee-shop"]{ --sans:"Nunito",sans-serif; --serif:"Nunito",sans-serif; }
  :root[data-look="coffee-shop"] .stage{
    background-image:repeating-linear-gradient(135deg, var(--paper) 0px, var(--paper) 22px, var(--line) 23px);
    background-size:32px 32px; background-color:var(--paper);
  }
  :root[data-look="coffee-shop"] .nodebar{
    font-weight:700;
    border-radius:14px 8px 14px 8px;
    border:1.5px solid var(--ink); box-shadow:none;
  }
  :root[data-look="coffee-shop"] .side{border-right:1.5px solid var(--ink)}
  :root[data-look="coffee-shop"] .vf-card{
    border-radius:18px 7px 18px 7px; border:1.5px solid var(--ink); box-shadow:var(--shadow-lg);
  }
  :root[data-look="coffee-shop"] .vf-card h2{font-weight:700}
  :root[data-look="coffee-shop"] .row-pop,
  :root[data-look="coffee-shop"] .picker,
  :root[data-look="coffee-shop"] .donate-card,
  :root[data-look="coffee-shop"] .export-pop{
    border-radius:14px 5px 14px 5px; border:1.5px solid var(--ink);
  }
  :root[data-look="coffee-shop"] .donate-card{ border-radius:18px 7px 18px 7px; }
  :root[data-look="coffee-shop"] .search-wrap{ border-radius:12px 5px 12px 5px; border:1.5px solid var(--ink); }
  :root[data-look="coffee-shop"] .minimap{ border-radius:10px 4px 10px 4px; border:1.5px solid var(--ink); }
  :root[data-look="coffee-shop"] .toast{ border-radius:12px 4px 12px 4px; border:1.5px solid var(--ink); }

  /* ===== "In the Lab" look and feel — technical, squared-off =====
      Font-only override plus a quiet blueprint grid on the canvas, same
      principles as the other looks: no palette change, no card-shape or
      edge-style interference (those belong to Map Style). Everything is
      squared and precise to match a monospace: 3px corners instead of
      organic rounded ones, 1.5px ink borders, a lab-notebook grid texture
      (both axes) instead of dots or ruled lines. JetBrains Mono is a
      designed text face, so no font-size compensation on .node. */
   :root[data-look="lab"]{ --sans:"JetBrains Mono",monospace; --serif:"JetBrains Mono",monospace; }
   :root[data-look="lab"] .stage{
     background-image:linear-gradient(color-mix(in srgb, var(--line) 55%, transparent) 1px, transparent 1px),
       linear-gradient(90deg, color-mix(in srgb, var(--line) 55%, transparent) 1px, transparent 1px);
     background-size:26px 26px; background-color:var(--paper);
   }
   :root[data-look="lab"] .nodebar{
     border-radius:3px;
     border:1.5px solid var(--ink); box-shadow:none;
   }
   :root[data-look="lab"] .side{border-right:1.5px solid var(--ink)}
   :root[data-look="lab"] .new-map{border:1.5px dashed var(--ink-soft)}
   :root[data-look="lab"] .vf-card{
     border-radius:3px; border:1.5px solid var(--ink); box-shadow:var(--shadow-lg);
   }
   :root[data-look="lab"] .vf-card h2{font-weight:700}
   :root[data-look="lab"] .row-pop,
   :root[data-look="lab"] .picker,
   :root[data-look="lab"] .donate-card,
   :root[data-look="lab"] .export-pop,
   :root[data-look="lab"] .tpl-pop{
     border-radius:3px; border:1.5px solid var(--ink);
   }
   :root[data-look="lab"] .donate-card{ border-radius:4px; }
   :root[data-look="lab"] .search-wrap{ border-radius:3px; border:1.5px solid var(--ink); }
   :root[data-look="lab"] .minimap{ border-radius:3px; border:1.5px solid var(--ink); }
:root[data-look="lab"] .toast{ border-radius:3px; border:1.5px solid var(--ink); }

/* Forest — birch grove: staggered vertical trunk lines on the canvas,
     rounded asymmetric corners, teal-green chrome. Fredoka is rounded and
     friendly, like a nature walk sign. */
  :root[data-look="forest"]{ --sans:"Fredoka",system-ui,sans-serif; --serif:"Fredoka",system-ui,sans-serif; }
  :root[data-look="forest"] .stage{
    background-image:
      radial-gradient(ellipse 7px 10px at 18% 22%, color-mix(in srgb, var(--teal) 10%, transparent) 98%, transparent 100%),
      radial-gradient(ellipse 5px 7px at 68% 18%, color-mix(in srgb, var(--teal) 7%, transparent) 98%, transparent 100%),
      radial-gradient(ellipse 9px 6px at 42% 38%, color-mix(in srgb, var(--teal) 8%, transparent) 98%, transparent 100%),
      radial-gradient(ellipse 6px 8px at 82% 52%, color-mix(in srgb, var(--teal) 6%, transparent) 98%, transparent 100%),
      radial-gradient(ellipse 8px 5px at 12% 68%, color-mix(in srgb, var(--teal) 7%, transparent) 98%, transparent 100%),
      radial-gradient(ellipse 5px 9px at 55% 78%, color-mix(in srgb, var(--teal) 6%, transparent) 98%, transparent 100%),
      radial-gradient(ellipse 6px 6px at 30% 88%, color-mix(in srgb, var(--teal) 5%, transparent) 98%, transparent 100%);
    background-size:220px 220px, 240px 240px, 200px 200px, 260px 260px, 210px 210px, 230px 230px, 190px 190px;
    background-color:var(--paper);
  }
  :root[data-look="forest"] .nodebar{
    border-radius:22px 10px 22px 10px;
    border:2px solid var(--teal); box-shadow:var(--shadow);
  }
  :root[data-look="forest"] .side{border-right:2px solid var(--teal)}
  :root[data-look="forest"] .new-map{border:2px dashed var(--teal)}
  :root[data-look="forest"] .vf-card{
    border-radius:22px 10px 22px 10px; border:2px solid var(--teal); box-shadow:var(--shadow);
  }
  :root[data-look="forest"] .vf-card h2{font-weight:600}
  :root[data-look="forest"] .row-pop,
  :root[data-look="forest"] .picker,
  :root[data-look="forest"] .donate-card,
  :root[data-look="forest"] .export-pop,
  :root[data-look="forest"] .tpl-pop{
    border-radius:18px 8px 18px 8px; border:2px solid var(--teal);
  }
  :root[data-look="forest"] .donate-card{ border-radius:24px 10px 24px 10px; }
  :root[data-look="forest"] .search-wrap{ border-radius:18px 8px 18px 8px; border:2px solid var(--teal); }
  :root[data-look="forest"] .minimap{ border-radius:18px 8px 18px 8px; border:2px solid var(--teal); }
  :root[data-look="forest"] .toast{ border-radius:16px 8px 16px 8px; border:2px solid var(--teal); }

  /* Beach — ocean ripples: horizontal wave bands on the canvas, pebble-pill
     cards. Oswald is tall and condensed, like seaside signage. */
  :root[data-look="beach"]{ --sans:"Oswald",system-ui,sans-serif; --serif:"Oswald",system-ui,sans-serif; }
  :root[data-look="beach"] .stage{
    background-image:repeating-linear-gradient(45deg, transparent 0 16px, color-mix(in srgb, var(--teal) 7%, transparent) 17px, transparent 18px);
    background-size:60px 60px; background-color:var(--paper);
  }
  :root[data-look="beach"] .nodebar{
    border-radius:999px;
    border:1px solid var(--teal); box-shadow:var(--shadow);
  }
  :root[data-look="beach"] .side{border-right:1px solid var(--teal)}
  :root[data-look="beach"] .new-map{border:1.5px dashed var(--teal)}
  :root[data-look="beach"] .vf-card{
    border-radius:999px; border:1px solid var(--teal); box-shadow:var(--shadow);
  }
  :root[data-look="beach"] .vf-card h2{font-weight:600}
  :root[data-look="beach"] .row-pop,
  :root[data-look="beach"] .picker,
  :root[data-look="beach"] .donate-card,
  :root[data-look="beach"] .export-pop,
  :root[data-look="beach"] .tpl-pop{
    border-radius:18px; border:1px solid var(--teal);
  }
  :root[data-look="beach"] .donate-card{ border-radius:24px; }
  :root[data-look="beach"] .search-wrap{ border-radius:999px; border:1px solid var(--teal); }
  :root[data-look="beach"] .minimap{ border-radius:999px; border:1px solid var(--teal); }
  :root[data-look="beach"] .toast{ border-radius:999px; border:1px solid var(--teal); }

  /* Studio — artist's sketchbook: diagonal crosshatch on the canvas, dashed
     pencil-outline chrome. Fraunces is a warm, wonky editorial serif. */
  :root[data-look="studio"]{ --sans:"Fraunces",serif; --serif:"Fraunces",serif; }
  :root[data-look="studio"] .stage{
    background-image:
      repeating-linear-gradient(45deg, color-mix(in srgb, var(--ink) 12%, transparent) 0 1px, transparent 1px 22px),
      repeating-linear-gradient(-45deg, color-mix(in srgb, var(--ink) 12%, transparent) 0 1px, transparent 1px 22px);
    background-size:31px 31px; background-color:var(--paper);
  }
  :root[data-look="studio"] .nodebar{
    border-radius:6px;
    border:1.5px dashed var(--ink); box-shadow:none;
  }
  :root[data-look="studio"] .side{border-right:1.5px dashed var(--ink)}
  :root[data-look="studio"] .new-map{border:1.5px dashed var(--ink-soft)}
  :root[data-look="studio"] .vf-card{
    border-radius:6px; border:1.5px dashed var(--ink); box-shadow:none;
  }
  :root[data-look="studio"] .vf-card h2{font-style:italic}
  :root[data-look="studio"] .row-pop,
  :root[data-look="studio"] .picker,
  :root[data-look="studio"] .donate-card,
  :root[data-look="studio"] .export-pop,
  :root[data-look="studio"] .tpl-pop{
    border-radius:6px; border:1.5px dashed var(--ink);
  }
  :root[data-look="studio"] .donate-card{ border-radius:8px; }
  :root[data-look="studio"] .search-wrap{ border-radius:6px; border:1.5px dashed var(--ink); }
  :root[data-look="studio"] .minimap{ border-radius:6px; border:1.5px dashed var(--ink); }
  :root[data-look="studio"] .toast{ border-radius:6px; border:1.5px dashed var(--ink); }

  /* Mountain — topographic contour rings on the canvas, peaked angular
     cards. Roboto Condensed is compact and alpine. */
  :root[data-look="mountain"]{ --sans:"Roboto Condensed",system-ui,sans-serif; --serif:"Roboto Condensed",system-ui,sans-serif; }
  :root[data-look="mountain"] .stage{
    background-image:
      linear-gradient(180deg, transparent 60%, color-mix(in srgb, var(--ink-soft) 12%, transparent) 61%, transparent 62%),
      repeating-linear-gradient(90deg, transparent 0 80px, color-mix(in srgb, var(--ink-soft) 8%, transparent) 81px, transparent 82px);
    background-size:100% 120px, 100% 100%; background-color:var(--paper);
  }
  :root[data-look="mountain"] .nodebar{
    border-radius:12px 12px 0 0;
    border:2px solid var(--ink-soft); box-shadow:var(--shadow-lg);
  }
  :root[data-look="mountain"] .side{border-right:2px solid var(--ink-soft)}
  :root[data-look="mountain"] .new-map{border:2px dashed var(--ink-soft)}
  :root[data-look="mountain"] .vf-card{
    border-radius:12px 12px 0 0; border:2px solid var(--ink-soft); box-shadow:var(--shadow-lg);
  }
  :root[data-look="mountain"] .vf-card h2{font-weight:700; text-transform:uppercase; letter-spacing:.04em}
  :root[data-look="mountain"] .row-pop,
  :root[data-look="mountain"] .picker,
  :root[data-look="mountain"] .donate-card,
  :root[data-look="mountain"] .export-pop,
  :root[data-look="mountain"] .tpl-pop{
    border-radius:10px 10px 0 0; border:2px solid var(--ink-soft);
  }
  :root[data-look="mountain"] .donate-card{ border-radius:14px 14px 0 0; }
  :root[data-look="mountain"] .search-wrap{ border-radius:10px 10px 0 0; border:2px solid var(--ink-soft); }
  :root[data-look="mountain"] .minimap{ border-radius:10px 10px 0 0; border:2px solid var(--ink-soft); }
  :root[data-look="mountain"] .toast{ border-radius:10px 10px 0 0; border:2px solid var(--ink-soft); }

  /* Observatory — night sky: sparse scattered stars of varied size with soft
     nebula haze, crisp accent-edged cards. Libre Baskerville is a classical
     scholarly serif. */
  :root[data-look="observatory"]{ --sans:"Libre Baskerville",serif; --serif:"Libre Baskerville",serif; }
  :root[data-look="observatory"] .stage{
    background-image:
      radial-gradient(circle at 12px 14px, color-mix(in srgb, var(--accent) 60%, transparent) 1.4px, transparent 2px),
      radial-gradient(circle at 44px 38px, color-mix(in srgb, var(--accent) 40%, transparent) 1px, transparent 1.6px),
      radial-gradient(circle at 30px 52px, color-mix(in srgb, var(--accent) 50%, transparent) 0.9px, transparent 1.4px),
      radial-gradient(circle at 56px 12px, color-mix(in srgb, var(--accent) 35%, transparent) 0.7px, transparent 1.1px),
      radial-gradient(ellipse at 28% 26%, color-mix(in srgb, var(--accent) 12%, transparent), transparent 70%),
      radial-gradient(ellipse at 74% 68%, color-mix(in srgb, var(--accent) 10%, transparent), transparent 70%);
    background-size:70px 70px, 70px 70px, 70px 70px, 70px 70px, 100% 100%, 100% 100%; background-color:var(--paper);
  }
  :root[data-look="observatory"] .nodebar{
    border-radius:6px;
    border:1.5px solid var(--accent); box-shadow:var(--shadow-lg);
  }
  :root[data-look="observatory"] .side{border-right:1.5px solid var(--accent)}
  :root[data-look="observatory"] .new-map{border:1.5px dashed var(--accent)}
  :root[data-look="observatory"] .vf-card{
    border-radius:6px; border:1.5px solid var(--accent); box-shadow:var(--shadow-lg);
  }
  :root[data-look="observatory"] .vf-card h2{font-weight:700}
  :root[data-look="observatory"] .row-pop,
  :root[data-look="observatory"] .picker,
  :root[data-look="observatory"] .donate-card,
  :root[data-look="observatory"] .export-pop,
  :root[data-look="observatory"] .tpl-pop{
    border-radius:6px; border:1.5px solid var(--accent);
  }
  :root[data-look="observatory"] .donate-card{ border-radius:8px; }
  :root[data-look="observatory"] .search-wrap{ border-radius:6px; border:1.5px solid var(--accent); }
  :root[data-look="observatory"] .minimap{ border-radius:6px; border:1.5px solid var(--accent); }
  :root[data-look="observatory"] .toast{ border-radius:6px; border:1.5px solid var(--accent); }

  /* Sketchpad — expressive, bold pen strokes on a clean canvas. Thick borders,
     very asymmetric radii for a hand-drawn feel, and slightly larger node text
     to give the writing more presence. */
  :root[data-look="sketchpad"]{ --sans:system-ui,sans-serif; --serif:system-ui,sans-serif; }
  :root[data-look="sketchpad"] .node{ font-size:1.15em; }
  :root[data-look="sketchpad"] .nodebar{
    border-radius:14px 4px 14px 4px;
    border:2px solid var(--ink); box-shadow:none;
  }
  :root[data-look="sketchpad"] .side{border-right:2px solid var(--ink)}
  :root[data-look="sketchpad"] .vf-card{
    border-radius:16px 5px 16px 5px; border:2px solid var(--ink); box-shadow:var(--shadow-lg);
  }
  :root[data-look="sketchpad"] .vf-card h2{font-weight:700}
  :root[data-look="sketchpad"] .row-pop,
  :root[data-look="sketchpad"] .picker,
  :root[data-look="sketchpad"] .donate-card,
  :root[data-look="sketchpad"] .export-pop{
    border-radius:14px 4px 14px 4px; border:2px solid var(--ink);
  }
  :root[data-look="sketchpad"] .donate-card{ border-radius:18px 6px 18px 6px; }
  :root[data-look="sketchpad"] .search-wrap{ border-radius:12px 4px 12px 4px; border:2px solid var(--ink); }
  :root[data-look="sketchpad"] .minimap{ border-radius:10px 4px 10px 4px; border:2px solid var(--ink); }
  :root[data-look="sketchpad"] .toast{ border-radius:12px 5px 12px 5px; border:2px solid var(--ink); }

  /* ===== Theme panel — multi-section layout ===== */
  /* ===== Theme picker panel ===== */
  .theme-panel{
    background:var(--chrome); border:1px solid var(--chrome-edge); border-radius:14px;
    box-shadow:var(--shadow-lg); padding:8px; z-index:1000;
    min-width:340px; font-family:var(--sans);
  }
  .theme-panel-large{
    min-width:580px; max-width:700px; display:flex; flex-direction:column;
    gap:0; padding:0; overflow-x:hidden; overflow-y:auto;
  }
  .theme-panel-large .tp-section{padding:7px 12px; border-top:1px solid var(--chrome-edge)}
  .theme-panel-large .tp-section:first-child{border-top:none}
  .theme-panel-large .tp-section-special{
    background:color-mix(in srgb, var(--accent) 6%, transparent);
    border-top:1px solid color-mix(in srgb, var(--accent) 30%, transparent);
    border-bottom:1px solid color-mix(in srgb, var(--accent) 30%, transparent);
  }
  .theme-panel-large .tp-section-special .tp-label{color:var(--accent)}
  .theme-panel-large .tp-label{
    font-size:11px; text-transform:uppercase; letter-spacing:.11em;
    color:var(--ink-soft); font-weight:700; margin-bottom:5px;
  }
  /* Cog beside a section label — opens that section's JSON settings. */
  .theme-panel-large .tp-label{ display:flex; align-items:center; gap:6px; }
  .theme-panel-large .tp-cog{
    background:none; border:none; cursor:pointer; padding:0 2px; line-height:1;
    font-size:12px; color:var(--ink-soft); opacity:.7;
  }
  .theme-panel-large .tp-cog:hover{ opacity:1; color:var(--accent); }
  /* Explanatory line and inline error inside a .var-form card. */
  .var-form .vf-hint{
    font-size:12px; line-height:1.5; color:var(--ink-soft); margin:-2px 0 12px;
  }
  .var-form .vf-err{
    font-size:12.5px; color:#c0392b; margin:8px 0 0;
    background:color-mix(in srgb, #c0392b 10%, transparent);
    border:1px solid color-mix(in srgb, #c0392b 35%, transparent);
    border-radius:8px; padding:7px 10px;
  }
  .var-form .vf-json{
    font-family:ui-monospace, SFMono-Regular, Menlo, monospace; font-size:12.5px;
    line-height:1.5; white-space:pre; overflow:auto;
  }
  /* Import tile in the Layout row — a dashed square marking it as an action
     rather than one more layout to choose. */
  .theme-panel-large .theme-opt.layout-import .li-tile{
    width:70px; height:40px; flex-shrink:0; display:flex; align-items:center; justify-content:center;
    border:1.5px dashed var(--line-2); border-radius:10px;
    font-size:18px; line-height:1; color:var(--ink-soft);
  }
  .theme-panel-large .theme-opt.layout-import:hover .li-tile{
    border-color:var(--accent); color:var(--accent);
  }
  /* Saved-layout chips inside the import dialog. */
  .var-form .li-list{ display:flex; flex-wrap:wrap; gap:6px; margin-top:6px; }
  .var-form .li-chip{
    display:inline-flex; align-items:center; gap:6px; font-size:12.5px;
    background:var(--paper-2); border:1px solid var(--line); border-radius:999px; padding:4px 6px 4px 11px;
  }
  .var-form .li-chip button{
    background:none; border:none; cursor:pointer; color:var(--ink-soft); font-size:14px; line-height:1; padding:0 2px;
  }
  .var-form .li-chip button:hover{ color:#c0392b; }
  .theme-panel-large .tp-grid{
    display:grid; gap:3px;
    grid-template-columns:repeat(4,minmax(160px,1fr));
  }
  /* One-line scrolling row (Layout). Keeps the panel from gaining a whole
     extra line for a fifth option. Overrides the grid above rather than
     replacing it, so every other section is untouched. */
  .theme-panel-large .tp-grid.tp-scroll-row{
    display:flex; overflow-x:auto; overflow-y:hidden;
    scroll-behavior:smooth; scrollbar-width:none;   /* Firefox */
    position:relative;
  }
  .theme-panel-large .tp-grid.tp-scroll-row::-webkit-scrollbar{ display:none; }
  .theme-panel-large .tp-grid.tp-scroll-row > .theme-opt{
    flex:0 0 160px; width:160px; min-width:0;
  }
   /* Colour theme: 3 rows (4 columns) visible, horizontally scrollable like
      the single-row sections. A grid fills down before across, so it gets
      explicit rows and auto-flowing columns; overflow lands in new columns
      past the visible four rather than wrapping to a 4th row. The column min
      (166px) matches what the "I am" cards measure on a full-width panel:
      (700px panel - 24px padding - 12px gaps) / 4 columns. The fifth column
      (custom + Add theme tiles) is what forces every column to its minimum —
      with it the fr share never expands, so the minimum IS the card width. */
  .theme-panel-large .tp-grid.tp-scroll-row.tp-scroll-3row{
    display:grid; gap:4px; overflow-x:auto; overflow-y:hidden;
    grid-template-columns:none; grid-template-rows:repeat(3,auto);
    grid-auto-flow:column; grid-auto-columns:minmax(166px,1fr);
    scroll-behavior:smooth; scrollbar-width:none; position:relative;
  }
  .theme-panel-large .tp-grid.tp-scroll-row.tp-scroll-3row::-webkit-scrollbar{ display:none; }
  .theme-panel-large .tp-grid.tp-scroll-row.tp-scroll-3row > .theme-opt{
    flex:none; width:auto;
  }
  /* Edge fades: the only cue that more options exist off-screen. Applied with
     a mask so they tint whatever is behind them, and only on the side that
     actually has more to show — a permanent fade would imply content that
     is not there. */
  .theme-panel-large .tp-grid.tp-scroll-row.has-more-right{
    -webkit-mask-image:linear-gradient(to right, #000 calc(100% - 34px), transparent 100%);
    mask-image:linear-gradient(to right, #000 calc(100% - 34px), transparent 100%);
  }
  .theme-panel-large .tp-grid.tp-scroll-row.has-more-left{
    -webkit-mask-image:linear-gradient(to left, #000 calc(100% - 34px), transparent 100%);
    mask-image:linear-gradient(to left, #000 calc(100% - 34px), transparent 100%);
  }
  .theme-panel-large .tp-grid.tp-scroll-row.has-more-left.has-more-right{
    -webkit-mask-image:linear-gradient(to right, transparent 0, #000 34px, #000 calc(100% - 34px), transparent 100%);
    mask-image:linear-gradient(to right, transparent 0, #000 34px, #000 calc(100% - 34px), transparent 100%);
  }
  /* A focused option must never be hidden behind a fade. */
  .theme-panel-large .tp-grid.tp-scroll-row > .theme-opt:focus-visible{ outline-offset:-2px; }
  /* Two-row horizontal scrolling grid (Colour theme): only two rows are ever
     shown and extra columns scroll sideways — same fades and behaviour as the
     one-line rows, just with a taller window. Items keep stretching to fill
     the column track (the one-line row's fixed 160px flex width doesn't
     apply to grid items). */
  .theme-panel-large .tp-grid.tp-scroll-row.tp-scroll-2rows{
    display:grid;
    grid-template-rows:repeat(2,auto);
    grid-auto-flow:column;
    grid-auto-columns:minmax(160px,1fr);
  }
  .theme-panel-large .tp-grid.tp-scroll-row.tp-scroll-2rows > .theme-opt{
    width:auto; flex:none;
  }
  .style-thumb{
    width:70px; height:40px; border-radius:6px; border:1px solid var(--line);
    background:var(--paper); display:inline-flex; align-items:center; justify-content:center;
    flex-shrink:0; overflow:hidden;
  }
  .theme-opt{
    display:flex; align-items:center; gap:8px;
    padding:6px 8px; border:1.5px solid transparent; border-radius:9px;
    background:transparent; cursor:pointer; text-align:left;
    font-family:inherit; font-size:13px; font-weight:500; color:var(--ink);
  }
  .theme-opt:hover{background:var(--hover)}
  .theme-opt.active{border-color:var(--accent); background:var(--paper-2)}
  .theme-thumb{
    width:70px; height:40px; border-radius:6px;
    position:relative; border:1px solid var(--line); flex-shrink:0; overflow:hidden;
    display:flex; align-items:center; justify-content:center; gap:6px;
  }
  .theme-thumb .t1{position:static; width:14px; height:14px; border-radius:3px; flex-shrink:0}
  .theme-thumb .t2{position:static; width:11px; height:11px; border-radius:50%; flex-shrink:0}
  .theme-thumb.look-thumb{
    display:flex; align-items:center; justify-content:center;
    background:var(--paper); color:var(--ink); font-size:17px; font-weight:600;
  }
  .theme-name{flex:1; white-space:normal; line-height:1.25}

  .theme-opt.add-theme-opt{
    border:1.5px dashed var(--line-2);
    flex-direction:column; justify-content:center; text-align:center; gap:2px;
  }
  .theme-opt.add-theme-opt .theme-name{flex:0 0 auto; font-weight:600}
  .theme-opt.add-theme-opt .add-theme-icon{
    width:26px; height:26px; border-radius:50%;
    border:1.5px dashed var(--line-2);
    display:flex; align-items:center; justify-content:center;
    font-size:16px; line-height:1; font-weight:600; color:var(--ink-soft);
  }
  .theme-opt.add-theme-opt:hover .add-theme-icon,
  .theme-opt.add-theme-opt.active .add-theme-icon{border-color:var(--accent); color:var(--accent)}
  .theme-opt.custom-theme-opt .theme-name{
    white-space:normal; overflow-wrap:break-word; min-width:0;
  }
  /* Add-a-theme dialog: the one-click library picker. */
  .lib-grid{
    display:grid; grid-template-columns:repeat(3,minmax(0,1fr));
    gap:4px; max-height:216px; overflow-y:auto; margin-top:6px; padding:2px;
    scrollbar-width:thin;
  }
  .lib-card{
    display:flex; align-items:center; gap:6px; padding:5px 6px;
    border:1.5px solid transparent; border-radius:8px;
    background:transparent; cursor:pointer; text-align:left;
    font-family:inherit; font-size:12px; font-weight:500; color:var(--ink);
    transition: background-color 0.2s ease, border-color 0.2s ease;
  }
  .lib-card:hover{background:var(--hover); border-color:var(--line-2)}
  .lib-card .lib-name{flex:1; min-width:0; white-space:nowrap; overflow:hidden; text-overflow:ellipsis; line-height:1.2}


  /* ===== Context toolbar on selected node ===== */
  .nodebar{position:absolute;z-index:25;display:flex;align-items:center;gap:2px;background:var(--toolbar-bg);color:var(--toolbar-text);border-radius:10px;padding:4px;box-shadow:var(--shadow-lg)}
  .nodebar .nb-group{display:flex;gap:1px}
  .nodebar .nb-div{width:1px;height:22px;background:color-mix(in srgb, var(--toolbar-text) 22%, transparent);margin:0 4px}
  .nodebar button{border:none;background:none;color:var(--toolbar-text);min-width:30px;height:30px;padding:0;border-radius:7px;font-size:14px;display:inline-flex;align-items:center;justify-content:center;cursor:pointer;font-family:inherit}
  .nodebar button:hover{background:color-mix(in srgb, var(--toolbar-text) 16%, transparent)}
  .nodebar button.on{background:var(--accent);color:#fff}
  .nodebar button.size-btn{padding:0 8px;gap:3px;font-size:12.5px;font-weight:500;font-variant-numeric:tabular-nums}
  .nodebar button.color-btn{padding:0 6px;gap:2px}
  .nodebar button .caret{font-size:9px;opacity:.7}
  .nodebar button .A-mark{font-family:var(--serif);font-weight:700;font-size:13px;line-height:1;display:inline-block;padding-bottom:1px}
  .nodebar button b,.nodebar button s,.nodebar button u,.nodebar button i{font-family:var(--serif);font-size:14px}
  .nodebar button i{font-style:italic}
  .node-text math{ font-size:1.04em; }
  .node-text math[display="block"]{ display:block; margin:3px auto; }
  .node-text{min-width:0;max-width:100%;overflow-wrap:anywhere;word-break:break-word}
  .node-text code{font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;font-size:.9em;background:var(--paper-2,rgba(127,127,127,.14));padding:.1em .35em;border-radius:4px}
  /* Block nodes: a fenced code block or a table imported as its own node */
  .node-block{max-width:100%;overflow:auto;text-align:left}
  .node-block pre{margin:0;white-space:pre;overflow-x:auto;background:var(--paper-2,rgba(0,0,0,.05));padding:6px 9px;border-radius:6px;font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;font-size:11.5px;line-height:1.5}
  .node-block pre code{font-family:inherit}
  .node-block table{border-collapse:collapse;font-size:11.5px}
  .node-block th,.node-block td{border:1px solid var(--line,#d9dee6);padding:2px 7px;text-align:left;white-space:nowrap}
  .node-block th{background:var(--paper-2,rgba(0,0,0,.05));font-weight:600}
  .node.block-node{max-width:none}                 /* grow to fit code/table; no scrollbar unless resized smaller */
  .block-node .node-text{cursor:default}
  .node .img-alt{display:block;font-size:12px;font-style:italic;color:var(--ink-soft,#667);white-space:normal;max-width:220px;line-height:1.4}
  .node.img-missing{border-style:dashed}
  .node.editing-block .node-block{cursor:text;user-select:text}
  .node.editing-block{border-color:var(--accent,#e0613a)}
  .node-text .node-link{color:var(--link,var(--accent));text-decoration:underline;text-underline-offset:2px;cursor:pointer;word-break:break-all}
  .node-text .node-link:hover{color:var(--accent-deep)}
  .node.editing .node-text .node-link{cursor:text;color:inherit;text-decoration:underline}
  .node-text .node-link-fav{width:14px;height:14px;border-radius:3px;object-fit:cover;vertical-align:-2px;margin-right:5px;display:inline-block;background:var(--line-2,#e2e8f0)}
  .node-text .node-link-label{word-break:break-all}
  .node.editing .node-text .node-link-fav{display:none}
  .swatches{display:flex;gap:3px;align-items:center;padding:0 2px}
  .sw{width:18px;height:18px;border-radius:50%;border:2px solid transparent;cursor:pointer}
  .sw:hover{transform:scale(1.18)}

  /* ===== Picker popovers (font size / text color / highlight) ===== */
  .picker{background:var(--node-bg, #fff);color:var(--ink);border-radius:10px;box-shadow:0 10px 32px rgba(0,0,0,.30),0 1px 3px rgba(0,0,0,.10);padding:6px;display:flex;gap:3px;align-items:center;z-index:1000;border:1px solid var(--chrome-edge)}
  .picker.size{flex-direction:column;max-height:240px;overflow-y:auto;padding:4px}
  .picker.size button{min-width:54px;justify-content:flex-start;padding:6px 12px}
  .picker button{border:none;background:none;cursor:pointer;padding:6px 10px;font-family:inherit;font-size:13px;border-radius:6px;color:var(--ink);display:inline-flex;align-items:center;justify-content:center}
  .picker button:hover{background:var(--hover)}
  .picker button.on{background:var(--paper-2);font-weight:600;color:var(--ink)}
  .picker .p-sw{width:22px;height:22px;padding:0;border-radius:50%;border:2px solid var(--node-bg, #fff);box-shadow:0 0 0 1px var(--line-2)}
  .picker .p-sw.on{box-shadow:0 0 0 2px var(--accent)}
  .picker .p-default{color:var(--ink-soft);font-size:12px;padding:6px 8px;border-right:1px solid var(--line);margin-right:2px;border-radius:0}

  /* ===== Empty state ===== */
  .empty{position:absolute;inset:0;display:grid;place-items:center;text-align:center;color:var(--ink-soft);z-index:5}
  .empty .e-card{background:var(--chrome);border:1px solid var(--chrome-edge);border-radius:20px;padding:40px 44px;box-shadow:var(--shadow-lg);max-width:380px}
  .empty h2{font-family:var(--serif);font-size:26px;color:var(--ink);margin:0 0 8px}
  .empty p{margin:0 0 20px;line-height:1.6}

  .toast{position:absolute;bottom:64px;left:50%;transform:translateX(-50%) translateY(20px);background:var(--toolbar-bg);color:var(--toolbar-text);padding:11px 20px;border-radius:11px;font-size:13.5px;font-weight:500;box-shadow:var(--shadow-lg);opacity:0;pointer-events:none;transition:opacity .25s,transform .25s,background-color .3s ease,border-color .3s ease,color .3s ease;z-index:50}
  .toast.show{opacity:1;transform:translateX(-50%) translateY(0)}
  /* ===== Login overlay (cloud / static-deploy mode only) ===== */
  .login-overlay{
    position:fixed; inset:0; z-index:5000;
    display:flex; align-items:center; justify-content:center;
    background:var(--paper);
    font-family:var(--sans);
  }
  .login-card{
    background:var(--node-bg, #fff); color:var(--ink);
    border-radius:16px; box-shadow:0 22px 70px rgba(0,0,0,.25), 0 1px 3px rgba(0,0,0,.06);
    padding:32px 36px; width:520px; max-width:92vw;
    border:1px solid var(--chrome-edge);
  }
  .login-brand{display:flex; align-items:center; gap:10px; margin-bottom:18px}
  .login-brand .mark{flex:0 0 auto; filter:drop-shadow(0 2px 6px rgba(224,97,58,.3))}
  .login-brand h1{
    font-family:var(--serif); font-weight:900; font-size:26px; margin:0;
    color:var(--ink); letter-spacing:-.5px;
  }
  .login-brand h1 span{color:var(--accent)}
  .login-card h2{
    font-family:var(--serif); font-weight:700; font-size:22px;
    margin:0 0 10px; color:var(--ink);
  }
  .login-card > p{
    color:var(--ink-soft); line-height:1.55; margin:0 0 14px; font-size:14px;
  }
  .login-card code{
    background:var(--paper-2); padding:1px 6px; border-radius:4px;
    font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace; font-size:12.5px;
  }
  .login-steps{
    counter-reset:step; list-style:none; padding:0; margin:18px 0;
  }
  .login-steps > li{
    position:relative; padding-left:40px; margin-bottom:18px;
    counter-increment:step;
  }
  .login-steps > li:before{
    content:counter(step);
    position:absolute; left:0; top:-2px;
    width:28px; height:28px; border-radius:50%;
    background:var(--accent); color:#fff;
    display:flex; align-items:center; justify-content:center;
    font-weight:700; font-size:14px;
  }
  .login-step-link{
    color:var(--accent); font-weight:600; text-decoration:none; font-size:15px;
  }
  .login-step-link:hover{text-decoration:underline}
  .login-step-hint{font-size:13px; color:var(--ink-soft); margin-top:6px; line-height:1.5}
  .login-steps label{display:block; font-size:14px; color:var(--ink); margin-bottom:6px; font-weight:500}
  .token-input{display:flex; gap:8px}
  .token-input input{
    flex:1; padding:10px 12px;
    font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace; font-size:13px;
    border:1.5px solid var(--line); border-radius:8px;
    background:var(--paper); color:var(--ink); outline:none;
  }
  .token-input input:focus{border-color:var(--accent); background:var(--node-bg, #fff)}
  .token-input button{
    padding:10px 20px; background:var(--accent); color:#fff;
    border:none; border-radius:8px; font-family:inherit; font-weight:600;
    cursor:pointer; font-size:14px;
  }
  .token-input button:hover{background:var(--accent-deep)}
  .token-input button:disabled{opacity:.65; cursor:wait}
  .login-error{
    color:#c5392a; font-size:13px; margin-top:8px; min-height:16px; line-height:1.4;
  }
  .login-extra{margin-top:18px; padding-top:16px; border-top:1px solid var(--chrome-edge)}
  .login-extra summary{cursor:pointer; color:var(--ink-soft); font-size:13px; font-weight:500}
  .login-extra summary:hover{color:var(--ink)}
  .login-extra p{margin:10px 0 0; font-size:13px; color:var(--ink-soft); line-height:1.6}
  .login-extra a{color:var(--accent)}

  /* User pill — shown in topbar after GitHub sign-in */
  .user-pill{
    display:flex; align-items:center; gap:8px;
    padding:3px 4px 3px 4px;
    background:var(--chrome); border:1px solid var(--chrome-edge);
    border-radius:22px; font-size:13px; font-weight:500;
    color:var(--ink); height:32px;
  }
  .user-pill img{width:24px; height:24px; border-radius:50%; background:var(--paper-2)}
  .user-pill span{padding:0 4px}
  .user-pill button{
    background:transparent; border:none; color:var(--ink-soft);
    cursor:pointer; font-family:inherit; padding:2px 8px;
    border-radius:6px; font-size:14px; height:26px;
  }
  .user-pill button:hover{background:var(--hover); color:var(--ink)}

  /* ===== Donate button + modal ===== */
  .tb.donate-btn{color:#e0613a; font-size:17px}
  .tb.donate-btn:hover{background:rgba(224,97,58,.12); color:#e0613a}

  .donate-modal{position:fixed; inset:0; z-index:6000; font-family:var(--sans); animation:fadeIn .15s ease}
  @keyframes fadeIn{from{opacity:0}to{opacity:1}}
  .donate-backdrop{position:absolute; inset:0; background:rgba(20,15,8,.45); backdrop-filter:blur(2px)}
  .donate-card{
    position:absolute; left:50%; top:50%; transform:translate(-50%,-50%);
    background:var(--node-bg, #fff); color:var(--ink);
    border-radius:18px; box-shadow:0 30px 80px rgba(0,0,0,.35);
    padding:30px 32px; width:440px; max-width:92vw; max-height:90vh; overflow-y:auto;
    border:1px solid var(--chrome-edge);
  }
  .donate-close{
    position:absolute; top:12px; right:14px; width:32px; height:32px;
    border:none; background:transparent; color:var(--ink-soft);
    font-size:22px; line-height:1; cursor:pointer; border-radius:8px;
  }
  .donate-close:hover{background:var(--hover); color:var(--ink)}
  .donate-head{text-align:center; margin-bottom:22px}
  .donate-icon{
    width:54px; height:54px; border-radius:50%;
    background:radial-gradient(circle at 30% 25%, #ff8a5b, #e0613a);
    color:#fff; font-size:26px; display:flex; align-items:center; justify-content:center;
    margin:0 auto 14px; box-shadow:0 6px 18px rgba(224,97,58,.4);
  }
  .donate-head h2{font-family:var(--serif); font-weight:700; font-size:22px; margin:0 0 6px}
  .donate-head p{color:var(--ink-soft); font-size:14px; line-height:1.55; margin:0}
  .donate-label{font-size:11px; text-transform:uppercase; letter-spacing:.1em; color:var(--ink-soft); font-weight:700; margin-bottom:8px}
  .donate-amounts{margin-bottom:18px}
  .donate-amount-row{display:flex; gap:8px; flex-wrap:wrap}
  .donate-amt{
    flex:1; min-width:60px; padding:11px 6px;
    background:var(--paper-2); border:1.5px solid var(--line); border-radius:9px;
    font-family:inherit; font-weight:600; font-size:14px; color:var(--ink); cursor:pointer;
    transition:.15s;
  }
  .donate-amt:hover{border-color:var(--accent); color:var(--accent)}
  .donate-amt.on{background:var(--accent); color:#fff; border-color:var(--accent)}
  .donate-custom{
    flex:1.4; min-width:90px; display:flex; align-items:center; gap:4px;
    background:var(--paper-2); border:1.5px solid var(--line); border-radius:9px;
    padding:0 10px; color:var(--ink-soft);
  }
  .donate-custom input{
    flex:1; width:0; border:none; background:transparent; outline:none;
    font-family:inherit; font-weight:600; font-size:14px; padding:10px 0; color:var(--ink);
  }
  .donate-providers{display:flex; flex-direction:column; gap:6px; margin-bottom:18px}
  .donate-provider{
    display:flex; align-items:center; gap:12px; padding:13px 14px;
    background:var(--paper-2); border:1px solid var(--line); border-radius:10px;
    font-family:inherit; font-size:14px; font-weight:500; color:var(--ink);
    cursor:pointer; transition:.15s; text-align:left;
  }
  .donate-provider:hover{background:var(--node-bg, #fff); border-color:var(--p-color); transform:translateX(2px)}
  .donate-provider .dp-icon{
    width:32px; height:32px; border-radius:8px;
    background:var(--p-color); color:#000; opacity:.95;
    display:flex; align-items:center; justify-content:center; font-weight:700; font-size:15px;
    flex-shrink:0;
  }
  .donate-provider .dp-label{flex:1}
  .donate-provider .dp-arrow{color:var(--ink-soft); font-size:16px}
  .donate-empty{
    background:var(--paper-2); border-radius:10px; padding:18px;
    font-size:13px; color:var(--ink-soft); line-height:1.6;
  }
  .donate-empty .small{font-size:12px}
  .donate-foot{
    text-align:center; padding-top:14px;
    border-top:1px solid var(--chrome-edge); font-size:12.5px;
  }
  .donate-foot a{color:var(--ink-soft); text-decoration:none; margin:0 6px}
  .donate-foot a:hover{color:var(--accent)}

  /* ===== MOBILE / TOUCH ===== */
  @media (max-width: 720px){
    /* Single-column grid: stage takes the whole screen; sidebar overlays it */
    .app{grid-template-columns:1fr}
    body.md-ready .app{grid-template-columns:1fr}                     /* single column; md pane overlays */
    #mdPane{position:fixed;top:0;left:0;bottom:0;width:min(94vw,560px);z-index:200;box-shadow:var(--shadow-lg);transform:translateX(-100%);transition:transform .25s cubic-bezier(.4,0,.2,1)}
    body.md-mode #mdPane{width:min(94vw,560px);transform:translateX(0)}
    #mdPane .md-resize{display:none}
    .side{
      position:fixed; top:0; left:0; bottom:0; width:min(280px, 86vw);
      z-index:200; box-shadow:var(--shadow-lg);
      transform:translateX(0);
      transition:transform .25s cubic-bezier(.4,0,.2,1);
    }
    .side.collapsed{
      width:min(280px, 86vw);     /* keep width so transform works */
      transform:translateX(-100%);
      border:none; box-shadow:none;
    }
    /* Off-canvas overlay shows the sidebar contents again — but only the
       ACTIVE pane, and with !important to beat the collapsed-rail rules.
       (The brand stays hidden: the overlay is dismissed by tapping the dimmed
       stage, which closes the sidebar.) */
    .side.collapsed .side-tabs{display:flex !important}
    .side.collapsed .side-pane.active{display:flex !important}
    .side.collapsed .side-foot{display:block !important}
    .side.collapsed .side-rail,
    .side-resize{display:none !important}       /* no icon rail / resize on touch */
    /* Status bar: single-line, hint text shrinks to fit */
    .statusbar{padding:4px 10px; gap:8px; grid-column:1; grid-row:4}
    .statusbar .hint{max-width:58%}
    .statusbar .save-pill{display:none}
    .statusbar .token-total{padding:4px 9px; font-size:11px}
    /* Dim the canvas while the mobile sidebar is open */
    .app:has(.side:not(.collapsed)) .stage::after{
      content:""; position:absolute; inset:0; background:rgba(20,15,8,.35);
      z-index:150; backdrop-filter:blur(1px);
    }
    .stage{width:100%}

    /* Topbar: keep buttons readable on tiny screens */
    .topbar{padding:7px 8px; gap:4px; grid-column:1; grid-row:1}
    .side{grid-column:1; grid-row:2}
    .stage{grid-column:1; grid-row:3}
    #tabStrip, #tabsBtn{display:none}               /* no tabs on touch screens */
    .title-edit{min-width:60px; max-width:130px; font-size:16px; padding:4px 8px}
    .tb{width:38px; height:38px; font-size:18px}    /* bigger tap targets */
    .tb.wide{padding:0 10px}
    .save-pill{display:none}                        /* hide on phones to save room */
    .user-pill span{display:none}                   /* avatar only */
    .search-wrap.open{width:140px}
    .search-wrap.open.replace-mode{width:min(86vw,330px)}
    .donate-btn{display:flex}

    .hint{display:none}

    /* Format toolbar wraps and scrolls on narrow screens */
    .nodebar{max-width:calc(100vw - 16px); flex-wrap:wrap}
    .nodebar button{width:34px; height:34px; min-width:34px}

    /* Overview chip tighter on phones; minimap hidden */
    .overview{gap:4px; padding:2px 4px}
    .overview .minimap{display:none}
    .zoom-row button{width:32px; height:32px}

    /* Cards fit phone width */
    .login-card{padding:24px 22px}
    .login-brand h1{font-size:22px}
    .notes-popup{width:96vw}
    .donate-card{padding:24px 22px; border-radius:14px}
    .donate-head h2{font-size:20px}

    /* Theme panel becomes a bottom sheet */
    .theme-panel-large{
      min-width:0; width:100vw; max-width:100vw;
      position:fixed !important; left:0 !important; right:0 !important;
      bottom:0; top:auto !important;
      border-radius:16px 16px 0 0; max-height:80vh; overflow-y:auto;
    }
    .theme-panel-large .tp-grid{grid-template-columns:repeat(2, 1fr)}
  }

  /* Disable browser tap-highlight on interactive UI */
  .tb, .node, .handle, .sw, .donate-provider, .donate-amt, .theme-opt, .map-item,
  .nodebar button, .picker button, .login-card button {
    -webkit-tap-highlight-color:transparent;
    touch-action:manipulation;
  }
  /* Stage shouldn't double-tap-zoom on iOS */
  #stage{touch-action:none}

  /* ===== QR sub-view inside the donate modal ===== */
  .donate-back{
    position:absolute; top:14px; left:14px;
    border:none; background:transparent; cursor:pointer;
    color:var(--ink-soft); font-family:inherit; font-size:13px; padding:4px 8px;
    border-radius:6px;
  }
  .donate-back:hover{background:var(--hover); color:var(--ink)}
  .qr-view{text-align:center; padding-top:8px}
  .qr-view h2{font-family:var(--serif); font-weight:700; font-size:20px; margin:0 0 6px; color:var(--ink)}
  .qr-sub{color:var(--ink-soft); font-size:13.5px; line-height:1.5; margin:0 0 18px}
  .qr-frame{
    width:240px; max-width:90%; aspect-ratio:1/1; margin:0 auto;
    background:#fff; border-radius:12px; padding:14px;
    box-shadow:0 4px 20px rgba(0,0,0,.12); border:1px solid var(--chrome-edge);
  }
  .qr-image{width:100%; height:100%; object-fit:contain; display:block}
  .qr-note{
    margin-top:14px; font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;
    font-size:13px; color:var(--ink); background:var(--paper-2);
    padding:7px 12px; border-radius:7px; display:inline-block;
  }
  .qr-deeplink{
    display:inline-block; margin-top:14px; font-size:13.5px;
    color:var(--accent); text-decoration:none; font-weight:500;
  }
  .qr-deeplink:hover{text-decoration:underline}
  .qr-foot{margin:18px 0 0; font-size:13px; color:var(--ink-soft)}

  /* ===== Export popover ===== */
  .export-pop{
    background:var(--chrome); border:1px solid var(--chrome-edge); border-radius:14px;
    box-shadow:var(--shadow-lg); padding:6px; z-index:1000;
    min-width:280px; max-width:300px; font-family:var(--sans);
    display:flex; flex-direction:column; gap:1px;
    max-height:calc(100vh - 72px); overflow-y:auto;
  }
  .export-pop button{
    display:flex; align-items:center; gap:12px;
    padding:9px 10px; background:transparent; border:none;
    border-radius:9px; cursor:pointer; text-align:left;
    color:var(--ink); font-family:inherit; font-size:13.5px;
  }
  .export-pop button:hover{background:var(--hover)}
  .export-pop .ex-ic{
    width:30px; height:30px; flex-shrink:0;
    display:flex; align-items:center; justify-content:center;
    background:var(--paper-2); border-radius:7px;
    font-size:15px; font-family:ui-monospace,monospace;
  }
  .export-pop button span:not(.ex-ic){display:flex; flex-direction:column; line-height:1.3}
  .export-pop button b{font-weight:600; font-size:13px}
  .export-pop button i{font-style:normal; color:var(--ink-soft); font-size:11.5px; margin-top:1px}
  .export-pop .ex-div{height:1px; background:var(--chrome-edge); margin:4px 6px}

  /* ===== Templates popover (classic floating) ===== */
  .tpl-pop{
    background:var(--chrome); border:1px solid var(--chrome-edge); border-radius:14px;
    box-shadow:var(--shadow-lg); padding:8px; z-index:1000;
    width:340px; font-family:var(--sans);
    display:flex; flex-direction:column; gap:1px;
    overflow-y:auto;
  }
  .tpl-pop .tpl-head{
    font-size:11px; text-transform:uppercase; letter-spacing:.11em;
    color:var(--ink-soft); font-weight:700; padding:6px 10px 8px;
  }
  .tpl-pop .tpl-divider{height:1px; background:var(--chrome-edge); margin:5px 6px}
  .tpl-pop .tpl-chev{margin-left:auto; color:var(--ink-soft); font-size:18px; font-weight:400; padding-left:6px}
  .tpl-cat:hover .tpl-chev{color:var(--ink)}
  .tpl-pop .tpl-back{
    display:flex; align-items:center; gap:4px;
    background:transparent; border:none; cursor:pointer;
    color:var(--ink-soft); font-family:inherit; font-size:12.5px; font-weight:600;
    padding:6px 8px; border-radius:8px; text-align:left;
  }
  .tpl-pop .tpl-back:hover{background:var(--hover); color:var(--ink)}
  .tpl-item{
    display:flex; align-items:center; gap:11px;
    padding:9px 10px; background:transparent; border:none;
    border-radius:9px; cursor:pointer; text-align:left;
    color:var(--ink); font-family:inherit;
  }
  .tpl-item:hover{background:var(--hover)}
  .tpl-ic{
    width:30px; height:30px; flex-shrink:0;
    display:flex; align-items:center; justify-content:center;
    color:#fff; border-radius:7px; font-weight:700;
    font-size:14px; font-family:var(--serif);
  }
  .tpl-item span:not(.tpl-ic){display:flex; flex-direction:column; line-height:1.3; min-width:0}
  .tpl-item b{font-weight:600; font-size:13px; color:var(--ink); white-space:nowrap; overflow:hidden; text-overflow:ellipsis}
  .tpl-item i{font-style:normal; color:var(--ink-soft); font-size:11.5px; margin-top:2px}
  .tpl-pop .tpl-del{
    margin-left:auto; color:var(--ink-soft); font-size:12px; padding:2px 6px;
    border-radius:5px; opacity:0;
  }
  .tpl-pop .tpl-item:hover .tpl-del{opacity:.7}
  .tpl-pop .tpl-del:hover{opacity:1; background:var(--hover); color:#c0392b}

  /* ===== Sidebar GitHub / bug links ===== */
  .side-links{
    display:flex; flex-direction:column; gap:8px; margin-top:10px; padding-top:10px;
    border-top:1px solid var(--chrome-edge);
  }
  .side-links a{
    display:flex; align-items:center; gap:7px;
    color:var(--ink-soft); text-decoration:none;
    font-size:12px; font-weight:500; white-space:nowrap;
  }
  .side-links a:hover{color:var(--accent)}
  /* Uniform 16px icon gutter so emoji and the GitHub SVG line up in a column. */
  .side-links a svg,
  .side-links a .li-ic{
    flex-shrink:0; width:16px; height:16px;
    display:inline-flex; align-items:center; justify-content:center;
    opacity:.85; font-size:13px; line-height:1;
  }
  .gh-stars{margin-left:auto;font-size:11px;font-weight:600;color:var(--ink-soft);background:var(--paper-2);border:1px solid var(--line);border-radius:20px;padding:1px 7px;line-height:1.6;white-space:nowrap}
  .gh-stars[hidden]{display:none}

  /* Inline lists inside a node (created via the selection-aware UL/OL button).
     Override the centered text-align since bulleted lines look better aligned left. */
  .node-text ul, .node-text ol{
    margin:4px 0; padding-left:22px;
    text-align:left; display:inline-block; vertical-align:top;
  }
  .node-text li{margin:2px 0}
  .node-text ul{list-style-type:disc}
  .node-text ol{list-style-type:decimal}

  /* ===== Focus mode — hide all chrome, full-bleed canvas ===== */
  body.focus-mode .topbar,
  body.focus-mode .side,
  body.focus-mode .hint,
  body.focus-mode .save-pill,
  body.focus-mode .user-pill,
  body.focus-mode .empty .btn-row,
  body.focus-mode .statusbar,
  body.focus-mode .search-wrap{display:none !important}
  body.focus-mode .app{grid-template-columns:1fr}
  body.focus-mode .stage{grid-column:1;grid-row:3;width:calc(100vw / var(--ui-zoom, 1)); height:calc(100vh / var(--ui-zoom, 1)); height:calc(100dvh / var(--ui-zoom, 1))}
  .focus-exit{
    position:fixed; top:16px; right:18px; z-index:5500;
    padding:8px 14px;
    background:var(--chrome); color:var(--ink);
    border:1px solid var(--chrome-edge);
    border-radius:22px;
    font-family:var(--sans); font-size:13px; font-weight:500;
    cursor:pointer; box-shadow:var(--shadow);
    opacity:.7; transition:opacity .2s;
  }
  .focus-exit:hover{opacity:1; background:var(--hover)}

  /* ===== Token-count badge (bottom-right of node) ===== */
  .node .token-badge{
    position:absolute; bottom:-9px; left:-6px;
    padding:1px 7px; border-radius:9px;
    background:var(--toolbar-bg); color:var(--toolbar-text);
    font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;
    font-size:10px; font-weight:600; line-height:1.4;
    opacity:.85; pointer-events:auto; z-index:5;
    border:1.5px solid var(--node-bg, #fff);
    white-space:nowrap;
  }
  .node .token-badge:hover{opacity:1}
  .node.sel .token-badge{opacity:1}

  /* ===== Variable / placeholder form (Export as prompt) ===== */
  .var-form{position:fixed; inset:0; z-index:6000; font-family:var(--sans); animation:fadeIn .15s ease}
  .vf-backdrop{position:absolute; inset:0; background:rgba(20,15,8,.45); backdrop-filter:blur(2px)}
  .vf-card{
    position:absolute; left:50%; top:50%; transform:translate(-50%,-50%);
    background:var(--node-bg, #fff); color:var(--ink);
    border-radius:16px; box-shadow:0 30px 80px rgba(0,0,0,.35);
    padding:28px 30px; width:520px; max-width:92vw; max-height:88vh; overflow-y:auto;
    border:1px solid var(--chrome-edge);
  }
  .vf-close{
    position:absolute; top:12px; right:14px; width:32px; height:32px;
    border:none; background:transparent; color:var(--ink-soft);
    font-size:22px; line-height:1; cursor:pointer; border-radius:8px;
  }
  .vf-close:hover{background:var(--hover); color:var(--ink)}
  .vf-card h2{font-family:var(--serif); font-weight:700; font-size:22px; margin:0 0 6px}
  .vf-sub{color:var(--ink-soft); font-size:13.5px; margin:0 0 18px; line-height:1.55}
  .vf-fields{display:flex; flex-direction:column; gap:14px}
  .vf-row{display:flex; flex-direction:column; gap:6px}
  .vf-name{font-size:12px; color:var(--ink-soft); font-weight:500}
  .vf-name code{
    background:var(--paper-2); color:var(--ink);
    padding:2px 8px; border-radius:5px;
    font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace; font-size:13px;
  }
  .vf-input{
    width:100%; box-sizing:border-box;
    padding:9px 12px; font-family:var(--sans); font-size:14px;
    line-height:1.45; color:var(--ink);
    background:var(--paper); border:1.5px solid var(--line); border-radius:8px;
    resize:vertical; outline:none; min-height:38px;
  }
  .vf-input:focus{border-color:var(--accent); background:var(--node-bg, #fff)}
  .vf-actions{display:flex; gap:8px; margin-top:18px; align-items:center}
  .vf-actions button{
    padding:9px 16px; border-radius:8px; border:1px solid var(--line);
    background:var(--node-bg, #fff); cursor:pointer;
    font-family:inherit; font-size:13px; font-weight:500; color:var(--ink);
  }
  .vf-actions button:hover{background:var(--hover)}
  .vf-actions .vf-go{background:var(--accent); color:#fff; border-color:var(--accent)}
  .vf-actions .vf-go:hover{background:var(--accent-deep)}
  .vf-skip{margin-right:auto; color:var(--ink-soft); border-color:transparent !important; background:transparent !important}
  .vf-skip:hover{color:var(--ink); background:var(--hover) !important}
  .vf-clear{margin-right:auto; color:var(--ink-soft); border-color:transparent !important; background:transparent !important}
  .vf-clear:hover{color:var(--ink); background:var(--hover) !important}

  /* ===== Keyboard help overlay (press ?) ===== */
  .kb-help{position:fixed; inset:0; z-index:6000; font-family:var(--sans); animation:fadeIn .15s ease}
  .kb-backdrop{position:absolute; inset:0; background:rgba(20,15,8,.45); backdrop-filter:blur(2px)}
  .kb-card{
    position:absolute; left:50%; top:50%; transform:translate(-50%,-50%);
    background:var(--node-bg, #fff); color:var(--ink);
    border-radius:16px; box-shadow:0 30px 80px rgba(0,0,0,.35);
    padding:28px 32px; width:640px; max-width:92vw; max-height:88vh; overflow-y:auto;
    border:1px solid var(--chrome-edge);
  }
  .kb-close{
    position:absolute; top:12px; right:14px; width:32px; height:32px;
    border:none; background:transparent; color:var(--ink-soft);
    font-size:22px; line-height:1; cursor:pointer; border-radius:8px;
  }
  .kb-close:hover{background:var(--hover); color:var(--ink)}
  .kb-card h2{font-family:var(--serif); font-weight:700; font-size:22px; margin:0 0 16px}
  .kb-grid{display:grid; grid-template-columns:1fr 1fr; gap:18px 32px}
  .kb-card h3{
    font-size:11px; text-transform:uppercase; letter-spacing:.1em;
    color:var(--ink-soft); font-weight:700; margin:0 0 6px;
  }
  .kb-card table{border-collapse:collapse; width:100%; font-size:13.5px}
  .kb-card td{padding:5px 0; vertical-align:middle}
  .kb-card td:first-child{width:120px; padding-right:12px}
  .kb-card kbd{
    display:inline-block; padding:2px 7px;
    background:var(--paper-2); border:1px solid var(--chrome-edge);
    border-radius:5px; font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;
    font-size:12px; line-height:1.4; color:var(--ink);
    box-shadow:0 1px 0 var(--chrome-edge);
  }
  .kb-foot{margin-top:18px; padding-top:14px; border-top:1px solid var(--chrome-edge);
    color:var(--ink-soft); font-size:12.5px; text-align:center}
  @media (max-width:720px){
    .kb-card{padding:22px 20px}
    .kb-grid{grid-template-columns:1fr}
  }

  /* ===== Whole-map token total (topbar) ===== */
  .token-total{
    font-size:12px; color:var(--ink-soft);
    background:var(--chrome); border:1px solid var(--chrome-edge);
    border-radius:20px; padding:6px 13px;
    box-shadow:var(--shadow); font-weight:500; white-space:nowrap;
    font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;
  }
  @media (max-width:720px){ .token-total{display:none !important} }

  /* ===== Multi-select ===== */
  .node.multi-sel{
    outline:2.5px dashed var(--accent); outline-offset:3px;
  }
  .node.multi-sel::after{
    content:'✓'; position:absolute; top:-9px; right:-9px;
    width:18px; height:18px; border-radius:50%;
    background:var(--accent); color:#fff;
    font-size:11px; font-weight:700; line-height:18px; text-align:center;
    box-shadow:0 1px 4px rgba(0,0,0,.3); z-index:6;
  }
  .bulk-bar{
    position:fixed; bottom:22px; left:50%; transform:translateX(-50%);
    z-index:600; display:flex; align-items:center; gap:4px;
    background:var(--toolbar-bg); color:var(--toolbar-text);
    border-radius:14px; padding:6px 8px; box-shadow:0 12px 36px rgba(0,0,0,.4);
    font-family:var(--sans); animation:fadeIn .15s ease;
  }
  .bulk-bar .bulk-count{font-size:13px; font-weight:600; padding:0 10px; white-space:nowrap}
  .bulk-bar .bulk-sep{width:1px; height:22px; background:currentColor; opacity:.2; margin:0 3px}
  .bulk-bar button{
    border:none; background:transparent; color:var(--toolbar-text);
    cursor:pointer; font-family:inherit; font-size:13px; font-weight:500;
    padding:7px 11px; border-radius:9px; white-space:nowrap;
  }
  .bulk-bar button:hover{background:color-mix(in srgb, var(--toolbar-text) 16%, transparent)}
  .bulk-bar .bulk-danger:hover{background:color-mix(in srgb, #e0473a 65%, transparent); color:#fff}
  .bulk-bar .bulk-cancel{font-size:14px; opacity:.75}

  /* ===== Cross-link mode ===== */
  .node.link-source{
    outline:2.5px solid var(--accent); outline-offset:3px;
    animation:linkpulse 1.1s ease-in-out infinite;
  }
  @keyframes linkpulse{50%{outline-color:color-mix(in srgb,var(--accent) 40%,transparent)}}

  /* ===== Print — take the map to a meeting ===== */
  @media print{
    /* The app is a fixed-viewport SPA (html,body{height:100%;overflow:hidden}) so the
       canvas never page-scrolls on screen — but that same constraint silently clips ANY
       print output to a single page's worth of content, however much there actually is.
       Print has no "viewport" in that sense, so drop the constraint entirely here. */
    html, body{ height:auto !important; overflow:visible !important; }
    .topbar, .side, .overview, .hint, .save-pill, .token-total, .statusbar,
    .nodebar, .search-wrap, .user-pill, .bulk-bar, .focus-exit,
    .picker, .tpl-pop, .export-pop, .theme-panel, #outlinePane, #deckBar, #tabStrip{ display:none !important; }
    .app{ grid-template-columns:1fr !important; }
    .stage{ width:100% !important; height:auto !important; overflow:visible !important; }
    body, .app, .stage{ background:#fff !important; }
    .node{ box-shadow:none !important; -webkit-print-color-adjust:exact; print-color-adjust:exact; }
    .node .token-badge, .node .notes-mark{ display:none !important; }
    @page{ margin:1cm; }
  }

  /* ===== Task state ===== */
  .node.has-image{flex-direction:column; align-items:stretch; padding-top:8px}
  /* Image nodes size themselves to the picture. Two changes from the
     original rule, both deliberate:
       - object-fit was `cover`, which CROPS the image to fill the box; an
         attached picture should be shown in full, so `contain` + auto
         dimensions let it keep its own aspect ratio.
       - .node caps at 240px, which squeezed every picture regardless of its
         real size. Images are down-scaled to 360px wide on attach
         (readImageFile), so 400px here lets one display at natural size
         including the node's 15px horizontal padding, while still bounding
         how large a card can get. */
  .node .node-image{
    max-width:100%; max-height:280px; width:auto; height:auto;
    border-radius:8px; object-fit:contain;
    margin-bottom:6px; cursor:zoom-in; display:block;
  }
  .node.has-image{ max-width:400px; }
  /* Marker badge — sits beside the task checkbox and uses the same
     flex-shrink:0 / vertical-align treatment so the two line up when a node
     has both. font-size is nudged up because emoji render smaller than
     surrounding text at the same size. */
  .node .node-marker{
    flex-shrink:0; margin-right:6px; font-size:17px; line-height:1;
    cursor:pointer; user-select:none; vertical-align:middle;
  }
  .node .node-marker:hover{ transform:scale(1.15); }
  .picker.marker-picker{
    display:grid; grid-template-columns:repeat(4, 1fr); gap:2px; padding:6px;
  }
  .picker.marker-picker button{
    font-size:19px; line-height:1; padding:6px; border-radius:8px;
    background:none; border:1.5px solid transparent; cursor:pointer;
  }
  .picker.marker-picker button:hover{ background:var(--hover); }
  .picker.marker-picker button.on{ border-color:var(--accent); background:var(--paper-2); }
  .picker.marker-picker button.mk-none{ grid-column:1 / -1; font-size:13px; color:var(--ink-soft); }
  .picker.marker-picker button.mk-custom{ grid-column:1 / -1; font-size:13px; color:var(--ink-soft); border:1.5px dashed var(--line-2); }
  .picker.marker-picker .mk-custom-row{ grid-column:1 / -1; display:flex; align-items:center; gap:6px; }
  .picker.marker-picker .mk-custom-row input{
    flex:1; min-width:0; font-size:16px; padding:5px 8px; border-radius:8px;
    border:1.5px solid var(--line-2); background:var(--paper-1); color:var(--ink); font-family:inherit;
  }
  .picker.marker-picker .mk-custom-row input:focus{ outline:none; border-color:var(--accent); }
  .picker.marker-picker .mk-custom-row button.mk-apply{ font-size:13px; padding:5px 10px; }
  .picker.marker-picker .mk-custom-row button.mk-apply:disabled{ opacity:.45; cursor:default; }
  .node .task-check{
    flex-shrink:0; width:18px; height:18px; margin-right:7px;
    border:2px solid var(--line-2); border-radius:5px;
    display:inline-flex; align-items:center; justify-content:center;
    font-size:12px; font-weight:700; cursor:pointer; vertical-align:middle;
    background:var(--node-bg);
  }
  .node .task-check.task-todo{}
  .node .task-check.task-doing{border-color:#c98a1a; color:#c98a1a}
  .node .task-check.task-done{background:#4a9d5b; border-color:#4a9d5b; color:#fff}
  .node.task-done .node-text{text-decoration:line-through; opacity:.62}
  .node .task-progress{
    position:absolute; top:-9px; left:-6px;
    padding:1px 7px; border-radius:9px;
    background:var(--toolbar-bg); color:var(--toolbar-text);
    font-size:10px; font-weight:700; line-height:1.4;
    border:1.5px solid var(--node-bg); white-space:nowrap; z-index:5; opacity:.9;
    font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;
  }
  .node .task-progress.complete{background:#4a9d5b; color:#fff}

  /* ===== Reference / citation nodes ===== */
  .node.ref-node{
    border-left:4px solid var(--accent);
    font-style:italic;
  }
  .node .ref-mark{
    position:absolute; top:-9px; left:-9px;
    width:22px; height:22px; border-radius:50%;
    background:var(--node-bg); border:1.5px solid var(--accent);
    display:flex; align-items:center; justify-content:center;
    font-size:11px; cursor:pointer; z-index:6;
    box-shadow:0 1px 3px rgba(0,0,0,.18);
  }
  .node .ref-mark:hover{transform:scale(1.1)}

  /* ===== Global search results panel ===== */
  .global-results{
    position:fixed; z-index:1200; display:none;
    width:380px; max-width:92vw; max-height:70vh; overflow-y:auto;
    background:var(--chrome); border:1px solid var(--chrome-edge);
    border-radius:14px; box-shadow:var(--shadow-lg);
    font-family:var(--sans); padding:6px;
  }
  .global-results .gs-status{padding:14px; color:var(--ink-soft); font-size:13px; text-align:center}
  .global-results .gs-head{
    padding:8px 10px 6px; font-size:11px; text-transform:uppercase;
    letter-spacing:.08em; color:var(--ink-soft); font-weight:700;
  }
  .global-results .gs-group{margin-bottom:4px}
  .global-results .gs-map{
    padding:6px 10px 3px; font-size:12px; font-weight:700; color:var(--accent);
  }
  .global-results .gs-cur{color:var(--ink-soft); font-weight:400; text-transform:none}
  .global-results .gs-item{
    display:block; width:100%; text-align:left;
    padding:7px 10px; border:none; background:transparent; cursor:pointer;
    font-family:inherit; font-size:13px; color:var(--ink); border-radius:7px;
    line-height:1.4;
  }
  .global-results .gs-item:hover{background:var(--hover)}
  .global-results .gs-item mark{background:color-mix(in srgb, var(--accent) 40%, transparent); color:inherit; border-radius:2px; padding:0 1px}
  .global-results .gs-more{padding:3px 10px 8px; font-size:11.5px; color:var(--ink-soft)}
  /* 'all maps' toggle active state */
  .search-toggle.on{color:var(--accent); background:var(--hover)}

  /* ===== Sidebar duplicate button ===== */

  /* ===== Breadcrumb (floating pill, anchored under the topbar's left edge) =====
     Hidden by default; expands (fades in) while the mouse is over the overview
     in the status bar — the .shown class is toggled from JS. */
  .breadcrumb{
    position:fixed; top:56px; left:14px; transform:none;
    display:flex; align-items:center; gap:1px; z-index:90;
    background:var(--chrome); border:1px solid var(--chrome-edge);
    border-radius:10px; box-shadow:var(--shadow); padding:3px 6px;
    max-width:min(70vw, 720px); overflow:hidden; font-family:var(--sans);
    opacity:0; pointer-events:none; transform:translateY(-4px);
    transition:opacity .16s ease, transform .16s ease;
  }
  .breadcrumb.shown{opacity:1; pointer-events:auto; transform:translateY(0)}
  .breadcrumb .bc-crumb{
    border:none; background:transparent; cursor:pointer;
    font-family:inherit; font-size:12px; color:var(--ink-soft);
    padding:3px 7px; border-radius:6px; white-space:nowrap;
    max-width:170px; overflow:hidden; text-overflow:ellipsis;
  }
  .breadcrumb .bc-crumb:hover{background:var(--hover); color:var(--ink)}
  .breadcrumb .bc-crumb.current{color:var(--ink); font-weight:600}
  .breadcrumb .bc-sep{color:var(--ink-soft); font-size:12px; opacity:.6; flex:none}

  /* ===== Minimap (inside the overview card, bottom-right) ===== */
  .minimap{
    position:relative; z-index:29;
    width:104px; height:50px;
    background:color-mix(in srgb, var(--chrome) 92%, transparent);
    border:1px solid var(--chrome-edge); border-radius:10px;
    box-shadow:var(--shadow); overflow:hidden; cursor:crosshair;
  }
  .minimap svg{display:block;width:100%;height:100%}
  .minimap #mmView{ stroke:var(--accent); stroke-width:1.5; fill:color-mix(in srgb, var(--accent) 12%, transparent); }
  .minimap .mm-sel{ stroke:var(--accent); stroke-width:1.5; }
  @media (max-width:760px){ .minimap{display:none} .breadcrumb{max-width:88vw} }

  /* ===== Read-only shared view ===== */
  .shared-banner{
    position:fixed; top:0; left:0; right:0; z-index:300;
    display:flex; align-items:center; gap:12px;
    padding:9px 16px; font-family:var(--sans); font-size:13px;
    background:var(--accent); color:#fff;
    box-shadow:0 2px 12px rgba(0,0,0,.18);
  }
  .shared-banner .sb-eye{font-size:15px}
  .shared-banner .sb-text{opacity:.96}
  .shared-banner .sb-text b{font-weight:700}
  .shared-banner .sb-copy{
    margin-left:auto; border:1px solid rgba(255,255,255,.6); background:rgba(255,255,255,.16);
    color:#fff; font-family:inherit; font-size:12.5px; font-weight:600;
    padding:5px 12px; border-radius:8px; cursor:pointer;
  }
  .shared-banner .sb-copy:hover{background:rgba(255,255,255,.28)}
  .shared-banner .sb-brand{
    color:#fff; opacity:.85; text-decoration:none; font-weight:700; letter-spacing:.01em;
  }
  .shared-banner .sb-brand:hover{opacity:1; text-decoration:underline}

  /* In shared view: hide all editing chrome, keep viewing aids (zoom, minimap) */
  body.shared-view .side,
  body.shared-view #newMap,
  body.shared-view #menuExport,
  body.shared-view #searchBtn,
  body.shared-view #varsBtn,
  body.shared-view #focusBtn,
  body.shared-view #collapseAll,
  body.shared-view #mdToggle,
  body.shared-view #undo,
  body.shared-view #redo,
  body.shared-view #layout,
  body.shared-view #donateBtn,
  body.shared-view .hint,
  body.shared-view .save-pill,
  body.shared-view .menu-toggle,
  body.shared-view #addChild,
  body.shared-view #toggleSide{ display:none !important; }
  /* Sidebar is hidden in shared view — collapse the grid to one column so the
     stage fills the full width (otherwise it auto-places into the 0-width track
     and the canvas clips to nothing). */
  body.shared-view .app{ grid-template-columns:1fr; padding-top:var(--shared-banner-h, 42px); }
  body.shared-view .topbar{ grid-column:1; grid-row:1; }
  body.shared-view .stage{ grid-column:1; grid-row:3; }
  body.shared-view .statusbar{ grid-column:1; grid-row:4; }
  body.shared-view .breadcrumb{ top:97px; left:14px; }
  body.shared-view #mapTitle{ pointer-events:none; max-width:none; }
  body.shared-view .node{ cursor:default; }
  /* Read-only: no node editing affordances (collapse toggle + notes stay). */
  body.shared-view .handle.h-child,
  body.shared-view .handle.h-sibling,
  body.shared-view .resize-grip{ display:none !important; }
  @media (max-width:760px){
    .shared-banner{ font-size:12px; gap:8px; padding:8px 10px; }
    .shared-banner .sb-text{ flex:1; min-width:0; }
  }

  /* ===== Display-size (UI scale) control in theme panel ===== */
  .theme-panel .tp-hint{ font-weight:400; text-transform:none; letter-spacing:0; color:var(--ink-soft); font-size:10.5px; margin-left:6px; }
  .theme-panel .tp-scale{ display:flex; gap:6px; }
  .theme-panel .scale-opt{
    flex:1; padding:5px 0; border:1px solid var(--chrome-edge); border-radius:8px;
    background:var(--node-bg); color:var(--ink); cursor:pointer;
    font-family:var(--sans); font-size:12.5px; font-weight:600;
  }
  .theme-panel .scale-opt:hover{ background:var(--hover); }
  .theme-panel .scale-opt.active{ background:var(--accent); color:#fff; border-color:var(--accent); }

  /* ===== Version history panel ===== */
  .hist-panel{ position:fixed; top:64px; right:18px; width:320px; max-height:70vh; z-index:60;
    background:var(--node-bg); border:1px solid var(--chrome-edge); border-radius:14px;
    box-shadow:0 18px 50px rgba(0,0,0,.28); display:flex; flex-direction:column; overflow:hidden; font-family:var(--sans); }
  .hist-head{ display:flex; align-items:center; justify-content:space-between; padding:12px 14px; border-bottom:1px solid var(--chrome-edge); }
  .hist-x{ border:none; background:none; font-size:20px; cursor:pointer; color:var(--ink-soft); line-height:1; }
  .hist-list{ overflow-y:auto; padding:6px; }
  .hist-status{ padding:18px 14px; color:var(--ink-soft); font-size:13px; }
  .hist-sub{ color:var(--ink-soft); font-size:12px; }
  .hist-row{ display:flex; align-items:center; justify-content:space-between; gap:8px; padding:9px 10px; border-radius:9px; }
  .hist-row:hover{ background:var(--hover); }
  .hist-row.active{ background:var(--hover); outline:2px solid var(--accent); }
  .hist-when b{ display:block; font-size:13px; }
  .hist-when i{ display:block; font-size:11px; color:var(--ink-soft); font-style:normal; }
  .hist-actions{ display:flex; gap:6px; }
  .hist-actions button{ border:1px solid var(--chrome-edge); background:var(--node-bg); color:var(--ink);
    border-radius:7px; padding:5px 9px; font-size:12px; cursor:pointer; }
  .hist-actions button:hover{ background:var(--accent); color:#fff; border-color:var(--accent); }
  .hist-actions button.disabled{ opacity:.4; pointer-events:none; }
  .hist-banner{ position:fixed; top:14px; left:50%; transform:translateX(-50%); z-index:61;
    background:#2d2d2d; color:#fff; border-radius:999px; padding:8px 10px 8px 16px; display:flex; align-items:center; gap:10px;
    font-family:var(--sans); font-size:13px; box-shadow:0 10px 30px rgba(0,0,0,.3); }
  .hist-banner button{ border:none; border-radius:999px; padding:6px 12px; font-size:12px; cursor:pointer; font-weight:600; }
  .hb-restore{ background:var(--accent); color:#fff; }
  .hb-cancel{ background:rgba(255,255,255,.15); color:#fff; }

  /* ===== Build-prompt panel ===== */
  .bp-panel{ position:fixed; top:64px; right:18px; width:420px; max-width:calc(100vw - 36px); max-height:80vh; z-index:60;
    background:var(--node-bg); border:1px solid var(--chrome-edge); border-radius:14px;
    box-shadow:0 18px 50px rgba(0,0,0,.28); display:flex; flex-direction:column; overflow:hidden; font-family:var(--sans); }
  .bp-head{ display:flex; align-items:center; justify-content:space-between; padding:12px 14px; border-bottom:1px solid var(--chrome-edge); }
  .bp-head b{ font-size:14px; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
  .bp-x{ border:none; background:none; font-size:20px; cursor:pointer; color:var(--ink-soft); }
  .bp-text{ margin:12px 14px 0; min-height:160px; max-height:38vh; resize:vertical; border:1px solid var(--chrome-edge);
    border-radius:9px; padding:10px; font-family:var(--mono,ui-monospace,monospace); font-size:12.5px; line-height:1.5;
    background:var(--bg); color:var(--ink); }
  .bp-meta{ padding:6px 14px; color:var(--ink-soft); font-size:11.5px; }
  .bp-row{ display:flex; gap:8px; padding:0 14px 12px; }
  .bp-row button, .bp-run button{ border:1px solid var(--chrome-edge); background:var(--node-bg); color:var(--ink);
    border-radius:8px; padding:8px 12px; font-size:13px; cursor:pointer; font-family:var(--sans); }
  .bp-row button.primary, .bp-run button.primary{ background:var(--accent); color:#fff; border-color:var(--accent); }
  .bp-run{ border-top:1px solid var(--chrome-edge); padding:12px 14px; overflow-y:auto; }
  .bp-run-row{ display:flex; gap:8px; margin-bottom:8px; }
  .bp-run select, .bp-run input{ flex:1; border:1px solid var(--chrome-edge); border-radius:8px; padding:7px 9px;
    background:var(--bg); color:var(--ink); font-family:var(--sans); font-size:12.5px; min-width:0; }
  .bp-warn{ color:var(--ink-soft); font-size:11px; margin:4px 0 10px; line-height:1.4; }
  .bp-result{ margin-top:10px; font-size:12.5px; }
  .bp-answer{ white-space:pre-wrap; background:var(--bg); border:1px solid var(--chrome-edge); border-radius:9px;
    padding:10px; max-height:30vh; overflow-y:auto; line-height:1.5; }
  .bp-answer-acts{ display:flex; gap:8px; margin-top:8px; }
  .vf-doi-lookup{ display:flex; gap:8px; margin:0 0 12px; }
  .vf-doi-in{ flex:1; border:1px solid var(--chrome-edge); border-radius:8px; padding:8px 10px; background:var(--bg); color:var(--ink); font-family:var(--sans); font-size:13px; }
  .vf-doi-go{ border:1px solid var(--accent); background:var(--accent); color:#fff; border-radius:8px; padding:8px 14px; cursor:pointer; font-weight:600; }
  .vf-doi-go:disabled{ opacity:.6; cursor:default; }

  /* ===== Presentation mode ===== */
  body.presenting .node{ opacity:.28; transition:opacity .25s; }
  body.presenting .node.pres-current{ opacity:1; outline:3px solid var(--accent); outline-offset:3px; box-shadow:0 10px 40px rgba(0,0,0,.3); }
  body.presenting .handle, body.presenting .resize-grip, body.presenting #nodebar{ display:none !important; }
  .pres-bar{ position:fixed; bottom:24px; left:50%; transform:translateX(-50%); z-index:62;
    background:#23201b; color:#fff; border-radius:999px; padding:8px 12px; display:flex; align-items:center; gap:12px;
    font-family:var(--sans); box-shadow:0 12px 40px rgba(0,0,0,.4); max-width:90vw; }
  .pres-bar button{ border:none; background:rgba(255,255,255,.12); color:#fff; width:34px; height:34px; border-radius:50%;
    font-size:14px; cursor:pointer; flex:none; }
  .pres-bar button:hover:not(:disabled){ background:var(--accent); }
  .pres-bar button:disabled{ opacity:.35; cursor:default; }
  .pres-exit{ background:rgba(255,80,60,.25) !important; }
  .pres-count{ font-size:12px; opacity:.8; flex:none; }
  .pres-title{ font-size:14px; font-weight:600; max-width:46vw; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }

  /* Version diff panel */
  .diff-panel{ position:fixed; right:18px; top:64px; width:360px; max-height:70vh; overflow:auto;
    background:var(--paper); border:1px solid var(--line); border-radius:14px; box-shadow:var(--shadow-lg);
    z-index:120; padding:6px 0; font-size:13px; }
  .diff-head{ display:flex; align-items:center; justify-content:space-between; padding:8px 14px; border-bottom:1px solid var(--line); position:sticky; top:0; background:var(--paper); }
  .diff-head b{ color:var(--ink); }
  .diff-x{ border:0; background:transparent; font-size:18px; cursor:pointer; color:var(--ink-soft); line-height:1; }
  .diff-sec{ padding:6px 0; }
  .diff-h{ font-size:11px; font-weight:700; text-transform:uppercase; letter-spacing:.04em; padding:4px 14px; }
  .diff-h.add{ color:#1a7f37; } .diff-h.del{ color:#cf222e; } .diff-h.chg{ color:#9a6700; }
  .diff-row{ padding:4px 14px; border-left:3px solid transparent; color:var(--ink); word-break:break-word; }
  .diff-row.add{ border-left-color:#1a7f37; background:rgba(26,127,55,.06); }
  .diff-row.del{ border-left-color:#cf222e; background:rgba(207,34,46,.06); text-decoration:line-through; color:var(--ink-soft); }
  .diff-row.chg{ border-left-color:#9a6700; background:rgba(154,103,0,.06); }
  .diff-row .d-from{ color:var(--ink-soft); text-decoration:line-through; }
  .diff-row .d-arrow{ margin:0 6px; color:var(--ink-soft); }
  .diff-empty{ padding:16px 14px; color:var(--ink-soft); }

  /* OAuth ("Sign in with GitHub") button on the login overlay */
  .login-oauth{ margin:2px 0 4px; }
  .oauth-btn{ display:flex; align-items:center; justify-content:center; gap:9px; width:100%; padding:11px 14px;
    border-radius:11px; border:1px solid var(--chrome-edge); background:var(--ink); color:var(--paper);
    font-size:14px; font-weight:600; cursor:pointer; transition:opacity .15s; }
  .oauth-btn:hover{ opacity:.9; }
  .oauth-btn svg{ width:18px; height:18px; fill:currentColor; }
  .oauth-or{ display:flex; align-items:center; gap:10px; margin:15px 2px 2px; color:var(--ink-soft); font-size:12px; }
  .oauth-or::before, .oauth-or::after{ content:''; flex:1; height:1px; background:var(--line); }

/* Pinned maps: small badge before the title in the sidebar list. */
.map-item.pinned .nm::before{ content:'\1F4CC'; margin-right:6px; font-size:.85em; opacity:.9; }

/* Live collaboration: remote cursors + presence pill. */
#collabCursors{ position:fixed; inset:0; pointer-events:none; z-index:60; overflow:hidden; }
.collab-cursor{ position:absolute; top:0; left:0; will-change:transform; transition:transform .08s linear; }
.collab-cursor svg{ display:block; filter:drop-shadow(0 1px 1px rgba(0,0,0,.3)); }
.collab-cursor b{ position:absolute; left:15px; top:13px; font-size:11px; font-weight:600; color:#fff; padding:1px 6px; border-radius:8px; white-space:nowrap; }
#collabPill{ position:fixed; bottom:18px; left:18px; z-index:70; display:flex; align-items:center; gap:8px;
  background:var(--chrome); border:1px solid var(--chrome-edge); border-radius:999px; padding:5px 8px 5px 12px;
  box-shadow:var(--shadow); font-size:12px; font-weight:500; }
#collabPill .cp-dots{ display:flex; }
#collabPill .cp-dot{ width:13px; height:13px; border-radius:50%; border:2px solid var(--chrome); margin-left:-5px; }
#collabPill .cp-dot:first-child{ margin-left:0; }
#collabPill .cp-txt{ color:var(--ink-soft); }
#collabPill button{ border:none; background:transparent; cursor:pointer; font-size:12px; opacity:.7; padding:2px 5px; border-radius:6px; color:var(--ink-soft); }
#collabPill button:hover{ opacity:1; background:var(--hover, rgba(127,127,127,.18)); }
#collabPill .cp-save{ opacity:1; font-weight:600; color:var(--accent); padding:3px 9px; border:1px solid var(--chrome-edge); border-radius:999px; }
#collabPill .cp-save:hover{ background:var(--accent); color:#fff; border-color:var(--accent); }

/* Export menu: small uppercase section labels grouping the items. */
.ex-grp{ font-size:10px; font-weight:700; text-transform:uppercase; letter-spacing:.6px;
  color:var(--ink-soft); opacity:.65; padding:10px 14px 3px; user-select:none; }
.export-pop > .ex-grp:first-child{ padding-top:6px; }

/* Shared-with-me section in the sidebar. */
.map-group-label{ font-size:10px; font-weight:700; text-transform:uppercase; letter-spacing:.6px; color:var(--ink-soft); opacity:.6; padding:12px 12px 4px; user-select:none; }
.map-item .shared-badge{ font-size:11px; opacity:.7; flex:0 0 auto; margin-right:2px; }

/* Cloud-edit keeps the editing toolbar visible, so push it clear of the shared banner. */
/* Cloud-edit shows the sidebar AND toolbar, so shift the whole app below the fixed
   shared banner (measured into --shared-banner-h so it adapts when the banner wraps). */
body.cloud-edit .app{ padding-top:var(--shared-banner-h, 44px); }

/* ---- Manage-access modal (identity ACLs) ---- */
.access-modal{ position:fixed; inset:0; background:rgba(0,0,0,.45); display:grid; place-items:center; z-index:600; }
.access-modal .am-card{ width:min(440px,92vw); max-height:86vh; overflow:auto; background:var(--paper); color:var(--ink);
  border:1px solid var(--line); border-radius:14px; box-shadow:var(--shadow-lg); padding:16px 18px; }
.access-modal .am-head{ display:flex; align-items:center; justify-content:space-between; margin-bottom:6px; font-size:16px; font-weight:700; }
.access-modal .am-x{ background:none; border:none; color:var(--ink-soft); font-size:22px; line-height:1; cursor:pointer; }
.access-modal .am-x:hover{ color:var(--ink); }
.access-modal .am-sec{ margin-top:14px; }
.access-modal .am-lbl{ font-size:12px; text-transform:uppercase; letter-spacing:.04em; color:var(--ink-soft); margin-bottom:8px; }
.access-modal .am-link label{ display:block; padding:5px 0; font-size:14px; cursor:pointer; }
.access-modal .am-link input{ margin-right:8px; accent-color:var(--accent); }
.access-modal .am-auth{ display:flex; align-items:center; gap:8px; margin-top:10px; font-size:13.5px; cursor:pointer; }
.access-modal .am-auth input{ margin:0; accent-color:var(--accent); }
.access-modal .am-auth input:disabled{ opacity:.4; }
.access-modal .am-list{ display:flex; flex-direction:column; gap:6px; margin-bottom:10px; }
.access-modal .am-row{ display:flex; align-items:center; gap:10px; padding:7px 10px; background:var(--paper-2); border:1px solid var(--line); border-radius:8px; }
.access-modal .am-who{ flex:1; font-size:14px; }
.access-modal .am-role{ font-size:12px; color:var(--ink-soft); }
.access-modal .am-rm{ background:none; border:1px solid var(--line-2); color:var(--ink-soft); border-radius:6px; padding:3px 9px; font-size:12px; cursor:pointer; }
.access-modal .am-rm:hover{ border-color:var(--accent); color:var(--accent); }
.access-modal .am-empty{ font-size:13px; color:var(--ink-soft); padding:6px 2px; }
.access-modal .am-add{ display:flex; gap:8px; }
.access-modal .am-user{ flex:1; background:var(--paper-2); border:1px solid var(--line); color:var(--ink); border-radius:8px; padding:8px 10px; font-size:14px; }
.access-modal .am-user::placeholder{ color:var(--ink-soft); }
.access-modal .am-user:focus{ outline:none; border-color:var(--accent); }
.access-modal .am-newrole{ background:var(--paper-2); border:1px solid var(--line); color:var(--ink); border-radius:8px; padding:8px; }
.access-modal .am-addbtn{ background:var(--accent); border:none; color:#fff; border-radius:8px; padding:8px 14px; font-weight:600; cursor:pointer; }
.access-modal .am-addbtn:hover{ background:var(--accent-deep); }
.access-modal .am-vis{ display:flex; flex-direction:column; gap:5px; }
.access-modal .am-visrow{ display:flex; align-items:center; justify-content:space-between; padding:5px 10px; background:var(--paper-2); border:1px solid var(--line); border-radius:8px; font-size:13px; }
.access-modal .am-vtime{ color:var(--ink-soft); font-size:12px; }
.access-modal .am-foot{ margin-top:14px; font-size:12px; color:var(--ink-soft); }

/* Contextual note on the login overlay when access requires sign-in (e.g. a shared map) */
.login-share-note{ margin:0 0 14px; padding:10px 13px; border-radius:10px; font-size:13.5px; line-height:1.4;
  background:color-mix(in srgb, var(--accent) 14%, transparent); border:1px solid color-mix(in srgb, var(--accent) 40%, transparent); color:var(--ink); }

/* Shared-map indicator: a compact themed pill (replaces the full-width banner). */
.user-pill.shared-pill{ background:var(--accent); color:#fff; border-color:transparent; font-weight:600; padding:3px 12px; }
.user-pill.shared-pill img, .user-pill.shared-pill button{ display:none !important; }
.user-pill.shared-pill span{ display:inline-block !important; padding:0; }
/* Pill-mode has no banner, so reclaim the space the banner used to reserve. */
body.no-banner.cloud-edit .app{ padding-top:0; }
body.no-banner.shared-view .stage{ top:0; }

/* Themed scrollbars — desktop only (mobile keeps native overlay scrollbars) */
@media (min-width:721px){
  *::-webkit-scrollbar{width:12px;height:12px}
  *::-webkit-scrollbar-track{background:transparent}
  *::-webkit-scrollbar-thumb{background:var(--line-2,var(--line));border-radius:10px;border:3px solid transparent;background-clip:padding-box}
  *::-webkit-scrollbar-thumb:hover{background:var(--ink-soft)}
  *::-webkit-scrollbar-corner{background:transparent}
  html{scrollbar-color:var(--line-2,var(--line)) transparent;scrollbar-width:thin}
}

/* ===== PDF export (markdown preview -> browser print -> Save as PDF) =====
   #mdPrintRoot is populated on demand by mdDownloadPdf() and is otherwise empty/hidden.
   Forces light, ink-friendly colors regardless of the app's active theme. */
#mdPrintRoot{display:none}
@media print{
  body.md-printing > *:not(#mdPrintRoot){display:none !important}
  body.md-printing #mdPrintRoot{
    display:block !important;position:static !important;padding:0 32px;
    color:#1a1a1a;background:#fff;
    font:14px/1.6 -apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,Helvetica,Arial,sans-serif;
  }
  /* Browsers drop background colors/images when printing unless told otherwise — this is
     what was silently stripping the code-block shading (and would strip any other
     background color here too, e.g. a table header tint) even though it renders fine
     on screen in the live preview. Applies to every descendant, not just #mdPrintRoot
     itself, since print-color-adjust doesn't reliably cascade in all engines. */
  #mdPrintRoot, #mdPrintRoot *{ -webkit-print-color-adjust:exact; print-color-adjust:exact; color-adjust:exact; }
  #mdPrintRoot h1{font-size:1.9em;margin:0 0 .4em;line-height:1.25;color:#111;border-bottom:1px solid #ccc;padding-bottom:.2em}
  #mdPrintRoot h1,#mdPrintRoot h2,#mdPrintRoot h3{page-break-after:avoid}
  #mdPrintRoot h2,#mdPrintRoot h3{margin:.9em 0 .3em;line-height:1.25;color:#111}
  #mdPrintRoot h2{font-size:1.35em;border-bottom:1px solid #ccc;padding-bottom:.2em}
  #mdPrintRoot h3{font-size:1.1em}
  #mdPrintRoot p,#mdPrintRoot ul,#mdPrintRoot ol,#mdPrintRoot blockquote{margin:.5em 0}
  #mdPrintRoot pre.mp-code{background:#f2f2f2;padding:10px 12px;border-radius:6px;overflow:auto;font-size:12px;page-break-inside:avoid}
  #mdPrintRoot code{font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace}
  #mdPrintRoot table{border-collapse:collapse;font-size:.95em;page-break-inside:avoid;margin:.5em 0}
  #mdPrintRoot th,#mdPrintRoot td{border:1px solid #ccc;padding:5px 9px}
  #mdPrintRoot th{background:#eef0f3;font-weight:700;text-align:left}
  #mdPrintRoot blockquote{border-left:3px solid #ccc;margin-left:0;padding:.2em 0 .2em 12px;color:#555}
  #mdPrintRoot img{max-width:100%}
  #mdPrintRoot hr{border:0;border-top:1px solid #ccc;margin:1em 0}
  #mdPrintRoot a{color:#2a5db0;text-decoration:underline}
  #mdPrintRoot math{font-size:1.04em;color:#1a1a1a}
  #mdPrintRoot math[display="block"]{display:block;margin:.6em auto;text-align:center;page-break-inside:avoid}
}

/* ===== Floating-shell interface layouts (Classic / Side-toolbar) =====
   body.ui-classic and body.ui-rail both drop the status bar and float the
   chrome over the canvas: minimap card + vertical zoombar bottom-right, hint
   bottom-left, breadcrumb top-centre, collapsed sidebar vanishes (no rail).
   Classic keeps the upstream toolbar as one floating strip inside .stage;
   Side-toolbar docks the same toolbar as a vertical icon rail left of the
   canvas with the title, save pill and minimap floating over it. The same
   DOM elements are reparented by applyUiLayout() — nothing is hidden or
   cloned, only restyled and repositioned. */
body.ui-classic .app, body.ui-rail .app{grid-template-rows:minmax(0,1fr)}
body.ui-classic .side, body.ui-rail .side, body.ui-zen .side{grid-column:1;grid-row:1;width:268px}
body.ui-classic .side.collapsed, body.ui-rail .side.collapsed, body.ui-zen .side.collapsed{width:0}
body.ui-classic .side-rail, body.ui-rail .side-rail, body.ui-zen .side-rail,
body.ui-classic .side-resize, body.ui-rail .side-resize, body.ui-zen .side-resize{display:none}
body.ui-classic .statusbar, body.ui-rail .statusbar, body.ui-zen .statusbar{display:none}
/* Floating bottom-right: the minimap as its own card (right:72) and the
   vertical zoom bar beside it (right:18) — the upstream zoombar. The zoom
   row is reparented out of the overview card by applyUiLayout(); the
   overview here is just the minimap chip. */
body.ui-classic .overview, body.ui-rail .overview, body.ui-zen .overview{
  position:absolute;bottom:18px;right:72px;z-index:29;
  flex-direction:column;align-items:stretch;gap:0;padding:0;
  background:none;border:none;box-shadow:none;
}
body.ui-classic .overview .minimap, body.ui-rail .overview .minimap, body.ui-zen .overview .minimap{width:168px;height:120px}
body.ui-classic .zoom-row, body.ui-rail .zoom-row, body.ui-zen .zoom-row{
  position:absolute;bottom:18px;right:18px;z-index:30;
  flex-direction:column;gap:2px;padding:4px;
  background:var(--chrome);border:1px solid var(--chrome-edge);border-radius:12px;
  box-shadow:var(--shadow);
}
body.ui-classic .zoom-row button, body.ui-rail .zoom-row button, body.ui-zen .zoom-row button{width:36px;height:34px;border-radius:8px;font-size:17px}
body.ui-classic #zoomSlider, body.ui-rail #zoomSlider, body.ui-zen #zoomSlider{display:none}   /* no slider here; the % label handles custom zoom */
body.ui-classic .zoom-row #zoomIn, body.ui-rail .zoom-row #zoomIn, body.ui-zen .zoom-row #zoomIn{order:1}  /* upstream order: ＋ 100% － ⊡ */
body.ui-classic .zoom-row #zoomVal, body.ui-rail .zoom-row #zoomVal, body.ui-zen .zoom-row #zoomVal{order:2}
body.ui-classic .zoom-row #zoomOut, body.ui-rail .zoom-row #zoomOut, body.ui-zen .zoom-row #zoomOut{order:3}
body.ui-classic .zoom-row #zoomFit, body.ui-rail .zoom-row #zoomFit, body.ui-zen .zoom-row #zoomFit{order:4}
body.ui-classic .overview-toggle, body.ui-rail .overview-toggle, body.ui-zen .overview-toggle{display:none}
/* Floating hint pill, bottom-left (upstream position). */
body.ui-classic .hint, body.ui-rail .hint, body.ui-zen .hint{
  position:absolute;bottom:18px;left:18px;z-index:20;
  background:var(--chrome);border:1px solid var(--chrome-edge);border-radius:11px;
  padding:9px 13px;box-shadow:var(--shadow);font-size:12px;color:var(--ink-soft);
  max-width:330px;line-height:1.55;
}
body.ui-classic .hint .hint-text, body.ui-rail .hint .hint-text, body.ui-zen .hint .hint-text{white-space:normal;overflow:visible}
/* Breadcrumb: top-centre. */
body.ui-classic .breadcrumb, body.ui-rail .breadcrumb, body.ui-zen .breadcrumb{top:60px;left:50%;transform:translateX(-50%) translateY(-4px)}
body.ui-classic .breadcrumb.shown, body.ui-rail .breadcrumb.shown, body.ui-zen .breadcrumb.shown{transform:translateX(-50%) translateY(0)}
body.ui-classic.focus-mode .overview, body.ui-rail.focus-mode .overview, body.ui-zen.focus-mode .overview{display:none !important}
body.ui-classic.shared-view .overview, body.ui-rail.shared-view .overview, body.ui-zen.shared-view .overview{display:none !important}

/* ---- Classic: the upstream floating toolbar ---- */
body.ui-classic .app{grid-template-columns:auto 1fr}
body.ui-classic .stage{grid-column:2;grid-row:1}
body.ui-classic .topbar{
  position:absolute;top:14px;left:14px;right:14px;z-index:30;pointer-events:none;
  background:none;border-bottom:none;padding:0;flex-wrap:nowrap;gap:8px;
}
body.ui-classic .topbar > *{pointer-events:auto}
body.ui-classic .tb-group{background:var(--chrome);border:1px solid var(--chrome-edge);border-radius:12px;padding:4px;box-shadow:var(--shadow)}
body.ui-classic .tb-sep{display:none}
body.ui-classic .search-wrap{background:var(--chrome);border:1px solid var(--chrome-edge);border-radius:12px;box-shadow:var(--shadow)}
body.ui-classic .search-wrap.open{background:var(--paper-2)}
/* Sidebar shell (as upstream): plain brand, new-map row with ▾ caret, no
   tabs — the caret toggles the Templates pane in and out. */
body.ui-classic .side-tabs{display:none}
body.ui-classic .new-map-row{display:flex;gap:0;margin:14px 14px 10px}
body.ui-classic .new-map-row #newMap{
  flex:1;height:auto;padding:11px;margin:0;
  border:1.5px dashed var(--line-2);background:none;color:var(--ink-soft);
  border-top-left-radius:11px;border-bottom-left-radius:11px;
  border-top-right-radius:0;border-bottom-right-radius:0;
  font-weight:600;font-size:14px;font-family:inherit;
}
body.ui-classic .new-map-row #newMap:hover{border-color:var(--accent);color:var(--accent);background:var(--node-bg)}
body.ui-classic .new-map-row .new-map-caret{
  width:36px;padding:0;background:var(--accent);color:#fff;border:none;
  border-left:1px solid color-mix(in srgb, #000 18%, var(--accent));
  border-top-right-radius:11px;border-bottom-right-radius:11px;
  cursor:pointer;font-size:13px;font-family:inherit;
}
body.ui-classic .new-map-row .new-map-caret:hover{background:var(--accent-deep)}
body.ui-classic.md-ready .app{grid-template-columns:auto auto minmax(0,1fr)}
body.ui-classic #mdPane{grid-column:2;grid-row:1}
body.ui-classic.md-ready .stage{grid-column:3;grid-row:1}
body.ui-classic.focus-mode .app{grid-template-columns:1fr}
body.ui-classic.focus-mode .stage{grid-column:1;grid-row:1;width:calc(100vw / var(--ui-zoom, 1));height:calc(100dvh / var(--ui-zoom, 1))}
body.ui-classic.shared-view .app{grid-template-columns:1fr;padding-top:var(--shared-banner-h, 42px)}
body.ui-classic.shared-view .stage{grid-column:1;grid-row:1}
body.ui-classic.shared-view .breadcrumb{top:97px;left:50%;transform:translateX(-50%) translateY(-4px)}
body.ui-classic.shared-view .breadcrumb.shown{transform:translateX(-50%) translateY(0)}

/* ---- Side-toolbar: the toolbar is a vertical icon rail left of the canvas.
   Title, save pill, minimap card, zoombar and hint float over the canvas. ---- */
body.ui-rail .app{grid-template-columns:auto 46px minmax(0,1fr)}
body.ui-rail .side{grid-column:1;grid-row:1}
body.ui-rail .topbar{
  grid-column:2;grid-row:1;position:relative;
  display:flex;flex-direction:column;align-items:center;gap:5px;
  padding:10px 5px;background:var(--chrome);border-right:1px solid var(--chrome-edge);
  border-bottom:none;overflow:visible;scrollbar-width:none;
}
body.ui-rail .topbar::-webkit-scrollbar{display:none}
body.ui-rail .topbar .tb-group{flex-direction:column;gap:2px}
body.ui-rail .topbar .tb{width:36px;height:34px;padding:0;font-size:16px}
body.ui-rail .topbar .tb.wide{width:36px;padding:0;font-size:16px}
body.ui-rail .topbar .tb-sep{display:none}
body.ui-rail .topbar .spacer,
body.ui-rail .topbar .title-edit{display:none}   /* the title is moved out to float on the canvas */
body.ui-rail .topbar > .user-pill,
body.ui-rail .topbar > .token-total{display:none}  /* too wide for the rail (left over from classic) */
/* Search floats right of the rail, over the canvas — toggled by the
   ⌕ button exactly like the modern toolbar's own inline field. */
body.ui-rail .topbar .search-wrap{
  position:absolute;top:64px;left:calc(100% + 8px);right:auto;z-index:20;
  width:0; overflow:hidden;
  background:none; border:none; box-shadow:none;
}
body.ui-rail .topbar .search-wrap.open{
  width:230px;
  background:var(--chrome);border:1px solid var(--chrome-edge);border-radius:12px;
  box-shadow:var(--shadow);
}
body.ui-rail .topbar .search-wrap.open.replace-mode{width:420px}
body.ui-rail .stage{grid-column:3;grid-row:1}
body.ui-rail .title-edit{
  position:absolute;top:14px;left:14px;z-index:30;max-width:42vw;
  background:transparent;border:1px solid transparent;
}
body.ui-rail .title-edit:hover, body.ui-rail .title-edit:focus{background:var(--chrome);border-color:var(--chrome-edge)}
body.ui-rail .save-pill{position:absolute;top:14px;right:14px;z-index:30;margin:0}
body.ui-rail.md-ready .app{grid-template-columns:auto 46px auto minmax(0,1fr)}
body.ui-rail #mdPane{grid-column:3;grid-row:1}
body.ui-rail.md-ready .stage{grid-column:4;grid-row:1}
body.ui-rail.focus-mode .app{grid-template-columns:1fr}
body.ui-rail.focus-mode .topbar{display:none}
body.ui-rail.focus-mode .stage{grid-column:1;grid-row:1;width:calc(100vw / var(--ui-zoom, 1));height:calc(100dvh / var(--ui-zoom, 1))}
body.ui-rail.shared-view .app{grid-template-columns:auto 46px minmax(0,1fr);padding-top:var(--shared-banner-h, 42px)}
body.ui-rail.shared-view .topbar{grid-column:2;grid-row:1}
body.ui-rail.shared-view .stage{grid-column:3;grid-row:1}
body.ui-rail.shared-view .breadcrumb{top:97px;left:50%;transform:translateX(-50%) translateY(-4px)}
body.ui-rail.shared-view .breadcrumb.shown{transform:translateX(-50%) translateY(0)}

/* ── Side-toolbar popovers: fly out to the right of the rail ───────────────
   In the rail layout the toolbar is a 46px vertical strip. A classic dropdown
   (below the button, right-aligned) gets clamped to the left viewport edge and
   looks detached — the pattern every modern app with a vertical rail uses is a
   horizontal flyout 8px to the right of the rail, top-aligned with the trigger
   (VS Code activity bar, Figma tools, Slack navigation, Discord server list).
   The JS `positionPopup(…, {side:'right'})` places the popover there; these
   rules just polish the feel so the flyout reads as attached to the rail. */
@keyframes railPopIn{
  from{opacity:0; transform:translateX(-6px) scale(.98);}
  to{opacity:1; transform:translateX(0) scale(1);}
}
body.ui-rail .theme-panel,
body.ui-rail .export-pop{
  transform-origin:left center;
  animation:railPopIn .14s cubic-bezier(.2,0,.2,1);
  /* A slightly stronger shadow so the flyout lifts clearly off the canvas and
     the rail when it sits 8px away — matching VS Code / Slack elevation. */
  box-shadow:0 12px 40px rgba(0,0,0,.22), 0 2px 8px rgba(0,0,0,.14);
}
@media (prefers-reduced-motion: reduce){
  body.ui-rail .theme-panel,
  body.ui-rail .export-pop{animation:none;}
}

/* ---- Zen / write: the shell vanishes; the canvas fills the window. The
   toolbar strip, breadcrumb and save pill are hidden and slide in only while
   the pointer hovers the top edge (body.zen-chrome). Minimap card, zoombar
   and hint stay floating at all times. ---- */
body.ui-zen .app{grid-template-columns:1fr;grid-template-rows:minmax(0,1fr)}
body.ui-zen .side{
  position:fixed;top:0;left:0;bottom:0;width:min(320px,86vw);z-index:400;
  background:var(--chrome);border-right:1px solid var(--chrome-edge);
  box-shadow:var(--shadow-lg);transform:translateX(-100%);
  transition:transform .25s cubic-bezier(.4,0,.2,1);
  display:flex;flex-direction:column;
}
body.ui-zen.side-open .side{transform:translateX(0)}
body.ui-zen .statusbar{display:none}
body.ui-zen .stage{grid-column:1;grid-row:1}
body.ui-zen .topbar{
  position:absolute;top:14px;left:50%;right:auto;z-index:30;pointer-events:none;
  display:flex;align-items:center;gap:6px;flex-wrap:nowrap;overflow:hidden;
  background:var(--chrome);border:1px solid var(--chrome-edge);border-radius:12px;
  padding:4px 8px;box-shadow:var(--shadow);max-width:92vw;width:max-content;
  opacity:0;transform:translateX(-50%) translateY(-12px);
  transition:opacity .18s ease, transform .18s ease;
}
body:not(.ui-zen) #zenPin{display:none}
body.ui-zen.zen-chrome .topbar{opacity:1;transform:translateX(-50%) translateY(0);pointer-events:auto}
/* Pinned: bar stays visible without hovering the top edge (state in localStorage).
   Declared BEFORE the focus-mode rules below so focus mode still hides it. */
body.ui-zen.zen-pinned .topbar{opacity:1;transform:translateX(-50%) translateY(0);pointer-events:auto}
body.ui-zen #zenPin.on{background:var(--accent);color:#fff}
body.ui-zen .tb-group{background:none;border:none;border-radius:0;padding:0;box-shadow:none}
body.ui-zen .tb-sep{width:1px;height:22px;background:var(--chrome-edge);flex:0 0 auto}
body.ui-zen .search-wrap{background:transparent;border:none;box-shadow:none;flex:0 0 auto}
body.ui-zen .search-wrap.open{background:var(--paper-2);border:1px solid var(--chrome-edge);border-radius:8px;padding:2px}
/* Opening search must widen the centered bar instead of squeezing the field:
   lift the 92vw cap and absorb the extra width from the map title first. */
body.ui-zen .topbar:has(.search-wrap.open){max-width:98vw}
body.ui-zen .topbar:has(.search-wrap.open) .title-edit{min-width:60px;max-width:160px}
/* While the find field is open the least-used actions step aside, so the
   token counter and pin stay on the first row instead of wrapping. The wrap
   rule above remains as the safety net for very narrow windows. */
body.ui-zen .topbar:has(.search-wrap.open) #presentBtn,
body.ui-zen .topbar:has(.search-wrap.open) #tabsBtn{display:none}
body.ui-zen .save-pill{display:flex;position:absolute;top:22px;right:14px;z-index:30;margin:0}
body.ui-zen .token-total{background:none;border:none;box-shadow:none;border-radius:0;padding:6px 4px;margin-left:4px}
body.ui-zen .breadcrumb{display:none}
body.ui-zen.md-ready .topbar{max-width:min(92vw, calc(100% - 28px))}
body.ui-zen.md-ready .topbar:has(.search-wrap.open){max-width:min(98vw, calc(100% - 16px))}
body.ui-zen.md-ready .app{grid-template-columns:auto minmax(0,1fr)}
body.ui-zen #mdPane{grid-column:1;grid-row:1}
body.ui-zen.md-ready .stage{grid-column:2;grid-row:1}
body.ui-zen.tabs-on .app{grid-template-rows:auto minmax(0,1fr)}
body.ui-zen.tabs-on #tabStrip{grid-column:1;grid-row:1;display:flex}
body.ui-zen.tabs-on .stage{grid-column:1;grid-row:2}
body.ui-zen.tabs-on.md-ready .app{grid-template-columns:auto minmax(0,1fr);grid-template-rows:auto minmax(0,1fr)}
body.ui-zen.tabs-on.md-ready #tabStrip{grid-column:1/-1;grid-row:1}
body.ui-zen.tabs-on.md-ready #mdPane{grid-column:1;grid-row:2}
body.ui-zen.tabs-on.md-ready .stage{grid-column:2;grid-row:2}
body.ui-zen.focus-mode #mdPane{display:none}
@media (prefers-reduced-motion: reduce){ body.ui-zen .topbar{transition:none} }
body.ui-zen.focus-mode .topbar{opacity:0;transform:translateY(-12px);pointer-events:none}
body.ui-zen.focus-mode .stage{grid-column:1;grid-row:1;width:calc(100vw / var(--ui-zoom, 1));height:calc(100dvh / var(--ui-zoom, 1))}
body.ui-zen.shared-view .app{grid-template-columns:1fr;padding-top:var(--shared-banner-h, 42px)}
body.ui-zen.shared-view .topbar{display:none}
body.ui-zen.shared-view .stage{grid-column:1;grid-row:1}
body.ui-zen.shared-view .breadcrumb{top:97px;left:50%;transform:translateX(-50%) translateY(-4px)}
body.ui-zen.shared-view .breadcrumb.shown{transform:translateX(-50%) translateY(0)}

/* ---- Bottom-dock: the status bar becomes a full-width dock that owns the
   sidebar toggle, the Maps/Templates tabs, the hint and the overview chip;
   the sidebar turns into a slide-over panel instead of a permanent column. ---- */
body.ui-dock .app{grid-template-columns:1fr;grid-template-rows:auto auto minmax(0,1fr) auto}
body.ui-dock .topbar{grid-column:1;grid-row:1}
body.ui-dock #tabStrip{grid-column:1;grid-row:2}
body.ui-dock .stage{grid-column:1;grid-row:3}
body.ui-dock .statusbar{grid-column:1;grid-row:4;width:100%;gap:12px;padding:6px 12px}
body.ui-dock .side{
  position:fixed;top:0;left:0;bottom:0;width:min(320px,86vw);z-index:400;
  background:var(--chrome);border-right:1px solid var(--chrome-edge);
  box-shadow:var(--shadow-lg);transform:translateX(-100%);
  transition:transform .25s cubic-bezier(.4,0,.2,1);
}
body.ui-dock.side-open .side{transform:translateX(0)}
body.ui-dock .side-rail, body.ui-dock .side-resize{display:none}
body.ui-dock .side-tabs{display:flex;gap:2px;padding:2px;background:var(--paper-2);border-radius:10px}
body.ui-dock .hint{margin-left:auto}
body.ui-dock.md-ready .app{grid-template-columns:minmax(0,1fr) auto}
body.ui-dock.md-ready #mdPane{grid-column:2;grid-row:3; border-right:none; border-left:1px solid var(--line)}
body.ui-dock.md-ready .stage{grid-column:1;grid-row:3}
body.ui-dock.md-ready .topbar{grid-column:1/-1;grid-row:1}
body.ui-dock.md-ready #tabStrip{grid-column:1/-1;grid-row:2}
body.ui-dock.md-ready .statusbar{grid-column:1/-1;grid-row:4}
body.ui-dock.md-ready #mdPane .md-resize{left:0; right:auto}
body.ui-dock.md-mode #mdPane{width:var(--md-w,40vw)}
body.ui-dock.focus-mode .app{grid-template-columns:1fr}
body.ui-dock.focus-mode #mdPane{display:none}
body.ui-dock.focus-mode .stage{grid-column:1;grid-row:3;width:calc(100vw / var(--ui-zoom, 1));height:calc(100dvh / var(--ui-zoom, 1))}
body.ui-dock.shared-view .app{grid-template-columns:1fr}
body.ui-dock.shared-view #mdPane{display:none}
body.ui-dock.shared-view .stage{grid-column:1;grid-row:3}

/* ---- Split editor: the modern shell plus the markdown pane pinned open as a
   permanent third column (side | editor | canvas). ---- */
body.ui-split .app{grid-template-columns:auto auto minmax(0,1fr)}
body.ui-split .side{grid-column:1;grid-row:1/5}
body.ui-split .topbar{grid-column:2/-1;grid-row:1}
body.ui-split #mdPane{grid-column:2;grid-row:3;width:var(--md-w,40vw)}
body.ui-split .stage{grid-column:3;grid-row:3}
body.ui-split .statusbar{grid-column:2/-1;grid-row:4}
body.ui-split #mdToggle{display:none}
body.ui-split #mdPane .md-close{display:none}
 body.ui-split.focus-mode .app{grid-template-columns:1fr}
  body.ui-split.focus-mode #mdPane{display:none}
  body.ui-split.focus-mode .stage{grid-column:1;grid-row:3;width:calc(100vw / var(--ui-zoom, 1));height:calc(100dvh / var(--ui-zoom, 1))}
body.ui-split.tabs-on .app{grid-template-rows:auto auto minmax(0,1fr) auto}
body.ui-split.tabs-on #tabStrip{display:flex;grid-column:2/-1;grid-row:2}
body.ui-split.tabs-on #mdPane{grid-column:2;grid-row:3}
body.ui-split.tabs-on .stage{grid-column:3;grid-row:3}
body.ui-split.shared-view .app{grid-template-columns:1fr}
body.ui-split.shared-view #mdPane{display:none}
body.ui-split.shared-view .stage{grid-column:1;grid-row:3}

 /* ---- Minimal: the plain modern shell with the sidebar gone entirely — no
   column, no slide-over, nothing to toggle. ---- */
body.ui-minimal .app{grid-template-columns:1fr}
body.ui-minimal .topbar{grid-column:1;grid-row:1}
body.ui-minimal .stage{grid-column:1;grid-row:3}
body.ui-minimal .statusbar{grid-column:1;grid-row:4}
body.ui-minimal .side{
  position:fixed;top:0;left:0;bottom:0;width:min(320px,86vw);z-index:400;
  background:var(--chrome);border-right:1px solid var(--chrome-edge);
  box-shadow:var(--shadow-lg);transform:translateX(-100%);
  transition:transform .25s cubic-bezier(.4,0,.2,1);
}
body.ui-minimal.side-open .side{transform:translateX(0)}
body.ui-minimal .side-rail, body.ui-minimal .side-resize{display:none}
body.ui-minimal #toggleSide{display:none}
body.ui-minimal.md-ready .app{grid-template-columns:minmax(0,1fr) auto}
body.ui-minimal.md-ready #mdPane{grid-column:2;grid-row:3; border-right:none; border-left:1px solid var(--line)}
body.ui-minimal.md-ready .stage{grid-column:1;grid-row:3}
body.ui-minimal.md-ready .topbar{grid-column:1/-1;grid-row:1}
body.ui-minimal.md-ready #tabStrip{grid-column:1/-1;grid-row:2}
body.ui-minimal.md-ready .statusbar{grid-column:1/-1;grid-row:4}
body.ui-minimal.md-ready #mdPane .md-resize{left:0; right:auto}
body.ui-minimal.md-mode #mdPane{width:var(--md-w,40vw)}
body.ui-minimal.tabs-on .app{grid-template-rows:auto auto minmax(0,1fr) auto}
body.ui-minimal.tabs-on #tabStrip{display:flex;grid-column:1;grid-row:2}
body.ui-minimal.tabs-on .stage{grid-column:1;grid-row:3}
body.ui-minimal.tabs-on.md-ready #mdPane{grid-column:2;grid-row:3}
body.ui-minimal.tabs-on.md-ready .stage{grid-column:1;grid-row:3}
body.ui-minimal.focus-mode .app{grid-template-columns:1fr}
body.ui-minimal.focus-mode #mdPane{display:none}
body.ui-minimal.focus-mode .stage{grid-column:1;grid-row:3;width:calc(100vw / var(--ui-zoom, 1));height:calc(100dvh / var(--ui-zoom, 1))}
body.ui-minimal.shared-view .app{grid-template-columns:1fr}
body.ui-minimal.shared-view #mdPane{display:none}
body.ui-minimal.shared-view .stage{grid-column:1;grid-row:3}

  /* ---- Minimal launcher: a Raspberry-Pi-OS-style menu. The MindSpark logo
   sits beside the map title at the top-left and opens a context menu with
   Maps, Templates and Open source. Only the minimal layout shows the logo. ---- */
.minimal-menu-btn{display:none;align-items:center;justify-content:center;
  width:34px;height:34px;margin:6px 4px 6px 10px;padding:0;flex:0 0 auto;
  border:none;border-radius:9px;background:none;cursor:pointer}
.minimal-menu-btn:hover{background:var(--hover)}
.minimal-menu-btn:active{transform:scale(.94)}
.minimal-menu-btn svg{width:24px;height:24px}
body.ui-minimal .minimal-menu-btn{display:flex}
.minimal-menu{
  position:fixed;min-width:190px;z-index:500;padding:6px;
  background:var(--chrome);border:1px solid var(--chrome-edge);border-radius:12px;
  box-shadow:var(--shadow-lg);display:flex;flex-direction:column;gap:2px;
  animation:pop .12s ease-out;
}
.minimal-menu[hidden]{display:none}
.minimal-menu .mm-item{
  display:flex;align-items:center;gap:10px;padding:8px 10px;width:100%;
  border:none;background:none;border-radius:8px;font-family:inherit;font-size:13px;
  color:var(--ink);cursor:pointer;text-align:left}
.minimal-menu .mm-item:hover{background:var(--hover)}
.minimal-menu .mm-item.mm-has-sub:hover{background:var(--paper-2)}
.minimal-menu .mm-item.mm-has-sub:hover .mm-caret{color:var(--accent);opacity:1}
.minimal-menu .mm-item:active{transform:scale(.98)}
.minimal-menu .mm-item + .mm-item{border-top:1px solid transparent}
.minimal-menu .mm-item .mm-lbl{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.minimal-menu .mm-item .mm-caret{margin-left:auto;font-size:10px;opacity:.6;transform:translateY(-1px)}
.minimal-menu .mm-ic{width:18px;height:18px;flex:0 0 auto;display:flex;align-items:center;justify-content:center;color:var(--accent)}
.minimal-menu .mm-ic svg{width:16px;height:16px}
.minimal-menu .mm-ic .dot{width:9px;height:9px;border-radius:50%;flex:0 0 auto;display:block}
.minimal-menu .mm-ic svg + .dot{display:none}
@keyframes pop{from{opacity:0}to{opacity:1}}

/* Cascading sub-panels anchored beside their parent item. They live on <body>
   (never inside the animated menu) so their fixed positioning is relative to
   the viewport; they flip to the left/bottom edge when they would otherwise
   run off the screen. */
.minimal-sub{
  position:fixed;min-width:190px;max-width:280px;max-height:min(70vh,420px);overflow-y:auto;
  z-index:501;padding:6px;background:var(--chrome);border:1px solid var(--chrome-edge);
  border-radius:12px;box-shadow:var(--shadow-lg);display:flex;flex-direction:column;gap:2px;
  animation:pop .12s ease-out;
}
.minimal-sub[hidden]{display:none}
.minimal-sub .mm-item{display:flex;align-items:center;gap:10px;padding:8px 10px;width:100%;border:none;background:none;border-radius:8px;font-family:inherit;font-size:13px;color:var(--ink);cursor:pointer;text-align:left}
.minimal-sub .mm-item:hover{background:var(--hover)}
.minimal-sub .mm-item:active{transform:scale(.98)}
.minimal-sub .mm-item.active{background:var(--paper-2);color:var(--accent);font-weight:600}
.minimal-sub .mm-item .mm-lbl{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.minimal-sub .mm-item .mm-pin{margin-left:auto;font-size:11px;opacity:.7}
.minimal-sub .mm-ic{width:18px;height:18px;flex:0 0 auto;display:flex;align-items:center;justify-content:center;color:var(--accent)}
.minimal-sub .mm-ic svg{width:16px;height:16px}
.minimal-sub .mm-ic .dot{width:9px;height:9px;border-radius:50%;flex:0 0 auto;display:block}
.minimal-sub .mm-empty{padding:8px 10px;font-size:12px;color:var(--muted);text-align:center}
.minimal-sub .map-group-label{font-size:10px;text-transform:uppercase;letter-spacing:.6px;color:var(--muted);padding:8px 10px 4px;font-weight:700}

/* ---- Mirror classic: the same floating shell as classic, flipped to the
   left. applyUiLayout() keeps body.ui-classic applied too, so every classic
   rule already covers this layout — only the positions are mirrored. ---- */
body.ui-mirror .topbar{justify-content:flex-end}     /* actions left, title right */
body.ui-mirror .tb-group{flex-direction:row-reverse}
body.ui-mirror .overview{right:auto;left:72px}       /* minimap card bottom-left */
body.ui-mirror .zoom-row{right:auto;left:18px}       /* zoombar beside it, left edge */
body.ui-mirror .hint{left:auto;right:18px}           /* hint bottom-right */
body.ui-mirror.shared-view .breadcrumb{transform:translateX(-50%) translateY(-4px)}
body.ui-mirror.shared-view .breadcrumb.shown{transform:translateX(-50%) translateY(0)}

/* ---- Presentation: chrome vanishes, the canvas fills the window and the map
   is walked node by node (breadth-first). The current node gets an accent
   ring and the rest of the map dims; a slim bar top-centre shows the node
   title, the position in the walk and prev/next controls. ---- */
body.ui-deck .app{grid-template-columns:1fr;grid-template-rows:minmax(0,1fr)}
body.ui-deck .stage{grid-column:1;grid-row:1}
body.ui-deck .side, body.ui-deck .topbar, body.ui-deck .statusbar,
body.ui-deck .hint, body.ui-deck .overview, body.ui-deck .breadcrumb,
body.ui-deck .save-pill, body.ui-deck .search-wrap, body.ui-deck #mdPane,
body.ui-deck .focus-exit{display:none !important}
#deckBar{
  position:fixed;top:14px;left:50%;transform:translateX(-50%);z-index:500;
  display:flex;align-items:center;gap:12px;max-width:min(92vw, 640px);
  padding:6px 8px 6px 14px;background:var(--chrome);
  border:1px solid var(--chrome-edge);border-radius:12px;box-shadow:var(--shadow);
  font-size:13px;color:var(--ink);
}
#deckBar .deck-title{font-weight:600;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
#deckBar .deck-pos{font-variant-numeric:tabular-nums;color:var(--ink-soft);font-size:12px;flex:0 0 auto}
#deckBar .deck-nav{display:flex;gap:4px}
#deckBar button{width:30px;height:30px;border-radius:8px;border:none;background:none;color:var(--ink-soft);cursor:pointer;font-size:13px;line-height:1}
#deckBar button:hover{background:var(--hover);color:var(--ink)}
#deckBar #deckExit:hover{background:color-mix(in srgb, var(--accent) 14%, transparent);color:var(--accent)}
body.ui-deck .node{transition:opacity .3s ease}
body.ui-deck .node:not(.deck-current){opacity:.28}
body.ui-deck .node.deck-current{box-shadow:0 0 0 3px var(--accent)}

/* ---- Outline dock: the modern shell plus a live tree panel between the
   sidebar and the canvas (side | outline | canvas). Folded by default — the
   ▤ toolbar button opens it. Rows select + centre the node; the twist folds
   a branch locally without touching the map. ---- */
body.ui-outline .app{grid-template-columns:auto 0 minmax(0,1fr)}
body.ui-outline.outline-open .app{grid-template-columns:auto auto minmax(0,1fr)}
body.ui-outline .topbar, body.ui-outline .statusbar{grid-column:2/-1}
body.ui-outline .stage{grid-column:3;grid-row:3}
body.ui-outline #mdToggle{display:none}
body:not(.ui-outline) #outlineBtn{display:none}
#outlinePane{
  grid-column:2;grid-row:3;display:flex;flex-direction:column;min-width:0;min-height:0;
  width:0;overflow:hidden;background:var(--paper);border-right:1px solid var(--line);
  transition:width .22s cubic-bezier(.4,0,.2,1);
}
body.ui-outline.outline-open #outlinePane{width:min(280px,24vw)}
#outlinePane .ol-head{display:flex;align-items:center;gap:8px;padding:8px 12px;border-bottom:1px solid var(--line);font-size:12px;font-weight:700;color:var(--ink-soft);letter-spacing:.04em}
#outlinePane .ol-close{margin-left:auto;border:none;background:none;cursor:pointer;color:var(--ink-soft);font-size:13px;line-height:1;padding:4px 6px;border-radius:6px}
#outlinePane .ol-close:hover{background:var(--hover);color:var(--ink)}
#outlinePane .ol-body{flex:1;min-height:0;overflow:auto;padding:8px 6px 14px}
#outlinePane .ol-tree, #outlinePane .ol-sub{list-style:none;margin:0;padding:0}
#outlinePane .ol-sub{padding-left:16px}
#outlinePane .ol-node.collapsed > .ol-sub{display:none}
#outlinePane .ol-row{display:flex;align-items:center;gap:4px;padding:4px 8px;border-radius:8px;cursor:pointer;font-size:13px;line-height:1.45;color:var(--ink)}
#outlinePane .ol-row:hover{background:var(--hover)}
#outlinePane .ol-node.sel > .ol-row{background:color-mix(in srgb, var(--accent) 14%, transparent);color:var(--accent)}
#outlinePane .ol-twist{flex:0 0 14px;width:14px;text-align:center;color:var(--ink-soft);font-size:10px;user-select:none;transition:transform .15s ease}
#outlinePane .ol-leaf{visibility:hidden}
#outlinePane .ol-node.collapsed > .ol-row .ol-twist{transform:rotate(-90deg)}
#outlinePane .ol-label{white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
body.ui-outline.focus-mode .app{grid-template-columns:1fr}
body.ui-outline.focus-mode #outlinePane{display:none}
body.ui-outline.focus-mode .stage{grid-column:1;grid-row:3;width:calc(100vw / var(--ui-zoom, 1));height:calc(100dvh / var(--ui-zoom, 1))}
body.ui-outline.shared-view .app{grid-template-columns:auto minmax(0,1fr)}
body.ui-outline.shared-view #outlinePane{display:none}
body.ui-outline.shared-view .stage{grid-column:2;grid-row:3}

@media (max-width:720px){
  #deckBar{top:8px;left:8px;right:8px;transform:none;max-width:none}
  body.ui-outline .app{grid-template-columns:1fr}
  body.ui-outline .topbar, body.ui-outline .statusbar{grid-column:1}
  body.ui-outline .stage{grid-column:1;grid-row:3}
  body.ui-outline #outlinePane, body.ui-outline #outlineBtn{display:none}
  body.ui-classic .app{grid-template-columns:1fr}
  body.ui-classic .side{grid-column:1;grid-row:1;width:min(280px, 86vw)}
  body.ui-classic .stage{grid-column:1;grid-row:1}
  body.ui-classic .side.collapsed{width:min(280px, 86vw)}
  body.ui-classic .topbar{top:10px;left:10px;right:10px}
  /* Full-width strip on phones. The insets stretch the bar, so the desktop
     translateX(-50%) centering must go too — it shifted the strip half its
     own width off-screen (left edge unreachable). */
  body.ui-zen .topbar{top:10px;left:10px;right:10px;width:auto;max-width:none;transform:translateY(-12px)}
  body.ui-zen.zen-chrome .topbar,
  body.ui-zen.zen-pinned .topbar{transform:translateY(0)}
  body.ui-split .app{grid-template-columns:1fr}
  body.ui-split .topbar{grid-column:1;grid-row:1}
  body.ui-split .stage{grid-column:1;grid-row:3}
  body.ui-split .statusbar{grid-column:1;grid-row:4}
  body.ui-classic .hint, body.ui-rail .hint, body.ui-zen .hint{display:none}
  body.ui-classic .overview, body.ui-rail .overview, body.ui-zen .overview{display:none}   /* minimap is hidden on small screens; the zoombar stays */
  body.ui-classic .zoom-row, body.ui-rail .zoom-row, body.ui-zen .zoom-row{bottom:12px;right:12px}
  body.ui-mirror .zoom-row{bottom:12px;left:12px;right:auto}
  /* Rail keeps its slim column on phones; the sidebar is the off-canvas
     overlay and the canvas fills the remaining column. */
  body.ui-rail .app{grid-template-columns:40px minmax(0,1fr)}
  body.ui-rail .side{grid-column:1;grid-row:1;width:min(280px, 86vw)}
  body.ui-rail .topbar{grid-column:1;grid-row:1;padding:8px 2px}
  body.ui-rail .stage{grid-column:2;grid-row:1}
}

/* ===== Smooth theme switching =====
   When a Colour Theme (or a theme-config JSON) changes the custom
   properties, these surfaces interpolate their colors over 0.3s — the same
   easing as the theme cards — instead of snapping. Canvas textures
   (background-image) are not interpolatable, so they still swap instantly
   while the paper color underneath fades; node and edge strokes fade with
   the theme too. Interactive hover controls use the shorter 0.2s so hover
   feedback stays snappy. */
body, .app, .topbar, .statusbar, .stage, .nodebar, .brand, .save-pill,
.vf-card, .row-pop, .picker, .donate-card, .export-pop,
.search-wrap, .minimap, .toast, .theme-panel, .notes-popup{
  transition: background-color 0.3s ease, border-color 0.3s ease, color 0.3s ease;
}
#edges path{
  transition: stroke 0.3s ease;
}
.tb, .map-item, .scale-opt, .side-tab, .tpl-side-item, .title-edit,
.overview, .zoom-val, .zoom-row button,
input, textarea, select{
  transition: background-color 0.2s ease, border-color 0.2s ease, color 0.2s ease;
}
@media (prefers-reduced-motion: reduce){
  body, .app, .topbar, .statusbar, .stage, .nodebar, .brand, .save-pill,
  .vf-card, .row-pop, .picker, .donate-card, .export-pop,
  .minimap, .theme-panel, .notes-popup, #edges path,
  .tb, .map-item, .scale-opt, .side-tab, .tpl-side-item, .title-edit,
  .overview, .zoom-val, .zoom-row button,
  input, textarea, select{
    transition: none !important;
  }
}

