Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
173 commits
Select commit Hold shift + click to select a range
fabd3ae
feat(storybook): add Textarea story
myelinated-wackerow May 5, 2026
e9a5ae4
feat(storybook): expand Input story coverage
myelinated-wackerow May 5, 2026
531eee6
feat(storybook): expand Checkbox story coverage
myelinated-wackerow May 5, 2026
8495b69
feat(storybook): expand Switch story coverage
myelinated-wackerow May 5, 2026
8cccb5b
feat(storybook): expand RadioGroup story coverage
myelinated-wackerow May 5, 2026
c28f190
feat(storybook): add Tabs story
myelinated-wackerow May 5, 2026
12e1524
feat(storybook): add Skeleton story
myelinated-wackerow May 5, 2026
a6d9264
feat(storybook): add Spinner story
myelinated-wackerow May 5, 2026
8c78b2f
feat(storybook): add Progress story
myelinated-wackerow May 5, 2026
af63b28
feat(storybook): add Breadcrumb story
myelinated-wackerow May 5, 2026
bb6c7d2
feat(storybook): add ScrollArea story
myelinated-wackerow May 5, 2026
c58dc34
feat(storybook): add List story
myelinated-wackerow May 5, 2026
0af6a64
feat(storybook): add Collapsible story
myelinated-wackerow May 5, 2026
d60ebe5
feat(storybook): add TruncatedText story
myelinated-wackerow May 5, 2026
2c305eb
feat(storybook): add Section story
myelinated-wackerow May 5, 2026
3006cd9
feat(storybook): add TabNav story
myelinated-wackerow May 5, 2026
91bc659
feat(storybook): add Flex story
myelinated-wackerow May 5, 2026
0a94075
feat(storybook): add LinkBox story
myelinated-wackerow May 5, 2026
1badfde
feat(storybook): add SvgButtonLink story
myelinated-wackerow May 5, 2026
d7f65c6
Update Nethermind sync strategies in docs
MarekM25 May 5, 2026
09a0218
feat(storybook): add Chart story
myelinated-wackerow May 5, 2026
36f2f91
revert(storybook): drop SvgButtonLink story
myelinated-wackerow May 6, 2026
2021192
chore(storybook): remove RadioGroup story
myelinated-wackerow May 6, 2026
01da580
chore: remove unused/stale components
myelinated-wackerow May 6, 2026
b22d2e1
chore(intl): drop adoption-chart keys
myelinated-wackerow May 6, 2026
e186b13
Leaderboard update for XDZIBECX
bshastry May 7, 2026
87ce0a4
a11y: ProductTable filter sidebar semantics
myelinated-wackerow May 8, 2026
366910c
docs(node): add Chainstack Self-Hosted to Guided setup list
akegaviar May 11, 2026
a42048a
refactor(community): hub cards as row stack
myelinated-wackerow May 12, 2026
d229816
Add Speedrun Ethereum's Oracles challenge
escottalexander May 12, 2026
55ab713
patch(ui): hk color adjustment
wackerow May 13, 2026
238084c
i18n(ar): LLM translation
wackerow May 13, 2026
28f3586
i18n(bn): LLM translation
wackerow May 13, 2026
71ec870
i18n(cs): LLM translation
wackerow May 13, 2026
d3c68d9
i18n(de): LLM translation
wackerow May 13, 2026
cf8a677
i18n(es): LLM translation
wackerow May 13, 2026
4e529ad
i18n(fr): LLM translation
wackerow May 13, 2026
fdd68a4
i18n(hi): LLM translation
wackerow May 13, 2026
de13916
i18n(id): LLM translation
wackerow May 13, 2026
d95c941
i18n(it): LLM translation
wackerow May 13, 2026
4a476b2
i18n(ja): LLM translation
wackerow May 13, 2026
ccdfd05
i18n(ko): LLM translation
wackerow May 13, 2026
e990440
i18n(mr): LLM translation
wackerow May 13, 2026
c5405af
i18n(pl): LLM translation
wackerow May 13, 2026
4fd3d9e
i18n(pt-br): LLM translation
wackerow May 13, 2026
96b4b8b
i18n(ru): LLM translation
wackerow May 13, 2026
2ccc88a
i18n(sw): LLM translation
wackerow May 13, 2026
0f3dc88
i18n(ta): LLM translation
wackerow May 13, 2026
95d2da9
i18n(te): LLM translation
wackerow May 13, 2026
c6fde80
i18n(tr): LLM translation
wackerow May 13, 2026
5304b1d
i18n(uk): LLM translation
wackerow May 13, 2026
46bc5f1
i18n(ur): LLM translation
wackerow May 13, 2026
03c0506
i18n(vi): LLM translation
wackerow May 13, 2026
fb51eb2
i18n(zh): LLM translation
wackerow May 13, 2026
cbd170b
i18n(zh-tw): LLM translation
wackerow May 13, 2026
b7d34a5
i18n: merge tmp-intl/run-0513-1039 into intl/pending-redesign-communi…
wackerow May 13, 2026
6314a54
chore(storybook): disable Chromatic snapshots on new form-input stories
myelinated-wackerow May 13, 2026
d797132
chore(storybook): disable Chromatic snapshots on new display stories
myelinated-wackerow May 13, 2026
ac0918c
chore(storybook): disable Chromatic snapshots on new layout/nav stories
myelinated-wackerow May 13, 2026
097d36e
docs: add dweb3 and web3compass to decentralized storage references
Emgevorgyan May 13, 2026
f1ece18
Add Stylus to Rust projects and tools
kafeelraza May 13, 2026
365734b
codeblock: replace prism-react-renderer with shiki
pettinarip May 14, 2026
d361f6b
codeblock: refresh styles and switch theme to vitesse
pettinarip May 14, 2026
4ebc5dc
Merge branch 'dev' into redesign-community-cards
wackerow May 14, 2026
d2398b5
refactor: centralize site title suffix in metadata
kafeelraza May 14, 2026
cba15c3
feat(layouts): consolidate topic layouts
myelinated-wackerow May 15, 2026
5c2e33b
refactor(content): migrate summary points
myelinated-wackerow May 15, 2026
ba00561
feat(md): render fenced code via Codeblock
myelinated-wackerow May 15, 2026
ac79475
chore(translatathon): remove pages and layout
myelinated-wackerow May 15, 2026
d4535c5
chore(translatathon): archive leaderboard page
myelinated-wackerow May 15, 2026
f8ea4ad
chore: drop public/images/translatathon dir
myelinated-wackerow May 15, 2026
4f898f9
docs(skills): land TopicLayout guidance
myelinated-wackerow May 15, 2026
b25edf5
chore: stories for card-family components
myelinated-wackerow May 15, 2026
b6ddc3f
chore: stories for content-primitive components
myelinated-wackerow May 15, 2026
0cdf29d
chore: stories for widget-primitive components
myelinated-wackerow May 15, 2026
559196f
chore: stories for shared layout infra
myelinated-wackerow May 15, 2026
3348588
chore: stories for callout/banner family
myelinated-wackerow May 15, 2026
04f5d3e
fix: address review feedback for site title suffix
kafeelraza May 15, 2026
ce3b6e4
fix: match Ethereum stablecoin entry by name (auto)
pettinarip May 15, 2026
6e24e53
Merge pull request #18205 from ethereum/recovery/fix/trigger-fetch-et…
pettinarip May 15, 2026
aac13d5
Update chains data
actions-user May 15, 2026
d11a978
Merge pull request #18196 from kafeelraza/fix-centralized-site-title
wackerow May 18, 2026
31fb641
docs: update README.md [skip ci]
allcontributors[bot] May 18, 2026
0a1a4be
docs: update .all-contributorsrc [skip ci]
allcontributors[bot] May 18, 2026
94273ec
Merge pull request #18212 from ethereum/all-contributors/add-kafeelraza
wackerow May 18, 2026
5223c89
Merge pull request #18123 from ethereum/feat/storybook-form-input-sto…
pettinarip May 18, 2026
ac06dc8
Merge pull request #18124 from ethereum/feat/storybook-display-primit…
pettinarip May 18, 2026
cdaa069
Merge pull request #18125 from ethereum/feat/storybook-layout-nav-pri…
pettinarip May 18, 2026
0b13d51
Merge pull request #18134 from ethereum/deprecate-components
pettinarip May 18, 2026
d03b352
Merge pull request #18153 from ethereum/product-tree
pettinarip May 18, 2026
8cdae93
Merge pull request #18197 from ethereum/deprecate-translatathon
pettinarip May 18, 2026
042e7a1
Merge pull request #18169 from ethereum/redesign-community-cards
pettinarip May 18, 2026
7008256
build(deps): bump brace-expansion from 1.1.11 to 5.0.4
dependabot[bot] May 18, 2026
540aea8
Merge branch 'dev' into feat/topic-layout-refactor
myelinated-wackerow May 19, 2026
b5fa2d3
Merge pull request #18199 from ethereum/chore/storybook-feature-cards
pettinarip May 19, 2026
ef8ed34
Merge pull request #18200 from ethereum/chore/storybook-feature-content
pettinarip May 19, 2026
7b2296c
Merge pull request #18201 from ethereum/chore/storybook-feature-widgets
pettinarip May 19, 2026
3cb9d8e
Merge pull request #18203 from ethereum/chore/storybook-feature-callouts
pettinarip May 19, 2026
ec2cacc
Merge pull request #18202 from ethereum/chore/storybook-feature-layout
pettinarip May 19, 2026
6d68fb3
refactor(layouts): drop pass-through slot props
myelinated-wackerow May 19, 2026
3545d00
patch: remove unavailable export
myelinated-wackerow May 19, 2026
c930c4c
fix(layouts): derive hero dims from source
myelinated-wackerow May 19, 2026
aedce62
bug-bounty: add EngineAPI as explicit out-of-scope item
0xMushow May 20, 2026
4696d6e
refactor: new product listing to end of list
wackerow May 20, 2026
6b37152
Merge pull request #18163 from akegaviar/docs/add-chainstack-self-hosted
wackerow May 20, 2026
db8adca
docs: update README.md [skip ci]
allcontributors[bot] May 20, 2026
e3c4a6e
docs: update .all-contributorsrc [skip ci]
allcontributors[bot] May 20, 2026
5f405e3
Merge pull request #18176 from escottalexander/patch-1
wackerow May 20, 2026
c7b4d57
Merge pull request #18226 from ethereum/all-contributors/add-akegaviar
wackerow May 20, 2026
074df31
docs: update README.md [skip ci]
allcontributors[bot] May 20, 2026
dbb3eb1
docs: update .all-contributorsrc [skip ci]
allcontributors[bot] May 20, 2026
f00eb13
Merge pull request #18183 from ethereum/intl/pending-redesign-communi…
wackerow May 20, 2026
248cc75
Merge pull request #18227 from ethereum/all-contributors/add-escottal…
wackerow May 20, 2026
ecd2736
update(content): discoverability via ens
wackerow May 20, 2026
815a05d
Merge pull request #18187 from Emgevorgyan/docs/ipfs-ens-discoverability
wackerow May 20, 2026
7d6b012
docs: update README.md [skip ci]
allcontributors[bot] May 20, 2026
c5763a7
docs: update .all-contributorsrc [skip ci]
allcontributors[bot] May 20, 2026
cb1acd8
refactor: move new product to end of list
wackerow May 20, 2026
9058d2b
Merge pull request #18189 from kafeelraza/add-stylus-rust-tool
wackerow May 20, 2026
5b4a831
docs: update README.md [skip ci]
allcontributors[bot] May 20, 2026
edda353
docs: update .all-contributorsrc [skip ci]
allcontributors[bot] May 20, 2026
bc474be
Merge pull request #18229 from ethereum/all-contributors/add-kafeelraza
wackerow May 20, 2026
dbe42d8
docs: update README.md [skip ci]
allcontributors[bot] May 20, 2026
9a73410
docs: update .all-contributorsrc [skip ci]
allcontributors[bot] May 20, 2026
bf837c2
Merge pull request #18198 from ethereum/feat/topic-layout-refactor
pettinarip May 20, 2026
bfbaa3b
Merge pull request #18230 from ethereum/all-contributors/add-ricardo-jtg
wackerow May 20, 2026
fc3cefd
Leaderboard: Points update for cyberthirst
bshastry May 20, 2026
e8cbb82
Merge pull request #18206 from ethereum/automated-update-20260515165740
wackerow May 20, 2026
a31f94c
Merge pull request #18213 from ethereum/dependabot/npm_and_yarn/brace…
wackerow May 20, 2026
90835bb
build(deps): bump ws from 8.17.1 to 8.20.1
dependabot[bot] May 20, 2026
9b325db
refactor(intl): re-apply keys for minimal diff
wackerow May 20, 2026
3d1bdce
Merge pull request #18225 from 0xMushow/add-explicit-oos-for-engine-api
wackerow May 20, 2026
8d99d69
Merge pull request #18231 from bshastry/cyberthirst-multiple
wackerow May 20, 2026
f5801fc
Merge branch 'dev' into all-contributors/add-Emgevorgyan
wackerow May 20, 2026
69ce9f3
Merge pull request #18228 from ethereum/all-contributors/add-Emgevorgyan
wackerow May 20, 2026
b753494
Merge pull request #18232 from ethereum/dependabot/npm_and_yarn/ws-8.…
wackerow May 20, 2026
410c477
build(deps): bump protobufjs from 7.5.4 to 7.6.0
dependabot[bot] May 20, 2026
56a0d9f
Merge branch 'dev' into mohamed-1376-teku-info
wackerow May 20, 2026
c430815
Merge pull request #18141 from bshastry/mohamed-1376-teku-info
wackerow May 20, 2026
1a08565
chore: prettier formatting
wackerow May 20, 2026
7b5ac5f
Merge pull request #18130 from MarekM25/patch-2
wackerow May 20, 2026
7437f34
Codeblock: always show copy button and inline component into index.tsx
pettinarip May 20, 2026
d605336
Merge pull request #18233 from ethereum/dependabot/npm_and_yarn/proto…
wackerow May 20, 2026
d30b0f1
Merge remote-tracking branch 'origin/dev' into HEAD
pettinarip May 20, 2026
0bda698
build(deps): bump fast-uri from 3.0.6 to 3.1.2
dependabot[bot] May 20, 2026
cfdaca3
build(deps): bump fast-xml-builder from 1.1.5 to 1.2.0
dependabot[bot] May 20, 2026
1ccabfa
Merge pull request #18194 from ethereum/codeblock-shiki
pettinarip May 20, 2026
cd819c3
Merge remote-tracking branch 'origin/dev' into codeblock-restyle
pettinarip May 20, 2026
d3be5e4
Apply suggestions from code review
pettinarip May 20, 2026
4158f5b
Merge pull request #18195 from ethereum/codeblock-restyle
pettinarip May 20, 2026
2fb01e0
fix: stop versioning next-env.d.ts and generate it for type-check
pettinarip May 20, 2026
1e5df38
add weekly release automation workflow
pettinarip May 20, 2026
81f6870
chore(docs): update to canonical `pnpm type-check`
wackerow May 21, 2026
36ff847
Merge pull request #18239 from ethereum/fix/untrack-next-env
wackerow May 21, 2026
75f4c29
refactor(ui): alert component
myelinated-wackerow May 21, 2026
a30384c
deprecate(ui): BannerNotification, BugBountyBanner
myelinated-wackerow May 21, 2026
b221533
refactor(ui): alert role is opt-in
myelinated-wackerow May 21, 2026
2f076a4
docs(skill): align design-system with Alert refactor
myelinated-wackerow May 21, 2026
84da2a9
Add new bounty hunter 'sonny2k' to JSON data
0xMushow May 21, 2026
723b33f
Merge pull request #18251 from 0xMushow/patch-12
wackerow May 21, 2026
277789b
Merge pull request #18236 from ethereum/dependabot/npm_and_yarn/fast-…
wackerow May 21, 2026
5dd2fcb
Merge pull request #18237 from ethereum/dependabot/npm_and_yarn/fast-…
wackerow May 21, 2026
98a522e
Merge pull request #18252 from ethereum/refactor-ui-alert
wackerow May 21, 2026
a1420c3
Merge pull request #18220 from ethereum/feat/weekly-release-automation
wackerow May 22, 2026
4c4da4b
fix(weekly-release): grant id-token: write for claude-code-action OIDC
pettinarip May 22, 2026
78e5aca
fix(weekly-release): drop GITHUB_TOKEN fallback for RELEASE_BOT_TOKEN
pettinarip May 22, 2026
66bd29c
Merge pull request #18257 from ethereum/fix/weekly-release-permissions
pettinarip May 22, 2026
8000157
Merge staging into dev
github-actions[bot] May 22, 2026
4bfdc9e
11.7.0
github-actions[bot] May 22, 2026
359eaf5
fix(layouts): fall back to description in topic hero
pettinarip May 22, 2026
8ce139d
Merge pull request #18260 from ethereum/fix/roadmap-hero-description
pettinarip May 22, 2026
4138475
fix(storybook): drop Pre from MdComponents story to unblock chromatic
pettinarip May 22, 2026
de4395f
Merge pull request #18262 from ethereum/fix/storybook-decorator-hooks
pettinarip May 22, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
46 changes: 46 additions & 0 deletions .all-contributorsrc
Original file line number Diff line number Diff line change
Expand Up @@ -14240,6 +14240,52 @@
"contributions": [
"maintenance"
]
},
{
"login": "kafeelraza",
"name": "kafeelraza",
"avatar_url": "https://avatars.githubusercontent.com/u/193384171?v=4",
"profile": "https://github.com/kafeelraza",
"contributions": [
"code",
"tool"
]
},
{
"login": "akegaviar",
"name": "Ake",
"avatar_url": "https://avatars.githubusercontent.com/u/10195782?v=4",
"profile": "https://ake.gg",
"contributions": [
"tool"
]
},
{
"login": "escottalexander",
"name": "Elliott Alexander",
"avatar_url": "https://avatars.githubusercontent.com/u/22101475?v=4",
"profile": "https://github.com/escottalexander",
"contributions": [
"tutorial"
]
},
{
"login": "Emgevorgyan",
"name": "Emgevorgyan",
"avatar_url": "https://avatars.githubusercontent.com/u/26285829?v=4",
"profile": "https://github.com/Emgevorgyan",
"contributions": [
"tool"
]
},
{
"login": "ricardo-jtg",
"name": "Ricardo Gonçalves",
"avatar_url": "https://avatars.githubusercontent.com/u/35004742?v=4",
"profile": "https://github.com/ricardo-jtg",
"contributions": [
"tool"
]
}
],
"contributorsPerLine": 7,
Expand Down
41 changes: 23 additions & 18 deletions .claude/commands/review-release.md
Original file line number Diff line number Diff line change
@@ -1,20 +1,23 @@
---
description: Review a release/deploy PR by checking key changes on staging with a browser
allowed-tools: Bash, Read, Glob, Grep, Agent, Skill, AskUserQuestion
argument-hints: [<pr-number> (auto-detects latest deploy PR)]
allowed-tools: Bash, Read, Glob, Grep, Agent, Skill
argument-hints: [<pr-number>] [--post-comment]
---

