diff --git a/docs/astro.config.mjs b/docs/astro.config.mjs
index 9f3f506f..b4b90af2 100644
--- a/docs/astro.config.mjs
+++ b/docs/astro.config.mjs
@@ -7,6 +7,11 @@ const arcadeDark = JSON.parse(
 	readFileSync(new URL('./src/themes/arcade-dark.json', import.meta.url), 'utf-8')
 );
 
+const latteGrammar = JSON.parse(
+	readFileSync(new URL('./src/grammars/latte.tmLanguage.json', import.meta.url), 'utf-8')
+);
+latteGrammar.name = 'latte';
+
 // https://astro.build/config
 export default defineConfig({
 	site: 'https://marko.build',
@@ -19,6 +24,12 @@ export default defineConfig({
 			},
 			expressiveCode: {
 				themes: [arcadeDark],
+				shiki: {
+					langs: [latteGrammar, 'dotenv'],
+					langAlias: {
+						env: 'dotenv',
+					},
+				},
 			},
 			social: [
 				{ icon: 'github', label: 'GitHub', href: 'https://github.com/markshust/marko' },
diff --git a/docs/package-lock.json b/docs/package-lock.json
index 9bbd1143..687d6425 100644
--- a/docs/package-lock.json
+++ b/docs/package-lock.json
@@ -17,9 +17,9 @@
       }
     },
     "node_modules/@astrojs/compiler": {
-      "version": "3.0.0",
-      "resolved": "https://registry.npmjs.org/@astrojs/compiler/-/compiler-3.0.0.tgz",
-      "integrity": "sha512-MwAbDE5mawZ1SS+D8qWiHdprdME5Tlj2e0YjxnEICvcOpbSukNS7Sa7hA5PK+6RrmUr/t6Gi5YgrdZKjbO/WPQ==",
+      "version": "4.0.0",
+      "resolved": "https://registry.npmjs.org/@astrojs/compiler/-/compiler-4.0.0.tgz",
+      "integrity": "sha512-eouss7G8ygdZqHuke033VMcVw5HTZUu+PXd/h06DGDUg/jt5btPYPqh66ENWw/mU78rBrf/oeC4oqoBwMtDMNA==",
       "license": "MIT"
     },
     "node_modules/@astrojs/internal-helpers": {
@@ -149,17 +149,15 @@
       }
     },
     "node_modules/@astrojs/telemetry": {
-      "version": "3.3.0",
-      "resolved": "https://registry.npmjs.org/@astrojs/telemetry/-/telemetry-3.3.0.tgz",
-      "integrity": "sha512-UFBgfeldP06qu6khs/yY+q1cDAaArM2/7AEIqQ9Cuvf7B1hNLq0xDrZkct+QoIGyjq56y8IaE2I3CTvG99mlhQ==",
+      "version": "3.3.2",
+      "resolved": "https://registry.npmjs.org/@astrojs/telemetry/-/telemetry-3.3.2.tgz",
+      "integrity": "sha512-j8DNruA8ors99Al39RYZPJK4DC1bKkoNm93mAMuBhY9TCNC4R8n1q7ovFnJ5qhGh5Lsh7pa1gpQVpYpsJPeTHQ==",
       "license": "MIT",
       "dependencies": {
-        "ci-info": "^4.2.0",
-        "debug": "^4.4.0",
-        "dlv": "^1.1.3",
+        "ci-info": "^4.4.0",
         "dset": "^3.1.4",
-        "is-docker": "^3.0.0",
-        "is-wsl": "^3.1.0",
+        "is-docker": "^4.0.0",
+        "is-wsl": "^3.1.1",
         "which-pm-runs": "^1.1.0"
       },
       "engines": {
@@ -2108,9 +2106,9 @@
       }
     },
     "node_modules/anymatch/node_modules/picomatch": {
-      "version": "2.3.1",
-      "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz",
-      "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==",
+      "version": "2.3.2",
+      "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.2.tgz",
+      "integrity": "sha512-V7+vQEJ06Z+c5tSye8S+nHUfI51xoXIXjHQ99cQtKUkQqqO1kO/KCJUfZXuB47h/YBlDhah2H3hdUGXn8ie0oA==",
       "license": "MIT",
       "engines": {
         "node": ">=8.6"
@@ -2160,17 +2158,17 @@
       }
     },
     "node_modules/astro": {
-      "version": "6.0.4",
-      "resolved": "https://registry.npmjs.org/astro/-/astro-6.0.4.tgz",
-      "integrity": "sha512-1piLJCPTL/x7AMO2cjVFSTFyRqKuC3W8sSEySCt1aJio+p/wGs5H3K+Xr/rE9ftKtknLUtjxCqCE7/0NsXfGpQ==",
+      "version": "6.3.8",
+      "resolved": "https://registry.npmjs.org/astro/-/astro-6.3.8.tgz",
+      "integrity": "sha512-xH2UA8Z17IS+JaqSlSkBor7jO6gd7zXTLdmu06nKpfpDDJFbi/7KZEy3NDmWxmier+6XrCZ9Z4aitO8jhC9oiA==",
       "license": "MIT",
       "dependencies": {
-        "@astrojs/compiler": "^3.0.0",
-        "@astrojs/internal-helpers": "0.8.0",
-        "@astrojs/markdown-remark": "7.0.0",
-        "@astrojs/telemetry": "3.3.0",
+        "@astrojs/compiler": "^4.0.0",
+        "@astrojs/internal-helpers": "0.9.1",
+        "@astrojs/markdown-remark": "7.1.2",
+        "@astrojs/telemetry": "3.3.2",
         "@capsizecss/unpack": "^4.0.0",
-        "@clack/prompts": "^1.0.1",
+        "@clack/prompts": "^1.1.0",
         "@oslojs/encoding": "^1.1.0",
         "@rollup/pluginutils": "^5.3.0",
         "aria-query": "^5.3.2",
@@ -2181,16 +2179,17 @@
         "cookie": "^1.1.1",
         "devalue": "^5.6.3",
         "diff": "^8.0.3",
-        "dlv": "^1.1.3",
         "dset": "^3.1.4",
         "es-module-lexer": "^2.0.0",
         "esbuild": "^0.27.3",
         "flattie": "^1.1.1",
         "fontace": "~0.4.1",
+        "get-tsconfig": "5.0.0-beta.4",
         "github-slugger": "^2.0.0",
         "html-escaper": "3.0.3",
         "http-cache-semantics": "^4.2.0",
         "js-yaml": "^4.1.1",
+        "jsonc-parser": "^3.3.1",
         "magic-string": "^0.30.21",
         "magicast": "^0.5.2",
         "mrmime": "^2.0.1",
@@ -2200,22 +2199,21 @@
         "p-queue": "^9.1.0",
         "package-manager-detector": "^1.6.0",
         "piccolore": "^0.1.3",
-        "picomatch": "^4.0.3",
+        "picomatch": "^4.0.4",
         "rehype": "^13.0.2",
         "semver": "^7.7.4",
-        "shiki": "^4.0.0",
+        "shiki": "^4.0.2",
         "smol-toml": "^1.6.0",
-        "svgo": "^4.0.0",
-        "tinyclip": "^0.1.6",
-        "tinyexec": "^1.0.2",
+        "svgo": "^4.0.1",
+        "tinyclip": "^0.1.12",
+        "tinyexec": "^1.0.4",
         "tinyglobby": "^0.2.15",
-        "tsconfck": "^3.1.6",
         "ultrahtml": "^1.6.0",
         "unifont": "~0.7.4",
         "unist-util-visit": "^5.1.0",
-        "unstorage": "^1.17.4",
+        "unstorage": "^1.17.5",
         "vfile": "^6.0.3",
-        "vite": "^7.3.1",
+        "vite": "^7.3.2",
         "vitefu": "^1.1.2",
         "xxhash-wasm": "^1.1.0",
         "yargs-parser": "^22.0.0",
@@ -2225,7 +2223,7 @@
         "astro": "bin/astro.mjs"
       },
       "engines": {
-        "node": "^20.19.1 || >=22.12.0",
+        "node": ">=22.12.0",
         "npm": ">=9.6.5",
         "pnpm": ">=7.1.0"
       },
@@ -2249,6 +2247,56 @@
         "astro": "^4.0.0-beta || ^5.0.0-beta || ^3.3.0 || ^6.0.0-beta"
       }
     },
