Skip to content

Commit 425a363

Browse files
ChanMeng666claude
andcommitted
fix(sites): Phase 2 polish — a11y to 100, header overflow, invert bug, stale refs
Docs: whole-site .dark invert bug fixed (partial :global selector miscompiled to a bare .dark rule — invert now unscoped-scoped to the credit mark only); role=main on the home layout; section eyebrows become real h2s; search placeholder and agents-band flag contrast to AA; mobile home nav goes carbon; pre-footer gap tightened; stale FamilyFooter comment updated. Playground: header fits one row at every width >=1024 (NAV collapses to overflow <1600); CodeMirror content gets an accessible name; tabs get real tablist/tab/ tabpanel roles with aria-selected; README updated for the styles/ split. Both sites ship a robots.txt. Lighthouse: docs home and playground both 100/100/100 (a11y/BP/SEO); hero CLS 0.01. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
1 parent 934c2b1 commit 425a363

13 files changed

Lines changed: 128 additions & 28 deletions

File tree

docs-site/.vitepress/config.ts

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -188,8 +188,9 @@ export default defineConfig({
188188
],
189189
socialLinks: [{ icon: "github", link: "https://github.com/chanmeng666/archlang" }],
190190
search: { provider: "local" },
191-
// The site-wide footer is rendered by FamilyFooter.vue (layout-bottom slot),
192-
// which carries the MIT/copyright line plus the brand-family ecosystem links.
193-
// Omitting the built-in `footer` here avoids a duplicate footer.
191+
// The site-wide footer is rendered by TitleBlockFooter.vue (layout-bottom slot),
192+
// a drawing title block carrying the project/license/issued cells plus the
193+
// brand-family ecosystem links. Omitting the built-in `footer` here avoids a
194+
// duplicate footer.
194195
},
195196
});

docs-site/.vitepress/theme/Layout.vue

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,22 @@
22
// Wraps the VitePress default Layout to inject the brand-family pieces through
33
// official slots: the "Compile Boundary" hero above the homepage body
44
// (home-hero-before) and the title-block footer site-wide (layout-bottom).
5+
import { onMounted } from "vue";
56
import DefaultTheme from "vitepress/theme";
67
import CompileSeam from "./CompileSeam.vue";
78
import TitleBlockFooter from "./TitleBlockFooter.vue";
89
910
const { Layout } = DefaultTheme;
11+
12+
// The `layout: home` page renders no <main> landmark (VitePress uses a bare
13+
// #VPContent > .VPHome). Mark .VPHome as the main landmark so the page has
14+
// exactly one — but only if the page doesn't already expose a main (inner
15+
// doc pages do), so we never create a duplicate. Client-only; harmless on
16+
// hydrate since it mutates an existing element's attribute after mount.
17+
onMounted(() => {
18+
if (document.querySelector('main, [role="main"]')) return;
19+
document.querySelector(".VPHome")?.setAttribute("role", "main");
20+
});
1021
</script>
1122
1223
<template>