# Review Release

Review a release/deploy PR by fetching its description, identifying the most important changes, and verifying them on the staging deploy using the browser.

## Arguments
This command NEVER approves or requests changes on the PR. By default it only prints the summary in the terminal. Pass `--post-comment` to additionally post the summary as a comment on the PR (informational, not a review).

`$ARGUMENTS` may contain the PR number to review. If empty, auto-detect the latest deploy PR:
## Arguments

```bash
gh pr list -B master -H staging -s open -S "Deploy" --json number -q ".[0].number" -L 1
```
`$ARGUMENTS` may contain:
- A PR number to review. If omitted, auto-detect the latest deploy PR:
```bash
gh pr list -B master -H staging -s open -S "Deploy" --json number -q ".[0].number" -L 1
```
- `--post-comment` flag. If present, after producing the summary, post it as a PR comment via `gh pr comment`. Without this flag, the summary is only printed to the terminal.

## Workflow

Expand Down Expand Up @@ -57,24 +60,26 @@ Present a summary table with:
|------|--------|-------|
| Page name | Pass/Fail | What was checked and confirmed |

Flag any issues found. If everything looks good, confirm the deploy is ready to ship.
Flag any issues found. If everything looks good, note that the deploy looks ready to ship.

### Step 5: Submit Review
### Step 5: Optionally Post as PR Comment