+    "node_modules/astro/node_modules/@astrojs/internal-helpers": {
+      "version": "0.9.1",
+      "resolved": "https://registry.npmjs.org/@astrojs/internal-helpers/-/internal-helpers-0.9.1.tgz",
+      "integrity": "sha512-1pWuARqYom/TzuU3+0ZugsTrKlUydWKuULmDqSMTuonY+9IRDUEGKX/8PXQ1nBxRq3w85uGtd9q9SXfqEldMIQ==",
+      "license": "MIT",
+      "dependencies": {
+        "picomatch": "^4.0.4"
+      }
+    },
+    "node_modules/astro/node_modules/@astrojs/markdown-remark": {
+      "version": "7.1.2",
+      "resolved": "https://registry.npmjs.org/@astrojs/markdown-remark/-/markdown-remark-7.1.2.tgz",
+      "integrity": "sha512-caXZ4Dc2St2dW8luEg22GlP0gupLdztCTQE4EzZOxW1pqWXz9mbeJEuHUkgDYcKWW8tjIHkydYDhWLVoxJ327Q==",
+      "license": "MIT",
+      "dependencies": {
+        "@astrojs/internal-helpers": "0.9.1",
+        "@astrojs/prism": "4.0.2",
+        "github-slugger": "^2.0.0",
+        "hast-util-from-html": "^2.0.3",
+        "hast-util-to-text": "^4.0.2",
+        "js-yaml": "^4.1.1",
+        "mdast-util-definitions": "^6.0.0",
+        "rehype-raw": "^7.0.0",
+        "rehype-stringify": "^10.0.1",
+        "remark-gfm": "^4.0.1",
+        "remark-parse": "^11.0.0",
+        "remark-rehype": "^11.1.2",
+        "remark-smartypants": "^3.0.2",
+        "retext-smartypants": "^6.2.0",
+        "shiki": "^4.0.0",
+        "smol-toml": "^1.6.0",
+        "unified": "^11.0.5",
+        "unist-util-remove-position": "^5.0.0",
+        "unist-util-visit": "^5.1.0",
+        "unist-util-visit-parents": "^6.0.2",
+        "vfile": "^6.0.3"
+      }
+    },
+    "node_modules/astro/node_modules/@astrojs/prism": {
+      "version": "4.0.2",
+      "resolved": "https://registry.npmjs.org/@astrojs/prism/-/prism-4.0.2.tgz",
+      "integrity": "sha512-KTivpmnz6lDsC6o9H4+DNm2SrE/GHzw8cNAvEJwAvUT+eoaEnn/4NtbDNfRRaxaJHdp15gf+tfHAWiXR4wB3BA==",
+      "license": "MIT",
+      "dependencies": {
+        "prismjs": "^1.30.0"
+      },
+      "engines": {
+        "node": ">=22.12.0"
+      }
+    },
     "node_modules/axobject-query": {
       "version": "4.1.0",
       "resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-4.1.0.tgz",
@@ -2440,9 +2488,9 @@
       }
     },
     "node_modules/cookie-es": {
-      "version": "1.2.2",
-      "resolved": "https://registry.npmjs.org/cookie-es/-/cookie-es-1.2.2.tgz",
-      "integrity": "sha512-+W7VmiVINB+ywl1HGXJXmrqkOhpKrIiVZV6tQuV54ZyQC7MMuBt81Vc336GMLoHBq5hV/F9eXgt5Mnx0Rha5Fg==",
+      "version": "1.2.3",
+      "resolved": "https://registry.npmjs.org/cookie-es/-/cookie-es-1.2.3.tgz",
+      "integrity": "sha512-lXVyvUvrNXblMqzIRrxHb57UUVmqsSWlxqt3XIjCkUP0wDAf6uicO6KMbEgYrMNtEvWgWHwe42CKxPu9MYAnWw==",
       "license": "MIT"
     },
     "node_modules/crossws": {
@@ -2587,9 +2635,9 @@
       }
     },
     "node_modules/defu": {
-      "version": "6.1.4",
-      "resolved": "https://registry.npmjs.org/defu/-/defu-6.1.4.tgz",
-      "integrity": "sha512-mEQCMmwJu317oSz8CwdIOdwf3xMif1ttiM8LTufzc3g6kR+9Pe236twL8j3IYT1F7GfRgGcW6MWxzZjLIkuHIg==",
+      "version": "6.1.7",
+      "resolved": "https://registry.npmjs.org/defu/-/defu-6.1.7.tgz",
+      "integrity": "sha512-7z22QmUWiQ/2d0KkdYmANbRUVABpZ9SNYyH5vx6PZ+nE5bcC0l7uFvEfHlyld/HcGBFTL536ClDt3DEcSlEJAQ==",
       "license": "MIT"
     },
     "node_modules/dequal": {
@@ -2617,9 +2665,9 @@
       }
     },
     "node_modules/devalue": {
-      "version": "5.6.4",
-      "resolved": "https://registry.npmjs.org/devalue/-/devalue-5.6.4.tgz",
-      "integrity": "sha512-Gp6rDldRsFh/7XuouDbxMH3Mx8GMCcgzIb1pDTvNyn8pZGQ22u+Wa+lGV9dQCltFQ7uVw0MhRyb8XDskNFOReA==",
+      "version": "5.8.1",
+      "resolved": "https://registry.npmjs.org/devalue/-/devalue-5.8.1.tgz",
+      "integrity": "sha512-4CXDYRBGqN+57wVJkuXBYmpAVUSg3L6JAQa/DFqm238G73E1wuyc/JhGQJzN7vUf/CMphYau2zXbfWzDR5aTEw==",
       "license": "MIT"
     },
     "node_modules/devlop": {
@@ -2657,12 +2705,6 @@
         "url": "https://github.com/sponsors/wooorm"
       }
     },
