# Page Source Contract

> Complete source-authoring contract for Lexsis storefront pages

Canonical URL: https://fa7e86e3d553:3005/pages/schema

Agents create storefront pages from readable HTML source. Pass the source and
its page-level settings to `lexsis_pages` with action `compile`, then use
the same inputs with `lexsis_page_create` and action `create`.

## Tool Input

```typescript
{
  source: string;
  head: {
    title: string;
    fonts?: string[];
    seo?: Record<string, unknown>;
  };
  theme_css?: string;
  scripts?: Array<{
    src?: string;
    inline?: string;
    position?: "head" | "body-end";
    defer?: boolean;
    async?: boolean;
    id?: string;
  }>;
}
```

## Source Structure

Separate page sections with descriptive comments:

```html
<!-- section: product-hero -->
<section class="mx-auto grid max-w-7xl gap-10 px-6 py-16 lg:grid-cols-2">
  <lx-island name="ProductGallery" hydrate="visible">
    <script type="application/json">
      {
        "media": [
          {
            "type": "image",
            "src": "https://cdn.example.com/product-front.jpg",
            "alt": "Product front"
          },
          {
            "type": "image",
            "src": "https://cdn.example.com/product-back.jpg",
            "alt": "Product back"
          }
        ],
        "layout": "horizontal",
        "enableLightbox": true,
        "autoplay": true,
        "interval": 4000
      }
    </script>
  </lx-island>

  <div class="lg:sticky lg:top-24 lg:self-start">
    <lx-island name="BuyBox">
      <script type="application/json">
        {
          "productId": "gid://shopify/Product/123",
          "ctaText": "Add to Cart"
        }
      </script>
    </lx-island>
  </div>
</section>

<!-- section: faq -->
<section class="mx-auto max-w-3xl px-6 py-16">
  <h2 class="mb-8 text-3xl font-semibold">Common questions</h2>
  <lx-island name="FAQ" hydrate="visible">
    <script type="application/json">
      {
        "items": [
          {
            "question": "How do I use it?",
            "answer": "Apply two to three drops to clean skin."
          },
          {
            "question": "When will my order arrive?",
            "answer": "Most orders arrive within three to five business days."
          }
        ],
        "mode": "single",
        "icon": "plus"
      }
    </script>
  </lx-island>
</section>
```

Use the supported FAQ island when a section needs accordion behavior. Native
`details` remains suitable for one-off static disclosure content.

Each section may be followed by one scoped `<style>` block, a managed motion
block, and a compatibility `<script>` block. New animation should use
`type="application/lexsis-motion"` rather than legacy section JavaScript.

## Styling Contract

Use Tailwind utilities for layout, spacing, sizing, responsive behavior, and
state styling:

```html
<div class="grid grid-cols-4 gap-3 md:gap-5">
  ...
</div>
```

The compiler scans every section and generates one immutable
`compiled_page_css` artifact. It contains:

1. `theme_css`
2. Generated Tailwind utilities
3. Section CSS in section order

There is no runtime Tailwind CDN. A referenced class that produces no Tailwind
CSS and is not defined in custom CSS is a compile error.

See [Theming and Tailwind](/pages/theming) for the complete ownership model.

## Island Contract

```html
<lx-island name="IslandName" hydrate="visible">
  <script type="application/json">
    { "prop": "value" }
  </script>
</lx-island>
```

- `name` is case-sensitive and must exist in `vibe://catalog/islands`.
- Read `vibe://schema/island/{name}` for exact props and examples.
- The JSON script must contain one object.
- `hydrate` accepts `immediate`, `visible`, `idle`, or `interaction`.
- `class`, `id`, `style`, ARIA attributes, and custom `data-*` attributes may
  be added to the island element.
- Use `data-scope` to isolate variant and inventory events when a page contains
  more than one product interaction group.
- Islands must be siblings rather than nested inside one another.

The JSON script is configuration data. It is parsed as island props and is
never executed as JavaScript.

## Script Types

These three script locations have different responsibilities:

