`next lint` is deprecated and disappears in Next 16. apps/web now runs
`eslint .` against eslint.config.mjs on ESLint 9, and the shared preset moves
to packages/config/eslint-preset.mjs. eslint-config-next 15 still ships only
an eslintrc-style config, so FlatCompat translates it; that keeps
next/core-web-vitals as the single source of rules.
The migration was done by hand rather than via @next/codemod, because the
codemod does not know about the shared @repo/config preset.
Two things worth knowing.
ESLint 9 only walks file extensions that some config names in `files`. The
first working version of this config linted three loose .js files, skipped
every .tsx in src/, and still exited 0 -- a green run that checked nothing.
The preset now names the extensions explicitly. Coverage went from 3 files to
82, and a deliberately broken canary component confirms rules still fire.
`@eslint/eslintrc` also needed a second scoped override: it does a default
import of minimatch and declares ^3.1.2, which the global ^9.0.7 audit
override broke. Same shape as the ajv fix in the previous commit.
- Streamers were rendering and hitting the monitor but invisible on phones:
preserveAspectRatio=none squishes the stroke horizontally on a narrow viewport,
so 0.12 went sub-pixel. Fatten 2.5x on mobile so they actually show.
- Terminal cursor now types 'such', backspaces, blinks ~6 times, then fades out
completely instead of blinking forever (it was distracting).
- Replace the centered dash with a tiny CSS terminal in the screen: types 'such'
once, backspaces, then the caret blinks on the left (steps() width typewriter).
- Impact pulse is snappier and brighter (0.9s ping, scale 1.14, bright cyan glow)
so streamer hits actually read; the screen color shifts with it.
- Pointer parallax dialed down to a subtle 6px with a gentler spring, fixing the
desktop 'shift up-left after load' (it was easing toward the cursor on first move).
- Revert the mobile streamer thinning/density cut from the prior commit: it made
them too sparse to see. Mobile now gets the full set at full weight, like desktop.
- Mobile jump fix: compute the monitor anchor from the title's document-absolute top
(scroll-independent) and only recompute on a real width change, so the address-bar
resize that fires mid-scroll no longer snaps it. Mobile parallax now lifts the field
up and away (faster than scroll) instead of drifting down over the text.
- Pointer parallax (desktop only): the field nudges toward the cursor, spring-damped
so it can never move abruptly. No mousemove on touch, so no mobile cost.
- Live monitor: a CSS blinking terminal cursor inside the screen (opacity only =
compositor); it shifts color on each streamer hit, reinforcing the impact pulse.
- Lighter mobile field: streamer density 8->5 and lines ~15% thinner on phones.
Desktop motion unchanged. (CSS/SMIL streamer rewrite deferred to its own commit.)
A phone has no left gutter like desktop, and the nebula was position:fixed, so
scrolling slid the text up into the pinned monitor (overlap + jumps). Keep the
monitor to the left of the title and keep the parallax, but on mobile the field
glides up and out with the hero (slower-than-scroll lag for depth) and fades as it
leaves, so it never crosses the content below. Only the monitor/streamer layer
fades; the base gradient stays. Extra top room (pt-44) keeps it clear of the header
at rest. Desktop unchanged.
Dials: yRangeMobile (parallax), heroOpacity range (fade), pt-44 (top room).
On phones the fixed monitor icon and its scroll parallax had no whitespace to live
in, so it drifted over the title/tagline and under the header. Fall back to the
static Cherenkov glow under 768px (same path as reduced-motion); desktop keeps the
full monitor + streamers.
- Logo is a plain <img fetchPriority=high> in a plain div (no framer-motion,
no drop-shadow filter) so it is a clean, statically-painted LCP candidate.
Water filter + a CSS zoom apply only on enter.
- Tracer target nudged to computerX/Y +1.5 (between the low-right +2.5 and the
high-left +0.5).
- Inline <svg> is not an LCP candidate; on mobile the tagline is hidden so the
logo was the only large element -> NO_LCP. Serve the mark as
/images/branding/splash-such.svg and render it via <img> (a valid LCP
candidate, painted from SSR HTML).
- Transition: start the cross-fade on click (shimmer plays as the splash fades
into the content) and shorten durations 1.2s -> 0.8s; snappier and blended.
- Tracer target back to the midpoint (computerX+0.5, computerY+0.5).
- Drop the two animated glow rings: stroke-dashoffset is non-composited, so
they repainted every frame next to the logo and prevented Lighthouse from
settling on an LCP (mobile NO_LCP). The static box + pulsing glow remain.
- Splash now cross-fades into the content: on enter it becomes a fixed overlay
and fades opacity to 0 over the revealed page, instead of a hard cut.
- Nebula tracer target moved up-and-left (computerX-1, computerY-1.5) so the
streamers converge on the monitor screen, not below-right of it.
- Removed the now-unused splash-* keyframes.
- Revert the nebula density/parallax change that disturbed the carefully
tuned streamer convergence (it gave no perf benefit; the nebula is behind
the splash and not in the load trace).
- Logo is now fully static (no float/breath) so it's a stable LCP candidate
on mobile; the rings, glow pulse, and staged button fade-ins still carry
the motion. (Desktop TBT win from the framer->CSS conversion is retained.)
- The splash's always-on animations (logo float/breath, the two traveling
glow rings) move from framer-motion (JS rAF every frame on the main thread)
to CSS keyframes (browser/compositor). framer now only drives the one-shot
click-to-enter water exit.
- Nebula: density 8 -> 4 and dropped the scroll parallax (the Forced-reflow
source); reduced-motion still gets the static background.
- Splash: full-viewport animated SUCH logo cover with four corner nav
buttons; reveals the site once "entered" (scroll-through or Explore) and
does not resurrect on scroll-up. Original hero restored beneath it
(title-anchored monitor pulse + Cherenkov-blue background).
- Logo: traveling Cherenkov glow ring + gentle letter breath (SVG/Framer,
reduced-motion safe); beveled glass corner buttons.
- Services: new "Nuclear & Radiation Modeling" section + "Consulting"
umbrella (payments, crypto, nuclear), MCNP Google Scholar link, and a
not-a-licensed-PE clarification.
- About/founder bio: LLNL credibility + accessibility, art101.io link.
- Products: add Barns & Neutrons, Alpha Doc, Decay Theory (detail pages,
OG cards, SVG icons); client-side sortable grid with coming-soon at the
bottom. New Neroswap + Custom Websites icons (de-duplicated).
- SEO: game pages added to sitemap.
- Copy: dial back em-dashes to colons/commas/parens on home + services.
- Add Playwright tests with axe-core (42 tests across 3 browsers)
- Add prefers-reduced-motion support to NebulaField
- Add JSON-LD structured data (Organization schema)
- Add canonical URLs to all pages
- Consolidate TODO files, update README
- Fix homepage heading hierarchy (h2 -> h1)
- Add page-specific metadata to services and about pages
- Fix outline-none on form inputs for keyboard accessibility
- Delete sync conflict files
- Add group class back to bento cards for hover animations
- Use raw CSS for glassmorphism to fix Tailwind opacity errors
- Add TODO.md with production checklist
- Add semantic CSS classes (.section-container, .glass-card)
- Update Tailwind config for opacity modifier support
- perfectly synced nebula streamer impacts with computer icon pulse
- standardized typography with left-border headers and blurbs across landing and services pages
- expanded services page with specialized solutions for commerce, custom apps, and crypto
- fixed bento grid image distortion and background persistence issues
- corrected hydration and syntax errors in nebula-field
- **Visuals**:
- Implemented 'Data Ingress' animation with lines starting from edges and converging to a fixed point.
- Added centralized 'Monitor' icon as the convergence target.
- Refactored 'NebulaField' to use percentage-based coordinates for perfect alignment on resize.
- Smoothed animation timing and easing.
- **Micro-interactions**:
- Increased transparency of Bento Grid cards (from 90% to 70%) for better visibility of background elements.
- Added backdrop-blur to cards.
- **Fixes**:
- Fixed 'bg-clip-text' bug cutting off descenders in the main headline.