2

scrape.ly — Design System & Product Site

A web scraping platform's brand site built on a bespoke twelve-column editorial grid, a strictly layered design-token architecture with an enforced rule about what may reference what, and an A/B landing variant that reshapes the layout through CSS alone — no UI kit, no component-API cost.

Technology Stack

Next.js 16, React 19, TypeScript, Tailwind CSS 4, Framer Motion, HugeIcons, ESLint, Prettier, Vercel

Overview

Duration: 5/2026 - 6/2026

scrape.ly sells web scraping infrastructure — scrapers, proxies, an API, prebuilt templates, and a template store — to developers and data teams. The site covers the product lines, the resources, the company, and the legal surface.

The dependency list is deliberately short: Next, React, Tailwind, one animation library, one icon set, and nothing else. No UI kit, no CSS-in-JS. Everything visual is built on a design system defined in a single stylesheet and a small set of layout primitives — and that is the actual deliverable here. The pages are the easy part; the foundation is what determines whether the site still looks coherent after a year of other people adding to it.

The Grid System

Every page is composed from two primitives, and the whole site inherits its rhythm from them.

SiteGrid establishes a twelve-column grid. GridRow then splits each row identically every time — two columns of decor, eight of content, two of decor — as three components: a left decor cell, a content cell, and a right decor cell.

What makes it hold is the CSS underneath. Below the breakpoint, the grid is twelve equal columns. Above it, the template becomes fluid margin, gutter, eight content columns, gutter, fluid margin — so the content band is a fixed measure and all the extra space is pushed to the outside where it belongs. Rows stretch, which is why the decorative side cells always match the height of whatever content sits between them, with no manual sizing anywhere.

The decor cells are then configurable rather than fixed:

The result is an editorial, visibly-gridded layout — the kind that is normally hand-built per page and starts drifting within a week — expressed as one row component that every page calls.

Token Architecture

The stylesheet opens by declaring its own layer order, then holds to it:

  1. A primitive palette of raw values, annotated as never to be referenced from components
  2. Semantic tokens — page, background, surface, border — mapped into the framework so they become utilities
  3. Typography, spacing, and radius scales feeding the corresponding utilities
  4. Base styles last

The discipline is the deliverable. A component reaches for bg-surface or border-border, never a hex value, and never the primitive behind the token either. Retheming the entire site is an edit to layer two, and nothing below it needs to be opened. That is the difference between a design system and a stylesheet with good intentions.

Routes are organised with route groups — marketing, products, resources, company, legal — so the URL structure stays flat while the source tree groups by concern.

A typed routes module is the counterpart on the link side:

The A/B Variant

The landing page ships in two versions with a shared component folder and a small variant folder for each.

The B hero needs a different grid treatment from every other row on the site. Rather than threading a variant flag down through the grid primitives — which would put a test concern permanently into the layout API — the stylesheet handles it directly:

.grid-row:has(.landing-b-hero) { /* … */ }
.grid-row:has(.landing-b-hero) .content-cell { /* … */ }
.grid-row:has(.landing-b-hero) .decor-cell { /* … */ }

The row reshapes itself because of what it contains. The layout primitives stay unaware that variants exist, and adding a third would not touch them either. Marketing can test layouts without engineering paying for it in permanent API surface.

What makes this build stand apart from the other marketing work is that almost none of the value is in the pages. It is in a grid that can be described in one sentence, a token layer with an enforced rule about what may reference what, and a variant mechanism that adds nothing to the component API.