P R O J E C T SC O N T A C T

[11]

ARCHITEKTON GDA — MODULE RENTAL WEBSITE

TIER C · YEAR 2026 · STATUS: WIP · LANGUAGES: JAVASCRIPT

Landing with an interactive rental map and a CMS panel — pure web design, 7 layout iterations

[FIG. 1] MISSION

architekton GDA has rented compact storage-and-office modules in the Tricity area since 1995 — and its web presence was a business-card leaflet that never answered the tenant's only question: what is available and where. I built a site whose core is an interactive location map (Leaflet): numbered property pins, business-card popups with the number of vacant units and a Google Maps directions link, schematic polylines of the S6/S7/A1 arteries. Next to the map lives a table of vacant units — floor area, price from, availability date, PDF floor plan — and every number (per-property availability, occupancy %, total m²) is computed by a single withDerived() function from a single data file, so the hero, spotlight and table never drift apart. The owner gets a password-protected /admin panel to edit properties, units and stats without touching code. The final composition — dark hero, diagonal bands, a spotlight with count-up stats — took seven layout versions, each documented with a screenshot.

[FIG. 2] ARCHITECTURE

LIVE DIAGRAM — coming up

[FIG. 3] CHALLENGES

[+][CH-01]

The decorative plus-field behind sections had one rule: no glyph may ever be cut by text. A plain background (CSS pattern, SVG) slices glyphs in half wherever a headline sits — ugly and illegible. I solved it with DOM geometry: PlusField renders pluses as grid cells and knocks out entire cells colliding with the bounding rectangles of text elements (getBoundingClientRect with a safety padding), and the grid recomputes on ResizeObserver and scroll, throttled through requestAnimationFrame. The measurement moment proved a separate trap: text rectangles are only trustworthy after webfonts settle, so the recomputation also fires delayed after layout stabilizes.

[+][CH-02]

Leaflet touches window at import time, and Next 14 renders components on the server — a static map import crashes SSR. So the map loads via next/dynamic with ssr:false and a placeholder in the map's background color, so hydration never jumps the layout. The real interactivity is a two-way landing↔map coupling: hovering a pin highlights the property card on the page, and selecting a property on the page opens its popup on the map — pins carry an occupancy state, the popup shows vacant-unit count and a directions link. Map centering averages the properties' coordinates; I know the limit of that shortcut (empty list → division by zero) and have the fix named.

[+][CH-03]

The CMS panel writes content and uploaded photos to disk — and Vercel's filesystem is read-only at runtime, so the write throws. Instead of hiding the constraint, the project owns it openly: readContent() gracefully falls back to the bundled seed (try/catch instead of a silent failure), production data comes from the committed content.json, and a comment in the upload code names the ceiling and the migration path to Vercel Blob. It's a conscious decision about the serverless execution model — the panel is fully functional on self-hosting, on Vercel it acts as a preview.

[+][CH-04]

Reaching the final composition took seven layout versions — each documented with a screenshot in the repo. The process worked like a design review with myself: version → Playwright screenshot → critique → next version. Whole directions died along the way (the brand orange as a gradient — rejected in favor of a flat #ec3d12 accent, never a gradient), and the palette froze into CSS tokens with rule-comments. The result: the site has a coherent system — one accent, two inks, texture only in chrome elements — instead of a collage of pretty sections.

[FIG. 4] AI LAYER

No model runs in the product — the map, table and CMS are fully deterministic. AI was the workshop, not an ingredient: the site was built entirely with Claude in a design-first regime — seven layout versions reviewed on Playwright MCP screenshots, project memory encoding decisions ('orange/black/white palette, texture only in the chrome'), and every deliberate shortcut in the code carries a comment naming its ceiling and upgrade path: single-password auth → NextAuth, disk upload → Vercel Blob.

[FIG. 4A] LAYOUT EVOLUTION — 7 VERSIONS

CLICK A VERSION — SAME SECTION, SUCCESSIVE TAKES (REVIEW ON SCREENSHOTS)

layout version FINAL

FINAL: dark hero, flat #ec3d12 accent (never a gradient), plus field knocked out under text

[FIG. 5] GALLERY

architekton GDA — module rental website — fig 5
[FIG. 5] 01/04
architekton GDA — module rental website — fig 6
[FIG. 6] 02/04
architekton GDA — module rental website — fig 7
[FIG. 7] 03/04
architekton GDA — module rental website — fig 8
[FIG. 8] 04/04

[FIG. 6] STACK & LINKS

NEXT.JS 14REACT 18LEAFLETFRAMER-MOTIONSPACE GROTESKJSON-AS-DBVERCEL
[RESTRICTED — CLIENT PROJECT]SEE IT LIVE