docs: ADR-0042 — public website + documentation site plan
Planning artifacts for the first public website, recorded before any code is written. - ADR-0042: the decisions — Astro 5 + Starlight + Tailwind v4 (over SvelteKit); asciinema .cast demos reusable in docs (scripted-input driver, not history.log replay); in-page WASM playground deferred behind a stable demo seam, with the portable-core vs native-edge boundary recorded for a future ADR; portable static hosting (Vercel target); monorepo (website/); website is the canonical docs home; full-feature-set docs with "planned" callouts; user-facing copy uses no engine name and no "DSL"; install via prebuilt binaries + package managers. - docs/plans/20260604-adr-0042-website.md: implementation plan with the grounded documentation inventory and phases A–E. - website/STYLE.md: living documentation style guide + open-decisions log. - docs/adr/README.md: index updated for ADR-0042 (numerical order).
This commit is contained in:
@@ -0,0 +1,124 @@
|
||||
# ADR-0042: Public website and documentation site
|
||||
|
||||
## Status
|
||||
|
||||
Accepted (2026-06-04). Implementation plan:
|
||||
[`docs/plans/20260604-adr-0042-website.md`](../plans/20260604-adr-0042-website.md).
|
||||
|
||||
## Context
|
||||
|
||||
RDBMS Playground is nearing its first public release and needs a public
|
||||
website that does two jobs: **attract** — a landing page that shows the
|
||||
playground in action — and **document** — a thorough, canonical reference
|
||||
for everything the playground can do.
|
||||
|
||||
The documentation-heavy surface is already implemented and verified (full
|
||||
simple- and advanced-mode command set, the ten-type vocabulary,
|
||||
relationships, constraints, indexes, EXPLAIN, undo/history/replay, projects,
|
||||
export/import, the teaching echo, clipboard, friendly errors, tab completion
|
||||
and syntax highlighting; 2151 tests passing at the time of writing). The
|
||||
site is therefore largely a presentation-and-writing effort, not a
|
||||
wait-for-features one. A grounded inventory of what is shippable now lives
|
||||
in the implementation plan.
|
||||
|
||||
Several choices here had no canonical default; they were settled during a
|
||||
planning + `/runda` pass with the user and are recorded below.
|
||||
|
||||
## Decision
|
||||
|
||||
1. **Stack — Astro 5 + Starlight + Tailwind v4.** Astro's content-first,
|
||||
zero-JS-by-default model with the Starlight docs theme fits a
|
||||
marketing-landing-plus-heavy-docs site better than the alternative
|
||||
considered, SvelteKit + Tailwind (the usual go-to here). Interactive
|
||||
pieces are added as Astro islands (Svelte or vanilla), so Svelte is still
|
||||
available where it earns its place. Tailwind v4 is wired via the official
|
||||
`@tailwindcss/vite` plugin; the `@astrojs/starlight-tailwind` plugin
|
||||
bridges Tailwind with Starlight's theming.
|
||||
|
||||
2. **Demo medium — asciinema.** Showcase sequences are recorded as
|
||||
asciinema `.cast` files (text-based, small, faithful to the full
|
||||
alternate-screen render) and embedded with `asciinema-player`. The same
|
||||
casts are reused inline in the docs — one recording format serves both
|
||||
the landing page and documentation enrichment. Recordings are produced by
|
||||
a **scripted-input driver** that types commands into a real PTY with
|
||||
viewer-friendly pacing; the app's own `history.log` **replay** (ADR-0034)
|
||||
re-executes commands without typing animation or pacing and is therefore
|
||||
suitable only for state-deterministic docs snippets, not the hero demo.
|
||||
|
||||
3. **In-page WASM playground — deferred** (OOS: **deferred**, not rejected).
|
||||
A live, type-it-yourself playground compiled from the Rust app to
|
||||
WebAssembly is desirable but is a multi-week sub-project, so it does not
|
||||
block the site. The demo section is designed with a stable seam (a single
|
||||
`Demo` component contract) so a WASM playground island can replace the
|
||||
asciinema player later with no change to call sites. Recorded boundary
|
||||
for that future work:
|
||||
- **Portable core (runs on `wasm32-unknown-unknown` largely as-is):**
|
||||
`src/dsl/*` (parser, types, grammar, walker), the pure `App::update()`,
|
||||
`ui.rs`, `theme.rs`, `friendly/*`, output rendering; an in-memory DB
|
||||
path already exists (`Connection::open_in_memory()`). `rusqlite`
|
||||
compiles to the browser target via its `ffi-sqlite-wasm-rs` feature.
|
||||
- **Native edge needing `cfg`-gated browser replacements:** the
|
||||
multi-thread Tokio runtime + the dedicated DB **worker thread**
|
||||
(ADR-0010) → current-thread/in-line async; `crossterm` terminal +
|
||||
event-stream → a browser backend (e.g. Ratzilla's DOM/Canvas) + DOM
|
||||
events; `arboard`, `zip`, file persistence (ADR-0015), file logging;
|
||||
and the rusqlite **backup-API** undo (ADR-0006) → a SQL dump/restore.
|
||||
When taken up, this becomes its own ADR + iteration plan.
|
||||
|
||||
4. **Hosting — portable static build; Vercel is the likely target.** Astro 5
|
||||
builds to static HTML/CSS with no adapter, so the output deploys equally
|
||||
to Vercel, Cloudflare Pages, Netlify, or GitHub Pages. We avoid coupling
|
||||
to any one host. **No CI yet** — the site is tested locally (`pnpm dev` /
|
||||
`pnpm build`) until the repo reaches its public home.
|
||||
|
||||
5. **Repo topology — monorepo.** The site lives under `website/` in the
|
||||
playground repo; the crate stays at the repo root. The repo as a whole
|
||||
moves to its public home later; site and crate travel together.
|
||||
|
||||
6. **Canonical docs home — the website.** User-facing documentation lives on
|
||||
the site. In-repo `docs/` keeps ADRs, handoffs, and development notes;
|
||||
`docs/simple-mode-limitations.md` (requirement DOC1) was a development aid
|
||||
and now *feeds* the site's content rather than competing with it. The
|
||||
sharing recipes promised by requirement E2 become a docs page.
|
||||
|
||||
7. **Documentation scope and conventions.** Document the **full supported
|
||||
feature set**. Any capability not yet fully implemented (a small minority
|
||||
— e.g. multi-line input, query cancellation, `seed`, `m:n` convenience,
|
||||
ER-diagram export, the `show tables`/`relationships`/`indexes` family) is
|
||||
either omitted or carries a clear **"planned / not yet available"**
|
||||
callout — never presented as shipped. Two wording rules bind all
|
||||
user-facing copy:
|
||||
- **No engine name** (SQLite/STRICT/rusqlite/PRAGMA) — continues the
|
||||
user-facing posture of ADR-0002; copy says "the database"/"the engine".
|
||||
- **No "DSL"** — it is internal jargon. The two input modes are **simple
|
||||
mode** (the playground's keyword command language) and **advanced
|
||||
mode** (SQL).
|
||||
|
||||
8. **Install documentation — two mechanisms.** The install page documents
|
||||
**prebuilt release binaries** (self-hosted download — not GitHub
|
||||
Releases, since the repo will move) and **package managers**. Both can be
|
||||
written now against the planned mechanisms; concrete download URLs slot in
|
||||
at release. (Distribution items D1–D3 in `requirements.md` remain the
|
||||
tracking home for the release tooling itself.)
|
||||
|
||||
## Consequences
|
||||
|
||||
- The site can ship on the strength of already-implemented features; it is
|
||||
gated on writing and recording, not on finishing the app.
|
||||
- One recording format (asciinema `.cast`) serves both marketing and docs,
|
||||
and is reusable as the app evolves (re-run the script, re-record).
|
||||
- The WASM playground is preserved as a real future option without holding
|
||||
up launch; the demo seam keeps the upgrade cheap.
|
||||
- A single canonical docs home removes the divergence risk of maintaining
|
||||
user docs in two places.
|
||||
- Website build choices (Decisions 1, 2, 4, 5) are recorded here for
|
||||
traceability but do not, by themselves, warrant further ADRs; only
|
||||
app-architecture decisions (notably the future WASM port) will.
|
||||
|
||||
## Out of scope
|
||||
|
||||
- **In-page WASM playground** — *deferred* (see Decision 3); revisit as its
|
||||
own ADR + iteration plan.
|
||||
- **Hosted/SaaS playground or a server-backed doc CMS** — *rejected*: a
|
||||
static site fully satisfies the need, consistent with ADR-0007's
|
||||
no-hosted-publishing stance. Revisit only if real demand emerges.
|
||||
@@ -47,3 +47,4 @@ This directory contains the project's ADRs, recorded per
|
||||
- [ADR-0039 — EXPLAIN over advanced-mode SQL queries](0039-explain-over-advanced-sql.md) — **Accepted** (2026-05-27), **implemented 2026-05-30 (issue #7)**, **supersedes ADR-0030 §13 OOS-2**. Lets `explain` wrap the advanced SQL commands (`Select`/`SqlInsert`/`SqlUpdate`/`SqlDelete`, plus `with`/CTE which builds a `Select`) in addition to the DSL `ShowData`/`Update`/`Delete` it already covers (ADR-0028), running `EXPLAIN QUERY PLAN` over the validated SQL text through the existing ADR-0028 span-styled plan tree (advanced mode only; DSL `explain` unchanged in both modes). Implemented via a second `Advanced` `explain` CommandNode (`EXPLAIN_SQL`) registered under the shared `explain` entry word — reusing the established `insert`/`update`/`delete` shared-word dispatch (`decide`: SQL-first / DSL-fallback), so `explain show data …` and DSL-only `--all-rows` still reach the DSL node; rejected a `DynamicSubgrammar` mode-gate (its resolution cache key omits `mode`). `build_explain_sql` slices the inner SQL off the source (excludes `explain`) and reuses the existing SQL builders; `do_explain_plan` runs the carried text verbatim, no params. Advanced `explain update`/`delete` now route through SQL (identical plan, full SQL syntax); DSL-explain tests pinned to simple mode. Reframed OOS-2 as a *deferred* exclusion (per ADR-0000's out-of-scope discipline), not a rejection. OOS (deferred): EXPLAIN of DDL (no query plan exists)
|
||||
- [ADR-0040 — A per-command completion marker (✓/✗) replaces the `[ok]` summary line](0040-completion-marker-replaces-ok-summary.md) — **Accepted 2026-05-30 (issue #9)**, amends ADR-0014 / ADR-0028 / ADR-0019 output conventions, builds on ADR-0037's mode-tagged echo. An audit of the whole command surface found the `[ok] <verb> <subject>` summary line duplicates the echo line above it (verb+subject) everywhere; its only unique contribution is the success-vs-error signal (and `explain select` even rendered `[ok] explain` with an empty subject post-ADR-0039). Decision: drop the `[ok]` line and the symmetric `"…" failed:` prefix; the echo line gains a trailing inline **✓** (green, success) / **✗** (red, failure) — `running:` becomes a pending state that resolves to `<input> ✓/✗` on completion (status set via the existing `rfind(Echo)` lookup). Content (row counts, structure, data, plan tree, teaching echo) unchanged. Scoped to the DSL/data/SQL family that has the redundant echo+`[ok]` pair; app-command `[ok]` lines (`rebuild`/`export`/`now editing`) are payload-bearing, have no echo to mark, and stay as-is. `ok.summary` retired; `dsl.failed` reduced to the rendered reason. Broad but mechanical snapshot churn. OOS: app-command `[ok]` lines, the `[WRN]` validity indicator, and the tag colours (issue #10)
|
||||
- [ADR-0041 — Copy the output panel to the system clipboard](0041-copy-output-to-clipboard.md) — **Accepted 2026-06-02 (issue #11)**, amends ADR-0003's app-command registry (adds **`copy`** / `copy all` / `copy last`). The friction it removes: filing a bug report meant terminal-selecting the output panel and fighting wrapping/borders. New **app-level command** (sigil-free, both modes): `copy` / `copy all` copy the whole panel; `copy last` copies from the most recent echo line to the end. **Mechanism — OSC 52 *and* native (`arboard`), always both**, because OSC 52 acceptance is undetectable (no terminal ack), so a true "fall back when unsupported" can't be built: emit the OSC 52 escape (no new dep — `base64`+`crossterm`; works over SSH; tmux-passthrough-wrapped via `$TMUX`), then a best-effort native write whose failure is ignored (headless host — OSC 52 carried it); the two carry identical content. **Format — plain text verbatim as rendered** (tags, `✓`/`✗`, box-drawing) joined by `\n`, without viewport padding/wrapping; a drift-lock test pins `OutputLine::plain_text` to `render_output_line`. `arboard` added **`--no-default-features`** (drops the `image` crate; X11-only on Linux — `wayland-data-control` deliberately omitted as it ~doubles the dep tree and OSC 52 covers native-Wayland). Security: write-only, scans clean for arboard's tree (cargo audit / osv-scanner / grype), 1Password-maintained, minimal surface. OOS: Markdown export, selection/range, a keybinding, OSC 52 read, `screen` passthrough
|
||||
- [ADR-0042 — Public website and documentation site](0042-public-website-and-documentation-site.md) — **Accepted 2026-06-04**. The first public website: a marketing landing page plus the **canonical** user docs. Stack **Astro 5 + Starlight + Tailwind v4** (chosen over SvelteKit + Tailwind for a docs-heavy + marketing site; interactive bits as Astro islands). Showcase demos are **asciinema** `.cast` recordings (scripted-input driver for paced, re-recordable sessions — *not* `history.log` replay), reused inline in docs. The **in-page WASM playground is deferred** (OOS: deferred) behind a stable `Demo` seam, with the portable-core (`dsl`/`app`/`ui`, in-memory `rusqlite` via `ffi-sqlite-wasm-rs`) vs native-edge (Tokio/worker-thread/`crossterm`/persistence/backup-API) boundary recorded for a future ADR + iteration plan. Portable **static build** (Vercel target, but host-agnostic); **no CI yet**; **monorepo** (`website/`). Docs cover the **full supported feature set** with "planned" callouts for the unshipped minority; two wording rules bind user-facing copy — **no engine name** (continues ADR-0002) and **no "DSL"** ("simple mode" / "advanced mode"). Install docs cover **prebuilt binaries + package managers** (D1–D3 track the release tooling). Plan: `docs/plans/20260604-adr-0042-website.md`
|
||||
|
||||
@@ -0,0 +1,172 @@
|
||||
# Plan: public website and documentation site
|
||||
|
||||
**Date:** 2026-06-04 · **Status:** ready to build
|
||||
|
||||
Decisions for this work are recorded in
|
||||
[ADR-0042](../adr/0042-public-website-and-documentation-site.md): Astro 5 +
|
||||
Starlight + Tailwind v4; asciinema demos reusable in docs; the in-page WASM
|
||||
playground deferred behind a stable demo seam; portable static hosting
|
||||
(Vercel target); monorepo (`website/`); website is the canonical docs home;
|
||||
full-feature-set docs with "planned" callouts; install docs cover prebuilt
|
||||
binaries + package managers. This plan is the *how*.
|
||||
|
||||
## Repository layout
|
||||
|
||||
The site lives under `website/` in this repo; the crate stays at the root.
|
||||
|
||||
```
|
||||
website/
|
||||
├── package.json # pnpm; astro, @astrojs/starlight, tailwind v4
|
||||
├── astro.config.mjs # Starlight integration + sidebar nav
|
||||
├── src/
|
||||
│ ├── pages/index.astro # marketing landing (custom, not Starlight)
|
||||
│ ├── components/
|
||||
│ │ ├── Demo.astro # demo SLOT — the WASM-playground seam
|
||||
│ │ └── Cast.astro # asciinema-player island wrapper
|
||||
│ ├── content/docs/ # Starlight MDX docs (the bulk of the work)
|
||||
│ └── styles/ # shared Tailwind + Starlight theme tokens
|
||||
├── public/casts/ # recorded *.cast asciinema files
|
||||
├── README.md # local dev + recording recipe
|
||||
└── STYLE.md # living documentation style guide
|
||||
```
|
||||
|
||||
Root `.gitignore` gains `website/node_modules`, `website/dist`,
|
||||
`website/.astro`.
|
||||
|
||||
## Documentation inventory (grounded — drives Phase D scope)
|
||||
|
||||
Built from `docs/handoff/55–57`, `docs/adr/*`, the command REGISTRY
|
||||
(`src/dsl/grammar/mod.rs:603`, which also auto-assembles in-app `help`), the
|
||||
`Command` enum (`src/dsl/command.rs:149`), and
|
||||
`src/friendly/strings/en-US.yaml` — **not** the coarse `requirements.md`
|
||||
checkboxes. Test state at survey time: **2151 passing, 0 failing, 1 ignored.**
|
||||
|
||||
**SHIPPED — document as-is (the doc core):**
|
||||
- Input modes: simple, advanced (SQL), `:` one-shot escape, `mode` command,
|
||||
per-project mode restore (ADR-0003/0015/0037).
|
||||
- Full simple-mode command surface: create/drop table; add/drop/rename/
|
||||
change column; add/drop 1:n relationship (named, ON DELETE/UPDATE
|
||||
CASCADE/SET NULL/RESTRICT, `--create-fk`); add/drop index; insert/update/
|
||||
delete (required WHERE + `--all-rows`; complex WHERE: AND/OR/NOT, LIKE,
|
||||
IS NULL, IN, BETWEEN); show table/data (where/limit); add/drop constraint;
|
||||
explain (ADR-0009/0013/0014/0025/0026/0028/0029).
|
||||
- Full advanced-mode SQL: CREATE/DROP/ALTER TABLE (cols, constraints, inline
|
||||
+ table FKs, rename, alter-column-type), CREATE [UNIQUE]/DROP INDEX; SELECT
|
||||
(joins, GROUP BY/HAVING, ORDER BY, LIMIT/OFFSET, UNION/INTERSECT/EXCEPT,
|
||||
WITH [RECURSIVE] CTEs); INSERT (multi-row, ON CONFLICT, RETURNING)/UPDATE/
|
||||
DELETE; full expression grammar incl. CASE, CAST, curated functions;
|
||||
EXPLAIN over SQL (ADR-0030–0039).
|
||||
- Types: all ten, advanced-mode SQL aliases, serial/shortid auto-fill
|
||||
(ADR-0005/0011/0017/0018). Constraints: PK incl. compound, NOT NULL,
|
||||
UNIQUE, CHECK, DEFAULT, FK (ADR-0029/0013/0035).
|
||||
- Undo/redo, history.log journal, replay, `--resume`, `--no-undo`
|
||||
(ADR-0006/0034). Projects & storage: project.yaml + CSV + history.log,
|
||||
save/save as/load/new/rebuild, temp projects, `--data-dir`
|
||||
(ADR-0004/0015). Export/import (zip), clipboard copy/copy all/copy last
|
||||
(ADR-0007/0041).
|
||||
- Friendly errors (all five categories) + validity indicator
|
||||
(ADR-0019/0027), DSL→SQL teaching echo (ADR-0038), EXPLAIN plan tree
|
||||
(ADR-0028), box-drawing tables (ADR-0016), tab completion + syntax
|
||||
highlighting + in-line editing (ADR-0022).
|
||||
|
||||
**DOCUMENT WITH CAVEAT:** `add unique index` is advanced-only; simple-mode
|
||||
table rename is intentionally absent (rename is `ALTER TABLE … RENAME TO`);
|
||||
FK references target single-column PKs only (compound-PK FK refs pending);
|
||||
`help <command>` detail and richer `hint` (H2/H3) still partial.
|
||||
|
||||
**OMIT or MARK "planned":** multi-line input (I1), readline shortcuts (I1b),
|
||||
in-flight cancellation / query timeout (I5/B3), `seed` (SD1), `m:n` (C4),
|
||||
one-step modify relationship (C3a), `show tables`/`relationships`/`indexes`
|
||||
(V5), ER-diagram view/export (V1/V3), session-log + Markdown export (V4).
|
||||
|
||||
**Mine verbatim for docs:** `en-US.yaml` `help.app.*`, `help.ddl.*`,
|
||||
`help.data.*`, `help.types_reference`, `parse.usage.*` (one-line syntax
|
||||
templates), `hint.*` — keeps docs and in-app help consistent.
|
||||
|
||||
## Phases
|
||||
|
||||
### A — Scaffold
|
||||
`pnpm create astro@latest` (Starlight template) in `website/`; `astro add
|
||||
tailwind` (Tailwind v4 via `@tailwindcss/vite`); add
|
||||
`@astrojs/starlight-tailwind`. Confirm `pnpm dev` serves and `pnpm build`
|
||||
emits a static `dist/`. Echo build steps for traceability.
|
||||
|
||||
### B — Landing page
|
||||
Custom `src/pages/index.astro` (Starlight owns `/docs/*`). Hero + value prop
|
||||
("learn relational databases by doing"), feature highlights from the
|
||||
inventory, an embedded demo cast above the fold. Use the `frontend-design`
|
||||
skill to avoid generic AI aesthetics; honour NFR-4/5/7 (distinctive design,
|
||||
meaningful colour, light/dark).
|
||||
|
||||
### C — asciinema recording workflow
|
||||
Record real `rdbms-playground` sessions to `public/casts/*.cast` using a
|
||||
**scripted-input driver** (e.g. `asciinema-automation`/autocast, or an
|
||||
expect/doitlive script) for paced, re-recordable demos. Record at a fixed
|
||||
sensible cols×rows; provide light + dark player themes. `Cast.astro` wraps
|
||||
`asciinema-player` as a `client:visible` island; the same component embeds
|
||||
casts inline in docs. Document the recipe in `website/README.md`.
|
||||
(`asciinema` 2.4.0 is installed.)
|
||||
|
||||
### D — Documentation (the bulk)
|
||||
Starlight sidebar, scoped from the inventory; built in priority order:
|
||||
- **Getting started** — install (prebuilt binaries + package managers),
|
||||
first project, simple vs. advanced mode.
|
||||
- **Concepts** — projects & storage; undo, history & replay.
|
||||
- **Simple-mode command reference** — full surface; syntax conventions;
|
||||
simple-command → SQL teaching echo.
|
||||
- **Advanced (SQL) mode** — full SQL DDL/DML/SELECT surface.
|
||||
- **Types**, **Relationships**, **Constraints**, **Indexes**, **Query plans
|
||||
/ EXPLAIN**.
|
||||
- **Working with the editor** — completion, highlighting, validity
|
||||
indicator, in-line editing.
|
||||
- **Errors explained** — the friendly error layer.
|
||||
- **Export / import & sharing** (E2 recipes), **clipboard**.
|
||||
|
||||
Build order: Tier 1 simple-mode reference + types + constraints + input
|
||||
modes + mined help/usage strings → Tier 2 advanced SQL + relationships +
|
||||
project lifecycle + undo/history → Tier 3 teaching echo + EXPLAIN + errors +
|
||||
completion/highlighting → Tier 4 clipboard + hints + editing.
|
||||
|
||||
Conventions live in the **living style guide** `website/STYLE.md` (binding
|
||||
rules from ADR-0042 §7 — no engine name, **no "DSL"**, "planned" callouts —
|
||||
plus finer conventions and an open-decisions log for depth/splitting/example
|
||||
dataset/etc. as they settle). Sources to mine: `src/dsl/command.rs`,
|
||||
`src/dsl/grammar/*`, the REGISTRY, `en-US.yaml`, `docs/adr/*`,
|
||||
`docs/simple-mode-limitations.md`.
|
||||
|
||||
### E — Hosting & portability
|
||||
Keep the default static build (no adapter); `dist/` deploys to Vercel or any
|
||||
static host. `website/README.md` notes the Vercel preset (root dir
|
||||
`website/`) and the one-line `@astrojs/vercel` switch if SSR is ever needed.
|
||||
|
||||
## Demo seam (WASM hook)
|
||||
|
||||
`Demo.astro` exposes a stable contract (`{ src, title, height, autoplay }`).
|
||||
At launch it renders `Cast.astro`; later a `Playground.astro` WASM island
|
||||
swaps in behind the same props on the landing page and in docs, with zero
|
||||
call-site changes. Boundary details are in ADR-0042 §3.
|
||||
|
||||
## Verification
|
||||
|
||||
- `pnpm dev` renders landing + docs; `pnpm build` emits a clean static
|
||||
`dist/` with no errors/warnings.
|
||||
- Landing shows at least one playing `.cast`; the same component renders a
|
||||
cast inline in a docs page (proves reuse).
|
||||
- Starlight link-check passes (broken internal links fail the build).
|
||||
- Docs grep clean of forbidden terms: **no "DSL"**, no engine name.
|
||||
- A `dist/` static deploy works on Vercel (manual import) — confirms
|
||||
portability. (No CI gate yet, per ADR-0042 §4.)
|
||||
|
||||
## Notes / recommendations (non-blocking)
|
||||
|
||||
- **Doc drift:** consider generating the command reference from source (the
|
||||
`help` REGISTRY / `en-US.yaml`) rather than hand-writing all of it.
|
||||
- **Accessibility/SEO:** pair each hero `.cast` with a text transcript or the
|
||||
equivalent docs snippet.
|
||||
- **Branding/domain & analytics** unspecified — assume none until decided;
|
||||
no third-party trackers without consent.
|
||||
- Tailwind v4 + Starlight have occasional theme-token friction; the
|
||||
`@astrojs/starlight-tailwind` plugin is the supported bridge.
|
||||
- Starlight ships local search (Pagefind) by default.
|
||||
- No `README.md` exists at the repo root yet — wanted for the destination
|
||||
repo; out of this plan's core scope but flagged.
|
||||
Reference in New Issue
Block a user