After presenting results, ask the user if they want to submit a review on the PR. Offer two options:
If `--post-comment` was passed in `$ARGUMENTS`, post the summary table as a PR comment:

1. **Approve** — if all checks passed
2. **Request changes** — if issues were found
```bash
gh pr comment <PR_NUMBER> --repo ethereum/ethereum-org-website --body "$(cat <<'EOF'
## /review-release summary

Ask the user which action to take (or skip). If they choose to submit, post the summary table as the review body using:
<summary table here>

```bash
gh pr review <PR_NUMBER> --repo ethereum/ethereum-org-website --approve --body "..."
# or
gh pr review <PR_NUMBER> --repo ethereum/ethereum-org-website --request-changes --body "..."
_Informational only — this is not a PR review. Approval and merge remain manual._
EOF
)"
```

Do NOT submit a review without explicit user confirmation.
If `--post-comment` is NOT present, do nothing further — the terminal output is the only artifact.

This command must NEVER call `gh pr review --approve` or `gh pr review --request-changes`. Approval and merge stay with humans.

## Tips

Expand Down
4 changes: 3 additions & 1 deletion .claude/skills/design-system/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ When the existing primitive doesn't quite fit, the answer is usually "add a vari
8. **`useRtlFlip()` for directional icons** (right-pointing arrows/chevrons). Or use `ChevronNext`/`ChevronPrev` from `@/components/Chevron`.
9. **Markdown content goes through `MdComponents`.** The legacy `@/components/Card` (default export) is reserved for markdown shortcodes -- never import it from app code; use `@/components/ui/card`.
10. **Storybook stories ship with new UI components.** No automated unit tests; Storybook + Chromatic + types are the verification layer.
11. **Don't add new layouts.** There are six canonical layouts (`TopicLayout`, `StaticLayout`, `DocsLayout`, `TutorialLayout`, `ContentLayout`, `BaseLayout`). New sectioned content goes in `src/data/topics/<key>.ts` as a `TopicLayout` config -- not a new layout component. See `references/layouts.md`.

## Highest-Value Gotchas (read these now)

Expand Down Expand Up @@ -80,7 +81,7 @@ Don't add more. Use `numberFormat()`.
| Anchor (CTA with arrow) | `import { LinkWithArrow } from "@/components/ui/Link"` |
| Page hero | `import { ContentHero, SimpleHero, HubHero, MdxHero } from "@/components/Hero"` |
| Inline alert | `import { Alert, AlertContent, AlertDescription } from "@/components/ui/alert"` |
| Top-of-page banner | `import BannerNotification from "@/components/Banners/BannerNotification"` |
| Top-of-page banner | `import { Alert } from "@/components/ui/alert"` then `<Alert variant="banner">` |
| Big numeric display | `import BigNumber from "@/components/BigNumber"` |
| Layout | `import { Stack, HStack, VStack, Flex, Center } from "@/components/ui/flex"` |
| Number formatting | `import { numberFormat } from "@/lib/utils/numbers"` |
Expand All @@ -105,6 +106,7 @@ Pull these in only when the trigger applies. Don't read them all upfront.
- **`references/a11y.md`** -- Load when adding interactive elements (modals, dropdowns, custom click targets), building forms, or working with images and headings.
- **`references/card-walkthrough.md`** -- Load when starting any card-shaped UI work; an end-to-end worked example.
- **`references/page-hero-walkthrough.md`** -- Load when starting a new page that needs a hero; an end-to-end worked example.
- **`references/layouts.md`** -- Load when you're tempted to create a new layout, when adding a new topic-hub section, or when refactoring a one-off `src/layouts/md/<Section>Layout` file. The canonical inventory plus the rule that new layouts are very rare.
- **`references/new-component-checklist.md`** -- Load before opening a PR for a new component. The pre-merge checklist.

## Other Project Skills That May Apply
Expand Down
18 changes: 17 additions & 1 deletion .claude/skills/design-system/references/a11y.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,11 @@ Without it, screen readers announce nothing meaningful for the button.

### `<aside>` is for tangentially-related content

`<aside>` is being used for site-wide ribbons in `Banners/BannerNotification.tsx:15` and `TranslationBanner.tsx:57`. For announcement banners, `role="status"` (non-urgent) or `role="alert"` (urgent) is more appropriate.
`<aside>` is the right element for content that sits beside the main flow -- top-of-page ribbons, side callouts, supplementary explainers. In this codebase that includes `UpgradeStatus`, `CalloutBanner`/`CalloutSSR`, `CallToContribute`, `StakingHierarchy`, `TranslationBanner`, and `<Alert variant="banner">`. None of these should be `<section>` or `<article>`.

What `<aside>` does NOT imply is a live-region role. If the content is announced dynamically (form result, async status change), pair the `<aside>` with `role="status"` (polite) or `role="alert"` (assertive). Static editorial banners can stay role-less and shouldn't announce on page load.

`<Alert variant="banner">` is the canonical pattern for "tangential ribbon that may need to announce" -- it already renders `<aside>` and accepts `role` as a plain HTML pass-through. `TranslationBanner/index.tsx:56` still rolls its own `<aside>`; if you touch it, prefer migrating to `<Alert variant="banner">` to inherit the pattern.

### Image `alt` text

Expand Down Expand Up @@ -85,6 +89,18 @@ For dynamic content that should be announced:
<div role="alert" aria-live="assertive">{urgentMessage}</div> // Urgent: "Error"
```