-    "node_modules/dlv": {
-      "version": "1.1.3",
-      "resolved": "https://registry.npmjs.org/dlv/-/dlv-1.1.3.tgz",
-      "integrity": "sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==",
-      "license": "MIT"
-    },
     "node_modules/dom-serializer": {
       "version": "2.0.0",
       "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-2.0.0.tgz",
@@ -3018,6 +3060,21 @@
         "node": "^8.16.0 || ^10.6.0 || >=11.0.0"
       }
     },
+    "node_modules/get-tsconfig": {
+      "version": "5.0.0-beta.4",
+      "resolved": "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-5.0.0-beta.4.tgz",
+      "integrity": "sha512-7nF7C9fIPFEMHgEMEfgIlO9wDdZ8CyHw27rWciFZfHvHDReIiPhsYuzPRXsfvBCqFy1l8RRyyWV7QLM+ZhUJsQ==",
+      "license": "MIT",
+      "dependencies": {
+        "resolve-pkg-maps": "^1.0.0"
+      },
+      "engines": {
+        "node": ">=20.20.0"
+      },
+      "funding": {
+        "url": "https://github.com/privatenumber/get-tsconfig?sponsor=1"
+      }
+    },
     "node_modules/github-slugger": {
       "version": "2.0.0",
       "resolved": "https://registry.npmjs.org/github-slugger/-/github-slugger-2.0.0.tgz",
@@ -3025,14 +3082,14 @@
       "license": "ISC"
     },
     "node_modules/h3": {
-      "version": "1.15.6",
-      "resolved": "https://registry.npmjs.org/h3/-/h3-1.15.6.tgz",
-      "integrity": "sha512-oi15ESLW5LRthZ+qPCi5GNasY/gvynSKUQxgiovrY63bPAtG59wtM+LSrlcwvOHAXzGrXVLnI97brbkdPF9WoQ==",
+      "version": "1.15.11",
+      "resolved": "https://registry.npmjs.org/h3/-/h3-1.15.11.tgz",
+      "integrity": "sha512-L3THSe2MPeBwgIZVSH5zLdBBU90TOxarvhK9d04IDY2AmVS8j2Jz2LIWtwsGOU3lu2I5jCN7FNvVfY2+XyF+mg==",
       "license": "MIT",
       "dependencies": {
-        "cookie-es": "^1.2.2",
+        "cookie-es": "^1.2.3",
         "crossws": "^0.3.5",
-        "defu": "^6.1.4",
+        "defu": "^6.1.6",
         "destr": "^2.0.5",
         "iron-webcrypto": "^1.2.1",
         "node-mock-http": "^1.0.4",
@@ -3511,15 +3568,15 @@
       }
     },
     "node_modules/is-docker": {
-      "version": "3.0.0",
-      "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-3.0.0.tgz",
-      "integrity": "sha512-eljcgEDlEns/7AXFosB5K/2nCM4P7FQPkGc/DWLy5rmFEWvZayGrik1d9/QIY5nJ4f9YsVvBkA6kJpHn9rISdQ==",
+      "version": "4.0.0",
+      "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-4.0.0.tgz",
+      "integrity": "sha512-LHE+wROyG/Y/0ZnbktRCoTix2c1RhgWaZraMZ8o1Q7zCh0VSrICJQO5oqIIISrcSBtrXv0o233w1IYwsWCjTzA==",
       "license": "MIT",
       "bin": {
         "is-docker": "cli.js"
       },
       "engines": {
-        "node": "^12.20.0 || ^14.13.1 || >=16.0.0"
+        "node": ">=20"
       },
       "funding": {
         "url": "https://github.com/sponsors/sindresorhus"
@@ -3553,6 +3610,21 @@
         "url": "https://github.com/sponsors/sindresorhus"
       }
     },
