Skip to content
Back to skills

Angora Compose Page

ASecurity

Assemble or evolve Astro pages in `src/pages/*.astro` and layout specimens in `src/pages/design-system/layouts/` from already-built components — including list/detail patterns like `/collection` + `[slug].astro`, SEO wiring from table fields, and site layout (header/footer) integration. Trigger whenever the user wants to compose, assemble, build, or evolve a full page from existing components. Phrases like 'compose the pricing page', 'build the about page', 'wire up the blog index and [slug]'...

  • 6 stars
  • 0 votes
  • 0 copies
  • 4 views
  • Added May 28, 2026
designgoreactdatabase

Works with

  • cli

Security analysis

A100/100

Pro scans all 2 files and shows the line behind each finding

Scanned May 28, 2026

npx -y skills add Aysnc-Labs/angora --skill angora-compose-page --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Angora Compose Page?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Angora Compose Page
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/aysnc-labs-angora-compose-page/badge)](https://www.skillsdirectory.com/skills/aysnc-labs-angora-compose-page)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: angora-compose-page
description: Assemble or evolve Astro pages in `src/pages/*.astro` and layout specimens in `src/pages/design-system/layouts/` from already-built components — including list/detail patterns like `/collection` + `[slug].astro`, SEO wiring from table fields, and site layout (header/footer) integration. Trigger whenever the user wants to compose, assemble, build, or evolve a full page from existing components. Phrases like 'compose the pricing page', 'build the about page', 'wire up the blog index and [slug]', 'assemble the home from hero + pricing + CTA', 'put together the careers page', 'evolve the contact page to add a form section' all trigger this.
argument-hint: <page-name>
---

# Compose Page: $ARGUMENTS

Build or update a full site page from approved components. Pages are living documents — this skill handles both creation and evolution.

## Scope

This skill does two things:
- **Design system layouts** — full-page compositions in `src/pages/design-system/layouts/` using real components with placeholder content. These are specimens, not production pages.
- **Site pages** — real routes in `src/pages/` with production content, database queries, SEO, and site layout wrappers.

**Intent check:** When the user says "update the home page" or similar, clarify before proceeding: "Do you mean the **home layout** in the design system (`/design-system/layouts/home`), or the **actual website home page** at `src/pages/index.astro`?"

## Before you start

1. **Read `src/system.md`** — intent, accessibility standard, anti-patterns.
2. **Read `src/styles/global.css`** — available tokens for page-level spacing and backgrounds. All color references must use **semantic token utilities** — raw palette classes don't exist.
3. **Read [design-principles.md](../docs/design-principles.md)** — especially Spacing & Layout, Dark Mode, and Finishing Touches sections.
4. **Read [tailwind-conventions.md](../docs/tailwind-conventions.md)** — Tailwind v4 syntax rules.
5. **Inventory components** — list `src/components/*.astro` to know what's available. Only use approved, built components.
6. **Read `src/components/Section.astro`** — understand the Section pattern before composing pages. Section accepts: `seamless`, `fullWidth` (drops flow width constraint), `narrow` (constrains to `--container-narrow`), `withWrap` (re-constrains children of full-width sections), `withPadding` (adds vertical padding without seamless), `title` (renders `<h2>` with automatic `aria-labelledby`).
7. **Check for wireframe** — look for `src/pages/design-system/wireframes/<page-name>.astro`. If it exists, read it — especially the data source annotations in frontmatter.
8. **Check for layout** — look for `src/pages/design-system/layouts/<page-name>.astro`. If a layout exists, it's an approved composition showing how components assemble for this page. Use it as the reference — match its section order, component choices, and visual rhythm. The real page replaces placeholder content with real data but follows the same structure.
9. **Check for existing page** — look for `src/pages/<page-name>.astro`. If it exists, read it first. This is an evolution, not a rewrite.
10. **Check for site layout** — look in `src/layouts/` for existing site layouts (header/footer wrappers).

## Entry points

This skill can be invoked with:
- A **wireframe reference** — "compose the pricing page" (where a wireframe exists)
- A **component list** — "build a page with hero, features, and CTA"
- A **description** — "build our about page"

If no wireframe exists, recommend one ("Want me to sketch a wireframe first with `/angora-wireframe`?") but don't force it.

## Mandatory gate: static vs template per section

Before building, determine the data source for every section on the page.

If a wireframe exists with data source annotations, read them:
```
/*
  Data sources:
  sections:
    - component: Hero
      data: static
    - component: Testimonials
      data: table:testimonials
    - component: Pricing
      data: table:pricing_tiers
*/
```

If no wireframe or annotations, ask for each section:
- "Will this content change? Is there more than one?" → **template** (table reference)
- "Is this one-off copy edited in code?" → **static**

For **template sections**, verify the table exists by globbing `src/data/schema/tables/*.ts` — each file is a table definition.

If a required table doesn't exist, flag it: "The `testimonials` table doesn't exist yet. This needs schema work first. Run `/angora-schema testimonials` to design it."

## List/detail pattern

Recognize when cards link to individual pages (blog posts, case studies, cities, team members). This is a first-class pattern:

### List page
`src/pages/<collection>.astro`
- Query: `SELECT * FROM <table> WHERE status = 'published'`
- Renders cards/list items linking to `/collection/[slug]`

### Detail template
`src/pages/<collection>/[slug].astro`
- Uses `getStaticPaths()` to generate pages from database
- Query: `SELECT * FROM <table> WHERE status = 'published'`
- Wire up SEO from table fields: `<title>`, `<meta name="description">`, OG tags
- Only render published records

```astro
---
import db from '../../data/db.ts';
import { <table> } from '../../data/schema/tables/<table>';
import { eq } from 'drizzle-orm';

export function getStaticPaths() {
  const items = db.select().from(<table>).where(eq(<table>.status, 'published')).all();
  return items.map(item => ({
    params: { slug: item.slug },
    props: { item },
  }));
}

const { item } = Astro.props;
---
<html>
<head>
  <title>{item.metaTitle || item.title}</title>
  <meta name="description" content={item.metaDescription || ''} />
</head>
...
</html>
```

## Site layout

Ask: "Should this page have the site header/footer, or is it a standalone landing page?"

Check for `src/layouts/` — if no layout exists and user wants header/footer, flag it: "No site layout exists yet. Want me to create one, or should we build this as a standalone page for now?"

Site layouts go in `src/layouts/` (Astro convention). A site layout wraps page content with shared header/footer/nav.

## Output

- `src/pages/<page-name>.astro` — the site page
- Optional: `src/pages/<collection>/[slug].astro` — for list/detail patterns

## Form sections

When a page includes forms (contact, signup, settings), use the form layout primitives:

- **FieldGroup** — vertical stack of form rows with standard `grid-gap` spacing
- **FormRow** — horizontal row within a FieldGroup. Children grow to fill space by default. Use `grow={false}` for button rows

Every field inside a FieldGroup should be wrapped in a FormRow. Don't use raw `<div>` wrappers for form layout.

## Page-level concerns

- **Page wrapper uses `section-flow`** — `<main class="section-flow">` wraps all sections. The `section-flow` utility lives in `global.css` and controls inter-section spacing (gap controlled by `--section-gap`). For editorial content (blog posts, articles), use `<article class="prose-flow">` instead.
- **Ambient prose** — `section-flow` and `prose-flow` include prose automatically via `@apply prose`. Raw HTML elements get typographic styling from prose at low specificity (`:where()`) — component classes always win. Don't add `prose` separately. The only local `prose` usage is for nested content zones that need their own vertical rhythm.
- **Landmark components live on their own** — Hero, Footer, Nav go directly inside `section-flow`. They render their own semantic element with `data-component` and flow attributes (`data-seamless`, `data-full-width`). Don't wrap landmarks in `<Section>`.
- **Content components go inside `<Section>`** — the consumer controls `title`, `seamless`, `narrow`, `fullWidth`, `withWrap`. Use `<Section fullWidth withWrap>` when a section needs edge-to-edge background but children should stay constrained to container width.
- **Backgrounded sections use `seamless`** — `<Section seamless>` for sections with background colors/images. Adjacent seamless sections get 0 gap so backgrounds butt up.
- Background alternation for visual rhythm — use semantic surface tokens for section variety. These automatically adapt in dark mode
- Visual flow — the eye moves naturally through the page
- Responsive behavior via container queries
- SEO: `<title>`, `<meta name="description">`, OG tags
- **`color-scheme` meta tag** — already handled by `Layout.astro` for design system pages. For site pages, include `<meta name="color-scheme" content="light dark">` if the site supports dark mode, or `<meta name="color-scheme" content="light">` if light-only
- **Images in dark mode** — photographs on dark backgrounds can feel jarring. Use `dark:brightness-80 dark:contrast-125` on `<img>` elements to dim slightly. Avoid images with baked-in white backgrounds — they become glowing rectangles in dark mode. Prefer transparent or neutral backgrounds for logos and illustrations

## Layout purity rules (design system layouts only)

When building a layout in `src/pages/design-system/layouts/`, enforce these additional rules:

- **Single-file rule** — a layout page is one `.astro` file. No extracted sub-components, no helper modules. If the layout feels too complex for one file, the components are too coarse — refine them in `/angora-component`.
- **Zero-class layout rule** — layouts are pure component composition. No Tailwind utility classes on raw HTML elements. If you need to add a class to a `<div>`, a component is missing. **Allowed:** just `section-flow` on `<main>`. **Not allowed:** spacing wrappers (`<div class="mt-8">`), grid layouts (`<div class="grid grid-cols-2">`), visual treatments (`<div class="bg-card rounded-lg">`), styled headings, width constraints, Button wrapper divs, `class` overrides on components, raw markup.
- **No client-side code** — design system layouts are static. No inline `<script>` tags for interactivity. If a section needs interactivity, it should use a Preact island via the component itself.
- **Layout purity check** — after building, verify: single file? No client code? Zero-class compliance? Landmark components outside `<Section>`? Content components inside `<Section>`? No arbitrary values? No double-wrapping? Background rhythm makes sense?

## Review

Present the completed page to the user and suggest they review in browser (`pnpm dev`). Then run `/angora-design-system-audit` automatically — this is verification, not a change. Present findings and proposed fixes. Wait for approval before applying fixes. (Accessibility is covered at the component and layout level by `pnpm test:a11y` — no need to re-test assembled pages.)

Files in this skill

  • SKILL.md10.5 KB
  • evals/trigger-eval.json2.2 KB

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.