| Location | Type | Purpose |
|---|---|---|
| Inside `<lx-island>` | `application/json` | Non-executable island props |
| Section `<script type="application/lexsis-motion">` | Managed function expression | Custom animation with declared capabilities and lifecycle limits |
| Section `<script>` | JavaScript | Compatibility behavior scoped to that section |
| Page-level `scripts` argument | External or inline JavaScript | Approved integrations and shared page behavior |

Do not put executable code in an island's JSON script. Do not put external
script tags inside section HTML.

## Managed motion

```html
<!-- section: product-object -->
<section>
  <canvas class="product-canvas"></canvas>
</section>

<script
  type="application/lexsis-motion"
  data-motion-id="product-object"
  data-capabilities="three resize"
  data-mode="interaction"
  data-importance="decorative"
  data-reduced-motion="static"
>
async ({ dom, three, resize, scheduler, quality }) => {
  // The compiler validates this function and the renderer owns its lifecycle.
}
</script>
```

Managed motion supports arbitrary agent-authored WAAPI, GSAP, SVG, Canvas,
WebGL, Three.js, Lottie, Rive, video, pointer, scroll, and event work within
declared performance boundaries. See
[Animations and Managed Motion](/pages/animations) for the complete
capability and safety contract.

## Head

| Field | Required | Description |
|---|---|---|
| `title` | Yes | Browser and SEO page title |
| `fonts` | No | HTTPS stylesheet URLs for approved web fonts |
| `seo` | No | Additional search and social metadata |

Cart V2 is enabled by default for every storefront and cannot be disabled.
Configure the effective profile separately and omit `use_cart_v2` from new
source. Older source containing `use_cart_v2:true` remains compatible;
`use_cart_v2:false` is rejected.

## Theme CSS

Use `theme_css` for page-wide design tokens. Use Tailwind classes in section
HTML to apply the tokens:

```css
:root {
  --lx-accent-color: #2d5016;
  --lx-accent-color-hover: #203c10;
  --lx-text-color: #171a14;
  --lx-text-muted: #66705f;
  --lx-bg-color: #ffffff;
  --lx-bg-surface: #f7f8f2;
  --lx-border-color: #dfe3d8;
  --lx-font-heading: "Cormorant Garamond", serif;
  --lx-font-body: "Inter", sans-serif;
}
```

See [Theming](/pages/theming) for the complete token reference.

Theme changes on source-backed pages require a complete page-style recompile.
Call `lexsis_drafts` action `page_update_head` with the complete `theme_css`.
The MCP recompiles the stored source and commits through the atomic source
replacement path rather than using a direct backend head-only patch.

## Scripts

Use page-level `scripts` for approved analytics and integrations. Use managed
motion for new local animation. Legacy section JavaScript remains available for
compatibility behavior.

The following are blocked in section JavaScript:

- Network requests and WebSockets
- Dynamic code execution
- Browser storage
- Dynamic imports
- External script tags

## Validation Workflow

```typescript
const validation = await callTool("lexsis_pages", {
  action: "compile",
  args: { source, head, theme_css, scripts },
});

if (validation.ok) {
  await callTool("lexsis_page_create", {
    action: "create",
    args: {
      slug: "hydrating-serum",
      source,
      head,
      theme_css,
      scripts,
      archetype: "pdp",
      publish: false,
    },
  });
}
```

Fix every compilation error before creating or updating a page.

Compilation proves the source contract, not successful client rendering.
Hosted preview QA must also confirm `data-lx-hydration-state="ready"`, required
controls, event coordination, and visible cart feedback. Runtime failures set
`data-lx-hydration-state="error"` and `data-lx-hydration-error`.

New source should use native media islands such as `HeroMedia`,
`MediaCarousel`, `ProductGallery`, `ProductHero`, or `VideoPlayer` instead of
authoring standalone image or video tags for reusable media behavior. The
compiler reports `native_media_island_recommended` when raw media should be
replaced with an island.

## Related

- [Page Management](/tools/page-management)
- [Publishing](/pages/publishing)
- [Generation Guide](/resources/generation-guide)
- [Island Catalog](/resources/island-catalog)