`role="status"` and `role="alert"` carry implicit `aria-live` and `aria-atomic` values, so the explicit `aria-live` is usually redundant.

When the announcement lives inside an `Alert`, pass the role directly -- it's a plain HTML pass-through, no custom prop:

```tsx
<Alert variant="warning" role="status">
<AlertContent>{t("no-results")}</AlertContent>
</Alert>
```

The `Alert` primitive intentionally applies **no** ARIA role by default -- variant names like `error`/`warning` are visual emphasis on this editorial site, not runtime UI state. Opt in only when the alert is genuinely dynamic. See the `Alert` entry in `references/components.md`.

## One `<h1>` Per Page

`MdxHero` and `HubHero` both render `<h1>`. Most React-page heroes do. Most markdown layouts also auto-render the page `title` from frontmatter as the `<h1>`.
Expand Down
37 changes: 32 additions & 5 deletions .claude/skills/design-system/references/canonical-imports.md
Original file line number Diff line number Diff line change
Expand Up @@ -185,22 +185,49 @@ import PageHero from "@/components/PageHero"

## Banners / Callouts / Alerts

### Inline message in content area: `Alert`
### Inline notice AND top-of-page ribbon: `Alert`

```tsx
import { Alert, AlertContent, AlertDescription } from "@/components/ui/alert"
```

