Lightbox.astro — reusable native HTMLDialogElement wrapper:
- Trigger: <button> wrapping the <img>, cursor: zoom-in, amber zoom-pill
badge fades in on hover/focus.
- Dialog: showModal() opens a full-viewport modal (≤1800x1200 cap) with
blurred amber-tinted backdrop.
- Close paths: native form[method=dialog] submit (Escape + close button),
click on backdrop, click on the image itself.
- Accessibility: aria-labelledby + visually-hidden heading avoids both
aria-label-misuse and no-redundant-role validator conflicts. Focus
returns to trigger on close (native HTMLDialogElement behavior).
- Motion: 220ms fade+scale open, disabled under prefers-reduced-motion.
- CSP: <script> is Astro-bundled to an external file — script-src 'self'
respected.
Hero and ProductShowcase now use <Lightbox> instead of a raw <img> for
the product screenshots. The existing frame styling (border, glow, ring
overlay) is untouched — the lightbox trigger is a block-level button
that fills the frame.
TopographicBg now actually reads:
- Per-line stroke width varies (triangle wave — contour-interval feel)
- Per-line opacity varies by vertical depth (darker mid-section, lighter
edges)
- One line in four rendered in cyan (echo of cross-route correlation)
- Radial-mask soft edge fade so lines dissolve into the section boundary
- Default opacity bumped from 0.12 to 0.35; section callers still scale it
down via the opacity prop, but the new internal variation makes the
atmosphere visible where before it was invisible
WhyUs second tile: 3-AM storytelling moment now lands typographically:
- Decorative 03:00 glyph (amber/4% alpha) in the top-right corner
- Eyebrow log-entry treatment: pulsing amber dot + mono 03:00:47.218
timestamp + OPS DESK label — reads like a product UI log row
- The rest of the tile unchanged
ProductShowcase figure: figcaption moved to last child (HTML spec
requires figcaption to be first or last in a figure; a div after it was
a validation error).
- DualValueProps: 110ms staggered rise-in on load (cubic-bezier ease),
reduced-motion users see cards pre-populated, no animation.
- All card sections (DualValueProps, HowItWorks, WhyUs, Pricing) gain a
subtle hover lift: -translate-y-0.5, amber/40 border, soft amber drop
shadow. 200ms ease-out — tactile but not noisy.
- Pricing MID tier now looks like the highlighted option: ring-2 accent,
amber-tinted drop shadow, lg:-translate-y-2 (sits above the others),
and a 'MOST POPULAR' ribbon pill. The 1px border swap was invisible.
Editorial section between DualValueProps and HowItWorks. Breaks the
identical-rectangle cascade with an asymmetric 8/4 grid: large
error-detail screenshot with subtle cyan/amber backlight on the left,
three numbered callout captions on the right.
The screenshot (cross-route correlation chain + circuit breaker +
fallback + Java stack trace) makes the 'deep tracing, replay, live
control' claims concrete in a way the abstract RouteDiagram never did.
Cyan kicker on this section (vs. amber elsewhere) signals 'this one is
different' and echoes the cross-route correlation color in the product.
- Hero restructured from stacked to 2-col grid on lg+ (copy left, product
screenshot right). Replaces the abstract RouteDiagram with the actual
exchange-detail view — the product doing the thing the copy promises.
- Kicker broken out of the shared uppercase-mono pattern: italic pill with
a soft amber fill/border, scaled up to 14px. The humor now wears a
different costume from the other section kickers.
- Hero brand mark scaled to 64px and given a slow 7s sway (reduced-motion
guarded) — living atmosphere, not ambient animation.
- H1 min-height raised to 2.5em to absorb the 2-line wrap of line 1 at
mobile sizes without layout shift on rotation.
- Amber radial glow behind the product shot + subtle bevel + frame ring.
- Footer placeholder 3-wavy-lines SVG replaced with real camel logo
(spec gap from earlier refresh — header got swapped, footer didn't).
- Screenshot assets imported under public/product/.
Tile 2 headline now 'Built by people who know what 3 AM looks like.'
Bodies soften 'bidirectional protocol / signed config' into plain-value
language. nJAMS-legacy trademark review note preserved.
Three tiles: ship-then-sleep, debug-in-daylight, keep-what-you-chose.
Drops -javaagent, nanosecond, and 45+ EIP node types from the landing
copy — those belong in docs.
All three lines render in the DOM; CSS drives the fade via data-active.
Reduced-motion users see the first line only (no interval, no fade).
Rotation pauses on hover and keyboard focus. aria-live=off on the
rotator so AT does not announce every swap; aria-hidden flips per-swap
to avoid duplicate heading announcements.
Also set vite.build.assetsInlineLimit=0 in astro.config.mjs so Astro
emits the rotator script as a same-origin external file (dist/assets/)
rather than inlining it — required for CSP script-src 'self' compliance.
- Remove Sitemap line from robots.txt (no @astrojs/sitemap installed; was
pointing to a 404 that would trip Google Search Console).
- Align Permissions-Policy across all three enforcement layers (middleware,
.htaccess, Cloudflare Transform Rule in OPERATOR-CHECKLIST) by dropping the
stray fullscreen=(self) from the middleware.
- Bump Lighthouse CI numberOfRuns from 1 to 3 to dampen CI-runner noise.
- Add CI guard that fails the build if any <TBD:...> marker survives into
dist/ — prevents a legally incomplete imprint from shipping by accident.
- Add SFTP_* secret null-guard before the rsync --delete step so a missing
secret fails loudly instead of targeting the SSH user's home root.
- Document the set:html compile-time-constant invariant in DualValueProps.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- .htmlvalidate.json with relaxed rules for design-system inline styles
- linkinator.config.json skipping mail, external auth/platform origins
- Fix lint:html npm script quoting for Windows-shell compatibility
- Switch astro build.format to 'directory' so /pricing resolves without MultiViews
- trailingSlash: 'ignore' lets both /pricing and /pricing/ work naturally
- Add aria-label to both <nav> landmarks (Primary, Footer) to satisfy html-validate
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Exports buildSecurityHeaders() (pure, testable) and wires it into the
Astro onRequest middleware. Adds astro:middleware alias in vitest config
so the unit tests run outside Astro's build context. 14 tests pass (7
existing + 7 new).
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>