docs-site/.vitepress/theme/SheetGrid.vue

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ const row2: Sheet[] = [
6464
<div class="dimdiv" role="presentation">
6565
<span class="dimdiv__tick" />
6666
<span class="dimdiv__line" />
67-
<span class="dimdiv__label">Features · Sheets A-101 — A-105</span>
67+
<h2 class="dimdiv__label">Features · Sheets A-101 — A-105</h2>
6868
<span class="dimdiv__line" />
6969
<span class="dimdiv__tick" />
7070
</div>
@@ -138,10 +138,17 @@ const row2: Sheet[] = [
138138
}
139139
.dimdiv__label {
140140
flex: none;
141+
/* It IS the section's h2 (heading order: hero h1 → this → card h3s), styled as
142+
a dimension-line label. Reset the .vp-doc h2 box so the drawing detail is
143+
visually unchanged. */
144+
margin: 0;
145+
border: 0;
146+
padding: 0;
141147
font-family: var(--font-display);
142148
font-variation-settings: "wdth" 86;
143149
font-weight: 600;
144150
font-size: 11px;
151+
line-height: 1;
145152
letter-spacing: 0.13em;
146153
text-transform: uppercase;
147154
color: var(--ink-muted);

docs-site/.vitepress/theme/TitleBlockFooter.vue

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -161,9 +161,6 @@ const ECOSYSTEM = [
161161
.cell__credit img {
162162
display: block;
163163
}
164-
:global(.dark) .cell__credit img {
165-
filter: invert(1);
166-
}
167164
.cell__links {
168165
display: flex;
169166
flex-wrap: wrap;
@@ -180,3 +177,13 @@ const ECOSYSTEM = [
180177
color: var(--redline-ink);
181178
}
182179
</style>
180+
181+
<style>
182+
/* Unscoped on purpose: partial `:global(.dark) descendant` selectors are
183+
miscompiled by the SFC compiler into a bare `.dark` rule (which inverted
184+
the whole site). The credit mark is the one raster that needs inverting
185+
on mylar. */
186+
.dark .cell__credit img {
187+
filter: invert(1);
188+
}
189+
</style>

docs-site/.vitepress/theme/doc-pages.css

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -445,11 +445,22 @@ html:not(.dark) .vp-doc .vp-code span {
445445
color: var(--redline-ink);
446446
}
447447

448-
.DocSearch-Button {
448+
/* Paper-world search trigger — everywhere EXCEPT the home page's carbon
449+
`.home.top` bar, which paints its own source-world ghost trigger in home.css.
450+
Scoped off `.home.top` (instead of an even louder !important there) so the
451+
carbon bar's search doesn't read as a white block over the hero, at any width. */
452+
.VPNavBar:not(.home.top) .DocSearch-Button {
449453
border-radius: 3px !important;
450454
border: 1px solid var(--hairline) !important;
451455
background: var(--paper-panel) !important;
452456
}
457+
/* On the paper bar the placeholder + hotkey hint must be paper-world ink, not the
458+
source-world --src-muted (#98a0ac → only 2.5:1 on --paper-panel). --ink-muted
459+
is 5.4:1 AA. (The carbon .home.top bar keeps --src-muted via home.css.) */
460+
.VPNavBar:not(.home.top) .DocSearch-Button .DocSearch-Button-Placeholder,
461+
.VPNavBar:not(.home.top) .DocSearch-Button .DocSearch-Button-Key {
462+
color: var(--ink-muted) !important;
463+
}
453464

454465
/* ============================================================================
455466
10 · PREV/NEXT FOOTER · EDIT LINK · LAST UPDATED

docs-site/.vitepress/theme/home.css

Lines changed: 41 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,42 @@
6767
color: var(--src-muted);
6868
}
6969

70+
/* Mobile nav (<768px): the search trigger and the hamburger share the carbon
71+
`.home.top` bar. The .DocSearch-Button rules above give the trigger its
72+
source-world ghost look (the paper-world fill lives in doc-pages.css, scoped
73+
off `.home.top`). The remaining mobile-only piece is the hamburger's three
74+
bars, which default to the paper world's dark ink (--vp-c-text-1) and are
75+
near-invisible on carbon — re-tint them to the source world. */
76+
.VPNavBar.home.top .DocSearch-Button:hover .DocSearch-Search-Icon {
77+
background-color: var(--src-fg);
78+
}
79+
.VPNavBar.home.top .VPNavBarHamburger .top,
80+
.VPNavBar.home.top .VPNavBarHamburger .middle,
81+
.VPNavBar.home.top .VPNavBarHamburger .bottom {
82+
background-color: var(--src-fg);
83+
}
84+
.VPNavBar.home.top .VPNavBarHamburger:hover .top,
85+
.VPNavBar.home.top .VPNavBarHamburger:hover .middle,
86+
.VPNavBar.home.top .VPNavBarHamburger:hover .bottom {
87+
background-color: var(--plum-bright);
88+
}
89+
90+
/* ═══ Landing bottom — deliberate footer gap ═══════════════════════════════
91+
The last landing section is the carbon "agents" band; VitePress's default
92+
`.VPHome` margin-bottom (96/128px) then drops the title-block footer, which
93+
over a dark band reads as a pale void. Tighten it to a deliberate ~112px so
94+
the footer follows the band as an intended step, not empty paper.
95+
(Selector carries `.VPContent.is-home` so it outranks VitePress's scoped
96+
`.VPHome[data-v-…]` default of 96/128px.) */
97+
.VPContent.is-home .VPHome {
98+
margin-bottom: 96px;
99+
}
100+
@media (min-width: 768px) {
101+
.VPContent.is-home .VPHome {
102+
margin-bottom: 112px;
103+
}
104+
}
105+
70106
/* ═══ Landing sections — full bleed ════════════════════════════════════════
71107
The section components render inside `.vp-doc.container` (max-width + padding).
72108
Pull them out to the full viewport width with VitePress's own `--vp-offset`
@@ -146,7 +182,11 @@
146182
user-select: none;
147183
}
148184
.vp-doc .agents__flag {
149-
color: var(--redline);
185+
/* On-carbon redline: a FIXED lightened redline (the band is carbon in both
186+
light and dark, so --redline — which flips per mode and is only AA on paper —
187+
can't be used). #f0705f on carbon-2 (#171b23) = 5.9:1, well past AA for this
188+
micro-label, and stays redline-family (distinct from the plum keys). */
189+
color: #f0705f;
150190
}
151191
.vp-doc .agents__key {
152192
color: var(--plum-bright);

docs-site/public/robots.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
User-agent: *
2+
Allow: /

playground/README.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,12 +42,14 @@ The playground is TypeScript; every module below is `.ts` except the generated g
4242
| `preview.ts` / `pan-zoom.ts` | SVG preview + circulation Paths overlay; CSS-transform pan/zoom/fit controller |
4343
| `interact.ts` | hover-room tooltip + click-to-source (`data-span`) |
4444
| `actions.ts` | header actions: **Format**, **Repair furniture**, **Embed**, copy-link |
45+
| `llm-prompt.ts` | builds the **Copy for LLM** payload (source + `describe()` facts + diagnostics) |
4546
| `embed.ts` / `viewer.ts` | Embed-snippet builder; the chrome-less `embed.html` viewer runtime |
4647
| `facts-strip.ts` / `describe-panel.ts` / `lint-panel.ts` / `diagnostics-panel.ts` | the `describe()`/`lint()` fact & diagnostic panels |
4748
| `share.ts` | `#z=` deflate-raw permalink encode/decode (reads legacy `#src=`) |
4849
| `raster-export.ts` | copy/download SVG · PNG · DXF · PDF |
4950
| `snapshots.ts` / `storage.ts` | named snapshot history UI + defensive `localStorage` helpers |
50-
| `examples.ts`, `flowing-lines.ts`, `escape.ts`, `style.css` | example plans, brand animation, HTML-escape helper, styles |
51+
| `examples.ts`, `escape.ts` | example plans, HTML-escape helper |
52+
| `styles/*.css` | the shell's styles, split by concern: `tokens.css` (the shared "Compile Boundary" brand tokens, byte-identical with the docs site), `chrome.css` (carbon source-world header + the compile-seam divider), `editor.css`, `panels.css` (sheet-world output panels), `embed.css` (the chrome-less viewer) |
5153

5254
## Run
5355

playground/index.html

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@
7474
</div>
7575
<div class="spacer"></div>
7676
<!-- brand-family navigation: quiet text links (no boxes), right-aligned.
77-
Collapses into the "⋯" disclosure below <1024px (CSS-only). -->
77+
Collapses into the "⋯" disclosure below <1600px (CSS-only). -->
7878
<nav class="tb-nav" aria-label="Related sites">
7979
<a href="https://archlang-docs.vercel.app" target="_blank" rel="noopener">Docs ↗</a>
8080
<a href="https://archlang-docs.vercel.app/spec" target="_blank" rel="noopener">Spec</a>
@@ -101,13 +101,13 @@ <h2 class="src-tab">SOURCE.ARCH</h2>
101101
<h2>
102102
<span class="dot" id="status"></span><span id="statusText">ready</span>
103103
<span class="grow"></span>
104-
<span class="tabs" role="tablist">
105-
<button class="tab active" data-tab="preview" type="button">Preview</button>
106-
<button class="tab" data-tab="describe" type="button">Describe</button>
107-
<button class="tab" data-tab="lint" type="button">Lint</button>
104+
<span class="tabs" role="tablist" aria-label="Output view">
105+
<button class="tab active" id="tab-preview" data-tab="preview" type="button" role="tab" aria-selected="true" aria-controls="preview">Preview</button>
106+
<button class="tab" id="tab-describe" data-tab="describe" type="button" role="tab" aria-selected="false" aria-controls="describe">Describe</button>
107+
<button class="tab" id="tab-lint" data-tab="lint" type="button" role="tab" aria-selected="false" aria-controls="lint">Lint</button>
108108
</span>
109109
</h2>
110-
<div id="preview" class="tabview active" role="tabpanel">
110+
<div id="preview" class="tabview active" role="tabpanel" aria-labelledby="tab-preview">
111111
<div class="pz-viewport">
112112
<div class="pz-stage"></div>
113113
<div class="pz-toolbar">
@@ -124,8 +124,8 @@ <h2>
124124
</div>
125125
<div id="facts" class="facts" aria-label="Plan facts"></div>
126126
</div>
127-
<div id="describe" class="tabview" role="tabpanel"></div>
128-
<div id="lint" class="tabview" role="tabpanel">
127+
<div id="describe" class="tabview" role="tabpanel" aria-labelledby="tab-describe"></div>
128+
<div id="lint" class="tabview" role="tabpanel" aria-labelledby="tab-lint">
129129
<div class="lint-controls">
130130
<label for="lintProfile">Profile</label>
131131
<select id="lintProfile" aria-label="Lint profile"></select>

playground/public/robots.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
User-agent: *
2+
Allow: /

0 commit comments

Comments
 (0)