Variants: `info | error | success | warning | update`. Optional `size: "full"` for borderless full-width.
One primitive covers both shapes via `variant`:

### In-content / top-of-page callout: `Callout`
| Use case | Variant |
|---|---|
| In-prose notice | `info` `error` `success` `warning` `update` |
| Full-bleed top-of-page ribbon (white-on-primary) | `banner` |

```tsx
// Top-of-page ribbon:
<Alert variant="banner">{t("page-roadmap-banner-notification")}</Alert>

// In-content warning:
<Alert variant="warning">
<AlertContent>
<AlertDescription>{t("warning-text")}</AlertDescription>
</AlertContent>
</Alert>
```

`variant="banner"` renders `<aside>` (tangential to main content); other variants render `<div>`. No ARIA role by default -- pass `role="status"` for polite dynamic announcements (e.g. filter result counts) or `role="alert"` for genuine assertive errors. See `references/components.md` for the full parts inventory.

### Do NOT import `BannerNotification`

```tsx
// DON'T -- file deleted May 2026:
import BannerNotification from "@/components/Banners/BannerNotification"
```

The `Banners/` subdirectory is gone. Use `<Alert variant="banner">` for top-of-page ribbons.

### Card-shaped in-content callouts: `Callout` family

> **Migration in progress.** A unified server-renderable `Callout` component is being built that absorbs the current `Callout`/`CalloutSSR`/`CalloutBanner`/`CalloutBannerSSR`/`BannerNotification`/`DismissableBanner` set into a single primitive with variants. Tracked in a dedicated issue.
> **Migration in progress.** A unified server-renderable `Callout` component is being built to absorb `Callout`/`CalloutSSR`/`CalloutBanner`/`CalloutBannerSSR`/`DismissableBanner` into a single primitive with variants. (`BannerNotification` was previously on this list but was absorbed into `Alert` as `variant="banner"` ahead of the broader consolidation.) Tracked in a dedicated issue.

