diff --git a/docs/THEMING.md b/docs/THEMING.md index b3e57e6..9fa9cb2 100644 --- a/docs/THEMING.md +++ b/docs/THEMING.md @@ -6,16 +6,27 @@ How color, light/dark mode, section tone, and animation work on this site. ## Palette -From the spec, exposed as CSS variables in `src/styles/themes.css` and mapped to -Tailwind utilities in `src/styles/global.css`: +The site uses the Patiun LLC brand palette (shared by Patiun and Greg Kilmer), +exposed as CSS variables in `src/styles/global.css` under `@theme`: | Token | Value | Meaning | |---|---|---| -| `--color-slate` | `#1E293B` | Professional confidence (primary) | -| `--color-amber` | `#F59E0B` | Warm accent (the making/creative side) | -| `--color-teal` | `#699a94` | Soft teal (secondary, favorite) | -| `--color-ink` | `#0F172A` | Near-black text on light | -| `--color-cream` | `#FFFBEB` | Cream-white text on dark | +| `--color-teal` | `#14A39A` | Patiun Teal, primary: buttons, fills, the glyph | +| `--color-teal-bright` | `#2BC2B7` | Teal text and links on dark grounds | +| `--color-teal-deep` | `#0F8C84` | Teal marks on light grounds | +| `--color-slate-teal` | `#2D4A58` | Dark end of the Tide gradient | +| `--color-gold` | `#C9A24A` | Alchemist Gold: stars, rules, seal lines (never a large fill) | +| `--color-gold-bright` | `#D8B35A` | Gold text on dark grounds | +| `--color-gold-deep` | `#8A6516` | Gold text under 24px on Starlight | +| `--color-violet` / `--color-indigo` | `#6A2FE0` / `#3B1F8F` | Nebula light only, never text | +| `--color-midnight` | `#131C2B` | Panels, tiles, browser theme color | +| `--color-sky` | `#0E1522` | Night-sky ground | +| `--color-starlight` | `#F4F2ED` | Text on dark; paper ground | + +The semantic Tailwind tokens (`--color-accent`, `--color-surface`, ...) resolve +at `:root`, so content sections render with the Starlight values in +`themes.css`. Night-sky bands (the nav and page heroes) carry the `.on-sky` +class, which re-points accent and gold to their on-dark values. Brand colors are fixed. **Semantic** tokens (`--surface`, `--text`, `--accent`, `--secondary`, `--border`, ...) resolve differently per theme + section, and are @@ -118,9 +129,11 @@ reduce)')` before drawing, so even JS-driven motion is skipped. Self-hosted variable fonts via Fontsource (woff2, no external requests): -- **Headings / UI:** Plus Jakarta Sans Variable (geometric sans) -- **Body:** Inter Variable -- **Mono / kickers / quotes:** JetBrains Mono Variable +- **Headings, names, card titles:** Cinzel Variable (`font-display`, used by + `h1`-`h4` automatically). Open tracking, never for paragraphs. +- **Body and UI:** Montserrat Variable (`font-sans`, `font-body`). +- **Eyebrows / kickers:** Montserrat uppercase with wide tracking (`font-eyebrow`). +- **Code-like blocks only:** JetBrains Mono Variable (`font-mono`). Font sizes use `clamp()` for fluid scaling (see the `h1`-`h4` rules in `global.css`). diff --git a/package-lock.json b/package-lock.json index 777e9dd..11d5bf2 100644 --- a/package-lock.json +++ b/package-lock.json @@ -12,9 +12,9 @@ "@astrojs/mdx": "^7.0.2", "@astrojs/node": "^11.0.2", "@astrojs/react": "^6.0.2", - "@fontsource-variable/inter": "^5.2.8", + "@fontsource-variable/cinzel": "^5.3.0", "@fontsource-variable/jetbrains-mono": "^5.2.8", - "@fontsource-variable/plus-jakarta-sans": "^5.2.8", + "@fontsource-variable/montserrat": "^5.3.0", "@iconify-json/mdi": "^1.2.3", "@tailwindcss/vite": "^4.3.2", "@types/nodemailer": "^8.0.1", @@ -1389,10 +1389,10 @@ "node": ">=18" } }, - "node_modules/@fontsource-variable/inter": { + "node_modules/@fontsource-variable/cinzel": { "version": "5.3.0", - "resolved": "https://registry.npmjs.org/@fontsource-variable/inter/-/inter-5.3.0.tgz", - "integrity": "sha512-OupL48va4JNofb97w6NYeF9S7W/kHNKM0Er8Dem5nqi4jeOLrVJDoE8tZEpnMJmtkvNbB1EIPPwHcdkF6b1oUA==", + "resolved": "https://registry.npmjs.org/@fontsource-variable/cinzel/-/cinzel-5.3.0.tgz", + "integrity": "sha512-eFcU0TwaAP5QESF2pV8VoOPJJXJ6sSGm/6mXMwqTdMBPAJMaLhfa6oISHuOtFeddsoHP9RYm4Io0j1j3mNEz2Q==", "license": "OFL-1.1", "funding": { "url": "https://github.com/sponsors/ayuhito" @@ -1407,10 +1407,10 @@ "url": "https://github.com/sponsors/ayuhito" } }, - "node_modules/@fontsource-variable/plus-jakarta-sans": { + "node_modules/@fontsource-variable/montserrat": { "version": "5.3.0", - "resolved": "https://registry.npmjs.org/@fontsource-variable/plus-jakarta-sans/-/plus-jakarta-sans-5.3.0.tgz", - "integrity": "sha512-/l/4r0yyWK9JzAlmA0LiYgGgmJe/Gswt4jTJEzr5QhJfwMbvJZDmYWyW0M4X7yCK69BajMVlV/Lx8g7WDc1+sw==", + "resolved": "https://registry.npmjs.org/@fontsource-variable/montserrat/-/montserrat-5.3.0.tgz", + "integrity": "sha512-7PaZoxaxrWLAyrhO46v65An9LhUhfkTExWLhfbywYZCnZEgg/W1rEHnlNmZKjNZ3nJTVYyicqxlJt10z/26yTA==", "license": "OFL-1.1", "funding": { "url": "https://github.com/sponsors/ayuhito" diff --git a/package.json b/package.json index d26a1b1..f432565 100644 --- a/package.json +++ b/package.json @@ -19,9 +19,9 @@ "@astrojs/mdx": "^7.0.2", "@astrojs/node": "^11.0.2", "@astrojs/react": "^6.0.2", - "@fontsource-variable/inter": "^5.2.8", + "@fontsource-variable/cinzel": "^5.3.0", "@fontsource-variable/jetbrains-mono": "^5.2.8", - "@fontsource-variable/plus-jakarta-sans": "^5.2.8", + "@fontsource-variable/montserrat": "^5.3.0", "@iconify-json/mdi": "^1.2.3", "@tailwindcss/vite": "^4.3.2", "@types/nodemailer": "^8.0.1", diff --git a/public/android-chrome-192x192.png b/public/android-chrome-192x192.png deleted file mode 100644 index eb0469d..0000000 Binary files a/public/android-chrome-192x192.png and /dev/null differ diff --git a/public/android-chrome-512x512.png b/public/android-chrome-512x512.png deleted file mode 100644 index 9f5102f..0000000 Binary files a/public/android-chrome-512x512.png and /dev/null differ diff --git a/public/apple-touch-icon.png b/public/apple-touch-icon.png index d235de2..30ffa99 100644 Binary files a/public/apple-touch-icon.png and b/public/apple-touch-icon.png differ diff --git a/public/favicon-16.png b/public/favicon-16.png new file mode 100644 index 0000000..15b45bd Binary files /dev/null and b/public/favicon-16.png differ diff --git a/public/favicon-16x16.png b/public/favicon-16x16.png deleted file mode 100644 index d500618..0000000 Binary files a/public/favicon-16x16.png and /dev/null differ diff --git a/public/favicon-32.png b/public/favicon-32.png new file mode 100644 index 0000000..832fc93 Binary files /dev/null and b/public/favicon-32.png differ diff --git a/public/favicon-32x32.png b/public/favicon-32x32.png deleted file mode 100644 index 307e061..0000000 Binary files a/public/favicon-32x32.png and /dev/null differ diff --git a/public/favicon-48.png b/public/favicon-48.png new file mode 100644 index 0000000..c61adc2 Binary files /dev/null and b/public/favicon-48.png differ diff --git a/public/favicon.ico b/public/favicon.ico index d698140..46e2cb4 100644 Binary files a/public/favicon.ico and b/public/favicon.ico differ diff --git a/public/favicon.svg b/public/favicon.svg index f7aa549..d9761cb 100644 --- a/public/favicon.svg +++ b/public/favicon.svg @@ -1,15 +1 @@ - - - - - - - - - - - - - - - + \ No newline at end of file diff --git a/public/icon-192.png b/public/icon-192.png new file mode 100644 index 0000000..25a1055 Binary files /dev/null and b/public/icon-192.png differ diff --git a/public/icon-512.png b/public/icon-512.png new file mode 100644 index 0000000..fcada0b Binary files /dev/null and b/public/icon-512.png differ diff --git a/public/icon-maskable-192.png b/public/icon-maskable-192.png new file mode 100644 index 0000000..2d0d1da Binary files /dev/null and b/public/icon-maskable-192.png differ diff --git a/public/icon-maskable-512.png b/public/icon-maskable-512.png new file mode 100644 index 0000000..c44a1c1 Binary files /dev/null and b/public/icon-maskable-512.png differ diff --git a/public/site.webmanifest b/public/site.webmanifest index 45dc8a2..0c8d74d 100644 --- a/public/site.webmanifest +++ b/public/site.webmanifest @@ -1 +1,33 @@ -{"name":"","short_name":"","icons":[{"src":"/android-chrome-192x192.png","sizes":"192x192","type":"image/png"},{"src":"/android-chrome-512x512.png","sizes":"512x512","type":"image/png"}],"theme_color":"#ffffff","background_color":"#ffffff","display":"standalone"} \ No newline at end of file +{ + "name": "Greg Kilmer Web Development", + "short_name": "Greg Kilmer", + "description": "Web development by Greg Kilmer, a Patiun LLC company.", + "icons": [ + { + "src": "/icon-192.png", + "sizes": "192x192", + "type": "image/png" + }, + { + "src": "/icon-512.png", + "sizes": "512x512", + "type": "image/png" + }, + { + "src": "/icon-maskable-192.png", + "sizes": "192x192", + "type": "image/png", + "purpose": "maskable" + }, + { + "src": "/icon-maskable-512.png", + "sizes": "512x512", + "type": "image/png", + "purpose": "maskable" + } + ], + "theme_color": "#131C2B", + "background_color": "#131C2B", + "display": "standalone", + "start_url": "/" +} diff --git a/src/components/brand/PatiunGlyph.astro b/src/components/brand/PatiunGlyph.astro new file mode 100644 index 0000000..fe68e2f --- /dev/null +++ b/src/components/brand/PatiunGlyph.astro @@ -0,0 +1,40 @@ +--- +/** + * PatiunGlyph.astro + * --------------------------------------------------------------------------- + * The Patiun LLC main mark: the alchemical symbol for platinum (the moon of + * silver joined to the sun of gold). Used small as the maker's mark in the + * Greg Kilmer lockup. Geometry is copied unchanged from the brand file + * patiun-symbol-A-exact-teal.svg; only the color is themable. + * + * Brand rules: Patiun Teal by default (gold, black or white are the only + * other allowed colors), no rings around it at small sizes, minimum 16px, and + * text sits beside it, never over it. + * + * Usage: + */ +interface Props { + class?: string; + style?: string; + /** Accessible name. Omit (default) when the mark sits next to visible text. */ + title?: string; +} +const { class: className, style = "color: var(--color-teal);", title } = Astro.props; +--- + + + + + + + + diff --git a/src/components/cards/DeckCard.astro b/src/components/cards/DeckCard.astro index 0d87250..e584b1f 100644 --- a/src/components/cards/DeckCard.astro +++ b/src/components/cards/DeckCard.astro @@ -96,13 +96,13 @@ const updated = updatedAt ? new Date(updatedAt).toLocaleDateString('en-US', {

