diff --git a/home/features/desktop/firefox/default.nix b/home/features/desktop/firefox/default.nix
index 83f8e68..cbbf020 100644
--- a/home/features/desktop/firefox/default.nix
+++ b/home/features/desktop/firefox/default.nix
@@ -222,6 +222,9 @@ in
         # Do not restore sessions after what looks like a "crash"
         "browser.sessionstore.resume_from_crash" = false;
 
+        # Do not paste with middle mouse click
+        "middlemouse.paste" = false;
+
         # Inspired by https://github.com/TLATER/dotfiles/blob/b39af91fbd13d338559a05d69f56c5a97f8c905d/home-config/config/graphical-applications/firefox.nix
         # {{{ Performance settings
         "gfx.webrender.all" = true; # Force enable GPU acceleration
diff --git a/home/features/neovim/config/lua/my/luasnip.lua b/home/features/neovim/config/lua/my/luasnip.lua
index 29337fa..c0e057e 100644
--- a/home/features/neovim/config/lua/my/luasnip.lua
+++ b/home/features/neovim/config/lua/my/luasnip.lua
@@ -73,4 +73,8 @@ M.text = conditions.make_condition(function()
 end)
 -- }}}
 
+M.never = conditions.make_condition(function()
+  return false
+end)
+
 return M
diff --git a/home/features/neovim/default.nix b/home/features/neovim/default.nix
index b69c530..f317569 100644
--- a/home/features/neovim/default.nix
+++ b/home/features/neovim/default.nix
@@ -19,6 +19,7 @@ let
     { tempestModule = "my.tempest"; };
 
   mirosSnippetCache = "${config.xdg.cacheHome}/miros";