+    "node_modules/is-inside-container/node_modules/is-docker": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-3.0.0.tgz",
+      "integrity": "sha512-eljcgEDlEns/7AXFosB5K/2nCM4P7FQPkGc/DWLy5rmFEWvZayGrik1d9/QIY5nJ4f9YsVvBkA6kJpHn9rISdQ==",
+      "license": "MIT",
+      "bin": {
+        "is-docker": "cli.js"
+      },
+      "engines": {
+        "node": "^12.20.0 || ^14.13.1 || >=16.0.0"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
+      }
+    },
     "node_modules/is-plain-obj": {
       "version": "4.1.0",
       "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-4.1.0.tgz",
@@ -3592,6 +3664,12 @@
         "js-yaml": "bin/js-yaml.js"
       }
     },
+    "node_modules/jsonc-parser": {
+      "version": "3.3.1",
+      "resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-3.3.1.tgz",
+      "integrity": "sha512-HUgH65KyejrUFPvHFPbqOY0rsFip3Bo5wb4ngvdi1EpCYWUQDC5V+Y7mZws+DLkr4M//zQJoanu1SP+87Dv1oQ==",
+      "license": "MIT"
+    },
     "node_modules/klona": {
       "version": "2.0.6",
       "resolved": "https://registry.npmjs.org/klona/-/klona-2.0.6.tgz",
@@ -3612,9 +3690,9 @@
       }
     },
     "node_modules/lru-cache": {
-      "version": "11.2.6",
-      "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.2.6.tgz",
-      "integrity": "sha512-ESL2CrkS/2wTPfuend7Zhkzo2u0daGJ/A2VucJOgQ/C48S/zB8MMeMHSGKYpXhIjbPxfuezITkaBH1wqv00DDQ==",
+      "version": "11.5.0",
+      "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.5.0.tgz",
+      "integrity": "sha512-5YgH9UJd7wVb9hIouI2adWpgqrrICkt070Dnj8EUY1+B4B2P9eRLPAkAAo6NICA7CEhOIeBHl46u9zSNpNu7zA==",
       "license": "BlueOak-1.0.0",
       "engines": {
         "node": "20 || >=22"
@@ -4743,9 +4821,9 @@
       "license": "MIT"
     },
     "node_modules/nanoid": {
-      "version": "3.3.11",
-      "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.11.tgz",
-      "integrity": "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==",
+      "version": "3.3.12",
+      "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.12.tgz",
+      "integrity": "sha512-ZB9RH/39qpq5Vu6Y+NmUaFhQR6pp+M2Xt76XBnEwDaGcVAqhlvxrl3B2bKS5D3NH3QR76v3aSrKaF/Kiy7lEtQ==",
       "funding": [
         {
           "type": "github",
@@ -4993,9 +5071,9 @@
       "license": "ISC"
     },
     "node_modules/picomatch": {
-      "version": "4.0.3",
-      "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz",
-      "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==",
+      "version": "4.0.4",
+      "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.4.tgz",
+      "integrity": "sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==",
       "license": "MIT",
       "engines": {
         "node": ">=12"
@@ -5005,9 +5083,9 @@
       }
     },
     "node_modules/postcss": {
-      "version": "8.5.8",
-      "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.8.tgz",
-      "integrity": "sha512-OW/rX8O/jXnm82Ey1k44pObPtdblfiuWnrd8X7GJ7emImCOstunGbXUpp7HdBrFQX6rJzn3sPT397Wp5aCwCHg==",
+      "version": "8.5.15",
+      "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.15.tgz",
+      "integrity": "sha512-FfR8sjd4em2T6fb3I2MwAJU7HWVMr9zba+enmQeeWFfCbm+UOC/0X4DS8XtpUTMwWMGbjKYP7xjfNekzyGmB3A==",
       "funding": [
         {
           "type": "opencollective",
@@ -5024,7 +5102,7 @@
       ],
       "license": "MIT",
       "dependencies": {
-        "nanoid": "^3.3.11",
+        "nanoid": "^3.3.12",
         "picocolors": "^1.1.1",
         "source-map-js": "^1.2.1"
       },
@@ -5409,6 +5487,15 @@
         "url": "https://opencollective.com/unified"
       }
     },
+    "node_modules/resolve-pkg-maps": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/resolve-pkg-maps/-/resolve-pkg-maps-1.0.0.tgz",
+      "integrity": "sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==",
+      "license": "MIT",
+      "funding": {
+        "url": "https://github.com/privatenumber/resolve-pkg-maps?sponsor=1"
+      }
+    },
     "node_modules/retext": {
       "version": "9.0.0",
       "resolved": "https://registry.npmjs.org/retext/-/retext-9.0.0.tgz",
@@ -5624,9 +5711,9 @@
       }
     },
     "node_modules/smol-toml": {
-      "version": "1.6.0",
-      "resolved": "https://registry.npmjs.org/smol-toml/-/smol-toml-1.6.0.tgz",
-      "integrity": "sha512-4zemZi0HvTnYwLfrpk/CF9LOd9Lt87kAt50GnqhMpyF9U3poDAP2+iukq2bZsO/ufegbYehBkqINbsWxj4l4cw==",
+      "version": "1.6.1",
+      "resolved": "https://registry.npmjs.org/smol-toml/-/smol-toml-1.6.1.tgz",
+      "integrity": "sha512-dWUG8F5sIIARXih1DTaQAX4SsiTXhInKf1buxdY9DIg4ZYPZK5nGM1VRIYmEbDbsHt7USo99xSLFu5Q1IqTmsg==",
       "license": "BSD-3-Clause",
       "engines": {
         "node": ">= 18"
@@ -5742,9 +5829,9 @@
       }
     },
     "node_modules/tinyexec": {
-      "version": "1.0.2",
-      "resolved": "https://registry.npmjs.org/tinyexec/-/tinyexec-1.0.2.tgz",
-      "integrity": "sha512-W/KYk+NFhkmsYpuHq5JykngiOCnxeVL8v8dFnqxSD8qEEdRfXk1SDM6JzNqcERbcGYj9tMrDQBYV9cjgnunFIg==",
+      "version": "1.2.2",
+      "resolved": "https://registry.npmjs.org/tinyexec/-/tinyexec-1.2.2.tgz",
+      "integrity": "sha512-M/Q0B2cp4K7kynaT/vnED1j8TlLY+Pp7C6Wl2bl/7u/F0mUVwdyOpwomQb8JpYLitHUssAJRmLZdMCGsrx7i+g==",
       "license": "MIT",
       "engines": {
         "node": ">=18"
@@ -5786,26 +5873,6 @@
         "url": "https://github.com/sponsors/wooorm"
       }
     },
-    "node_modules/tsconfck": {
-      "version": "3.1.6",
-      "resolved": "https://registry.npmjs.org/tsconfck/-/tsconfck-3.1.6.tgz",
-      "integrity": "sha512-ks6Vjr/jEw0P1gmOVwutM3B7fWxoWBL2KRDb1JfqGVawBmO5UsvmWOQFGHBPl5yxYz4eERr19E6L7NMv+Fej4w==",
-      "license": "MIT",
-      "bin": {
-        "tsconfck": "bin/tsconfck.js"
-      },
-      "engines": {
-        "node": "^18 || >=20"
-      },
-      "peerDependencies": {
-        "typescript": "^5.0.0"
-      },
-      "peerDependenciesMeta": {
-        "typescript": {
-          "optional": true
-        }
-      }
-    },
     "node_modules/tslib": {
       "version": "2.8.1",
       "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz",
@@ -6004,16 +6071,16 @@
       }
     },
     "node_modules/unstorage": {
-      "version": "1.17.4",
-      "resolved": "https://registry.npmjs.org/unstorage/-/unstorage-1.17.4.tgz",
-      "integrity": "sha512-fHK0yNg38tBiJKp/Vgsq4j0JEsCmgqH58HAn707S7zGkArbZsVr/CwINoi+nh3h98BRCwKvx1K3Xg9u3VV83sw==",
+      "version": "1.17.5",
+      "resolved": "https://registry.npmjs.org/unstorage/-/unstorage-1.17.5.tgz",
+      "integrity": "sha512-0i3iqvRfx29hkNntHyQvJTpf5W9dQ9ZadSoRU8+xVlhVtT7jAX57fazYO9EHvcRCfBCyi5YRya7XCDOsbTgkPg==",
       "license": "MIT",
       "dependencies": {
         "anymatch": "^3.1.3",
         "chokidar": "^5.0.0",
         "destr": "^2.0.5",
-        "h3": "^1.15.5",
-        "lru-cache": "^11.2.0",
+        "h3": "^1.15.10",
+        "lru-cache": "^11.2.7",
         "node-fetch-native": "^1.6.7",
         "ofetch": "^1.5.1",
         "ufo": "^1.6.3"
@@ -6148,9 +6215,9 @@
       }
     },
     "node_modules/vite": {
-      "version": "7.3.1",
-      "resolved": "https://registry.npmjs.org/vite/-/vite-7.3.1.tgz",
-      "integrity": "sha512-w+N7Hifpc3gRjZ63vYBXA56dvvRlNWRczTdmCBBa+CotUzAPf5b7YMdMR/8CQoeYE5LX3W4wj6RYTgonm1b9DA==",
+      "version": "7.3.3",
+      "resolved": "https://registry.npmjs.org/vite/-/vite-7.3.3.tgz",
+      "integrity": "sha512-/4XH147Ui7OGTjg3HbdWe5arnZQSbfuRzdr9Ec7TQi5I7R+ir0Rlc9GIvD4v0XZurELqA035KVXJXpR61xhiTA==",
       "license": "MIT",
       "dependencies": {
         "esbuild": "^0.27.0",
diff --git a/docs/src/grammars/LICENSE-latte b/docs/src/grammars/LICENSE-latte
new file mode 100644
index 00000000..04361168
--- /dev/null
+++ b/docs/src/grammars/LICENSE-latte
@@ -0,0 +1,21 @@
+MIT License
+
+Copyright (c) 2023 Přemysl Karbula
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
diff --git a/docs/src/grammars/latte.tmLanguage.json b/docs/src/grammars/latte.tmLanguage.json
new file mode 100644
index 00000000..02e79ff1
--- /dev/null
+++ b/docs/src/grammars/latte.tmLanguage.json
@@ -0,0 +1,108 @@
+{
+	"fileTypes": [
+		"latte"
+	],
+	"name": "Latte",
+	"patterns": [
+		{
+			"begin": "\\{\\*",
+			"end": "\\*\\}",
+			"name": "comment.block.latte"
+		},
+		{
+			"begin": "\\{(\\{)?",
+			"beginCaptures": {
+				"0": {
+					"name": "punctuation.definition.tag.begin.latte"
+				}
+			},
+			"end": "\\}(\\})?",
+			"endCaptures": {
+				"0": {
+					"name": "punctuation.definition.tag.end.latte"
+				}
+			},
+			"name": "source.latte",
+			"patterns": [
+				{
+					"match": "(?<=\\{)(\\![^}]*?)",
+					"name": "keyword.latte"
+				},
+				{
+					"match": "\\b((0(x|X)[0-9a-fA-F]*)|(([0-9]+\\.?[0-9]*)|(\\.[0-9]+))((e|E)(\\+|-)?[0-9]+)?)\\b",
+					"name": "constant.numeric.latte"
+				},
+				{
+					"match": "(?i)true|false|null",
+					"name": "constant.language.latte"
+				},
+				{
+					"captures": {
+						"1": {
+							"name": "keyword.control.single.latte"
+						},
+						"2": {
+							"patterns": [
+								{
+									"include": "source.php#php-types"
+								}
+							]
+						}
+					},
+					"match": "(?<=\\{)(varType|var)\\s+([^\\$][^\\s]+\\b)"
+				},
+				{
+					"match": "(?i)(?<=\\{)/?([a-z0-9_]+)\\s*",
+					"name": "keyword.control.latte"
+				},
+				{
+					"match": "(?i)(?<=\\s)(\\!|/|===|as|and|&&|or|\\|\\||\\+\\+|\\-\\-|==|<=>|>=|<=)\\s?",
+					"name": "keyword.operator.latte"
+				},
+				{
+					"match": "->",
+					"name": "keyword.operator.latte"
+				},
+				{
+					"captures": {
+						"1": {
+							"name": "keyword.other.latte"
+						},
+						"2": {
+							"name": "keyword.other.latte"
+						}
+					},
+					"match": "(\\|)(\\w+)(?:\\:([^\\|\\}]+))*?"
+				},
+				{
+					"name": "variable.other.latte",
+					"include": "#variable-name"
+				},
+				{
+					"name": "string.quoted.single.latte",
+					"include": "source.php#string-single-quoted"
+				},
+				{
+					"name": "string.quoted.double.latte",
+					"include": "source.php#string-double-quoted"
+				}
+			]
+		},
+		{
+			"include": "text.html.basic"
+		}
+	],
+	"repository": {
+		"variable-name": {
+			"patterns": [
+				{
+					"name": "variable.other.latte",
+					"match": "\\$[a-zA-Z_\\x80-\\xff][a-zA-Z0-9_\\x80-\\xff]*"
+				}
+			]
+		}
+	},
+	"scopeName": "source.latte"
+}
+
+
