Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions astro.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ export default defineConfig({
],
sidebar: sidebar(),
components: {
Header: "./src/components/overrides/Header.astro",
SiteTitle: "./src/components/overrides/SiteTitle.astro",
SocialIcons: "./src/components/overrides/SocialIcons.astro",
Footer: "./src/components/overrides/Footer.astro",
Expand Down
94 changes: 94 additions & 0 deletions src/components/overrides/Header.astro
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
---
// Starlight's header with Go to console, as on the landing page's nav: the one thing in the
// bar that looks pressable. From 50rem it sits between the links and the theme switch; below
// that Starlight moves the links and the switch into the menu, and the button stays in the
// bar beside search, so it is there at every width. Below 500px the wordmark is read out but
// not shown (SiteTitle), which leaves room for it on a 320px phone.
import LanguageSelect from "@astrojs/starlight/components/LanguageSelect.astro";
import Search from "@astrojs/starlight/components/Search.astro";
import ThemeSelect from "@astrojs/starlight/components/ThemeSelect.astro";
import { CONSOLE_URL } from "../../lib/site";
import Button from "../Button.astro";
import SiteTitle from "./SiteTitle.astro";
import SocialIcons from "./SocialIcons.astro";
---

<div class="header">
<div class="title-wrapper sl-flex">
<SiteTitle />
</div>
<div class="sl-flex print:hidden search-wrapper">
<Search />
<Button href={CONSOLE_URL} size="sm" class="sw-console sw-console--bar">Go to console</Button>
</div>
<div class="sl-hidden md:sl-flex print:hidden right-group">
<div class="sl-flex social-icons">
<SocialIcons />
</div>
<Button href={CONSOLE_URL} size="sm" class="sw-console">Go to console</Button>
<ThemeSelect />
<LanguageSelect />
</div>
</div>

<style>
.header {
display: flex;
gap: var(--sl-nav-gap);
justify-content: space-between;
align-items: center;
height: 100%;
}
.title-wrapper {
overflow: clip;
padding: 0.25rem;
margin: -0.25rem;
min-width: 0;
}
.search-wrapper {
align-items: center;
gap: var(--space-2);
}
.right-group,
.social-icons {
gap: var(--space-2);
align-items: center;
}
.right-group {
gap: var(--space-3);
}
.sw-console {
white-space: nowrap;
}
/* The copy in the bar is for a phone; from 50rem the one in the right group shows. */
@media (min-width: 50rem) {
.sw-console--bar {
display: none;
}
:global(:root[data-has-sidebar]) {
--__sidebar-pad: calc(2 * var(--sl-nav-pad-x));
}
:global(:root:not([data-has-toc])) {
--__toc-width: 0rem;
}
.header {
--__sidebar-width: max(0rem, var(--sl-content-inline-start, 0rem) - var(--sl-nav-pad-x));
--__main-column-fr: calc(
(
100% + var(--__sidebar-pad, 0rem) - var(--__toc-width, var(--sl-sidebar-width)) -
(2 * var(--__toc-width, var(--sl-nav-pad-x))) - var(--sl-content-inline-start, 0rem) -
var(--sl-content-width)
) / 2
);
display: grid;
grid-template-columns:
minmax(
calc(var(--__sidebar-width) + max(0rem, var(--__main-column-fr) - var(--sl-nav-gap))),
auto
)
1fr
auto;
align-content: center;
}
}
</style>
11 changes: 11 additions & 0 deletions src/components/overrides/SiteTitle.astro
Original file line number Diff line number Diff line change
Expand Up @@ -53,4 +53,15 @@ const { siteTitleHref } = Astro.locals.starlightRoute;
font-weight: 800;
letter-spacing: -0.02em;
}
/* Read out but not shown below 500px, as on the landing page, so Go to console fits. */
@media (max-width: 499.98px) {
.sw-site-title__word {
position: absolute;
width: 1px;
height: 1px;
overflow: hidden;
clip-path: inset(50%);
white-space: nowrap;
}
}
</style>
47 changes: 32 additions & 15 deletions src/components/overrides/SocialIcons.astro
Original file line number Diff line number Diff line change
@@ -1,22 +1,20 @@
---
// Text links in place of Starlight's icon row, drawn as the design system's nav links.
// In place of Starlight's icon row: the landing page as a nav link, then GitHub as a small
// quiet icon. It has no outline and no shadow, so Go to console (Header) stays the one thing
// in the bar that looks pressable; the focus ring is the global one. The mark is Octicons'
// mark-github-16 (@primer/octicons 19.38.0), as the design system asks of a true icon.
import { LANDING_URL } from "../../lib/site";
import { DOCS_REPO_URL, REPO_URL } from "../../lib/source";

const links = [
{ label: "Sluiceway", title: "The Sluiceway home page", href: LANDING_URL },
{ label: "GitHub", title: "Sluiceway on GitHub", href: REPO_URL },
{ label: "Docs repo", title: "The source of this site on GitHub", href: DOCS_REPO_URL },
];
import { REPO_URL } from "../../lib/source";
---

{
links.map(({ label, title, href }) => (
<a class="sw-navlink" {href} {title}>
{label}
</a>
))
}
<a class="sw-navlink" href={LANDING_URL} title="The Sluiceway home page">Sluiceway</a>
<a class="sw-icon-link" href={REPO_URL} aria-label="Sluiceway on GitHub">
<svg aria-hidden="true" viewBox="0 0 16 16" width="18" height="18" fill="currentColor">
<path
d="M6.766 11.328c-2.063-.25-3.516-1.734-3.516-3.656 0-.781.281-1.625.75-2.188-.203-.515-.172-1.609.063-2.062.625-.078 1.468.25 1.968.703.594-.187 1.219-.281 1.985-.281.765 0 1.39.094 1.953.265.484-.437 1.344-.765 1.969-.687.218.422.25 1.515.046 2.047.5.593.766 1.39.766 2.203 0 1.922-1.453 3.375-3.547 3.64.531.344.89 1.094.89 1.954v1.625c0 .468.391.734.86.547C13.781 14.359 16 11.53 16 8.03 16 3.61 12.406 0 7.984 0 3.563 0 0 3.61 0 8.031a7.88 7.88 0 0 0 5.172 7.422c.422.156.828-.125.828-.547v-1.25c-.219.094-.5.156-.75.156-1.031 0-1.64-.562-2.078-1.609-.172-.422-.36-.672-.719-.719-.187-.015-.25-.093-.25-.187 0-.188.313-.328.625-.328.453 0 .844.281 1.25.86.313.452.64.655 1.031.655s.641-.14 1-.5c.266-.265.47-.5.657-.656"
></path>
</svg>
</a>

<style>
.sw-navlink {
Expand All @@ -35,4 +33,23 @@ const links = [
border-color: var(--line);
background: var(--surface-sunk);
}
.sw-icon-link {
display: grid;
place-items: center;
width: 36px;
height: 36px;
border-radius: var(--radius-crate);
color: var(--ink-muted);
}
.sw-icon-link:hover {
background: var(--surface-sunk);
color: var(--ink);
}
/* A full 44px touch target on a phone. */
@media (pointer: coarse) {
.sw-icon-link {
width: 44px;
height: 44px;
}
}
</style>
3 changes: 3 additions & 0 deletions src/lib/site.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,6 @@ export const UNLISTED = ["404", "style-check"];

/** The landing page, which the header and footer link to as "Sluiceway". */
export const LANDING_URL = "https://sluiceway.dev/";

/** The hosted app, where a person signs in with GitHub. The header's one button goes there. */
export const CONSOLE_URL = "https://console.sluiceway.dev";
59 changes: 43 additions & 16 deletions src/styles/theme.css
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,9 @@
--sl-line-height-headings: 1.18;

--sl-nav-height: 4rem;
/* The phone menu button's 44px touch target, so Starlight centres it in the bar and keeps
the header clear of it. */
--sl-menu-button-size: 44px;
/* `ch` is the width of Inter's "0", about 1.33 average characters: 54ch holds a line of
about 72 characters, the measure 30-pages.md asks for. */
--sl-content-width: 54ch;
Expand Down Expand Up @@ -93,24 +96,31 @@ starlight-theme-select select:focus-visible,
header.header {
border-bottom: var(--border-ink) solid var(--line);
}
/* The phone menu button, drawn like every other control: a crate, not a circle, and a full
44px touch target. */
/* The phone menu button, drawn as the landing page's Menu: a crate, not a circle, outlined
but without a shadow, so Go to console stays the one thing in the bar that looks pressable.
A full 44px touch target. */
button.sl-menu-button {
width: 44px;
height: 44px;
align-items: center;
justify-content: center;
border: var(--border-ink) solid var(--line);
border-radius: var(--radius-crate);
background: var(--surface);
color: var(--ink);
box-shadow: var(--shadow-press);
box-shadow: none;
}
.header .right-group,
.header .social-icons {
gap: var(--space-2);
button.sl-menu-button:hover {
background: var(--surface-sunk);
}
/* The header draws no rule between the links and the rest, as the landing page's nav. */
.header .social-icons::after {
border-inline-end: var(--border-ink) solid var(--line-soft);
margin-inline-start: var(--space-2);
content: none;
}
/* The phone menu's last row: the links and the theme switch on one line. */
.mobile-preferences {
align-items: center;
}
.mobile-preferences .social-icons {
gap: var(--space-2);
}

/* The `label` style: the theme switch, "On this page" and table headers. */
Expand All @@ -125,15 +135,18 @@ starlight-theme-select select,
text-transform: uppercase;
}

/* The theme switch, drawn as the landing page's theme button. */
/* The theme switch, quiet as the landing page's: no outline and no shadow, in `ink-muted`. */
starlight-theme-select select {
color: var(--ink);
background-color: var(--surface);
border: var(--border-ink) solid var(--line);
color: var(--ink-muted);
background-color: transparent;
border: 0;
border-radius: var(--radius-crate);
box-shadow: var(--shadow-press);
padding-block: var(--space-2);
}
starlight-theme-select select:hover {
background-color: var(--surface-sunk);
color: var(--ink);
}
starlight-theme-select select {
/* Room for the uppercase, letter-spaced label beside the icon and caret. */
width: 9em;
Expand All @@ -145,7 +158,8 @@ site-search > button[data-open-modal] {
border-radius: var(--radius-crate);
background: var(--surface);
color: var(--ink-muted);
box-shadow: var(--shadow-press);
/* Outlined as a field, without a shadow: Go to console is the pressable thing. */
box-shadow: none;
}
site-search > button[data-open-modal]:hover {
border-color: var(--line);
Expand All @@ -165,6 +179,19 @@ site-search > button[data-open-modal]:focus-visible {
justify-content: center;
}
}
/* Between 50rem and 60rem the links, Go to console and the theme switch take the room the
search box had, so search is the icon it is on a phone. */
@media (min-width: 50rem) and (max-width: 60rem) {
site-search > button[data-open-modal] {
min-width: 44px;
min-height: 44px;
justify-content: center;
}
site-search > button[data-open-modal] > :is(span, kbd) {
/* biome-ignore lint/complexity/noImportantStyles: Starlight's script sets the shortcut's display inline. */
display: none !important;
}
}
site-search > button[data-open-modal] kbd {
background: var(--surface-sunk);
color: var(--ink);
Expand Down
Loading