--- name: docs-page-style description: >- House style and structure for uploads.sh documentation pages — the MDX subject pages under apps/web/src/content/docs/ (and the docs.astro hub) built on DocsLayout. Use this whenever you write, restructure, trim, or review a docs page: requests like "clean up the galleries docs", "this docs page has too much prose", "rework the agents page", "the flow on /docs/comment-config feels complicated", "make the reference page scannable", or any edit to a file under apps/web/src/content/docs/. Encodes the page structure (understand → set up → do), the Stripe-style intro voice, the copy-affordance and inline-code rules, the prose diet, and the DocsLayout component vocabulary, so every docs page reads like one deliberate, scannable system rather than a wall of prose. Reach for it even mid-task when you notice a docs page drifting toward heavy paragraphs, fabricated terminal output, or a copy button on every line. --- # uploads.sh docs page style These pages teach a developer (or their agent) to do one thing with the `uploads` CLI and then get out of the way. Each subject page is one `.mdx` file in the `docs` content collection (`apps/web/src/content/docs/`), rendered through `DocsLayout` by the `apps/web/src/pages/docs/[...slug].astro` route: you write Markdown prose, fenced code blocks, and a small, fixed vocabulary of HTML wrappers and components. The hub page (`apps/web/src/pages/docs.astro`) is still a plain Astro page — it is a card index, not prose. The goal is a page that reads like reputable dev-tool docs (Stripe, Vercel, Wrangler): one short orientation, then commands you can actually run, with prose used only as connective tissue. The failure mode to fight is the opposite: heavy paragraphs, an example for every variation, a copy button on every line, and setup buried below usage. That reads as "complicated" even when every sentence is individually fine — because the _structure_ makes the reader work. ## How to approach a page 1. **Read the page and identify the ONE thing it's for.** Everything else is secondary and should be demoted or linked out, not given equal weight. 2. **Decide the page's job.** A hub/landing page (`docs.astro`) _triages and links_ — it should not re-teach what a subject page already covers. A subject page _walks through one workflow_. Don't duplicate a worked example that lives on another page; link to it instead. 3. **Order it: understand → set up → do.** A short "what/why", then install or prerequisites, then the golden-path command. A reader should be able to run the first real command without scrolling back up to find setup. 4. **Pick one golden path.** If there are two ways to do the thing, show the more universal one as the worked example and demote the other to a one-line pointer (see the pattern below). Never present two competing commands as parallel entry points — that fork is the single most common source of "this feels complicated." 5. **Apply the prose, copy, and inline-code rules** below to what's left. 6. **Verify it renders.** Reuse only the existing component classes, keep every command/flag/link real (never invent one — check a sibling page or the CLI), and confirm the page still compiles (`pnpm build` in `apps/web`). ## Adding or editing a page A new subject page is a new `.mdx` file in `apps/web/src/content/docs/`. The filename is the URL slug (`galleries.mdx` → `/docs/galleries`); the left nav, the prev/next chain, and the static path all derive from its frontmatter, so there is no route, nav, or pagination edit to make. ```yaml --- title: Galleries #
`: MDX wraps multi-line children in their own `
`, and a `
` inside a `
` is invalid. - Never let an inline component or `{expression}` start a line inside a paragraph — MDX reparses it as a block and splits the sentence around it. This is why `*.mdx` is excluded from `oxfmt` (see `.oxfmtrc.json`): a reflow would do exactly that. Wrap prose by hand. ## Structure & voice ### Intro: one sentence, then a capability list — not paragraphs Lead with what the tool/feature _does for the reader_, verb-first, then (if scope needs conveying) a short bulleted capability list where each bullet links to the relevant page. This is the Stripe pattern: the copy reads like a spec sheet, not a pitch. No scene-setting ("In this guide…", "uploads.sh is a service that…"), no adjectives, no wind-up. **Prefer:** ```html
Galleries collect related media behind one public link. With a gallery you can:
Already have a PR open? Use uploads attach instead —
see the walkthrough →.
` is for **short identifiers and single tokens** — a command verb,
a flag, a package name, a path like `/g/`. This is near-universal in good docs.
**Never set a full, multi-argument command inline** (e.g.
`uploads attach ./before.png ./after.png` mid-sentence). It forces the reader to
switch between prose cadence and monospace in one breath, wraps awkwardly across
lines, and makes a runnable command look like a passing mention. Instead:
- Put the full command in a ` ```bash ` block, **or**
- Reference only the verb inline (`uploads attach`) and let the full form live in
a block or on the linked page.
Watch inline-code _density_ too: three or more inline-code spans crammed into one
paragraph reads as busy. Split them across sentences, or move asides (like an
`npx` alternative or a `doctor` check) into a `.note`.
## Component vocabulary (DocsLayout)
Reuse these classes — don't invent new ones without a strong reason (note any new
class you add and why). Headings and their `#` anchors, the copy-button behavior,
the table of contents, and section dividers are all handled by `DocsLayout`
automatically; you don't wire them up per page.
| Element | Use for |
| ---------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `` | The first section (no top divider under the page title). |
| `` | Every subsequent section; gets a top divider automatically. |
| `` with an `#` inside | Section heading. The anchor sits in the left gutter and appears on hover; the whole heading is click-to-anchor. Keep the markup pattern; the layout styles it. |
| `` | Sub-heading within a section (e.g. a card title, a labelled step). |
| ` ```bash ` fence | A copyable command. The `$ ` prompt is drawn by CSS — never type it. A trailing `# comment` is stripped from the copied text. |
| ` ```ansi ` fence | Multi-line, **non-copyable** output or a reference command listing. Only for real, reproducible output. |
| ` ```text ` fence | A copyable non-shell line — a slash command typed into an agent, an instructions-file snippet. |
| `` / `` | Two or more genuinely equivalent commands. `syncKey` links groups across the page. Not for sequences of steps. |
| `