# Brand Website

> Build and maintain brand/corporate websites using the Astro + Tailwind CSS + React islands stack. Use this skill whenever the user wants to: create a new page for the website, modify existing page content or layout, update translations/locale content, add new sections or components to a page, change the design system tokens, or restructure the site navigation. Also trigger when the user mentions: 品牌網站, 官網, landing page, 新增頁面, 修改頁面, 網站內容, page content, website section, add a page, update the homepage, or any task involving the Astro brand website codebase.

- Skill: `arova-ai/brand-website` (Agent Skill, multi-file: 5 files)
- Install (CLI): `npx skillmds@latest add arova-ai/brand-website`
- Raw SKILL.md: https://api.skillmd.com/api/skills/arova-ai/brand-website/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Design & Media
- Author: arova-ai (https://skillmd.com/u/arova-ai)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/arova-ai/brand-website

---


# Brand Website Builder

This skill guides you through creating and maintaining brand/corporate websites built with **Astro 5.x**, **Tailwind CSS v4**, and **React islands** for interactivity. The architecture is designed for enterprise marketing sites that need static rendering, excellent SEO, bilingual content (zh-TW / en), and minimal client-side JavaScript.

## When to use this skill

- Creating a new page
- Modifying existing page content or layout
- Adding sections or components to a page
- Updating translation/locale content
- Changing design system tokens (colors, typography, effects)
- Adding navigation items

## Project architecture

```
src/
  pages/[locale]/       ← Route pages (.astro), generates /zh-TW/... and /en/...
  components/
    layout/             ← Navbar, Footer, PageLayout, MobileMenu
    sections/           ← Reusable page sections (Hero, CTA, TrustBadges)
    ui/                 ← Primitives (Button, Card, Badge, SectionTitle, Accordion)
    visuals/            ← Diagrams and animated graphics (some are React .tsx)
  i18n/
    zh-TW.json          ← Traditional Chinese content (default locale)
    en.json             ← English content (must mirror zh-TW structure)
    utils.ts            ← getTranslation(), getLocalePath(), locale types
  layouts/
    BaseLayout.astro    ← HTML shell with <html lang>, fonts, meta, CSS
  styles/
    global.css          ← Tailwind v4 @theme tokens, custom utilities
```

## Core workflow

### Modifying page content

Content lives in `src/i18n/zh-TW.json` and `src/i18n/en.json`, not in page files. To change text:

1. Find the relevant key path in the JSON (e.g., `home.hero.headline`)
2. Update **both** locale files — the structure must stay in sync
3. No page file changes needed unless the layout changes

### Creating a new page

Follow this sequence — each step builds on the previous:

**Step 1: Add content to locale files**

Add a new top-level key in both `src/i18n/zh-TW.json` and `src/i18n/en.json`:

```json
{
  "meta": {
    "newPage": { "title": "頁面標題", "description": "頁面描述" }
  },
  "newPage": {
    "hero": { "headline": "...", "subtitle": "..." },
    "sections": [ ... ],
    "cta": { "headline": "...", "button": "..." }
  }
}
```

Both files must have identical key structure. zh-TW values are in Traditional Chinese, en values in English.

**Step 2: Create the page file**

Create `src/pages/[locale]/new-page.astro`. Read `references/page-template.md` for the exact boilerplate. Every page follows this pattern:

```astro
---
import BaseLayout from '../../layouts/BaseLayout.astro';
import PageLayout from '../../components/layout/PageLayout.astro';
import { locales, getTranslation, getLocalePath } from '../../i18n/utils';
import type { Locale } from '../../i18n/utils';

export function getStaticPaths() {
  return locales.map((locale) => ({ params: { locale } }));
}

const locale = Astro.params.locale as Locale;
const t = getTranslation(locale);
---

<BaseLayout title={t.meta.newPage.title} description={t.meta.newPage.description} locale={locale} currentPath="/new-page">
  <PageLayout locale={locale} currentPath="/new-page">
    <!-- sections here -->
  </PageLayout>
</BaseLayout>
```

Key points:
- `getStaticPaths()` generates both `/zh-TW/new-page` and `/en/new-page`
- `currentPath` must match the URL path segment (used for language switcher and hreflang)
- All visible text comes from `t` (the translation object), never hardcoded

**Step 3: Add navigation (if needed)**

If the page should appear in the navbar:
1. Add the label to `nav` in both locale files
2. Add the link to `src/components/layout/Navbar.astro` in the `navLinks` array
3. Add the link to `src/components/layout/Footer.astro` if appropriate

**Step 4: Verify**

Run `npm run build` and confirm the page appears in the output for both locales.

### Adding a new section to an existing page

1. Check `references/component-catalog.md` for available components
2. If an existing component fits, import and use it
3. If a new component is needed, create it in the appropriate directory:
   - `components/sections/` for full-width page sections
   - `components/ui/` for small reusable primitives
   - `components/visuals/` for diagrams or animated graphics
4. Add any new translatable text to both locale files
5. Use `.astro` for static components, `.tsx` (React) only when client-side interactivity is required (animations with framer-motion, state like accordion open/close, mobile menu toggle)

### React islands

Most components should be `.astro` (zero client JS). Use React `.tsx` only when the component needs:
- Client-side state (e.g., accordion open/close, mobile menu toggle)
- framer-motion animations that run on scroll or interaction

When using React islands in Astro pages, specify a client directive:
- `client:load` — for immediately interactive components (mobile menu)
- `client:visible` — for components that animate on scroll (preferred for diagrams)

## Design system quick reference

Read `references/design-tokens.md` for the full token list.

**Colors:** dark navy background (#0F172A), cyan primary (#06B6D4), purple accent (#8B5CF6), glass-card semi-transparent surfaces

**Typography:** Inter (primary) + Noto Sans TC (Chinese fallback)

**Key CSS utilities defined in `global.css`:**
- `.glass-card` — semi-transparent card with backdrop blur and border
- `.gradient-text` — cyan-to-purple gradient text effect
- `.text-glow-cyan` / `.text-glow-purple` — subtle text shadow glow
- `.glow-cyan` / `.glow-purple` / `.glow-amber` / `.glow-emerald` — box shadow glow

**Layout patterns:**
- Max width: `max-w-7xl mx-auto px-4 sm:px-6 lg:px-8`
- Section spacing: `py-20` or `py-24`
- Dark panel sections: `bg-surface-panel border-y border-white/5`
- Very dark sections: `bg-surface-dark`

## Verification checklist

After any change, verify:

1. **Build succeeds**: `npm run build` — check for errors
2. **Both locales generated**: confirm HTML files exist under both `dist/zh-TW/` and `dist/en/`
3. **Locale sync**: if content was added/changed, both JSON files have matching structure
4. **No hardcoded text**: all visible text comes from locale files, not inline strings
5. **Links preserve locale**: all `<a href>` use `getLocalePath(locale, '/path')`

## Reference files

For detailed information, read these files from the `references/` directory:

- **`component-catalog.md`** — Full API docs for every available component (props, variants, usage examples)
- **`design-tokens.md`** — Complete color palette, typography, spacing, and custom CSS utilities
- **`page-template.md`** — Copy-paste starter template for new pages with all imports and boilerplate

