Replace plain page headings with a terminal-style, PageHeader component

This commit is contained in:
badblocks 2026-07-20 12:10:04 -07:00
parent c959f0d848
commit 5d5fb93647
Signed by: badblocks
SSH key fingerprint: SHA256:hEcM6BP4hKm9F7WsomNuXSBpPn2BSDnFzPSl3y1NerQ
4 changed files with 74 additions and 9 deletions

View file

@ -0,0 +1,64 @@
---
interface Props {
/** Shell-style path shown as the heading, e.g. "~/projects" */
path: string;
/** Command echoed under the heading, without the "$ " prompt */
command?: string;
/** Heading level; pages with their own <h1> elsewhere should stay at 2 */
level?: 1 | 2;
}
const { path, command, level = 2 } = Astro.props;
const Heading = level === 1 ? "h1" : "h2";
---
<style>
.page-header {
margin-block-end: var(--stack-large);
}
.listing-line {
color: var(--color-mg);
font-size: var(--pt-small-pica);
}
.prompt-cursor {
margin-inline-start: 0.667em;
animation: blink 1.2s steps(1) infinite;
color: var(--color-accent);
}
@keyframes blink {
50% {
opacity: 0;
}
}
:root[data-reduce-motion="on"] .prompt-cursor {
animation: none;
}
@media (prefers-reduced-motion: reduce) {
:root:not([data-reduce-motion="off"]) .prompt-cursor {
animation: none;
}
}
:root[data-more-contrast="on"] .listing-line {
color: var(--color-fg);
}
@media (prefers-contrast: more) {
:root:not([data-more-contrast="off"]) .listing-line {
color: var(--color-fg);
}
}
</style>
<hgroup class="page-header">
<Heading>
{path}
<span class="prompt-cursor" aria-hidden="true">█</span>
</Heading>
{
command && (
<p class="listing-line" aria-hidden="true">
$ {command}
</p>
)
}
</hgroup>

View file

@ -1,5 +1,6 @@
---
import Layout from "@layouts/BaseLayout.astro";
import PageHeader from "@components/PageHeader.astro";
import { actions, isInputError } from "astro:actions";
export const prerender = false;
@ -147,7 +148,7 @@ const msgValue = pickValue("msg") || (await Astro.session?.get("msg"));
</style>
</Fragment>
<Fragment slot="main">
<h2>Contact</h2>
<PageHeader path="~/contact" command="mail badblocks" />
{
(nextAction != "complete" && (
<form method="post" x-data="{}" action={actions.contact.submitForm}>

View file

@ -1,5 +1,6 @@
---
import Layout from "@layouts/BaseLayout.astro";
import PageHeader from "@components/PageHeader.astro";
import fs from "node:fs";
const txtToHtml = (string: string) => {
@ -23,13 +24,11 @@ const license_file_contents = txtToHtml(
<Layout>
<title slot="head">LICENSE | badblocks.dev</title>
<Fragment slot="main">
<header>
<h1>
<a href="https://opensource.org/license/mit" target="_blank"
>MIT License</a
<PageHeader path="~/license" command="cat LICENSE" level={1} />
<p>
<a href="https://opensource.org/license/mit" target="_blank">MIT License</a
>
</h1>
</header>
</p>
<div style="font-size: medium;" set:html={license_file_contents} />
</Fragment>
</Layout>

View file

@ -1,5 +1,6 @@
---
import Layout from "@layouts/BaseLayout.astro";
import PageHeader from "@components/PageHeader.astro";
---
<Layout>
@ -15,7 +16,7 @@ import Layout from "@layouts/BaseLayout.astro";
</style>
<Fragment slot="main">
<section class="tools" id="tools">
<h2>Tools</h2>
<PageHeader path="~/tools" command="ls" />
<div class="tools-grid">
<div class="tool-card">Tool 1</div>
<div class="tool-card">Tool 2</div>