Until the unified `Callout` lands:
- For **in-content** callouts with image + heading: use `CalloutBannerSSR` (NOT `CalloutBanner.tsx`). Server-renderable; uses `cva` with `large | medium | small` sizes.
- For **big ornamental section dividers** with image overlap: use `CalloutSSR` (NOT `Callout.tsx`). Server-renderable.
- For **top-of-page site-wide stripes**: use `BannerNotification` (`@/components/Banners/BannerNotification`). Will be absorbed as a `notification` variant on the unified `Callout`.
- Avoid `Callout.tsx` and `CalloutBanner.tsx` (client-only thunks; superseded by their SSR siblings and ultimately by the unified component).

## Tabs / Tab Navigation
Expand Down
90 changes: 90 additions & 0 deletions .claude/skills/design-system/references/cleanup-playbook.md
Original file line number Diff line number Diff line change
Expand Up @@ -247,6 +247,53 @@ import { ContentHero } from "@/components/Hero"

The shapes are different; you may need to restructure the page slightly. `PageHero` is on the deprecation track.

## `BannerNotification` -> `Alert variant="banner"`

```tsx
// Before (file no longer exists -- import is broken):
import BannerNotification from "@/components/Banners/BannerNotification"
<BannerNotification shouldShow={isPageIncomplete}>
<Translation id="page-developers-docs:banner-page-incomplete" />
</BannerNotification>

// After:
import { Alert } from "@/components/ui/alert"
{isPageIncomplete && (
<Alert variant="banner">
<Translation id="page-developers-docs:banner-page-incomplete" />
</Alert>
)}
```

