Commit Graph
12 Commits
Author SHA1 Message Date
jwinterm abc968fe6f feat(web): a gate for the repository, starting with the tags in the built HTML
The site had no CI of any kind: no .github, no .gitea, no workflow. The only
automation touching production is the redeploy timer, and it runs no checks. So
`pnpm run check` now exists as the single command, lint then build then the
metadata assertions, and it is the thing a CI lane will eventually call.

The first assertion reads the emitted HTML, because that is the only place the
defect it catches is visible. Next composes metadata at build time and merges it
shallowly, so a page declaring its own `openGraph` silently replaces the parent's
image. No diff, no type error and no lint rule shows that; only the output does.
Reintroducing the bug on /support was confirmed to fail this check, and the
refusal names the route, the missing tag, and what breaks without it.

It refuses rather than passing vacuously when there is no build output, or when
the output holds no HTML. A metadata checker that reports success over zero pages
is worse than none, because it is quoted.

Four tags per page, each with its reason: og:image, twitter:image, canonical,
description. 51 of 51 today.
2026-09-05 23:42:40 -04:00
jwinterm e1ea0ce18c chore(lint): migrate off next lint to the ESLint CLI and flat config
`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.
2026-08-17 06:06:14 -04:00
jwinterm 1dc0c5f06a fix(lint): make the linter run again, and finish the em dash sweep
The linter had two faults stacked on top of each other.

First, the global `ajv: ^8.17.1` override starved @eslint/eslintrc, which
needs ajv 6 and passes it `missingRefs`; ajv 8 rejects that option, so ESLint
died before loading a single rule. Scoped overrides give eslint and
@eslint/eslintrc ajv 6.12.6 and leave the audit override in place everywhere
else.

Second, underneath that, `extends: ["@repo/config/eslint-preset.js"]` could
never resolve: ESLint's shareable-config naming convention rewrites it to
`@repo/eslint-config-config/...`. require.resolve hands ESLint a real path.

With the linter running it reported 35 react/no-unescaped-entities errors
across 7 files. Those are escaped rather than silenced, using ESLint's own
coordinates so only flagged text nodes were touched. Lint now exits 0. Two
@next/next/no-img-element warnings remain on the splash logos, which are
deliberate: theme-paired and fetchPriority="high".

Em dashes are also gone from the six blog posts and the README (105
occurrences), same rules as the site copy: colons for definition labels,
commas for appositives, semicolons for independent clauses.
2026-08-17 05:53:16 -04:00
jwinterm 468eaa1d60 analytics: config-driven Umami tag + accurate privacy disclosure; fix @types/react v18/v19 dup that broke the build at HEAD 2026-06-12 13:24:54 -04:00
jwinterm e1ff60180b Trim oversized bento images + fix sizes; bump turbo (clears advisories)
- Cap the two wildly oversized bento source PNGs so Next can't serve giant variants:
  occupy-wallets 1200x837/393K -> 700x488/167K, neroswap 1584x672/1.8M -> 700x297/404K.
  (bauhaus/vegan are already 512px and self-cap; privacy-labs was already small.)
- Fix the bento <Image> sizes: object-contain height-constrains the image so it renders
  ~360px wide in either span; 66vw/100vw made Next serve up to ~750-1200w. Now
  '(max-width:768px) 90vw, 33vw'.
- Bump turbo 2.7.4 -> 2.9.16 (GHSA-hcf7-66rw-9f5r, GHSA-3qcw-2rhx-2726). pnpm audit
  now clean.
2026-06-07 18:15:10 -04:00
jwinterm b43c9d851b Homepage: Server Component + client splash island (cut hydration render-delay)
The data-URI logo still had LCP ~5s with zero network request, proving the
bottleneck is render delay (JS), not the image. So:
- page.tsx is now a Server Component. The hero, tagline, buttons, ServicesPreview,
  PortfolioGrid, and FounderSignature render as static server HTML (they had no
  client features, so they now hydrate to nothing).
- Splash state machine + header/nav/background gating + nebula position + scroll
  restoration moved into a small client island (home-shell.tsx) that takes the
  static content as children. Nebula reads the title via getElementById.
- Dedupe @types/react to 19 across the workspace (pnpm override) so the
  server->client children boundary type-checks.
2026-06-06 19:52:11 -04:00
jwinterm 927cf80c58 Fix blog build + clear 14 dependabot advisories
Build was failing because the new MDX post tried to `import` the
SuchMoonLaunchStoreButtons component — next-mdx-remote/rsc doesn't
support imports inside .mdx; components must be passed via the
`components` prop. Wire the helper into [slug]/page.tsx and drop the
import line from the .mdx.

Dependency bumps to clear the 14 outstanding Dependabot advisories
(9 high, 4 moderate, 1 low):
- apps/web/next: ^15.5.15 → ^15.5.18 (covers 12 next.js advisories)
- pnpm overrides: pin postcss ^8.5.14 (clears 1117015 XSS via </style>)
- pnpm overrides: pin fast-uri ^3.1.2 (clears 1117870 + 1117884 path
  traversal / host confusion)

pnpm audit: 14 vulnerabilities → 0.
2026-05-18 10:28:02 -04:00
jwinterm a6dc211ef6 Patch remaining dev-dependency advisories via pnpm overrides
Forces flatted, minimatch, picomatch, ajv, and brace-expansion to
patched versions across the transitive graph (ESLint, Tailwind, and
Playwright toolchains). Both prod and full audits now report no
known vulnerabilities.
2026-04-20 13:33:02 -04:00
jwinterm 7eb531170d Sharpen services page and bump deps to patch known vulns
- Brand Motion card rewritten with concrete capability language
- Revenue-share card clarified: no upfront fees, no retainers, low % after launch
- Recent Work section added with Occupy Wallets as the first case study
- Bumped next to ^15.5.15 to patch 2 high and 3 moderate advisories
- Added pnpm override for yaml ^2.8.3 to resolve the transitive next-mdx-remote
  stack-overflow advisory. Production audit now reports no known vulnerabilities.
2026-04-20 13:19:51 -04:00
jwinterm f2940ad956 Add documentation and fix pnpm start command
- Add README.md with tech stack, project structure, and dev setup
- Add TODO_ACCESS.md with Lighthouse audit results and priority fixes
- Add start script to root package.json
- Add start task to turbo.json
2026-01-17 10:32:01 -05:00
jwinterm d40a1caa85 style: fix portfolio image distortion, nebula animation timing and add parallax to computer 2026-01-16 10:36:22 -05:00
jwinterm 717a3be1c8 feat: Initial Monorepo Setup for Such Software
- **Architecture**: Initialized Turborepo monorepo with pnpm workspace.
- **Frontend**: Scaffolding for Next.js 14 app (apps/web) with Tailwind CSS v4 configuration.
- **UI System**: Created shared UI package (@repo/ui) with Shadcn/UI primitives (Card, Button).
- **Procedural Design**:
  - Implemented 'NebulaField' organic background animation for Home.
  - Implemented 'DataGrid' isometric background for Services.
  - Added 'DynamicBackground' for theme-aware transitions.
- **Features**:
  - Responsive 'ThemeToggle' with View Transitions API support.
  - 'PortfolioGrid' component showcasing key projects (r/CryptoCurrency, etc.).
  - 'FounderSignature' component detailing accessibility focus.
  - 'ContactForm' with Zod validation + turnstile integration stub.
- **Pages**:
  - Landing page with parallax/procedural visuals.
  - Services page highlighting Medusa v2 development capabilities.
- **Clean Up**: Removed initial Medusa backend scaffold to focus on frontend delivery first.
2026-01-15 15:43:47 -05:00