mirror of
https://github.com/Patiun/com.gregkilmer.www.git
synced 2026-11-08 04:08:24 +00:00
Match the site to the approved designs
Denser star field, the page nebula, a favicon package, the filament banner without its box, the About portrait, Kashi and tea photos and Scorpius, the Store's own header, a header logo glow, a resume PDF that fills its page, one divider on the Library and Shelf, star-chart art for coverless favorites, Shelf Players, Play time and blog filters with a Show all fold, make kind pills on craft pages, and full-width closing bands. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_012aSbo2D1qP8cMFQCykf7kx
This commit is contained in:
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="#F4F2ED" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round" role="img" aria-label="Download"><path d="M12 4v11M7 10.5l5 5 5-5M5 19.5h14"/></svg>
|
||||
|
After Width: | Height: | Size: 239 B |
File diff suppressed because one or more lines are too long
|
Before Width: | Height: | Size: 25 KiB After Width: | Height: | Size: 25 KiB |
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1100 400"><line x1="565.0" y1="34.9" x2="578.5" y2="43.6" stroke="#2BC2B7" stroke-width="1.2" opacity="0.8" stroke-linecap="round"/><line x1="591.7" y1="55.4" x2="605.3" y2="72.1" stroke="#2BC2B7" stroke-width="1.2" opacity="0.8" stroke-dasharray="2 5" stroke-linecap="round"/><line x1="582.8" y1="56.8" x2="567.6" y2="96.5" stroke="#2BC2B7" stroke-width="1.2" opacity="0.8" stroke-linecap="round"/><line x1="559.7" y1="112.7" x2="557.7" y2="116.1" stroke="#2BC2B7" stroke-width="1.2" opacity="0.8" stroke-linecap="round"/><line x1="552.6" y1="132.8" x2="552.2" y2="140.5" stroke="#2BC2B7" stroke-width="1.2" opacity="0.8" stroke-linecap="round"/><line x1="553.1" y1="158.4" x2="561.7" y2="216.6" stroke="#2BC2B7" stroke-width="1.2" opacity="0.8" stroke-linecap="round"/><line x1="567.7" y1="233.2" x2="580.0" y2="253.6" stroke="#2BC2B7" stroke-width="1.2" opacity="0.8" stroke-linecap="round"/><line x1="588.7" y1="269.4" x2="603.1" y2="298.0" stroke="#2BC2B7" stroke-width="1.2" opacity="0.8" stroke-linecap="round"/><line x1="601.1" y1="312.7" x2="584.4" y2="330.7" stroke="#2BC2B7" stroke-width="1.2" opacity="0.8" stroke-linecap="round"/><line x1="570.7" y1="342.2" x2="535.2" y2="365.1" stroke="#2BC2B7" stroke-width="1.2" opacity="0.8" stroke-linecap="round"/><line x1="519.1" y1="367.2" x2="497.5" y2="360.0" stroke="#2BC2B7" stroke-width="1.2" opacity="0.8" stroke-linecap="round"/><line x1="490.2" y1="348.3" x2="490.0" y2="349.4" stroke="#2BC2B7" stroke-width="1.2" opacity="0.8" stroke-linecap="round"/><line x1="492.8" y1="331.6" x2="495.0" y2="319.5" stroke="#2BC2B7" stroke-width="1.2" opacity="0.8" stroke-dasharray="2 5" stroke-linecap="round"/><line x1="505.2" y1="307.9" x2="495.2" y2="311.0" stroke="#2BC2B7" stroke-width="1.2" opacity="0.8" stroke-linecap="round"/><polygon points="557.4,23.0 558.5,28.9 564.4,30.0 558.5,31.1 557.4,37.0 556.3,31.1 550.4,30.0 556.3,28.9" fill="#9A70F5"/><polygon points="586.1,41.4 587.2,47.3 593.1,48.4 587.2,49.6 586.1,55.4 584.9,49.6 579.1,48.4 584.9,47.3" fill="#9A70F5"/><circle cx="611.0" cy="79.1" r="2.4" fill="#F4F2ED"/><circle cx="564.3" cy="104.9" r="2.4" fill="#F4F2ED"/><polygon points="553.1,110.8 555.2,121.7 566.1,123.8 555.2,125.9 553.1,136.8 551.0,125.9 540.1,123.8 551.0,121.7" fill="#C9A24A"/><circle cx="551.8" cy="149.5" r="2.4" fill="#F4F2ED"/><polygon points="563.0,218.5 564.2,224.4 570.0,225.5 564.2,226.7 563.0,232.5 561.9,226.7 556.0,225.5 561.9,224.4" fill="#9A70F5"/><circle cx="584.6" cy="261.3" r="2.4" fill="#F4F2ED"/><circle cx="607.2" cy="306.1" r="2.4" fill="#F4F2ED"/><circle cx="578.3" cy="337.3" r="2.4" fill="#F4F2ED"/><polygon points="527.7,363.0 528.8,368.9 534.7,370.0 528.8,371.1 527.7,377.0 526.6,371.1 520.7,370.0 526.6,368.9" fill="#9A70F5"/><circle cx="489.0" cy="357.2" r="2.4" fill="#F4F2ED"/><circle cx="491.3" cy="340.5" r="2.4" fill="#F4F2ED"/><circle cx="503.8" cy="308.3" r="2.4" fill="#F4F2ED"/><polygon points="496.6,303.6 497.7,309.5 503.6,310.6 497.7,311.7 496.6,317.6 495.5,311.7 489.6,310.6 495.5,309.5" fill="#9A70F5"/></svg>
|
||||
|
After Width: | Height: | Size: 3.0 KiB |
File diff suppressed because one or more lines are too long
|
Before Width: | Height: | Size: 30 KiB After Width: | Height: | Size: 29 KiB |
@@ -1,14 +1,21 @@
|
||||
---
|
||||
/** Sparse, static specks behind a page; about one in five gold. */
|
||||
/**
|
||||
* Static specks behind a page; about one in five gold. Two tiles of different
|
||||
* sizes repeat across the page, so long pages are as starry as short ones and
|
||||
* the repeat is hard to spot.
|
||||
*/
|
||||
import { dust, seedOf } from "../lib/ornaments.ts";
|
||||
|
||||
interface Props {
|
||||
count?: number;
|
||||
seed?: string;
|
||||
}
|
||||
const { count = 48, seed = Astro.url.pathname } = Astro.props;
|
||||
const { seed = Astro.url.pathname } = Astro.props;
|
||||
const base = seedOf(seed);
|
||||
---
|
||||
<div class="gk-dust" aria-hidden="true" style={`background:${dust(count, seedOf(seed))}`}></div>
|
||||
<div class="gk-dust" aria-hidden="true">
|
||||
<div class="layer near" style={`background-image:${dust(26, base)}`}></div>
|
||||
<div class="layer far" style={`background-image:${dust(30, base + 7919)}`}></div>
|
||||
</div>
|
||||
|
||||
<style>
|
||||
.gk-dust {
|
||||
@@ -16,4 +23,16 @@ const { count = 48, seed = Astro.url.pathname } = Astro.props;
|
||||
inset: 0;
|
||||
pointer-events: none;
|
||||
}
|
||||
.layer {
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
background-repeat: repeat;
|
||||
}
|
||||
.near {
|
||||
background-size: 520px 520px;
|
||||
}
|
||||
.far {
|
||||
background-size: 790px 790px;
|
||||
background-position: 213px 157px;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -12,7 +12,7 @@ import ConstellationDust from "./ConstellationDust.astro";
|
||||
import EdgeSeals from "./EdgeSeals.astro";
|
||||
import SiteFooter from "./SiteFooter.astro";
|
||||
import SiteHeader from "./SiteHeader.astro";
|
||||
import type { NavKey } from "./nav.ts";
|
||||
import type { NavKey, StoreNav } from "./nav.ts";
|
||||
import type { PageFamily, SealName } from "./seals.ts";
|
||||
|
||||
interface Props {
|
||||
@@ -22,10 +22,12 @@ interface Props {
|
||||
/** A craft page's own seal, overriding the family's. */
|
||||
seal?: SealName;
|
||||
current?: NavKey;
|
||||
/** The Store's own header, on Store pages. */
|
||||
store?: StoreNav;
|
||||
/** Leave the edge seals off, for a page led by a photo. */
|
||||
noSeals?: boolean;
|
||||
}
|
||||
const { title, description, family = "landing", seal, current, noSeals } = Astro.props;
|
||||
const { title, description, family = "landing", seal, current, store, noSeals } = Astro.props;
|
||||
const fullTitle = title === "Greg Kilmer" ? title : `${title} · Greg Kilmer`;
|
||||
---
|
||||
<!doctype html>
|
||||
@@ -35,6 +37,10 @@ const fullTitle = title === "Greg Kilmer" ? title : `${title} · Greg Kilmer`;
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
<meta name="color-scheme" content="dark" />
|
||||
<meta name="theme-color" content="#0E1522" />
|
||||
<link rel="icon" href="/favicon.ico" sizes="48x48" />
|
||||
<link rel="icon" href="/favicon.svg" type="image/svg+xml" />
|
||||
<link rel="apple-touch-icon" href="/apple-touch-icon.png" />
|
||||
<link rel="manifest" href="/site.webmanifest" />
|
||||
<title>{fullTitle}</title>
|
||||
{description && <meta name="description" content={description} />}
|
||||
<slot name="head" />
|
||||
@@ -44,7 +50,7 @@ const fullTitle = title === "Greg Kilmer" ? title : `${title} · Greg Kilmer`;
|
||||
<div class="gk-page">
|
||||
<ConstellationDust />
|
||||
{!noSeals && <EdgeSeals family={family} seal={seal} />}
|
||||
<SiteHeader current={current}><slot name="hero" /></SiteHeader>
|
||||
<SiteHeader current={current} store={store} hero={Astro.slots.has("hero")}><slot name="hero" /></SiteHeader>
|
||||
<main id="main" class="gk-wrap gk-main">
|
||||
<slot />
|
||||
</main>
|
||||
@@ -58,6 +64,11 @@ const fullTitle = title === "Greg Kilmer" ? title : `${title} · Greg Kilmer`;
|
||||
position: relative;
|
||||
min-height: 100vh;
|
||||
overflow-x: clip;
|
||||
/* The page's nebula: violet from the top right, teal from the bottom left. */
|
||||
background:
|
||||
radial-gradient(ellipse at 100% 0%, rgba(106, 47, 224, 0.28), transparent 50%),
|
||||
radial-gradient(ellipse at 0% 100%, rgba(20, 163, 154, 0.2), transparent 55%),
|
||||
var(--gk-sky);
|
||||
}
|
||||
.gk-main {
|
||||
position: relative;
|
||||
|
||||
@@ -2,65 +2,89 @@
|
||||
/**
|
||||
* The site header: nebula and filament banner behind the primary nav, an
|
||||
* optional page hero (the `hero` slot), and the header divider. The filament
|
||||
* banner and divider appear here only, never elsewhere on a page.
|
||||
* banner and divider appear here only, never elsewhere on a page. Store pages
|
||||
* pass `store` and get the Store's own header: Store.GregKilmer.com, its
|
||||
* product lines, Order request and a way back to the main site.
|
||||
*/
|
||||
import monogram from "../assets/brand/gk-monogram.svg?url";
|
||||
import Divider from "./Divider.astro";
|
||||
import Star from "./Star.astro";
|
||||
import { main, tail, world, type NavKey } from "./nav.ts";
|
||||
import { main, tail, world, type NavKey, type StoreNav } from "./nav.ts";
|
||||
import { filamentBanner } from "./seals.ts";
|
||||
|
||||
interface Props {
|
||||
/** Which nav entry the page belongs to. */
|
||||
current?: NavKey;
|
||||
store?: StoreNav;
|
||||
/** Whether the page has a hero; PageShell always fills the slot, so it says. */
|
||||
hero?: boolean;
|
||||
}
|
||||
const { current } = Astro.props;
|
||||
const { current, store, hero = Astro.slots.has("default") } = Astro.props;
|
||||
const inWorld = world.some((w) => w.key === current);
|
||||
const aria = (key: NavKey) => (key === current ? "page" : undefined);
|
||||
---
|
||||
<header class="gk-site-header">
|
||||
<div class="nebula" aria-hidden="true"></div>
|
||||
<img src={filamentBanner} alt="" aria-hidden="true" class="banner" />
|
||||
<nav aria-label="Primary" class="nav">
|
||||
<a href="/" class="brand" aria-current={aria("home")}>
|
||||
<img src={monogram} alt="" width="72" height="72" class="mono" />
|
||||
<span class="words">
|
||||
<span class="name">GREG KILMER</span>
|
||||
<span class="tag">DEVELOPER<Star size={8} tone="teal" />MAKER<Star size={8} tone="teal" />STORYTELLER</span>
|
||||
</span>
|
||||
</a>
|
||||
<ul class="links">
|
||||
{main.map((l) => <li><a href={l.href} aria-current={aria(l.key)}>{l.label}</a></li>)}
|
||||
<li class="sep" aria-hidden="true"><Star size={12} /></li>
|
||||
<li class="mw">
|
||||
<a href="/library" class="mw-top" aria-haspopup="true" aria-current={inWorld ? "true" : undefined}>
|
||||
My world
|
||||
<svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" aria-hidden="true"><path d="M6 9l6 6 6-6" /></svg>
|
||||
</a>
|
||||
<ul class="mw-menu">
|
||||
{
|
||||
world.map((w) => (
|
||||
<li>
|
||||
<a href={w.href} aria-current={aria(w.key)}>
|
||||
<span class="mw-name">{w.label}</span>
|
||||
<span class="mw-blurb">{w.blurb}</span>
|
||||
</a>
|
||||
</li>
|
||||
))
|
||||
}
|
||||
</ul>
|
||||
</li>
|
||||
{tail.map((l) => <li><a href={l.href} aria-current={aria(l.key)} class="dim">{l.label}</a></li>)}
|
||||
</ul>
|
||||
</nav>
|
||||
{
|
||||
Astro.slots.has("default") && (
|
||||
store ? (
|
||||
<nav aria-label="Store" class="nav">
|
||||
<a href="/store" class="brand" aria-current={store.current === "/store" ? "page" : undefined}>
|
||||
<img src={monogram} alt="" width="72" height="72" class="mono" />
|
||||
<span class="words">
|
||||
<span class="name store-name">Store.GregKilmer.com</span>
|
||||
<span class="store-tag">a Patiun LLC workshop</span>
|
||||
</span>
|
||||
</a>
|
||||
<ul class="links">
|
||||
{store.links.map((l) => <li><a href={l.href} aria-current={l.href === store.current ? "page" : undefined}>{l.label}</a></li>)}
|
||||
<li class="sep" aria-hidden="true"><Star size={12} /></li>
|
||||
<li><a href="/" class="dim">Back to GregKilmer.com</a></li>
|
||||
</ul>
|
||||
</nav>
|
||||
) : (
|
||||
<nav aria-label="Primary" class="nav">
|
||||
<a href="/" class="brand" aria-current={aria("home")}>
|
||||
<img src={monogram} alt="" width="72" height="72" class="mono" />
|
||||
<span class="words">
|
||||
<span class="name">GREG KILMER</span>
|
||||
<span class="tag">DEVELOPER<Star size={8} tone="teal" />MAKER<Star size={8} tone="teal" />STORYTELLER</span>
|
||||
</span>
|
||||
</a>
|
||||
<ul class="links">
|
||||
{main.map((l) => <li><a href={l.href} aria-current={aria(l.key)}>{l.label}</a></li>)}
|
||||
<li class="sep" aria-hidden="true"><Star size={12} /></li>
|
||||
<li class="mw">
|
||||
<a href="/library" class="mw-top" aria-haspopup="true" aria-current={inWorld ? "true" : undefined}>
|
||||
My world
|
||||
<svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" aria-hidden="true"><path d="M6 9l6 6 6-6" /></svg>
|
||||
</a>
|
||||
<ul class="mw-menu">
|
||||
{
|
||||
world.map((w) => (
|
||||
<li>
|
||||
<a href={w.href} aria-current={aria(w.key)}>
|
||||
<span class="mw-name">{w.label}</span>
|
||||
<span class="mw-blurb">{w.blurb}</span>
|
||||
</a>
|
||||
</li>
|
||||
))
|
||||
}
|
||||
</ul>
|
||||
</li>
|
||||
{tail.map((l) => <li><a href={l.href} aria-current={aria(l.key)} class="dim">{l.label}</a></li>)}
|
||||
</ul>
|
||||
</nav>
|
||||
)
|
||||
}
|
||||
{
|
||||
hero && (
|
||||
<div class="gk-wrap hero">
|
||||
<slot />
|
||||
</div>
|
||||
)
|
||||
}
|
||||
<div class="gk-wrap divider"><Divider /></div>
|
||||
{hero && <div class="gk-wrap divider"><Divider /></div>}
|
||||
</header>
|
||||
|
||||
<style>
|
||||
@@ -114,6 +138,17 @@ const aria = (key: NavKey) => (key === current ? "page" : undefined);
|
||||
.mono {
|
||||
width: 72px;
|
||||
height: 72px;
|
||||
border-radius: 50%;
|
||||
transition: filter 0.25s ease;
|
||||
}
|
||||
.brand:hover .mono,
|
||||
.brand:focus-visible .mono {
|
||||
filter: drop-shadow(0 0 6px rgba(216, 179, 90, 0.7)) drop-shadow(0 0 16px rgba(43, 194, 183, 0.45));
|
||||
}
|
||||
@media (prefers-reduced-motion: reduce) {
|
||||
.mono {
|
||||
transition: none;
|
||||
}
|
||||
}
|
||||
.words {
|
||||
display: flex;
|
||||
@@ -126,6 +161,15 @@ const aria = (key: NavKey) => (key === current ? "page" : undefined);
|
||||
letter-spacing: 0.14em;
|
||||
font-size: 17px;
|
||||
}
|
||||
.store-name {
|
||||
font-variant: small-caps;
|
||||
letter-spacing: 0.06em;
|
||||
font-size: 19px;
|
||||
}
|
||||
.store-tag {
|
||||
font-size: 12px;
|
||||
color: var(--gk-soft);
|
||||
}
|
||||
.tag {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
@@ -17,3 +17,9 @@ export const tail: { key: NavKey; label: string; href: string }[] = [
|
||||
{ key: "blog", label: "Blog", href: "/blog" },
|
||||
{ key: "store", label: "Store", href: "/store" },
|
||||
];
|
||||
|
||||
/** The Store's own header: its pages in order, and which one is open. */
|
||||
export interface StoreNav {
|
||||
links: { label: string; href: string }[];
|
||||
current?: string;
|
||||
}
|
||||
|
||||
@@ -5,6 +5,11 @@
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
/* A component's own display never un-hides what a script hid. */
|
||||
[hidden] {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
html {
|
||||
-webkit-text-size-adjust: 100%;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user