-
-
-
+
-
-
-
@@ -454,7 +383,29 @@ onUnmounted(() => {
>
{{ getFileIcon(name) }}
{{ name }}
+
+
+
+
+
@@ -617,12 +568,14 @@ onUnmounted(() => {
.file-item:hover .delete-btn { opacity: 1; }
.delete-btn:hover { color: var(--vp-c-danger-1); background: var(--vp-c-default-soft); }
+/* βββ Editor area βββ */
/* βββ Editor area βββ */
.editor-area {
flex: 1;
display: flex;
flex-direction: column;
min-width: 0;
+ min-height: 0;
background: var(--vp-c-bg);
}
@@ -661,6 +614,56 @@ onUnmounted(() => {
.tab-icon { font-size: 9px; }
.tab-name { font-family: inherit; }
+.tab-close-btn {
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ width: 16px;
+ height: 16px;
+ border: none;
+ background: transparent;
+ color: var(--vp-c-text-3);
+ cursor: pointer;
+ border-radius: 4px;
+ padding: 0;
+ margin-left: 2px;
+ opacity: 0;
+ transition: all 0.12s;
+}
+.tab:hover .tab-close-btn { opacity: 1; }
+.tab-close-btn:hover { color: var(--vp-c-text-1); background: var(--vp-c-default-soft); }
+
+.tab-add-btn {
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ width: 32px;
+ min-width: 32px;
+ border: none;
+ background: transparent;
+ color: var(--vp-c-text-3);
+ cursor: pointer;
+ transition: all 0.12s;
+}
+.tab-add-btn:hover { color: var(--vp-c-text-1); background: var(--vp-c-default-soft); }
+
+.tab-new-file-row {
+ padding: 4px 8px;
+ border-bottom: 1px solid var(--vp-c-divider);
+ background: var(--vp-c-bg-alt);
+}
+.tab-new-file-row input {
+ width: 200px;
+ padding: 4px 8px;
+ font-size: 12px;
+ border: 1px solid var(--vp-c-brand-1);
+ border-radius: 4px;
+ background: var(--vp-c-bg);
+ color: var(--vp-c-text-1);
+ outline: none;
+ font-family: inherit;
+}
+
.editor-container {
flex: 1;
overflow: hidden;
@@ -679,6 +682,7 @@ onUnmounted(() => {
display: flex;
flex-direction: column;
min-width: 0;
+ min-height: 0;
background: var(--vp-c-bg);
}
diff --git a/docs/.vitepress/config.js b/docs/.vitepress/config.js
index 39cf23d9..1c36b55b 100644
--- a/docs/.vitepress/config.js
+++ b/docs/.vitepress/config.js
@@ -1,12 +1,15 @@
export default {
title: "WebUI Framework",
description: "Native HTML Templating for Every Platform",
+ appearance: true,
head: [
['link', { rel: 'icon', href: '/favicon.ico' }],
],
themeConfig: {
logo: '/logo.svg',
siteTitle: 'WebUI Framework',
+ aside: false,
+ outline: false,
// Navigation bar
nav: [
diff --git a/docs/.vitepress/theme/custom.css b/docs/.vitepress/theme/custom.css
new file mode 100644
index 00000000..f84ee457
--- /dev/null
+++ b/docs/.vitepress/theme/custom.css
@@ -0,0 +1,619 @@
+@import url('https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700;800&display=swap');
+
+/* ==========================================================
+ 1. Design tokens β light mode (default)
+ All theme-aware values live here as custom properties.
+ Dark mode overrides only the variables, never duplicates
+ selectors.
+ ========================================================== */
+
+:root {
+ /* --- Typography --- */
+ --vp-font-family-base: 'Inter', ui-sans-serif, system-ui, -apple-system,
+ BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;
+ --vp-font-family-mono: 'Cascadia Code', 'Fira Code', 'JetBrains Mono',
+ ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace;
+
+ /* --- Radius tokens --- */
+ --radius-md: 12px;
+ --radius-lg: 20px;
+ --radius-xl: 24px;
+
+ /* --- Surfaces --- */
+ --vp-c-bg: #efeae7;
+ --vp-c-bg-alt: #e8e3df;
+ --vp-c-bg-elv: #f8f4f1;
+ --vp-c-bg-soft: #e8e3df;
+ --vp-c-mute: #e8e3df;
+ --copilot-panel: #f8f4f1;
+ --copilot-panel-shadow: 0 16px 24px rgba(0, 0, 0, 0.08);
+
+ /* --- Brand / accent --- */
+ --vp-c-brand-1: #a25a02;
+ --vp-c-brand-2: #c87b0a;
+ --vp-c-brand-3: #8a4b03;
+ --vp-c-brand-soft: rgba(162, 90, 2, 0.08);
+ --accent: #a25a02;
+ --accent-soft-border: rgba(162, 90, 2, 0.25);
+ --accent-soft-bg: rgba(162, 90, 2, 0.04);
+ --accent-hover: rgba(162, 90, 2, 0.20);
+
+ /* --- Tip --- */
+ --vp-c-tip-1: var(--accent);
+ --vp-c-tip-soft: var(--vp-c-brand-soft);
+
+ /* --- Text --- */
+ --vp-c-text-1: #272320;
+ --vp-c-text-2: rgba(39, 35, 32, 0.70);
+ --vp-c-text-3: rgba(39, 35, 32, 0.44);
+ --text-muted: rgba(39, 35, 32, 0.55);
+
+ /* --- Borders --- */
+ --vp-c-border: rgba(39, 35, 32, 0.10);
+ --vp-c-divider: rgba(39, 35, 32, 0.06);
+ --vp-c-gutter: rgba(39, 35, 32, 0.04);
+ --border-subtle: rgba(39, 35, 32, 0.06);
+
+ /* --- Nav / Sidebar --- */
+ --vp-nav-bg-color: rgba(239, 234, 231, 0.85);
+ --vp-sidebar-bg-color: #efeae7;
+
+ /* --- Code --- */
+ --vp-code-block-bg: #efeae7;
+ --vp-code-line-highlight-color: rgba(162, 90, 2, 0.06);
+ --vp-code-copy-code-hover-bg: rgba(39, 35, 32, 0.06);
+
+ /* --- Hero gradients --- */
+ --vp-home-hero-name-color: transparent;
+ --vp-home-hero-name-background: linear-gradient(135deg, #a25a02, #c87b0a 40%, #8a4b03);
+ --vp-home-hero-image-background-image: linear-gradient(135deg, rgba(162, 90, 2, 0.12), rgba(200, 123, 10, 0.08) 50%, rgba(138, 75, 1, 0.08));
+ --vp-home-hero-image-filter: blur(56px);
+
+ /* --- Buttons --- */
+ --vp-button-brand-border: transparent;
+ --vp-button-brand-text: #fff;
+ --vp-button-brand-bg: #272320;
+ --vp-button-brand-hover-border: transparent;
+ --vp-button-brand-hover-text: #fff;
+ --vp-button-brand-hover-bg: #3d3833;
+ --vp-button-brand-active-border: transparent;
+ --vp-button-brand-active-text: #fff;
+ --vp-button-brand-active-bg: #4e4843;
+ --vp-button-alt-border: rgba(39, 35, 32, 0.12);
+ --vp-button-alt-text: #272320;
+ --vp-button-alt-bg: rgba(39, 35, 32, 0.04);
+ --vp-button-alt-hover-border: rgba(39, 35, 32, 0.20);
+ --vp-button-alt-hover-text: #272320;
+ --vp-button-alt-hover-bg: rgba(39, 35, 32, 0.08);
+
+ /* --- Feature cards --- */
+ --card-bg: #ffffff;
+ --card-border: rgba(39, 35, 32, 0.06);
+ --card-shadow: 0 1px 3px rgba(39, 35, 32, 0.04);
+ --card-hover-border: var(--accent-hover);
+ --card-hover-shadow: 0 8px 32px rgba(39, 35, 32, 0.06);
+ --card-hover-bg: #ffffff;
+
+ /* --- Scrollbar --- */
+ --scrollbar-thumb: rgba(39, 35, 32, 0.12);
+ --scrollbar-thumb-hover: rgba(39, 35, 32, 0.22);
+
+ /* --- Search --- */
+ --search-bg: #ffffff;
+ --search-border: rgba(39, 35, 32, 0.10);
+
+ /* --- Table --- */
+ --table-border: var(--border-subtle);
+ --table-header-bg: rgba(39, 35, 32, 0.03);
+
+ /* --- Badge --- */
+ --vp-badge-info-border: var(--accent-soft-border);
+ --vp-badge-info-text: var(--accent);
+ --vp-badge-info-bg: var(--vp-c-brand-soft);
+}
+
+/* ==========================================================
+ 2. Dark mode β override only the variables
+ ========================================================== */
+
+.dark {
+ --vp-c-bg: #0e111b;
+ --vp-c-bg-alt: #0a0d14;
+ --vp-c-bg-elv: #1c1f2e;
+ --vp-c-bg-soft: #151823;
+ --vp-c-mute: #151823;
+ --copilot-panel: #161a26;
+ --copilot-panel-shadow: 0 16px 24px rgba(0, 0, 0, 0.30);
+
+ --vp-c-brand-1: #97abea;
+ --vp-c-brand-2: #b3c1f4;
+ --vp-c-brand-3: #7b8fd2;
+ --vp-c-brand-soft: rgba(151, 171, 234, 0.14);
+ --accent: #97abea;
+ --accent-soft-border: rgba(151, 171, 234, 0.25);
+ --accent-soft-bg: rgba(151, 171, 234, 0.06);
+ --accent-hover: rgba(151, 171, 234, 0.20);
+
+ --vp-c-text-1: #e5ebfa;
+ --vp-c-text-2: rgba(229, 235, 250, 0.60);
+ --vp-c-text-3: rgba(229, 235, 250, 0.38);
+ --text-muted: rgba(229, 235, 250, 0.55);
+
+ --vp-c-border: rgba(229, 235, 250, 0.10);
+ --vp-c-divider: rgba(229, 235, 250, 0.06);
+ --vp-c-gutter: rgba(229, 235, 250, 0.04);
+ --border-subtle: rgba(229, 235, 250, 0.06);
+
+ --vp-nav-bg-color: rgba(14, 17, 27, 0.85);
+ --vp-sidebar-bg-color: #0e111b;
+
+ --vp-code-block-bg: #0e111b;
+ --vp-code-line-highlight-color: rgba(151, 171, 234, 0.08);
+ --vp-code-copy-code-hover-bg: rgba(229, 235, 250, 0.06);
+
+ --vp-home-hero-name-background: linear-gradient(135deg, #97abea, #b3c1f4 40%, #7b8fd2);
+ --vp-home-hero-image-background-image: linear-gradient(135deg, rgba(151, 171, 234, 0.20), rgba(121, 143, 212, 0.12) 50%, rgba(83, 105, 182, 0.12));
+
+ --vp-button-brand-border: transparent;
+ --vp-button-brand-text: #0e111b;
+ --vp-button-brand-bg: #e5ebfa;
+ --vp-button-brand-hover-border: transparent;
+ --vp-button-brand-hover-text: #0e111b;
+ --vp-button-brand-hover-bg: #d1d9ee;
+ --vp-button-brand-active-border: transparent;
+ --vp-button-brand-active-text: #0e111b;
+ --vp-button-brand-active-bg: #bbc5de;
+ --vp-button-alt-border: rgba(229, 235, 250, 0.10);
+ --vp-button-alt-text: #e5ebfa;
+ --vp-button-alt-bg: rgba(229, 235, 250, 0.05);
+ --vp-button-alt-hover-border: rgba(229, 235, 250, 0.18);
+ --vp-button-alt-hover-text: #e5ebfa;
+ --vp-button-alt-hover-bg: rgba(229, 235, 250, 0.08);
+
+ --card-bg: rgba(229, 235, 250, 0.03);
+ --card-border: rgba(229, 235, 250, 0.06);
+ --card-shadow: none;
+ --card-hover-border: var(--accent-hover);
+ --card-hover-shadow: 0 8px 32px rgba(151, 171, 234, 0.06);
+ --card-hover-bg: rgba(151, 171, 234, 0.04);
+
+ --scrollbar-thumb: rgba(229, 235, 250, 0.10);
+ --scrollbar-thumb-hover: rgba(229, 235, 250, 0.18);
+
+ --search-bg: #161a26;
+ --search-border: rgba(229, 235, 250, 0.08);
+
+ --table-border: var(--border-subtle);
+ --table-header-bg: rgba(229, 235, 250, 0.04);
+
+ --vp-badge-info-border: rgba(151, 171, 234, 0.30);
+ --vp-badge-info-text: #b3c1f4;
+ --vp-badge-info-bg: rgba(151, 171, 234, 0.12);
+}
+
+/* ==========================================================
+ 3. Layout β raised content panel
+ ========================================================== */
+
+html,
+body {
+ overflow: hidden;
+ height: 100%;
+}
+
+.Layout {
+ height: 100vh;
+ overflow: hidden;
+}
+
+.VPContent {
+ position: fixed !important;
+ inset: 64px 12px 8px 260px;
+ width: auto !important;
+ padding: 0 !important;
+ overflow-y: auto;
+ overflow-x: hidden;
+ background: var(--copilot-panel);
+ border-radius: var(--radius-xl) var(--radius-xl) 8px var(--radius-xl);
+ box-shadow: var(--copilot-panel-shadow);
+ z-index: 1;
+}
+
+.VPContent:not(.has-sidebar) {
+ left: 12px;
+}
+
+.VPContent:has(.VPHome) {
+ background: transparent;
+ left: 8px;
+}
+
+/* --- VPDoc reset (panel is on VPContent) --- */
+
+.VPDoc {
+ background: transparent;
+ border-radius: 0;
+ box-shadow: none;
+ margin-top: 0;
+ min-height: auto;
+ padding: 48px 56px 96px !important;
+}
+
+.VPDoc .container,
+.VPDoc .content,
+.VPDoc .content-container,
+.vp-doc,
+.vp-doc>* {
+ max-width: 100%;
+ min-width: 0;
+}
+
+.VPDoc .content {
+ width: 100%;
+ padding-left: 0 !important;
+ padding-right: 0 !important;
+}
+
+.vp-doc {
+ overflow-wrap: break-word;
+ word-break: break-word;
+}
+
+/* --- Home page panel --- */
+
+.VPHome {
+ position: relative;
+ min-height: calc(100vh - 80px);
+}
+
+/* --- Responsive --- */
+
+@media (max-width: 959px) {
+ .VPContent {
+ left: 12px !important;
+ top: 64px;
+ }
+
+ .VPDoc {
+ padding: 32px 32px 96px !important;
+ }
+}
+
+@media (max-width: 640px) {
+ .VPContent {
+ left: 6px !important;
+ right: 6px;
+ bottom: 6px;
+ top: 64px;
+ border-radius: var(--radius-lg) var(--radius-lg) 6px var(--radius-lg);
+ }
+
+ .VPDoc {
+ padding: 24px 20px 96px !important;
+ }
+}
+
+/* ==========================================================
+ 4. Navbar β clean glass, no borders
+ ========================================================== */
+
+.VPNavBar {
+ backdrop-filter: blur(12px) saturate(1.4);
+ -webkit-backdrop-filter: blur(12px) saturate(1.4);
+ border-bottom: none !important;
+}
+
+.VPNavBar .wrapper {
+ padding: 0 !important;
+ max-width: 100% !important;
+}
+
+.VPNavBar .wrapper .container {
+ max-width: 100% !important;
+}
+
+.VPNavBar .content {
+ padding-right: 30px !important;
+ padding-left: var(--vp-sidebar-width) !important;
+}
+
+.VPNavBar.home .content,
+.playground-active .VPNavBar .content {
+ padding-left: 73px !important;
+}
+
+.VPNavBar .divider,
+.VPNavBar .divider-line {
+ display: none !important;
+}
+
+.VPNavBarTitle .title {
+ border-bottom: none !important;
+}
+
+.VPNavBarTitle {
+ padding-left: 0 !important;
+}
+
+.VPNavBar .container > .title {
+ padding-left: 25px !important;
+}
+
+/* ==========================================================
+ 5. Sidebar
+ ========================================================== */
+
+.VPSidebar {
+ background-color: var(--vp-sidebar-bg-color) !important;
+ border-right: none !important;
+ padding-left: 24px !important;
+ width: 252px !important;
+}
+
+.VPSidebarItem.level-0 .text {
+ font-weight: 600;
+ letter-spacing: -0.01em;
+}
+
+.VPSidebarItem.is-active>.item>.indicator {
+ background: var(--accent);
+}
+
+.VPSidebarItem .link:hover .text {
+ color: var(--accent);
+}
+
+/* ==========================================================
+ 6. Hidden elements
+ ========================================================== */
+
+.VPFooter {
+ display: none !important;
+}
+
+/* VPLocalNav: hidden on desktop, restyled as floating sidebar tab on mobile */
+.VPLocalNav {
+ display: none !important;
+}
+
+@media (max-width: 959px) {
+ .VPLocalNav {
+ display: block !important;
+ position: fixed !important;
+ top: 100px !important;
+ left: 0;
+ right: auto !important;
+ width: auto !important;
+ height: auto !important;
+ background: transparent !important;
+ border: none !important;
+ z-index: 5;
+ padding: 0 !important;
+ margin: 0 !important;
+ }
+
+ /* Hide everything except the menu button */
+ .VPLocalNav .container {
+ display: contents;
+ }
+
+ .VPLocalNav .VPLocalNavOutlineDropdown {
+ display: none !important;
+ }
+
+ /* Style the menu button as a peek tab on the left edge */
+ .VPLocalNav .menu {
+ display: flex !important;
+ align-items: center;
+ gap: 0;
+ padding: 10px 6px;
+ background: var(--copilot-panel);
+ border: 1px solid var(--vp-c-border);
+ border-left: none;
+ border-radius: 0 var(--radius-md) var(--radius-md) 0;
+ box-shadow: 2px 2px 12px rgba(0, 0, 0, 0.08);
+ color: var(--accent);
+ cursor: pointer;
+ transition: all 0.2s ease;
+ writing-mode: vertical-rl;
+ font-size: 11px;
+ font-weight: 600;
+ letter-spacing: 0.05em;
+ line-height: 1;
+ }
+
+ .VPLocalNav .menu .menu-icon {
+ font-size: 12px;
+ writing-mode: horizontal-tb;
+ margin-bottom: 4px;
+ }
+
+ .VPLocalNav .menu .menu-text {
+ font-size: 11px;
+ }
+
+ .VPLocalNav .menu:hover,
+ .VPLocalNav .menu:active {
+ background: var(--vp-c-bg-elv);
+ padding-right: 10px;
+ }
+}
+
+/* Mobile nav screen & sidebar must layer above the content panel */
+.VPNavScreen {
+ z-index: 10 !important;
+ background: var(--copilot-panel) !important;
+ bottom: auto !important;
+ height: auto !important;
+ border-radius: 0 0 var(--radius-xl) var(--radius-xl);
+ box-shadow: var(--copilot-panel-shadow);
+ padding: 0 24px !important;
+ width: 100% !important;
+ left: 0 !important;
+ right: 0 !important;
+}
+
+.VPNavScreen .container {
+ padding: 16px 0 24px !important;
+}
+
+/* ==========================================================
+ 7. Hero
+ ========================================================== */
+
+.VPHero {
+ padding: 88px 48px 32px !important;
+ max-width: 100% !important;
+}
+
+.VPHero .main {
+ max-width: 720px !important;
+}
+
+.VPHero .name {
+ font-size: 36px !important;
+ font-weight: 800;
+ letter-spacing: -0.03em;
+ line-height: 1.1;
+}
+
+.VPHero .text {
+ font-size: 28px !important;
+ font-weight: 600;
+ letter-spacing: -0.02em;
+ line-height: 1.25;
+}
+
+.VPHero .tagline {
+ font-size: 16px !important;
+ font-weight: 400;
+ line-height: 1.6;
+ color: var(--text-muted);
+}
+
+.VPHero .actions .VPButton.brand,
+.VPHero .actions .VPButton.alt {
+ border-radius: var(--radius-lg);
+ font-weight: 600;
+ padding: 0 28px;
+ transition: all 0.25s cubic-bezier(0.4, 0, 0.2, 1);
+}
+
+.VPHero .actions .VPButton.brand:hover {
+ transform: translateY(-1px);
+ box-shadow: 0 4px 16px rgba(0, 0, 0, 0.10);
+}
+
+.VPHero .actions .VPButton.alt:hover {
+ transform: translateY(-1px);
+}
+
+/* ==========================================================
+ 8. Content polish
+ ========================================================== */
+
+div[class*='language-'] {
+ border-radius: var(--radius-md) !important;
+}
+
+div[class*='language-']>button.copy {
+ border-radius: 8px;
+}
+
+.vp-code-group .tabs {
+ border-radius: var(--radius-md) var(--radius-md) 0 0;
+ border-bottom: 1px solid var(--border-subtle);
+}
+
+.custom-block {
+ border-radius: var(--radius-md);
+}
+
+.custom-block.tip {
+ border-color: var(--accent-soft-border);
+ background-color: var(--accent-soft-bg);
+}
+
+.vp-doc a {
+ text-decoration: none;
+ transition: color 0.2s ease;
+}
+
+.vp-doc a:hover {
+ text-decoration: underline;
+ text-underline-offset: 3px;
+}
+
+.vp-doc table {
+ border-radius: var(--radius-md);
+ overflow: hidden;
+}
+
+.vp-doc tr {
+ border-color: var(--table-border);
+}
+
+.vp-doc th {
+ background-color: var(--table-header-bg);
+}
+
+/* ==========================================================
+ 9. Feature cards
+ ========================================================== */
+
+.VPFeature {
+ border-radius: var(--radius-lg) !important;
+ background-color: var(--card-bg) !important;
+ border: 1px solid var(--card-border) !important;
+ box-shadow: var(--card-shadow);
+ transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
+}
+
+.VPFeature:hover {
+ border-color: var(--card-hover-border) !important;
+ background-color: var(--card-hover-bg) !important;
+ box-shadow: var(--card-hover-shadow);
+ transform: translateY(-2px);
+}
+
+/* ==========================================================
+ 10. Scrollbar
+ ========================================================== */
+
+::-webkit-scrollbar {
+ width: 6px;
+ height: 6px;
+}
+
+::-webkit-scrollbar-track {
+ background: transparent;
+}
+
+::-webkit-scrollbar-thumb {
+ background: var(--scrollbar-thumb);
+ border-radius: 3px;
+}
+
+::-webkit-scrollbar-thumb:hover {
+ background: var(--scrollbar-thumb-hover);
+}
+
+/* ==========================================================
+ 11. Search dialog
+ ========================================================== */
+
+.VPLocalSearchBox .shell {
+ border-radius: var(--radius-lg);
+ border: 1px solid var(--search-border);
+ background-color: var(--search-bg);
+}
+
+/* ==========================================================
+ 12. Transitions
+ ========================================================== */
+
+.VPSidebarItem .link,
+.VPNavBarMenuLink,
+.VPNavBarMenuGroup {
+ transition: color 0.2s ease, background-color 0.2s ease;
+}
\ No newline at end of file
diff --git a/docs/.vitepress/theme/index.js b/docs/.vitepress/theme/index.js
new file mode 100644
index 00000000..15492a8c
--- /dev/null
+++ b/docs/.vitepress/theme/index.js
@@ -0,0 +1,6 @@
+import DefaultTheme from 'vitepress/theme'
+import './custom.css'
+
+export default {
+ extends: DefaultTheme,
+}
diff --git a/docs/guide/index.md b/docs/guide/index.md
index 7cbc6442..b0b476bc 100644
--- a/docs/guide/index.md
+++ b/docs/guide/index.md
@@ -1,57 +1,56 @@
-# Introduction to WebUI Framework
+# Introduction
-## Reimagining Web Development
+## What is WebUI?
-WebUI Framework was born from a simple question: What if we could build web applications without the overhead that modern JavaScript frameworks impose?
+WebUI is a server-side rendering framework that compiles HTML templates into a binary protocol at build time. At runtime, your backend simply applies state data to the pre-compiled protocol and gets rendered HTML back β no template parsing, no JavaScript runtime, minimal computation.
-The web platform was designed with clear separation of concerns - HTML for structure, CSS for presentation, and JavaScript for behavior. Yet somewhere along the way, we ended up with JavaScript frameworks that do everything, often at the expense of performance and simplicity.
+## The Problem
-## The Problem With Traditional JS Frameworks
+Traditional server-side rendering re-parses and re-evaluates templates on every request. JavaScript-based SSR frameworks require a Node.js runtime on the server. Both approaches add latency and complexity that scales poorly.
-Modern web development has strayed far from the web's original design:
+## How WebUI Works
-- **JavaScript Wasn't Built to Be a UI Framework**: JavaScript was designed as a lightweight scripting language to add interactivity, not to manage the entire rendering pipeline.
+WebUI splits the work into two phases:
-- **Tangled Concerns**: CSS-in-JS, HTML-in-JS, and JSX blur the lines between structure, style, and logic, making codebases harder to maintain and understand.
+1. **Build time** β The CLI parses your HTML templates, discovers web components, evaluates static content, and compiles everything into a compact Protocol Buffer binary. Static and dynamic content are separated. This happens once.
-- **Client-Side Rendering Costs**: Shipping megabytes of JavaScript to be parsed and executed by browsers creates poor initial loading experiences and hurts performance metrics.
+2. **Runtime** β Your backend handler loads the pre-compiled protocol, receives JSON state data, and produces rendered HTML. No parsing, no AST walking, no expression compilation β just fill in the blanks.
-- **Runtime Overhead**: Every interaction requires JavaScript to recalculate state, rebuild the DOM, and update the UI - creating unnecessary work for both servers and browsers.
+The result: rendering is fast, predictable, and language-agnostic.
-## WebUI's Approach: Back to Fundamentals, Forward to Performance
+## Key Concepts
-WebUI Framework returns to the web platform's core strengths while embracing modern needs:
+- **Protocol Buffer binary** β Templates compile to a compact binary format. The handler reads fragments sequentially β static fragments are emitted as-is, dynamic fragments are resolved from state.
-- **Separation of Concerns**: HTML templates are HTML, CSS is CSS, and JavaScript is for enhancing interactivity - not recreating the browser's rendering engine.
+- **Language agnostic** β Native handlers for Rust, Node/Bun/Deno, C#, Python, and Go. Any other language can use the C FFI bindings.
-- **Build-Time Optimization**: WebUI separates static and dynamic content at build time, creating an efficient protocol that dramatically reduces runtime costs.
+- **Web Components** β Templates are standard HTML with native web components and Shadow DOM. No proprietary syntax beyond a few template directives (`
`, ``, `{{}}`).
-- **Islands of Interactivity**: Following the "Islands Architecture," we keep most of the page static and fast, with interactive components only where needed.
+- **Server-side expressions** β Conditionals and expressions are evaluated on the server. Template logic doesn't leak into the browser.
-- **Extensible Plugin System**: Framework-specific plugins can customize parsing and rendering behavior β for example, injecting hydration markers for FAST-HTML β without changing WebUI's core.
+- **Plugin system** β Parser and handler plugins for hydration, adding reactivity to interactive islands, custom directives, and framework-specific behavior.
-- **Language-Agnostic Backend**: Whether you use Rust, Go, C#, PHP, Ruby, or any other server language, WebUI works without requiring a Node.js runtime.
+## Quick Overview
-## Real Benefits You'll Experience
+```
+ββββββββββββββββ βββββββββββββββββ βββββββββββββββββ
+β HTML + CSS βββββΆβ webui build βββββΆβ .webui binary β
+β templates β β (build time) β β (protocol) β
+ββββββββββββββββ βββββββββββββββββ βββββββββ¬ββββββββ
+ β
+ βββββββββββββββββ β
+ β JSON state ββββββββββββββ€
+ β (runtime) β β
+ βββββββββββββββββ βΌ
+ βββββββββββββββββ
+ β handler β
+ β (any lang β
+ βββββββββ¬ββββββββ
+ β
+ βΌ
+ βββββββββββββββββ
+ β rendered HTML β
+ βββββββββββββββββ
+```
-- **Lightning-Fast Performance**: By minimizing JavaScript execution and optimizing for key web vitals, users experience near-instant page loads.
-
-- **Simplified Development**: Write templates as templates, styles as styles, and focus your JavaScript just on what's interactive.
-
-- **Universal Server Support**: No more JavaScript backend requirements - use the language and server infrastructure you prefer.
-
-- **Reduced Bundle Sizes**: Send just the state data, not entire rendering libraries or HTML strings.
-
-- **Better SEO and Accessibility**: Pre-rendered content ensures search engines and assistive technologies can easily interpret your pages.
-
-## How Is This Possible?
-
-WebUI takes a fundamentally different approach:
-
-1. At **build time**, WebUI analyzes your components and creates an efficient protocol separating static from dynamic content
-2. At **runtime**, your server applies state to this protocol with minimal computation
-3. In the **browser**, content arrives mostly pre-rendered and ready to display
-
-This means pages load faster, servers require less processing power, and developers can work with a more intuitive separation of concerns.
-
-Ready to see how it works in practice? Let's start building with WebUI Framework!
\ No newline at end of file
+Ready to try it? Start with the [Playground](/playground/) to experiment in the browser, then follow the [installation guide](./installation) or the [Hello World tutorial](/tutorials/hello-world) to build locally.
\ No newline at end of file
diff --git a/docs/index.md b/docs/index.md
index 39998f08..b96d19f3 100644
--- a/docs/index.md
+++ b/docs/index.md
@@ -1,38 +1,34 @@
---
layout: home
hero:
- name: "WebUI Framework"
- text: "Fast Web Rendering Without JavaScript Overhead"
- tagline: Build UIs at compile time, serve them blazingly fast from any backend language
+ name: "WebUI"
+ text: "Web Rendering Without a JavaScript Runtime"
+ tagline: Compile templates to binary. Serve them instantly from any backend.
actions:
- theme: brand
- text: Get Started
+ text: Get Started β
link: /guide/
- theme: alt
text: View on GitHub
link: https://github.com/microsoft/webui
----
-
-# Welcome to WebUI Framework
-
-## A New Approach to Server-Side Rendering
-
-WebUI Framework is a high-performance solution for building web applications that deliver exceptional user experiences without JavaScript runtime overhead. Unlike traditional frameworks that build UIs at runtime, WebUI separates dynamic from static content at build time and creates an efficient protocol for fast rendering.
-
-### Why WebUI?
-- **Language Agnostic Backend**: Use Rust, Go, C#, PHP, Ruby, or any other language - no Node.js required!
-- **Optimized Web Vitals**: Significantly faster FCP, LCP, and INP metrics compared to JS-based SSR
-- **Web Component-Based**: Built on the native web platform using modern web components
-- **Edge-Ready**: Can be served from edge functions or a streamable Service Worker
-- **Separation of Concerns**: UI structure is cached and separate from state data
-- **Minimal Transfer Size**: Only send the state, not the entire rendered HTML
-- **Framework Integration**: Extensible plugin system for client-side hydration with frameworks like FAST-HTML
-
-## How It Works
-
-1. **Build Time**: WebUI discovers all your web components and creates a protocol that separates dynamic from static content
-2. **Serving**: Your backend (in any language) applies state to this protocol through a lightweight handler
-3. **Rendering**: Content reaches the browser pre-rendered and ready to display, with minimal JavaScript overhead
-
-Get started now by following our [installation guide](/guide/) or check out the [Hello World tutorial](/tutorials/hello-world).
+features:
+ - icon: β‘
+ title: Compiled to Binary
+ details: Templates are compiled at build time into a Protocol Buffer binary β no parsing or interpretation at runtime.
+ - icon: π
+ title: Language Agnostic
+ details: Render from Rust, Node, Bun, Deno, C#, Python, Go β or any language via FFI.
+ - icon: π©
+ title: Minimal Runtime Work
+ details: Static and dynamic split at build time. At runtime the server fills in state and evaluates expressions β no client-side scripting for template logic.
+ - icon: π§©
+ title: Web Components
+ details: Built on native web components with Shadow DOM encapsulation for style isolation and reusability.
+ - icon: π
+ title: Plugin System
+ details: Parser and handler plugins for hydration, adding reactivity to interactive islands, custom directives, and framework-specific behavior.
+ - icon: ποΈ
+ title: Replaces Node.js SSR
+ details: No JavaScript runtime on the server. Rust-native rendering uses less memory and handles more requests per second β fewer servers, lower bills.
+---