Guidance for AI coding agents working in this repository. Tool-agnostic; CLAUDE.md points here.
Bootstrap v6.0.0-alpha.1 — CSS/JS framework.
Sass source in scss/, TypeScript source in js/src/, docs site in site/ (Astro 5 + MDX).
npm start— dev server (watch + Astro on port 9001)npm run dist— full CSS + JS buildnpm run css— compile, prefix, minify CSSnpm run js— compile + minify JSnpm run css-lint/npm run js-lint— lintnpm run docs-build— build docs sitenpm test— full test suite (lint + dist + tests + docs)
Use ASD-STE100 Simplified Technical English for all prose: replies to the user, docs, code comments, commit messages, and PR text.
- Write short sentences. Use approximately 20 words or fewer.
- Give one instruction per sentence.
- Use the active voice. Name the actor.
- Use simple verbs. Do not use a complex verb when a simple one works.
- Use one term for one thing. Keep terms the same across the project.
- Keep paragraphs short. Cover one topic per paragraph.
Be extremely brief. Report the result, not the journey.
- Target 75 words or fewer. Hard cap 150 words, and only for a genuinely multi-part answer.
- Answer in the first sentence. Then stop.
- Give one supporting fact per claim, at most. Cut the rest.
- Do not narrate your process, tool calls, or verification steps. Report a check only when it failed or changed the outcome.
- Do not restate the work you just did. The user reads the diff, the commit, and the PR.
- State a finding once. Never repeat it in a summary or closing line.
- No headings. No tables. Use a list of 5 items or fewer only when the answer is a real list.
- Cut praise, apologies, hedging, and filler such as "great question" or "worth noting".
- Do not explain what you did not do, or list caveats the user did not ask about.
- Do not offer next steps unless the user asks or the work is blocked.
- Expand only when the user asks for detail, or asks you to teach.
Act as a teacher for JavaScript, TypeScript, React, and all JavaScript-family topics.
- When the work hits a new problem, concept, or language feature, stop and explain it.
- Keep each explanation short and plain. Define jargon on first use.
- Use a small code example when it makes the idea clear.
- Assume strong HTML/CSS knowledge. Do not assume deep JS internals knowledge.
- Variable naming:
$component-state-property-size(e.g.,$nav-link-disabled-color) - Module system:
@use/@forwardonly — never@import - Token system: component tokens are SCSS maps of CSS custom properties, merged via
defaults(), output via@include tokens($map)on the component root selector - Disallowed: raw
border-radius/transitionproperties (use mixins),lighten()/darken(),border: none/outline: none - Order:
@use→@forward→$variables→--custom-properties→ declarations → rules - Variables use
!default(except locals) - CSS layers:
colors, config, root, reboot, layout, content, forms, components, custom, helpers, utilities - Logical properties: prefer
padding-inline-startoverpadding-left, etc. - Modern CSS:
color-mix(),light-dark(), range media queries (@media (width >= 1024px)) - Doc markers:
// scss-docs-start name/// scss-docs-end namefor docs extraction
- Source is TypeScript (
js/src/**/*.ts, entryjs/src/index.ts); ESM-only, no semicolons, 2-space indent - Imports use
.jsextensions (standard TS ESM style); Rolldown resolves them to.tsviaresolve.extensionAlias, Vitest via thetsResolveplugin injs/tests/vitest.config.mts - Dist builds use Rolldown (
build/rolldown.config.mjs,build/build-plugins.mjs) with built-in TS transforms;build/browser-targets.mjsderives the browser floors from.browserslistrcat build time, so there is nothing to keep in sync. Rollup and Babel are gone from the repo — Vitest transforms the specs itself - Strict tsconfig with
verbatimModuleSyntax+erasableSyntaxOnly;tsconly type-checks and emits.d.ts(npm run js-typecheck,npm run js-emit-types) - Components extend
BaseComponent(which extendsConfig); per-component configtype XxxConfigtyped offDefault, refined on the class viaprotected declare _config: XxxConfig - Instance fields use
declare(no runtime emit); constructorelementparam stays optional to keeptypeof Componentassignable totypeof BaseComponent - Every
_-prefixed instance member isprotected(neverprivate, so subclasses keep access); public API methods and statics stay public. This keeps the internals out of the published.d.tssurface - Constants:
NAME,DATA_KEY,EVENT_KEY,VERSION - DOM utilities via
dom/event-handler.ts,dom/selector-engine.ts,dom/manipulator.ts - Floating UI for positioning (dropdown, tooltip, popover)
- Tests: Vitest browser mode (real Chromium via Playwright), config in
js/tests/vitest.config.mts, specs injs/tests/unit/*.spec.js(plain JS, bundled against the TS sources).js/tests/vitest-setup.jsmaps the Jasmine API the specs are written against onto Vitest — notespyOnstubs by default, unlikevi.spyOn. Async specs return a promise; Vitest 4 droppeddone. Coverage is Istanbul over all ofjs/src, thresholds 90/88/90/90 - Type-level API tests in
js/tests/types/—api.tschecks the source (npm run js-typecheck),consumer.tschecks the shippedjs/dist/*.d.tsthrough the packageexportsmap (npm run js-typecheck-dist, after the build). Keep the two in sync
- Astro 5 + MDX in
site/src/content/docs/ - Frontmatter schema:
title(required),description(required),toc,aliases,added,mdn,reference, etc. - Shortcodes:
Example,Callout,Code,Details - Internal links:
[[docsref:/path/]] - JS component "Dependencies" tables are auto-generated — add a
### Dependenciesheading with<JsDependencies component="<js-src-basename>" />(before### Options) on any doc for ajs/src/*.tscomponent. The table is derived at build time by walking the component's import graph insite/src/libs/js-dependencies.ts; never hand-write the file list. When a new source file or third-party package enters the graph, add its human-readable label toFILE_DESCRIPTIONS/PACKAGE_DESCRIPTIONSin that lib (the build throws if a label is missing).
- 2 spaces, UTF-8, LF line endings, trim trailing whitespace, final newline
- Preserve smart punctuation (curly apostrophes U+2019, curly quotes) — never replace with ASCII equivalents
- Use
StrReplacefor targeted edits; avoid full-file rewrites on MDX files to protect typography
- Validate after changes:
npm run css-lint,npm run js-lint,npm run dist,npm run docs-build - Keep config files in sync:
config.yml,site/src/libs/config.ts(Zod schema),build/rolldown.config.mjs,build/generate-sri.mjs,package.json - For rebases/conflicts: favor base branch structure, layer feature changes on top
- Commit messages: direct, succinct prose explaining why the change was made.
- PR descriptions: direct bulleted lists, minimal fluff — one bullet per notable change.
- Reference related issues/PRs explicitly with
Fixes #{issue},Closes #{issue}, orSupersedes #{pr}. - No "Test plan" section and no extra headings — just the bullets and the references.
Built output in dist/, _site/, js/dist/ — these are generated.