Commit Graph

76 Commits

Author SHA1 Message Date
jwright df72a22952 docs: refresh README for the current layout; ASCII sweep on SECURITY.md 2026-08-04 03:45:58 +10:00
jwright f89957370e gitignore local staging
Draft posts are private staging. They reach the public only by being moved
into src/content/blog at publish time, deliberately, one at a time.
2026-08-04 03:28:31 +10:00
jwright d26e981d7a blog: expand the series to six pillars; add the catalogue generator
Drafted from the last month of real work - OpenShift fleet hardening, edge AI
and GPU, network policy enforcement, supply-chain security, automation and
observability - weighted toward the work stack the site advertises. Each has
a photo prompt in the house palette and a diagram brief.

Adds BLOG-LEDGER.md, generated from disk so it cannot drift, listing every
live and drafted idea in one place. Search it before drafting; claim the idea
when the folder is created rather than at publish, so two sessions cannot
collide. Expands the series from three arcs to six now the catalogue is deep
enough to split edge AI, automation and observability out of PLATFORM.
2026-08-04 03:21:49 +10:00
jwright cbfc4007cf projects: cover art on the dossier cards, replacing the sketch thumbnails
The inline SVG thumbs were placeholder-grade next to real art. Cards now use
a 640px mini of the same cover (9-22KB), object-fit cover with a slow hover
zoom, and a corner scrim so the DOSSIER tag stays legible over the brighter
frames. Falls back to the sketch for any project without a cover.
2026-08-03 17:57:44 +10:00
jwright cd08cd04c1 projects: cover art on every case study
Six generated covers wired in via an optional cover key - 2528x1696 sources
optimised to 1600px webp, 49-144KB each. They sit on the page background
rather than the diagrams' light card, since the art is already generated in
the site palette on near-black. Cover carries the story at a glance, the
diagram still carries the architecture below it.
2026-08-03 17:53:25 +10:00
jwright ba81705a39 projects: drop the two diagram refs that never had files
gpu-as-code and global-infra-modernisation pointed at diagrams that do not
exist, rendering a dead image box on a light card. Removing the key is
better than a broken frame until real art lands. Prompt pack for all six
covers ships alongside, in the blog-hero visual language.
2026-08-03 17:34:07 +10:00
jwright 99fd652569 projects: author the missing network-fleet diagram (was a 404 on the case study) 2026-08-03 17:32:52 +10:00
jwright afba75dd3a capabilities: keep the video-analytics line vendor-neutral 2026-08-03 16:58:14 +10:00
jwright f7e64cebe5 capabilities: proof-points fill the tall tiles; headers rebalanced to the flagship weight
The hero and full-row tiles stretched to their grid height with nothing
between blurb and chips - reading as missing body. Adds a points field
rendered as accent-dashed proof lines (flagship gets four, observability
three), each grounded in the running estate. Category titles step up to
23px/700 with the flagship at 30px so the hierarchy holds.
2026-08-03 16:54:53 +10:00
jwright 6c7e577633 blog: three curated series across the whole catalogue + badge on post pages
Extends the lone security thread into three arcs that read as skill pillars -
SECURITY (6), NETWORKING (5), PLATFORM (7) - so every post carries a numbered
badge and the catalogue advertises three areas of depth rather than a loose
list. Adds the badge to the post detail header too, styled to match the cards.
2026-08-03 16:47:07 +10:00
jwright 6ea2582a66 blog: heroes belong in frontmatter - fix the five new posts
The five carried the hero only as an inline markdown image, but the index
cards and the post hero figure render from hero/heroAlt frontmatter - so
the cards showed no image and the post pages lost the hero treatment.
Moved each hero into frontmatter and dropped the inline line (the body
keeps only the diagram), matching every earlier post.
2026-08-03 08:24:22 +10:00
jwright 317e5230b6 deps: clear the audit gate (astro 7.0.10 + transitive fixes); reword one-doorman past the secret scan
npm audit fix - 13 advisories incl. astro high and tar critical, all
non-breaking, gates re-run green locally. The dist secret scan greps
password-adjacent patterns, so the post now says htpasswd file (which the
registry auth actually is), credential vault, and lock-of-its-own.
2026-08-02 23:34:17 +10:00
jwright 521cc2f066 blog: publish five posts - landing-on-cilium, sleep-half-the-fleet, clone-not-keys, stage-the-locks, one-doorman-many-doors
Heroes optimised to 1600px webp from the prepped batch; diagrams authored
to the house palette; dates set to publish day.
2026-08-02 23:17:31 +10:00
jwright 91b3cff67a blog: publish three posts — observe-first-deny-second, snat-ate-my-source, no-ssh
Heroes de-watermarked via the calibrated Jacobi diffuse (dewatermark.mjs now
parameterised src/out), diagrams authored in the house light-card style.
2026-07-14 18:43:32 +10:00
jwright a0d71388c4 constellation: seamless animation loops — dash offset aligned to the 136px pattern period (dots no longer jump at the seam), radar ring fades in instead of popping 2026-07-13 15:32:09 +10:00
jwright 3217d779b3 constellation: key to the right edge (left clips on narrow heroes), bat-gloss swatch for core/services 2026-07-13 15:16:24 +10:00
jwright 94698c6315 constellation: intel accent for alfred + elfastc, compute colour key, drop the stale kate caption 2026-07-13 15:00:11 +10:00
jwright 87cfe78ffc blog: publish three posts — backup restore drills, the bastion pattern, split-horizon DNS-01 (heroes + diagrams) 2026-07-09 15:02:17 +10:00
jwright 2896f89af3 footer: unify the receipt + identity into one terminal session panel; fix HEAD sha in container builds (GIT_SHA build-arg) 2026-07-09 14:04:54 +10:00
jwright 908d311e5c fix(skills): collapse bento spans at 2-col breakpoint, not 720px
Landscape phone (720-1000px band) put the parent grid at 2 columns while the
tile spans (hero span-2, full span-3) only reset at 720px. A span-3 tile in a
2-col grid forced a phantom 3rd column and collapsed the 1fr tracks to
58px 58px 760px, squishing the flagship card to ~132px off the visible area.
Move the span reset to the same 1000px breakpoint the grid drops to 2 columns:
now 446px 446px, hero full-width. Desktop 4-col + portrait 1-col unchanged.
2026-07-03 23:56:07 +10:00
jwright 0d05aae721 blog: republish 2 edited posts, dossier thumbnails 4-6, new post broker-pattern
Content: shipping-this-site + init-gating-gpu-readiness get their edited-workshop bodies (from the
NAS Published/ pass) - site frontmatter (hero/heroAlt) kept, only prose replaced.

