# Skill: HTML Multi-Page Template Architecture
## Purpose
Guide FORGE to produce comprehensive, multi-page vanilla HTML/CSS/JS templates that look and feel like real applications — not thin landing pages.
## Core Principle
Every "easy" template should be a **complete static prototype** of the described application. A user opening it should immediately think "this looks like a real product" — with multiple navigable pages, interactive widgets, realistic data, and polished styling.
---
## File Organization Pattern
```
index.html ← Landing / main dashboard
pages/
dashboard.html ← Primary data view
details.html ← Single-item detail view
settings.html ← Configuration / preferences
about.html ← Info, FAQ, team
components/
nav.html ← Shared top navigation
footer.html ← Shared footer
sidebar.html ← Optional sidebar navigation
modal.html ← Reusable modal template
styles/
variables.css ← CSS custom properties (colors, spacing, typography)
reset.css ← Minimal CSS reset
layout.css ← Grid/flexbox page layouts, responsive breakpoints
components.css ← Cards, buttons, badges, tables, forms
pages.css ← Page-specific overrides
utilities.css ← Utility classes (flex, text-center, mt-4, etc.)
scripts/
app.js ← Main init, component loader, router
components.js ← Interactive widgets (tabs, modals, accordions, toasts)
data.js ← Dummy data rendering and filtering
utils.js ← DOM helpers, formatters, validators
data/
dummy.js ← All dummy data exports (20+ realistic entries)
```
---
## Navigation Pattern
Every page includes:
```html
```
Active state logic in app.js:
```javascript
document.querySelectorAll('.nav-link').forEach(link => {
if (link.getAttribute('href') === location.pathname ||
location.pathname.endsWith(link.getAttribute('href')))
link.classList.add('active');
else link.classList.remove('active');
});
```
---
## Page Content Minimums
### index.html (Home/Overview)
- Hero section or summary banner
- 3-4 stat/metric cards with numbers and icons (inline SVG)
- Recent activity list or table (5+ rows of dummy data)
- Quick action buttons
- Status overview (badges: green/yellow/red)
### dashboard.html (Data View)
- Filter bar (search input, dropdown filters, date range)
- Data table with 10+ rows, sortable columns, status badges
- Pagination controls
- Bulk action toolbar
- Summary stats above the table
### details.html (Item Detail)
- Breadcrumb navigation
- Item header with title, status badge, metadata
- Tabbed content sections (Overview, History, Config)
- Side panel with related info
- Action buttons (Edit, Delete, Export)
### settings.html (Configuration)
- Grouped settings sections with headings
- Toggle switches with labels
- Text inputs, selects, textareas
- Save/Reset buttons per section
- Form validation on submit (JS)
- Success toast notification on save
### about.html (Info)
- App description section
- Feature list with icons
- FAQ accordion (3-5 questions, JS toggle)
- Team/credits section
- Version/changelog section
---
## Interactive Component Patterns
### Tabs
```javascript
function initTabs(container) {
const tabs = container.querySelectorAll('[data-tab]');
const panels = container.querySelectorAll('[data-panel]');
tabs.forEach(tab => {
tab.addEventListener('click', () => {
tabs.forEach(t => t.classList.remove('active'));
panels.forEach(p => p.classList.remove('active'));
tab.classList.add('active');
container.querySelector(`[data-panel="${tab.dataset.tab}"]`).classList.add('active');
});
});
}
```
### Modal
```javascript
function openModal(id) {
document.getElementById(id).classList.add('open');
document.body.style.overflow = 'hidden';
}
function closeModal(id) {
document.getElementById(id).classList.remove('open');
document.body.style.overflow = '';
}
```
### Toast Notification
```javascript
function showToast(message, type = 'success') {
const toast = document.createElement('div');
toast.className = `toast toast-${type}`;
toast.textContent = message;
document.body.appendChild(toast);
requestAnimationFrame(() => toast.classList.add('show'));
setTimeout(() => { toast.classList.remove('show'); setTimeout(() => toast.remove(), 300); }, 3000);
}
```
### Sortable Table
```javascript
function initSortableTable(table) {
table.querySelectorAll('th[data-sort]').forEach(th => {
th.addEventListener('click', () => {
const key = th.dataset.sort;
const rows = [...table.querySelectorAll('tbody tr')];
const asc = th.classList.toggle('asc');
rows.sort((a, b) => {
const av = a.querySelector(`td[data-col="${key}"]`).textContent;
const bv = b.querySelector(`td[data-col="${key}"]`).textContent;
return asc ? av.localeCompare(bv, undefined, {numeric: true})
: bv.localeCompare(av, undefined, {numeric: true});
});
const tbody = table.querySelector('tbody');
rows.forEach(r => tbody.appendChild(r));
});
});
}
```
### Search/Filter
```javascript
function initSearch(inputSelector, itemsSelector) {
const input = document.querySelector(inputSelector);
if (!input) return;
input.addEventListener('input', () => {
const q = input.value.toLowerCase();
document.querySelectorAll(itemsSelector).forEach(item => {
item.style.display = item.textContent.toLowerCase().includes(q) ? '' : 'none';
});
});
}
```
---
## CSS Quality Checklist
- [ ] CSS custom properties for ALL colors, spacing, radii, shadows
- [ ] Dark mode toggle via `[data-theme="dark"]` on ``
- [ ] Responsive breakpoints: 480px, 768px, 1024px, 1200px
- [ ] Card component: padding, border-radius, box-shadow, hover transform
- [ ] Button variants: primary, secondary, danger, ghost, disabled
- [ ] Form inputs: focus ring, error state, disabled state
- [ ] Table: striped rows, hover highlight, sticky header
- [ ] Badge/pill: success, warning, error, info colors
- [ ] Progress bar with animated fill
- [ ] Smooth transitions on all interactive elements (0.2s ease)
- [ ] Scroll-to-top button on long pages
- [ ] Skeleton loading placeholder styles
---
## Dummy Data Guidelines
Generate at least 15-20 entries in dummy data arrays. Each entry should have:
- Unique, realistic names/titles (not "Item 1", "Item 2")
- Varied statuses (active, pending, error, completed)
- Realistic dates, numbers, descriptions
- Consistent schema matching the project domain
Example:
```javascript
export const apiEndpoints = [
{ id: 1, name: "/users", method: "GET", status: "operational", latency: 45, uptime: 99.98, lastChecked: "2024-01-15T10:30:00Z" },
{ id: 2, name: "/auth/login", method: "POST", status: "degraded", latency: 230, uptime: 98.5, lastChecked: "2024-01-15T10:29:00Z" },
// ... 18+ more entries
];
```