@@ -133,7 +170,7 @@ export default function PageWrapper({ children }) {
### Markdown Components
-Components in `components/markdown/` override default Markdown element rendering:
+Components in `src/markdown/` override default Markdown element rendering:
- `Heading.tsx` - Custom heading rendering (h1-h6)
- `CodeBlock.tsx` - Custom code block rendering with syntax highlighting
@@ -148,25 +185,66 @@ Files in `public/` are copied directly to the build output. Reference them with
## Theming
-Scratch uses custom prose styling defined in `tailwind.css` for markdown content. The default template includes:
+Scratch uses [Tailwind Typography](https://github.com/tailwindlabs/tailwindcss-typography) for markdown styling. The `prose` class is applied via PageWrapper.
+
+### Customizing Typography
+
+- **Size variants**: Add `prose-sm`, `prose-lg`, `prose-xl` in PageWrapper.jsx
+- **Color themes**: Add `prose-slate`, `prose-zinc`, `prose-neutral`, etc.
-- `scratch-prose` class for typography styling
-- Dark mode support (follows system preference via `.dark` class)
+### Overriding Prose Styling (No Custom Component)
-### Customizing the Theme
+Tailwind Typography supports element modifiers to override styling for specific element types directly in `PageWrapper.jsx`:
-The `tailwind.css` file contains all prose styling for markdown elements. You can customize:
+```jsx
+
+```
-- Headings (h1-h4), paragraphs, links, lists
-- Code blocks and inline code
-- Blockquotes, tables, images
-- Light and dark mode colors
+Available element modifiers:
+- `prose-headings:` - all headings (h1-h6)
+- `prose-h1:`, `prose-h2:`, etc. - specific heading levels
+- `prose-a:` - links
+- `prose-p:` - paragraphs
+- `prose-blockquote:` - blockquotes
+- `prose-code:` - inline code
+- `prose-pre:` - code blocks
+- `prose-ol:`, `prose-ul:`, `prose-li:` - lists
+- `prose-table:`, `prose-th:`, `prose-td:` - tables
+- `prose-img:`, `prose-figure:`, `prose-figcaption:` - images
+
+You can also add CSS overrides in `src/tailwind.css`:
+```css
+.prose a {
+ @apply text-blue-600 hover:text-blue-800 no-underline;
+}
+```
-Simply edit the `.scratch-prose` rules in `tailwind.css` to match your design.
+### Overriding with Custom Components
-### Dark Mode
+For more complex overrides (adding interactivity, conditional logic), create a custom component in `src/markdown/`:
+
+1. Create/edit a component (e.g., `Link.tsx`)
+2. Export from `src/markdown/index.ts` and add to `MDXComponents`
+
+Example:
+```tsx
+// src/markdown/Link.tsx
+export default function Link({ href, children, ...props }) {
+ const isExternal = href?.startsWith('http');
+ return (
+
+ {children}
+
+ );
+}
+```
-Dark mode is enabled by default and follows system preferences. The `PageWrapper` component uses the `scratch-prose` class, and dark mode styles are automatically applied when the `.dark` class is present on a parent element.
+Use `not-prose` class to exclude elements from typography styling.
## Generated Files
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..38eedd1
--- /dev/null
+++ b/README.md
@@ -0,0 +1,7 @@
+
+
+
+
+# scratch.dev
+
+Website for the [Scratch](https://scratch.dev) project
diff --git a/bun.lock b/bun.lock
new file mode 100644
index 0000000..18a0122
--- /dev/null
+++ b/bun.lock
@@ -0,0 +1,184 @@
+{
+ "lockfileVersion": 1,
+ "configVersion": 1,
+ "workspaces": {
+ "": {
+ "name": "scratch.dev",
+ "dependencies": {
+ "@mdx-js/react": "latest",
+ "@tailwindcss/cli": "latest",
+ "@tailwindcss/typography": "latest",
+ "react": "latest",
+ "react-dom": "latest",
+ "tailwindcss": "latest",
+ },
+ },
+ },
+ "packages": {
+ "@jridgewell/gen-mapping": ["@jridgewell/gen-mapping@0.3.13", "", { "dependencies": { "@jridgewell/sourcemap-codec": "^1.5.0", "@jridgewell/trace-mapping": "^0.3.24" } }, "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA=="],
+
+ "@jridgewell/remapping": ["@jridgewell/remapping@2.3.5", "", { "dependencies": { "@jridgewell/gen-mapping": "^0.3.5", "@jridgewell/trace-mapping": "^0.3.24" } }, "sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ=="],
+
+ "@jridgewell/resolve-uri": ["@jridgewell/resolve-uri@3.1.2", "", {}, "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw=="],
+
+ "@jridgewell/sourcemap-codec": ["@jridgewell/sourcemap-codec@1.5.5", "", {}, "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og=="],
+
+ "@jridgewell/trace-mapping": ["@jridgewell/trace-mapping@0.3.31", "", { "dependencies": { "@jridgewell/resolve-uri": "^3.1.0", "@jridgewell/sourcemap-codec": "^1.4.14" } }, "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw=="],
+
+ "@mdx-js/react": ["@mdx-js/react@3.1.1", "", { "dependencies": { "@types/mdx": "^2.0.0" }, "peerDependencies": { "@types/react": ">=16", "react": ">=16" } }, "sha512-f++rKLQgUVYDAtECQ6fn/is15GkEH9+nZPM3MS0RcxVqoTfawHvDlSCH7JbMhAM6uJ32v3eXLvLmLvjGu7PTQw=="],
+
+ "@parcel/watcher": ["@parcel/watcher@2.5.1", "", { "dependencies": { "detect-libc": "^1.0.3", "is-glob": "^4.0.3", "micromatch": "^4.0.5", "node-addon-api": "^7.0.0" }, "optionalDependencies": { "@parcel/watcher-android-arm64": "2.5.1", "@parcel/watcher-darwin-arm64": "2.5.1", "@parcel/watcher-darwin-x64": "2.5.1", "@parcel/watcher-freebsd-x64": "2.5.1", "@parcel/watcher-linux-arm-glibc": "2.5.1", "@parcel/watcher-linux-arm-musl": "2.5.1", "@parcel/watcher-linux-arm64-glibc": "2.5.1", "@parcel/watcher-linux-arm64-musl": "2.5.1", "@parcel/watcher-linux-x64-glibc": "2.5.1", "@parcel/watcher-linux-x64-musl": "2.5.1", "@parcel/watcher-win32-arm64": "2.5.1", "@parcel/watcher-win32-ia32": "2.5.1", "@parcel/watcher-win32-x64": "2.5.1" } }, "sha512-dfUnCxiN9H4ap84DvD2ubjw+3vUNpstxa0TneY/Paat8a3R4uQZDLSvWjmznAY/DoahqTHl9V46HF/Zs3F29pg=="],
+
+ "@parcel/watcher-android-arm64": ["@parcel/watcher-android-arm64@2.5.1", "", { "os": "android", "cpu": "arm64" }, "sha512-KF8+j9nNbUN8vzOFDpRMsaKBHZ/mcjEjMToVMJOhTozkDonQFFrRcfdLWn6yWKCmJKmdVxSgHiYvTCef4/qcBA=="],
+
+ "@parcel/watcher-darwin-arm64": ["@parcel/watcher-darwin-arm64@2.5.1", "", { "os": "darwin", "cpu": "arm64" }, "sha512-eAzPv5osDmZyBhou8PoF4i6RQXAfeKL9tjb3QzYuccXFMQU0ruIc/POh30ePnaOyD1UXdlKguHBmsTs53tVoPw=="],
+
+ "@parcel/watcher-darwin-x64": ["@parcel/watcher-darwin-x64@2.5.1", "", { "os": "darwin", "cpu": "x64" }, "sha512-1ZXDthrnNmwv10A0/3AJNZ9JGlzrF82i3gNQcWOzd7nJ8aj+ILyW1MTxVk35Db0u91oD5Nlk9MBiujMlwmeXZg=="],
+
+ "@parcel/watcher-freebsd-x64": ["@parcel/watcher-freebsd-x64@2.5.1", "", { "os": "freebsd", "cpu": "x64" }, "sha512-SI4eljM7Flp9yPuKi8W0ird8TI/JK6CSxju3NojVI6BjHsTyK7zxA9urjVjEKJ5MBYC+bLmMcbAWlZ+rFkLpJQ=="],
+
+ "@parcel/watcher-linux-arm-glibc": ["@parcel/watcher-linux-arm-glibc@2.5.1", "", { "os": "linux", "cpu": "arm" }, "sha512-RCdZlEyTs8geyBkkcnPWvtXLY44BCeZKmGYRtSgtwwnHR4dxfHRG3gR99XdMEdQ7KeiDdasJwwvNSF5jKtDwdA=="],
+
+ "@parcel/watcher-linux-arm-musl": ["@parcel/watcher-linux-arm-musl@2.5.1", "", { "os": "linux", "cpu": "arm" }, "sha512-6E+m/Mm1t1yhB8X412stiKFG3XykmgdIOqhjWj+VL8oHkKABfu/gjFj8DvLrYVHSBNC+/u5PeNrujiSQ1zwd1Q=="],
+
+ "@parcel/watcher-linux-arm64-glibc": ["@parcel/watcher-linux-arm64-glibc@2.5.1", "", { "os": "linux", "cpu": "arm64" }, "sha512-LrGp+f02yU3BN9A+DGuY3v3bmnFUggAITBGriZHUREfNEzZh/GO06FF5u2kx8x+GBEUYfyTGamol4j3m9ANe8w=="],
+
+ "@parcel/watcher-linux-arm64-musl": ["@parcel/watcher-linux-arm64-musl@2.5.1", "", { "os": "linux", "cpu": "arm64" }, "sha512-cFOjABi92pMYRXS7AcQv9/M1YuKRw8SZniCDw0ssQb/noPkRzA+HBDkwmyOJYp5wXcsTrhxO0zq1U11cK9jsFg=="],
+
+ "@parcel/watcher-linux-x64-glibc": ["@parcel/watcher-linux-x64-glibc@2.5.1", "", { "os": "linux", "cpu": "x64" }, "sha512-GcESn8NZySmfwlTsIur+49yDqSny2IhPeZfXunQi48DMugKeZ7uy1FX83pO0X22sHntJ4Ub+9k34XQCX+oHt2A=="],
+
+ "@parcel/watcher-linux-x64-musl": ["@parcel/watcher-linux-x64-musl@2.5.1", "", { "os": "linux", "cpu": "x64" }, "sha512-n0E2EQbatQ3bXhcH2D1XIAANAcTZkQICBPVaxMeaCVBtOpBZpWJuf7LwyWPSBDITb7In8mqQgJ7gH8CILCURXg=="],
+
+ "@parcel/watcher-win32-arm64": ["@parcel/watcher-win32-arm64@2.5.1", "", { "os": "win32", "cpu": "arm64" }, "sha512-RFzklRvmc3PkjKjry3hLF9wD7ppR4AKcWNzH7kXR7GUe0Igb3Nz8fyPwtZCSquGrhU5HhUNDr/mKBqj7tqA2Vw=="],
+
+ "@parcel/watcher-win32-ia32": ["@parcel/watcher-win32-ia32@2.5.1", "", { "os": "win32", "cpu": "ia32" }, "sha512-c2KkcVN+NJmuA7CGlaGD1qJh1cLfDnQsHjE89E60vUEMlqduHGCdCLJCID5geFVM0dOtA3ZiIO8BoEQmzQVfpQ=="],
+
+ "@parcel/watcher-win32-x64": ["@parcel/watcher-win32-x64@2.5.1", "", { "os": "win32", "cpu": "x64" }, "sha512-9lHBdJITeNR++EvSQVUcaZoWupyHfXe1jZvGZ06O/5MflPcuPLtEphScIBL+AiCWBO46tDSHzWyD0uDmmZqsgA=="],
+
+ "@tailwindcss/cli": ["@tailwindcss/cli@4.1.18", "", { "dependencies": { "@parcel/watcher": "^2.5.1", "@tailwindcss/node": "4.1.18", "@tailwindcss/oxide": "4.1.18", "enhanced-resolve": "^5.18.3", "mri": "^1.2.0", "picocolors": "^1.1.1", "tailwindcss": "4.1.18" }, "bin": { "tailwindcss": "dist/index.mjs" } }, "sha512-sMZ+lZbDyxwjD2E0L7oRUjJ01Ffjtme5OtjvvnC+cV4CEDcbqzbp25TCpxHj6kWLU9+DlqJOiNgSOgctC2aZmg=="],
+
+ "@tailwindcss/node": ["@tailwindcss/node@4.1.18", "", { "dependencies": { "@jridgewell/remapping": "^2.3.4", "enhanced-resolve": "^5.18.3", "jiti": "^2.6.1", "lightningcss": "1.30.2", "magic-string": "^0.30.21", "source-map-js": "^1.2.1", "tailwindcss": "4.1.18" } }, "sha512-DoR7U1P7iYhw16qJ49fgXUlry1t4CpXeErJHnQ44JgTSKMaZUdf17cfn5mHchfJ4KRBZRFA/Coo+MUF5+gOaCQ=="],
+
+ "@tailwindcss/oxide": ["@tailwindcss/oxide@4.1.18", "", { "optionalDependencies": { "@tailwindcss/oxide-android-arm64": "4.1.18", "@tailwindcss/oxide-darwin-arm64": "4.1.18", "@tailwindcss/oxide-darwin-x64": "4.1.18", "@tailwindcss/oxide-freebsd-x64": "4.1.18", "@tailwindcss/oxide-linux-arm-gnueabihf": "4.1.18", "@tailwindcss/oxide-linux-arm64-gnu": "4.1.18", "@tailwindcss/oxide-linux-arm64-musl": "4.1.18", "@tailwindcss/oxide-linux-x64-gnu": "4.1.18", "@tailwindcss/oxide-linux-x64-musl": "4.1.18", "@tailwindcss/oxide-wasm32-wasi": "4.1.18", "@tailwindcss/oxide-win32-arm64-msvc": "4.1.18", "@tailwindcss/oxide-win32-x64-msvc": "4.1.18" } }, "sha512-EgCR5tTS5bUSKQgzeMClT6iCY3ToqE1y+ZB0AKldj809QXk1Y+3jB0upOYZrn9aGIzPtUsP7sX4QQ4XtjBB95A=="],
+
+ "@tailwindcss/oxide-android-arm64": ["@tailwindcss/oxide-android-arm64@4.1.18", "", { "os": "android", "cpu": "arm64" }, "sha512-dJHz7+Ugr9U/diKJA0W6N/6/cjI+ZTAoxPf9Iz9BFRF2GzEX8IvXxFIi/dZBloVJX/MZGvRuFA9rqwdiIEZQ0Q=="],
+
+ "@tailwindcss/oxide-darwin-arm64": ["@tailwindcss/oxide-darwin-arm64@4.1.18", "", { "os": "darwin", "cpu": "arm64" }, "sha512-Gc2q4Qhs660bhjyBSKgq6BYvwDz4G+BuyJ5H1xfhmDR3D8HnHCmT/BSkvSL0vQLy/nkMLY20PQ2OoYMO15Jd0A=="],
+
+ "@tailwindcss/oxide-darwin-x64": ["@tailwindcss/oxide-darwin-x64@4.1.18", "", { "os": "darwin", "cpu": "x64" }, "sha512-FL5oxr2xQsFrc3X9o1fjHKBYBMD1QZNyc1Xzw/h5Qu4XnEBi3dZn96HcHm41c/euGV+GRiXFfh2hUCyKi/e+yw=="],
+
+ "@tailwindcss/oxide-freebsd-x64": ["@tailwindcss/oxide-freebsd-x64@4.1.18", "", { "os": "freebsd", "cpu": "x64" }, "sha512-Fj+RHgu5bDodmV1dM9yAxlfJwkkWvLiRjbhuO2LEtwtlYlBgiAT4x/j5wQr1tC3SANAgD+0YcmWVrj8R9trVMA=="],
+
+ "@tailwindcss/oxide-linux-arm-gnueabihf": ["@tailwindcss/oxide-linux-arm-gnueabihf@4.1.18", "", { "os": "linux", "cpu": "arm" }, "sha512-Fp+Wzk/Ws4dZn+LV2Nqx3IilnhH51YZoRaYHQsVq3RQvEl+71VGKFpkfHrLM/Li+kt5c0DJe/bHXK1eHgDmdiA=="],
+
+ "@tailwindcss/oxide-linux-arm64-gnu": ["@tailwindcss/oxide-linux-arm64-gnu@4.1.18", "", { "os": "linux", "cpu": "arm64" }, "sha512-S0n3jboLysNbh55Vrt7pk9wgpyTTPD0fdQeh7wQfMqLPM/Hrxi+dVsLsPrycQjGKEQk85Kgbx+6+QnYNiHalnw=="],
+
+ "@tailwindcss/oxide-linux-arm64-musl": ["@tailwindcss/oxide-linux-arm64-musl@4.1.18", "", { "os": "linux", "cpu": "arm64" }, "sha512-1px92582HkPQlaaCkdRcio71p8bc8i/ap5807tPRDK/uw953cauQBT8c5tVGkOwrHMfc2Yh6UuxaH4vtTjGvHg=="],
+
+ "@tailwindcss/oxide-linux-x64-gnu": ["@tailwindcss/oxide-linux-x64-gnu@4.1.18", "", { "os": "linux", "cpu": "x64" }, "sha512-v3gyT0ivkfBLoZGF9LyHmts0Isc8jHZyVcbzio6Wpzifg/+5ZJpDiRiUhDLkcr7f/r38SWNe7ucxmGW3j3Kb/g=="],
+
+ "@tailwindcss/oxide-linux-x64-musl": ["@tailwindcss/oxide-linux-x64-musl@4.1.18", "", { "os": "linux", "cpu": "x64" }, "sha512-bhJ2y2OQNlcRwwgOAGMY0xTFStt4/wyU6pvI6LSuZpRgKQwxTec0/3Scu91O8ir7qCR3AuepQKLU/kX99FouqQ=="],
+
+ "@tailwindcss/oxide-wasm32-wasi": ["@tailwindcss/oxide-wasm32-wasi@4.1.18", "", { "dependencies": { "@emnapi/core": "^1.7.1", "@emnapi/runtime": "^1.7.1", "@emnapi/wasi-threads": "^1.1.0", "@napi-rs/wasm-runtime": "^1.1.0", "@tybys/wasm-util": "^0.10.1", "tslib": "^2.4.0" }, "cpu": "none" }, "sha512-LffYTvPjODiP6PT16oNeUQJzNVyJl1cjIebq/rWWBF+3eDst5JGEFSc5cWxyRCJ0Mxl+KyIkqRxk1XPEs9x8TA=="],
+
+ "@tailwindcss/oxide-win32-arm64-msvc": ["@tailwindcss/oxide-win32-arm64-msvc@4.1.18", "", { "os": "win32", "cpu": "arm64" }, "sha512-HjSA7mr9HmC8fu6bdsZvZ+dhjyGCLdotjVOgLA2vEqxEBZaQo9YTX4kwgEvPCpRh8o4uWc4J/wEoFzhEmjvPbA=="],
+
+ "@tailwindcss/oxide-win32-x64-msvc": ["@tailwindcss/oxide-win32-x64-msvc@4.1.18", "", { "os": "win32", "cpu": "x64" }, "sha512-bJWbyYpUlqamC8dpR7pfjA0I7vdF6t5VpUGMWRkXVE3AXgIZjYUYAK7II1GNaxR8J1SSrSrppRar8G++JekE3Q=="],
+
+ "@tailwindcss/typography": ["@tailwindcss/typography@0.5.19", "", { "dependencies": { "postcss-selector-parser": "6.0.10" }, "peerDependencies": { "tailwindcss": ">=3.0.0 || insiders || >=4.0.0-alpha.20 || >=4.0.0-beta.1" } }, "sha512-w31dd8HOx3k9vPtcQh5QHP9GwKcgbMp87j58qi6xgiBnFFtKEAgCWnDw4qUT8aHwkCp8bKvb/KGKWWHedP0AAg=="],
+
+ "@types/mdx": ["@types/mdx@2.0.13", "", {}, "sha512-+OWZQfAYyio6YkJb3HLxDrvnx6SWWDbC0zVPfBRzUk0/nqoDyf6dNxQi3eArPe8rJ473nobTMQ/8Zk+LxJ+Yuw=="],
+
+ "@types/react": ["@types/react@19.2.7", "", { "dependencies": { "csstype": "^3.2.2" } }, "sha512-MWtvHrGZLFttgeEj28VXHxpmwYbor/ATPYbBfSFZEIRK0ecCFLl2Qo55z52Hss+UV9CRN7trSeq1zbgx7YDWWg=="],
+
+ "braces": ["braces@3.0.3", "", { "dependencies": { "fill-range": "^7.1.1" } }, "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA=="],
+
+ "cssesc": ["cssesc@3.0.0", "", { "bin": { "cssesc": "bin/cssesc" } }, "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg=="],
+
+ "csstype": ["csstype@3.2.3", "", {}, "sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ=="],
+
+ "detect-libc": ["detect-libc@1.0.3", "", { "bin": { "detect-libc": "./bin/detect-libc.js" } }, "sha512-pGjwhsmsp4kL2RTz08wcOlGN83otlqHeD/Z5T8GXZB+/YcpQ/dgo+lbU8ZsGxV0HIvqqxo9l7mqYwyYMD9bKDg=="],
+
+ "enhanced-resolve": ["enhanced-resolve@5.18.4", "", { "dependencies": { "graceful-fs": "^4.2.4", "tapable": "^2.2.0" } }, "sha512-LgQMM4WXU3QI+SYgEc2liRgznaD5ojbmY3sb8LxyguVkIg5FxdpTkvk72te2R38/TGKxH634oLxXRGY6d7AP+Q=="],
+
+ "fill-range": ["fill-range@7.1.1", "", { "dependencies": { "to-regex-range": "^5.0.1" } }, "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg=="],
+
+ "graceful-fs": ["graceful-fs@4.2.11", "", {}, "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ=="],
+
+ "is-extglob": ["is-extglob@2.1.1", "", {}, "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ=="],
+
+ "is-glob": ["is-glob@4.0.3", "", { "dependencies": { "is-extglob": "^2.1.1" } }, "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg=="],
+
+ "is-number": ["is-number@7.0.0", "", {}, "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng=="],
+
+ "jiti": ["jiti@2.6.1", "", { "bin": { "jiti": "lib/jiti-cli.mjs" } }, "sha512-ekilCSN1jwRvIbgeg/57YFh8qQDNbwDb9xT/qu2DAHbFFZUicIl4ygVaAvzveMhMVr3LnpSKTNnwt8PoOfmKhQ=="],
+
+ "lightningcss": ["lightningcss@1.30.2", "", { "dependencies": { "detect-libc": "^2.0.3" }, "optionalDependencies": { "lightningcss-android-arm64": "1.30.2", "lightningcss-darwin-arm64": "1.30.2", "lightningcss-darwin-x64": "1.30.2", "lightningcss-freebsd-x64": "1.30.2", "lightningcss-linux-arm-gnueabihf": "1.30.2", "lightningcss-linux-arm64-gnu": "1.30.2", "lightningcss-linux-arm64-musl": "1.30.2", "lightningcss-linux-x64-gnu": "1.30.2", "lightningcss-linux-x64-musl": "1.30.2", "lightningcss-win32-arm64-msvc": "1.30.2", "lightningcss-win32-x64-msvc": "1.30.2" } }, "sha512-utfs7Pr5uJyyvDETitgsaqSyjCb2qNRAtuqUeWIAKztsOYdcACf2KtARYXg2pSvhkt+9NfoaNY7fxjl6nuMjIQ=="],
+
+ "lightningcss-android-arm64": ["lightningcss-android-arm64@1.30.2", "", { "os": "android", "cpu": "arm64" }, "sha512-BH9sEdOCahSgmkVhBLeU7Hc9DWeZ1Eb6wNS6Da8igvUwAe0sqROHddIlvU06q3WyXVEOYDZ6ykBZQnjTbmo4+A=="],
+
+ "lightningcss-darwin-arm64": ["lightningcss-darwin-arm64@1.30.2", "", { "os": "darwin", "cpu": "arm64" }, "sha512-ylTcDJBN3Hp21TdhRT5zBOIi73P6/W0qwvlFEk22fkdXchtNTOU4Qc37SkzV+EKYxLouZ6M4LG9NfZ1qkhhBWA=="],
+
+ "lightningcss-darwin-x64": ["lightningcss-darwin-x64@1.30.2", "", { "os": "darwin", "cpu": "x64" }, "sha512-oBZgKchomuDYxr7ilwLcyms6BCyLn0z8J0+ZZmfpjwg9fRVZIR5/GMXd7r9RH94iDhld3UmSjBM6nXWM2TfZTQ=="],
+
+ "lightningcss-freebsd-x64": ["lightningcss-freebsd-x64@1.30.2", "", { "os": "freebsd", "cpu": "x64" }, "sha512-c2bH6xTrf4BDpK8MoGG4Bd6zAMZDAXS569UxCAGcA7IKbHNMlhGQ89eRmvpIUGfKWNVdbhSbkQaWhEoMGmGslA=="],
+
+ "lightningcss-linux-arm-gnueabihf": ["lightningcss-linux-arm-gnueabihf@1.30.2", "", { "os": "linux", "cpu": "arm" }, "sha512-eVdpxh4wYcm0PofJIZVuYuLiqBIakQ9uFZmipf6LF/HRj5Bgm0eb3qL/mr1smyXIS1twwOxNWndd8z0E374hiA=="],
+
+ "lightningcss-linux-arm64-gnu": ["lightningcss-linux-arm64-gnu@1.30.2", "", { "os": "linux", "cpu": "arm64" }, "sha512-UK65WJAbwIJbiBFXpxrbTNArtfuznvxAJw4Q2ZGlU8kPeDIWEX1dg3rn2veBVUylA2Ezg89ktszWbaQnxD/e3A=="],
+
+ "lightningcss-linux-arm64-musl": ["lightningcss-linux-arm64-musl@1.30.2", "", { "os": "linux", "cpu": "arm64" }, "sha512-5Vh9dGeblpTxWHpOx8iauV02popZDsCYMPIgiuw97OJ5uaDsL86cnqSFs5LZkG3ghHoX5isLgWzMs+eD1YzrnA=="],
+
+ "lightningcss-linux-x64-gnu": ["lightningcss-linux-x64-gnu@1.30.2", "", { "os": "linux", "cpu": "x64" }, "sha512-Cfd46gdmj1vQ+lR6VRTTadNHu6ALuw2pKR9lYq4FnhvgBc4zWY1EtZcAc6EffShbb1MFrIPfLDXD6Xprbnni4w=="],
+
+ "lightningcss-linux-x64-musl": ["lightningcss-linux-x64-musl@1.30.2", "", { "os": "linux", "cpu": "x64" }, "sha512-XJaLUUFXb6/QG2lGIW6aIk6jKdtjtcffUT0NKvIqhSBY3hh9Ch+1LCeH80dR9q9LBjG3ewbDjnumefsLsP6aiA=="],
+
+ "lightningcss-win32-arm64-msvc": ["lightningcss-win32-arm64-msvc@1.30.2", "", { "os": "win32", "cpu": "arm64" }, "sha512-FZn+vaj7zLv//D/192WFFVA0RgHawIcHqLX9xuWiQt7P0PtdFEVaxgF9rjM/IRYHQXNnk61/H/gb2Ei+kUQ4xQ=="],
+
+ "lightningcss-win32-x64-msvc": ["lightningcss-win32-x64-msvc@1.30.2", "", { "os": "win32", "cpu": "x64" }, "sha512-5g1yc73p+iAkid5phb4oVFMB45417DkRevRbt/El/gKXJk4jid+vPFF/AXbxn05Aky8PapwzZrdJShv5C0avjw=="],
+
+ "magic-string": ["magic-string@0.30.21", "", { "dependencies": { "@jridgewell/sourcemap-codec": "^1.5.5" } }, "sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ=="],
+
+ "micromatch": ["micromatch@4.0.8", "", { "dependencies": { "braces": "^3.0.3", "picomatch": "^2.3.1" } }, "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA=="],
+
+ "mri": ["mri@1.2.0", "", {}, "sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA=="],
+
+ "node-addon-api": ["node-addon-api@7.1.1", "", {}, "sha512-5m3bsyrjFWE1xf7nz7YXdN4udnVtXK6/Yfgn5qnahL6bCkf2yKt4k3nuTKAtT4r3IG8JNR2ncsIMdZuAzJjHQQ=="],
+
+ "picocolors": ["picocolors@1.1.1", "", {}, "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA=="],
+
+ "picomatch": ["picomatch@2.3.1", "", {}, "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA=="],
+
+ "postcss-selector-parser": ["postcss-selector-parser@6.0.10", "", { "dependencies": { "cssesc": "^3.0.0", "util-deprecate": "^1.0.2" } }, "sha512-IQ7TZdoaqbT+LCpShg46jnZVlhWD2w6iQYAcYXfHARZ7X1t/UGhhceQDs5X0cGqKvYlHNOuv7Oa1xmb0oQuA3w=="],
+
+ "react": ["react@19.2.3", "", {}, "sha512-Ku/hhYbVjOQnXDZFv2+RibmLFGwFdeeKHFcOTlrt7xplBnya5OGn/hIRDsqDiSUcfORsDC7MPxwork8jBwsIWA=="],
+
+ "react-dom": ["react-dom@19.2.3", "", { "dependencies": { "scheduler": "^0.27.0" }, "peerDependencies": { "react": "^19.2.3" } }, "sha512-yELu4WmLPw5Mr/lmeEpox5rw3RETacE++JgHqQzd2dg+YbJuat3jH4ingc+WPZhxaoFzdv9y33G+F7Nl5O0GBg=="],
+
+ "scheduler": ["scheduler@0.27.0", "", {}, "sha512-eNv+WrVbKu1f3vbYJT/xtiF5syA5HPIMtf9IgY/nKg0sWqzAUEvqY/xm7OcZc/qafLx/iO9FgOmeSAp4v5ti/Q=="],
+
+ "source-map-js": ["source-map-js@1.2.1", "", {}, "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA=="],
+
+ "tailwindcss": ["tailwindcss@4.1.18", "", {}, "sha512-4+Z+0yiYyEtUVCScyfHCxOYP06L5Ne+JiHhY2IjR2KWMIWhJOYZKLSGZaP5HkZ8+bY0cxfzwDE5uOmzFXyIwxw=="],
+
+ "tapable": ["tapable@2.3.0", "", {}, "sha512-g9ljZiwki/LfxmQADO3dEY1CbpmXT5Hm2fJ+QaGKwSXUylMybePR7/67YW7jOrrvjEgL1Fmz5kzyAjWVWLlucg=="],
+
+ "to-regex-range": ["to-regex-range@5.0.1", "", { "dependencies": { "is-number": "^7.0.0" } }, "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ=="],
+
+ "util-deprecate": ["util-deprecate@1.0.2", "", {}, "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw=="],
+
+ "@tailwindcss/oxide-wasm32-wasi/@emnapi/core": ["@emnapi/core@1.7.1", "", { "dependencies": { "@emnapi/wasi-threads": "1.1.0", "tslib": "^2.4.0" }, "bundled": true }, "sha512-o1uhUASyo921r2XtHYOHy7gdkGLge8ghBEQHMWmyJFoXlpU58kIrhhN3w26lpQb6dspetweapMn2CSNwQ8I4wg=="],
+
+ "@tailwindcss/oxide-wasm32-wasi/@emnapi/runtime": ["@emnapi/runtime@1.7.1", "", { "dependencies": { "tslib": "^2.4.0" }, "bundled": true }, "sha512-PVtJr5CmLwYAU9PZDMITZoR5iAOShYREoR45EyyLrbntV50mdePTgUn4AmOw90Ifcj+x2kRjdzr1HP3RrNiHGA=="],
+
+ "@tailwindcss/oxide-wasm32-wasi/@emnapi/wasi-threads": ["@emnapi/wasi-threads@1.1.0", "", { "dependencies": { "tslib": "^2.4.0" }, "bundled": true }, "sha512-WI0DdZ8xFSbgMjR1sFsKABJ/C5OnRrjT06JXbZKexJGrDuPTzZdDYfFlsgcCXCyf+suG5QU2e/y1Wo2V/OapLQ=="],
+
+ "@tailwindcss/oxide-wasm32-wasi/@napi-rs/wasm-runtime": ["@napi-rs/wasm-runtime@1.1.0", "", { "dependencies": { "@emnapi/core": "^1.7.1", "@emnapi/runtime": "^1.7.1", "@tybys/wasm-util": "^0.10.1" }, "bundled": true }, "sha512-Fq6DJW+Bb5jaWE69/qOE0D1TUN9+6uWhCeZpdnSBk14pjLcCWR7Q8n49PTSPHazM37JqrsdpEthXy2xn6jWWiA=="],
+
+ "@tailwindcss/oxide-wasm32-wasi/@tybys/wasm-util": ["@tybys/wasm-util@0.10.1", "", { "dependencies": { "tslib": "^2.4.0" }, "bundled": true }, "sha512-9tTaPJLSiejZKx+Bmog4uSubteqTvFrVrURwkmHixBo0G4seD0zUxp98E1DzUBJxLQ3NPwXrGKDiVjwx/DpPsg=="],
+
+ "@tailwindcss/oxide-wasm32-wasi/tslib": ["tslib@2.8.1", "", { "bundled": true }, "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w=="],
+
+ "lightningcss/detect-libc": ["detect-libc@2.1.2", "", {}, "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ=="],
+ }
+}
diff --git a/dist/_redirects b/dist/_redirects
deleted file mode 100644
index 0badd56..0000000
--- a/dist/_redirects
+++ /dev/null
@@ -1 +0,0 @@
-/install.sh https://raw.githubusercontent.com/scratch/scratch/main/install.sh 302
diff --git a/dist/favicon.svg b/dist/favicon.svg
deleted file mode 100644
index d350106..0000000
--- a/dist/favicon.svg
+++ /dev/null
@@ -1,198 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/dist/github-mark.svg b/dist/github-mark.svg
deleted file mode 100644
index 37fa923..0000000
--- a/dist/github-mark.svg
+++ /dev/null
@@ -1 +0,0 @@
-
\ No newline at end of file
diff --git a/dist/index-ym20sk5q.js b/dist/index-ym20sk5q.js
deleted file mode 100644
index b13e2e1..0000000
--- a/dist/index-ym20sk5q.js
+++ /dev/null
@@ -1,59 +0,0 @@
-var bU=Object.create;var{getPrototypeOf:SU,defineProperty:HH,getOwnPropertyNames:NU}=Object;var jU=Object.prototype.hasOwnProperty;var m0=(A,Y,G)=>{G=A!=null?bU(SU(A)):{};let H=Y||!A||!A.__esModule?HH(G,"default",{value:A,enumerable:!0}):G;for(let X of NU(A))if(!jU.call(H,X))HH(H,X,{get:()=>A[X],enumerable:!0});return H};var XH=(A,Y)=>()=>(Y||A((Y={exports:{}}).exports,Y),Y.exports);var zw=(A,Y)=>{for(var G in Y)HH(A,G,{get:Y[G],enumerable:!0,configurable:!0,set:(H)=>Y[G]=()=>H})};var wH=(A,Y)=>()=>(A&&(Y=A(A=0)),Y);var p0=XH((iU)=>{var qH=Symbol.for("react.transitional.element"),CU=Symbol.for("react.portal"),$U=Symbol.for("react.fragment"),xU=Symbol.for("react.strict_mode"),kU=Symbol.for("react.profiler"),_U=Symbol.for("react.consumer"),PU=Symbol.for("react.context"),gU=Symbol.for("react.forward_ref"),hU=Symbol.for("react.suspense"),EU=Symbol.for("react.memo"),Iw=Symbol.for("react.lazy"),yU=Symbol.for("react.activity"),Dw=Symbol.iterator;function vU(A){if(A===null||typeof A!=="object")return null;return A=Dw&&A[Dw]||A["@@iterator"],typeof A==="function"?A:null}var Ow={isMounted:function(){return!1},enqueueForceUpdate:function(){},enqueueReplaceState:function(){},enqueueSetState:function(){}},Kw=Object.assign,Tw={};function FY(A,Y,G){this.props=A,this.context=Y,this.refs=Tw,this.updater=G||Ow}FY.prototype.isReactComponent={};FY.prototype.setState=function(A,Y){if(typeof A!=="object"&&typeof A!=="function"&&A!=null)throw Error("takes an object of state variables to update or a function which returns an object of state variables.");this.updater.enqueueSetState(this,A,Y,"setState")};FY.prototype.forceUpdate=function(A){this.updater.enqueueForceUpdate(this,A,"forceUpdate")};function bw(){}bw.prototype=FY.prototype;function UH(A,Y,G){this.props=A,this.context=Y,this.refs=Tw,this.updater=G||Ow}var MH=UH.prototype=new bw;MH.constructor=UH;Kw(MH,FY.prototype);MH.isPureReactComponent=!0;var Qw=Array.isArray;function WH(){}var c={H:null,A:null,T:null,S:null},Sw=Object.prototype.hasOwnProperty;function JH(A,Y,G){var H=G.ref;return{$$typeof:qH,type:A,key:Y,ref:H!==void 0?H:null,props:G}}function uU(A,Y){return JH(A.type,Y,A.props)}function RH(A){return typeof A==="object"&&A!==null&&A.$$typeof===qH}function dU(A){var Y={"=":"=0",":":"=2"};return"$"+A.replace(/[=:]/g,function(G){return Y[G]})}var Fw=/\/+/g;function ZH(A,Y){return typeof A==="object"&&A!==null&&A.key!=null?dU(""+A.key):Y.toString(36)}function mU(A){switch(A.status){case"fulfilled":return A.value;case"rejected":throw A.reason;default:switch(typeof A.status==="string"?A.then(WH,WH):(A.status="pending",A.then(function(Y){A.status==="pending"&&(A.status="fulfilled",A.value=Y)},function(Y){A.status==="pending"&&(A.status="rejected",A.reason=Y)})),A.status){case"fulfilled":return A.value;case"rejected":throw A.reason}}throw A}function QY(A,Y,G,H,X){var w=typeof A;if(w==="undefined"||w==="boolean")A=null;var Z=!1;if(A===null)Z=!0;else switch(w){case"bigint":case"string":case"number":Z=!0;break;case"object":switch(A.$$typeof){case qH:case CU:Z=!0;break;case Iw:return Z=A._init,QY(Z(A._payload),Y,G,H,X)}}if(Z)return X=X(A),Z=H===""?"."+ZH(A,0):H,Qw(X)?(G="",Z!=null&&(G=Z.replace(Fw,"$&/")+"/"),QY(X,Y,G,"",function(R){return R})):X!=null&&(RH(X)&&(X=uU(X,G+(X.key==null||A&&A.key===X.key?"":(""+X.key).replace(Fw,"$&/")+"/")+Z)),Y.push(X)),1;Z=0;var W=H===""?".":H+":";if(Qw(A))for(var q=0;q
>>1,X=A[H];if(0>>1;HK4(W,G))qK4(R,W)?(A[H]=R,A[q]=G,H=q):(A[H]=W,A[Z]=G,H=Z);else if(qK4(R,G))A[H]=R,A[q]=G,H=q;else break A}}return Y}function K4(A,Y){var G=A.sortIndex-Y.sortIndex;return G!==0?G:A.id-Y.id}function S4(A){for(var Y=s0(KA);Y!==null;){if(Y.callback===null)j4(KA);else if(Y.startTime<=A)j4(KA),Y.sortIndex=Y.expirationTime,LH(YA,Y);else break;Y=s0(KA)}}function VH(A){if(L6=!1,S4(A),!B6)if(s0(YA)!==null)B6=!0,IY||(IY=!0,VY());else{var Y=s0(KA);Y!==null&&IH(VH,Y.startTime-A)}}function xw(){return FH?!0:r0()-$wA&&xw());){var H=x0.callback;if(typeof H==="function"){x0.callback=null,b4=x0.priorityLevel;var X=H(x0.expirationTime<=A);if(A=r0(),typeof X==="function"){x0.callback=X,S4(A),Y=!0;break Y}x0===s0(YA)&&j4(YA),S4(A)}else j4(YA);x0=s0(YA)}if(x0!==null)Y=!0;else{var w=s0(KA);w!==null&&IH(VH,w.startTime-A),Y=!1}}break A}finally{x0=null,b4=G,DH=!1}Y=void 0}}finally{Y?VY():IY=!1}}}function IH(A,Y){f6=jw(function(){A(r0())},Y)}var r0=void 0,fH,T4,zH,YA,KA,PM=1,x0=null,b4=3,DH=!1,B6=!1,L6=!1,FH=!1,jw,Cw,Nw,IY=!1,f6=-1,gM=5,$w=-1,VY,N4,QH,OH=5,KH=1,TH=4,OY=3,bH=2,SH=function(A){A.callback=null},NH=function(){return b4},jH=function(){FH=!0},KY=function(A,Y,G){var H=r0();switch(typeof G==="object"&&G!==null?(G=G.delay,G=typeof G==="number"&&0H?(A.sortIndex=G,LH(KA,A),s0(YA)===null&&A===s0(KA)&&(L6?(Cw(f6),f6=-1):L6=!0,IH(VH,G-H))):(A.sortIndex=X,LH(YA,A),B6||DH||(B6=!0,IY||(IY=!0,VY()))),A},CH;var kw=wH(()=>{if(typeof performance==="object"&&typeof performance.now==="function")fH=performance,r0=function(){return fH.now()};else T4=Date,zH=T4.now(),r0=function(){return T4.now()-zH};YA=[],KA=[],jw=typeof setTimeout==="function"?setTimeout:null,Cw=typeof clearTimeout==="function"?clearTimeout:null,Nw=typeof setImmediate<"u"?setImmediate:null;if(typeof Nw==="function")VY=function(){Nw(BH)};else if(typeof MessageChannel<"u")N4=new MessageChannel,QH=N4.port2,N4.port1.onmessage=BH,VY=function(){QH.postMessage(null)};else VY=function(){jw(BH,0)};CH=xw});var $H={};zw($H,{version:()=>rw,useFormStatus:()=>sw,useFormState:()=>pw,unstable_batchedUpdates:()=>iw,requestFormReset:()=>cw,preloadModule:()=>lw,preload:()=>mw,preinitModule:()=>dw,preinit:()=>uw,prefetchDNS:()=>vw,preconnect:()=>yw,flushSync:()=>Ew,createPortal:()=>hw,__DOM_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE:()=>gw});function Pw(A){var Y="https://react.dev/errors/"+A;if(1{_w=m0(p0(),1);R0={d:{f:TA,r:function(){throw Error(Pw(522))},D:TA,C:TA,L:TA,m:TA,X:TA,S:TA,M:TA},p:0,findDOMNode:null},EM=Symbol.for("react.portal");z6=_w.__CLIENT_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE;gw=R0});var tw=XH((OR,nw)=>{ow();function aw(){if(typeof __REACT_DEVTOOLS_GLOBAL_HOOK__>"u"||typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE!=="function")return;try{__REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE(aw)}catch(A){console.error(A)}}aw(),nw.exports=$H});var Gw={};zw(Gw,{version:()=>MU,hydrateRoot:()=>UU,createRoot:()=>qU});function F(A){var Y="https://react.dev/errors/"+A;if(1$Y||(A.current=L8[$Y],L8[$Y]=null,$Y--)}function l(A,Y){$Y++,L8[$Y]=A.current,A.current=Y}function WG(A,Y){switch(l(hA,Y),l(i6,A),l(t0,null),Y.nodeType){case 9:case 11:A=(A=Y.documentElement)?(A=A.namespaceURI)?wZ(A):0:0;break;default:if(A=Y.tagName,Y=Y.namespaceURI)Y=wZ(Y),A=rq(Y,A);else switch(A){case"svg":A=1;break;case"math":A=2;break;default:A=0}}Z0(t0),l(t0,A)}function rY(){Z0(t0),Z0(i6),Z0(hA)}function f8(A){A.memoizedState!==null&&l(ZG,A);var Y=t0.current,G=rq(Y,A.type);Y!==G&&(l(i6,A),l(t0,G))}function qG(A){i6.current===A&&(Z0(t0),Z0(i6)),ZG.current===A&&(Z0(ZG),G4._currentValue=HY)}function tA(A){if(xH===void 0)try{throw Error()}catch(G){var Y=G.stack.trim().match(/\n( *(at )?)/);xH=Y&&Y[1]||"",Y9=-1)":-1X||q[H]!==R[X]){var z=`
-`+q[H].replace(" at new "," at ");return A.displayName&&z.includes("")&&(z=z.replace("",A.displayName)),z}while(1<=H&&0<=X);break}}}finally{kH=!1,Error.prepareStackTrace=G}return(G=A?A.displayName||A.name:"")?tA(G):""}function lM(A,Y){switch(A.tag){case 26:case 27:case 5:return tA(A.type);case 16:return tA("Lazy");case 13:return A.child!==Y&&Y!==null?tA("Suspense Fallback"):tA("Suspense");case 19:return tA("SuspenseList");case 0:case 15:return _H(A.type,!1);case 11:return _H(A.type.render,!1);case 1:return _H(A.type,!0);case 31:return tA("Activity");default:return""}}function G9(A){try{var Y="",G=null;do Y+=lM(A,G),G=A,A=A.return;while(A);return Y}catch(H){return`
-Error generating stack: `+H.message+`
-`+H.stack}}function xA(A){if(typeof rM==="function"&&oM(A),S0&&typeof S0.setStrictMode==="function")try{S0.setStrictMode(Z4,A)}catch(Y){}}function tM(A){return A>>>=0,A===0?32:31-(aM(A)/nM|0)|0}function eA(A){var Y=A&42;if(Y!==0)return Y;switch(A&-A){case 1:return 1;case 2:return 2;case 4:return 4;case 8:return 8;case 16:return 16;case 32:return 32;case 64:return 64;case 128:return 128;case 256:case 512:case 1024:case 2048:case 4096:case 8192:case 16384:case 32768:case 65536:case 131072:return A&261888;case 262144:case 524288:case 1048576:case 2097152:return A&3932160;case 4194304:case 8388608:case 16777216:case 33554432:return A&62914560;case 67108864:return 67108864;case 134217728:return 134217728;case 268435456:return 268435456;case 536870912:return 536870912;case 1073741824:return 0;default:return A}}function hG(A,Y,G){var H=A.pendingLanes;if(H===0)return 0;var X=0,w=A.suspendedLanes,Z=A.pingedLanes;A=A.warmLanes;var W=H&134217727;return W!==0?(H=W&~w,H!==0?X=eA(H):(Z&=W,Z!==0?X=eA(Z):G||(G=W&~A,G!==0&&(X=eA(G))))):(W=H&~w,W!==0?X=eA(W):Z!==0?X=eA(Z):G||(G=H&~A,G!==0&&(X=eA(G)))),X===0?0:Y!==0&&Y!==X&&(Y&w)===0&&(w=X&-X,G=Y&-Y,w>=G||w===32&&(G&4194048)!==0)?Y:X}function W4(A,Y){return(A.pendingLanes&~(A.suspendedLanes&~A.pingedLanes)&Y)===0}function eM(A,Y){switch(A){case 1:case 2:case 4:case 8:case 64:return Y+250;case 16:case 32:case 128:case 256:case 512:case 1024:case 2048:case 4096:case 8192:case 16384:case 32768:case 65536:case 131072:case 262144:case 524288:case 1048576:case 2097152:return Y+5000;case 4194304:case 8388608:case 16777216:case 33554432:return-1;case 67108864:case 134217728:case 268435456:case 536870912:case 1073741824:return-1;default:return-1}}function kZ(){var A=_4;return _4<<=1,(_4&62914560)===0&&(_4=4194304),A}function gH(A){for(var Y=[],G=0;31>G;G++)Y.push(A);return Y}function q4(A,Y){A.pendingLanes|=Y,Y!==268435456&&(A.suspendedLanes=0,A.pingedLanes=0,A.warmLanes=0)}function AJ(A,Y,G,H,X,w){var Z=A.pendingLanes;A.pendingLanes=G,A.suspendedLanes=0,A.pingedLanes=0,A.warmLanes=0,A.expiredLanes&=G,A.entangledLanes&=G,A.errorRecoveryDisabledLanes&=G,A.shellSuspendCounter=0;var{entanglements:W,expirationTimes:q,hiddenUpdates:R}=A;for(G=Z&~G;0"u")return null;try{return A.activeElement||A.body}catch(Y){return A.body}}function h0(A){return A.replace(ZJ,function(Y){return"\\"+Y.charCodeAt(0).toString(16)+" "})}function F8(A,Y,G,H,X,w,Z,W){if(A.name="",Z!=null&&typeof Z!=="function"&&typeof Z!=="symbol"&&typeof Z!=="boolean"?A.type=Z:A.removeAttribute("type"),Y!=null)if(Z==="number"){if(Y===0&&A.value===""||A.value!=Y)A.value=""+_0(Y)}else A.value!==""+_0(Y)&&(A.value=""+_0(Y));else Z!=="submit"&&Z!=="reset"||A.removeAttribute("value");Y!=null?V8(A,Z,_0(Y)):G!=null?V8(A,Z,_0(G)):H!=null&&A.removeAttribute("value"),X==null&&w!=null&&(A.defaultChecked=!!w),X!=null&&(A.checked=X&&typeof X!=="function"&&typeof X!=="symbol"),W!=null&&typeof W!=="function"&&typeof W!=="symbol"&&typeof W!=="boolean"?A.name=""+_0(W):A.removeAttribute("name")}function dZ(A,Y,G,H,X,w,Z,W){if(w!=null&&typeof w!=="function"&&typeof w!=="symbol"&&typeof w!=="boolean"&&(A.type=w),Y!=null||G!=null){if(!(w!=="submit"&&w!=="reset"||Y!==void 0&&Y!==null)){Q8(A);return}G=G!=null?""+_0(G):"",Y=Y!=null?""+_0(Y):G,W||Y===A.value||(A.value=Y),A.defaultValue=Y}H=H!=null?H:X,H=typeof H!=="function"&&typeof H!=="symbol"&&!!H,A.checked=W?A.checked:!!H,A.defaultChecked=!!H,Z!=null&&typeof Z!=="function"&&typeof Z!=="symbol"&&typeof Z!=="boolean"&&(A.name=Z),Q8(A)}function V8(A,Y,G){Y==="number"&&MG(A.ownerDocument)===A||A.defaultValue===""+G||(A.defaultValue=""+G)}function mY(A,Y,G,H){if(A=A.options,Y){Y={};for(var X=0;X=Y)return{node:G,offset:Y-A};A=H}A:{for(;G;){if(G.nextSibling){G=G.nextSibling;break A}G=G.parentNode}G=void 0}G=Q9(G)}}function eZ(A,Y){return A&&Y?A===Y?!0:A&&A.nodeType===3?!1:Y&&Y.nodeType===3?eZ(A,Y.parentNode):("contains"in A)?A.contains(Y):A.compareDocumentPosition?!!(A.compareDocumentPosition(Y)&16):!1:!1}function AW(A){A=A!=null&&A.ownerDocument!=null&&A.ownerDocument.defaultView!=null?A.ownerDocument.defaultView:window;for(var Y=MG(A.document);Y instanceof A.HTMLIFrameElement;){try{var G=typeof Y.contentWindow.location.href==="string"}catch(H){G=!1}if(G)A=Y.contentWindow;else break;Y=MG(A.document)}return Y}function DX(A){var Y=A&&A.nodeName&&A.nodeName.toLowerCase();return Y&&(Y==="input"&&(A.type==="text"||A.type==="search"||A.type==="tel"||A.type==="url"||A.type==="password")||Y==="textarea"||A.contentEditable==="true")}function V9(A,Y,G){var H=G.window===G?G.document:G.nodeType===9?G:G.ownerDocument;T8||PY==null||PY!==MG(H)||(H=PY,("selectionStart"in H)&&DX(H)?H={start:H.selectionStart,end:H.selectionEnd}:(H=(H.ownerDocument&&H.ownerDocument.defaultView||window).getSelection(),H={anchorNode:H.anchorNode,anchorOffset:H.anchorOffset,focusNode:H.focusNode,focusOffset:H.focusOffset}),P6&&r6(P6,H)||(P6=H,H=jG(K8,"onSelect"),0>=Z,X-=Z,o0=1<<32-N0(Y)+X|G<N?(x=V,V=null):x=V.sibling;var g=L(J,V,B[N],D);if(g===null){V===null&&(V=x);break}A&&V&&g.alternate===null&&Y(J,V),U=w(g,U,N),$===null?K=g:$.sibling=g,$=g,V=x}if(N===B.length)return G(J,V),_&&WA(J,N),K;if(V===null){for(;NN?(x=V,V=null):x=V.sibling;var OA=L(J,V,g.value,D);if(OA===null){V===null&&(V=x);break}A&&V&&OA.alternate===null&&Y(J,V),U=w(OA,U,N),$===null?K=OA:$.sibling=OA,$=OA,V=x}if(g.done)return G(J,V),_&&WA(J,N),K;if(V===null){for(;!g.done;N++,g=B.next())g=Q(J,g.value,D),g!==null&&(U=w(g,U,N),$===null?K=g:$.sibling=g,$=g);return _&&WA(J,N),K}for(V=H(V);!g.done;N++,g=B.next())g=f(V,J,N,g.value,D),g!==null&&(A&&g.alternate!==null&&V.delete(g.key===null?N:g.key),U=w(g,U,N),$===null?K=g:$.sibling=g,$=g);return A&&V.forEach(function(TU){return Y(J,TU)}),_&&WA(J,N),K}function P(J,U,B,D){if(typeof B==="object"&&B!==null&&B.type===CY&&B.key===null&&(B=B.props.children),typeof B==="object"&&B!==null){switch(B.$$typeof){case $4:A:{for(var K=B.key;U!==null;){if(U.key===K){if(K=B.type,K===CY){if(U.tag===7){G(J,U.sibling),D=X(U,B.props.children),D.return=J,J=D;break A}}else if(U.elementType===K||typeof K==="object"&&K!==null&&K.$$typeof===bA&&YY(K)===U.type){G(J,U.sibling),D=X(U,B.props),F6(D,B),D.return=J,J=D;break A}G(J,U);break}else Y(J,U);U=U.sibling}B.type===CY?(D=XY(B.props.children,J.mode,D,B.key),D.return=J,J=D):(D=o4(B.type,B.key,B.props,null,J.mode,D),F6(D,B),D.return=J,J=D)}return Z(J);case K6:A:{for(K=B.key;U!==null;){if(U.key===K)if(U.tag===4&&U.stateNode.containerInfo===B.containerInfo&&U.stateNode.implementation===B.implementation){G(J,U.sibling),D=X(U,B.children||[]),D.return=J,J=D;break A}else{G(J,U);break}else Y(J,U);U=U.sibling}D=mH(B,J.mode,D),D.return=J,J=D}return Z(J);case bA:return B=YY(B),P(J,U,B,D)}if(T6(B))return I(J,U,B,D);if(D6(B)){if(K=D6(B),typeof K!=="function")throw Error(F(150));return B=K.call(B),T(J,U,B,D)}if(typeof B.then==="function")return P(J,U,E4(B),D);if(B.$$typeof===UA)return P(J,U,h4(J,B),D);y4(J,B)}return typeof B==="string"&&B!==""||typeof B==="number"||typeof B==="bigint"?(B=""+B,U!==null&&U.tag===6?(G(J,U.sibling),D=X(U,B),D.return=J,J=D):(G(J,U),D=dH(B,J.mode,D),D.return=J,J=D),Z(J)):G(J,U)}return function(J,U,B,D){try{n6=0;var K=P(J,U,B,D);return iY=null,K}catch(V){if(V===q6||V===mG)throw V;var $=K0(29,V,null,J.mode);return $.lanes=D,$.return=J,$}finally{}}}function SX(A){A.updateQueue={baseState:A.memoizedState,firstBaseUpdate:null,lastBaseUpdate:null,shared:{pending:null,lanes:0,hiddenCallbacks:null},callbacks:null}}function x8(A,Y){A=A.updateQueue,Y.updateQueue===A&&(Y.updateQueue={baseState:A.baseState,firstBaseUpdate:A.firstBaseUpdate,lastBaseUpdate:A.lastBaseUpdate,shared:A.shared,callbacks:null})}function yA(A){return{lane:A,tag:0,payload:null,callback:null,next:null}}function vA(A,Y,G){var H=A.updateQueue;if(H===null)return null;if(H=H.shared,(h&2)!==0){var X=H.pending;return X===null?Y.next=Y:(Y.next=X.next,X.next=Y),H.pending=Y,Y=RG(A),WW(A,null,G),Y}return dG(A,H,Y,G),RG(A)}function h6(A,Y,G){if(Y=Y.updateQueue,Y!==null&&(Y=Y.shared,(G&4194048)!==0)){var H=Y.lanes;H&=A.pendingLanes,G|=H,Y.lanes=G,PZ(A,G)}}function cH(A,Y){var{updateQueue:G,alternate:H}=A;if(H!==null&&(H=H.updateQueue,G===H)){var X=null,w=null;if(G=G.firstBaseUpdate,G!==null){do{var Z={lane:G.lane,tag:G.tag,payload:G.payload,callback:null,next:null};w===null?X=w=Z:w=w.next=Z,G=G.next}while(G!==null);w===null?X=w=Y:w=w.next=Y}else X=w=Y;G={baseState:H.baseState,firstBaseUpdate:X,lastBaseUpdate:w,shared:H.shared,callbacks:H.callbacks},A.updateQueue=G;return}A=G.lastBaseUpdate,A===null?G.firstBaseUpdate=Y:A.next=Y,G.lastBaseUpdate=Y}function E6(){if(k8){var A=cY;if(A!==null)throw A}}function y6(A,Y,G,H){k8=!1;var X=A.updateQueue;SA=!1;var{firstBaseUpdate:w,lastBaseUpdate:Z}=X,W=X.shared.pending;if(W!==null){X.shared.pending=null;var q=W,R=q.next;q.next=null,Z===null?w=R:Z.next=R,Z=q;var z=A.alternate;z!==null&&(z=z.updateQueue,W=z.lastBaseUpdate,W!==Z&&(W===null?z.firstBaseUpdate=R:W.next=R,z.lastBaseUpdate=q))}if(w!==null){var Q=X.baseState;Z=0,z=R=q=null,W=w;do{var L=W.lane&-536870913,f=L!==W.lane;if(f?(k&L)===L:(H&L)===L){L!==0&&L===nY&&(k8=!0),z!==null&&(z=z.next={lane:0,tag:W.tag,payload:W.payload,callback:null,next:null});A:{var I=A,T=W;L=Y;var P=G;switch(T.tag){case 1:if(I=T.payload,typeof I==="function"){Q=I.call(P,Q,L);break A}Q=I;break A;case 3:I.flags=I.flags&-65537|128;case 0:if(I=T.payload,L=typeof I==="function"?I.call(P,Q,L):I,L===null||L===void 0)break A;Q=s({},Q,L);break A;case 2:SA=!0}}L=W.callback,L!==null&&(A.flags|=64,f&&(A.flags|=8192),f=X.callbacks,f===null?X.callbacks=[L]:f.push(L))}else f={lane:L,tag:W.tag,payload:W.payload,callback:W.callback,next:null},z===null?(R=z=f,q=Q):z=z.next=f,Z|=L;if(W=W.next,W===null)if(W=X.shared.pending,W===null)break;else f=W,W=f.next,f.next=null,X.lastBaseUpdate=f,X.shared.pending=null}while(1);z===null&&(q=Q),X.baseState=q,X.firstBaseUpdate=R,X.lastBaseUpdate=z,w===null&&(X.shared.lanes=0),rA|=Z,A.lanes=Z,A.memoizedState=Q}}function DW(A,Y){if(typeof A!=="function")throw Error(F(191,A));A.call(Y)}function QW(A,Y){var G=A.callbacks;if(G!==null)for(A.callbacks=null,A=0;Aw?w:8;var Z=b.T,W={};b.T=W,vX(A,!1,Y,G);try{var q=X(),R=b.S;if(R!==null&&R(W,q),q!==null&&typeof q==="object"&&typeof q.then==="function"){var z=A1(q,H);v6(A,Y,z,j0(A))}else v6(A,Y,H,j0(A))}catch(Q){v6(A,Y,{then:function(){},status:"rejected",reason:Q},j0())}finally{E.p=w,Z!==null&&W.types!==null&&(Z.types=W.types),b.T=Z}}function Z1(){}function E8(A,Y,G,H){if(A.tag!==5)throw Error(F(476));var X=lW(A).queue;mW(A,X,Y,HY,G===null?Z1:function(){return cW(A),G(H)})}function lW(A){var Y=A.memoizedState;if(Y!==null)return Y;Y={memoizedState:HY,baseState:HY,baseQueue:null,queue:{pending:null,lanes:0,dispatch:null,lastRenderedReducer:DA,lastRenderedState:HY},next:null};var G={};return Y.next={memoizedState:G,baseState:G,baseQueue:null,queue:{pending:null,lanes:0,dispatch:null,lastRenderedReducer:DA,lastRenderedState:G},next:null},A.memoizedState=Y,A=A.alternate,A!==null&&(A.memoizedState=Y),Y}function cW(A){var Y=lW(A);Y.next===null&&(Y=A.alternate.memoizedState),v6(A,Y.next.queue,{},j0())}function yX(){return M0(G4)}function iW(){return t().memoizedState}function pW(){return t().memoizedState}function W1(A){for(var Y=A.return;Y!==null;){switch(Y.tag){case 24:case 3:var G=j0();A=yA(G);var H=vA(Y,A,G);H!==null&&(Q0(H,Y,G),h6(H,Y,G)),Y={cache:KX()},A.payload=Y;return}Y=Y.return}}function q1(A,Y,G){var H=j0();G={lane:H,revertLane:0,gesture:null,action:G,hasEagerState:!1,eagerState:null,next:null},pG(A)?rW(Y,G):(G=FX(A,Y,G,H),G!==null&&(Q0(G,A,H),oW(G,Y,H)))}function sW(A,Y,G){var H=j0();v6(A,Y,G,H)}function v6(A,Y,G,H){var X={lane:H,revertLane:0,gesture:null,action:G,hasEagerState:!1,eagerState:null,next:null};if(pG(A))rW(Y,X);else{var w=A.alternate;if(A.lanes===0&&(w===null||w.lanes===0)&&(w=Y.lastRenderedReducer,w!==null))try{var Z=Y.lastRenderedState,W=w(Z,G);if(X.hasEagerState=!0,X.eagerState=W,C0(W,Z))return dG(A,Y,X,0),m===null&&uG(),!1}catch(q){}finally{}if(G=FX(A,Y,X,H),G!==null)return Q0(G,A,H),oW(G,Y,H),!0}return!1}function vX(A,Y,G,H){if(H={lane:2,revertLane:rX(),gesture:null,action:H,hasEagerState:!1,eagerState:null,next:null},pG(A)){if(Y)throw Error(F(479))}else Y=FX(A,G,H,2),Y!==null&&Q0(Y,A,2)}function pG(A){var Y=A.alternate;return A===S||Y!==null&&Y===S}function rW(A,Y){pY=QG=!0;var G=A.pending;G===null?Y.next=Y:(Y.next=G.next,G.next=Y),A.pending=Y}function oW(A,Y,G){if((G&4194048)!==0){var H=Y.lanes;H&=A.pendingLanes,G|=H,Y.lanes=G,PZ(A,G)}}function pH(A,Y,G,H){Y=A.memoizedState,G=G(H,Y),G=G===null||G===void 0?Y:s({},Y,G),A.memoizedState=G,A.lanes===0&&(A.updateQueue.baseState=G)}function h9(A,Y,G,H,X,w,Z){return A=A.stateNode,typeof A.shouldComponentUpdate==="function"?A.shouldComponentUpdate(H,w,Z):Y.prototype&&Y.prototype.isPureReactComponent?!r6(G,H)||!r6(X,w):!0}function E9(A,Y,G,H){A=Y.state,typeof Y.componentWillReceiveProps==="function"&&Y.componentWillReceiveProps(G,H),typeof Y.UNSAFE_componentWillReceiveProps==="function"&&Y.UNSAFE_componentWillReceiveProps(G,H),Y.state!==A&&y8.enqueueReplaceState(Y,Y.state,null)}function RY(A,Y){var G=Y;if("ref"in Y){G={};for(var H in Y)H!=="ref"&&(G[H]=Y[H])}if(A=A.defaultProps){G===Y&&(G=s({},G));for(var X in A)G[X]===void 0&&(G[X]=A[X])}return G}function tW(A){JG(A)}function eW(A){console.error(A)}function Aq(A){JG(A)}function VG(A,Y){try{var G=A.onUncaughtError;G(Y.value,{componentStack:Y.stack})}catch(H){setTimeout(function(){throw H})}}function y9(A,Y,G){try{var H=A.onCaughtError;H(G.value,{componentStack:G.stack,errorBoundary:Y.tag===1?Y.stateNode:null})}catch(X){setTimeout(function(){throw X})}}function v8(A,Y,G){return G=yA(G),G.tag=3,G.payload={element:null},G.callback=function(){VG(A,Y)},G}function Yq(A){return A=yA(A),A.tag=3,A}function Gq(A,Y,G,H){var X=G.type.getDerivedStateFromError;if(typeof X==="function"){var w=H.value;A.payload=function(){return X(w)},A.callback=function(){y9(Y,G,H)}}var Z=G.stateNode;Z!==null&&typeof Z.componentDidCatch==="function"&&(A.callback=function(){y9(Y,G,H),typeof X!=="function"&&(uA===null?uA=new Set([this]):uA.add(this));var W=H.stack;this.componentDidCatch(H.value,{componentStack:W!==null?W:""})})}function U1(A,Y,G,H,X){if(G.flags|=32768,H!==null&&typeof H==="object"&&typeof H.then==="function"){if(Y=G.alternate,Y!==null&&W6(Y,G,X,!0),G=$0.current,G!==null){switch(G.tag){case 31:case 13:return v0===null?bG():G.alternate===null&&a===0&&(a=3),G.flags&=-257,G.flags|=65536,G.lanes=X,H===fG?G.flags|=16384:(Y=G.updateQueue,Y===null?G.updateQueue=new Set([H]):Y.add(H),H8(A,H,X)),!1;case 22:return G.flags|=65536,H===fG?G.flags|=16384:(Y=G.updateQueue,Y===null?(Y={transitions:null,markerInstances:null,retryQueue:new Set([H])},G.updateQueue=Y):(G=Y.retryQueue,G===null?Y.retryQueue=new Set([H]):G.add(H)),H8(A,H,X)),!1}throw Error(F(435,G.tag))}return H8(A,H,X),bG(),!1}if(_)return Y=$0.current,Y!==null?((Y.flags&65536)===0&&(Y.flags|=256),Y.flags|=65536,Y.lanes=X,H!==S8&&(A=Error(F(422),{cause:H}),a6(E0(A,G)))):(H!==S8&&(Y=Error(F(423),{cause:H}),a6(E0(Y,G))),A=A.current.alternate,A.flags|=65536,X&=-X,A.lanes|=X,H=E0(H,G),X=v8(A.stateNode,H,X),cH(A,X),a!==4&&(a=2)),!1;var w=Error(F(520),{cause:H});if(w=E0(w,G),m6===null?m6=[w]:m6.push(w),a!==4&&(a=2),Y===null)return!0;H=E0(H,G),G=Y;do{switch(G.tag){case 3:return G.flags|=65536,A=X&-X,G.lanes|=A,A=v8(G.stateNode,H,A),cH(G,A),!1;case 1:if(Y=G.type,w=G.stateNode,(G.flags&128)===0&&(typeof Y.getDerivedStateFromError==="function"||w!==null&&typeof w.componentDidCatch==="function"&&(uA===null||!uA.has(w))))return G.flags|=65536,X&=-X,G.lanes|=X,X=Yq(X),Gq(X,A,G,H),cH(G,X),!1}G=G.return}while(G!==null);return!1}function W0(A,Y,G,H){Y.child=A===null?zW(Y,null,G,H):MY(Y,A.child,G,H)}function v9(A,Y,G,H,X){G=G.render;var w=Y.ref;if("ref"in H){var Z={};for(var W in H)W!=="ref"&&(Z[W]=H[W])}else Z=H;if(UY(Y),H=CX(A,Y,G,Z,w,X),W=$X(),A!==null&&!G0)return xX(A,Y,X),QA(A,Y,X);return _&&W&&IX(Y),Y.flags|=1,W0(A,Y,H,X),Y.child}function u9(A,Y,G,H,X){if(A===null){var w=G.type;if(typeof w==="function"&&!VX(w)&&w.defaultProps===void 0&&G.compare===null)return Y.tag=15,Y.type=w,Hq(A,Y,w,H,X);return A=o4(G.type,null,H,Y,Y.mode,X),A.ref=Y.ref,A.return=Y,Y.child=A}if(w=A.child,!mX(A,X)){var Z=w.memoizedProps;if(G=G.compare,G=G!==null?G:r6,G(Z,H)&&A.ref===Y.ref)return QA(A,Y,X)}return Y.flags|=1,A=RA(w,H),A.ref=Y.ref,A.return=Y,Y.child=A}function Hq(A,Y,G,H,X){if(A!==null){var w=A.memoizedProps;if(r6(w,H)&&A.ref===Y.ref)if(G0=!1,Y.pendingProps=H=w,mX(A,X))(A.flags&131072)!==0&&(G0=!0);else return Y.lanes=A.lanes,QA(A,Y,X)}return u8(A,Y,G,H,X)}function Xq(A,Y,G,H){var X=H.children,w=A!==null?A.memoizedState:null;if(A===null&&Y.stateNode===null&&(Y.stateNode={_visibility:1,_pendingMarkers:null,_retryCache:null,_transitions:null}),H.mode==="hidden"){if((Y.flags&128)!==0){if(w=w!==null?w.baseLanes|G:G,A!==null){H=Y.child=A.child;for(X=0;H!==null;)X=X|H.lanes|H.childLanes,H=H.sibling;H=X&~w}else H=0,Y.child=null;return d9(A,Y,w,G,H)}if((G&536870912)!==0)Y.memoizedState={baseLanes:0,cachePool:null},A!==null&&a4(Y,w!==null?w.cachePool:null),w!==null?C9(Y,w):_8(),FW(Y);else return H=Y.lanes=536870912,d9(A,Y,w!==null?w.baseLanes|G:G,G,H)}else w!==null?(a4(Y,w.cachePool),C9(Y,w),CA(Y),Y.memoizedState=null):(A!==null&&a4(Y,null),_8(),CA(Y));return W0(A,Y,X,G),Y.child}function j6(A,Y){return A!==null&&A.tag===22||Y.stateNode!==null||(Y.stateNode={_visibility:1,_pendingMarkers:null,_retryCache:null,_transitions:null}),Y.sibling}function d9(A,Y,G,H,X){var w=TX();return w=w===null?null:{parent:Y0._currentValue,pool:w},Y.memoizedState={baseLanes:G,cachePool:w},A!==null&&a4(Y,null),_8(),FW(Y),A!==null&&W6(A,Y,H,!0),Y.childLanes=X,null}function e4(A,Y){return Y=IG({mode:Y.mode,children:Y.children},A.mode),Y.ref=A.ref,A.child=Y,Y.return=A,Y}function m9(A,Y,G){return MY(Y,A.child,null,G),A=e4(Y,Y.pendingProps),A.flags|=2,O0(Y),Y.memoizedState=null,A}function M1(A,Y,G){var H=Y.pendingProps,X=(Y.flags&128)!==0;if(Y.flags&=-129,A===null){if(_){if(H.mode==="hidden")return A=e4(Y,H),Y.lanes=536870912,j6(null,A);if(P8(Y),(A=p)?(A=aq(A,y0),A=A!==null&&A.data==="&"?A:null,A!==null&&(Y.memoizedState={dehydrated:A,treeContext:iA!==null?{id:o0,overflow:a0}:null,retryLane:536870912,hydrationErrors:null},G=UW(A),G.return=Y,Y.child=G,U0=Y,p=null)):A=null,A===null)throw pA(Y);return Y.lanes=536870912,null}return e4(Y,H)}var w=A.memoizedState;if(w!==null){var Z=w.dehydrated;if(P8(Y),X)if(Y.flags&256)Y.flags&=-257,Y=m9(A,Y,G);else if(Y.memoizedState!==null)Y.child=A.child,Y.flags|=128,Y=null;else throw Error(F(558));else if(G0||W6(A,Y,G,!1),X=(G&A.childLanes)!==0,G0||X){if(H=m,H!==null&&(Z=gZ(H,G),Z!==0&&Z!==w.retryLane))throw w.retryLane=Z,zY(A,Z),Q0(H,A,Z),dX;bG(),Y=m9(A,Y,G)}else A=w.treeContext,p=u0(Z.nextSibling),U0=Y,_=!0,EA=null,y0=!1,A!==null&&JW(Y,A),Y=e4(Y,H),Y.flags|=4096;return Y}return A=RA(A.child,{mode:H.mode,children:H.children}),A.ref=Y.ref,Y.child=A,A.return=Y,A}function AG(A,Y){var G=Y.ref;if(G===null)A!==null&&A.ref!==null&&(Y.flags|=4194816);else{if(typeof G!=="function"&&typeof G!=="object")throw Error(F(284));if(A===null||A.ref!==G)Y.flags|=4194816}}function u8(A,Y,G,H,X){if(UY(Y),G=CX(A,Y,G,H,void 0,X),H=$X(),A!==null&&!G0)return xX(A,Y,X),QA(A,Y,X);return _&&H&&IX(Y),Y.flags|=1,W0(A,Y,G,X),Y.child}function l9(A,Y,G,H,X,w){if(UY(Y),Y.updateQueue=null,G=IW(Y,H,G,X),VW(A),H=$X(),A!==null&&!G0)return xX(A,Y,w),QA(A,Y,w);return _&&H&&IX(Y),Y.flags|=1,W0(A,Y,G,w),Y.child}function c9(A,Y,G,H,X){if(UY(Y),Y.stateNode===null){var w=EY,Z=G.contextType;typeof Z==="object"&&Z!==null&&(w=M0(Z)),w=new G(H,w),Y.memoizedState=w.state!==null&&w.state!==void 0?w.state:null,w.updater=y8,Y.stateNode=w,w._reactInternals=Y,w=Y.stateNode,w.props=H,w.state=Y.memoizedState,w.refs={},SX(Y),Z=G.contextType,w.context=typeof Z==="object"&&Z!==null?M0(Z):EY,w.state=Y.memoizedState,Z=G.getDerivedStateFromProps,typeof Z==="function"&&(pH(Y,G,Z,H),w.state=Y.memoizedState),typeof G.getDerivedStateFromProps==="function"||typeof w.getSnapshotBeforeUpdate==="function"||typeof w.UNSAFE_componentWillMount!=="function"&&typeof w.componentWillMount!=="function"||(Z=w.state,typeof w.componentWillMount==="function"&&w.componentWillMount(),typeof w.UNSAFE_componentWillMount==="function"&&w.UNSAFE_componentWillMount(),Z!==w.state&&y8.enqueueReplaceState(w,w.state,null),y6(Y,H,w,X),E6(),w.state=Y.memoizedState),typeof w.componentDidMount==="function"&&(Y.flags|=4194308),H=!0}else if(A===null){w=Y.stateNode;var W=Y.memoizedProps,q=RY(G,W);w.props=q;var R=w.context,z=G.contextType;Z=EY,typeof z==="object"&&z!==null&&(Z=M0(z));var Q=G.getDerivedStateFromProps;z=typeof Q==="function"||typeof w.getSnapshotBeforeUpdate==="function",W=Y.pendingProps!==W,z||typeof w.UNSAFE_componentWillReceiveProps!=="function"&&typeof w.componentWillReceiveProps!=="function"||(W||R!==Z)&&E9(Y,w,H,Z),SA=!1;var L=Y.memoizedState;w.state=L,y6(Y,H,w,X),E6(),R=Y.memoizedState,W||L!==R||SA?(typeof Q==="function"&&(pH(Y,G,Q,H),R=Y.memoizedState),(q=SA||h9(Y,G,q,H,L,R,Z))?(z||typeof w.UNSAFE_componentWillMount!=="function"&&typeof w.componentWillMount!=="function"||(typeof w.componentWillMount==="function"&&w.componentWillMount(),typeof w.UNSAFE_componentWillMount==="function"&&w.UNSAFE_componentWillMount()),typeof w.componentDidMount==="function"&&(Y.flags|=4194308)):(typeof w.componentDidMount==="function"&&(Y.flags|=4194308),Y.memoizedProps=H,Y.memoizedState=R),w.props=H,w.state=R,w.context=Z,H=q):(typeof w.componentDidMount==="function"&&(Y.flags|=4194308),H=!1)}else{w=Y.stateNode,x8(A,Y),Z=Y.memoizedProps,z=RY(G,Z),w.props=z,Q=Y.pendingProps,L=w.context,R=G.contextType,q=EY,typeof R==="object"&&R!==null&&(q=M0(R)),W=G.getDerivedStateFromProps,(R=typeof W==="function"||typeof w.getSnapshotBeforeUpdate==="function")||typeof w.UNSAFE_componentWillReceiveProps!=="function"&&typeof w.componentWillReceiveProps!=="function"||(Z!==Q||L!==q)&&E9(Y,w,H,q),SA=!1,L=Y.memoizedState,w.state=L,y6(Y,H,w,X),E6();var f=Y.memoizedState;Z!==Q||L!==f||SA||A!==null&&A.dependencies!==null&&LG(A.dependencies)?(typeof W==="function"&&(pH(Y,G,W,H),f=Y.memoizedState),(z=SA||h9(Y,G,z,H,L,f,q)||A!==null&&A.dependencies!==null&&LG(A.dependencies))?(R||typeof w.UNSAFE_componentWillUpdate!=="function"&&typeof w.componentWillUpdate!=="function"||(typeof w.componentWillUpdate==="function"&&w.componentWillUpdate(H,f,q),typeof w.UNSAFE_componentWillUpdate==="function"&&w.UNSAFE_componentWillUpdate(H,f,q)),typeof w.componentDidUpdate==="function"&&(Y.flags|=4),typeof w.getSnapshotBeforeUpdate==="function"&&(Y.flags|=1024)):(typeof w.componentDidUpdate!=="function"||Z===A.memoizedProps&&L===A.memoizedState||(Y.flags|=4),typeof w.getSnapshotBeforeUpdate!=="function"||Z===A.memoizedProps&&L===A.memoizedState||(Y.flags|=1024),Y.memoizedProps=H,Y.memoizedState=f),w.props=H,w.state=f,w.context=q,H=z):(typeof w.componentDidUpdate!=="function"||Z===A.memoizedProps&&L===A.memoizedState||(Y.flags|=4),typeof w.getSnapshotBeforeUpdate!=="function"||Z===A.memoizedProps&&L===A.memoizedState||(Y.flags|=1024),H=!1)}return w=H,AG(A,Y),H=(Y.flags&128)!==0,w||H?(w=Y.stateNode,G=H&&typeof G.getDerivedStateFromError!=="function"?null:w.render(),Y.flags|=1,A!==null&&H?(Y.child=MY(Y,A.child,null,X),Y.child=MY(Y,null,G,X)):W0(A,Y,G,X),Y.memoizedState=w.state,A=Y.child):A=QA(A,Y,X),A}function i9(A,Y,G,H){return qY(),Y.flags|=256,W0(A,Y,G,H),Y.child}function rH(A){return{baseLanes:A,cachePool:BW()}}function oH(A,Y,G){return A=A!==null?A.childLanes&~G:0,Y&&(A|=T0),A}function wq(A,Y,G){var H=Y.pendingProps,X=!1,w=(Y.flags&128)!==0,Z;if((Z=w)||(Z=A!==null&&A.memoizedState===null?!1:(n.current&2)!==0),Z&&(X=!0,Y.flags&=-129),Z=(Y.flags&32)!==0,Y.flags&=-33,A===null){if(_){if(X?jA(Y):CA(Y),(A=p)?(A=aq(A,y0),A=A!==null&&A.data!=="&"?A:null,A!==null&&(Y.memoizedState={dehydrated:A,treeContext:iA!==null?{id:o0,overflow:a0}:null,retryLane:536870912,hydrationErrors:null},G=UW(A),G.return=Y,Y.child=G,U0=Y,p=null)):A=null,A===null)throw pA(Y);return GX(A)?Y.lanes=32:Y.lanes=536870912,null}var W=H.children;if(H=H.fallback,X)return CA(Y),X=Y.mode,W=IG({mode:"hidden",children:W},X),H=XY(H,X,G,null),W.return=Y,H.return=Y,W.sibling=H,Y.child=W,H=Y.child,H.memoizedState=rH(G),H.childLanes=oH(A,Z,G),Y.memoizedState=sH,j6(null,H);return jA(Y),d8(Y,W)}var q=A.memoizedState;if(q!==null&&(W=q.dehydrated,W!==null)){if(w)Y.flags&256?(jA(Y),Y.flags&=-257,Y=aH(A,Y,G)):Y.memoizedState!==null?(CA(Y),Y.child=A.child,Y.flags|=128,Y=null):(CA(Y),W=H.fallback,X=Y.mode,H=IG({mode:"visible",children:H.children},X),W=XY(W,X,G,null),W.flags|=2,H.return=Y,W.return=Y,H.sibling=W,Y.child=H,MY(Y,A.child,null,G),H=Y.child,H.memoizedState=rH(G),H.childLanes=oH(A,Z,G),Y.memoizedState=sH,Y=j6(null,H));else if(jA(Y),GX(W)){if(Z=W.nextSibling&&W.nextSibling.dataset,Z)var R=Z.dgst;Z=R,H=Error(F(419)),H.stack="",H.digest=Z,a6({value:H,source:null,stack:null}),Y=aH(A,Y,G)}else if(G0||W6(A,Y,G,!1),Z=(G&A.childLanes)!==0,G0||Z){if(Z=m,Z!==null&&(H=gZ(Z,G),H!==0&&H!==q.retryLane))throw q.retryLane=H,zY(A,H),Q0(Z,A,H),dX;YX(W)||bG(),Y=aH(A,Y,G)}else YX(W)?(Y.flags|=192,Y.child=A.child,Y=null):(A=q.treeContext,p=u0(W.nextSibling),U0=Y,_=!0,EA=null,y0=!1,A!==null&&JW(Y,A),Y=d8(Y,H.children),Y.flags|=4096);return Y}if(X)return CA(Y),W=H.fallback,X=Y.mode,q=A.child,R=q.sibling,H=RA(q,{mode:"hidden",children:H.children}),H.subtreeFlags=q.subtreeFlags&65011712,R!==null?W=RA(R,W):(W=XY(W,X,G,null),W.flags|=2),W.return=Y,H.return=Y,H.sibling=W,Y.child=H,j6(null,H),H=Y.child,W=A.child.memoizedState,W===null?W=rH(G):(X=W.cachePool,X!==null?(q=Y0._currentValue,X=X.parent!==q?{parent:q,pool:q}:X):X=BW(),W={baseLanes:W.baseLanes|G,cachePool:X}),H.memoizedState=W,H.childLanes=oH(A,Z,G),Y.memoizedState=sH,j6(A.child,H);return jA(Y),G=A.child,A=G.sibling,G=RA(G,{mode:"visible",children:H.children}),G.return=Y,G.sibling=null,A!==null&&(Z=Y.deletions,Z===null?(Y.deletions=[A],Y.flags|=16):Z.push(A)),Y.child=G,Y.memoizedState=null,G}function d8(A,Y){return Y=IG({mode:"visible",children:Y},A.mode),Y.return=A,A.child=Y}function IG(A,Y){return A=K0(22,A,null,Y),A.lanes=0,A}function aH(A,Y,G){return MY(Y,A.child,null,G),A=d8(Y,Y.pendingProps.children),A.flags|=2,Y.memoizedState=null,A}function p9(A,Y,G){A.lanes|=Y;var H=A.alternate;H!==null&&(H.lanes|=Y),j8(A.return,Y,G)}function nH(A,Y,G,H,X,w){var Z=A.memoizedState;Z===null?A.memoizedState={isBackwards:Y,rendering:null,renderingStartTime:0,last:H,tail:G,tailMode:X,treeForkCount:w}:(Z.isBackwards=Y,Z.rendering=null,Z.renderingStartTime=0,Z.last=H,Z.tail=G,Z.tailMode=X,Z.treeForkCount=w)}function Zq(A,Y,G){var H=Y.pendingProps,X=H.revealOrder,w=H.tail;H=H.children;var Z=n.current,W=(Z&2)!==0;if(W?(Z=Z&1|2,Y.flags|=128):Z&=1,l(n,Z),W0(A,Y,H,G),H=_?o6:0,!W&&A!==null&&(A.flags&128)!==0)A:for(A=Y.child;A!==null;){if(A.tag===13)A.memoizedState!==null&&p9(A,G,Y);else if(A.tag===19)p9(A,G,Y);else if(A.child!==null){A.child.return=A,A=A.child;continue}if(A===Y)break A;for(;A.sibling===null;){if(A.return===null||A.return===Y)break A;A=A.return}A.sibling.return=A.return,A=A.sibling}switch(X){case"forwards":G=Y.child;for(X=null;G!==null;)A=G.alternate,A!==null&&DG(A)===null&&(X=G),G=G.sibling;G=X,G===null?(X=Y.child,Y.child=null):(X=G.sibling,G.sibling=null),nH(Y,!1,X,G,w,H);break;case"backwards":case"unstable_legacy-backwards":G=null,X=Y.child;for(Y.child=null;X!==null;){if(A=X.alternate,A!==null&&DG(A)===null){Y.child=X;break}A=X.sibling,X.sibling=G,G=X,X=A}nH(Y,!0,G,null,w,H);break;case"together":nH(Y,!1,null,null,void 0,H);break;default:Y.memoizedState=null}return Y.child}function QA(A,Y,G){if(A!==null&&(Y.dependencies=A.dependencies),rA|=Y.lanes,(G&Y.childLanes)===0)if(A!==null){if(W6(A,Y,G,!1),(G&Y.childLanes)===0)return null}else return null;if(A!==null&&Y.child!==A.child)throw Error(F(153));if(Y.child!==null){A=Y.child,G=RA(A,A.pendingProps),Y.child=G;for(G.return=Y;A.sibling!==null;)A=A.sibling,G=G.sibling=RA(A,A.pendingProps),G.return=Y;G.sibling=null}return Y.child}function mX(A,Y){if((A.lanes&Y)!==0)return!0;return A=A.dependencies,A!==null&&LG(A)?!0:!1}function J1(A,Y,G){switch(Y.tag){case 3:WG(Y,Y.stateNode.containerInfo),NA(Y,Y0,A.memoizedState.cache),qY();break;case 27:case 5:f8(Y);break;case 4:WG(Y,Y.stateNode.containerInfo);break;case 10:NA(Y,Y.type,Y.memoizedProps.value);break;case 31:if(Y.memoizedState!==null)return Y.flags|=128,P8(Y),null;break;case 13:var H=Y.memoizedState;if(H!==null){if(H.dehydrated!==null)return jA(Y),Y.flags|=128,null;if((G&Y.child.childLanes)!==0)return wq(A,Y,G);return jA(Y),A=QA(A,Y,G),A!==null?A.sibling:null}jA(Y);break;case 19:var X=(A.flags&128)!==0;if(H=(G&Y.childLanes)!==0,H||(W6(A,Y,G,!1),H=(G&Y.childLanes)!==0),X){if(H)return Zq(A,Y,G);Y.flags|=128}if(X=Y.memoizedState,X!==null&&(X.rendering=null,X.tail=null,X.lastEffect=null),l(n,n.current),H)break;else return null;case 22:return Y.lanes=0,Xq(A,Y,G,Y.pendingProps);case 24:NA(Y,Y0,A.memoizedState.cache)}return QA(A,Y,G)}function Wq(A,Y,G){if(A!==null)if(A.memoizedProps!==Y.pendingProps)G0=!0;else{if(!mX(A,G)&&(Y.flags&128)===0)return G0=!1,J1(A,Y,G);G0=(A.flags&131072)!==0?!0:!1}else G0=!1,_&&(Y.flags&1048576)!==0&&MW(Y,o6,Y.index);switch(Y.lanes=0,Y.tag){case 16:A:{var H=Y.pendingProps;if(A=YY(Y.elementType),Y.type=A,typeof A==="function")VX(A)?(H=RY(A,H),Y.tag=1,Y=c9(null,Y,A,H,G)):(Y.tag=0,Y=u8(null,Y,A,H,G));else{if(A!==void 0&&A!==null){var X=A.$$typeof;if(X===ZX){Y.tag=11,Y=v9(null,Y,A,H,G);break A}else if(X===WX){Y.tag=14,Y=u9(null,Y,A,H,G);break A}}throw Y=B8(A)||A,Error(F(306,Y,""))}}return Y;case 0:return u8(A,Y,Y.type,Y.pendingProps,G);case 1:return H=Y.type,X=RY(H,Y.pendingProps),c9(A,Y,H,X,G);case 3:A:{if(WG(Y,Y.stateNode.containerInfo),A===null)throw Error(F(387));H=Y.pendingProps;var w=Y.memoizedState;X=w.element,x8(A,Y),y6(Y,H,null,G);var Z=Y.memoizedState;if(H=Z.cache,NA(Y,Y0,H),H!==w.cache&&C8(Y,[Y0],G,!0),E6(),H=Z.element,w.isDehydrated)if(w={element:H,isDehydrated:!1,cache:Z.cache},Y.updateQueue.baseState=w,Y.memoizedState=w,Y.flags&256){Y=i9(A,Y,H,G);break A}else if(H!==X){X=E0(Error(F(424)),Y),a6(X),Y=i9(A,Y,H,G);break A}else{switch(A=Y.stateNode.containerInfo,A.nodeType){case 9:A=A.body;break;default:A=A.nodeName==="HTML"?A.ownerDocument.body:A}p=u0(A.firstChild),U0=Y,_=!0,EA=null,y0=!0,G=zW(Y,null,H,G);for(Y.child=G;G;)G.flags=G.flags&-3|4096,G=G.sibling}else{if(qY(),H===X){Y=QA(A,Y,G);break A}W0(A,Y,H,G)}Y=Y.child}return Y;case 26:return AG(A,Y),A===null?(G=RZ(Y.type,null,Y.pendingProps,null))?Y.memoizedState=G:_||(G=Y.type,A=Y.pendingProps,H=CG(hA.current).createElement(G),H[q0]=Y,H[F0]=A,J0(H,G,A),w0(H),Y.stateNode=H):Y.memoizedState=RZ(Y.type,A.memoizedProps,Y.pendingProps,A.memoizedState),null;case 27:return f8(Y),A===null&&_&&(H=Y.stateNode=nq(Y.type,Y.pendingProps,hA.current),U0=Y,y0=!0,X=p,aA(Y.type)?(HX=X,p=u0(H.firstChild)):p=X),W0(A,Y,Y.pendingProps.children,G),AG(A,Y),A===null&&(Y.flags|=4194304),Y.child;case 5:if(A===null&&_){if(X=H=p)H=v1(H,Y.type,Y.pendingProps,y0),H!==null?(Y.stateNode=H,U0=Y,p=u0(H.firstChild),y0=!1,X=!0):X=!1;X||pA(Y)}return f8(Y),X=Y.type,w=Y.pendingProps,Z=A!==null?A.memoizedProps:null,H=w.children,e8(X,w)?H=null:Z!==null&&e8(X,Z)&&(Y.flags|=32),Y.memoizedState!==null&&(X=CX(A,Y,G1,null,null,G),G4._currentValue=X),AG(A,Y),W0(A,Y,H,G),Y.child;case 6:if(A===null&&_){if(A=G=p)G=u1(G,Y.pendingProps,y0),G!==null?(Y.stateNode=G,U0=Y,p=null,A=!0):A=!1;A||pA(Y)}return null;case 13:return wq(A,Y,G);case 4:return WG(Y,Y.stateNode.containerInfo),H=Y.pendingProps,A===null?Y.child=MY(Y,null,H,G):W0(A,Y,H,G),Y.child;case 11:return v9(A,Y,Y.type,Y.pendingProps,G);case 7:return W0(A,Y,Y.pendingProps,G),Y.child;case 8:return W0(A,Y,Y.pendingProps.children,G),Y.child;case 12:return W0(A,Y,Y.pendingProps.children,G),Y.child;case 10:return H=Y.pendingProps,NA(Y,Y.type,H.value),W0(A,Y,H.children,G),Y.child;case 9:return X=Y.type._context,H=Y.pendingProps.children,UY(Y),X=M0(X),H=H(X),Y.flags|=1,W0(A,Y,H,G),Y.child;case 14:return u9(A,Y,Y.type,Y.pendingProps,G);case 15:return Hq(A,Y,Y.type,Y.pendingProps,G);case 19:return Zq(A,Y,G);case 31:return M1(A,Y,G);case 22:return Xq(A,Y,G,Y.pendingProps);case 24:return UY(Y),H=M0(Y0),A===null?(X=TX(),X===null&&(X=m,w=KX(),X.pooledCache=w,w.refCount++,w!==null&&(X.pooledCacheLanes|=G),X=w),Y.memoizedState={parent:H,cache:X},SX(Y),NA(Y,Y0,X)):((A.lanes&G)!==0&&(x8(A,Y),y6(Y,null,null,G),E6()),X=A.memoizedState,w=Y.memoizedState,X.parent!==H?(X={parent:H,cache:H},Y.memoizedState=X,Y.lanes===0&&(Y.memoizedState=Y.updateQueue.baseState=X),NA(Y,Y0,H)):(H=w.cache,NA(Y,Y0,H),H!==X.cache&&C8(Y,[Y0],G,!0))),W0(A,Y,Y.pendingProps.children,G),Y.child;case 29:throw Y.pendingProps}throw Error(F(156,Y.tag))}function HA(A){A.flags|=4}function tH(A,Y,G,H,X){if(Y=(A.mode&32)!==0)Y=!1;if(Y){if(A.flags|=16777216,(X&335544128)===X)if(A.stateNode.complete)A.flags|=8192;else if(xq())A.flags|=8192;else throw ZY=fG,bX}else A.flags&=-16777217}function s9(A,Y){if(Y.type!=="stylesheet"||(Y.state.loading&4)!==0)A.flags&=-16777217;else if(A.flags|=16777216,!AU(Y))if(xq())A.flags|=8192;else throw ZY=fG,bX}function v4(A,Y){Y!==null&&(A.flags|=4),A.flags&16384&&(Y=A.tag!==22?kZ():536870912,A.lanes|=Y,A6|=Y)}function V6(A,Y){if(!_)switch(A.tailMode){case"hidden":Y=A.tail;for(var G=null;Y!==null;)Y.alternate!==null&&(G=Y),Y=Y.sibling;G===null?A.tail=null:G.sibling=null;break;case"collapsed":G=A.tail;for(var H=null;G!==null;)G.alternate!==null&&(H=G),G=G.sibling;H===null?Y||A.tail===null?A.tail=null:A.tail.sibling=null:H.sibling=null}}function i(A){var Y=A.alternate!==null&&A.alternate.child===A.child,G=0,H=0;if(Y)for(var X=A.child;X!==null;)G|=X.lanes|X.childLanes,H|=X.subtreeFlags&65011712,H|=X.flags&65011712,X.return=A,X=X.sibling;else for(X=A.child;X!==null;)G|=X.lanes|X.childLanes,H|=X.subtreeFlags,H|=X.flags,X.return=A,X=X.sibling;return A.subtreeFlags|=H,A.childLanes=G,Y}function R1(A,Y,G){var H=Y.pendingProps;switch(OX(Y),Y.tag){case 16:case 15:case 0:case 11:case 7:case 8:case 12:case 9:case 14:return i(Y),null;case 1:return i(Y),null;case 3:if(G=Y.stateNode,H=null,A!==null&&(H=A.memoizedState.cache),Y.memoizedState.cache!==H&&(Y.flags|=2048),BA(Y0),rY(),G.pendingContext&&(G.context=G.pendingContext,G.pendingContext=null),A===null||A.child===null)TY(Y)?HA(Y):A===null||A.memoizedState.isDehydrated&&(Y.flags&256)===0||(Y.flags|=1024,lH());return i(Y),null;case 26:var{type:X,memoizedState:w}=Y;return A===null?(HA(Y),w!==null?(i(Y),s9(Y,w)):(i(Y),tH(Y,X,null,H,G))):w?w!==A.memoizedState?(HA(Y),i(Y),s9(Y,w)):(i(Y),Y.flags&=-16777217):(A=A.memoizedProps,A!==H&&HA(Y),i(Y),tH(Y,X,A,H,G)),null;case 27:if(qG(Y),G=hA.current,X=Y.type,A!==null&&Y.stateNode!=null)A.memoizedProps!==H&&HA(Y);else{if(!H){if(Y.stateNode===null)throw Error(F(166));return i(Y),null}A=t0.current,TY(Y)?O9(Y,A):(A=nq(X,H,G),Y.stateNode=A,HA(Y))}return i(Y),null;case 5:if(qG(Y),X=Y.type,A!==null&&Y.stateNode!=null)A.memoizedProps!==H&&HA(Y);else{if(!H){if(Y.stateNode===null)throw Error(F(166));return i(Y),null}if(w=t0.current,TY(Y))O9(Y,w);else{var Z=CG(hA.current);switch(w){case 1:w=Z.createElementNS("http://www.w3.org/2000/svg",X);break;case 2:w=Z.createElementNS("http://www.w3.org/1998/Math/MathML",X);break;default:switch(X){case"svg":w=Z.createElementNS("http://www.w3.org/2000/svg",X);break;case"math":w=Z.createElementNS("http://www.w3.org/1998/Math/MathML",X);break;case"script":w=Z.createElement("div"),w.innerHTML="",w=w.removeChild(w.firstChild);break;case"select":w=typeof H.is==="string"?Z.createElement("select",{is:H.is}):Z.createElement("select"),H.multiple?w.multiple=!0:H.size&&(w.size=H.size);break;default:w=typeof H.is==="string"?Z.createElement(X,{is:H.is}):Z.createElement(X)}}w[q0]=Y,w[F0]=H;A:for(Z=Y.child;Z!==null;){if(Z.tag===5||Z.tag===6)w.appendChild(Z.stateNode);else if(Z.tag!==4&&Z.tag!==27&&Z.child!==null){Z.child.return=Z,Z=Z.child;continue}if(Z===Y)break A;for(;Z.sibling===null;){if(Z.return===null||Z.return===Y)break A;Z=Z.return}Z.sibling.return=Z.return,Z=Z.sibling}Y.stateNode=w;A:switch(J0(w,X,H),X){case"button":case"input":case"select":case"textarea":H=!!H.autoFocus;break A;case"img":H=!0;break A;default:H=!1}H&&HA(Y)}}return i(Y),tH(Y,Y.type,A===null?null:A.memoizedProps,Y.pendingProps,G),null;case 6:if(A&&Y.stateNode!=null)A.memoizedProps!==H&&HA(Y);else{if(typeof H!=="string"&&Y.stateNode===null)throw Error(F(166));if(A=hA.current,TY(Y)){if(A=Y.stateNode,G=Y.memoizedProps,H=null,X=U0,X!==null)switch(X.tag){case 27:case 5:H=X.memoizedProps}A[q0]=Y,A=A.nodeValue===G||H!==null&&H.suppressHydrationWarning===!0||sq(A.nodeValue,G)?!0:!1,A||pA(Y,!0)}else A=CG(A).createTextNode(H),A[q0]=Y,Y.stateNode=A}return i(Y),null;case 31:if(G=Y.memoizedState,A===null||A.memoizedState!==null){if(H=TY(Y),G!==null){if(A===null){if(!H)throw Error(F(318));if(A=Y.memoizedState,A=A!==null?A.dehydrated:null,!A)throw Error(F(557));A[q0]=Y}else qY(),(Y.flags&128)===0&&(Y.memoizedState=null),Y.flags|=4;i(Y),A=!1}else G=lH(),A!==null&&A.memoizedState!==null&&(A.memoizedState.hydrationErrors=G),A=!0;if(!A){if(Y.flags&256)return O0(Y),Y;return O0(Y),null}if((Y.flags&128)!==0)throw Error(F(558))}return i(Y),null;case 13:if(H=Y.memoizedState,A===null||A.memoizedState!==null&&A.memoizedState.dehydrated!==null){if(X=TY(Y),H!==null&&H.dehydrated!==null){if(A===null){if(!X)throw Error(F(318));if(X=Y.memoizedState,X=X!==null?X.dehydrated:null,!X)throw Error(F(317));X[q0]=Y}else qY(),(Y.flags&128)===0&&(Y.memoizedState=null),Y.flags|=4;i(Y),X=!1}else X=lH(),A!==null&&A.memoizedState!==null&&(A.memoizedState.hydrationErrors=X),X=!0;if(!X){if(Y.flags&256)return O0(Y),Y;return O0(Y),null}}if(O0(Y),(Y.flags&128)!==0)return Y.lanes=G,Y;return G=H!==null,A=A!==null&&A.memoizedState!==null,G&&(H=Y.child,X=null,H.alternate!==null&&H.alternate.memoizedState!==null&&H.alternate.memoizedState.cachePool!==null&&(X=H.alternate.memoizedState.cachePool.pool),w=null,H.memoizedState!==null&&H.memoizedState.cachePool!==null&&(w=H.memoizedState.cachePool.pool),w!==X&&(H.flags|=2048)),G!==A&&G&&(Y.child.flags|=8192),v4(Y,Y.updateQueue),i(Y),null;case 4:return rY(),A===null&&oX(Y.stateNode.containerInfo),i(Y),null;case 10:return BA(Y.type),i(Y),null;case 19:if(Z0(n),H=Y.memoizedState,H===null)return i(Y),null;if(X=(Y.flags&128)!==0,w=H.rendering,w===null)if(X)V6(H,!1);else{if(a!==0||A!==null&&(A.flags&128)!==0)for(A=Y.child;A!==null;){if(w=DG(A),w!==null){Y.flags|=128,V6(H,!1),A=w.updateQueue,Y.updateQueue=A,v4(Y,A),Y.subtreeFlags=0,A=G;for(G=Y.child;G!==null;)qW(G,A),G=G.sibling;return l(n,n.current&1|2),_&&WA(Y,H.treeForkCount),Y.child}A=A.sibling}H.tail!==null&&b0()>KG&&(Y.flags|=128,X=!0,V6(H,!1),Y.lanes=4194304)}else{if(!X)if(A=DG(w),A!==null){if(Y.flags|=128,X=!0,A=A.updateQueue,Y.updateQueue=A,v4(Y,A),V6(H,!0),H.tail===null&&H.tailMode==="hidden"&&!w.alternate&&!_)return i(Y),null}else 2*b0()-H.renderingStartTime>KG&&G!==536870912&&(Y.flags|=128,X=!0,V6(H,!1),Y.lanes=4194304);H.isBackwards?(w.sibling=Y.child,Y.child=w):(A=H.last,A!==null?A.sibling=w:Y.child=w,H.last=w)}if(H.tail!==null)return A=H.tail,H.rendering=A,H.tail=A.sibling,H.renderingStartTime=b0(),A.sibling=null,G=n.current,l(n,X?G&1|2:G&1),_&&WA(Y,H.treeForkCount),A;return i(Y),null;case 22:case 23:return O0(Y),NX(),H=Y.memoizedState!==null,A!==null?A.memoizedState!==null!==H&&(Y.flags|=8192):H&&(Y.flags|=8192),H?(G&536870912)!==0&&(Y.flags&128)===0&&(i(Y),Y.subtreeFlags&6&&(Y.flags|=8192)):i(Y),G=Y.updateQueue,G!==null&&v4(Y,G.retryQueue),G=null,A!==null&&A.memoizedState!==null&&A.memoizedState.cachePool!==null&&(G=A.memoizedState.cachePool.pool),H=null,Y.memoizedState!==null&&Y.memoizedState.cachePool!==null&&(H=Y.memoizedState.cachePool.pool),H!==G&&(Y.flags|=2048),A!==null&&Z0(wY),null;case 24:return G=null,A!==null&&(G=A.memoizedState.cache),Y.memoizedState.cache!==G&&(Y.flags|=2048),BA(Y0),i(Y),null;case 25:return null;case 30:return null}throw Error(F(156,Y.tag))}function B1(A,Y){switch(OX(Y),Y.tag){case 1:return A=Y.flags,A&65536?(Y.flags=A&-65537|128,Y):null;case 3:return BA(Y0),rY(),A=Y.flags,(A&65536)!==0&&(A&128)===0?(Y.flags=A&-65537|128,Y):null;case 26:case 27:case 5:return qG(Y),null;case 31:if(Y.memoizedState!==null){if(O0(Y),Y.alternate===null)throw Error(F(340));qY()}return A=Y.flags,A&65536?(Y.flags=A&-65537|128,Y):null;case 13:if(O0(Y),A=Y.memoizedState,A!==null&&A.dehydrated!==null){if(Y.alternate===null)throw Error(F(340));qY()}return A=Y.flags,A&65536?(Y.flags=A&-65537|128,Y):null;case 19:return Z0(n),null;case 4:return rY(),null;case 10:return BA(Y.type),null;case 22:case 23:return O0(Y),NX(),A!==null&&Z0(wY),A=Y.flags,A&65536?(Y.flags=A&-65537|128,Y):null;case 24:return BA(Y0),null;case 25:return null;default:return null}}function qq(A,Y){switch(OX(Y),Y.tag){case 3:BA(Y0),rY();break;case 26:case 27:case 5:qG(Y);break;case 4:rY();break;case 31:Y.memoizedState!==null&&O0(Y);break;case 13:O0(Y);break;case 19:Z0(n);break;case 10:BA(Y.type);break;case 22:case 23:O0(Y),NX(),A!==null&&Z0(wY);break;case 24:BA(Y0)}}function B4(A,Y){try{var G=Y.updateQueue,H=G!==null?G.lastEffect:null;if(H!==null){var X=H.next;G=X;do{if((G.tag&A)===A){H=void 0;var{create:w,inst:Z}=G;H=w(),Z.destroy=H}G=G.next}while(G!==X)}}catch(W){v(Y,Y.return,W)}}function sA(A,Y,G){try{var H=Y.updateQueue,X=H!==null?H.lastEffect:null;if(X!==null){var w=X.next;H=w;do{if((H.tag&A)===A){var Z=H.inst,W=Z.destroy;if(W!==void 0){Z.destroy=void 0,X=Y;var q=G,R=W;try{R()}catch(z){v(X,q,z)}}}H=H.next}while(H!==w)}}catch(z){v(Y,Y.return,z)}}function Uq(A){var Y=A.updateQueue;if(Y!==null){var G=A.stateNode;try{QW(Y,G)}catch(H){v(A,A.return,H)}}}function Mq(A,Y,G){G.props=RY(A.type,A.memoizedProps),G.state=A.memoizedState;try{G.componentWillUnmount()}catch(H){v(A,Y,H)}}function u6(A,Y){try{var G=A.ref;if(G!==null){switch(A.tag){case 26:case 27:case 5:var H=A.stateNode;break;case 30:H=A.stateNode;break;default:H=A.stateNode}typeof G==="function"?A.refCleanup=G(H):G.current=H}}catch(X){v(A,Y,X)}}function n0(A,Y){var{ref:G,refCleanup:H}=A;if(G!==null)if(typeof H==="function")try{H()}catch(X){v(A,Y,X)}finally{A.refCleanup=null,A=A.alternate,A!=null&&(A.refCleanup=null)}else if(typeof G==="function")try{G(null)}catch(X){v(A,Y,X)}else G.current=null}function Jq(A){var{type:Y,memoizedProps:G,stateNode:H}=A;try{A:switch(Y){case"button":case"input":case"select":case"textarea":G.autoFocus&&H.focus();break A;case"img":G.src?H.src=G.src:G.srcSet&&(H.srcset=G.srcSet)}}catch(X){v(A,A.return,X)}}function eH(A,Y,G){try{var H=A.stateNode;_1(H,A.type,G,Y),H[F0]=Y}catch(X){v(A,A.return,X)}}function Rq(A){return A.tag===5||A.tag===3||A.tag===26||A.tag===27&&aA(A.type)||A.tag===4}function A8(A){A:for(;;){for(;A.sibling===null;){if(A.return===null||Rq(A.return))return null;A=A.return}A.sibling.return=A.return;for(A=A.sibling;A.tag!==5&&A.tag!==6&&A.tag!==18;){if(A.tag===27&&aA(A.type))continue A;if(A.flags&2)continue A;if(A.child===null||A.tag===4)continue A;else A.child.return=A,A=A.child}if(!(A.flags&2))return A.stateNode}}function m8(A,Y,G){var H=A.tag;if(H===5||H===6)A=A.stateNode,Y?(G.nodeType===9?G.body:G.nodeName==="HTML"?G.ownerDocument.body:G).insertBefore(A,Y):(Y=G.nodeType===9?G.body:G.nodeName==="HTML"?G.ownerDocument.body:G,Y.appendChild(A),G=G._reactRootContainer,G!==null&&G!==void 0||Y.onclick!==null||(Y.onclick=MA));else if(H!==4&&(H===27&&aA(A.type)&&(G=A.stateNode,Y=null),A=A.child,A!==null))for(m8(A,Y,G),A=A.sibling;A!==null;)m8(A,Y,G),A=A.sibling}function OG(A,Y,G){var H=A.tag;if(H===5||H===6)A=A.stateNode,Y?G.insertBefore(A,Y):G.appendChild(A);else if(H!==4&&(H===27&&aA(A.type)&&(G=A.stateNode),A=A.child,A!==null))for(OG(A,Y,G),A=A.sibling;A!==null;)OG(A,Y,G),A=A.sibling}function Bq(A){var{stateNode:Y,memoizedProps:G}=A;try{for(var H=A.type,X=Y.attributes;X.length;)Y.removeAttributeNode(X[0]);J0(Y,H,G),Y[q0]=A,Y[F0]=G}catch(w){v(A,A.return,w)}}function L1(A,Y){if(A=A.containerInfo,n8=_G,A=AW(A),DX(A)){if("selectionStart"in A)var G={start:A.selectionStart,end:A.selectionEnd};else A:{G=(G=A.ownerDocument)&&G.defaultView||window;var H=G.getSelection&&G.getSelection();if(H&&H.rangeCount!==0){G=H.anchorNode;var{anchorOffset:X,focusNode:w}=H;H=H.focusOffset;try{G.nodeType,w.nodeType}catch(T){G=null;break A}var Z=0,W=-1,q=-1,R=0,z=0,Q=A,L=null;Y:for(;;){for(var f;;){if(Q!==G||X!==0&&Q.nodeType!==3||(W=Z+X),Q!==w||H!==0&&Q.nodeType!==3||(q=Z+H),Q.nodeType===3&&(Z+=Q.nodeValue.length),(f=Q.firstChild)===null)break;L=Q,Q=f}for(;;){if(Q===A)break Y;if(L===G&&++R===X&&(W=Z),L===w&&++z===H&&(q=Z),(f=Q.nextSibling)!==null)break;Q=L,L=Q.parentNode}Q=f}G=W===-1||q===-1?null:{start:W,end:q}}else G=null}G=G||{start:0,end:0}}else G=null;t8={focusedElem:A,selectionRange:G},_G=!1;for(X0=Y;X0!==null;)if(Y=X0,A=Y.child,(Y.subtreeFlags&1028)!==0&&A!==null)A.return=Y,X0=A;else for(;X0!==null;){switch(Y=X0,w=Y.alternate,A=Y.flags,Y.tag){case 0:if((A&4)!==0&&(A=Y.updateQueue,A=A!==null?A.events:null,A!==null))for(G=0;G title"));J0(w,H,G),w[q0]=A,w0(w),H=w;break A;case"link":var Z=LZ("link","href",X).get(H+(G.href||""));if(Z){for(var W=0;WP&&(Z=P,P=T,T=Z);var J=F9(W,T),U=F9(W,P);if(J&&U&&(f.rangeCount!==1||f.anchorNode!==J.node||f.anchorOffset!==J.offset||f.focusNode!==U.node||f.focusOffset!==U.offset)){var B=Q.createRange();B.setStart(J.node,J.offset),f.removeAllRanges(),T>P?(f.addRange(B),f.extend(U.node,U.offset)):(B.setEnd(U.node,U.offset),f.addRange(B))}}}}Q=[];for(f=W;f=f.parentNode;)f.nodeType===1&&Q.push({element:f,left:f.scrollLeft,top:f.scrollTop});typeof W.focus==="function"&&W.focus();for(W=0;WG?32:G,b.T=null,G=i8,i8=null;var w=dA,Z=LA;if(H0=0,Y6=dA=null,LA=0,(h&6)!==0)throw Error(F(331));var W=h;if(h|=4,Tq(w.current),Iq(w,w.current,Z,G),h=W,L4(0,!1),S0&&typeof S0.onPostCommitFiberRoot==="function")try{S0.onPostCommitFiberRoot(Z4,w)}catch(q){}return!0}finally{E.p=X,b.T=H,vq(A,Y)}}function t9(A,Y,G){Y=E0(G,Y),Y=v8(A.stateNode,Y,2),A=vA(A,Y,2),A!==null&&(q4(A,2),AA(A))}function v(A,Y,G){if(A.tag===3)t9(A,A,G);else for(;Y!==null;){if(Y.tag===3){t9(Y,A,G);break}else if(Y.tag===1){var H=Y.stateNode;if(typeof Y.type.getDerivedStateFromError==="function"||typeof H.componentDidCatch==="function"&&(uA===null||!uA.has(H))){A=E0(G,A),G=Yq(2),H=vA(Y,G,2),H!==null&&(Gq(G,H,Y,A),q4(H,2),AA(H));break}}Y=Y.return}}function H8(A,Y,G){var H=A.pingCache;if(H===null){H=A.pingCache=new D1;var X=new Set;H.set(Y,X)}else X=H.get(Y),X===void 0&&(X=new Set,H.set(Y,X));X.has(G)||(iX=!0,X.add(G),A=O1.bind(null,A,Y,G),Y.then(A,A))}function O1(A,Y,G){var H=A.pingCache;H!==null&&H.delete(Y),A.pingedLanes|=A.suspendedLanes&G,A.warmLanes&=~G,m===A&&(k&G)===G&&(a===4||a===3&&(k&62914560)===k&&300>b0()-sG?(h&2)===0&&G6(A,0):pX|=G,A6===k&&(A6=0)),AA(A)}function dq(A,Y){Y===0&&(Y=kZ()),A=zY(A,Y),A!==null&&(q4(A,Y),AA(A))}function K1(A){var Y=A.memoizedState,G=0;Y!==null&&(G=Y.retryLane),dq(A,G)}function T1(A,Y){var G=0;switch(A.tag){case 31:case 13:var{stateNode:H,memoizedState:X}=A;X!==null&&(G=X.retryLane);break;case 19:H=A.stateNode;break;case 22:H=A.stateNode._retryCache;break;default:throw Error(F(314))}H!==null&&H.delete(Y),dq(A,G)}function b1(A,Y){return qX(A,Y)}function AA(A){A!==NY&&A.next===null&&(NY===null?SG=NY=A:NY=NY.next=A),NG=!0,s8||(s8=!0,N1())}function L4(A,Y){if(!X8&&NG){X8=!0;do{var G=!1;for(var H=SG;H!==null;){if(!Y)if(A!==0){var X=H.pendingLanes;if(X===0)var w=0;else{var{suspendedLanes:Z,pingedLanes:W}=H;w=(1<<31-N0(42|A)+1)-1,w&=X&~(Z&~W),w=w&201326741?w&201326741|1:w?w|2:0}w!==0&&(G=!0,e9(H,w))}else w=k,w=hG(H,H===m?w:0,H.cancelPendingCommit!==null||H.timeoutHandle!==-1),(w&3)===0||W4(H,w)||(G=!0,e9(H,w));H=H.next}}while(G);X8=!1}}function S1(){mq()}function mq(){NG=s8=!1;var A=0;gA!==0&&g1()&&(A=gA);for(var Y=b0(),G=null,H=SG;H!==null;){var X=H.next,w=lq(H,Y);if(w===0)H.next=null,G===null?SG=X:G.next=X,X===null&&(NY=G);else if(G=H,A!==0||(w&3)!==0)NG=!0;H=X}H0!==0&&H0!==5||L4(A,!1),gA!==0&&(gA=0)}function lq(A,Y){for(var{suspendedLanes:G,pingedLanes:H,expirationTimes:X}=A,w=A.pendingLanes&-62914561;0W)break;var{transferSize:z,initiatorType:Q}=q;z&&XZ(Q)&&(q=q.responseEnd,Z+=z*(q title"):null)}function t1(A,Y,G){if(G===1||Y.itemProp!=null)return!1;switch(A){case"meta":case"title":return!0;case"style":if(typeof Y.precedence!=="string"||typeof Y.href!=="string"||Y.href==="")break;return!0;case"link":if(typeof Y.rel!=="string"||typeof Y.href!=="string"||Y.href===""||Y.onLoad||Y.onError)break;switch(Y.rel){case"stylesheet":return A=Y.disabled,typeof Y.precedence==="string"&&A==null;default:return!0}case"script":if(Y.async&&typeof Y.async!=="function"&&typeof Y.async!=="symbol"&&!Y.onLoad&&!Y.onError&&Y.src&&typeof Y.src==="string")return!0}return!1}function AU(A){return A.type==="stylesheet"&&(A.state.loading&3)===0?!1:!0}function e1(A,Y,G,H){if(G.type==="stylesheet"&&(typeof H.media!=="string"||matchMedia(H.media).matches!==!1)&&(G.state.loading&4)===0){if(G.instance===null){var X=H6(H.href),w=Y.querySelector(f4(X));if(w){Y=w._p,Y!==null&&typeof Y==="object"&&typeof Y.then==="function"&&(A.count++,A=xG.bind(A),Y.then(A,A)),G.state.loading|=4,G.instance=w,w0(w);return}w=Y.ownerDocument||Y,H=eq(H),(X=d0.get(X))&&aX(H,X),w=w.createElement("link"),w0(w);var Z=w;Z._p=new Promise(function(W,q){Z.onload=W,Z.onerror=q}),J0(w,"link",H),G.instance=w}A.stylesheets===null&&(A.stylesheets=new Map),A.stylesheets.set(G,Y),(Y=G.state.preload)&&(G.state.loading&3)===0&&(A.count++,G=xG.bind(A),Y.addEventListener("load",G),Y.addEventListener("error",G))}}function AR(A,Y){return A.stylesheets&&A.count===0&&XG(A,A.stylesheets),0q8?50:800)+Y);return A.unsuspend=G,function(){A.unsuspend=null,clearTimeout(H),clearTimeout(X)}}:null}function xG(){if(this.count--,this.count===0&&(this.imgCount===0||!this.waitingForImages)){if(this.stylesheets)XG(this,this.stylesheets);else if(this.unsuspend){var A=this.unsuspend;this.unsuspend=null,A()}}}function XG(A,Y){A.stylesheets=null,A.unsuspend!==null&&(A.count++,kG=new Map,Y.forEach(YR,A),kG=null,xG.call(A))}function YR(A,Y){if(!(Y.state.loading&4)){var G=kG.get(A);if(G)var H=G.get(null);else{G=new Map,kG.set(A,G);for(var X=A.querySelectorAll("link[data-precedence],style[data-precedence]"),w=0;w{kw();gG=m0(p0(),1),OZ=m0(tw(),1);s=Object.assign,uM=Symbol.for("react.element"),$4=Symbol.for("react.transitional.element"),K6=Symbol.for("react.portal"),CY=Symbol.for("react.fragment"),NZ=Symbol.for("react.strict_mode"),U8=Symbol.for("react.profiler"),jZ=Symbol.for("react.consumer"),UA=Symbol.for("react.context"),ZX=Symbol.for("react.forward_ref"),M8=Symbol.for("react.suspense"),J8=Symbol.for("react.suspense_list"),WX=Symbol.for("react.memo"),bA=Symbol.for("react.lazy"),R8=Symbol.for("react.activity"),dM=Symbol.for("react.memo_cache_sentinel"),A9=Symbol.iterator;mM=Symbol.for("react.client.reference");T6=Array.isArray,b=gG.__CLIENT_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE,E=OZ.__DOM_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE,HY={pending:!1,data:null,method:null,action:null},L8=[];t0=e0(null),i6=e0(null),hA=e0(null),ZG=e0(null);z8=Object.prototype.hasOwnProperty,qX=KY,PH=SH,cM=CH,iM=jH,b0=r0,pM=NH,CZ=KH,$Z=bH,UG=OY,sM=TH,xZ=OH,rM=void 0,oM=void 0;N0=Math.clz32?Math.clz32:tM,aM=Math.log,nM=Math.LN2;oA=Math.random().toString(36).slice(2),q0="__reactFiber$"+oA,F0="__reactProps$"+oA,w6="__reactContainer$"+oA,D8="__reactEvents$"+oA,YJ="__reactListeners$"+oA,GJ="__reactHandles$"+oA,X9="__reactResources$"+oA,U4="__reactMarker$"+oA;EZ=new Set,yZ={};HJ=RegExp("^[:A-Z_a-z\\u00C0-\\u00D6\\u00D8-\\u00F6\\u00F8-\\u02FF\\u0370-\\u037D\\u037F-\\u1FFF\\u200C-\\u200D\\u2070-\\u218F\\u2C00-\\u2FEF\\u3001-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFFD][:A-Z_a-z\\u00C0-\\u00D6\\u00D8-\\u00F6\\u00F8-\\u02FF\\u0370-\\u037D\\u037F-\\u1FFF\\u200C-\\u200D\\u2070-\\u218F\\u2C00-\\u2FEF\\u3001-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFFD\\-.0-9\\u00B7\\u0300-\\u036F\\u203F-\\u2040]*$"),w9={},Z9={};ZJ=/[\n"\\]/g;WJ=new Set("animationIterationCount aspectRatio borderImageOutset borderImageSlice borderImageWidth boxFlex boxFlexGroup boxOrdinalGroup columnCount columns flex flexGrow flexPositive flexShrink flexNegative flexOrder gridArea gridRow gridRowEnd gridRowSpan gridRowStart gridColumn gridColumnEnd gridColumnSpan gridColumnStart fontWeight lineClamp lineHeight opacity order orphans scale tabSize widows zIndex zoom fillOpacity floodOpacity stopOpacity strokeDasharray strokeDashoffset strokeMiterlimit strokeOpacity strokeWidth MozAnimationIterationCount MozBoxFlex MozBoxFlexGroup MozLineClamp msAnimationIterationCount msFlex msZoom msFlexGrow msFlexNegative msFlexOrder msFlexPositive msFlexShrink msGridColumn msGridColumnSpan msGridRow msGridRowSpan WebkitAnimationIterationCount WebkitBoxFlex WebKitBoxFlexGroup WebkitBoxOrdinalGroup WebkitColumnCount WebkitColumns WebkitFlex WebkitFlexGrow WebkitFlexPositive WebkitFlexShrink WebkitLineClamp".split(" "));qJ=new Map([["acceptCharset","accept-charset"],["htmlFor","for"],["httpEquiv","http-equiv"],["crossOrigin","crossorigin"],["accentHeight","accent-height"],["alignmentBaseline","alignment-baseline"],["arabicForm","arabic-form"],["baselineShift","baseline-shift"],["capHeight","cap-height"],["clipPath","clip-path"],["clipRule","clip-rule"],["colorInterpolation","color-interpolation"],["colorInterpolationFilters","color-interpolation-filters"],["colorProfile","color-profile"],["colorRendering","color-rendering"],["dominantBaseline","dominant-baseline"],["enableBackground","enable-background"],["fillOpacity","fill-opacity"],["fillRule","fill-rule"],["floodColor","flood-color"],["floodOpacity","flood-opacity"],["fontFamily","font-family"],["fontSize","font-size"],["fontSizeAdjust","font-size-adjust"],["fontStretch","font-stretch"],["fontStyle","font-style"],["fontVariant","font-variant"],["fontWeight","font-weight"],["glyphName","glyph-name"],["glyphOrientationHorizontal","glyph-orientation-horizontal"],["glyphOrientationVertical","glyph-orientation-vertical"],["horizAdvX","horiz-adv-x"],["horizOriginX","horiz-origin-x"],["imageRendering","image-rendering"],["letterSpacing","letter-spacing"],["lightingColor","lighting-color"],["markerEnd","marker-end"],["markerMid","marker-mid"],["markerStart","marker-start"],["overlinePosition","overline-position"],["overlineThickness","overline-thickness"],["paintOrder","paint-order"],["panose-1","panose-1"],["pointerEvents","pointer-events"],["renderingIntent","rendering-intent"],["shapeRendering","shape-rendering"],["stopColor","stop-color"],["stopOpacity","stop-opacity"],["strikethroughPosition","strikethrough-position"],["strikethroughThickness","strikethrough-thickness"],["strokeDasharray","stroke-dasharray"],["strokeDashoffset","stroke-dashoffset"],["strokeLinecap","stroke-linecap"],["strokeLinejoin","stroke-linejoin"],["strokeMiterlimit","stroke-miterlimit"],["strokeOpacity","stroke-opacity"],["strokeWidth","stroke-width"],["textAnchor","text-anchor"],["textDecoration","text-decoration"],["textRendering","text-rendering"],["transformOrigin","transform-origin"],["underlinePosition","underline-position"],["underlineThickness","underline-thickness"],["unicodeBidi","unicode-bidi"],["unicodeRange","unicode-range"],["unitsPerEm","units-per-em"],["vAlphabetic","v-alphabetic"],["vHanging","v-hanging"],["vIdeographic","v-ideographic"],["vMathematical","v-mathematical"],["vectorEffect","vector-effect"],["vertAdvY","vert-adv-y"],["vertOriginX","vert-origin-x"],["vertOriginY","vert-origin-y"],["wordSpacing","word-spacing"],["writingMode","writing-mode"],["xmlnsXlink","xmlns:xlink"],["xHeight","x-height"]]),UJ=/^[\u0000-\u001F ]*j[\r\n\t]*a[\r\n\t]*v[\r\n\t]*a[\r\n\t]*s[\r\n\t]*c[\r\n\t]*r[\r\n\t]*i[\r\n\t]*p[\r\n\t]*t[\r\n\t]*:/i;fA=!(typeof window>"u"||typeof window.document>"u"||typeof window.document.createElement>"u");if(fA)try{AY={},Object.defineProperty(AY,"passive",{get:function(){O8=!0}}),window.addEventListener("test",AY,AY),window.removeEventListener("test",AY,AY)}catch(A){O8=!1}LY={eventPhase:0,bubbles:0,cancelable:0,timeStamp:function(A){return A.timeStamp||Date.now()},defaultPrevented:0,isTrusted:0},EG=V0(LY),M4=s({},LY,{view:0,detail:0}),MJ=V0(M4),yG=s({},M4,{screenX:0,screenY:0,clientX:0,clientY:0,pageX:0,pageY:0,ctrlKey:0,shiftKey:0,altKey:0,metaKey:0,getModifierState:fX,button:0,buttons:0,relatedTarget:function(A){return A.relatedTarget===void 0?A.fromElement===A.srcElement?A.toElement:A.fromElement:A.relatedTarget},movementX:function(A){if("movementX"in A)return A.movementX;return A!==Q6&&(Q6&&A.type==="mousemove"?(EH=A.screenX-Q6.screenX,yH=A.screenY-Q6.screenY):yH=EH=0,Q6=A),EH},movementY:function(A){return"movementY"in A?A.movementY:yH}}),M9=V0(yG),JJ=s({},yG,{dataTransfer:0}),RJ=V0(JJ),BJ=s({},M4,{relatedTarget:0}),vH=V0(BJ),LJ=s({},LY,{animationName:0,elapsedTime:0,pseudoElement:0}),fJ=V0(LJ),zJ=s({},LY,{clipboardData:function(A){return"clipboardData"in A?A.clipboardData:window.clipboardData}}),DJ=V0(zJ),QJ=s({},LY,{data:0}),J9=V0(QJ),FJ={Esc:"Escape",Spacebar:" ",Left:"ArrowLeft",Up:"ArrowUp",Right:"ArrowRight",Down:"ArrowDown",Del:"Delete",Win:"OS",Menu:"ContextMenu",Apps:"ContextMenu",Scroll:"ScrollLock",MozPrintableKey:"Unidentified"},VJ={8:"Backspace",9:"Tab",12:"Clear",13:"Enter",16:"Shift",17:"Control",18:"Alt",19:"Pause",20:"CapsLock",27:"Escape",32:" ",33:"PageUp",34:"PageDown",35:"End",36:"Home",37:"ArrowLeft",38:"ArrowUp",39:"ArrowRight",40:"ArrowDown",45:"Insert",46:"Delete",112:"F1",113:"F2",114:"F3",115:"F4",116:"F5",117:"F6",118:"F7",119:"F8",120:"F9",121:"F10",122:"F11",123:"F12",144:"NumLock",145:"ScrollLock",224:"Meta"},IJ={Alt:"altKey",Control:"ctrlKey",Meta:"metaKey",Shift:"shiftKey"};KJ=s({},M4,{key:function(A){if(A.key){var Y=FJ[A.key]||A.key;if(Y!=="Unidentified")return Y}return A.type==="keypress"?(A=s4(A),A===13?"Enter":String.fromCharCode(A)):A.type==="keydown"||A.type==="keyup"?VJ[A.keyCode]||"Unidentified":""},code:0,location:0,ctrlKey:0,shiftKey:0,altKey:0,metaKey:0,repeat:0,locale:0,getModifierState:fX,charCode:function(A){return A.type==="keypress"?s4(A):0},keyCode:function(A){return A.type==="keydown"||A.type==="keyup"?A.keyCode:0},which:function(A){return A.type==="keypress"?s4(A):A.type==="keydown"||A.type==="keyup"?A.keyCode:0}}),TJ=V0(KJ),bJ=s({},yG,{pointerId:0,width:0,height:0,pressure:0,tangentialPressure:0,tiltX:0,tiltY:0,twist:0,pointerType:0,isPrimary:0}),R9=V0(bJ),SJ=s({},M4,{touches:0,targetTouches:0,changedTouches:0,altKey:0,metaKey:0,ctrlKey:0,shiftKey:0,getModifierState:fX}),NJ=V0(SJ),jJ=s({},LY,{propertyName:0,elapsedTime:0,pseudoElement:0}),CJ=V0(jJ),$J=s({},yG,{deltaX:function(A){return"deltaX"in A?A.deltaX:("wheelDeltaX"in A)?-A.wheelDeltaX:0},deltaY:function(A){return"deltaY"in A?A.deltaY:("wheelDeltaY"in A)?-A.wheelDeltaY:("wheelDelta"in A)?-A.wheelDelta:0},deltaZ:0,deltaMode:0}),xJ=V0($J),kJ=s({},LY,{newState:0,oldState:0}),_J=V0(kJ),PJ=[9,13,27,32],zX=fA&&"CompositionEvent"in window;fA&&"documentMode"in document&&(k6=document.documentMode);gJ=fA&&"TextEvent"in window&&!k6,sZ=fA&&(!zX||k6&&8=k6),B9=String.fromCharCode(32);yJ={color:!0,date:!0,datetime:!0,"datetime-local":!0,email:!0,month:!0,number:!0,password:!0,range:!0,search:!0,tel:!0,text:!0,time:!0,url:!0,week:!0};if(fA){if(fA){if(N6="oninput"in document,!N6)r4=document.createElement("div"),r4.setAttribute("oninput","return;"),N6=typeof r4.oninput==="function";S6=N6}else S6=!1;nZ=S6&&(!document.documentMode||9=document.documentMode;gY={animationend:nA("Animation","AnimationEnd"),animationiteration:nA("Animation","AnimationIteration"),animationstart:nA("Animation","AnimationStart"),transitionrun:nA("Transition","TransitionRun"),transitionstart:nA("Transition","TransitionStart"),transitioncancel:nA("Transition","TransitionCancel"),transitionend:nA("Transition","TransitionEnd")},uH={},YW={};fA&&(YW=document.createElement("div").style,("AnimationEvent"in window)||(delete gY.animationend.animation,delete gY.animationiteration.animation,delete gY.animationstart.animation),("TransitionEvent"in window)||delete gY.transitionend.transition);GW=fY("animationend"),HW=fY("animationiteration"),XW=fY("animationstart"),pJ=fY("transitionrun"),sJ=fY("transitionstart"),rJ=fY("transitioncancel"),wW=fY("transitionend"),ZW=new Map,b8="abort auxClick beforeToggle cancel canPlay canPlayThrough click close contextMenu copy cut drag dragEnd dragEnter dragExit dragLeave dragOver dragStart drop durationChange emptied encrypted ended error gotPointerCapture input invalid keyDown keyPress keyUp load loadedData loadedMetadata loadStart lostPointerCapture mouseDown mouseMove mouseOut mouseOver mouseUp paste pause play playing pointerCancel pointerDown pointerMove pointerOut pointerOver pointerUp progress rateChange reset resize seeked seeking stalled submit suspend timeUpdate touchCancel touchEnd touchStart volumeChange scroll toggle touchMove waiting wheel".split(" ");b8.push("scrollEnd");JG=typeof reportError==="function"?reportError:function(A){if(typeof window==="object"&&typeof window.ErrorEvent==="function"){var Y=new window.ErrorEvent("error",{bubbles:!0,cancelable:!0,message:typeof A==="object"&&A!==null&&typeof A.message==="string"?String(A.message):String(A),error:A});if(!window.dispatchEvent(Y))return}else if(typeof process==="object"&&typeof process.emit==="function"){process.emit("uncaughtException",A);return}console.error(A)},k0=[];EY={};I9=new WeakMap;yY=[],P0=[];S8=Error(F(519));N8=e0(null);aJ=typeof AbortController<"u"?AbortController:function(){var A=[],Y=this.signal={aborted:!1,addEventListener:function(G,H){A.push(H)}};this.abort=function(){Y.aborted=!0,A.forEach(function(G){return G()})}},nJ=KY,tJ=OY,Y0={$$typeof:UA,Consumer:null,Provider:null,_currentValue:null,_currentValue2:null,_threadCount:0};b9=b.S;b.S=function(A,Y){Sq=b0(),typeof Y==="object"&&Y!==null&&typeof Y.then==="function"&&eJ(A,Y),b9!==null&&b9(A,Y)};wY=e0(null);q6=Error(F(460)),bX=Error(F(474)),mG=Error(F(542)),fG={then:function(){}};MY=fW(!0),zW=fW(!1);tY=e0(null),zG=e0(0);$0=e0(null);n=e0(0);e6={readContext:M0,use:cG,useCallback:o,useContext:o,useEffect:o,useImperativeHandle:o,useLayoutEffect:o,useInsertionEffect:o,useMemo:o,useReducer:o,useRef:o,useState:o,useDebugValue:o,useDeferredValue:o,useTransition:o,useSyncExternalStore:o,useId:o,useHostTransitionStatus:o,useFormState:o,useActionState:o,useOptimistic:o,useMemoCache:o,useCacheRefresh:o};e6.useEffectEvent=o;aW={readContext:M0,use:cG,useCallback:function(A,Y){return B0().memoizedState=[A,Y===void 0?null:Y],A},useContext:M0,useEffect:g9,useImperativeHandle:function(A,Y,G){G=G!==null&&G!==void 0?G.concat([A]):null,t4(4194308,4,EW.bind(null,Y,A),G)},useLayoutEffect:function(A,Y){return t4(4194308,4,A,Y)},useInsertionEffect:function(A,Y){t4(4,2,A,Y)},useMemo:function(A,Y){var G=B0();Y=Y===void 0?null:Y;var H=A();if(JY){xA(!0);try{A()}finally{xA(!1)}}return G.memoizedState=[H,Y],H},useReducer:function(A,Y,G){var H=B0();if(G!==void 0){var X=G(Y);if(JY){xA(!0);try{G(Y)}finally{xA(!1)}}}else X=Y;return H.memoizedState=H.baseState=X,A={pending:null,lanes:0,dispatch:null,lastRenderedReducer:A,lastRenderedState:X},H.queue=A,A=A.dispatch=q1.bind(null,S,A),[H.memoizedState,A]},useRef:function(A){var Y=B0();return A={current:A},Y.memoizedState=A},useState:function(A){A=g8(A);var Y=A.queue,G=sW.bind(null,S,Y);return Y.dispatch=G,[A.memoizedState,G]},useDebugValue:hX,useDeferredValue:function(A,Y){var G=B0();return EX(G,A,Y)},useTransition:function(){var A=g8(!1);return A=mW.bind(null,S,A.queue,!0,!1),B0().memoizedState=A,[!1,A]},useSyncExternalStore:function(A,Y,G){var H=S,X=B0();if(_){if(G===void 0)throw Error(F(407));G=G()}else{if(G=Y(),m===null)throw Error(F(349));(k&127)!==0||KW(H,Y,G)}X.memoizedState=G;var w={value:G,getSnapshot:Y};return X.queue=w,g9(bW.bind(null,H,w,A),[A]),H.flags|=2048,eY(9,{destroy:void 0},TW.bind(null,H,w,G,Y),null),G},useId:function(){var A=B0(),Y=m.identifierPrefix;if(_){var G=a0,H=o0;G=(H&~(1<<32-N0(H)-1)).toString(32)+G,Y="_"+Y+"R_"+G,G=FG++,0"u"?null:document;G4={$$typeof:UA,Provider:null,Consumer:null,_currentValue:HY,_currentValue2:HY,_threadCount:0};H4=new Map,X4=new Map,$A=[],wR="mousedown mouseup touchcancel touchend touchstart auxclick dblclick pointercancel pointerdown pointerup dragend dragstart drop compositionend compositionstart keydown keypress keyup input textInput copy cut paste click change contextmenu reset".split(" ");nG.prototype.render=Yw.prototype.render=function(A){var Y=this._internalRoot;if(Y===null)throw Error(F(409));var G=Y.current,H=j0();HU(G,H,A,Y,null,null)};nG.prototype.unmount=Yw.prototype.unmount=function(){var A=this._internalRoot;if(A!==null){this._internalRoot=null;var Y=A.containerInfo;HU(A.current,2,null,A,null,null),rG(),Y[w6]=null}};nG.prototype.unstable_scheduleHydration=function(A){if(A){var Y=hZ();A={blockedOn:null,target:A,priority:Y};for(var G=0;G<$A.length&&Y!==0&&Y<$A[G].priority;G++);$A.splice(G,0,A),G===0&&ZU(A)}};IZ=gG.version;if(IZ!=="19.2.3")throw Error(F(527,IZ,"19.2.3"));E.findDOMNode=function(A){var Y=A._reactInternals;if(Y===void 0){if(typeof A.render==="function")throw Error(F(188));throw A=Object.keys(A).join(","),Error(F(268,A))}return A=vM(Y),A=A!==null?SZ(A):null,A=A===null?null:A.stateNode,A};qR={bundleType:0,version:"19.2.3",rendererPackageName:"react-dom",currentDispatcherRef:b,reconcilerVersion:"19.2.3"};if(typeof __REACT_DEVTOOLS_GLOBAL_HOOK__<"u"){if(jY=__REACT_DEVTOOLS_GLOBAL_HOOK__,!jY.isDisabled&&jY.supportsFiber)try{Z4=jY.inject(qR),S0=jY}catch(A){}}});var LU=XH((KR,BU)=>{JU();function RU(){if(typeof __REACT_DEVTOOLS_GLOBAL_HOOK__>"u"||typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE!=="function")return;try{__REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE(RU)}catch(A){console.error(A)}}RU(),BU.exports=Gw});var fw=m0(p0(),1),GH=m0(LU(),1);var D4=m0(p0(),1),Hw={},fU=D4.default.createContext(Hw);function Q4(A){let Y=D4.default.useContext(fU);return D4.default.useMemo(function(){if(typeof A==="function")return A(Y);return{...Y,...A}},[Y,A])}function Xw(A){let Y;if(A.disableParentContext)Y=typeof A.components==="function"?A.components(Hw):A.components||Hw;else Y=Q4(A.components);return D4.default.createElement(fU.Provider,{value:Y},A.children)}var JR=Symbol.for("react.transitional.element"),RR=Symbol.for("react.fragment");function zU(A,Y,G){var H=null;if(G!==void 0&&(H=""+G),Y.key!==void 0&&(H=""+Y.key),"key"in Y){G={};for(var X in Y)X!=="key"&&(G[X]=Y[X])}else G=Y;return Y=G.ref,{$$typeof:JR,type:A,key:H,ref:Y!==void 0?Y:null,props:G}}var F4=RR,M=zU,O=zU;function ww({children:A}){return M("span",{className:"font-bold bg-gradient-to-t from-red-600 via-orange-500 to-yellow-400 bg-clip-text text-transparent animate-pulse",children:A})}var I4=m0(p0(),1);var DU="scratch-demo-todos",V4=null,Zw=new Set;function R6(){if(V4===null)if(typeof window>"u")V4=[];else{let A=localStorage.getItem(DU);V4=A?JSON.parse(A):[]}return V4}function BR(A){if(typeof window>"u")return;localStorage.setItem(DU,JSON.stringify(A))}function LR(){Zw.forEach((A)=>A(R6()))}function fR(){let[A,Y]=I4.useState(()=>R6());I4.useEffect(()=>{Y(R6());let W=(q)=>Y(q);return Zw.add(W),()=>{Zw.delete(W)}},[]);let G=(W)=>{V4=W,BR(W),LR()};return{todos:A,addTodo:(W)=>{if(!W.trim())return;G([...R6(),{id:Date.now(),text:W.trim(),completed:!1}])},toggleTodo:(W)=>{G(R6().map((q)=>q.id===W?{...q,completed:!q.completed}:q))},deleteTodo:(W)=>{G(R6().filter((q)=>q.id!==W))},reset:()=>{G([])}}}function Ww(){let{todos:A,addTodo:Y,toggleTodo:G,deleteTodo:H,reset:X}=fR(),[w,Z]=I4.useState(""),W=()=>{Y(w),Z("")};return O("div",{className:"not-prose border border-gray-200 rounded-lg p-4 my-12 mx-2 sm:mx-8 md:mx-16 bg-gray-50",children:[O("div",{className:"flex gap-2 mb-4",children:[M("input",{type:"text",value:w,onChange:(q)=>Z(q.target.value),onKeyDown:(q)=>q.key==="Enter"&&W(),placeholder:"Add a todo...",className:"flex-1 px-3 py-2 border border-gray-300 rounded-md bg-white text-gray-900 placeholder-gray-400"}),M("button",{onClick:W,className:"px-4 py-2 bg-gray-900 text-white rounded-md hover:bg-gray-700 transition-colors",children:"Add"})]}),A.length===0?M("p",{className:"text-gray-500 text-center py-4",children:"No todos yet. Add one above!"}):M("ul",{className:"space-y-2",children:A.map((q)=>O("li",{className:"flex items-center gap-3 p-2 rounded-md hover:bg-gray-100",children:[M("input",{type:"checkbox",checked:q.completed,onChange:()=>G(q.id),className:"w-4 h-4 rounded border-gray-300"}),M("span",{className:`flex-1 ${q.completed?"line-through text-gray-400":"text-gray-900"}`,children:q.text}),M("button",{onClick:()=>H(q.id),className:"text-gray-400 hover:text-red-500 transition-colors","aria-label":"Delete todo",children:M("svg",{xmlns:"http://www.w3.org/2000/svg",className:"h-5 w-5",viewBox:"0 0 20 20",fill:"currentColor",children:M("path",{fillRule:"evenodd",d:"M4.293 4.293a1 1 0 011.414 0L10 8.586l4.293-4.293a1 1 0 111.414 1.414L11.414 10l4.293 4.293a1 1 0 01-1.414 1.414L10 11.414l-4.293 4.293a1 1 0 01-1.414-1.414L8.586 10 4.293 5.707a1 1 0 010-1.414z",clipRule:"evenodd"})})})]},q.id))}),O("div",{className:"mt-4 pt-4 border-t border-gray-200 flex justify-between items-center",children:[O("span",{className:"text-sm text-gray-500",children:[A.filter((q)=>!q.completed).length," remaining"]}),M("button",{onClick:X,className:"text-sm text-gray-500 hover:text-gray-700 transition-colors",children:"Reset"})]})]})}var IA=m0(p0(),1);function qw(){let A=IA.useRef(null),[Y,G]=IA.useState(0),[H,X]=IA.useState({x:20,y:20}),[w,Z]=IA.useState({x:2,y:1.5}),[W,q]=IA.useState("#8b5cf6"),R=80,z=40,Q=["#8b5cf6","#ec4899","#f59e0b","#10b981","#3b82f6","#ef4444"],L=()=>{let f=Q[Math.floor(Math.random()*Q.length)];return f===W?Q[(Q.indexOf(W)+1)%Q.length]:f};return IA.useEffect(()=>{let f=A.current;if(!f)return;let T=setInterval(()=>{X((P)=>{let{clientWidth:J,clientHeight:U}=f,B=P.x+w.x,D=P.y+w.y,K=!1,$=!1;if(B<=0)B=0,K=!0,Z((V)=>({...V,x:Math.abs(V.x)})),q(L());else if(B>=J-80)B=J-80,K=!0,Z((V)=>({...V,x:-Math.abs(V.x)})),q(L());if(D<=0){if(D=0,$=!0,Z((V)=>({...V,y:Math.abs(V.y)})),!K)q(L())}else if(D>=U-40){if(D=U-40,$=!0,Z((V)=>({...V,y:-Math.abs(V.y)})),!K)q(L())}if(K&&$)G((V)=>V+1);return{x:B,y:D}})},16);return()=>clearInterval(T)},[w]),O("div",{className:"not-prose my-6 mx-12",children:[M("div",{className:"bg-gradient-to-b from-gray-700 via-gray-800 to-gray-900 p-3 rounded-2xl shadow-xl",children:M("div",{className:"bg-black p-1 rounded-lg",children:O("div",{ref:A,className:"relative w-full h-48 rounded overflow-hidden",style:{background:"linear-gradient(145deg, #1a1a2e 0%, #0f0f1a 50%, #1a1a2e 100%)"},children:[M("div",{className:"absolute",style:{left:H.x,top:H.y,width:80,height:40},children:M("div",{className:"transition-colors duration-300",style:{width:"100%",height:"100%",backgroundColor:W,maskImage:"url(/DVD_logo.svg)",maskSize:"contain",maskRepeat:"no-repeat",maskPosition:"center",WebkitMaskImage:"url(/DVD_logo.svg)",WebkitMaskSize:"contain",WebkitMaskRepeat:"no-repeat",WebkitMaskPosition:"center"}})}),M("div",{className:"absolute inset-0 pointer-events-none",style:{background:"linear-gradient(135deg, rgba(255,255,255,0.08) 0%, transparent 50%, transparent 100%)"}})]})})}),O("p",{className:"text-center text-sm text-gray-500 mt-3",children:["Corner hits: ",Y]})]})}function zR(A){let Y=A.trim().split(`
-`),G=[],H=[];for(let X of Y){if(!X.trim())continue;let w=X.match(/[^\s│|├└─]/);if(!w)continue;let Z=w.index,W=X.slice(0,Z),q=X.slice(Z).trim();if(!q)continue;let R=W.includes("└"),z=W.includes("├")||W.includes("└"),Q=(W.match(/[│|]/g)||[]).length,L;if(!z&&W.length===0)L=0,H.length=0;else{while(H.length>0){if(H.filter((P)=>!P.isLast).length<=Q)break;H.pop()}L=H.length+1}if(R)while(H.length>=L)H.pop();let f=H.map((T)=>T.isLast),I=q.endsWith("/")||!q.includes(".");if(G.push({name:q,depth:L,isLast:R,parentIsLast:f}),I)H.push({depth:L,isLast:R})}return G}function DR({node:A}){let Y=A.name.endsWith("/")||!A.name.includes(".");return O("div",{className:"flex items-stretch h-7 font-mono text-sm",children:[A.parentIsLast.map((G,H)=>M("div",{className:"w-5 flex-shrink-0 relative",children:!G&&M("div",{className:"absolute left-2 top-0 bottom-0 w-px bg-gray-300"})},H)),A.depth>0&&O("div",{className:"w-5 flex-shrink-0 relative",children:[M("div",{className:`absolute left-2 w-px bg-gray-300 ${A.isLast?"top-0 h-1/2":"top-0 bottom-0"}`}),M("div",{className:"absolute left-2 top-1/2 w-3 h-px bg-gray-300"})]}),M("span",{className:`flex items-center ${Y?"text-gray-700 font-bold":"text-gray-600"}`,children:A.name})]})}function tG(A){if(typeof A==="string")return A;if(typeof A==="number")return String(A);if(!A)return"";if(Array.isArray(A))return A.map(tG).join(`
-`);if(typeof A==="object"&&"props"in A){let Y=A;if(Y.type==="p"||Y.type==="br")return tG(Y.props.children)+`
-`;return tG(Y.props.children)}return""}function eG({children:A}){let Y=tG(A),G=zR(Y);return M("div",{className:"not-prose my-6 py-4 px-4",children:G.map((H,X)=>M(DR,{node:H},X))})}var QR=m0(p0(),1);function Uw({children:A}){return O("div",{className:"min-h-screen bg-white prose max-w-2xl mx-auto px-6 py-8",children:[O("div",{className:"not-prose flex justify-center gap-4 mb-4",children:[M("a",{href:"https://github.com/scratch/scratch",target:"_blank",rel:"noopener noreferrer",className:"opacity-30 hover:opacity-100 transition-opacity",children:M("img",{src:"/github-mark.svg",alt:"GitHub",className:"w-6 h-6"})}),M("a",{href:"https://x.com/koomen",target:"_blank",rel:"noopener noreferrer",className:"opacity-30 hover:opacity-100 transition-opacity",children:M("img",{src:"/x-logo.svg",alt:"X",className:"w-6 h-6"})})]}),A,O("footer",{className:"text-center text-gray-400 text-sm mt-16 pb-8",children:["Released under the MIT License",M("br",{}),"Copyright 2025 Pete Koomen"]})]})}function QU(A){let Y={a:"a",code:"code",div:"div",h2:"h2",p:"p",pre:"pre",span:"span",strong:"strong",table:"table",tbody:"tbody",td:"td",th:"th",thead:"thead",tr:"tr",...Q4(),...A.components};return O(Uw,{children:[M("div",{className:"not-prose flex flex-col items-center justify-center mb-8",children:M("img",{src:"/scratch-logo.svg",alt:"Scratch",height:"120"})}),M(Y.p,{children:"Scratch compiles Markdown and React into beautiful static websites that can be hosted anywhere."}),M(Y.h2,{children:"Quick Start"}),M(F4,{children:M(Y.pre,{className:"shiki github-light",style:{backgroundColor:"#fff",color:"#24292e"},tabIndex:"0",children:O(Y.code,{children:[M(Y.span,{className:"line",children:M(Y.span,{style:{color:"#6A737D"},children:"# Install scratch"})}),`
-`,O(Y.span,{className:"line",children:[M(Y.span,{style:{color:"#6F42C1"},children:"curl"}),M(Y.span,{style:{color:"#005CC5"},children:" -fsSL"}),M(Y.span,{style:{color:"#032F62"},children:" https://scratch.dev/install.sh"}),M(Y.span,{style:{color:"#D73A49"},children:" |"}),M(Y.span,{style:{color:"#6F42C1"},children:" bash"})]}),`
-`,M(Y.span,{className:"line"}),`
-`,M(Y.span,{className:"line",children:M(Y.span,{style:{color:"#6A737D"},children:"# Create a new project"})}),`
-`,O(Y.span,{className:"line",children:[M(Y.span,{style:{color:"#6F42C1"},children:"scratch"}),M(Y.span,{style:{color:"#032F62"},children:" create"})]}),`
-`,M(Y.span,{className:"line"}),`
-`,M(Y.span,{className:"line",children:M(Y.span,{style:{color:"#6A737D"},children:"# Start the dev server"})}),`
-`,O(Y.span,{className:"line",children:[M(Y.span,{style:{color:"#6F42C1"},children:"scratch"}),M(Y.span,{style:{color:"#032F62"},children:" dev"})]})]})})}),M(Y.h2,{children:"What can you do with Scratch?"}),O(Y.p,{children:["Scratch was designed for collaborative writing with coding agents like ",M(Y.a,{href:"https://www.claude.com/product/claude-code",children:"Claude Code"}),". Use your favorite editor to write in ",M(Y.a,{href:"https://daringfireball.net/projects/markdown/",children:"Markdown"})," and embed React components when it's easier to express yourself with code."]}),M(Y.p,{children:"Scratch supports Github-flavored Markdown features like tables and todolists:"}),O(Y.table,{children:[M(Y.thead,{children:O(Y.tr,{children:[M(Y.th,{children:"Feature"}),M(Y.th,{children:"Supported?"})]})}),O(Y.tbody,{children:[O(Y.tr,{children:[O(Y.td,{children:["Compiles ",M(Y.code,{children:".md"})," ",M(Y.code,{children:".mdx"})," ",M(Y.code,{children:".tsx"})," ",M(Y.code,{children:".ts"})," ",M(Y.code,{children:".jsx"})," ",M(Y.code,{children:".js"})]}),M(Y.td,{children:"✅"})]}),O(Y.tr,{children:[M(Y.td,{children:"Dev server with HMR"}),M(Y.td,{children:"✅"})]}),O(Y.tr,{children:[M(Y.td,{children:"Tailwind CSS styling"}),M(Y.td,{children:"✅"})]}),O(Y.tr,{children:[M(Y.td,{children:"Code syntax highlighting"}),M(Y.td,{children:"✅"})]})]})]}),O(Y.p,{children:["Code blocks use syntax highlighting by ",M(Y.a,{href:"https://shiki.style/",children:"Shiki"}),":"]}),M(F4,{children:M(Y.pre,{className:"shiki github-light",style:{backgroundColor:"#fff",color:"#24292e"},tabIndex:"0",children:O(Y.code,{children:[O(Y.span,{className:"line",children:[M(Y.span,{style:{color:"#D73A49"},children:"def"}),M(Y.span,{style:{color:"#6F42C1"},children:" greet"}),M(Y.span,{style:{color:"#24292E"},children:"(name: "}),M(Y.span,{style:{color:"#005CC5"},children:"str"}),M(Y.span,{style:{color:"#24292E"},children:") -> "}),M(Y.span,{style:{color:"#005CC5"},children:"str"}),M(Y.span,{style:{color:"#24292E"},children:":"})]}),`
-`,O(Y.span,{className:"line",children:[M(Y.span,{style:{color:"#D73A49"},children:" return"}),M(Y.span,{style:{color:"#D73A49"},children:" f"}),M(Y.span,{style:{color:"#032F62"},children:'"Hello, '}),M(Y.span,{style:{color:"#005CC5"},children:"{"}),M(Y.span,{style:{color:"#24292E"},children:"name"}),M(Y.span,{style:{color:"#005CC5"},children:"}"}),M(Y.span,{style:{color:"#032F62"},children:'!"'})]}),`
-`,M(Y.span,{className:"line"}),`
-`,O(Y.span,{className:"line",children:[M(Y.span,{style:{color:"#005CC5"},children:"print"}),M(Y.span,{style:{color:"#24292E"},children:"(greet("}),M(Y.span,{style:{color:"#032F62"},children:'"World"'}),M(Y.span,{style:{color:"#24292E"},children:"))"})]})]})})}),O(Y.p,{children:["You can use React components to ",M(ww,{children:"style text"})," or embed fully working demos in your product specs:"]}),M(Y.div,{className:"not-prose",children:M(Ww,{})}),M(Y.p,{children:"In fact, coding agents have gotten so good that if you can describe it, you can add it to a document:"}),M(Y.div,{className:"not-prose",children:M(qw,{})}),M(Y.h2,{children:"No Boilerplate"}),O(Y.p,{children:["Scratch uses an opinionated project structure and requires ",M(Y.strong,{children:"no boilerplate or configuration"}),": just create a project, run the dev server with ",M(Y.code,{children:"scratch dev"}),", and start writing."]}),O(Y.p,{children:["A simple Scratch project (created with ",M(Y.code,{children:"scratch create"}),") looks like this:"]}),M(eG,{children:M(Y.p,{children:`mysite/
-├── pages/
-│ ├── index.mdx
-│ ├── Counter.tsx
-│ └── examples/
-│ ├── index.md
-│ ├── markdown.md
-│ ├── todolist-spec.mdx
-│ └── TodoList.tsx
-└── public/
-├── logo.png
-└── favicon.svg`})}),O(Y.p,{children:["Use ",M(Y.code,{children:"scratch build"})," to compile this project into a ",M(Y.a,{href:"https://scratch.dev/template",children:"static website"}),"."]}),O(Y.p,{children:["Borrowing heavily from ",M(Y.a,{href:"https://github.com/tailwindlabs/tailwindcss-typography",children:"Tailwind Typography"}),", Scratch uses default styles and Markdown components to render your prose with a clean aesthetic. Code blocks use syntax highlighting by ",M(Y.a,{href:"https://shiki.style/",children:"Shiki"}),"."]}),O(Y.p,{children:["You can change styles and customize the page wrapper component by including the ",M(Y.code,{children:"src/"})," directory when you run ",M(Y.code,{children:"scratch create"}),":"]}),M(eG,{children:M(Y.p,{children:`mysite/
-├── pages/
-├── public/
-└── src/
-├── markdown/
-├── PageWrapper.tsx
-└── tailwind.css`})}),O(Y.p,{children:["Component files and js/ts libraries can live anywhere in ",M(Y.code,{children:"pages/"})," and ",M(Y.code,{children:"src/"}),". They are auto-detected by Scratch and don't need to be explicitly imported in your .mdx files as long as the filename matches the component name."]}),O(Y.p,{children:["Scratch installs build dependencies automatically. You can add additional third-party dependencies by including a ",M(Y.code,{children:"package.json"})," file in your project root."]}),M(Y.h2,{children:"Built on Bun"}),O(Y.p,{children:["Scratch is built on ",M(Y.a,{href:"https://bun.com/",children:"Bun"})," for lightning-fast builds, development with HMR, and native typescript support. It uses the ",M(Y.a,{href:"https://tailwindcss.com/",children:"Tailwind CSS"})," framework to make component styling easy."]}),M(Y.p,{children:"Scratch compiles Javascript (.js), Typescript (.ts), JSX (.jsx), TSX (.tsx), Markdown (.md), and MDX (.mdx)."}),M(Y.h2,{children:"Commands"}),M(F4,{children:M(Y.pre,{className:"shiki github-light",style:{backgroundColor:"#fff",color:"#24292e"},tabIndex:"0",children:O(Y.code,{children:[M(Y.span,{className:"line",children:M(Y.span,{style:{color:"#6A737D"},children:"# Create a new project"})}),`
-`,O(Y.span,{className:"line",children:[M(Y.span,{style:{color:"#6F42C1"},children:"scratch"}),M(Y.span,{style:{color:"#032F62"},children:" create"}),M(Y.span,{style:{color:"#032F62"},children:" my-site"}),M(Y.span,{style:{color:"#6A737D"},children:" # interactive"})]}),`
-`,O(Y.span,{className:"line",children:[M(Y.span,{style:{color:"#6F42C1"},children:"scratch"}),M(Y.span,{style:{color:"#032F62"},children:" create"}),M(Y.span,{style:{color:"#005CC5"},children:" --minimal"}),M(Y.span,{style:{color:"#6A737D"},children:" # omit src/ and page examples"})]}),`
-`,O(Y.span,{className:"line",children:[M(Y.span,{style:{color:"#6F42C1"},children:"scratch"}),M(Y.span,{style:{color:"#032F62"},children:" create"}),M(Y.span,{style:{color:"#005CC5"},children:" --full"}),M(Y.span,{style:{color:"#6A737D"},children:" # include src/, examples, and package.json"})]}),`
-`,M(Y.span,{className:"line"}),`
-`,M(Y.span,{className:"line",children:M(Y.span,{style:{color:"#6A737D"},children:"# Start dev server with hot module reloading"})}),`
-`,O(Y.span,{className:"line",children:[M(Y.span,{style:{color:"#6F42C1"},children:"scratch"}),M(Y.span,{style:{color:"#032F62"},children:" dev"})]}),`
-`,M(Y.span,{className:"line"}),`
-`,M(Y.span,{className:"line",children:M(Y.span,{style:{color:"#6A737D"},children:"# Build for production"})}),`
-`,O(Y.span,{className:"line",children:[M(Y.span,{style:{color:"#6F42C1"},children:"scratch"}),M(Y.span,{style:{color:"#032F62"},children:" build"})]}),`
-`,O(Y.span,{className:"line",children:[M(Y.span,{style:{color:"#6F42C1"},children:"scratch"}),M(Y.span,{style:{color:"#032F62"},children:" build"}),M(Y.span,{style:{color:"#005CC5"},children:" --ssg"}),M(Y.span,{style:{color:"#005CC5"},children:" false"}),M(Y.span,{style:{color:"#6A737D"},children:" # disable static site generation"})]}),`
-`,O(Y.span,{className:"line",children:[M(Y.span,{style:{color:"#6F42C1"},children:"scratch"}),M(Y.span,{style:{color:"#032F62"},children:" build"}),M(Y.span,{style:{color:"#005CC5"},children:" --development"}),M(Y.span,{style:{color:"#6A737D"},children:" # unminified, with source maps"})]}),`
-`,M(Y.span,{className:"line"}),`
-`,M(Y.span,{className:"line",children:M(Y.span,{style:{color:"#6A737D"},children:"# Preview production build locally"})}),`
-`,O(Y.span,{className:"line",children:[M(Y.span,{style:{color:"#6F42C1"},children:"scratch"}),M(Y.span,{style:{color:"#032F62"},children:" preview"})]}),`
-`,M(Y.span,{className:"line"}),`
-`,M(Y.span,{className:"line",children:M(Y.span,{style:{color:"#6A737D"},children:"# Remove build artifacts"})}),`
-`,O(Y.span,{className:"line",children:[M(Y.span,{style:{color:"#6F42C1"},children:"scratch"}),M(Y.span,{style:{color:"#032F62"},children:" clean"})]}),`
-`,M(Y.span,{className:"line"}),`
-`,M(Y.span,{className:"line",children:M(Y.span,{style:{color:"#6A737D"},children:"# Update scratch to latest version"})}),`
-`,O(Y.span,{className:"line",children:[M(Y.span,{style:{color:"#6F42C1"},children:"scratch"}),M(Y.span,{style:{color:"#032F62"},children:" update"})]})]})})})]})}function Mw(A={}){let{wrapper:Y}={...Q4(),...A.components};return Y?M(Y,{...A,children:M(QU,{...A})}):QU(A)}var AH=m0(p0(),1);function Jw({children:A,className:Y,style:G,...H}){let[X,w]=AH.useState(!1),Z=AH.useRef(null);return O("div",{className:"relative group",children:[M("button",{onClick:async()=>{if(!Z.current)return;let q=Z.current.textContent||"";await navigator.clipboard.writeText(q),w(!0),setTimeout(()=>w(!1),2000)},className:"copy-button","aria-label":"Copy code",children:X?"Copied!":"Copy"}),M("pre",{ref:Z,className:Y,style:G,...H,children:A})]})}var FU=m0(p0(),1);function FR(A){return A.toString().toLowerCase().trim().replace(/\s+/g,"-").replace(/[^\w\-]+/g,"").replace(/\-\-+/g,"-")}function Rw(A){if(typeof A==="string")return A;if(Array.isArray(A))return A.map(Rw).join("");if(FU.default.isValidElement(A)&&A.props?.children)return Rw(A.props.children);return""}function VU({children:A,level:Y}){let G=Rw(A),H=FR(G),X=`h${Y}`;return O(X,{id:H,className:"group relative",children:[M("a",{href:`#${H}`,className:"heading-anchor","aria-label":`Link to ${G}`,children:"#"}),A]})}function Bw(A){return M(VU,{...A,level:2})}function Lw(A){return M(VU,{...A,level:3})}function YH({href:A,children:Y,...G}){let H=A?.startsWith("http://")||A?.startsWith("https://");return M("a",{href:A,...H&&{target:"_blank",rel:"noopener noreferrer"},...G,children:Y})}var IU={pre:Jw,h2:Bw,h3:Lw,a:YH};var OU=fw.default.createElement(Xw,{components:IU},fw.default.createElement(Mw)),KU=document.getElementById("mdx");if(window.__scratch_ssg)console.log("Hydrating mdx component"),GH.hydrateRoot(KU,OU);else console.log("Rendering mdx component"),GH.createRoot(KU).render(OU);
diff --git a/dist/index.html b/dist/index.html
deleted file mode 100644
index 3487831..0000000
--- a/dist/index.html
+++ /dev/null
@@ -1,54 +0,0 @@
-
-
-
-
-
-
-
-
- Scratch
-
-
-
-
-
-
-
-
-
-
-
- Scratch compiles Markdown and React into beautiful static websites that can be hosted anywhere.
# Quick StartCopy # Install scratch
-curl -fsSL https://scratch.dev/install.sh | bash
-
-# Create a new project
-scratch create
-
-# Start the dev server
-scratch dev # What can you do with Scratch?Scratch was designed for collaborative writing with coding agents like Claude Code . Use your favorite editor to write in Markdown and embed React components when it's easier to express yourself with code.
Scratch supports Github-flavored Markdown features like tables and todolists:
Feature Supported? Compiles .md .mdx .tsx .ts .jsx .js ✅ Dev server with HMR ✅ Tailwind CSS styling ✅ Code syntax highlighting ✅
Code blocks use syntax highlighting by Shiki :
Copy def greet (name: str ) -> str :
- return f "Hello, { name } !"
-
-print (greet( "World" )) You can use React components to style text or embed fully working demos in your product specs:
Add
No todos yet. Add one above!
0 remaining Reset
In fact, coding agents have gotten so good that if you can describe it, you can add it to a document:
# No BoilerplateScratch uses an opinionated project structure and requires no boilerplate or configuration : just create a project, run the dev server with scratch dev, and start writing.
A simple Scratch project (created with scratch create) looks like this:
Use scratch build to compile this project into a static website .
Borrowing heavily from Tailwind Typography , Scratch uses default styles and Markdown components to render your prose with a clean aesthetic. Code blocks use syntax highlighting by Shiki .
You can change styles and customize the page wrapper component by including the src/ directory when you run scratch create:
Component files and js/ts libraries can live anywhere in pages/ and src/. They are auto-detected by Scratch and don't need to be explicitly imported in your .mdx files as long as the filename matches the component name.
Scratch installs build dependencies automatically. You can add additional third-party dependencies by including a package.json file in your project root.
# Built on BunScratch is built on Bun for lightning-fast builds, development with HMR, and native typescript support. It uses the Tailwind CSS framework to make component styling easy.
Scratch compiles Javascript (.js), Typescript (.ts), JSX (.jsx), TSX (.tsx), Markdown (.md), and MDX (.mdx).
# CommandsCopy # Create a new project
-scratch create my-site # interactive
-scratch create --minimal # omit src/ and page examples
-scratch create --full # include src/, examples, and package.json
-
-# Start dev server with hot module reloading
-scratch dev
-
-# Build for production
-scratch build
-scratch build --ssg false # disable static site generation
-scratch build --development # unminified, with source maps
-
-# Preview production build locally
-scratch preview
-
-# Remove build artifacts
-scratch clean
-
-# Update scratch to latest version
-scratch update Released under the MIT License Copyright 2025 Pete Koomen
-
-
-
\ No newline at end of file
diff --git a/dist/scratch-logo.svg b/dist/scratch-logo.svg
deleted file mode 100644
index c44fcb1..0000000
--- a/dist/scratch-logo.svg
+++ /dev/null
@@ -1,212 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Scratch
-
diff --git a/dist/tailwind-510c5f85.css b/dist/tailwind-510c5f85.css
deleted file mode 100644
index df53666..0000000
--- a/dist/tailwind-510c5f85.css
+++ /dev/null
@@ -1,2 +0,0 @@
-/*! tailwindcss v4.1.18 | MIT License | https://tailwindcss.com */
-@layer properties{@supports (((-webkit-hyphens:none)) and (not (margin-trim:inline))) or ((-moz-orient:inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-rotate-x:initial;--tw-rotate-y:initial;--tw-rotate-z:initial;--tw-skew-x:initial;--tw-skew-y:initial;--tw-space-y-reverse:0;--tw-border-style:solid;--tw-gradient-position:initial;--tw-gradient-from:#0000;--tw-gradient-via:#0000;--tw-gradient-to:#0000;--tw-gradient-stops:initial;--tw-gradient-via-stops:initial;--tw-gradient-from-position:0%;--tw-gradient-via-position:50%;--tw-gradient-to-position:100%;--tw-font-weight:initial;--tw-ordinal:initial;--tw-slashed-zero:initial;--tw-numeric-figure:initial;--tw-numeric-spacing:initial;--tw-numeric-fraction:initial;--tw-shadow:0 0 #0000;--tw-shadow-color:initial;--tw-shadow-alpha:100%;--tw-inset-shadow:0 0 #0000;--tw-inset-shadow-color:initial;--tw-inset-shadow-alpha:100%;--tw-ring-color:initial;--tw-ring-shadow:0 0 #0000;--tw-inset-ring-color:initial;--tw-inset-ring-shadow:0 0 #0000;--tw-ring-inset:initial;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-offset-shadow:0 0 #0000;--tw-duration:initial;--tw-leading:initial}}}@layer theme{:root,:host{--font-sans:ui-sans-serif,system-ui,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji";--font-mono:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace;--color-red-500:oklch(63.7% .237 25.331);--color-red-600:oklch(57.7% .245 27.325);--color-orange-500:oklch(70.5% .213 47.604);--color-yellow-400:oklch(85.2% .199 91.936);--color-gray-50:oklch(98.5% .002 247.839);--color-gray-100:oklch(96.7% .003 264.542);--color-gray-200:oklch(92.8% .006 264.531);--color-gray-300:oklch(87.2% .01 258.338);--color-gray-400:oklch(70.7% .022 261.325);--color-gray-500:oklch(55.1% .027 264.364);--color-gray-600:oklch(44.6% .03 256.802);--color-gray-700:oklch(37.3% .034 259.733);--color-gray-800:oklch(27.8% .033 256.848);--color-gray-900:oklch(21% .034 264.665);--color-black:#000;--color-white:#fff;--spacing:.25rem;--container-2xl:42rem;--text-xs:.75rem;--text-xs--line-height:calc(1/.75);--text-sm:.875rem;--text-sm--line-height:calc(1.25/.875);--text-xl:1.25rem;--text-xl--line-height:calc(1.75/1.25);--font-weight-normal:400;--font-weight-medium:500;--font-weight-semibold:600;--font-weight-bold:700;--leading-relaxed:1.625;--radius-md:.375rem;--radius-lg:.5rem;--radius-2xl:1rem;--animate-pulse:pulse 2s cubic-bezier(.4,0,.6,1)infinite;--default-transition-duration:.15s;--default-transition-timing-function:cubic-bezier(.4,0,.2,1);--default-font-family:var(--font-sans);--default-mono-font-family:var(--font-mono)}}@layer base{*,:after,:before,::backdrop{box-sizing:border-box;border:0 solid;margin:0;padding:0}::file-selector-button{box-sizing:border-box;border:0 solid;margin:0;padding:0}html,:host{-webkit-text-size-adjust:100%;tab-size:4;line-height:1.5;font-family:var(--default-font-family,ui-sans-serif,system-ui,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji");font-feature-settings:var(--default-font-feature-settings,normal);font-variation-settings:var(--default-font-variation-settings,normal);-webkit-tap-highlight-color:transparent}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;-webkit-text-decoration:inherit;-webkit-text-decoration:inherit;-webkit-text-decoration:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,samp,pre{font-family:var(--default-mono-font-family,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace);font-feature-settings:var(--default-mono-font-feature-settings,normal);font-variation-settings:var(--default-mono-font-variation-settings,normal);font-size:1em}small{font-size:80%}sub,sup{vertical-align:baseline;font-size:75%;line-height:0;position:relative}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}:-moz-focusring{outline:auto}progress{vertical-align:baseline}summary{display:list-item}ol,ul,menu{list-style:none}img,svg,video,canvas,audio,iframe,embed,object{vertical-align:middle;display:block}img,video{max-width:100%;height:auto}button,input,select,optgroup,textarea{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}::file-selector-button{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}:where(select:is([multiple],[size])) optgroup{font-weight:bolder}:where(select:is([multiple],[size])) optgroup option{padding-inline-start:20px}::file-selector-button{margin-inline-end:4px}::placeholder{opacity:1}@supports (not ((-webkit-appearance:-apple-pay-button))) or (contain-intrinsic-size:1px){::placeholder{color:currentColor}@supports (color:color-mix(in lab, red, red)){::placeholder{color:color-mix(in oklab,currentcolor 50%,transparent)}}}textarea{resize:vertical}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-date-and-time-value{min-height:1lh;text-align:inherit}::-webkit-datetime-edit{display:inline-flex}::-webkit-datetime-edit-fields-wrapper{padding:0}::-webkit-datetime-edit{padding-block:0}::-webkit-datetime-edit-year-field{padding-block:0}::-webkit-datetime-edit-month-field{padding-block:0}::-webkit-datetime-edit-day-field{padding-block:0}::-webkit-datetime-edit-hour-field{padding-block:0}::-webkit-datetime-edit-minute-field{padding-block:0}::-webkit-datetime-edit-second-field{padding-block:0}::-webkit-datetime-edit-millisecond-field{padding-block:0}::-webkit-datetime-edit-meridiem-field{padding-block:0}::-webkit-calendar-picker-indicator{line-height:1}:-moz-ui-invalid{box-shadow:none}button,input:where([type=button],[type=reset],[type=submit]){appearance:button}::file-selector-button{appearance:button}::-webkit-inner-spin-button{height:auto}::-webkit-outer-spin-button{height:auto}[hidden]:where(:not([hidden=until-found])){display:none!important}}@layer components;@layer utilities{.pointer-events-none{pointer-events:none}.absolute{position:absolute}.relative{position:relative}.static{position:static}.inset-0{inset:calc(var(--spacing)*0)}.top-0{top:calc(var(--spacing)*0)}.top-1\/2{top:50%}.bottom-0{bottom:calc(var(--spacing)*0)}.left-2{left:calc(var(--spacing)*2)}.container{width:100%}@media (min-width:40rem){.container{max-width:40rem}}@media (min-width:48rem){.container{max-width:48rem}}@media (min-width:64rem){.container{max-width:64rem}}@media (min-width:80rem){.container{max-width:80rem}}@media (min-width:96rem){.container{max-width:96rem}}.mx-2{margin-inline:calc(var(--spacing)*2)}.mx-12{margin-inline:calc(var(--spacing)*12)}.mx-auto{margin-inline:auto}.my-6{margin-block:calc(var(--spacing)*6)}.my-12{margin-block:calc(var(--spacing)*12)}.prose{color:var(--tw-prose-body);max-width:65ch}.prose :where(p):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:1.25em;margin-bottom:1.25em}.prose :where([class~=lead]):not(:where([class~=not-prose],[class~=not-prose] *)){color:var(--tw-prose-lead);margin-top:1.2em;margin-bottom:1.2em;font-size:1.25em;line-height:1.6}.prose :where(a):not(:where([class~=not-prose],[class~=not-prose] *)){color:var(--tw-prose-links);font-weight:500;text-decoration:underline}.prose :where(strong):not(:where([class~=not-prose],[class~=not-prose] *)){color:var(--tw-prose-bold);font-weight:600}.prose :where(a strong):not(:where([class~=not-prose],[class~=not-prose] *)),.prose :where(blockquote strong):not(:where([class~=not-prose],[class~=not-prose] *)),.prose :where(thead th strong):not(:where([class~=not-prose],[class~=not-prose] *)){color:inherit}.prose :where(ol):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:1.25em;margin-bottom:1.25em;padding-inline-start:1.625em;list-style-type:decimal}.prose :where(ol[type=A]):not(:where([class~=not-prose],[class~=not-prose] *)){list-style-type:upper-alpha}.prose :where(ol[type=a]):not(:where([class~=not-prose],[class~=not-prose] *)){list-style-type:lower-alpha}.prose :where(ol[type=A s]):not(:where([class~=not-prose],[class~=not-prose] *)){list-style-type:upper-alpha}.prose :where(ol[type=a s]):not(:where([class~=not-prose],[class~=not-prose] *)){list-style-type:lower-alpha}.prose :where(ol[type=I]):not(:where([class~=not-prose],[class~=not-prose] *)){list-style-type:upper-roman}.prose :where(ol[type=i]):not(:where([class~=not-prose],[class~=not-prose] *)){list-style-type:lower-roman}.prose :where(ol[type=I s]):not(:where([class~=not-prose],[class~=not-prose] *)){list-style-type:upper-roman}.prose :where(ol[type=i s]):not(:where([class~=not-prose],[class~=not-prose] *)){list-style-type:lower-roman}.prose :where(ol[type="1"]):not(:where([class~=not-prose],[class~=not-prose] *)){list-style-type:decimal}.prose :where(ul):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:1.25em;margin-bottom:1.25em;padding-inline-start:1.625em;list-style-type:disc}.prose :where(ol>li):not(:where([class~=not-prose],[class~=not-prose] *))::marker{color:var(--tw-prose-counters);font-weight:400}.prose :where(ul>li):not(:where([class~=not-prose],[class~=not-prose] *))::marker{color:var(--tw-prose-bullets)}.prose :where(dt):not(:where([class~=not-prose],[class~=not-prose] *)){color:var(--tw-prose-headings);margin-top:1.25em;font-weight:600}.prose :where(hr):not(:where([class~=not-prose],[class~=not-prose] *)){border-color:var(--tw-prose-hr);border-top-width:1px;margin-top:3em;margin-bottom:3em}.prose :where(blockquote):not(:where([class~=not-prose],[class~=not-prose] *)){color:var(--tw-prose-quotes);border-inline-start-width:.25rem;border-inline-start-color:var(--tw-prose-quote-borders);quotes:"“""”""‘""’";margin-top:1.6em;margin-bottom:1.6em;padding-inline-start:1em;font-style:italic;font-weight:500}.prose :where(blockquote p:first-of-type):not(:where([class~=not-prose],[class~=not-prose] *)):before{content:open-quote}.prose :where(blockquote p:last-of-type):not(:where([class~=not-prose],[class~=not-prose] *)):after{content:close-quote}.prose :where(h1):not(:where([class~=not-prose],[class~=not-prose] *)){color:var(--tw-prose-headings);margin-top:0;margin-bottom:.888889em;font-size:2.25em;font-weight:800;line-height:1.11111}.prose :where(h1 strong):not(:where([class~=not-prose],[class~=not-prose] *)){color:inherit;font-weight:900}.prose :where(h2):not(:where([class~=not-prose],[class~=not-prose] *)){color:var(--tw-prose-headings);margin-top:2em;margin-bottom:1em;font-size:1.5em;font-weight:700;line-height:1.33333}.prose :where(h2 strong):not(:where([class~=not-prose],[class~=not-prose] *)){color:inherit;font-weight:800}.prose :where(h3):not(:where([class~=not-prose],[class~=not-prose] *)){color:var(--tw-prose-headings);margin-top:1.6em;margin-bottom:.6em;font-size:1.25em;font-weight:600;line-height:1.6}.prose :where(h3 strong):not(:where([class~=not-prose],[class~=not-prose] *)){color:inherit;font-weight:700}.prose :where(h4):not(:where([class~=not-prose],[class~=not-prose] *)){color:var(--tw-prose-headings);margin-top:1.5em;margin-bottom:.5em;font-weight:600;line-height:1.5}.prose :where(h4 strong):not(:where([class~=not-prose],[class~=not-prose] *)){color:inherit;font-weight:700}.prose :where(img):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:2em;margin-bottom:2em}.prose :where(picture):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:2em;margin-bottom:2em;display:block}.prose :where(video):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:2em;margin-bottom:2em}.prose :where(kbd):not(:where([class~=not-prose],[class~=not-prose] *)){color:var(--tw-prose-kbd);box-shadow:0 0 0 1px var(--tw-prose-kbd-shadows),0 3px 0 var(--tw-prose-kbd-shadows);padding-top:.1875em;padding-inline-end:.375em;padding-bottom:.1875em;border-radius:.3125rem;padding-inline-start:.375em;font-family:inherit;font-size:.875em;font-weight:500}.prose :where(code):not(:where([class~=not-prose],[class~=not-prose] *)){color:var(--tw-prose-code);font-size:.875em;font-weight:600}.prose :where(code):not(:where([class~=not-prose],[class~=not-prose] *)):before,.prose :where(code):not(:where([class~=not-prose],[class~=not-prose] *)):after{content:"`"}.prose :where(a code):not(:where([class~=not-prose],[class~=not-prose] *)),.prose :where(h1 code):not(:where([class~=not-prose],[class~=not-prose] *)){color:inherit}.prose :where(h2 code):not(:where([class~=not-prose],[class~=not-prose] *)){color:inherit;font-size:.875em}.prose :where(h3 code):not(:where([class~=not-prose],[class~=not-prose] *)){color:inherit;font-size:.9em}.prose :where(h4 code):not(:where([class~=not-prose],[class~=not-prose] *)),.prose :where(blockquote code):not(:where([class~=not-prose],[class~=not-prose] *)),.prose :where(thead th code):not(:where([class~=not-prose],[class~=not-prose] *)){color:inherit}.prose :where(pre):not(:where([class~=not-prose],[class~=not-prose] *)){color:var(--tw-prose-pre-code);background-color:var(--tw-prose-pre-bg);padding-top:.857143em;padding-inline-end:1.14286em;padding-bottom:.857143em;border-radius:.375rem;margin-top:1.71429em;margin-bottom:1.71429em;padding-inline-start:1.14286em;font-size:.875em;font-weight:400;line-height:1.71429;overflow-x:auto}.prose :where(pre code):not(:where([class~=not-prose],[class~=not-prose] *)){font-weight:inherit;color:inherit;font-size:inherit;font-family:inherit;line-height:inherit;background-color:#0000;border-width:0;border-radius:0;padding:0}.prose :where(pre code):not(:where([class~=not-prose],[class~=not-prose] *)):before,.prose :where(pre code):not(:where([class~=not-prose],[class~=not-prose] *)):after{content:none}.prose :where(table):not(:where([class~=not-prose],[class~=not-prose] *)){table-layout:auto;width:100%;margin-top:2em;margin-bottom:2em;font-size:.875em;line-height:1.71429}.prose :where(thead):not(:where([class~=not-prose],[class~=not-prose] *)){border-bottom-width:1px;border-bottom-color:var(--tw-prose-th-borders)}.prose :where(thead th):not(:where([class~=not-prose],[class~=not-prose] *)){color:var(--tw-prose-headings);vertical-align:bottom;padding-inline-end:.571429em;padding-bottom:.571429em;padding-inline-start:.571429em;font-weight:600}.prose :where(tbody tr):not(:where([class~=not-prose],[class~=not-prose] *)){border-bottom-width:1px;border-bottom-color:var(--tw-prose-td-borders)}.prose :where(tbody tr:last-child):not(:where([class~=not-prose],[class~=not-prose] *)){border-bottom-width:0}.prose :where(tbody td):not(:where([class~=not-prose],[class~=not-prose] *)){vertical-align:baseline}.prose :where(tfoot):not(:where([class~=not-prose],[class~=not-prose] *)){border-top-width:1px;border-top-color:var(--tw-prose-th-borders)}.prose :where(tfoot td):not(:where([class~=not-prose],[class~=not-prose] *)){vertical-align:top}.prose :where(th,td):not(:where([class~=not-prose],[class~=not-prose] *)){text-align:start}.prose :where(figure>*):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:0;margin-bottom:0}.prose :where(figcaption):not(:where([class~=not-prose],[class~=not-prose] *)){color:var(--tw-prose-captions);margin-top:.857143em;font-size:.875em;line-height:1.42857}.prose{--tw-prose-body:oklch(37.3% .034 259.733);--tw-prose-headings:oklch(21% .034 264.665);--tw-prose-lead:oklch(44.6% .03 256.802);--tw-prose-links:oklch(21% .034 264.665);--tw-prose-bold:oklch(21% .034 264.665);--tw-prose-counters:oklch(55.1% .027 264.364);--tw-prose-bullets:oklch(87.2% .01 258.338);--tw-prose-hr:oklch(92.8% .006 264.531);--tw-prose-quotes:oklch(21% .034 264.665);--tw-prose-quote-borders:oklch(92.8% .006 264.531);--tw-prose-captions:oklch(55.1% .027 264.364);--tw-prose-kbd:oklch(21% .034 264.665);--tw-prose-kbd-shadows:oklab(21% -.00316127 -.0338527/.1);--tw-prose-code:oklch(21% .034 264.665);--tw-prose-pre-code:oklch(92.8% .006 264.531);--tw-prose-pre-bg:oklch(27.8% .033 256.848);--tw-prose-th-borders:oklch(87.2% .01 258.338);--tw-prose-td-borders:oklch(92.8% .006 264.531);--tw-prose-invert-body:oklch(87.2% .01 258.338);--tw-prose-invert-headings:#fff;--tw-prose-invert-lead:oklch(70.7% .022 261.325);--tw-prose-invert-links:#fff;--tw-prose-invert-bold:#fff;--tw-prose-invert-counters:oklch(70.7% .022 261.325);--tw-prose-invert-bullets:oklch(44.6% .03 256.802);--tw-prose-invert-hr:oklch(37.3% .034 259.733);--tw-prose-invert-quotes:oklch(96.7% .003 264.542);--tw-prose-invert-quote-borders:oklch(37.3% .034 259.733);--tw-prose-invert-captions:oklch(70.7% .022 261.325);--tw-prose-invert-kbd:#fff;--tw-prose-invert-kbd-shadows:#ffffff1a;--tw-prose-invert-code:#fff;--tw-prose-invert-pre-code:oklch(87.2% .01 258.338);--tw-prose-invert-pre-bg:#00000080;--tw-prose-invert-th-borders:oklch(44.6% .03 256.802);--tw-prose-invert-td-borders:oklch(37.3% .034 259.733);font-size:1rem;line-height:1.75}.prose :where(picture>img):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:0;margin-bottom:0}.prose :where(li):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:.5em;margin-bottom:.5em}.prose :where(ol>li):not(:where([class~=not-prose],[class~=not-prose] *)),.prose :where(ul>li):not(:where([class~=not-prose],[class~=not-prose] *)){padding-inline-start:.375em}.prose :where(.prose>ul>li p):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:.75em;margin-bottom:.75em}.prose :where(.prose>ul>li>p:first-child):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:1.25em}.prose :where(.prose>ul>li>p:last-child):not(:where([class~=not-prose],[class~=not-prose] *)){margin-bottom:1.25em}.prose :where(.prose>ol>li>p:first-child):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:1.25em}.prose :where(.prose>ol>li>p:last-child):not(:where([class~=not-prose],[class~=not-prose] *)){margin-bottom:1.25em}.prose :where(ul ul,ul ol,ol ul,ol ol):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:.75em;margin-bottom:.75em}.prose :where(dl):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:1.25em;margin-bottom:1.25em}.prose :where(dd):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:.5em;padding-inline-start:1.625em}.prose :where(hr+*):not(:where([class~=not-prose],[class~=not-prose] *)),.prose :where(h2+*):not(:where([class~=not-prose],[class~=not-prose] *)),.prose :where(h3+*):not(:where([class~=not-prose],[class~=not-prose] *)),.prose :where(h4+*):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:0}.prose :where(thead th:first-child):not(:where([class~=not-prose],[class~=not-prose] *)){padding-inline-start:0}.prose :where(thead th:last-child):not(:where([class~=not-prose],[class~=not-prose] *)){padding-inline-end:0}.prose :where(tbody td,tfoot td):not(:where([class~=not-prose],[class~=not-prose] *)){padding-top:.571429em;padding-inline-end:.571429em;padding-bottom:.571429em;padding-inline-start:.571429em}.prose :where(tbody td:first-child,tfoot td:first-child):not(:where([class~=not-prose],[class~=not-prose] *)){padding-inline-start:0}.prose :where(tbody td:last-child,tfoot td:last-child):not(:where([class~=not-prose],[class~=not-prose] *)){padding-inline-end:0}.prose :where(figure):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:2em;margin-bottom:2em}.prose :where(.prose>:first-child):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:0}.prose :where(.prose>:last-child):not(:where([class~=not-prose],[class~=not-prose] *)){margin-bottom:0}.mt-3{margin-top:calc(var(--spacing)*3)}.mt-4{margin-top:calc(var(--spacing)*4)}.mt-16{margin-top:calc(var(--spacing)*16)}.mb-4{margin-bottom:calc(var(--spacing)*4)}.mb-8{margin-bottom:calc(var(--spacing)*8)}.block{display:block}.flex{display:flex}.inline{display:inline}.h-1\/2{height:50%}.h-4{height:calc(var(--spacing)*4)}.h-5{height:calc(var(--spacing)*5)}.h-6{height:calc(var(--spacing)*6)}.h-7{height:calc(var(--spacing)*7)}.h-8{height:calc(var(--spacing)*8)}.h-48{height:calc(var(--spacing)*48)}.h-px{height:1px}.min-h-screen{min-height:100vh}.w-3{width:calc(var(--spacing)*3)}.w-4{width:calc(var(--spacing)*4)}.w-5{width:calc(var(--spacing)*5)}.w-6{width:calc(var(--spacing)*6)}.w-8{width:calc(var(--spacing)*8)}.w-full{width:100%}.w-px{width:1px}.max-w-2xl{max-width:var(--container-2xl)}.flex-1{flex:1}.flex-shrink-0{flex-shrink:0}.transform{transform:var(--tw-rotate-x,)var(--tw-rotate-y,)var(--tw-rotate-z,)var(--tw-skew-x,)var(--tw-skew-y,)}.animate-pulse{animation:var(--animate-pulse)}.flex-col{flex-direction:column}.items-center{align-items:center}.items-stretch{align-items:stretch}.justify-between{justify-content:space-between}.justify-center{justify-content:center}.gap-2{gap:calc(var(--spacing)*2)}.gap-3{gap:calc(var(--spacing)*3)}.gap-4{gap:calc(var(--spacing)*4)}:where(.space-y-2>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing)*2)*var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing)*2)*calc(1 - var(--tw-space-y-reverse)))}.overflow-hidden{overflow:hidden}.rounded{border-radius:.25rem}.rounded-2xl{border-radius:var(--radius-2xl)}.rounded-full{border-radius:3.40282e38px}.rounded-lg{border-radius:var(--radius-lg)}.rounded-md{border-radius:var(--radius-md)}.border{border-style:var(--tw-border-style);border-width:1px}.border-t{border-top-style:var(--tw-border-style);border-top-width:1px}.border-gray-200{border-color:var(--color-gray-200)}.border-gray-300{border-color:var(--color-gray-300)}.bg-black{background-color:var(--color-black)}.bg-gray-50{background-color:var(--color-gray-50)}.bg-gray-300{background-color:var(--color-gray-300)}.bg-gray-900{background-color:var(--color-gray-900)}.bg-white{background-color:var(--color-white)}.bg-gradient-to-b{--tw-gradient-position:to bottom in oklab;background-image:linear-gradient(var(--tw-gradient-stops))}.bg-gradient-to-t{--tw-gradient-position:to top in oklab;background-image:linear-gradient(var(--tw-gradient-stops))}.from-gray-700{--tw-gradient-from:var(--color-gray-700);--tw-gradient-stops:var(--tw-gradient-via-stops,var(--tw-gradient-position),var(--tw-gradient-from)var(--tw-gradient-from-position),var(--tw-gradient-to)var(--tw-gradient-to-position))}.from-red-600{--tw-gradient-from:var(--color-red-600);--tw-gradient-stops:var(--tw-gradient-via-stops,var(--tw-gradient-position),var(--tw-gradient-from)var(--tw-gradient-from-position),var(--tw-gradient-to)var(--tw-gradient-to-position))}.via-gray-800{--tw-gradient-via:var(--color-gray-800);--tw-gradient-via-stops:var(--tw-gradient-position),var(--tw-gradient-from)var(--tw-gradient-from-position),var(--tw-gradient-via)var(--tw-gradient-via-position),var(--tw-gradient-to)var(--tw-gradient-to-position);--tw-gradient-stops:var(--tw-gradient-via-stops)}.via-orange-500{--tw-gradient-via:var(--color-orange-500);--tw-gradient-via-stops:var(--tw-gradient-position),var(--tw-gradient-from)var(--tw-gradient-from-position),var(--tw-gradient-via)var(--tw-gradient-via-position),var(--tw-gradient-to)var(--tw-gradient-to-position);--tw-gradient-stops:var(--tw-gradient-via-stops)}.to-gray-900{--tw-gradient-to:var(--color-gray-900);--tw-gradient-stops:var(--tw-gradient-via-stops,var(--tw-gradient-position),var(--tw-gradient-from)var(--tw-gradient-from-position),var(--tw-gradient-to)var(--tw-gradient-to-position))}.to-yellow-400{--tw-gradient-to:var(--color-yellow-400);--tw-gradient-stops:var(--tw-gradient-via-stops,var(--tw-gradient-position),var(--tw-gradient-from)var(--tw-gradient-from-position),var(--tw-gradient-to)var(--tw-gradient-to-position))}.bg-clip-text{-webkit-background-clip:text;background-clip:text}.p-1{padding:calc(var(--spacing)*1)}.p-2{padding:calc(var(--spacing)*2)}.p-3{padding:calc(var(--spacing)*3)}.p-4{padding:calc(var(--spacing)*4)}.p-8{padding:calc(var(--spacing)*8)}.px-3{padding-inline:calc(var(--spacing)*3)}.px-4{padding-inline:calc(var(--spacing)*4)}.px-6{padding-inline:calc(var(--spacing)*6)}.py-2{padding-block:calc(var(--spacing)*2)}.py-4{padding-block:calc(var(--spacing)*4)}.py-8{padding-block:calc(var(--spacing)*8)}.pt-4{padding-top:calc(var(--spacing)*4)}.pb-8{padding-bottom:calc(var(--spacing)*8)}.text-center{text-align:center}.font-mono{font-family:var(--font-mono)}.text-sm{font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height))}.text-xl{font-size:var(--text-xl);line-height:var(--tw-leading,var(--text-xl--line-height))}.font-bold{--tw-font-weight:var(--font-weight-bold);font-weight:var(--font-weight-bold)}.font-medium{--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium)}.text-gray-400{color:var(--color-gray-400)}.text-gray-500{color:var(--color-gray-500)}.text-gray-600{color:var(--color-gray-600)}.text-gray-700{color:var(--color-gray-700)}.text-gray-900{color:var(--color-gray-900)}.text-transparent{color:#0000}.text-white{color:var(--color-white)}.lowercase{text-transform:lowercase}.tabular-nums{--tw-numeric-spacing:tabular-nums;font-variant-numeric:var(--tw-ordinal,)var(--tw-slashed-zero,)var(--tw-numeric-figure,)var(--tw-numeric-spacing,)var(--tw-numeric-fraction,)}.line-through{text-decoration-line:line-through}.placeholder-gray-400::placeholder{color:var(--color-gray-400)}.opacity-30{opacity:.3}.shadow-md{--tw-shadow:0 4px 6px -1px var(--tw-shadow-color,#0000001a),0 2px 4px -2px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.shadow-xl{--tw-shadow:0 20px 25px -5px var(--tw-shadow-color,#0000001a),0 8px 10px -6px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.transition-colors{transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-opacity{transition-property:opacity;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-shadow{transition-property:box-shadow;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.duration-300{--tw-duration:.3s;transition-duration:.3s}@media (hover:hover){.hover\:border-gray-400:hover{border-color:var(--color-gray-400)}.hover\:bg-gray-100:hover{background-color:var(--color-gray-100)}.hover\:bg-gray-700:hover{background-color:var(--color-gray-700)}.hover\:text-gray-700:hover{color:var(--color-gray-700)}.hover\:text-red-500:hover{color:var(--color-red-500)}.hover\:opacity-100:hover{opacity:1}.hover\:shadow-lg:hover{--tw-shadow:0 10px 15px -3px var(--tw-shadow-color,#0000001a),0 4px 6px -4px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}}@media (min-width:40rem){.sm\:mx-8{margin-inline:calc(var(--spacing)*8)}}@media (min-width:48rem){.md\:mx-16{margin-inline:calc(var(--spacing)*16)}}}.prose :where(code):not(:where([class~=not-prose],pre *)){background-color:var(--color-gray-100);padding-inline:calc(var(--spacing)*1.5);padding-block:calc(var(--spacing)*.5);--tw-font-weight:var(--font-weight-medium);font-size:.9em;font-weight:var(--font-weight-medium);color:var(--color-gray-900);border-radius:.25rem}.prose :where(code):not(:where([class~=not-prose],pre *)):before,.prose :where(code):not(:where([class~=not-prose],pre *)):after{content:none}.prose :where(pre code):not(:where([class~=not-prose] *)){border-style:var(--tw-border-style);padding:calc(var(--spacing)*0);--tw-font-weight:var(--font-weight-normal);font-weight:var(--font-weight-normal);font-size:inherit;background-color:#0000;border-width:0;border-radius:0}.prose :where(kbd):not(:where([class~=not-prose] *)){border-style:var(--tw-border-style);border-width:1px;border-color:var(--color-gray-300);background-color:var(--color-gray-100);padding-inline:calc(var(--spacing)*1.5);padding-block:calc(var(--spacing)*.5);font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height));--tw-font-weight:var(--font-weight-semibold);font-weight:var(--font-weight-semibold);color:var(--color-gray-900);--tw-shadow:0 1px 3px 0 var(--tw-shadow-color,#0000001a),0 1px 2px -1px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);border-radius:.25rem}.prose :where(ul.contains-task-list):not(:where([class~=not-prose] *)){padding-left:calc(var(--spacing)*0);list-style-type:none}.prose :where(li.task-list-item>input[type=checkbox]):not(:where([class~=not-prose] *)){margin-right:calc(var(--spacing)*2);margin-left:calc(var(--spacing)*1);vertical-align:middle}.prose :where(table):not(:where([class~=not-prose] *)){margin-inline:calc(var(--spacing)*4);width:auto;max-width:100%}pre:has(>code){border-radius:var(--radius-lg);background-color:var(--color-white);overflow-x:auto}pre>code{padding:calc(var(--spacing)*4);font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height));--tw-leading:var(--leading-relaxed);line-height:var(--leading-relaxed);color:#24292e;display:block}.copy-button{top:calc(var(--spacing)*2);right:calc(var(--spacing)*2);padding-inline:calc(var(--spacing)*2);padding-block:calc(var(--spacing)*1);font-size:var(--text-xs);line-height:var(--tw-leading,var(--text-xs--line-height));opacity:0;transition-property:opacity;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration));border-radius:.25rem;position:absolute}@media (hover:hover){.copy-button:is(:where(.group):hover *){opacity:1}}.copy-button{background-color:var(--color-gray-200);color:var(--color-gray-500)}@media (hover:hover){.copy-button:hover{color:var(--color-gray-700)}}.heading-anchor{top:calc(var(--spacing)*0);left:calc(var(--spacing)*-6);opacity:0;transition-property:opacity;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration));-webkit-user-select:none;user-select:none;text-decoration-line:none;position:absolute}@media (hover:hover){.heading-anchor:is(:where(.group):hover *){opacity:1}}.heading-anchor{color:var(--color-gray-400)}@media (hover:hover){.heading-anchor:hover{color:var(--color-gray-600)}}@property --tw-rotate-x{syntax:"*";inherits:false}@property --tw-rotate-y{syntax:"*";inherits:false}@property --tw-rotate-z{syntax:"*";inherits:false}@property --tw-skew-x{syntax:"*";inherits:false}@property --tw-skew-y{syntax:"*";inherits:false}@property --tw-space-y-reverse{syntax:"*";inherits:false;initial-value:0}@property --tw-border-style{syntax:"*";inherits:false;initial-value:solid}@property --tw-gradient-position{syntax:"*";inherits:false}@property --tw-gradient-from{syntax:"";inherits:false;initial-value:#0000}@property --tw-gradient-via{syntax:"";inherits:false;initial-value:#0000}@property --tw-gradient-to{syntax:"";inherits:false;initial-value:#0000}@property --tw-gradient-stops{syntax:"*";inherits:false}@property --tw-gradient-via-stops{syntax:"*";inherits:false}@property --tw-gradient-from-position{syntax:"";inherits:false;initial-value:0%}@property --tw-gradient-via-position{syntax:"";inherits:false;initial-value:50%}@property --tw-gradient-to-position{syntax:"";inherits:false;initial-value:100%}@property --tw-font-weight{syntax:"*";inherits:false}@property --tw-ordinal{syntax:"*";inherits:false}@property --tw-slashed-zero{syntax:"*";inherits:false}@property --tw-numeric-figure{syntax:"*";inherits:false}@property --tw-numeric-spacing{syntax:"*";inherits:false}@property --tw-numeric-fraction{syntax:"*";inherits:false}@property --tw-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-shadow-color{syntax:"*";inherits:false}@property --tw-shadow-alpha{syntax:"";inherits:false;initial-value:100%}@property --tw-inset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-shadow-color{syntax:"*";inherits:false}@property --tw-inset-shadow-alpha{syntax:"";inherits:false;initial-value:100%}@property --tw-ring-color{syntax:"*";inherits:false}@property --tw-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-ring-color{syntax:"*";inherits:false}@property --tw-inset-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-ring-inset{syntax:"*";inherits:false}@property --tw-ring-offset-width{syntax:"";inherits:false;initial-value:0}@property --tw-ring-offset-color{syntax:"*";inherits:false;initial-value:#fff}@property --tw-ring-offset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-duration{syntax:"*";inherits:false}@property --tw-leading{syntax:"*";inherits:false}@keyframes pulse{50%{opacity:.5}}
\ No newline at end of file
diff --git a/dist/x-logo.svg b/dist/x-logo.svg
deleted file mode 100644
index 56368dd..0000000
--- a/dist/x-logo.svg
+++ /dev/null
@@ -1,3 +0,0 @@
-
-
-
diff --git a/package.json b/package.json
new file mode 100644
index 0000000..1194b55
--- /dev/null
+++ b/package.json
@@ -0,0 +1,16 @@
+{
+ "name": "scratch.dev",
+ "private": true,
+ "scripts": {
+ "dev": "scratch dev",
+ "build": "scratch build"
+ },
+ "dependencies": {
+ "react": "latest",
+ "react-dom": "latest",
+ "@mdx-js/react": "latest",
+ "tailwindcss": "latest",
+ "@tailwindcss/cli": "latest",
+ "@tailwindcss/typography": "latest"
+ }
+}
diff --git a/pages/Files.tsx b/pages/Files.tsx
deleted file mode 100644
index 892dbf4..0000000
--- a/pages/Files.tsx
+++ /dev/null
@@ -1,151 +0,0 @@
-import React from "react";
-
-interface FileNode {
- name: string;
- depth: number;
- isLast: boolean;
- parentIsLast: boolean[];
-}
-
-function parseTree(text: string): FileNode[] {
- const lines = text.trim().split("\n");
- const nodes: FileNode[] = [];
-
- // Stack of { depth, isLast } for each open folder level
- const stack: { depth: number; isLast: boolean }[] = [];
-
- for (const line of lines) {
- if (!line.trim()) continue;
-
- // Find where the actual filename starts
- const nameMatch = line.match(/[^\s│|├└─]/);
- if (!nameMatch) continue;
-
- const nameStart = nameMatch.index!;
- const prefix = line.slice(0, nameStart);
- const name = line.slice(nameStart).trim();
-
- if (!name) continue;
-
- const isLast = prefix.includes("└");
- const hasBranch = prefix.includes("├") || prefix.includes("└");
-
- // Count │ to know how many non-last ancestors
- const pipeCount = (prefix.match(/[│|]/g) || []).length;
-
- let depth: number;
-
- if (!hasBranch && prefix.length === 0) {
- // Root item
- depth = 0;
- stack.length = 0;
- } else {
- // Pop stack until we find the right parent level
- // pipeCount tells us how many ancestors are still "open" (not last)
- while (stack.length > 0) {
- const openCount = stack.filter((s) => !s.isLast).length;
- if (openCount <= pipeCount) break;
- stack.pop();
- }
-
- depth = stack.length + 1;
- }
-
- // Update stack
- if (isLast) {
- // Pop items at this depth or deeper
- while (stack.length >= depth) {
- stack.pop();
- }
- }
-
- // Build parentIsLast array from stack
- const parentIsLast = stack.map((s) => s.isLast);
-
- const isFolder = name.endsWith("/") || !name.includes(".");
-
- nodes.push({
- name,
- depth,
- isLast,
- parentIsLast,
- });
-
- // If this is a folder, push to stack for potential children
- if (isFolder) {
- stack.push({ depth, isLast });
- }
- }
-
- return nodes;
-}
-
-function FileRow({ node }: { node: FileNode }) {
- const isFolder = node.name.endsWith("/") || !node.name.includes(".");
-
- return (
-
- {/* Render vertical lines for each parent level */}
- {node.parentIsLast.map((parentLast, i) => (
-
- {!parentLast && (
-
- )}
-
- ))}
-
- {/* Render the branch for this node */}
- {node.depth > 0 && (
-
- {/* Vertical line (full height if not last, half if last) */}
-
- {/* Horizontal line */}
-
-
- )}
-
- {/* File/folder name */}
-
- {node.name}
-
-
- );
-}
-
-function extractText(children: React.ReactNode): string {
- if (typeof children === "string") return children;
- if (typeof children === "number") return String(children);
- if (!children) return "";
-
- if (Array.isArray(children)) {
- return children.map(extractText).join("\n");
- }
-
- if (typeof children === "object" && "props" in children) {
- const el = children as React.ReactElement;
- // If it's a tag or similar, extract and add newline
- if (el.type === "p" || el.type === "br") {
- return extractText(el.props.children) + "\n";
- }
- return extractText(el.props.children);
- }
-
- return "";
-}
-
-export default function Files({ children }: { children: React.ReactNode }) {
- const text = extractText(children);
- const nodes = parseTree(text);
-
- return (
-
- {nodes.map((node, i) => (
-
- ))}
-
- );
-}
diff --git a/pages/BouncingDvdLogo.tsx b/pages/components/BouncingDvdLogo.tsx
similarity index 62%
rename from pages/BouncingDvdLogo.tsx
rename to pages/components/BouncingDvdLogo.tsx
index 3f9ebf8..6dcc5b7 100644
--- a/pages/BouncingDvdLogo.tsx
+++ b/pages/components/BouncingDvdLogo.tsx
@@ -4,9 +4,19 @@ export default function BouncingDvdLogo() {
const containerRef = useRef(null);
const [cornerHits, setCornerHits] = useState(0);
const [position, setPosition] = useState({ x: 20, y: 20 });
- const [velocity, setVelocity] = useState({ x: 2, y: 1.5 });
+ const [speedMultiplier, setSpeedMultiplier] = useState(1);
+ const [velocity, setVelocity] = useState({ x: 2 * 1, y: 1.5 * 1 });
const [color, setColor] = useState("#8b5cf6");
+ const toggleSpeed = () => {
+ const newMultiplier = speedMultiplier === 10 ? 1 : 10;
+ setSpeedMultiplier(newMultiplier);
+ setVelocity((v) => ({
+ x: Math.sign(v.x) * 2 * newMultiplier,
+ y: Math.sign(v.y) * 1.5 * newMultiplier,
+ }));
+ };
+
const logoWidth = 80;
const logoHeight = 40;
@@ -21,13 +31,17 @@ export default function BouncingDvdLogo() {
const getRandomColor = () => {
const newColor = colors[Math.floor(Math.random() * colors.length)];
- return newColor === color ? colors[(colors.indexOf(color) + 1) % colors.length] : newColor;
+ return newColor === color
+ ? colors[(colors.indexOf(color) + 1) % colors.length]
+ : newColor;
};
useEffect(() => {
const container = containerRef.current;
if (!container) return;
+ const cornerTolerance = 10; // pixels of tolerance for corner detection
+
const animate = () => {
setPosition((prev) => {
const containerWidth = container.clientWidth;
@@ -64,8 +78,15 @@ export default function BouncingDvdLogo() {
if (!hitX) setColor(getRandomColor());
}
- // Corner hit!
- if (hitX && hitY) {
+ // Corner hit - check if near both edges (with tolerance)
+ const nearLeftOrRight =
+ newX <= cornerTolerance ||
+ newX >= containerWidth - logoWidth - cornerTolerance;
+ const nearTopOrBottom =
+ newY <= cornerTolerance ||
+ newY >= containerHeight - logoHeight - cornerTolerance;
+
+ if ((hitX || hitY) && nearLeftOrRight && nearTopOrBottom) {
setCornerHits((c) => c + 1);
}
@@ -78,9 +99,12 @@ export default function BouncingDvdLogo() {
}, [velocity]);
return (
-
+
{/* TV outer frame */}
-
+
{/* TV screen bezel */}
{/* Screen container */}
@@ -88,12 +112,20 @@ export default function BouncingDvdLogo() {
ref={containerRef}
className="relative w-full h-48 rounded overflow-hidden"
style={{
- background: "linear-gradient(145deg, #1a1a2e 0%, #0f0f1a 50%, #1a1a2e 100%)",
+ background:
+ "linear-gradient(145deg, #1a1a2e 0%, #0f0f1a 50%, #1a1a2e 100%)",
}}
>
+ {/* Corner hits counter in center */}
+
+
+ {cornerHits}
+
+
+
{/* Bouncing logo */}
-
- Corner hits: {cornerHits}
+ {/* Prompt text */}
+
+ "Make a component that looks like a TV screen with a bouncing DVD logo.
+ Count the number of times...
);
diff --git a/pages/Counter.tsx b/pages/components/Counter.tsx
similarity index 95%
rename from pages/Counter.tsx
rename to pages/components/Counter.tsx
index 03186e1..b55604a 100644
--- a/pages/Counter.tsx
+++ b/pages/components/Counter.tsx
@@ -1,4 +1,4 @@
-import React, { useState } from 'react';
+import React, { useState } from "react";
export default function Counter(): React.ReactElement {
const [count, setCount] = useState
(0);
diff --git a/dist/DVD_logo.svg b/pages/components/DVD_logo.svg
similarity index 100%
rename from dist/DVD_logo.svg
rename to pages/components/DVD_logo.svg
diff --git a/pages/components/DocsSidebar.tsx b/pages/components/DocsSidebar.tsx
new file mode 100644
index 0000000..5f6cc6d
--- /dev/null
+++ b/pages/components/DocsSidebar.tsx
@@ -0,0 +1,88 @@
+import React, { useState, useEffect } from "react";
+
+interface TocItem {
+ id: string;
+ text: string;
+}
+
+export default function DocsSidebar() {
+ const [headings, setHeadings] = useState([]);
+ const [activeId, setActiveId] = useState("");
+
+ useEffect(() => {
+ // Find all h2 elements on the page
+ const h2Elements = document.querySelectorAll("h2");
+ const items: TocItem[] = [];
+
+ h2Elements.forEach((h2) => {
+ // Generate id from text if not present
+ if (!h2.id) {
+ h2.id = h2.textContent
+ ?.toLowerCase()
+ .replace(/[^a-z0-9]+/g, "-")
+ .replace(/(^-|-$)/g, "") || "";
+ }
+ // Get text content, filtering out the # anchor
+ let text = h2.textContent || "";
+ text = text.replace(/^#\s*/, "").trim();
+ items.push({
+ id: h2.id,
+ text,
+ });
+ });
+
+ setHeadings(items);
+
+ // Scroll to hash after IDs are set
+ if (window.location.hash) {
+ const id = window.location.hash.slice(1);
+ const el = document.getElementById(id);
+ if (el) {
+ setTimeout(() => el.scrollIntoView(), 0);
+ }
+ }
+ }, []);
+
+ useEffect(() => {
+ const observer = new IntersectionObserver(
+ (entries) => {
+ entries.forEach((entry) => {
+ if (entry.isIntersecting) {
+ setActiveId(entry.target.id);
+ }
+ });
+ },
+ { rootMargin: "-80px 0px -80% 0px" }
+ );
+
+ headings.forEach(({ id }) => {
+ const el = document.getElementById(id);
+ if (el) observer.observe(el);
+ });
+
+ return () => observer.disconnect();
+ }, [headings]);
+
+ if (headings.length === 0) return null;
+
+ return (
+
+
+ {headings.map(({ id, text }) => (
+
+
+ {text}
+
+
+ ))}
+
+
+ );
+}
diff --git a/pages/components/Files.tsx b/pages/components/Files.tsx
new file mode 100644
index 0000000..48ba629
--- /dev/null
+++ b/pages/components/Files.tsx
@@ -0,0 +1,271 @@
+import React, { useState } from "react";
+
+// Tree node structure from parsing
+interface TreeNode {
+ id: string;
+ name: string;
+ comment?: string;
+ children: TreeNode[];
+ startCollapsed: boolean;
+}
+
+// Flattened node for rendering
+interface RenderNode {
+ id: string;
+ name: string;
+ comment?: string;
+ depth: number;
+ isLast: boolean;
+ parentIsLast: boolean[];
+ isFolder: boolean;
+ hasChildren: boolean;
+}
+
+function parseTree(text: string): TreeNode[] {
+ const lines = text.split("\n").filter((line) => line.trim().length > 0);
+ if (lines.length === 0) return [];
+
+ // Parse lines - support both whitespace and dash-prefix for indentation
+ const items = lines.map((line, index) => {
+ const dashMatch = line.match(/^(-+)/);
+ let name: string;
+ let indent: number;
+ let comment: string | undefined;
+
+ if (dashMatch) {
+ name = line.slice(dashMatch[1].length);
+ indent = dashMatch[1].length;
+ } else {
+ name = line.trim();
+ indent = line.length - line.trimStart().length;
+ }
+
+ // Check for # comment
+ const commentMatch = name.match(/\s*#\s*(.*)$/);
+ if (commentMatch) {
+ comment = commentMatch[1].trim();
+ name = name.slice(0, commentMatch.index).trim();
+ }
+
+ // Check for (collapsed) suffix
+ const collapsedMatch = name.match(/\s*\(collapsed\)\s*$/i);
+ const startCollapsed = !!collapsedMatch;
+ if (collapsedMatch) {
+ name = name.slice(0, collapsedMatch.index).trim();
+ }
+
+ return { name, indent, comment, startCollapsed, lineIndex: index };
+ });
+
+ // Normalize indents by subtracting the minimum
+ const baseIndent = Math.min(...items.map((item) => item.indent));
+ items.forEach((item) => (item.indent -= baseIndent));
+
+ // Build tree using a stack
+ const roots: TreeNode[] = [];
+ const stack: { node: TreeNode; indent: number }[] = [];
+
+ for (const { name, indent, comment, startCollapsed, lineIndex } of items) {
+ const node: TreeNode = {
+ id: `node-${lineIndex}`,
+ name,
+ comment,
+ children: [],
+ startCollapsed,
+ };
+
+ // Pop stack until we find the parent (item with smaller indent)
+ while (stack.length > 0 && stack[stack.length - 1].indent >= indent) {
+ stack.pop();
+ }
+
+ if (stack.length === 0) {
+ roots.push(node);
+ } else {
+ stack[stack.length - 1].node.children.push(node);
+ }
+
+ stack.push({ node, indent });
+ }
+
+ return roots;
+}
+
+function flattenTree(
+ roots: TreeNode[],
+ collapsedIds: Set
+): RenderNode[] {
+ const result: RenderNode[] = [];
+
+ function traverse(
+ nodes: TreeNode[],
+ depth: number,
+ parentIsLast: boolean[]
+ ): void {
+ nodes.forEach((node, index) => {
+ const isLast = index === nodes.length - 1;
+ const isFolder = node.name.endsWith("/");
+ const hasChildren = node.children.length > 0;
+
+ result.push({
+ id: node.id,
+ name: node.name,
+ comment: node.comment,
+ depth,
+ isLast,
+ parentIsLast: [...parentIsLast],
+ isFolder,
+ hasChildren,
+ });
+
+ // Only traverse children if not collapsed
+ if (hasChildren && !collapsedIds.has(node.id)) {
+ traverse(node.children, depth + 1, [...parentIsLast, isLast]);
+ }
+ });
+ }
+
+ traverse(roots, 0, []);
+ return result;
+}
+
+function getInitialCollapsed(roots: TreeNode[]): Set {
+ const collapsed = new Set();
+
+ function traverse(nodes: TreeNode[]): void {
+ for (const node of nodes) {
+ if (node.startCollapsed) {
+ collapsed.add(node.id);
+ }
+ traverse(node.children);
+ }
+ }
+
+ traverse(roots);
+ return collapsed;
+}
+
+interface FileRowProps {
+ node: RenderNode;
+ isCollapsed: boolean;
+ onToggle: () => void;
+}
+
+function FileRow({ node, isCollapsed, onToggle }: FileRowProps) {
+ const isClickable = node.isFolder;
+ const isDotfile = node.name.startsWith(".");
+
+ return (
+
+ {/* Left side: indent + caret + name */}
+
+ {/* Caret for folders */}
+ {isClickable ? (
+
+
+
+
+
+ ) : (
+
+ )}
+
+
+ {node.name}
+
+
+
+ {/* Right side: comment */}
+ {node.comment && (
+
+ {node.comment}
+
+ )}
+
+ );
+}
+
+function extractText(children: React.ReactNode): string {
+ if (typeof children === "string") return children;
+ if (typeof children === "number") return String(children);
+ if (!children) return "";
+
+ if (Array.isArray(children)) {
+ return children.map(extractText).join("\n");
+ }
+
+ if (typeof children === "object" && "props" in children) {
+ const el = children as React.ReactElement;
+ if (el.type === "p" || el.type === "br") {
+ return extractText(el.props.children) + "\n";
+ }
+ return extractText(el.props.children);
+ }
+
+ return "";
+}
+
+interface FilesProps {
+ content?: string;
+ children?: React.ReactNode;
+}
+
+export default function Files({ content, children }: FilesProps) {
+ const text = content ?? extractText(children);
+ const [tree] = useState(() => parseTree(text));
+ const [collapsedIds, setCollapsedIds] = useState(() =>
+ getInitialCollapsed(tree)
+ );
+
+ const nodes = flattenTree(tree, collapsedIds);
+
+ const toggleCollapse = (id: string) => {
+ setCollapsedIds((prev) => {
+ const next = new Set(prev);
+ if (next.has(id)) {
+ next.delete(id);
+ } else {
+ next.add(id);
+ }
+ return next;
+ });
+ };
+
+ return (
+
+ {nodes.map((node) => (
+ toggleCollapse(node.id)}
+ />
+ ))}
+
+ );
+}
diff --git a/pages/Fire.tsx b/pages/components/Fire.tsx
similarity index 100%
rename from pages/Fire.tsx
rename to pages/components/Fire.tsx
diff --git a/pages/TodoList.tsx b/pages/components/TodoList.tsx
similarity index 74%
rename from pages/TodoList.tsx
rename to pages/components/TodoList.tsx
index a1085ab..d3e9f0f 100644
--- a/pages/TodoList.tsx
+++ b/pages/components/TodoList.tsx
@@ -8,6 +8,13 @@ interface Todo {
const STORAGE_KEY = "scratch-demo-todos";
+const DEFAULT_TODOS: Todo[] = [
+ { id: 1, text: "Create scratch project", completed: false },
+ { id: 2, text: "Edit pages/index.mdx", completed: false },
+ { id: 3, text: "Build with `scratch build`", completed: false },
+ { id: 4, text: "Publish with `scratch publish`", completed: false },
+];
+
let globalTodos: Todo[] | null = null;
let listeners: Set<(todos: Todo[]) => void> = new Set();
@@ -17,7 +24,7 @@ function getTodos(): Todo[] {
globalTodos = [];
} else {
const stored = localStorage.getItem(STORAGE_KEY);
- globalTodos = stored ? JSON.parse(stored) : [];
+ globalTodos = stored ? JSON.parse(stored) : DEFAULT_TODOS;
}
}
return globalTodos;
@@ -72,7 +79,7 @@ function useTodos() {
};
const reset = () => {
- updateTodos([]);
+ updateTodos([...DEFAULT_TODOS]);
};
return { todos, addTodo, toggleTodo, deleteTodo, reset };
@@ -89,30 +96,9 @@ export default function TodoList() {
return (
-
- setInput(e.target.value)}
- onKeyDown={(e) => e.key === "Enter" && handleAdd()}
- placeholder="Add a todo..."
- className="flex-1 px-3 py-2 border border-gray-300 rounded-md bg-white text-gray-900 placeholder-gray-400"
- />
-
- Add
-
-
-
- {todos.length === 0 ? (
-
- No todos yet. Add one above!
-
- ) : (
-
- {todos.map((todo) => (
+ Todo List Demo
+
+ {todos.map((todo) => (
deleteTodo(todo.id)}
- className="text-gray-400 hover:text-red-500 transition-colors"
+ className="text-gray-400 hover:text-black transition-colors"
aria-label="Delete todo"
>
))}
-
- )}
-
-
+
+
+ setInput(e.target.value)}
+ onKeyDown={(e) => e.key === "Enter" && handleAdd()}
+ placeholder="Add a todo..."
+ className="flex-1 bg-transparent border-b border-transparent text-gray-900 placeholder-gray-400 focus:outline-none focus:border-gray-300"
+ />
+
+
+
+
{todos.filter((t) => !t.completed).length} remaining
diff --git a/pages/docs.mdx b/pages/docs.mdx
new file mode 100644
index 0000000..2247133
--- /dev/null
+++ b/pages/docs.mdx
@@ -0,0 +1,510 @@
+---
+# Basic metadata
+title: "Scratch - Documentation" # Page title (
, og:title, twitter:title)
+description: "Complete documentation for the Scratch CLI" # SEO description
+keywords: ["MDX", "static site", "React", "Bun", "markdown"] # SEO keywords
+author: "Pete Koomen" # Page author
+robots: "index, follow" # Search engine directives
+lang: "en" # HTML lang attribute
+canonical: "https://scratch.dev/docs/" # Canonical URL ( )
+
+# Open Graph (social sharing)
+image: "https://scratch.dev/scratch-social.png" # Social sharing image (og:image, twitter:image)
+url: "https://scratch.dev/docs/" # Open Graph URL (og:url)
+type: "website" # Content type (og:type) - "website" or "article"
+siteName: "Scratch" # Site name (og:site_name)
+locale: "en_US" # Locale (og:locale)
+siteUrl: "https://scratch.dev" # Base URL for resolving relative image paths
+---
+
+# Documentation
+
+
+
+## Quick Start
+
+Scratch requires no configuration so it's easy to get started:
+
+```bash
+# Install scratch
+curl -fsSL https://scratch.dev/install.sh | bash
+
+# Create a new project
+scratch create
+
+# Start the dev server
+scratch dev
+```
+
+Now you're ready to start writing in `pages/index.mdx`.
+
+## Project Structure
+
+Scratch uses an opinionated project structure and requires **no boilerplate or configuration**: just create a project, run the dev server, and start writing.
+
+A simple Scratch project (created with `scratch create my-scratch-project`) looks like this:
+
+
+```
+my-scratch-project/
+ pages/ # put markdown pages and components here
+ posts/ (collapsed)
+ post1.md # accessible at /posts/post1
+ post2.md # /posts/post2
+ blog.png # static assets in pages/ or public/
+ index.mdx # accessible at root path (/)
+ Counter.tsx
+ public/ (collapsed) # static assets
+ favicon.svg
+ src/ (collapsed) # global components and css
+ markdown/ (collapsed) # default markdown components
+ index.ts
+ CodeBlock.tsx
+ Heading.tsx
+ Link.tsx
+ template/ (collapsed) # page template components
+ Copyright.jsx
+ Footer.jsx
+ Header.jsx
+ PageWrapper.jsx # wraps every page
+ ScratchBadge.jsx
+ tailwind.css # global styles
+ AGENTS.md # agent context
+ package.json # dependencies
+ .gitignore
+```
+
+
+Use `scratch build` to compile this project into a static website, like [this one](https://github.com/scratch/scratch.dev).
+
+### pages/
+
+Markdown files live in `pages/` and can be either MDX (`.mdx`) or vanilla Markdown (`.md`).
+
+Scratch compiles each Markdown file into a static web page whose route is determined by your project's directory structure:
+| File | URL |
+|------|-----|
+| `pages/index.mdx` | `/` |
+| `pages/about.mdx` | `/about/` |
+| `pages/posts/index.mdx` | `/posts/` |
+| `pages/posts/hello.mdx` | `/posts/hello/` |
+
+Component files and libraries can live anywhere in `pages/` and `src/`. They are auto-detected by Scratch and don't need to be explicitly imported in your Markdown files as long as the component name (`Counter`) matches the component name (`Counter.jsx` or `Counter.tsx`).
+
+`pages/` can also contain static content like images. These are copied directly into your output directory (`dist/`) and will be served the same way your compiled Markdown is.
+
+### public/
+
+Add static content like a favicon or `_redirects` file to the `public/` directory. These are copied directly into your output directory (`dist/`) just like static content in `pages/`.
+
+### src/
+
+`src/` is for CSS files, components and JS/TS libraries. New Scratch projects will contain the following:
+
+- `src/template/PageWrapper.jsx` - your Markdown contents will be "wrapped" with this component. Modify it to change page headers, footers, nav bars and other global components.
+- `src/template/` - contains page template components like `Header.jsx`, `Footer.jsx`, `Copyright.jsx`, and `ScratchBadge.jsx`.
+- `src/tailwind.css` - global styles. Edit this to change the look and feel of your compiled Markdown.
+- `src/markdown` - a directory containing default Markdown components. For example, edit `src/markdown/CodeBlock.tsx` to change how Markdown code blocks are rendered.
+
+
+### package.json
+
+Scratch automatically installs build dependencies. You can add additional dependencies by editing `package.json`.
+
+## Commands
+
+### scratch create
+
+Create a new Scratch project.
+
+```bash
+scratch create [path]
+```
+
+Options:
+- `--no-src` - Skip the src/ template directory
+- `--no-package` - Skip package.json template
+- `--no-example` - Skip example content files
+
+### scratch dev
+
+Start the development server with live reload.
+
+```bash
+scratch dev [path]
+```
+
+Options:
+- `-p, --port ` - Port for dev server (default: 5173)
+- `-n, --no-open` - Don't open browser automatically
+- `-d, --development` - Development mode (unminified, with source maps)
+- `-b, --base ` - Base path for deployment (e.g., `/mysite/`)
+- `--static ` - Static file mode:
+ - `public` - ignore static assets in `pages/`
+ - `assets` (default) - serve assets like images, but not javascript or typescript code files like `lib.js`
+ - `all` - serve assets _and_ code files statically
+- `--strict` - Disable auto-injection of PageWrapper and imports
+- `--highlight ` - Syntax highlighting supported languages: `off`, `popular`, `auto` (default), `all`
+
+### scratch build
+
+Build the project for production.
+
+```bash
+scratch build [path]
+```
+
+Options:
+- `-o, --out-dir ` - Output directory (default: `dist`)
+- `-d, --development` - Development mode (unminified, with source maps)
+- `-b, --base ` - Base path for deployment
+- `--no-ssg` - Disable static site generation
+- `--static ` - Static file mode: `public`, `assets`, `all`
+- `--strict` - Disable auto-injection of PageWrapper and imports
+- `--highlight ` - Syntax highlighting mode
+
+### scratch preview
+
+Preview the production build locally.
+
+```bash
+scratch preview [path]
+```
+
+**Options:**
+- `-p, --port ` - Port for preview server (default: 4173)
+- `-n, --no-open` - Don't open browser automatically
+
+### scratch view
+
+Quick preview of a single file or directory. Handy for e.g. reading `README.md` files.
+
+```bash
+scratch view
+```
+
+Options:
+- `-p, --port ` - Port for dev server (default: 5173)
+- `-n, --no-open` - Don't open browser automatically
+
+Useful for viewing individual `.md` or `.mdx` files without setting up a full project.
+
+### scratch clean
+
+Remove build artifacts.
+
+```bash
+scratch clean [path]
+```
+
+Removes the `dist/` and `.scratch-build-cache/` directories.
+
+### scratch checkout
+
+Restore template files from built-in templates.
+
+```bash
+scratch checkout [file]
+```
+
+Options:
+- `-l, --list` - List all available template files
+- `-f, --force` - Overwrite existing files without confirmation
+
+### scratch update
+
+Update Scratch to the latest version.
+
+```bash
+scratch update
+```
+
+### Global Options
+
+These options work with all commands:
+
+- `-v, --verbose` - Verbose output for debugging
+- `-q, --quiet` - Quiet mode (errors only)
+- `--show-bun-errors` - Show full Bun error stack traces
+- `--version` - Show CLI version
+
+## Writing Content
+
+### Frontmatter
+
+Add YAML frontmatter at the top of your MDX files to set page metadata. These properties are automatically converted to HTML meta tags for SEO and social sharing.
+
+#### Basic Properties
+
+| Property | Description |
+|----------|-------------|
+| `title` | Page title. Sets ``, `og:title`, and `twitter:title` |
+| `description` | Page description for SEO. Sets meta description, `og:description`, and `twitter:description` |
+| `keywords` | Keywords for SEO. Can be a string or array (arrays are joined with ", ") |
+| `author` | Page author. Sets `meta[name="author"]` |
+| `robots` | Robots directive (e.g., `"index, follow"`) |
+| `lang` | HTML language attribute (e.g., `"en"`) |
+| `canonical` | Canonical URL. Sets ` ` |
+
+#### Open Graph Properties
+
+| Property | Description | Default |
+|----------|-------------|---------|
+| `image` | Social sharing image URL. Sets `og:image` and `twitter:image` | - |
+| `url` | Canonical Open Graph URL. Sets `og:url` | - |
+| `type` | Content type. Sets `og:type` | `"article"` |
+| `siteName` | Site name. Sets `og:site_name` | - |
+| `locale` | Locale (e.g., `"en_US"`). Sets `og:locale` | - |
+| `siteUrl` | Base URL for resolving relative image paths | - |
+
+#### Twitter Card Properties
+
+| Property | Description | Default |
+|----------|-------------|---------|
+| `twitterCard` | Card type. Sets `twitter:card` | `"summary_large_image"` |
+| `twitterSite` | Site's Twitter handle (e.g., `"@mysite"`). Sets `twitter:site` | - |
+| `twitterCreator` | Author's Twitter handle. Sets `twitter:creator` | - |
+
+#### Article Properties
+
+| Property | Description |
+|----------|-------------|
+| `publishDate` | Publication date (ISO format). Sets `article:published_time` |
+| `modifiedDate` | Last modified date (ISO format). Sets `article:modified_time` |
+| `tags` | Article tags. Can be string or array. Sets `article:tag` |
+
+#### Example
+
+```yaml
+---
+title: "My Page Title"
+description: "A brief description for SEO and social sharing"
+keywords: ["react", "markdown", "static site"]
+author: "Your Name"
+image: "/og-image.png"
+type: "article"
+siteName: "My Site"
+locale: "en_US"
+twitterCard: "summary_large_image"
+twitterSite: "@mysite"
+publishDate: "2025-01-01"
+tags: ["tutorial", "guide"]
+canonical: "https://example.com/my-page"
+lang: "en"
+siteUrl: "https://example.com"
+---
+```
+
+**Note:** Image URLs can be absolute (starting with `http://` or `https://`) or relative paths. Relative paths are resolved against `siteUrl` if provided.
+
+### Using Components
+
+Components in `src/` or `pages/` are automatically available in MDX files:
+
+```mdx
+# My Page
+
+
+
+Click me
+```
+
+The component filename must match the component name (e.g., `Counter.tsx` exports `Counter`).
+
+### Component Patterns
+
+**Self-closing** (wrapped in `not-prose` div):
+```mdx
+
+```
+
+**Inline children:**
+```mdx
+Click me
+```
+
+**Block children** (requires blank lines):
+```mdx
+
+
+## Warning
+
+This is **markdown** inside a component.
+
+
+```
+
+## Styling
+
+### Tailwind CSS
+
+Scratch uses Tailwind CSS. Edit `src/tailwind.css` for global styles:
+
+```css
+@import 'tailwindcss';
+@plugin "@tailwindcss/typography";
+
+/* Custom styles */
+.prose a {
+ @apply text-blue-600 hover:text-blue-800;
+}
+```
+
+### Typography
+
+Markdown content is styled with [Tailwind Typography](https://github.com/tailwindlabs/tailwindcss-typography). Use prose modifiers in `src/template/PageWrapper.jsx`:
+
+```jsx
+
+ {children}
+
+```
+
+Element modifiers: `prose-h1:`, `prose-a:`, `prose-p:`, `prose-code:`, `prose-pre:`, etc.
+
+### Excluding from Prose
+
+Use the `not-prose` class to exclude elements from typography styling:
+
+```jsx
+
+
+
+```
+
+## PageWrapper
+
+Create `src/template/PageWrapper.jsx` to wrap all pages with a layout:
+
+```jsx
+export default function PageWrapper({ children }) {
+ return (
+
+ ...
+ {children}
+
+
+ );
+}
+```
+
+## Custom Markdown Components
+
+Override default markdown rendering by creating components in `src/markdown/`:
+
+```tsx
+// src/markdown/Link.tsx
+export default function Link({ href, children, ...props }) {
+ const isExternal = href?.startsWith('http');
+ return (
+
+ {children}
+
+ );
+}
+```
+
+Export from `src/markdown/index.ts`:
+
+```ts
+export { default as a } from './Link';
+export { default as pre } from './CodeBlock';
+export { default as h1, default as h2 } from './Heading';
+```
+
+## Syntax Highlighting
+
+Code blocks are highlighted with [Shiki](https://shiki.style/). Control highlighting with the `--highlight` flag:
+
+- `off` - No syntax highlighting
+- `popular` - Common languages only
+- `auto` - Detect from code blocks (default)
+- `all` - All languages
+
+## Build Pipeline
+
+When you run `scratch build`, Scratch compiles your MDX files into a **fully static website**. There's no server-side code running in production—everything is pre-rendered HTML, CSS, and JavaScript that can be hosted on any static file server.
+
+Scratch supports defaults that make it easy to create beautiful & functional websites with your writing. Here's a description of the Scratch build pipeline:
+
+### Build Steps
+
+#### 1. Dependency Resolution
+
+Scratch auto-installs npm dependencies from your `package.json` using Bun. Dependencies are cached in `.scratch-build-cache/` for faster subsequent builds.
+
+#### 2. Entry Generation
+
+For each `.mdx` or `.md` file in `pages/`, Scratch generates client and server entry files that import your content and wire up React rendering.
+
+#### 3. MDX Compilation
+
+MDX files are compiled through a pipeline of remark and rehype plugins:
+
+**Remark plugins** (process Markdown AST):
+- **remark-gfm** - GitHub Flavored Markdown (tables, strikethrough, task lists)
+- **remark-frontmatter** - Extracts YAML frontmatter for page metadata
+- **remark-auto-import** - Automatically imports components used in MDX without explicit import statements
+- **remark-not-prose** - Wraps self-closing components in `not-prose` divs to prevent Tailwind Typography styles from affecting them
+
+**Rehype plugins** (process HTML AST):
+- **rehype-raw** - Allows raw HTML in Markdown while preserving MDX nodes
+- **rehype-image-paths** - Transforms relative image paths to absolute routes, handles base paths for subdirectory deployments
+- **rehype-shiki** - Syntax highlighting using Shiki with configurable language detection
+- **rehype-footnotes** - Moves footnotes inside PageWrapper for proper styling
+
+#### 4. Tailwind Compilation
+
+Scratch compiles your CSS using Tailwind CSS v4. Only the utilities actually used in your content are included in the final bundle.
+
+#### 5. Server Build
+
+Scratch builds a server bundle to pre-render each page. The "server bundle" doesn't actually run on a server; it's only used during the build process to generate pre-rendered HTML.
+
+#### 6. Client Build
+
+The client JavaScript is bundled with Bun's bundler. Output is minified for production with content-hashed filenames for cache busting.
+
+#### 7. HTML Generation
+
+Each page is rendered to static HTML with:
+- Pre-rendered content from the server build
+- Injected CSS and JS bundle references
+- Meta tags from frontmatter (title, description, og:image, etc.)
+
+#### 8. Static Assets
+
+Files from `public/` are copied to the output directory.
+
+#### 9. Output
+
+The final static site is written to `dist/`, ready for deployment to any static host.
+
+## Deployment
+
+Build your site and deploy the `dist/` folder to any static host:
+
+```bash
+scratch build
+```
+
+For subdirectory deployment, use the `--base` flag:
+
+```bash
+scratch build --base /my-site/
+```
+
+## Generated Files
+
+Add these to `.gitignore`:
+
+```
+dist/
+.scratch-build-cache/
+node_modules/
+```
diff --git a/pages/index.mdx b/pages/index.mdx
index 67e6c5f..ce430e3 100644
--- a/pages/index.mdx
+++ b/pages/index.mdx
@@ -1,24 +1,43 @@
---
-title: "Scratch"
-description: "A CLI for building static MDX websites with Bun"
-keywords: ["MDX", "static site", "React", "Bun", "markdown"]
-author: "Scratch"
-type: "website"
-lang: "en"
+# Basic metadata
+title: "Scratch" # Page title (, og:title, twitter:title)
+description: "Write with Markdown and React" # SEO description
+keywords: ["MDX", "static site", "React", "Bun", "markdown"] # SEO keywords
+author: "Pete Koomen" # Page author
+robots: "index, follow" # Search engine directives
+lang: "en" # HTML lang attribute
+canonical: "https://scratch.dev/" # Canonical URL ( )
+
+# Open Graph (social sharing)
+image: "https://scratch.dev/scratch-social.png" # Social sharing image (og:image, twitter:image)
+url: "https://scratch.dev/" # Open Graph URL (og:url)
+type: "website" # Content type (og:type) - "website" or "article"
+siteName: "Scratch" # Site name (og:site_name)
+locale: "en_US" # Locale (og:locale)
+siteUrl: "https://scratch.dev" # Base URL for resolving relative image paths
---
-
-
-
+
+
+Scratch is a tool for writing with [Markdown](https://daringfireball.net/projects/markdown/) and [React](https://react.dev/).
+
+Write in Markdown and embed React components right in your text. Scratch compiles your work into beautiful static websites that can be hosted anywhere.
+
+Scratch was designed for collaborative writing with coding agents like [Claude Code](https://www.claude.com/product/claude-code). Use your favorite editor to write in Markdown and ask a coding agent for help when it's easier to express yourself with code.
-Scratch compiles Markdown and React into beautiful static websites that can be hosted anywhere.
## Quick Start
+Scratch requires no configuration so it's easy to get started. First, install:
+
```bash
# Install scratch
curl -fsSL https://scratch.dev/install.sh | bash
+```
+
+Then create a project and start the dev server:
+```bash
# Create a new project
scratch create
@@ -26,20 +45,24 @@ scratch create
scratch dev
```
+Now you're ready to start writing in `pages/index.mdx`. When you're ready, use the `publish` command to share with specific people, your team, or the world:
+
+```bash
+# Publish with a Scratch Server on Cloudflare
+scratch publish
+```
+
## What can you do with Scratch?
-Scratch was designed for collaborative writing with coding agents like [Claude Code](https://www.claude.com/product/claude-code). Use your favorite editor to write in [Markdown](https://daringfireball.net/projects/markdown/) and embed React components when it's easier to express yourself with code.
+Scratch lets you embed interactive React components into your writing, like this counter:
+
+
-Scratch supports Github-flavored Markdown features like tables and todolists:
+You can use components to style text or embed fully working demos in your product specs:
-| Feature | Supported? |
-|---------|-----------|
-| Compiles `.md` `.mdx` `.tsx` `.ts` `.jsx` `.js` | ✅ |
-| Dev server with HMR | ✅ |
-| Tailwind CSS styling | ✅ |
-| Code syntax highlighting | ✅ |
+
-Code blocks use syntax highlighting by [Shiki](https://shiki.style/):
+Scratch uses [Tailwind Typography](https://github.com/tailwindlabs/tailwindcss-typography) to render your prose with a clean aesthetic. It supports [Github-flavored Markdown](https://github.com/remarkjs/remark-gfm) out of the box. Code blocks use syntax highlighting by [Shiki](https://shiki.style/).
```python
def greet(name: str) -> str:
@@ -48,83 +71,23 @@ def greet(name: str) -> str:
print(greet("World"))
```
-You can use React components to style text or embed fully working demos in your product specs:
-
-
-
-In fact, coding agents have gotten so good that if you can describe it, you can add it to a document:
+Unlike traditional word processors, Scratch makes it easy to express any idea. If you can describe it to a coding agent, you can add it to your document:
-## No Boilerplate
+Collaborating with AI makes writing more fun. Scratch makes that easy.
-Scratch uses an opinionated project structure and requires **no boilerplate or configuration**: just create a project, run the dev server with `scratch dev`, and start writing.
+## Acknowledgements
-A simple Scratch project (created with `scratch create`) looks like this:
-
- mysite/
- ├── pages/
- │ ├── index.mdx
- │ ├── Counter.tsx
- │ └── examples/
- │ ├── index.md
- │ ├── markdown.md
- │ ├── todolist-spec.mdx
- │ └── TodoList.tsx
- └── public/
- ├── logo.png
- └── favicon.svg
-
+[Bun](https://bun.com/) for lightning-fast builds, development with HMR, native typescript support, and a portable executable.
-Use `scratch build` to compile this project into a [static website](https://scratch.dev/template).
+[React](https://react.dev/) and [MDX](https://mdxjs.com/) make it possible to write with Markdown and code. [Tailwind CSS](https://tailwindcss.com/) makes component styling easy.
-Borrowing heavily from [Tailwind Typography](https://github.com/tailwindlabs/tailwindcss-typography), Scratch uses default styles and Markdown components to render your prose with a clean aesthetic. Code blocks use syntax highlighting by [Shiki](https://shiki.style/).
+Content preprocessing relies on [unified](https://unifiedjs.com/), with [remark-gfm](https://github.com/remarkjs/remark-gfm) for GitHub Flavored Markdown and [remark-frontmatter](https://github.com/remarkjs/remark-frontmatter) plus [gray-matter](https://github.com/jonschlinkert/gray-matter) for parsing front matter.
-You can change styles and customize the page wrapper component by including the `src/` directory when you run `scratch create`:
+[Shiki](https://shiki.style/) provides beautiful, accurate syntax highlighting with VS Code's grammar engine.
-
- mysite/
- ├── pages/
- ├── public/
- └── src/
- ├── markdown/
- ├── PageWrapper.tsx
- └── tailwind.css
-
+[Commander.js](https://github.com/tj/commander.js) scaffolds the CLI.
-Component files and js/ts libraries can live anywhere in `pages/` and `src/`. They are auto-detected by Scratch and don't need to be explicitly imported in your .mdx files as long as the filename matches the component name.
-
-Scratch installs build dependencies automatically. You can add additional third-party dependencies by including a `package.json` file in your project root.
-
-## Built on Bun
-
-Scratch is built on [Bun](https://bun.com/) for lightning-fast builds, development with HMR, and native typescript support. It uses the [Tailwind CSS](https://tailwindcss.com/) framework to make component styling easy.
-
-Scratch compiles Javascript (.js), Typescript (.ts), JSX (.jsx), TSX (.tsx), Markdown (.md), and MDX (.mdx).
-
-## Commands
-
-```bash
-# Create a new project
-scratch create my-site # interactive
-scratch create --minimal # omit src/ and page examples
-scratch create --full # include src/, examples, and package.json
-
-# Start dev server with hot module reloading
-scratch dev
-
-# Build for production
-scratch build
-scratch build --ssg false # disable static site generation
-scratch build --development # unminified, with source maps
-
-# Preview production build locally
-scratch preview
-
-# Remove build artifacts
-scratch clean
-
-# Update scratch to latest version
-scratch update
-```
+Additional dependencies: [fast-glob](https://github.com/mrmlnc/fast-glob), [acorn](https://github.com/acornjs/acorn), [@mdx-js/esbuild](https://mdxjs.com/packages/esbuild/), [@shikijs/rehype](https://shiki.style/packages/rehype), [@types/mdast](https://github.com/DefinitelyTyped/DefinitelyTyped), [unist-util-visit](https://github.com/syntax-tree/unist-util-visit), [unist-util-is](https://github.com/syntax-tree/unist-util-is).
diff --git a/public/DVD_logo.svg b/public/DVD_logo.svg
deleted file mode 100644
index e85f92a..0000000
--- a/public/DVD_logo.svg
+++ /dev/null
@@ -1 +0,0 @@
-
diff --git a/public/scratch-social.png b/public/scratch-social.png
new file mode 100644
index 0000000..cc4205e
Binary files /dev/null and b/public/scratch-social.png differ
diff --git a/public/scratch.svg b/public/scratch.svg
new file mode 100644
index 0000000..afaa536
--- /dev/null
+++ b/public/scratch.svg
@@ -0,0 +1,213 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/PageWrapper.jsx b/src/PageWrapper.jsx
deleted file mode 100644
index f39868c..0000000
--- a/src/PageWrapper.jsx
+++ /dev/null
@@ -1,27 +0,0 @@
-import React from 'react';
-
-/**
- * A simple wrapper applied to every page in the demo project. Feel free to
- * replace this with your own layout – the scratch CLI will automatically detect
- * the component and wrap each MDX page with it during the build.
- */
-export default function PageWrapper({ children }) {
- return (
-
-
- {children}
-
- Released under the MIT License
-
- Copyright 2025 Pete Koomen
-
-
- );
-}
diff --git a/src/ScratchBadge.jsx b/src/ScratchBadge.jsx
new file mode 100644
index 0000000..e78c853
--- /dev/null
+++ b/src/ScratchBadge.jsx
@@ -0,0 +1,13 @@
+export default function ScratchBadge() {
+ return (
+
+ Made from
+
+
+ );
+}
diff --git a/src/tailwind.css b/src/tailwind.css
index a31aad8..678c7b5 100644
--- a/src/tailwind.css
+++ b/src/tailwind.css
@@ -11,9 +11,19 @@
* Custom prose overrides for elements not fully styled by @tailwindcss/typography
*/
+/* Links - only underline on hover */
+.prose :where(a):not(:where([class~='not-prose'] *)) {
+ @apply no-underline hover:underline;
+}
+
+/* H1 - center and add extra top margin */
+.prose :where(h1):not(:where([class~='not-prose'] *)) {
+ @apply text-center mt-16;
+}
+
/* Inline code - add background and padding, remove backticks */
.prose :where(code):not(:where([class~='not-prose'], pre *)) {
- @apply text-gray-900 font-medium text-[0.9em] bg-gray-100 px-1.5 py-0.5 rounded;
+ @apply text-gray-700 font-medium text-[0.9em] bg-gray-50 px-1.5 py-0.5 rounded;
}
.prose :where(code):not(:where([class~='not-prose'], pre *))::before,
@@ -44,9 +54,9 @@
@apply mr-2 align-middle ml-1;
}
-/* Tables - add horizontal padding, prevent overflow */
+/* Tables - center by default, prevent overflow */
.prose :where(table):not(:where([class~='not-prose'] *)) {
- @apply mx-4 w-auto max-w-full;
+ @apply mx-auto w-auto max-w-full;
}
/*
diff --git a/src/template/Copyright.jsx b/src/template/Copyright.jsx
new file mode 100644
index 0000000..131a290
--- /dev/null
+++ b/src/template/Copyright.jsx
@@ -0,0 +1,14 @@
+export default function Copyright({ name }) {
+ const author = name || (typeof window !== 'undefined' && window.__scratch_author__);
+ const year = new Date().getFullYear();
+
+ if (!author) {
+ return null;
+ }
+
+ return (
+
+ © {year} {author}
+
+ );
+}
diff --git a/src/template/Footer.jsx b/src/template/Footer.jsx
new file mode 100644
index 0000000..c9055c1
--- /dev/null
+++ b/src/template/Footer.jsx
@@ -0,0 +1,11 @@
+import ScratchBadge from './ScratchBadge';
+import Copyright from './Copyright';
+
+export default function Footer() {
+ return (
+
+ );
+}
diff --git a/src/template/Header.jsx b/src/template/Header.jsx
new file mode 100644
index 0000000..d6b3d2f
--- /dev/null
+++ b/src/template/Header.jsx
@@ -0,0 +1,20 @@
+export default function Header() {
+ return (
+
+ );
+}
diff --git a/src/template/PageWrapper.jsx b/src/template/PageWrapper.jsx
new file mode 100644
index 0000000..d727feb
--- /dev/null
+++ b/src/template/PageWrapper.jsx
@@ -0,0 +1,18 @@
+import React from 'react';
+import Header from './Header';
+import Footer from './Footer';
+
+/**
+ * A simple wrapper applied to every page in the demo project. Feel free to
+ * replace this with your own layout – the scratch CLI will automatically detect
+ * the component and wrap each MDX page with it during the build.
+ */
+export default function PageWrapper({ children }) {
+ return (
+
+
+ {children}
+
+
+ );
+}
diff --git a/src/template/ScratchBadge.jsx b/src/template/ScratchBadge.jsx
new file mode 100644
index 0000000..e78c853
--- /dev/null
+++ b/src/template/ScratchBadge.jsx
@@ -0,0 +1,13 @@
+export default function ScratchBadge() {
+ return (
+
+ Made from
+
+
+ );
+}