Dossiers 004-006 (gpu-as-code, global-infra-modernisation, network-automation-fleet) were all
rendering the same generic pipeline thumbnail - added 3 tailored DossierThumb motifs (gpu die +
passthrough lanes, region globe, switch-fleet grid) via a new diagram: frontmatter field. Also
closed the dead-space gap above the tag row on short-argument cards with a faint on-theme grid
fill (::before, masked fade) instead of a flat void.

New post: broker-pattern ('An agent should never hold the key it's using') - SECURITY SERIES 02,
between secret-zero and workload-least-privilege. Hero de-watermarked from the NAS source (resized
to the calibrated 1600x1073 coordinate space, Jacobi-diffused out the Nano Banana sparkle at its
known center) via scripts/dewatermark-broker-pattern.mjs (reusable for the next 3 drafts). New
diagram/broker-pattern.svg in the house light-card palette. Inline top-of-body hero stripped per
the astro-static-site skill guard (frontmatter hero: is now the only render path).
2026-07-03 21:12:52 +10:00
jwright c162f2e4e7 nav: phone tabs on a compact second row - zero-JS, scrollable, no hamburger
The links were display:none under 720px (desktop-only nav). Phones now wrap the bar: brand +
theme toggle row 1, the five tabs row 2 (mono 0.78rem, overflow-x scroll, hidden scrollbar).
Media block placed AFTER the base rules - same-specificity source order was eating the first attempt.
2026-07-03 20:47:09 +10:00
jwright de7c257ab7 hero: wrap the fleet-fact bar on phones - nowrap+max-content busts a 390px viewport 2026-07-03 20:16:52 +10:00
jwright 71c3f00618 facelift: the Bat-Computer redesign - constellation hero, bento, dossiers, receipt
Promotes the blog art identity to the whole site. Fleet constellation hero (six real nodes,
dual-trace packets, typing fleet facts), Chakra Petch + JetBrains Mono self-hosted, bento
capabilities, dossier work cards, security-series badges, featured blog index, GitOps receipt
footer, native view transitions, light blueprint theme. CSP strict throughout; blog content
byte-identical.
2026-07-03 20:08:12 +10:00
jwright 4e13bf596c facelift: fix light-theme scrims/thumbs - :global() the data-theme overrides
Astro scopes compound selectors, so [data-theme=light] .hero__scrim inside a component style
block could never match html[data-theme] - the light theme rendered dark scrims (embossed
low-contrast copy). Wrap the theme prefix in :global() in Hero, ProjectCard and the blog index.
Light 'blueprint' hero now reads clean.
2026-07-03 19:50:18 +10:00
jwright 8a7ca88c40 facelift polish: native cross-document view transitions + og regen
@view-transition navigation:auto (pure CSS crossfade, 180ms; Firefox ignores, reduced-motion
disables) - zero JS, zero CSP surface. og.png regenerated from the electric-identity script.
Favicon already carries the identity (gradient jw chip + caret) - deliberately unchanged.
2026-07-03 19:47:03 +10:00
jwright de12f028eb facelift: blog index - featured security-series opener + image-led grid
Breadcrumb eyebrow (~/jwright/blog), 'Notes from the build.' H1, featured card for the series
opener (text left / hero art scrimmed right, series badge, eager-loaded), remaining posts in the
image-led responsive grid with series badges + reading time. Post CONTENT untouched (index only).
2026-07-03 19:46:07 +10:00
jwright 8d955aa802 facelift: the scroll story - bento capabilities, dossier cards, series badges, GitOps receipt
02 Capabilities becomes a 4-col bento (Edge AI 2x2 flagship w/ magenta corner radial, Platform
wide, magenta-flavoured security tile, Observability row-completer) driven by span/flavor fields
in skills.ts. 03 Selected Work becomes dossier cards: house-style SVG thumbnails (per-project
motif via DossierThumb), DOSSIER/00N corner tags, 'the argument' line from the outcome field,
chip tags, mono meta footer. 04 Writing cards gain the security-series badge (data/series.ts)
and sit three across. Section numbers glow cyan; a circuit divider (gradient hairlines + two
diamonds) closes the hero. Footer opens with the GitOps receipt - git sha + build date baked at
build time via lib/build-info.ts, zero runtime calls.
2026-07-03 19:43:45 +10:00
jwright 65ba1ec7dc facelift: fleet constellation hero + Bat-Computer type/token layer
Chakra Petch site-wide (300-700) + JetBrains Mono variable, all self-hosted (CSP zero-external
holds). Token layer gains the mock-exact text tiers, glass panel, cyan-tinted borders, glows,
tighter radii; light 'blueprint' variants included. New Constellation.astro: the six real nodes
as IC chips on dual-trace PCB paths (cyan out / magenta back, dasharray packets), radar ring on
the cave hub, vias at bends - pure SVG + scoped CSS keyframes, full reduced-motion fallback.
Hero rebuilt: scrim stack + masked grid over the board art, two-line gradient nameplate, typing
bar cycling six real fleet facts via the external site.js (facts from src/data/fleet.ts), scroll
indicator. Facts wrap, never clip.
2026-07-03 18:58:49 +10:00
jwright 08bab080b1 nav: stop tabs sticking lit on Projects/Blog pages
build-and-deploy / build (push) Failing after 14m26s
On pages with no scroll-spy sections, activeIdx stays -1 and indexOf(link)
is also -1, so the pointerleave 'keep lit if active' check matched every
hovered tab. Guard with activeIdx >= 0 so a hovered tab always retracts when
nothing is active.
2026-06-29 19:54:30 +10:00
jwright dae9bbc91a nav: animate Projects/Blog underlines + coherent directional slide
build-and-deploy / build (push) Failing after 12m11s
- Projects/Blog had no data-nav-id so the scroll-spy skipped them entirely;
  point them at the homepage #projects/#writing sections so all five animate
- Drive the underline declaratively (re-assert all on each change) so none can
  be left stranded mid-spring
- Slide follows scroll direction: activating underline grows from its trailing
  edge while the rest collapse toward the leading edge (down→right, up→left)
2026-06-29 19:46:46 +10:00
jwright 7c300faec8 home: fix nav active-section at page bottom + exact progress bar; add blog tags to Writing
build-and-deploy / build (push) Failing after 10m38s
- Nav underline highlighted the wrong section at the bottom (the short last
  section never crossed the threshold) — force the last section when scrolled
  to the bottom so Contact lights up instead of Skills
- Scroll-progress bar: compute progress from scrollY/maxScroll so it spans a
  true 0→1 (Motion's default topped out ~0.89 at the bottom)
- Writing section: add blog tag chips linking to /blog/tags/<tag>/
2026-06-29 19:08:17 +10:00
jwright 257af5d22e home: add Writing section; fix scroll-progress snap + nav underline reverse
build-and-deploy / build (push) Failing after 10m20s
- Scroll-progress bar: drive scaleX from scroll progress via callback form;
  the animation form snapped the bar to 0 at the bottom (progress=1 boundary)
- Nav active-underline: recompute active section from scroll position each
  frame so it tracks upward scroll too (inView-enter died on the way back up)
- Add a Writing section to the homepage with recent posts + a blog CTA
2026-06-29 18:53:35 +10:00
jwright 880b9daeac projects: reword index tagline; split global infra into estate + network-automation
build-and-deploy / build (push) Failing after 11m25s
- New projects tagline + open-minded lead
- Split the combined infra project: keep the estate/cloud modernisation,
  add a dedicated Network Automation at Fleet Scale case (Unimus + NetBox,
  config backup, bulk push, vaulted+rotated credentials) from the Linde role
2026-06-29 18:32:29 +10:00
jwright a685789322 blog: drop duplicate inline hero on secret-zero
build-and-deploy / build (push) Failing after 10m24s
The hero image is rendered from frontmatter; the leftover inline
markdown image rendered it a second time (and uncached, so the old
asset showed).
2026-06-29 18:13:32 +10:00
jwright 61642e8db8 blog: add secret-zero bootstrap diagram; clean up hero images
build-and-deploy / build (push) Failing after 13m51s
- Add the secret-zero bootstrap-chain diagram (was a broken image ref)
- Remove the corner sparkle artifact from all six blog hero images
- Bump hero/diagram cache-bust params so the updated assets serve
2026-06-29 18:05:03 +10:00
jwright bed2dbaa1f blog: add outbound + secret-zero hero images
build-and-deploy / build (push) Failing after 11m34s
outbound-only-exposure (corrected sealed-vault image) + secret-zero (the seed-
key circuit-tree, _R revision). Both verified against their prompts, optimized
to webp (17KB / ~120KB). Completes hero coverage for all 6 posts.
2026-06-29 17:47:23 +10:00
jwright 354475a453 blog: hero images + publish secret-zero
build-and-deploy / build (push) Failing after 11m14s
Add an optional hero field to the blog schema; render it on the post page and
as the index card thumbnail. Ship 4 verified Nano Banana hero images (shipping/
init-gating/authentik/workload) as optimized webp (64-134KB). Publish the
secret-zero post. (outbound hero pending — its file was a dup of shipping;
secret-zero hero pending generation.)
2026-06-29 17:37:40 +10:00
jwright d8a147aabe ui: design polish — themed scrollbar, focus-ring glow, card depth
build-and-deploy / build (push) Failing after 11m52s
Themed thin scrollbar (cyan→magenta thumb, Firefox + WebKit), an on-brand glow
halo on the keyboard focus ring (solid outline keeps WCAG visibility), and a 1px
inner top highlight so cards read raised at rest. CSS-only, token-pure.
2026-06-28 23:32:04 +10:00
jwright f6d92e5c87 ui: Motion-driven animation layer (motion.dev)
build-and-deploy / build (push) Failing after 14m48s
Unify scroll reveals, hero entrance, nav active-underline, button springs,
the scroll-progress bar and backdrop parallax under one Motion system
(src/scripts/anim.ts), bundled into a self-hosted /_astro module so CSP
script-src 'self' holds. Progress bar + parallax now scroll()-driven and
cross-browser (was Chromium-only animation-timeline). Fail-open, reduced-motion
aware, content fully visible with JS off.
2026-06-28 23:23:58 +10:00
jwright 5d439752de ui: retheme favicon + OG card to the cyan→magenta theme
build-and-deploy / build (push) Failing after 12m13s
The tab logo and social preview were still on the old teal palette. Retone both
to the electric cyan→magenta theme matching the hero nameplate:
- favicon.svg: jw monogram + prompt-line + cursor on a cyan→magenta gradient.
- og.png (gen-og.mjs): name in the cyan→violet→magenta hero gradient, cyan
  eyebrow/separators, magenta URL, cyan→magenta top bar + dual corner glows.
- bump ?v=2 on both refs (public/ assets are CF-edge-cached + social platforms
  cache OG hard) so the new art shows immediately.
2026-06-27 23:01:41 +10:00
jwright 0c93328a2d ui: vivid electric nameplate — fix invisible hero title in light mode
build-and-deploy / build (push) Failing after 10m26s
The hero name was a mostly---text gradient with a thin accent sweep; in light
mode it rested on low-contrast tones and the body text-halo washed it to a ghost.
Replace with a full cyan→violet→magenta fill driven by the theme-aware accent
tokens (deep on light, bright on dark) so it's unmissable in either mode, plus a
tight dark edge-shadow for legibility, the electric glow, and a one-shot light
sheen that parks off-screen. Opt the title out of the light text-halo.
2026-06-27 21:28:30 +10:00
jwright ef1719c84e ui: keep the board visible in light mode + bust diagram cache
build-and-deploy / build (push) Failing after 14m43s
Light mode: revert the heavy white-out scrim back to a moderate wash so the
board stays visible, and earn legibility with a soft light text-halo behind
running text instead (invisible on the solid cards, only works over the image).
Pairs with the darker light-mode text tokens.

Also append ?v=2 to every /diagrams/*.svg reference so the recoloured diagrams
bypass Cloudflare's 4h edge cache and show immediately (the SVG URLs aren't
content-hashed like the CSS bundle).
2026-06-27 21:19:13 +10:00
jwright e264f673d7 fix(ui): readable light mode over the board backdrop
build-and-deploy / build (push) Failing after 13m46s
Body text washed out in light mode — the secondary/tertiary text tokens were
too light against the bright sandstone board image. Darken light --text-dim and
--text-faint, and heavily strengthen the light-theme scrim so the board drops
to a faint texture behind content. Dark mode unchanged.
2026-06-27 21:15:08 +10:00
jwright 8702c8a293 ui: re-theme architecture diagrams to the cyan→magenta palette
build-and-deploy / build (push) Failing after 13m39s
The diagrams still used the old teal/green/blue scheme. Remap all six to the
electric theme: teal #0d9488 → cyan #0c8fce (primary), blue #3b6fb0 → violet
#7c3aed (containers/boundaries), green #2e8b57 → magenta #c026d3 (services).
Neutral slate + navy kept for lines and text; light card unchanged so the
fixed-colour art stays legible in both themes.
2026-06-27 21:10:17 +10:00
jwright b7c91081b2 fix(ui): scroll-coupled backdrop pan that works in every browser
build-and-deploy / build (push) Failing after 11m10s
CSS animation-timeline: scroll() is Chromium-only, so the backdrop didn't move
for non-Chromium browsers. Replace it with a tiny rAF-throttled scroll handler
in site.js (the existing same-origin script — CSP stays strict, no inline JS)
that drives a --bg-shift CSS var off scroll position. The board now pans
vertically in lock-step with scroll and sits still at rest, in all browsers.
2026-06-27 21:02:46 +10:00
jwright af7e0287d4 fix(ui): backdrop now moves in every browser
build-and-deploy / build (push) Failing after 14m47s
The backdrop's only motion was the scroll-driven pan (animation-timeline:
scroll()), which is Chromium-only — so in Firefox/Safari the board sat dead
still. Add a continuous timed top↔bottom drift (48s, alternates) as the
universal baseline; keep the scroll-coupled pan as a Chromium enhancement that
overrides it. Motion-safe: both gated behind prefers-reduced-motion.
2026-06-27 20:54:08 +10:00
jwright 2aae7c287e ui: backdrop pan — monotonic top→bottom drift
build-and-deploy / build (push) Failing after 11m19s
The S→E→SE→NE loop wandered back near its start, so on a long page the
per-screen movement was imperceptible (worse once the image was zoomed to
215%). Replace it with a single continuous vertical pan (~40% travel) so the
board obviously drifts downward as the page scrolls.
2026-06-27 20:47:36 +10:00
jwright 9e177dcc41 ui+content: zoom the backdrop + de-dupe blog titles
build-and-deploy / build (push) Failing after 11m32s
- Backdrop image scaled 168% → 215% so the Bat-Computer board reads bigger
  and more immersive, with more room for the scroll-pan.
- Retitle the least-privilege post "The most secure credential is the one
  you never mount" → "Every pod holds a key to a door it never opens" so it
  no longer mirrors the "...inbound port is the one you never open" post.
2026-06-27 20:42:02 +10:00
jwright 99455d0168 chore(deps): upgrade Astro 6.4 → 7.0 (Vite 8)
Bumps astro to 7.0.3 and @astrojs/check to the matching release. Vite 8
under the hood; @tailwindcss/vite/sitemap/rss already compatible, Node 22
satisfied. Verified end-to-end: typecheck (0 errors), build, dist scan,
audit gate, and visual render (hero + blog + Shiki) all clean under the new
Rust compiler + Markdown pipeline.
2026-06-27 20:42:02 +10:00