pub fn Page(ctx: zx.PageContext) !zx.Component {
    // var page_timer = std.time.Timer.start() catch unreachable;
    const allocator = ctx.arena;
    const examples_source = @embedFile("../examples/feature_examples.zx");
    const examples = @import("../examples/feature_examples.zx");

    // std.log.info("\x1b[1;36m[DOCS PAGE] Starting page generation...\x1b[0m", .{});

    // If example
    const zx_example_if = util.extractSection(allocator, examples_source, "Control Flow: if");
    const zig_example_if = zx_example_if;
    const html_example_if = util.renderComponentToHtml(allocator, examples.ControlIf(allocator, .{ .is_admin = true }));

    // Switch example
    const zx_example_switch = util.extractSection(allocator, examples_source, "Control Flow: switch");
    const zig_example_switch = zx_example_switch;
    const html_example_switch = util.renderComponentToHtml(allocator, examples.ControlSwitch(allocator, .{ .role = .member }));

    // For example
    const zx_example_for = util.extractSection(allocator, examples_source, "Control Flow: for");
    const zig_example_for = zx_example_for;
    const html_example_for = util.renderComponentToHtml(allocator, examples.ControlFor(allocator, .{ .items = &.{ "Alice", "Bob", "Charlie" } }));

    // While example
    const zx_example_while = util.extractSection(allocator, examples_source, "Control Flow: while");
    const zig_example_while = zx_example_while;
    const html_example_while = util.renderComponentToHtml(allocator, examples.ControlWhile(allocator));

    // Expression example
    const zx_example_expr = util.extractSection(allocator, examples_source, "Expressions");
    const zig_example_expr = zx_example_expr;
    const html_example_expr = util.renderComponentToHtml(allocator, examples.Expressions(allocator));

    // Components example
    const zx_example_components = util.extractSection(allocator, examples_source, "Component: basics");
    const zig_example_components = zx_example_components;
    const html_example_components = util.renderComponentToHtml(allocator, FeatureButtonDemo(allocator));

    // Routing example
    const zx_example_routing = util.extractSection(allocator, examples_source, "File System Routing: page");
    const zig_example_routing = zx_example_routing;
    const html_example_routing = util.renderComponentToHtml(allocator, examples.Routing__Page(ctx));

    // Layout example - use simple example like learn page
    const zx_example_layout = util.extractSection(allocator, examples_source, "File System Routing: layout");
    const zig_example_layout = zx_example_layout;
    const layoutctx = zx.LayoutContext.init(ctx.request, ctx.response, ctx.allocator);
    const html_example_layout = util.renderComponentToHtml(allocator, examples.Layout(layoutctx, zx.Component{ .text = "Hello, World!" }));

    // Allocator example
    const zx_example_allocator = util.extractSection(allocator, examples_source, "Builtin Attributes: allocator");
    const zig_example_allocator = zx_example_allocator;
    const html_example_allocator = util.renderComponentToHtml(allocator, examples.AllocatorDemo(ctx));

    const expr_syntax = "{expression}";

    // Reference inline snippets extracted from feature_examples unwrap__ wrappers
    const expr_string_example = util.extractUnwrapSection(allocator, examples_source, "Reference Inline: expr string");
    const expr_int_example = util.extractUnwrapSection(allocator, examples_source, "Reference Inline: expr int");
    const expr_float_example = util.extractUnwrapSection(allocator, examples_source, "Reference Inline: expr float");
    const expr_bool_example = util.extractUnwrapSection(allocator, examples_source, "Reference Inline: expr bool");
    const expr_enum_example = util.extractUnwrapSection(allocator, examples_source, "Reference Inline: expr enum");
    const expr_optional_example = util.extractUnwrapSection(allocator, examples_source, "Reference Inline: expr optional");
    const expr_component_example = util.extractUnwrapSection(allocator, examples_source, "Reference Inline: expr component");
    const expr_component_array_example = util.extractUnwrapSection(allocator, examples_source, "Reference Inline: expr component array");

    const optional_capture_example = util.extractUnwrapSection(allocator, examples_source, "Reference Inline: optional capture");
    const error_capture_example = util.extractUnwrapSection(allocator, examples_source, "Reference Inline: error capture");

    const spread_attrs_example = util.extractUnwrapSection(allocator, examples_source, "Reference Inline: spread attrs");
    const shorthand_attrs_example = util.extractUnwrapSection(allocator, examples_source, "Reference Inline: shorthand attrs");
    const template_attrs_example = util.extractUnwrapSection(allocator, examples_source, "Reference Inline: template attrs");

    const component_ctx_example = util.extractUnwrapSection(allocator, examples_source, "Reference Inline: component context");
    const component_ctx_props_example = util.extractUnwrapSection(allocator, examples_source, "Reference Inline: component ctx props");

    const multiline_string_example = util.extractUnwrapSection(allocator, examples_source, "Reference Inline: multiline strings");
    const comments_example = util.extractUnwrapSection(allocator, examples_source, "Reference Inline: comments");

    // Escaping example
    const zx_example_escaping = util.extractSection(allocator, examples_source, "Builtin Attributes: escaping");
    const zig_example_escaping = zx_example_escaping;
    const html_example_escaping = util.renderComponentToHtml(allocator, examples.RawHtml(allocator));

    // CSR example
    const zx_example_csr = util.extractSection(allocator, examples_source, "Client-side Rendering");
    const zig_example_csr = zx_example_csr;
    const html_example_csr = util.renderComponentToHtml(allocator, examples.Client(allocator));
    const preview_csr = examples.Client(allocator);

    // Importing example
    const zx_example_importing = util.extractSection(allocator, examples_source, "Importing");
    const zig_example_importing = zx_example_importing;
    const html_example_importing = util.renderComponentToHtml(allocator, examples.ImportDemo(allocator));

    // Dynamic route example
    const zx_example_dynamic = util.extractSection(allocator, examples_source, "Dynamic Path");
    const zig_example_dynamic = zx_example_dynamic;
    const html_example_dynamic = util.renderComponentToHtml(allocator, examples.Page(ctx));

    // API and WebSocket examples
    const zig_api_route = util.extractSection(allocator, examples_source, "API Route");
    const zig_websocket_route = util.extractSection(allocator, examples_source, "WebSocket");

    // Fragment example
    const zx_example_fragment = util.extractSection(allocator, examples_source, "Component: fragment");
    const zig_example_fragment = zx_example_fragment;
    const html_example_fragment = util.renderComponentToHtml(allocator, examples.Fragment(allocator));

    // Children example
    const zx_example_children = util.extractSection(allocator, examples_source, "Component: children");
    const zig_example_children = zx_example_children;
    const html_example_children = util.renderComponentToHtml(allocator, examples.CardDemo(allocator));

    // const setup_elapsed_ns = page_timer.read();
    // const setup_elapsed_ms = @as(f64, @floatFromInt(setup_elapsed_ns)) / @as(f64, @floatFromInt(std.time.ns_per_ms));
    // std.log.info("\x1b[1;36m[DOCS PAGE] Setup phase completed: {d:.3}ms\x1b[0m", .{setup_elapsed_ms});

    const csr_simple_handler_example =
        \\fn handleInput(event: zx.client.Event) void {
        \\    const value = event.value() orelse "";
        \\    zx.log.info("Input: {s}", .{value});
        \\}
        \\// Attach: oninput={handleInput}
    ;

    const csr_stateful_handler_example =
        \\pub fn Counter(ctx: *zx.ComponentCtx(void)) zx.Component {
        \\    const count = ctx.state(i32, 0);
        \\    return (
        \\        <div @allocator={ctx.allocator}>
        \\            <button onclick={ctx.bind(increment)}>{count}</button>
        \\        </div>
        \\    );
        \\}
        \\fn increment(e: *zx.client.Event.Stateful) void {
        \\    const count = e.state(i32); // same order as ctx.state()
        \\    count.set(count.get() + 1);
        \\}
    ;

    const csr_state_bind_example =
        \\pub fn Counter(ctx: *zx.ComponentCtx(void)) zx.Component {
        \\    const count = ctx.state(i32, 0);
        \\    return (
        \\        <div @allocator={ctx.allocator}>
        \\            <button onclick={count.bind(increment)}>{count}</button>
        \\        </div>
        \\    );
        \\}
        \\fn increment(value: i32) i32 {
        \\    return value + 1;
        \\}
    ;

    // Allocate files on heap to avoid stack lifetime issues
    const layout_files = blk: {
        const files = allocator.alloc(File, 2) catch unreachable;
        files[0] = .{ .filename = "layout.zx", .code = zx_example_layout };
        files[1] = .{ .filename = "page.zx", .code = zx_example_routing };
        break :blk files;
    };
    return (
        <div @allocator={allocator}>
            // <Introduction />
            <section id="expressions" class="section">
                <h2>Expressions</h2>
                <p>Use curly braces <code>{expr_syntax}</code> to embed any Zig expression. Values are automatically formatted based on their type and HTML-escaped for safety.</p>
                <ExampleBlock id="expressions-example" zx_code={zx_example_expr} zig_code={zig_example_expr} html_code={html_example_expr} filename="expressions.zx" />

                <h3 id="expr-strings">Strings</h3>
                <p>String values (<code>[]const u8</code>) are displayed as text and automatically HTML-escaped to prevent XSS attacks. This is the safe default for displaying user input or any dynamic text content.</p>
                <CodeBlock code={expr_string_example} />

                <h3 id="expr-integers">Integers</h3>
                <p>Integer types (<code>i32</code>, <code>u64</code>, <code>comptime_int</code>, etc.) are formatted as decimal numbers. The special case <code>u8</code> is printed as a character if it's a printable ASCII character.</p>
                <CodeBlock code={expr_int_example} />

                <h3 id="expr-floats">Floats</h3>
                <p>Floating-point types (<code>f32</code>, <code>f64</code>, <code>comptime_float</code>) are formatted as decimal numbers.</p>
                <CodeBlock code={expr_float_example} />

                <h3 id="expr-booleans">Booleans</h3>
                <p>Boolean values are displayed as the literal strings "true" or "false".</p>
                <CodeBlock code={expr_bool_example} />

                <h3 id="expr-enums">Enums</h3>
                <p>Enum values are displayed as their tag name. This is useful for displaying status values, categories, or any enumerated type.</p>
                <CodeBlock code={expr_enum_example} />

                <h3 id="expr-optionals">Optionals</h3>
                <p>Optional values (<code>?T</code>) are automatically unwrapped and rendered if present. If the value is <code>null</code>, nothing is rendered. This makes it easy to conditionally display content.</p>
                <CodeBlock code={expr_optional_example} />

                <h3 id="expr-null">Null</h3>
                <p>The <code>null</code> value renders nothing, producing no output in the final HTML.</p>

                <h3 id="expr-components">Components</h3>
                <p>A <code>zx.Component</code> value is rendered directly. This allows you to embed components returned from functions or stored in variables.</p>
                <CodeBlock code={expr_component_example} />

                <h3 id="expr-component-arrays">Component Arrays</h3>
                <p>Arrays or slices of components (<code>[]zx.Component</code>) are rendered as a fragment containing all the components in sequence.</p>
                <CodeBlock code={expr_component_array_example} />
            </section>
            <section id="control-flow" class="section">
                <h2>Control Flow</h2>
                <p>ZX supports conditional rendering and iteration using familiar Zig control flow constructs. These expressions allow you to conditionally render components or iterate over collections to build dynamic UIs.</p>
                <h3 id="if-statements">If Statements</h3>
                <p>Use <code>if</code> expressions to conditionally render components based on boolean conditions. The<code>else</code> branch is optional and can render alternative content when the condition is false.</p>
                <ExampleBlock id="if" zx_code={zx_example_if} zig_code={zig_example_if} html_code={html_example_if} filename="conditional.zx" />
                <h3 id="switch-statements">Switch Statements</h3>
                <p>Use <code>switch</code> expressions to match against enum values or other types. Each case can return either a string literal or a component. Switch expressions are particularly useful for rendering different UI based on state or user roles.</p>
                <ExampleBlock id="switch" zx_code={zx_example_switch} zig_code={zig_example_switch} html_code={html_example_switch} filename="role_switch.zx" />
                <h3 id="for-loops">For Loops</h3>
                <p>Use <code>for</code> loops to iterate over arrays, slices, or strings and render a component for each item. The loop variable can be used within the component body to display item-specific content. This is ideal for rendering lists, tables, or any repeating UI patterns.</p>
                <ExampleBlock id="for" zx_code={zx_example_for} zig_code={zig_example_for} html_code={html_example_for} filename="user_list.zx" />
                <h3 id="while-loops">While Loops</h3>
                <p>Use <code>while</code> loops for conditional iteration with a continuation expression. The syntax follows Zig's while loop pattern: <code>{"while (condition) : (continue_expr) (body)"}</code>. This is useful for generating numbered sequences or iterating until a condition is met.</p>
                <ExampleBlock id="while" zx_code={zx_example_while} zig_code={zig_example_while} html_code={html_example_while} filename="counter.zx" />
                <h3 id="optional-capture">Optional Capture</h3>
                <p>Use payload capture syntax to unwrap optional values in <code>if</code> and <code>while</code> expressions:</p>
                <CodeBlock code={optional_capture_example} />
                <p>If the optional is <code>null</code>, the body is skipped (or the <code>else</code> branch runs if provided).</p>
                <h3 id="error-capture">Error Capture</h3>
                <p>Capture errors from error unions using <code>else |err|</code> syntax:</p>
                <CodeBlock code={error_capture_example} />
                <p>This works with both <code>if</code> and <code>while</code> expressions for handling fallible operations.</p>
            </section>
            <section id="components" class="section">
                <h2>Components</h2>
                <p>Components are reusable functions that return <code>zx.Component</code>. They allow you to encapsulate UI logic and create modular, maintainable code. Components can accept props (properties) to customize their behavior and appearance.</p>
                <h3>Component Function Signatures</h3>
                <p>Component functions can use one of several signatures depending on their needs:</p>
                <ul>
                    <li><strong>Allocator only:</strong><code>fn Component(allocator: zx.Allocator) zx.Component</code></li>
                    <li><strong>With props:</strong><code>fn Component(allocator: zx.Allocator, props: Props) zx.Component</code></li>
                    <li><strong>Context (children only):</strong><code>fn Component(ctx: *zx.ComponentContext) zx.Component</code></li>
                    <li><strong>Context with props:</strong><code>fn Component(ctx: *zx.ComponentCtx(Props)) zx.Component</code></li>
                </ul>
                <h3 id="component-context">ComponentContext</h3>
                <p>Use <code>zx.ComponentContext</code> when your component needs access to children but has no custom props:</p>
                <CodeBlock code={component_ctx_example} />
                <h3 id="component-ctx-props">ComponentCtx with Props</h3>
                <p>Use <code>zx.ComponentCtx(Props)</code> when you need both custom props and children access:</p>
                <CodeBlock code={component_ctx_props_example} />
                <p>The context provides <code>ctx.allocator</code>, <code>ctx.props</code>, and <code>ctx.children</code>.</p>
                <h3>Defining Components</h3>
                <p>To create a component, define a function that returns a <code>zx.Component</code>. The function must have an allocator as its first parameter. If your component needs configuration, add a props struct as the second parameter:</p>
                <ExampleBlock id="components" zx_code={zx_example_components} zig_code={zig_example_components} html_code={html_example_components} filename="button_demo.zx" />
                <h3>Props Coercion</h3>
                <p>ZX automatically coerces the attributes you pass to a component into the expected props struct. Missing required fields will result in a compile-time error, while fields with default values are optional. This provides type safety while keeping component usage flexible.</p>
            </section>
            <section id="routing" class="section">
                <h2>Routing</h2>
                <p>ZX provides a file-based routing system that maps URL paths to page components. Routes can be nested, and layouts can be applied hierarchically to wrap pages with common UI elements.</p>
                <h3 id="pages">Pages</h3>
                <p>Pages are the main content components for each route. A page function must:</p>
                <ul>
                    <li>Accept a <code>zx.PageContext</code> as its only parameter</li>
                    <li>Return a <code>zx.Component</code></li>
                    <li>Be exported as <code>pub fn Page</code></li>
                </ul>
                <ExampleBlock id="routing" zx_code={zx_example_routing} zig_code={zig_example_routing} html_code={html_example_routing} filename="home_page.zx" />
                <h3 id="layouts">Layouts</h3>
                <p>Layouts wrap pages with common UI elements like headers, footers, or navigation. A layout function must:</p>
                <ul>
                    <li>Accept a <code>zx.LayoutContext</code> as the first parameter</li>
                    <li>Accept a <code>zx.Component</code> (the page content) as the second parameter</li>
                    <li>Return a <code>zx.Component</code></li>
                    <li>Be exported as <code>pub fn Layout</code></li>
                </ul>
                <ExampleBlock id="layout" files={layout_files} zig_code={zig_example_layout} html_code={html_example_layout} />
                <h3>PageContext and LayoutContext</h3>
                <p>Both <code>PageContext</code> and <code>LayoutContext</code> provide access to:</p>
                <ul>
                    <li><code>request</code>: The HTTP request object with headers, query params, body, etc.</li>
                    <li><code>response</code>: The HTTP response object for setting headers and writing the response</li>
                    <li><code>allocator</code>: Global allocator for persistent allocations (freed manually)</li>
                    <li><code>arena</code>: Request-scoped allocator that's automatically freed after the request (recommended for most use cases)</li>
                </ul>
                <p>Use <code>ctx.arena</code> for temporary allocations that only need to persist during request processing. This is the recommended allocator for most page and component code.</p>
            </section>
            <section id="builtin-attributes" class="section">
                <h2>Builtin Attributes</h2>
                <p>ZX provides special builtin attributes that control component behavior and memory management. These attributes are prefixed with <code>@</code> to distinguish them from regular HTML attributes.</p>
                <h3 id="allocator">@allocator</h3>
                <p>The <code>@allocator</code> attribute is required to be passed to the topmost component. All child components will inherit the allocator from the parent component. It is available to all child components and expressions within that component tree.</p>
                <p><strong>Why is @allocator needed?</strong></p>
                <p>ZX components can allocate memory for various purposes:</p>
                <ul>
                    <li>Storing text content (which is HTML-escaped and allocated)</li>
                    <li>Copying child components arrays</li>
                    <li>Copying attribute arrays</li>
                    <li>Formatting expressions that allocate formatted strings</li>
                </ul>
                <p><strong>Usage:</strong></p>
                <ExampleBlock id="allocator" zx_code={zx_example_allocator} zig_code={zig_example_allocator} html_code={html_example_allocator} filename="allocator_demo.zx" />
                <p><strong>Best Practices:</strong></p>
                <ul>
                    <li>Always use <code>ctx.arena</code> in page components (it's automatically freed after the request)</li>
                    <li>Pass the allocator parameter to custom components and use it in the <code>@allocator</code> attribute</li>
                    <li>Set <code>@allocator</code> on the root element of each component that needs memory allocation</li>
                    <li>Child components inherit the allocator from their parent's component, so you don't need to pass it explicitly to every nested component</li>
                </ul>
                <h3 id="escaping">@escaping</h3>
                <p>The <code>@escaping</code> attribute controls how text content is escaped within an element. By default, all text is HTML-escaped to prevent XSS attacks.</p>
                <p><strong>Values:</strong></p>
                <ul>
                    <li><code>.html</code> - Standard HTML escaping (default behavior)</li>
                    <li><code>.none</code> - No escaping; outputs raw HTML. Use with caution for trusted content only.</li>
                </ul>
                <ExampleBlock id="escaping" zx_code={zx_example_escaping} zig_code={zig_example_escaping} html_code={html_example_escaping} filename="raw_html.zx" />
                <p><strong>Warning:</strong> Only use <code>@escaping={"{.none}"}</code> for content you trust completely. User-provided content should always use the default escaping.</p>
                <h3 id="rendering">@rendering</h3>
                <p>The <code>@rendering</code> attribute enables client-side rendering for interactive components. Without it, all components render server-side only and event handlers are not active in the browser.</p>
                <p><strong>Values:</strong></p>
                <ul>
                    <li><code>.client</code> - Client-side render with Zig (compiles component to WebAssembly)</li>
                    <li><code>.react</code> - Client-side render with React (for imported React/TSX components)</li>
                </ul>

                <h4 id="rendering-client">Client-side Zig rendering</h4>
                <p>Use <code>@rendering={"{.client}"}</code> to make a component interactive. The component is server-rendered for the initial HTML, then hydrated and re-rendered client-side on state changes. Only the marked component is managed client-side; the rest of the page stays server-rendered.</p>
                <ExampleBlock id="csr" zx_code={zx_example_csr} zig_code={zig_example_csr} html_code={html_example_csr} filename="counter.zx" preview_component={preview_csr} />

                <h4 id="rendering-client-state">Managing state</h4>
                <p>Client components that need reactive state must use <code>zx.ComponentCtx(Props)</code> (or <code>zx.ComponentCtx(void)</code> when there are no props). The context provides <code>ctx.state(T, initial)</code> to declare a piece of state:</p>
                <ul>
                    <li><code>ctx.state(T, initial_value)</code> - declares a reactive value of type <code>T</code>. Returns a <code>State(T)</code> handle that persists across re-renders.</li>
                    <li><code>state.get()</code> - read the current value. Can be used directly in markup as <code>{"{count}"}</code>.</li>
                    <li><code>state.set(new_value)</code> - update the value and trigger a re-render.</li>
                    <li><code>state.update(fn(T) T)</code> - update via a transform function.</li>
                </ul>
                <p>State is stored per-component-instance and survives re-renders. On the server (SSR), <code>ctx.state()</code> always returns the initial value.</p>

                <h4 id="rendering-client-events">Event handlers</h4>
                <p>ZX provides three ways to attach event handlers to client components:</p>
                <p><strong>1. Simple handler</strong> - for reading the event without touching state:</p>
                <CodeBlock code={csr_simple_handler_example} />
                <p>The handler receives a <code>zx.client.Event</code> value. Useful methods:</p>
                <ul>
                    <li><code>event.value()</code> - returns <code>?[]const u8</code> with <code>event.target.value</code> (for inputs and selects).</li>
                    <li><code>event.key()</code> - returns <code>?[]const u8</code> with the pressed key name (for keyboard events).</li>
                </ul>
                <p><strong>2. Stateful handler via <code>ctx.bind()</code></strong> - for reading or writing component state:</p>
                <CodeBlock code={csr_stateful_handler_example} />
                <p>The handler receives <code>*zx.client.Event.Stateful</code>. Call <code>e.state(T)</code> in the same order as <code>ctx.state()</code> in the component to access each piece of state.</p>
                <p><strong>3. State transform via <code>state.bind()</code></strong> - the simplest option when the update is a pure function of the current value:</p>
                <CodeBlock code={csr_state_bind_example} />
                <p>The transform function takes the current value and returns the new value. No event object is needed.</p>

                <h4 id="rendering-react">React integration</h4>
                <p>Use <code>@rendering={"{.react}"}</code> to embed a React or TSX component. Import the component with <code>@jsImport</code> and pass it as you would a ZX component. React handles rendering and hydration on the client.</p>
            </section>
            <section id="attribute-syntax" class="section">
                <h2>Attribute Syntax</h2>
                <p>ZX provides convenient syntax for working with attributes beyond simple static values.</p>
                <h3 id="spread-attributes">Spread Attributes</h3>
                <p>Use <code>{"{..struct}"}</code> to spread all fields of a struct as attributes on an element. This is useful for passing groups of attributes or forwarding props:</p>
                <CodeBlock code={spread_attrs_example} />
                <p>Spread attributes can be combined with explicit attributes. Explicit attributes take precedence when there are conflicts.</p>
                <h3 id="shorthand-attributes">Shorthand Attributes</h3>
                <p>When the attribute name matches the variable name, use the shorthand syntax <code>{"{variable}"}</code>:</p>
                <CodeBlock code={shorthand_attrs_example} />
                <p>This is equivalent to writing <code>class={"{class}"}</code> but more concise.</p>
                <h3 id="template-attributes">Template Attributes</h3>
                <p>Use backticks (<code>`</code>) for string interpolation in attribute values. Embed expressions with <code>{"{expr}"}</code> inside the template:</p>
                <CodeBlock code={template_attrs_example} />
                <p>Template attributes are useful for building dynamic URLs, class names, or data attributes that combine static text with dynamic values.</p>
            </section>
            <section id="importing" class="section">
                <h2>Importing</h2>
                <p>ZX supports importing components and modules from various sources. You can import ZX components from other files, React/TSX components for client-side interactivity, and standard Zig modules.</p>
                <ExampleBlock id="importing" zx_code={zx_example_importing} zig_code={zig_example_importing} html_code={html_example_importing} filename="import_demo.zx" />
                <p>Use <code>@jsImport</code> for React/TSX components and the standard <code>@import</code> for ZX and Zig files.</p>
            </section>
            <section id="dynamic-routes" class="section">
                <h2>Dynamic Routes</h2>
                <p>ZX supports dynamic route segments using bracket notation in folder names.</p>
                <h3>Creating Dynamic Routes</h3>
                <p>Create a folder with brackets around the parameter name:</p>
                <ul>
                    <li><code>site/pages/user/[id]/page.zx</code> → <code>/user/:id</code></li>
                    <li><code>site/pages/blog/[slug]/page.zx</code> → <code>/blog/:slug</code></li>
                    <li><code>site/pages/[category]/[item]/page.zx</code> → <code>/:category/:item</code></li>
                </ul>
                <h3>Accessing Route and Query Parameters</h3>
                <p>Use <code>ctx.request.params.get("name")</code> to access dynamic route parameters and <code>ctx.request.query("name")</code> for query strings:</p>
                <ExampleBlock id="dynamic-route" zx_code={zx_example_dynamic} zig_code={zig_example_dynamic} html_code={html_example_dynamic} filename="user_profile.zx" />
                <p>Both methods return <code>?[]const u8</code>, so use <code>orelse</code> to provide a default value.</p>
            </section>
            <APIAndWebSockets api_code={zig_api_route} ws_code={zig_websocket_route} />
            <section id="fragments" class="section">
                <h2>Fragments</h2>
                <p>Fragments allow you to return multiple elements from a component without adding an extra wrapper element to the DOM. Use the empty tag syntax <code>{"<>...</>"}</code> to create a fragment:</p>
                <ExampleBlock id="fragment" zx_code={zx_example_fragment} zig_code={zig_example_fragment} html_code={html_example_fragment} filename="fragment_demo.zx" />
                <p>The fragment's children are rendered directly without any containing element.</p>
            </section>
            <section id="children-props" class="section">
                <h2>Children Props</h2>
                <p>Components can accept child elements through a <code>children</code> prop, enabling wrapper and container patterns. Any elements between the opening and closing tags are passed as the <code>children</code> prop:</p>
                <ExampleBlock id="children" zx_code={zx_example_children} zig_code={zig_example_children} html_code={html_example_children} filename="card_demo.zx" />
            </section>
            <section id="syntax" class="section">
                <h2>Syntax Features</h2>
                <p>ZX supports additional Zig syntax features within templates.</p>
                <h3 id="multiline-strings">Multiline Strings</h3>
                <p>Use Zig's multiline string syntax (<code>\\</code>) to embed formatted text blocks:</p>
                <CodeBlock code={multiline_string_example} />
                <p>Each line prefixed with <code>\\</code> is concatenated. This is useful for code snippets, preformatted text, or ASCII art.</p>
                <h3 id="comments">Comments</h3>
                <p>Single-line comments are supported within ZX templates:</p>
                <CodeBlock code={comments_example} />
                <p>Comments are stripped from the output and do not appear in the rendered HTML.</p>
            </section>
            <CachingSection />
            <PluginsSection />
            <CLISection />
            // <ExamplesSection />
        </div>
    );
}

fn FeatureButtonDemo(allocator: zx.Allocator) zx.Component {
    const examples = @import("../examples/feature_examples.zx");
    return (
        <div @allocator={allocator}>
            <examples.Button label="Click Me" />
        </div>
    );
}

const zx = @import("zx");
const std = @import("std");
const root = @import("root");
const util = @import("util.zig");

const Introduction = @import("../components/introduction.zig").Introduction;
const ExamplesSection = @import("../components/examples_section.zig").ExamplesSection;
const example_block = @import("../components/example_block.zig");
const ExampleBlock = example_block.ExampleBlock;
const File = example_block.File;
const CodeBlock = @import("../components/code_block.zig").CodeBlock;
const InstallCLI = @import("../components/install_guide.zx").InstallCLI;

const APIAndWebSocketsProps = struct {
    api_code: []const u8,
    ws_code: []const u8,
};

fn APIAndWebSockets(allocator: zx.Allocator, props: APIAndWebSocketsProps) zx.Component {
    const examples_source = @embedFile("../examples/feature_examples.zx");
    const route_ctx_example = util.extractUnwrapSection(allocator, examples_source, "Reference Inline: route ctx");
    const socket_ctx_example = util.extractUnwrapSection(allocator, examples_source, "Reference Inline: socket ctx");

    return (
        <section id="api-and-websockets" class="section" @allocator={allocator}>
            <h2>API and WebSockets</h2>
            <p>ZX allows you to create server-side APIs and WebSocket handlers by adding a <code>route.zig</code> file to any route directory. This is similar to <code>page.zx</code> but for handling raw HTTP requests and real-time communication.</p>

            <h3 id="api-routes">API Routes</h3>
            <p>To create an API route, define a <code>route.zig</code> file and export functions for the HTTP methods you want to handle (<code>GET</code>, <code>POST</code>, <code>PUT</code>, <code>DELETE</code>, etc.).</p>
            <CodeBlock code={props.api_code} filename="route.zig" />

            <h3 id="route-context">RouteContext</h3>
            <p>All API handlers receive a <code>zx.RouteContext</code>, which provides everything needed to handle the request:</p>
            <CodeBlock code={route_ctx_example} />
            <ul>
                <li><code>request</code>: Access headers, query params, cookies, and body.</li>
                <li><code>response</code>: Set status codes and write response data (JSON, HTML, etc.).</li>
                <li><code>socket</code>: Interface for WebSocket upgrades and broadcasting.</li>
                <li><code>arena</code>: An allocator that is automatically freed when the request finishes.</li>
            </ul>

            <h3 id="websockets">WebSockets</h3>
            <p>ZX has first-class support for WebSockets. You can upgrade an API request to a WebSocket connection and handle real-time messages with simple lifecycle hooks.</p>
            <CodeBlock code={props.ws_code} filename="route.zig" />

            <h4 id="websocket-lifecycle">Lifecycle Handlers</h4>
            <ul>
                <li><code>Socket</code>: Called when a message is received. This is the main handler for WebSocket logic.</li>
                <li><code>SocketOpen</code>: Called when the connection is established.</li>
                <li><code>SocketClose</code>: Called when the connection is closed.</li>
                <li><code>SocketError</code>: Called when an error occurs on the connection.</li>
            </ul>

            <h4 id="socket-context">SocketContext</h4>
            <p>Message handlers receive a <code>zx.SocketContext</code> (or others like <code>SocketOpenContext</code>):</p>
            <CodeBlock code={socket_ctx_example} />

            <h4 id="pub-sub">Pub/Sub and Broadcasting</h4>
            <p>The <code>ctx.socket</code> interface provides a powerful pub/sub system for broadcasting messages to multiple clients:</p>
            <ul>
                <li><code>subscribe(topic)</code>: Join a topic.</li>
                <li><code>unsubscribe(topic)</code>: Leave a topic.</li>
                <li><code>publish(topic, message)</code>: Send a message to all subscribers of a topic.</li>
            </ul>
        </section>
    );
}

fn PluginsSection(allocator: zx.Allocator) zx.Component {
    const examples_source = @embedFile("../examples/feature_examples.zx");
    const tailwind_full_example = util.extractSection(allocator, examples_source, "Plugin: tailwind");
    const esbuild_full_example = util.extractSection(allocator, examples_source, "Plugin: esbuild");

    return (
        <section id="plugins" class="section" @allocator={allocator}>
            <h2>Plugins</h2>

               <div class="callout note">
                <strong>Note: </strong>Plugin system is still experimental and subject to change.
            </div>
            <p>ZX provides a plugin system to extend the build process with additional tools. Plugins run as build steps and integrate seamlessly with <code>zig build</code>.</p>
            <h3 id="plugin-overview">Overview</h3>
            <p>Plugins are configured in your <code>build.zig</code> file via <code>zx_build.plugin</code>. Each plugin adds build steps that run before or after ZX transpilation, allowing you to process CSS, bundle JavaScript, or run other tools.</p>
            <p>ZX provides <strong>builtin plugins</strong> for common tasks, and you can also <strong>create custom plugins</strong> for your specific needs.</p>

            <h3 id="builtin-plugins">Builtin Plugins</h3>
            <p>ZX ships with the following builtin plugins available via <code>zx.plugins</code>:</p>
            <ul>
                <li><strong><code>zx.plugins.tailwind</code></strong> - Compile Tailwind CSS styles</li>
                <li><strong><code>zx.plugins.esbuild</code></strong> - Bundle TypeScript/JavaScript for client-side code</li>
            </ul>

            <h3 id="tailwind-plugin">Tailwind CSS Plugin</h3>
            <p>The <code>tailwind</code> builtin plugin compiles your CSS using the Tailwind CSS CLI. It automatically runs after ZX transpiles your pages.</p>

            <h4>Options</h4>
            <table class="options-table">
                <thead>
                    <tr>
                        <th>Option</th>
                        <th>Type</th>
                        <th>Default</th>
                        <th>Description</th>
                    </tr>
                </thead>
                <tbody>
                    <tr>
                        <td><code>bin</code></td>
                        <td><code>?LazyPath</code></td>
                        <td><code>node_modules/.bin/tailwindcss</code></td>
                        <td>Path to the Tailwind CLI binary</td>
                    </tr>
                    <tr>
                        <td><code>input</code></td>
                        <td><code>?LazyPath</code></td>
                        <td><code>site/assets/styles.css</code></td>
                        <td>Input CSS file with Tailwind directives</td>
                    </tr>
                    <tr>
                        <td><code>output</code></td>
                        <td><code>?LazyPath</code></td>
                        <td><code>{"{outdir}"}/assets/styles.css</code></td>
                        <td>Output path for compiled CSS</td>
                    </tr>
                    <tr>
                        <td><code>minify</code></td>
                        <td><code>bool</code></td>
                        <td><code>false</code></td>
                        <td>Optimize and minify the output</td>
                    </tr>
                    <tr>
                        <td><code>optimize</code></td>
                        <td><code>bool</code></td>
                        <td><code>false</code></td>
                        <td>Optimize output without minifying</td>
                    </tr>
                    <tr>
                        <td><code>cwd</code></td>
                        <td><code>?LazyPath</code></td>
                        <td><code>null</code></td>
                        <td>Working directory for Tailwind</td>
                    </tr>
                    <tr>
                        <td><code>map</code></td>
                        <td><code>bool</code></td>
                        <td><code>false</code></td>
                        <td>Generate a source map</td>
                    </tr>
                </tbody>
            </table>

            <h4>Example</h4>
            <CodeBlock code={tailwind_full_example} filename="build.zig" />

            <h3 id="esbuild-plugin">esbuild Plugin</h3>
            <p>The <code>esbuild</code> builtin plugin bundles TypeScript or JavaScript files for client-side code. It supports modern JavaScript features and can bundle dependencies.</p>

            <h4>Options</h4>
            <table class="options-table">
                <thead>
                    <tr>
                        <th>Option</th>
                        <th>Type</th>
                        <th>Default</th>
                        <th>Description</th>
                    </tr>
                </thead>
                <tbody>
                    <tr>
                        <td><code>bin</code></td>
                        <td><code>?LazyPath</code></td>
                        <td><code>node_modules/.bin/esbuild</code></td>
                        <td>Path to the esbuild binary</td>
                    </tr>
                    <tr>
                        <td><code>input</code></td>
                        <td><code>?LazyPath</code></td>
                        <td><code>site/main.ts</code></td>
                        <td>Entry point file</td>
                    </tr>
                    <tr>
                        <td><code>output</code></td>
                        <td><code>?LazyPath</code></td>
                        <td><code>{"{outdir}"}/assets/main.js</code></td>
                        <td>Output file path</td>
                    </tr>
                    <tr>
                        <td><code>bundle</code></td>
                        <td><code>bool</code></td>
                        <td><code>true</code></td>
                        <td>Bundle all dependencies</td>
                    </tr>
                    <tr>
                        <td><code>minify</code></td>
                        <td><code>?bool</code></td>
                        <td><code>true</code> in release</td>
                        <td>Minify the output</td>
                    </tr>
                    <tr>
                        <td><code>sourcemap</code></td>
                        <td><code>?enum</code></td>
                        <td><code>inline</code> in debug</td>
                        <td>Source map mode: <code>none</code>, <code>inline</code>, <code>external</code>, <code>linked</code>, <code>both</code></td>
                    </tr>
                    <tr>
                        <td><code>log_level</code></td>
                        <td><code>?enum</code></td>
                        <td><code>silent</code></td>
                        <td>Log level: <code>verbose</code>, <code>debug</code>, <code>info</code>, <code>warning</code>, <code>error</code>, <code>silent</code></td>
                    </tr>
                    <tr>
                        <td><code>format</code></td>
                        <td><code>?enum</code></td>
                        <td>inferred</td>
                        <td>Output format: <code>iife</code>, <code>cjs</code>, <code>esm</code></td>
                    </tr>
                    <tr>
                        <td><code>platform</code></td>
                        <td><code>?enum</code></td>
                        <td><code>browser</code></td>
                        <td>Target platform: <code>browser</code>, <code>node</code>, <code>neutral</code></td>
                    </tr>
                    <tr>
                        <td><code>target</code></td>
                        <td><code>?[]const u8</code></td>
                        <td><code>esnext</code></td>
                        <td>Environment target (e.g., <code>es2017</code>, <code>chrome58</code>)</td>
                    </tr>
                    <tr>
                        <td><code>splitting</code></td>
                        <td><code>bool</code></td>
                        <td><code>false</code></td>
                        <td>Enable code splitting (ESM only)</td>
                    </tr>
                    <tr>
                        <td><code>external</code></td>
                        <td><code>[]const []const u8</code></td>
                        <td><code>&.{"{}"}</code></td>
                        <td>Modules to exclude from bundle</td>
                    </tr>
                    <tr>
                        <td><code>define</code></td>
                        <td><code>[]const struct</code></td>
                        <td><code>&.{"{}"}</code></td>
                        <td>Custom substitutions (key-value pairs)</td>
                    </tr>
                </tbody>
            </table>

            <p><strong>Automatic defines:</strong> The esbuild plugin automatically sets <code>__DEV__</code> and <code>process.env.NODE_ENV</code> based on the build mode.</p>

            <h4>Example</h4>
            <CodeBlock code={esbuild_full_example} filename="build.zig" />

            <h4>Plugin Lifecycle</h4>
            <ul>
                <li><strong><code>before_transpile</code></strong> - Runs before ZX transpiles <code>.zx</code> files to Zig. Useful for preprocessing source files.</li>
                <li><strong><code>after_transpile</code></strong> - Runs after ZX transpilation. Useful for post-processing like CSS compilation, JS bundling, or asset optimization.</li>
            </ul>

            <h4>Using <code>{"{outdir}"}</code></h4>
            <p>In output paths, use <code>{"{outdir}"}</code> as a placeholder for the ZX output directory.</p>

            <div class="callout tip">
                <strong>Tip:</strong> Look at the builtin plugins (<code>tailwind.zig</code> and <code>esbuild.zig</code> in the ZX source) for examples of how to structure complex plugins with many options.
            </div>
        </section>
    );
}

fn CachingSection(allocator: zx.Allocator) zx.Component {
    const examples_source = @embedFile("../examples/feature_examples.zx");

    const component_caching_basic = util.extractUnwrapSection(allocator, examples_source, "Reference Inline: component caching basic");
    const component_caching_key = util.extractUnwrapSection(allocator, examples_source, "Reference Inline: component caching key");
    const page_caching_example = util.extractUnwrapSection(allocator, examples_source, "Reference Inline: page caching");
    const layout_caching_example = util.extractUnwrapSection(allocator, examples_source, "Reference Inline: layout caching");
    const cache_invalidation_example = util.extractUnwrapSection(allocator, examples_source, "Reference Inline: cache invalidation");

    return (
        <section id="caching" class="section" @allocator={allocator}>
            <h2>Caching <span class="badge">Alpha</span></h2>
            <p>ZX provides built-in caching for components, pages, and layouts to improve performance. Cached content is stored in memory and served directly without re-rendering.</p>

            <h3 id="caching-overview">Overview</h3>
            <p>Caching can be applied at three levels:</p>
            <ul>
                <li><strong>Component caching</strong> - Cache individual components using the <code>@caching</code> attribute</li>
                <li><strong>Page caching</strong> - Cache entire pages using <code>PageOptions.caching</code></li>
                <li><strong>Layout caching</strong> - Cache layouts using <code>LayoutOptions.caching</code></li>
            </ul>

            <h3 id="caching-components">Component Caching</h3>
            <p>Use the <code>@caching</code> attribute on any component to cache its rendered HTML output. The syntax is <code>{"<duration>"}</code> or <code>{"<duration>:key"}</code>.</p>

            <h4>Time Units</h4>
            <table class="options-table">
                <thead>
                    <tr>
                        <th>Unit</th>
                        <th>Description</th>
                        <th>Example</th>
                    </tr>
                </thead>
                <tbody>
                    <tr>
                        <td><code>s</code></td>
                        <td>Seconds</td>
                        <td><code>"10s"</code> = 10 seconds</td>
                    </tr>
                    <tr>
                        <td><code>m</code></td>
                        <td>Minutes</td>
                        <td><code>"5m"</code> = 300 seconds</td>
                    </tr>
                    <tr>
                        <td><code>h</code></td>
                        <td>Hours</td>
                        <td><code>"2h"</code> = 7200 seconds</td>
                    </tr>
                    <tr>
                        <td><code>d</code></td>
                        <td>Days</td>
                        <td><code>"1d"</code> = 86400 seconds</td>
                    </tr>
                </tbody>
            </table>

            <h4>Basic Usage</h4>
            <CodeBlock code={component_caching_basic} />

            <h4>Custom Cache Keys</h4>
            <p>Add a custom key after the duration with a colon (<code>:</code>) separator. Keys are useful for manual cache invalidation:</p>
            <CodeBlock code={component_caching_key} />
            <p>The cache key is prefixed with <code>cmp:</code> internally, so <code>"10m:user-profile"</code> creates a key <code>cmp:user-profile</code>.</p>

            <h3 id="caching-pages">Page Caching</h3>
            <p>Enable page-level caching by exporting a <code>options</code> constant with caching settings:</p>
            <CodeBlock code={page_caching_example} filename="page.zx" />
            <p>Page caching stores the entire rendered response including headers. The server adds <code>ETag</code> and <code>Cache-Control</code> headers automatically.</p>

            <h3 id="caching-layouts">Layout Caching</h3>
            <p>Layouts can also be cached using <code>LayoutOptions</code>:</p>
            <CodeBlock code={layout_caching_example} filename="layout.zx" />
            <div class="callout note">
                <strong>Note:</strong> Layout caching caches the entire layout including children. Use with caution as it may cache dynamic page content unintentionally.
            </div>

            <h3 id="cache-invalidation">Cache Invalidation</h3>
            <p>Manually invalidate cache entries using <code>zx.cache</code> functions:</p>
            <CodeBlock code={cache_invalidation_example} />
            <p><strong>Available functions:</strong></p>
            <ul>
                <li><code>zx.cache.del(key)</code> - Delete a specific cache entry by exact key. Returns <code>true</code> if deleted.</li>
                <li><code>zx.cache.delPrefix(prefix)</code> - Delete all entries matching a prefix. Returns the count of deleted entries.</li>
                <li><code>zx.cache.get(key)</code> - Get cached HTML by key. Returns <code>?[]const u8</code>.</li>
            </ul>

            <h3 id="caching-best-practices">Best Practices</h3>
            <ul>
                <li><strong>Cache static content aggressively</strong> - Headers, footers, navigation, and other rarely-changing content benefit most from caching.</li>
                <li><strong>Use custom keys for related content</strong> - Group related cache entries with a common prefix for easy bulk invalidation.</li>
                <li><strong>Be careful with user-specific content</strong> - Don't cache components that display user-specific data without including user identity in the cache key.</li>
                <li><strong>Start with short TTLs</strong> - Begin with shorter cache durations and increase as you verify correctness.</li>
                <li><strong>Invalidate on data changes</strong> - Call <code>zx.cache.del()</code> or <code>zx.cache.delPrefix()</code> when underlying data changes.</li>
            </ul>

            <div class="callout tip">
                <strong>Performance tip:</strong> Component caching is most effective for expensive-to-render components with stable output.
            </div>
        </section>
    );
}

const CLIArg = struct {
    name: []const u8,
    description: []const u8,
};

const CLIFlag = struct {
    name: []const u8,
    description: []const u8,
};

const CLICommandInfo = struct {
    name: []const u8,
    id: []const u8,
    description: []const u8,
    usage: []const u8,
    badge: ?[]const u8 = null,
    arguments: ?[]const CLIArg = null,
    flags: ?[]const CLIFlag = null,
    note: ?[]const u8 = null,
};

const cli_commands = [_]CLICommandInfo{
    .{
        .name = "init",
        .id = "cli-init",
        .description = "Initialize a new ZX project. Creates all the necessary files and directory structure to get started with ZX.",
        .usage = "zx init [path] [flags]",
        .arguments = &[_]CLIArg{
            .{ .name = "[path]", .description = "Path to initialize the project in (default: current directory)" },
        },
        .flags = &[_]CLIFlag{
            .{ .name = "--template, -t <name>", .description = "Template to use (default: \"default\"). Options: default, react, wasm, react_wasm" },
            .{ .name = "--force, -f", .description = "Force initialization even if the directory is not empty" },
            .{ .name = "--existing", .description = "Initialize ZX in an existing project (only adds files that don't exist)" },
        },
        .note = "The command will warn if the directory is not empty. Use --force to override, or --existing to only add missing files.",
    },
    .{
        .name = "dev",
        .id = "cli-dev",
        .description = "Start the app in development mode with hot reloading. Watches for file changes and automatically rebuilds.",
        .usage = "zx dev [flags]",
        .flags = &[_]CLIFlag{
            .{ .name = "--binpath, -b <path>", .description = "Binpath of the app (default: auto-detected)" },
            .{ .name = "--build-args <args>", .description = "Additional arguments to pass to zig build" },
        },
    },
    .{
        .name = "serve",
        .id = "cli-serve",
        .description = "Serve the project for production. Builds and runs the executable.",
        .usage = "zx serve [flags]",
        .flags = &[_]CLIFlag{
            .{ .name = "--port, -p <number>", .description = "Port to run the server on (default: 3000)" },
        },
    },
    .{
        .name = "transpile",
        .id = "cli-transpile",
        .description = "Transpile .zx files to Zig source code. Useful for debugging or inspecting generated code.",
        .usage = "zx transpile <path> [flags]",
        .arguments = &[_]CLIArg{
            .{ .name = "<path>", .description = "Path to .zx file or directory (required)" },
        },
        .flags = &[_]CLIFlag{
            .{ .name = "--outdir, -o <directory>", .description = "Output directory (default: \".zx\")" },
        },
    },
    .{
        .name = "fmt",
        .id = "cli-fmt",
        .description = "Format ZX source code files according to ZX's formatting rules.",
        .usage = "zx fmt [path] [flags]",
        .arguments = &[_]CLIArg{
            .{ .name = "[path]", .description = "Path to .zx file or directory (optional, formats current directory if not specified)" },
        },
        .flags = &[_]CLIFlag{
            .{ .name = "--stdio", .description = "Read from stdin and write to stdout" },
            .{ .name = "--stdout", .description = "Write formatted output to stdout instead of modifying files" },
        },
    },
    .{
        .name = "export",
        .id = "cli-export",
        .description = "Generate static site assets. Builds your project and exports it for static hosting.",
        .usage = "zx export [flags]",
        .flags = &[_]CLIFlag{
            .{ .name = "--outdir, -o <directory>", .description = "Output directory (default: \"dist\")" },
            .{ .name = "--binpath, -b <path>", .description = "Binpath of the app executable (default: auto-detected)" },
        },
        .note = "Run zig build first to build the ZX executable before exporting.",
    },
    .{
        .name = "bundle",
        .id = "cli-bundle",
        .description = "Bundle the site into a deployable directory with the executable and assets.",
        .usage = "zx bundle [flags]",
        .flags = &[_]CLIFlag{
            .{ .name = "--outdir, -o <directory>", .description = "Output directory (default: \"bundle\")" },
            .{ .name = "--binpath, -b <path>", .description = "Binpath of the app executable (default: auto-detected)" },
        },
        .note = "Run zig build first to build the ZX executable before bundling.",
    },
    .{
        .name = "update",
        .id = "cli-update",
        .description = "Update the ZX dependency version in your project's build.zig.zon file.",
        .usage = "zx update [flags]",
        .flags = &[_]CLIFlag{
            .{ .name = "--version, -v <version>", .description = "Version to update to (default: \"latest\")" },
        },
    },
    .{
        .name = "upgrade",
        .id = "cli-upgrade",
        .description = "Upgrade the ZX CLI tool itself. Downloads and installs a new version of the CLI binary.",
        .usage = "zx upgrade [flags]",
        .flags = &[_]CLIFlag{
            .{ .name = "--version, -v <version>", .description = "Version to upgrade to (default: \"latest\")" },
        },
    },
    .{
        .name = "version",
        .id = "cli-version",
        .description = "Show the current version of the ZX CLI tool.",
        .usage = "zx version",
    },
};

fn CLISection(allocator: zx.Allocator) zx.Component {
    return (
        <section id="cli" class="section" @allocator={allocator}>
            <h2>Command Line Interface</h2>
            <p>ZX comes with a built-in CLI tool to help you create, develop, and deploy your projects.</p>

            <h3 id="cli-installation">Installation</h3>
            <p>Install the ZX CLI using one of the following methods:</p>
            <InstallCLI />

            {for (cli_commands) |cmd| (
                <CLICommand allocator={allocator} command={cmd} />
            )}
        </section>
    );
}

fn CLICommand(allocator: zx.Allocator, props: struct { command: CLICommandInfo }) zx.Component {
    const command = props.command;
    // Parse usage string into parts for syntax highlighting
    const usage = command.usage;
    var parts = std.ArrayList(struct { text: []const u8, class: []const u8 }).empty;
    defer parts.deinit(allocator);

    var iter = std.mem.tokenizeScalar(u8, usage, ' ');
    var first = true;
    while (iter.next()) |token| {
        const class_name = if (first) "function" else if (std.mem.startsWith(u8, token, "[") or std.mem.startsWith(u8, token, "<")) "variable" else "operator";
        parts.append(allocator, .{ .text = token, .class = class_name }) catch unreachable;
        first = false;
    }

    return (
        <div @allocator={allocator}>
            <h3 id={command.id}>
                {command.name}
                {if (command.badge) |badge| (
                    <span class="badge">{badge}</span>
                )}
            </h3>
            <p>{command.description}</p>

            <div class="install-box install-box-simple">
                <div class="install-box-content">
                    <div class="install-code" translate="no">
                        <span class="install-prompt">$ </span>
                        {for (parts.items) |part| (
                            <span>
                                <span class={part.class}>{part.text} {" "}</span>
                            </span>
                        )}
                    </div>
                </div>
            </div>

            {if (command.arguments) |args| (
                <div>
                    <h4>Arguments</h4>
                    <ul>
                        {for (args) |arg| (
                            <li><code>{arg.name}</code> - {arg.description}</li>
                        )}
                    </ul>
                </div>
            )}

            {if (command.flags) |flags| (
                <div>
                    <h4>Flags</h4>
                    <ul>
                        {for (flags) |flag| (
                            <li><code>{flag.name}</code> - {flag.description}</li>
                        )}
                    </ul>
                </div>
            )}

            {if (command.note) |note| (
                <div class="callout">
                    <strong>Note: </strong> {note}
                </div>
            )}
        </div>
    );
}
