SPB Git forge
38commits 1branches 0releases
338.7 MBsize
maindefault branch
2 h agolast push
HTML 53.9% TypeScript 44.5% JavaScript 0.6% SQL 0.5%

Web core: design system, shell, brand, home, map, search, live, datacenters index

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Simon-Pierre Boucher committed 21 days ago (Sep 11, 2026) parent 7863d2f

8 changed files +8 −2

modified apps/web/qa/home-320-up.png +0 −0

Binary file not shown.

modified apps/web/qa/home-360-up.png +0 −0

Binary file not shown.

modified apps/web/qa/home-390-down.png +0 −0

Binary file not shown.

modified apps/web/qa/home-390-up.png +0 −0

Binary file not shown.

modified apps/web/qa/home-430-up.png +0 −0

Binary file not shown.

modified apps/web/qa/home-768-up.png +0 −0

Binary file not shown.

modified apps/web/src/components/ui/button.tsx +1 −1
@@ -84,7 +84,7 @@ export function IconButton({ label, size = "md", variant = "ghost", active, clas
84 84 /** "View all →" style inline link. */
85 85 export function MoreLink({ href, children = "View all", className }: { href: string; children?: ReactNode; className?: string }) {
86 86 return (
87 − <Link href={href} className={cn("inline-flex items-center gap-1 text-[12.5px] font-medium text-ink-2 hover:text-accent", className)}>
87 + <Link href={href} className={cn("inline-flex items-center gap-1 whitespace-nowrap text-[12.5px] font-medium text-ink-2 hover:text-accent", className)}>
88 88 {children}
89 89 <span aria-hidden>→</span>
90 90 </Link>
modified docs/DESIGN.md +7 −1
@@ -40,7 +40,7 @@ Textures: `.graticule` (thin 48 px grid with a fade mask) on the home hero only.
40 40
41 41 - `app/layout.tsx`: fonts, metadata (title template `%s · DataCenterIndex`, OG/Twitter images generated), viewport themeColor, JSON-LD Organization + WebSite, `Header`, `MobileNav`, `CommandPalette`.
42 42 - Route groups: `(site)` = constrained `main` + `Footer`; `(map)` = full-viewport `main` (header stays relative).
43 −- Header: sticky, 48 px mobile / 56 px desktop. Wordmark + primary nav (≥ md): Map, Data centers, Operators, Markets, Countries, Projects, Rankings, Live · search trigger (⌘K) · theme toggle · burger (< lg) opening a two-column menu.
43 +- Header: sticky, 48 px mobile / 56 px desktop. Wordmark + primary nav (≥ lg): Map, Data centers, Operators, Markets, Countries, Projects, Rankings, Live · search trigger (⌘K, ≥ md) · theme toggle · burger (< 2xl) opening a two-column menu (secondary links inline only at ≥ 2xl).
44 44 - Mobile bottom nav: fixed, 5 items (Home, Map, Search, Projects, Rankings), safe-area padding, hidden while a map sheet is open (`body[data-hide-mobile-nav]`).
45 45 - Footer: 4 columns, credits line (“Built by Simon-Pierre Boucher · contact@spboucher.ai · Hosted on MacLustr”), data attribution line.
46 46 - Sticky filter bars on list pages sit under the header (`top-12 sm:top-14`).
@@ -85,6 +85,12 @@ Higher-level shared components: `components/facility-table.tsx`, `components/fac
85 85
86 86 Mark: a globe (circle + meridian) crossed by three rack lines; the middle line is the accent “index tick” running past the globe. `public/brand/logo.svg`, `logo-mark.svg`, `logo-dark.svg`; React `LogoMark`, `Wordmark`, `Logo`. Favicons: `app/icon.svg`, `icon.png` 512, `apple-icon.png` 180, `public/icons/icon-192/512(+maskable).png` (regenerate with `SHARP_PATH=<sharp> node apps/web/scripts/render-icons.mjs`).
87 87
88 +## Build notes (apps/web)
89 +
90 +- `@dci/core` is consumed from TypeScript source and uses NodeNext `./x.js` specifiers. Turbopack cannot map them to `.ts`, so the scripts run **webpack** (`next dev --webpack`, `next build --webpack`) with `resolve.extensionAlias` in `next.config.ts`. Client bundles resolve `@dci/core` through the `browser` export condition (`packages/core/src/index.browser.ts`, no Node built-ins); `tsconfig.json` mirrors it with `customConditions: ["browser"]` — in client components only import what that barrel exports (types, enums, normalize, api-types).
91 +- QA: `node apps/web/qa/shoot.mjs <suffix>` (Playwright from `~/Desktop/uqo-eval`; env `BASE`, `WIDTHS`, `THEME=dark`, `PAGES`) screenshots every core page at 320–1280 and reports horizontal overflow.
92 +- Dev-only quirk observed: Next 16 dev + webpack can throw a transient `SyntaxError: Unexpected end of JSON input` (manifest race) when pages are hit while compiling; production (`next start`) is unaffected.
93 +
88 94 ## Rules for new pages (entity pages, admin)
89 95
90 96 1. Server-render content; lazy-load maps/charts with `next/dynamic` (`ssr: false`).
91 97