`BannerNotification` was deleted in May 2026; if you find the import in stale code, this is the replacement. The `shouldShow` prop has no equivalent on `Alert` -- gate at the JSX level (`{condition && <Alert>...</Alert>}`).

`BugBountyBanner` (a thin one-off wrapper around `BannerNotification`) was deleted in the same pass with no replacement file -- inline `<Alert variant="banner">` at the call site.

## Inline `<strong>` lead-in inside `Alert` -> `AlertTitle` + `AlertDescription`

```tsx
// Before:
<Alert variant="info">
<AlertContent>
<p className="mt-0"><strong>Heads up</strong></p>
<p className="mt-4">Some description text...</p>
</AlertContent>
</Alert>

// After:
import { AlertTitle, AlertDescription } from "@/components/ui/alert"
<Alert variant="info">
<AlertContent>
<AlertTitle>Heads up</AlertTitle>
<AlertDescription>
<p>Some description text...</p>
</AlertDescription>
</AlertContent>
</Alert>
```

`AlertTitle` is the canonical "bold standard-font-size lead-in line" for an Alert -- use it whenever an alert needs a bold opening line. `AlertDescription` normalizes paragraph spacing internally, so no `mt-`/`mb-` classes are needed on the body paragraphs. The Alert sub-components are designed so callers don't apply manual typography or spacing inside the Alert.

