axe's label-content-name-mismatch rule flags the search button
(#5401): its visible text is "Search ⌘ K" while its accessible name
is "Search". aria-hidden on the keys does not help — the rule counts
visually rendered text, since WCAG 2.5.3 is about what sighted
speech-input users see and say.
The button was arguably conformant as it was: 2.5.3 constrains the
label, and the keycaps are a shortcut hint, not the label. Nobody
says "click Search command K". The glyphs move to CSS anyway because
it costs nothing visible and layers things right: the DOM text now
contains exactly the label, so speech software gets no stray "K"
target, strict audits pass without a human ruling them false
positives, and the decorative hint lives in the presentation layer
where decorative content belongs. Screen readers are unaffected — the
keys were already aria-hidden — and aria-keyshortcuts keeps carrying
the shortcut semantics.
Also folds the two display-toggled kbd elements into one whose
content switches per platform.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Safari composites the sticky local nav above the bar's negative-z
rule in their overlapping row, regardless of z-index, hiding the
divider below 60rem (#5399). Promoting the rule to its own layer
restores the order. Flyout panels still cover it.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The icon is a masked background on an inline box whose height follows
font metrics per engine. The fixed centered mask left an unmasked
sliver of the background visible below the arrow on iOS. A full-size
mask can only stretch the arrow slightly, never leak.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The nav menu is the bar's only growing element, so without `nav`
configured everything packed to the right edge. Search now carries an
auto right margin. A present menu's flex-grow still wins, so nothing
moves in that case.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The local nav's bottom rule reads its own token instead of a
hardcoded gutter color. It follows --vp-nav-divider-color by default,
like the surface color follows the navbar's.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The frosted-glass surface disappeared from builds. Two causes stacked:
lightningcss (vite's css minifier) collapses a standard-first pair
into the prefixed declaration alone, and -webkit-backdrop-filter is
dead weight everywhere — Chromium and Firefox don't recognize it, and
WebKit ignores var() values in it (bug 289800).
Only the standard property is written now. The minifier re-adds the
prefix from it for its own targets. Safari 17 and earlier show the
translucent color without the blur, noted in the glass recipe's
warning.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The sidebar item row was a `role="button"` wrapping both the group heading
and a second `role="button"` caret, which is invalid HTML and nests
interactive controls. The caret is now the only control (a native button
with `aria-expanded`), the row keeps its click handler as a mouse-only
affordance, and groups without a heading render a `div` instead of a
`section`.
fixes#5366closes#5371
Co-authored-by: Jibin7Jose <jibinjose884@gmail.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Any element with an `id` is keyed by it regardless of attribute order, and a
`meta` without one is keyed by its first attribute other than `content`. This
stops differently named meta tags with the same content from overriding each
other and lets repeated meta tags be kept apart with unique ids.
fixes#5362closes#5363closes#5379
Co-authored-by: Lazizbek Ergashev <20501725+lazerg@users.noreply.github.com>
Co-authored-by: shamu45678 <220251922@seu.edu.cn>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
`watch([props, navEl], ...)` is only accidentally valid on the client,
where props reaching setup are shallow-reactive. During SSR props are
not reactified (dev mode additionally wraps them in shallowReadonly),
so dev-flavored SSR warns "Invalid watch source: Proxy({ open: false })"
once per rendered page. Normally invisible because build() forces
NODE_ENV=production before vue loads — but any process that already
required vue under a different NODE_ENV (programmatic builds inside
test runners) keeps dev vue in the module cache and surfaces it.
Repro (pure Vue, no vitepress): renderToString of a component doing
watch([props, ref], cb, { immediate: true, flush: 'post' }) under dev
vue. Watching `() => props.open` expresses the actual dependency and
is valid in both environments.
dcb7a755 turned hasActiveLink from a computed into a ref fed only by a
non-immediate watch and onMounted, so is-active/has-active stopped
rendering in static HTML. This broke pre-hydration sidebar highlighting
and the docsearch crawler's lvl0 selector (section.has-active div h2),
which has indexed every record as the defaultValue since then.
Run the update once during setup with the hash check skipped: the server
and the client's initial render compute identical path-only state, so
hydration stays clean; the watch and onMounted refine with the real hash
after mount.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Indexing runs unawaited from `configureServer`, so a page whose snippet or
include cannot be resolved rejected the scan and killed the process on
startup. Warn and skip the page instead; the error is still reported by the
markdown transform, and the build still fails on it.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Documents the rewritten behavior: multi-region concatenation across
comment styles, region marker stripping, extra fence attributes from
snippet braces, build errors for missing files, regions and ranges
with the silent opt-out, url rebasing, which extensions are inferred
as a language, and including code files by line range through fenced
includes. Removes the outdated note claiming missing include files do
not error.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>