Files
such.software/README.md
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

81 lines
2.2 KiB
Markdown

# Such Software Website
Corporate website for Such Software LLC, a full-service software provider based in Kennett Square, PA.
## Lighthouse Scores
| Page | Performance | Accessibility | SEO | Best Practices |
|------|-------------|---------------|-----|----------------|
| Home | 99% | **100%** | **100%** | 77%* |
| Services | 98% | **100%** | **100%** | **100%** |
| About | 99% | **100%** | **100%** | **100%** |
*Home page Best Practices is 77% due to Cloudflare Turnstile third-party cookies.
## Tech Stack
- **Next.js 15** with App Router
- **React 18** + **TypeScript 5**
- **Tailwind CSS 3** + **Framer Motion 11**
- **Radix UI** accessible primitives
- **next-themes** for dark/light mode
- **Zod** for validation
- **Cloudflare Turnstile** for bot protection
- **Turborepo** + **pnpm 9**
## Project Structure
```
such-software-site/
├── apps/web/ # Next.js website
│ ├── src/app/ # Pages (home, services, about)
│ ├── src/components/ # React components
│ ├── tests/ # Playwright a11y tests
│ └── public/ # Static assets
├── packages/ui/ # Shared UI components
└── packages/config/ # Shared config
```
## Development
```bash
pnpm install # Install dependencies
pnpm dev # Start dev server at localhost:3000
pnpm build # Production build
pnpm start # Start production server
```
## Testing
```bash
cd apps/web
pnpm test:a11y # Run Playwright accessibility tests
pnpm test:ui # Run tests with interactive UI
```
42 accessibility tests across Chromium, Firefox, and WebKit covering WCAG 2.2 AA criteria, heading hierarchy, color contrast, and keyboard navigation.
## Accessibility
- **WCAG 2.2 AA**: engineered to meet, audited against (Lighthouse measured 100%)
- Skip-to-main link, semantic HTML5, ARIA labels
- Proper heading hierarchy, color contrast (4.5:1+)
- `prefers-reduced-motion` support
- Keyboard navigation, focus indicators
- Structured data (JSON-LD) and canonical URLs
## Environment Variables
Create `apps/web/.env.local`:
```env
NEXT_PUBLIC_TURNSTILE_SITE_KEY=your_site_key
TURNSTILE_SECRET_KEY=your_secret_key
```
See `apps/web/.env.example` for template.
## License
Proprietary - Such Software LLC