+  obsidianVault = "${config.xdg.userDirs.extraConfig.XDG_PROJECTS_DIR}/stellar-sanctum";
 
   generated = nlib.generateConfig
     (lib.fix (self: with nlib; {
@@ -88,10 +89,17 @@ let
           #  }}}
 
           # {{{ Starter page
-          callback = thunk ''
-            require("my.starter").setup(${encode {
-              header = builtins.readFile ./header.txt;
-            }})
+          callback = thunk /* lua */''
+            local cwd = vim.loop.cwd()
+            local header
+
+            if cwd == ${encode obsidianVault} then
+              header = ${encode (builtins.readFile ./headers/obsidian.txt)}
+            else
+              header = ${encode (builtins.readFile ./headers/main.txt)}
+            end
+
+            require("my.starter").setup({ header = header })
           '';
           # }}}
         };
@@ -1421,9 +1429,7 @@ let
         # }}}
         # {{{ obsidian
         obsidian =
-          let
-            vault = "${config.xdg.userDirs.extraConfig.XDG_PROJECTS_DIR}/stellar-sanctum";
-            dateFormat = "%Y-%m-%d";
+          let dateFormat = "%Y-%m-%d";
           in
           {
             package = "epwalsh/obsidian.nvim";
@@ -1432,7 +1438,7 @@ let
             event = "VeryLazy";
             cond = [
               (blacklist [ "vscode" "firenvim" ])
-              (lua /* lua */ "vim.loop.cwd() == ${encode vault}")
+              (lua /* lua */ "vim.loop.cwd() == ${encode obsidianVault}")
             ];
 
             config.keys =
@@ -1451,7 +1457,7 @@ let
               ];
 
             opts = {
-              dir = vault;
+              dir = obsidianVault;
               notes_subdir = "chaos";
 
               daily_notes = {
diff --git a/home/features/neovim/header.txt b/home/features/neovim/headers/main.txt
similarity index 100%
rename from home/features/neovim/header.txt
rename to home/features/neovim/headers/main.txt
diff --git a/home/features/neovim/headers/obsidian.txt b/home/features/neovim/headers/obsidian.txt
new file mode 100644
index 0000000..a7d0efd
--- /dev/null
+++ b/home/features/neovim/headers/obsidian.txt
@@ -0,0 +1,11 @@
+░        ░░  ░░░░  ░░        ░░░░░░░░░░░░░░░      ░░░        ░░        ░░  ░░░░░░░░  ░░░░░░░░░      ░░░       ░░
+▒▒▒▒  ▒▒▒▒▒  ▒▒▒▒  ▒▒  ▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒  ▒▒▒▒▒▒▒▒▒▒▒  ▒▒▒▒▒  ▒▒▒▒▒▒▒▒  ▒▒▒▒▒▒▒▒  ▒▒▒▒▒▒▒▒  ▒▒▒▒  ▒▒  ▒▒▒▒  ▒
+▓▓▓▓  ▓▓▓▓▓        ▓▓      ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓      ▓▓▓▓▓▓  ▓▓▓▓▓      ▓▓▓▓  ▓▓▓▓▓▓▓▓  ▓▓▓▓▓▓▓▓  ▓▓▓▓  ▓▓       ▓▓
+████  █████  ████  ██  ██████████████████████████  █████  █████  ████████  ████████  ████████        ██  ███  ██
+████  █████  ████  ██        ███████████████      ██████  █████        ██        ██        ██  ████  ██  ████  █
+
+░░░░░░░░░░░░░░░░░░░░░░░░░░      ░░░░      ░░░   ░░░  ░░░      ░░░        ░░  ░░░░  ░░  ░░░░  ░░░░░░░░░░░░░░░░░░░
+▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒  ▒▒▒▒▒▒▒▒  ▒▒▒▒  ▒▒    ▒▒  ▒▒  ▒▒▒▒  ▒▒▒▒▒  ▒▒▒▒▒  ▒▒▒▒  ▒▒   ▒▒   ▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
+▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓      ▓▓▓  ▓▓▓▓  ▓▓  ▓  ▓  ▓▓  ▓▓▓▓▓▓▓▓▓▓▓  ▓▓▓▓▓  ▓▓▓▓  ▓▓        ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓
+███████████████████████████████  ██        ██  ██    ██  ████  █████  █████  ████  ██  █  █  ███████████████████
+██████████████████████████      ███  ████  ██  ███   ███      ██████  ██████      ███  ████  ███████████████████
diff --git a/home/features/neovim/snippets/typst.miros b/home/features/neovim/snippets/typst.miros
index b3a522f..e0363d1 100644
--- a/home/features/neovim/snippets/typst.miros
+++ b/home/features/neovim/snippets/typst.miros
@@ -6,7 +6,7 @@ block auto start
         $0
       ]
 
-  for proofenv <- @⟨proof,solution⟩
+  for proofenv <- @⟨proof,solution,exercise,example⟩
   string @proofenv
     snip
       #@proofenv$|1⟨$1,(name: "$1")⟩[
@@ -42,11 +42,6 @@ block auto
     name definite integral
     snip ∫_$|1⟨$1,(-∞$1)⟩^$|2⟨$2,∞$2⟩ $3 dif $0
 
-  block !word
-    abbr .inv ^(-1)
-    abbr .neg _-
-    abbr .pos _+
-
   for limtarget <- @⟨anything,zero,infinity,negative infinity⟩
   for prefix <- @⟨@limtarget:,z,i,n⟩
   for limtargetsymbol <- @⟨@limtarget:$2,0,∞,-∞⟩
@@ -73,3 +68,41 @@ block auto
     string cr@operator
       name start with @operator
       snip \ &@symbol $0
+
+  block never
+    pattern (.*)e@⟨t(%a),(%d)⟩
+      name auto exponent
+      snip @0^@1 $0
+
+    pattern (.*)so(%a)
+      name auto subscript
+      snip @0_@1 $0
+
+  pattern ([%a]+)(%d)
+    name auto digt subscript
+    snip @0_@1 $0
+
+  string ss
+    name subscript
+    snip _{$1} $0
+
+  string ee
+    name exponent
+    snip ^($1) $0
+
+  pattern (%a)(.)pp
+    name auto function call
+    snip @0(@1) $0
+
+  pattern (%a)d(.)p
+    name auto derivative call
+    snip @0'(@1) $0
+
+  pattern (%a)i(.)p
+    name auto preimage call
+    snip @0^(-1)(@1) $0
+
+  block !word
+    abbr .inv ^(-1)
+    abbr .neg _-
+    abbr .pos _+