{name}

{formatLabel && {formatLabel}} diff --git a/src/components/cards/GameCard.astro b/src/components/cards/GameCard.astro index 99325b0..87286b3 100644 --- a/src/components/cards/GameCard.astro +++ b/src/components/cards/GameCard.astro @@ -67,7 +67,7 @@ const alt = artAlt ?? title; {year && ( {year} @@ -75,7 +75,7 @@ const alt = artAlt ?? title; )}
-

{title}

+

{title}

{blurb} diff --git a/src/components/cards/InterestCard.astro b/src/components/cards/InterestCard.astro index 7575e67..77181e9 100644 --- a/src/components/cards/InterestCard.astro +++ b/src/components/cards/InterestCard.astro @@ -41,7 +41,7 @@ const { icon, title, status, currently = false, class: className = '' } = Astro. {currently && ( - + Active @@ -50,7 +50,7 @@ const { icon, title, status, currently = false, class: className = '' } = Astro. {status} )}

-

{title}

+

{title}

diff --git a/src/components/cards/MediaCard.astro b/src/components/cards/MediaCard.astro index b85f934..cc8e126 100644 --- a/src/components/cards/MediaCard.astro +++ b/src/components/cards/MediaCard.astro @@ -81,7 +81,7 @@ const detail = [year ? String(year) : null, count].filter(Boolean).join(' \u00b7
-

+

{title}

{status && {status}} @@ -89,7 +89,7 @@ const detail = [year ? String(year) : null, count].filter(Boolean).join(' \u00b7 { detail && ( {detail} diff --git a/src/components/hero/AnimatedBackground.tsx b/src/components/hero/AnimatedBackground.tsx index ffc0280..644fa9e 100644 --- a/src/components/hero/AnimatedBackground.tsx +++ b/src/components/hero/AnimatedBackground.tsx @@ -85,17 +85,17 @@ export default function AnimatedBackground({ // Resolve star colors from CSS variables so the field matches the theme. const gold = - getComputedStyle(document.documentElement).getPropertyValue('--color-amber').trim() || - '#e8b54a'; - const violet = - getComputedStyle(document.documentElement).getPropertyValue('--color-violet').trim() || - '#8b7bd8'; + getComputedStyle(document.documentElement).getPropertyValue('--color-gold').trim() || + '#c9a24a'; + // Nebula Violet is background light only, so violet stars use a lifted + // tint of it; teal stars use the on-dark teal so they read at dot size. + const violet = '#8a63ee'; const teal = - getComputedStyle(document.documentElement).getPropertyValue('--color-teal').trim() || - '#6fb6ad'; + getComputedStyle(document.documentElement).getPropertyValue('--color-teal-bright').trim() || + '#2bc2b7'; const white = - getComputedStyle(document.documentElement).getPropertyValue('--color-cream').trim() || - '#f4f1e8'; + getComputedStyle(document.documentElement).getPropertyValue('--color-starlight').trim() || + '#f4f2ed'; const hueColor = (h: Star['hue']) => (h === 'gold' ? gold : h === 'violet' ? violet : h === 'teal' ? teal : white); @@ -214,7 +214,7 @@ export default function AnimatedBackground({ const proximity = 1 - Math.sqrt(d2) / LINK_DIST; const pulse = 0.5 + 0.5 * Math.sin(now / 1400 + (i + j) * 0.7); const alpha = proximity * 0.22 * (0.55 + 0.45 * pulse); - ctx.strokeStyle = `rgba(232, 181, 74, ${alpha.toFixed(3)})`; + ctx.strokeStyle = `rgba(201, 162, 74, ${alpha.toFixed(3)})`; ctx.beginPath(); ctx.moveTo(A.x, A.y); ctx.lineTo(B.x, B.y); @@ -270,8 +270,8 @@ export default function AnimatedBackground({ const grad = ctx.createLinearGradient(sh.x, sh.y, tailX, tailY); const headA = Math.max(0, Math.min(1, sh.life)); grad.addColorStop(0, `rgba(244, 241, 232, ${headA.toFixed(3)})`); - grad.addColorStop(0.4, `rgba(232, 181, 74, ${(headA * 0.6).toFixed(3)})`); - grad.addColorStop(1, 'rgba(232, 181, 74, 0)'); + grad.addColorStop(0.4, `rgba(201, 162, 74, ${(headA * 0.6).toFixed(3)})`); + grad.addColorStop(1, 'rgba(201, 162, 74, 0)'); ctx.strokeStyle = grad; ctx.lineWidth = 1.6; ctx.beginPath(); @@ -332,7 +332,7 @@ export default function AnimatedBackground({ className="absolute inset-0" style={{ background: - 'linear-gradient(180deg, #04061a 0%, #070b24 32%, #0a1230 58%, #0e1a3e 82%, #12224a 100%)', + 'linear-gradient(180deg, #080c14 0%, #0b111c 32%, #0e1522 58%, #131c2b 82%, #1a2a3a 100%)', }} /> {/* Milky Way galaxy band — a soft diagonal luminous streak with a denser @@ -341,10 +341,10 @@ export default function AnimatedBackground({ className="animate-gradient-shift absolute inset-0 opacity-90" style={{ backgroundImage: ` - radial-gradient(38% 70% at 68% 38%, rgba(111, 182, 173, 0.22), transparent 62%), - radial-gradient(30% 55% at 72% 44%, rgba(139, 123, 216, 0.26), transparent 60%), - radial-gradient(22% 40% at 76% 50%, rgba(232, 181, 74, 0.12), transparent 60%), - linear-gradient(115deg, transparent 30%, rgba(236, 233, 255, 0.06) 45%, rgba(236, 233, 255, 0.09) 52%, rgba(236, 233, 255, 0.05) 60%, transparent 72%) + radial-gradient(38% 70% at 68% 38%, rgba(20, 163, 154, 0.22), transparent 62%), + radial-gradient(30% 55% at 72% 44%, rgba(106, 47, 224, 0.26), transparent 60%), + radial-gradient(22% 40% at 76% 50%, rgba(201, 162, 74, 0.12), transparent 60%), + linear-gradient(115deg, transparent 30%, rgba(236, 233, 226, 0.06) 45%, rgba(236, 233, 226, 0.09) 52%, rgba(236, 233, 226, 0.05) 60%, transparent 72%) `, backgroundSize: '200% 200%', }} @@ -354,14 +354,14 @@ export default function AnimatedBackground({ className="absolute inset-0" style={{ backgroundImage: ` - radial-gradient(45% 55% at 12% 12%, rgba(139, 123, 216, 0.18), transparent 60%), - radial-gradient(40% 50% at 88% 88%, rgba(111, 182, 173, 0.16), transparent 62%) + radial-gradient(45% 55% at 12% 12%, rgba(106, 47, 224, 0.18), transparent 60%), + radial-gradient(40% 50% at 88% 88%, rgba(20, 163, 154, 0.16), transparent 62%) `, }} /> {/* Faint astrolabe + sacred-geometry ornaments for esoteric texture. */} {/* Canvas star field (skipped under reduced motion). */} diff --git a/src/components/layout/Footer.astro b/src/components/layout/Footer.astro index 2552294..771f968 100644 --- a/src/components/layout/Footer.astro +++ b/src/components/layout/Footer.astro @@ -3,11 +3,11 @@ * Footer.astro * --------------------------------------------------------------------------- * Minimal footer on a deep night-sky surface: a faint static starfield accent, - * a StarBurst mark beside the name, social links (mdi icons), copyright, and + * the Patiun glyph as a maker's mark beside the name, social links (mdi icons), copyright, and * the spec microcopy "Built with intention. Powered by caffeine." No emojis. */ import Icon from '@components/Icon.astro'; -import StarBurst from '@components/mystic/StarBurst.astro'; +import PatiunGlyph from '@components/brand/PatiunGlyph.astro'; import StarField from '@components/mystic/StarField.astro'; import { socials, footerMicrocopy, siteIdentity } from '@lib/site'; const year = new Date().getFullYear(); @@ -26,12 +26,12 @@ const socialList = Object.values(socials); />
- +
-

+

{siteIdentity.name}

-

+

{footerMicrocopy}

diff --git a/src/components/layout/InterestHero.astro b/src/components/layout/InterestHero.astro index c50a900..e1620b4 100644 --- a/src/components/layout/InterestHero.astro +++ b/src/components/layout/InterestHero.astro @@ -6,7 +6,7 @@ * Milky Way field: a back-to-hub breadcrumb, a small icon mark, the title, and * the italic tagline. * - * Tuned for the dark starfield: text uses bright cream tones (not the dim + * Tuned for the dark starfield: text uses bright Starlight tones (not the dim * --color-text-subtle/--color-text which vanish on the deep sky). The title is * h2-sized (the page is a sub-page, not Home) so it doesn't dominate. An * optional banner image sits above the heading. @@ -39,7 +39,7 @@ const { } = Astro.props; --- -
+
@@ -54,8 +54,8 @@ const { {eyebrow} @@ -74,8 +74,8 @@ const {

{title}

@@ -84,7 +84,7 @@ const {

{tagline}

diff --git a/src/components/layout/Placeholder.astro b/src/components/layout/Placeholder.astro index 84a3ced..70d421c 100644 --- a/src/components/layout/Placeholder.astro +++ b/src/components/layout/Placeholder.astro @@ -40,7 +40,7 @@ const { label, hint, class: className = '' } = Astro.props;
- + TODO · {label} {hint &&

{hint}

} diff --git a/src/components/layout/RelatedInterests.astro b/src/components/layout/RelatedInterests.astro index f3f6178..6e875cf 100644 --- a/src/components/layout/RelatedInterests.astro +++ b/src/components/layout/RelatedInterests.astro @@ -23,7 +23,7 @@ const { items } = Astro.props; ---
-

+

You might also like

diff --git a/src/components/layout/SectionHeader.astro b/src/components/layout/SectionHeader.astro index f30ec3d..9c5a03e 100644 --- a/src/components/layout/SectionHeader.astro +++ b/src/components/layout/SectionHeader.astro @@ -39,8 +39,8 @@ const { } = Astro.props; const isHero = tone === "hero"; -const titleColor = isHero ? "var(--color-cream)" : undefined; -const subtitleColor = isHero ? "var(--color-cream)" : "var(--color-text-muted)"; +const titleColor = isHero ? "var(--color-starlight)" : undefined; +const subtitleColor = isHero ? "var(--color-starlight)" : "var(--color-text-muted)"; ---
{icon && } diff --git a/src/components/layout/SplitTransition.astro b/src/components/layout/SplitTransition.astro index 45e1823..7377f98 100644 --- a/src/components/layout/SplitTransition.astro +++ b/src/components/layout/SplitTransition.astro @@ -39,7 +39,7 @@ const { /> The professional wing @@ -59,7 +59,7 @@ const { > The personal wing diff --git a/src/components/media/CategoryList.astro b/src/components/media/CategoryList.astro index 46f6e15..773e830 100644 --- a/src/components/media/CategoryList.astro +++ b/src/components/media/CategoryList.astro @@ -29,13 +29,13 @@ const { groups, pillIcon = 'play-circle' } = Astro.props;

{group.category}

{group.items.length} @@ -51,7 +51,7 @@ const { groups, pillIcon = 'play-circle' } = Astro.props; {item.title} {item.status && ( {item.status} @@ -59,7 +59,7 @@ const { groups, pillIcon = 'play-circle' } = Astro.props; )} {item.year && ( {item.year} diff --git a/src/components/mystic/AlchemicalDivider.astro b/src/components/mystic/AlchemicalDivider.astro index 5b88a92..4326e23 100644 --- a/src/components/mystic/AlchemicalDivider.astro +++ b/src/components/mystic/AlchemicalDivider.astro @@ -11,7 +11,7 @@ * --color-violet at the call site). * * Usage: - * + * */ interface Props { class?: string; diff --git a/src/components/mystic/Astrolabe.astro b/src/components/mystic/Astrolabe.astro index 04fc6e8..c9b0c3b 100644 --- a/src/components/mystic/Astrolabe.astro +++ b/src/components/mystic/Astrolabe.astro @@ -11,7 +11,7 @@ * opacity + color at the call site so it reads as a faint engraving. * * Usage: - * + * */ interface Props { class?: string; diff --git a/src/components/mystic/CelestialImage.astro b/src/components/mystic/CelestialImage.astro index bd3d80c..86d1d9f 100644 --- a/src/components/mystic/CelestialImage.astro +++ b/src/components/mystic/CelestialImage.astro @@ -80,7 +80,7 @@ const objectFit = fit === "contain" ? "object-contain" : "object-cover";
{alt} diff --git a/src/components/mystic/CircuitField.tsx b/src/components/mystic/CircuitField.tsx index 388e806..d14ab73 100644 --- a/src/components/mystic/CircuitField.tsx +++ b/src/components/mystic/CircuitField.tsx @@ -56,9 +56,9 @@ export default function CircuitField({ let traces: Trace[] = []; let nodes: Node[] = []; - const gold = '#e8b54a'; - const violet = '#8b7bd8'; - const teal = '#6fb6ad'; + const gold = '#c9a24a'; + const violet = '#8a63ee'; + const teal = '#2bc2b7'; function build() { if (!canvas || !ctx) return; @@ -116,7 +116,7 @@ export default function CircuitField({ for (let i = 0; i < traces.length; i++) { const t = traces[i]; // Base trace — clearly visible violet conductor line. - ctx.strokeStyle = 'rgba(168, 158, 220, 0.55)'; + ctx.strokeStyle = 'rgba(43, 194, 183, 0.55)'; ctx.lineWidth = 1.4; ctx.beginPath(); ctx.moveTo(t.x1, t.y1); @@ -140,7 +140,7 @@ export default function CircuitField({ ctx.stroke(); // Bright pulse head dot. ctx.globalAlpha = 1; - ctx.fillStyle = '#fff4d6'; + ctx.fillStyle = '#fbf3dc'; ctx.beginPath(); ctx.arc(px, py, 1.8, 0, Math.PI * 2); ctx.fill(); @@ -172,7 +172,7 @@ export default function CircuitField({ if (!ctx) return; ctx.clearRect(0, 0, width, height); for (const t of traces) { - ctx.strokeStyle = 'rgba(168, 158, 220, 0.5)'; + ctx.strokeStyle = 'rgba(43, 194, 183, 0.5)'; ctx.lineWidth = 1.4; ctx.beginPath(); ctx.moveTo(t.x1, t.y1); @@ -243,7 +243,7 @@ export default function CircuitField({ className="absolute inset-0" style={{ background: - 'linear-gradient(180deg, #04061a 0%, #070b24 32%, #0a1230 58%, #0e1a3e 82%, #12224a 100%)', + 'linear-gradient(180deg, #080c14 0%, #0b111c 32%, #0e1522 58%, #131c2b 82%, #1a2a3a 100%)', }} /> {/* Circuit traces + nodes + signal pulses. */} diff --git a/src/components/mystic/ConstellationField.tsx b/src/components/mystic/ConstellationField.tsx index 44cd174..7d32189 100644 --- a/src/components/mystic/ConstellationField.tsx +++ b/src/components/mystic/ConstellationField.tsx @@ -67,10 +67,10 @@ export default function ConstellationField({ } let stars: Star[] = []; - const gold = '#e8b54a'; - const violet = '#8b7bd8'; - const teal = '#6fb6ad'; - const white = '#f4f1e8'; + const gold = '#c9a24a'; + const violet = '#8a63ee'; + const teal = '#2bc2b7'; + const white = '#f4f2ed'; const accent = tint === 'violet' ? violet : tint === 'teal' ? teal : gold; // One full rotation every ~10 minutes — barely perceptible, "planet turning". @@ -168,7 +168,7 @@ export default function ConstellationField({ const proximity = 1 - Math.sqrt(d2) / LINK_DIST; const pulse = 0.5 + 0.5 * Math.sin(now / 1600 + (i + j) * 0.7); const alpha = proximity * 0.24 * (0.55 + 0.45 * pulse); - ctx.strokeStyle = `rgba(232, 181, 74, ${alpha.toFixed(3)})`; + ctx.strokeStyle = `rgba(201, 162, 74, ${alpha.toFixed(3)})`; ctx.beginPath(); ctx.moveTo(A.x, A.y); ctx.lineTo(B.x, B.y); diff --git a/src/components/mystic/SacredGeometry.astro b/src/components/mystic/SacredGeometry.astro index 3a9f086..591bc10 100644 --- a/src/components/mystic/SacredGeometry.astro +++ b/src/components/mystic/SacredGeometry.astro @@ -11,7 +11,7 @@ * Apply opacity + sizing + color at the call site. * * Usage: - * + * */ interface Props { class?: string; diff --git a/src/components/mystic/StarBurst.astro b/src/components/mystic/StarBurst.astro index 4fe1453..a70cfc8 100644 --- a/src/components/mystic/StarBurst.astro +++ b/src/components/mystic/StarBurst.astro @@ -11,7 +11,7 @@ * - `outline`: stroke-only, lighter * * Usage: - * + * * */ interface Props { diff --git a/src/components/mystic/StarField.astro b/src/components/mystic/StarField.astro index e9ad5af..e00475f 100644 --- a/src/components/mystic/StarField.astro +++ b/src/components/mystic/StarField.astro @@ -10,7 +10,7 @@ * cheap. Pointer-events disabled; inherits `currentColor`. * * Usage: - * + * */ interface Props { class?: string; diff --git a/src/components/nav/NavBar.astro b/src/components/nav/NavBar.astro index cd4536e..a18b485 100644 --- a/src/components/nav/NavBar.astro +++ b/src/components/nav/NavBar.astro @@ -12,7 +12,7 @@ */ import Icon from "@components/Icon.astro"; import MobileMenu from "./MobileMenu.tsx"; -import StarBurst from "@components/mystic/StarBurst.astro"; +import PatiunGlyph from "@components/brand/PatiunGlyph.astro"; import { navGroups, siteIdentity } from "@lib/site"; const path = Astro.url.pathname; @@ -33,7 +33,7 @@ const heroSkyClass = isHome ? "" : "vt-hero-sky"; id="site-nav" data-nav class:list={[ - "fixed inset-x-0 top-0 z-50 transition-[background,box-shadow,border-color] duration-300", + "on-sky fixed inset-x-0 top-0 z-50 transition-[background,box-shadow,border-color] duration-300", heroSkyClass, ]} > @@ -45,28 +45,29 @@ const heroSkyClass = isHome ? "" : "vt-hero-sky"; class="container-prose flex h-16 items-center justify-between gap-4" aria-label="Primary" > - +
- {siteIdentity.name} @@ -93,7 +94,7 @@ const heroSkyClass = isHome ? "" : "vt-hero-sky"; style={ active ? "color: var(--color-accent);" - : "color: var(--color-cream); opacity: 0.85;" + : "color: var(--color-starlight); opacity: 0.85;" } onmouseover="this.style.opacity='1'" onmouseout="this.style.opacity='0.85'" @@ -127,8 +128,8 @@ const heroSkyClass = isHome ? "" : "vt-hero-sky"; [data-nav-inner] { background: linear-gradient( 180deg, - rgba(8, 10, 32, 0.92) 0%, - rgba(12, 14, 40, 0.86) 100% + rgba(14, 21, 34, 0.92) 0%, + rgba(19, 28, 43, 0.86) 100% ); } /* Scrolled state: stronger blur + hairline border + shadow. */ @@ -140,7 +141,7 @@ const heroSkyClass = isHome ? "" : "vt-hero-sky"; var(--color-accent) 30%, var(--color-border) ); - box-shadow: 0 8px 30px -20px rgba(11, 16, 38, 0.7); + box-shadow: 0 8px 30px -20px rgba(8, 12, 20, 0.7); } /* A subtle violet/gold nebula glow behind the nav, fixed to the top. */ [data-nav]::before { @@ -152,12 +153,12 @@ const heroSkyClass = isHome ? "" : "vt-hero-sky"; background: radial-gradient( 60% 120% at 85% -20%, - rgba(139, 123, 216, 0.22), + rgba(106, 47, 224, 0.22), transparent 70% ), radial-gradient( 50% 120% at 10% -10%, - rgba(232, 181, 74, 0.1), + rgba(201, 162, 74, 0.1), transparent 70% ); } diff --git a/src/components/professional/Certifications.astro b/src/components/professional/Certifications.astro index 152c9a4..83f18fb 100644 --- a/src/components/professional/Certifications.astro +++ b/src/components/professional/Certifications.astro @@ -58,14 +58,14 @@ const entries: CertEntry[] = [ {c.status && {c.status}}
-

+

{c.name}

{c.issuer}

{c.year} diff --git a/src/components/professional/ContactForm.tsx b/src/components/professional/ContactForm.tsx index edf3cbc..3ead27c 100644 --- a/src/components/professional/ContactForm.tsx +++ b/src/components/professional/ContactForm.tsx @@ -223,7 +223,7 @@ export default function ContactForm({ turnstileSiteKey }: Props) { -

+

Message sent.

diff --git a/src/components/professional/EducationHistory.astro b/src/components/professional/EducationHistory.astro index 3c4c488..c5580a6 100644 --- a/src/components/professional/EducationHistory.astro +++ b/src/components/professional/EducationHistory.astro @@ -45,7 +45,7 @@ const entries: EduEntry[] = [

-

+

{e.credential}

{e.period} diff --git a/src/components/professional/ProjectCard.astro b/src/components/professional/ProjectCard.astro index 08641c5..0be0cb3 100644 --- a/src/components/professional/ProjectCard.astro +++ b/src/components/professional/ProjectCard.astro @@ -33,7 +33,7 @@ const links = [

{d.title}

-

+

{d.role}

diff --git a/src/components/professional/SectionNav.astro b/src/components/professional/SectionNav.astro index aa91501..cdc561f 100644 --- a/src/components/professional/SectionNav.astro +++ b/src/components/professional/SectionNav.astro @@ -8,7 +8,7 @@ * * Three bugs previously fixed here: * 1. Contrast: the rail used surface-relative tokens (--color-surface-raised / - * --color-cream) which collapsed to the same tone on light surfaces (the + * --color-starlight) which collapsed to the same tone on light surfaces (the * interest-surface cream made icons/text invisible). The rail now uses * FIXED dark colors regardless of the page's surface tone. * 2. Progress line clipping: the line sat at the icon column's horizontal @@ -41,7 +41,7 @@ const sections = [ for the progress line, then the icon+label list. */}
{/* --- Left gutter: the progress track + fill. Sits LEFT of the icons. --- */}
@@ -69,11 +69,11 @@ const sections = [ href={`#${s.id}`} data-section-link={s.id} class="group relative flex items-center gap-2.5 rounded-lg px-2.5 py-2 font-sans text-sm font-semibold transition-all" - style="color: #e8e6f5;" + style="color: #ece9e2;" > @@ -92,19 +92,19 @@ const sections = [ } .pro-section-nav a[data-section-link]:hover { opacity: 1; - background: rgba(232, 181, 74, 0.08); + background: rgba(201, 162, 74, 0.08); } /* Active link: bright accent text + accent wash. */ .pro-section-nav a[data-active="true"] { opacity: 1 !important; color: var(--color-accent) !important; - background: rgba(232, 181, 74, 0.14); + background: rgba(201, 162, 74, 0.14); } /* Active dot: filled accent, dark icon, glow ring. */ .pro-section-nav a[data-active="true"] [data-section-dot] { background: var(--color-accent) !important; - color: #0b1026 !important; - box-shadow: 0 0 12px rgba(232, 181, 74, 0.65); + color: #131c2b !important; + box-shadow: 0 0 12px rgba(201, 162, 74, 0.65); } diff --git a/src/components/professional/SkillGrid.astro b/src/components/professional/SkillGrid.astro index 2422aac..b9ef569 100644 --- a/src/components/professional/SkillGrid.astro +++ b/src/components/professional/SkillGrid.astro @@ -72,7 +72,7 @@ const techStack = [
-

+

Core Competencies