---
agent: web-engineer
allowed-tools:
- Read
- Bash
- Grep
- Glob
context: fork
description: Simple web development with HTML, CSS, JS, and HTMX. Auto-activates when
  working with .html, .css, or .htmx files, web templates, stylesheets, or vanilla
  JS scripts. NOT for React/Vue/Angular (use writing-typescript) or Node.js backends.
name: writing-web
user-invocable: false
---

# Web Development (Simple, Modern)

## Critical Output Rules

- Use semantic HTML elements before reaching for CSS or JS: `<button>`, `<dialog>`, `<details>`, `<summary>`, `<nav>`, `<article>`.
- CSS custom properties (`--var`) for all repeated values; no magic numbers.
- HTMX for server-driven interactivity; vanilla JS only when HTML/CSS/HTMX cannot do it.
- Include a verification plan for every generated page or component: manual browser check, responsive check at mobile/desktop, and a Playwright step when behavior changed.
- Do not run destructive shell commands. For broad or risky changes, state the risk and ask before acting.

## Philosophy

- HTML first: semantic markup does the work
- CSS second: small stylesheets, fluid layout, mobile-first, media/container queries only when needed
- HTMX third: server-driven interactivity
- JS last: only when nothing else works

## Patterns

### Semantic HTML

```html
<header>
  <nav><a href="/">Home</a></nav>
</header>
<main>
  <h1>Title</h1>
  <article>Content</article>
</main>
<footer>&copy; 2024</footer>
```

### Use native elements

- `<button>` for actions
- `<a>` for navigation
- `<details>`/`<summary>` for accordions
- `<dialog>` for modals

### Simple CSS

```css
:root {
  --primary: #2563eb;
  --spacing: 1rem;
}

.container {
  display: grid;
  gap: var(--spacing);
}

@media (min-width: 768px) {
  .container {
    grid-template-columns: 1fr 1fr;
  }
}
```

### HTMX (with Go)

```html
<!-- Load content -->
<div hx-get="/items" hx-trigger="load"></div>

<!-- Form -->
<form hx-post="/create" hx-target="#result">
  <input name="title" required />
  <button>Create</button>
</form>

<!-- Delete with confirmation -->
<button hx-delete="/item/123" hx-confirm="Delete?">Delete</button>

<!-- CSRF token -->
<body hx-headers='{"X-CSRF-Token": "{{.Token}}"}'></body>
```

### Minimal JS

```javascript
// Only when HTML/CSS/HTMX can't do it
document.body.addEventListener("click", (e) => {
  if (e.target.matches("[data-copy]")) {
    navigator.clipboard.writeText(e.target.dataset.copy);
  }
});
```

## Avoid

- JS for things HTML can do (accordions, modals)
- CSS for things HTML can do (form validation)
- Fetch when HTMX works
- Deep selector nesting
- Wrapper div soup

## Verify Generated Code

After generating code, validate HTML and check behavior:

```bash
npx html-validate . 2>&1 || true
# or, with Bun:
# bunx html-validate . 2>&1 || true
```

Verification plan must include:

1. Manual/browser check for the changed page or component.
2. Responsive check at mobile and desktop widths.
3. Playwright or equivalent browser test when behavior changed.
4. Screenshot or concise pass/fail notes for visual changes.

## Failure Cases

- **html-validate reports errors**: fix semantic/attribute issues before considering the task done; do not suppress with `|| true` in CI.
- **HTMX request not firing**: check `hx-trigger`, `hx-target` selector, and CSRF header presence before adding JS fallback.
