diff --git a/src/src/components/SiteBrand.astro b/src/src/components/SiteBrand.astro index be45894..4a0343e 100644 --- a/src/src/components/SiteBrand.astro +++ b/src/src/components/SiteBrand.astro @@ -12,26 +12,24 @@ const { iconOnly = false } = Astro.props; { - iconOnly ? ( + iconOnly ? - ) : ( - - ) } - \ No newline at end of file + diff --git a/src/src/components/SiteHeader.astro b/src/src/components/SiteHeader.astro index eabc3e3..0926790 100644 --- a/src/src/components/SiteHeader.astro +++ b/src/src/components/SiteHeader.astro @@ -6,15 +6,18 @@ import SiteNav from '~/components/SiteNav.astro'; import { SITE } from '~/lib/site'; interface Props { - /** True on documentation pages where the Starlight sidebar provides mobile nav. */ + /** True on documentation pages where Starlight renders its own sidebar toggle + * (for the doc tree). The site-level nav toggle below is independent of that + * and always renders, since it links to top-level sections (Projects, + * Documentation, Releases, About) rather than the current doc's sidebar. */ hasSidebar: boolean; } -const { hasSidebar } = Astro.props; +const { hasSidebar: _hasSidebar } = Astro.props; const currentPath = Astro.url.pathname; --- -
+
-
-
-
- -{ - hasSidebar ? null : ( -
- -
+
- ) -} \ No newline at end of file + + diff --git a/src/src/components/starlight/Search.astro b/src/src/components/starlight/Search.astro index 227b95c..c792f7a 100644 --- a/src/src/components/starlight/Search.astro +++ b/src/src/components/starlight/Search.astro @@ -2,12 +2,12 @@ import project from 'virtual:starlight/project-context'; const pagefindTranslations = { - placeholder: Astro.locals.t('search.label'), - ...Object.fromEntries( - Object.entries(Astro.locals.t.all()) - .filter(([key]) => key.startsWith('pagefind.')) - .map(([key, value]) => [key.replace('pagefind.', ''), value]) - ), + placeholder: Astro.locals.t('search.label'), + ...Object.fromEntries( + Object.entries(Astro.locals.t.all()) + .filter(([key]) => key.startsWith('pagefind.')) + .map(([key, value]) => [key.replace('pagefind.', ''), value]), + ), }; const dataAttributes: DOMStringMap = { 'data-translations': JSON.stringify(pagefindTranslations) }; @@ -15,512 +15,506 @@ if (project.trailingSlash === 'never') dataAttributes['data-strip-trailing-slash --- - - - -
- { - /* Theme-aware close button. The default Starlight button only shows + + + +
+ { + /* Theme-aware close button. The default Starlight button only shows on mobile and can overlap the search input's magnifier icon, so it is replaced here with an in-flow, right-aligned cross shown on every viewport. The accessible name comes from the translations below. */ - } - - { - import.meta.env.DEV ? ( -
-

{Astro.locals.t('search.devWarning')}

-
- ) : ( -
- - ) - } -
-
+ } + + { + import.meta.env.DEV ? +
+

{Astro.locals.t('search.devWarning')}

+
+ :
+ + } +
+
{ - /** - * This is intentionally inlined to avoid briefly showing an invalid shortcut. - * Purposely using the deprecated `navigator.platform` property to detect Apple devices, as the - * user agent is spoofed by some browsers when opening the devtools. - */ + /** + * This is intentionally inlined to avoid briefly showing an invalid shortcut. + * Purposely using the deprecated `navigator.platform` property to detect Apple devices, as the + * user agent is spoofed by some browsers when opening the devtools. + */ } \ No newline at end of file + @import url('@pagefind/default-ui/css/ui.css') layer(starlight.core); + + @layer starlight.core { + [data-search-modal-open] { + overflow: hidden; + } + + #starlight__search { + --sl-search-result-spacing: calc(1.25rem * var(--pagefind-ui-scale)); + --sl-search-result-pad-inline-start: calc(3.75rem * var(--pagefind-ui-scale)); + --sl-search-result-pad-inline-end: calc(1.25rem * var(--pagefind-ui-scale)); + --sl-search-result-pad-block: calc(0.9375rem * var(--pagefind-ui-scale)); + --sl-search-result-nested-pad-block: calc(0.625rem * var(--pagefind-ui-scale)); + --sl-search-corners: calc(0.3125rem * var(--pagefind-ui-scale)); + --sl-search-page-icon-size: calc(1.875rem * var(--pagefind-ui-scale)); + --sl-search-page-icon-inline-start: calc( + (var(--sl-search-result-pad-inline-start) - var(--sl-search-page-icon-size)) / 2 + ); + --sl-search-tree-diagram-size: calc(2.5rem * var(--pagefind-ui-scale)); + --sl-search-tree-diagram-inline-start: calc( + (var(--sl-search-result-pad-inline-start) - var(--sl-search-tree-diagram-size)) / 2 + ); + } + + #starlight__search .pagefind-ui__form::before { + --pagefind-ui-text: var(--sl-color-gray-1); + opacity: 1; + } + + #starlight__search .pagefind-ui__search-input { + color: var(--sl-color-white); + font-weight: 400; + width: calc(100% - var(--sl-search-cancel-space)); + } + + #starlight__search input:focus { + --pagefind-ui-border: var(--sl-color-accent); + } + + #starlight__search .pagefind-ui__search-clear { + inset-inline-end: var(--sl-search-cancel-space); + width: calc(60px * var(--pagefind-ui-scale)); + padding: 0; + background-color: transparent; + overflow: hidden; + } + #starlight__search .pagefind-ui__search-clear:focus { + outline: 1px solid var(--sl-color-accent); + } + #starlight__search .pagefind-ui__search-clear::before { + content: ''; + -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='m13.41 12 6.3-6.29a1 1 0 1 0-1.42-1.42L12 10.59l-6.29-6.3a1 1 0 0 0-1.42 1.42l6.3 6.29-6.3 6.29a1 1 0 0 0 .33 1.64 1 1 0 0 0 1.09-.22l6.29-6.3 6.29 6.3a1 1 0 0 0 1.64-.33 1 1 0 0 0-.22-1.09L13.41 12Z'/%3E%3C/svg%3E") + center / 50% no-repeat; + mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='m13.41 12 6.3-6.29a1 1 0 1 0-1.42-1.42L12 10.59l-6.29-6.3a1 1 0 0 0-1.42 1.42l6.3 6.29-6.3 6.29a1 1 0 0 0 .33 1.64 1 1 0 0 0 1.09-.22l6.29-6.3 6.29 6.3a1 1 0 0 0 1.64-.33 1 1 0 0 0-.22-1.09L13.41 12Z'/%3E%3C/svg%3E") + center / 50% no-repeat; + background-color: var(--sl-color-text-accent); + display: block; + width: 100%; + height: 100%; + } + + #starlight__search .pagefind-ui__results > * + * { + margin-top: var(--sl-search-result-spacing); + } + #starlight__search .pagefind-ui__result { + border: 0; + padding: 0; + } + + #starlight__search .pagefind-ui__result-nested { + position: relative; + padding: var(--sl-search-result-nested-pad-block) var(--sl-search-result-pad-inline-end); + padding-inline-start: var(--sl-search-result-pad-inline-start); + } + + #starlight__search .pagefind-ui__result-title:not(:where(.pagefind-ui__result-nested *)), + #starlight__search .pagefind-ui__result-nested { + position: relative; + background-color: var(--sl-color-black); + } + + #starlight__search .pagefind-ui__result-title:not(:where(.pagefind-ui__result-nested *)):hover, + #starlight__search + .pagefind-ui__result-title:not(:where(.pagefind-ui__result-nested *)):focus-within, + #starlight__search .pagefind-ui__result-nested:hover, + #starlight__search .pagefind-ui__result-nested:focus-within { + outline: 1px solid var(--sl-color-accent-high); + } + + #starlight__search + .pagefind-ui__result-title:not(:where(.pagefind-ui__result-nested *)):focus-within, + #starlight__search .pagefind-ui__result-nested:focus-within { + background-color: var(--sl-color-accent-low); + } + + #starlight__search .pagefind-ui__result-thumb, + #starlight__search .pagefind-ui__result-inner { + margin-top: 0; + } + + #starlight__search .pagefind-ui__result-inner > :first-child { + border-radius: var(--sl-search-corners) var(--sl-search-corners) 0 0; + } + #starlight__search .pagefind-ui__result-inner > :last-child { + border-radius: 0 0 var(--sl-search-corners) var(--sl-search-corners); + } + + #starlight__search .pagefind-ui__result-inner > .pagefind-ui__result-title { + padding: var(--sl-search-result-pad-block) var(--sl-search-result-pad-inline-end); + padding-inline-start: var(--sl-search-result-pad-inline-start); + } + #starlight__search .pagefind-ui__result-inner > .pagefind-ui__result-title::before { + content: ''; + position: absolute; + inset-block: 0; + inset-inline-start: var(--sl-search-page-icon-inline-start); + width: var(--sl-search-page-icon-size); + background: var(--sl-color-gray-3); + -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='currentColor' viewBox='0 0 24 24'%3E%3Cpath d='M9 10h1a1 1 0 1 0 0-2H9a1 1 0 0 0 0 2Zm0 2a1 1 0 0 0 0 2h6a1 1 0 0 0 0-2H9Zm11-3V8l-6-6a1 1 0 0 0-1 0H7a3 3 0 0 0-3 3v14a3 3 0 0 0 3 3h10a3 3 0 0 0 3-3V9Zm-6-4 3 3h-2a1 1 0 0 1-1-1V5Zm4 14a1 1 0 0 1-1 1H7a1 1 0 0 1-1-1V5a1 1 0 0 1 1-1h5v3a3 3 0 0 0 3 3h3v9Zm-3-3H9a1 1 0 0 0 0 2h6a1 1 0 0 0 0-2Z'/%3E%3C/svg%3E") + center no-repeat; + mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='currentColor' viewBox='0 0 24 24'%3E%3Cpath d='M9 10h1a1 1 0 1 0 0-2H9a1 1 0 0 0 0 2Zm0 2a1 1 0 0 0 0 2h6a1 1 0 0 0 0-2H9Zm11-3V8l-6-6a1 1 0 0 0-1 0H7a3 3 0 0 0-3 3v14a3 3 0 0 0 3 3h10a3 3 0 0 0 3-3V9Zm-6-4 3 3h-2a1 1 0 0 1-1-1V5Zm4 14a1 1 0 0 1-1 1H7a1 1 0 0 1-1-1V5a1 1 0 0 1 1-1h5v3a3 3 0 0 0 3 3h3v9Zm-3-3H9a1 1 0 0 0 0 2h6a1 1 0 0 0 0-2Z'/%3E%3C/svg%3E") + center no-repeat; + } + + #starlight__search .pagefind-ui__result-inner { + align-items: stretch; + gap: 1px; + } + + #starlight__search .pagefind-ui__result-link { + position: unset; + --pagefind-ui-text: var(--sl-color-white); + font-weight: 600; + } + + #starlight__search .pagefind-ui__result-link:hover { + text-decoration: none; + } + + #starlight__search .pagefind-ui__result-nested .pagefind-ui__result-link::before { + content: unset; + } + + #starlight__search .pagefind-ui__result-nested::before { + content: ''; + position: absolute; + inset-block: 0; + inset-inline-start: var(--sl-search-tree-diagram-inline-start); + width: var(--sl-search-tree-diagram-size); + background: var(--sl-color-gray-4); + -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='none' stroke='currentColor' stroke-linecap='round' viewBox='0 0 16 1000' preserveAspectRatio='xMinYMin slice'%3E%3Cpath d='M8 0v1000m6-988H8'/%3E%3C/svg%3E") + 0% 0% / 100% no-repeat; + mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='none' stroke='currentColor' stroke-linecap='round' viewBox='0 0 16 1000' preserveAspectRatio='xMinYMin slice'%3E%3Cpath d='M8 0v1000m6-988H8'/%3E%3C/svg%3E") + 0% 0% / 100% no-repeat; + } + #starlight__search .pagefind-ui__result-nested:last-of-type::before { + -webkit-mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='none' stroke='currentColor' stroke-linecap='round' stroke-linejoin='round' viewBox='0 0 16 16'%3E%3Cpath d='M8 0v12m6 0H8'/%3E%3C/svg%3E"); + mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='none' stroke='currentColor' stroke-linecap='round' stroke-linejoin='round' viewBox='0 0 16 16'%3E%3Cpath d='M8 0v12m6 0H8'/%3E%3C/svg%3E"); + } + + /* Flip page and tree icons around the vertical axis when in an RTL layout. */ + [dir='rtl'] .pagefind-ui__result-title::before, + [dir='rtl'] .pagefind-ui__result-nested::before { + transform: matrix(-1, 0, 0, 1, 0, 0); + } + + #starlight__search .pagefind-ui__result-link::after { + content: ''; + position: absolute; + inset: 0; + } + + #starlight__search .pagefind-ui__result-excerpt { + font-size: calc(1rem * var(--pagefind-ui-scale)); + overflow-wrap: anywhere; + } + + #starlight__search mark { + color: var(--sl-color-gray-2); + background-color: transparent; + font-weight: 600; + } + + #starlight__search .pagefind-ui__filter-value::before { + border-color: var(--sl-color-text-invert); + } + + #starlight__search .pagefind-ui__result-tags { + background-color: var(--sl-color-black); + margin-top: 0; + padding: var(--sl-search-result-nested-pad-block) var(--sl-search-result-pad-inline-end); + } + } + diff --git a/src/src/styles/global.css b/src/src/styles/global.css index 67f1c2f..0535b04 100644 --- a/src/src/styles/global.css +++ b/src/src/styles/global.css @@ -111,8 +111,20 @@ color-scheme: dark; } + /* Tailwind's preflight (which normally sets this) isn't imported — see note + * below — but every width/padding utility here assumes border-box sizing, + * so without this reset elements with both `width` and `padding-inline` + * (e.g. `.pv-container`) overflow their parent and cause horizontal + * scrolling on narrow viewports. */ + *, + *::before, + *::after { + box-sizing: border-box; + } + html { scroll-behavior: smooth; + overflow-x: hidden; } @media (prefers-reduced-motion: reduce) { @@ -138,6 +150,7 @@ body { background-color: var(--color-background); color: var(--color-foreground); + overflow-x: clip; } /* Tailwind preflight is intentionally not imported (Starlight owns the base