## Arbitrary z-index -> named z scale

```tsx
Expand Down Expand Up @@ -287,3 +334,46 @@ import { Stack } from "@/components/ui/flex"
```

(Stack already defaults to `flex-col gap-2`, so often you can drop the className entirely.)

## Per-section `src/layouts/md/<Section>Layout` -> `TopicLayout` config

```tsx
// Before -- a section gets its own layout file that duplicates 90% of every other section's layout:
// src/layouts/md/Staking.tsx
export const StakingLayout = ({ children, frontmatter, slug, ... }) => {
const { t } = useTranslation("page-staking")
const dropdownLinks = { text: t("..."), items: [ /* ... */ ] }
const heroProps = { ...frontmatter, breadcrumbs: { slug, startDepth: 1 }, heroImg: { ... } }
return <ContentLayout dropdownLinks={dropdownLinks} heroSection={<ContentHero {...heroProps} />}>{children}</ContentLayout>
}

// After -- the data lives in a config file, no layout component needed:
// src/data/topics/staking.ts
import type { TopicConfig } from "."
export const staking: TopicConfig = {
translationNs: "page-staking",
dropdown: {
textKey: "page-staking-dropdown-staking-options",
ariaLabelKey: "page-staking-dropdown-staking-options-alt",
matomoCategory: "Staking dropdown",
items: [
{ textKey: "page-staking-dropdown-home", href: "/staking/", matomoEvent: "clicked staking home" },
// ...
],
},
heroImage: { width: 800, height: 605 },
}

// src/layouts/index.ts
export const layoutMapping = {
// ...
staking: TopicLayout, // was: StakingLayout
}
```

After the move:
- Keep the section's MDX component bundle (`stakingComponents`) in `src/layouts/md/<key>.tsx`; only the layout export goes away.
- Delete any per-section heading overrides (`Heading1`/`Heading2`/etc. with extra className). The defaults in `MdComponents` are the baseline.
- If the section needs a swap-in component (HubHero on a specific slug, content after the markdown), use `config.hubHero` or the `afterContent` prop -- don't fork a new layout.

See `references/layouts.md` for the full inventory and `docs/topic-layout-refactor.md` for the worked migration.
Loading
Loading