Francisco López

Design system

Design System

The skeleton shared by every page of the site: grid, layout tokens, vertical rhythm, type hierarchy and light/dark behavior. It doesn't define any section's content — it defines how everything inside breathes. It's the internal criterion the site is built and audited against.

1360px
Max container width
4 Breakpoints
640 · 768 · 1024 · 1280
42rem
Reading measure (~91 char.)
AA→AAA
Accessibility target
(01)

Page grid

A wide container for layout; a narrow reading measure for running text.

Base grid: 12 columnsGutter: var(--gutter) · 16–24pxThe band marks the 12 columns — use the «grid» button above to toggle it.

Container

Max 1360px, centered. Above xl the margins grow; the content never stretches.

Margins (page-x)

clamp(1.25rem, 5vw, 2.5rem) — 20px on mobile, up to 40px on desktop.

Reading measure

Running text never exceeds 42rem (~91 char.) even when the container is wide. The classic comfortable measure runs 45 to 75 characters, so 91 is above it — a conscious wide-container decision, not an oversight.

(02)

Layout tokens

This page's own contribution. They don't exist anywhere else in the system and move to the repository when the site is built.

:root { }Copy at a glance
--container:1360px;
--page-x:clamp(1.25rem, 5vw, 2.5rem);
--gutter:clamp(1rem, 2.2vw, 1.5rem);
--measure:42rem;
--section-y:clamp(4.5rem, 9vw, 9rem);

Fixed, not editable in production

--section-y and --measure have fixed values: clamp(4.5rem, 9vw, 9rem) and 42rem. There's no tuning panel anymore — the rhythm is the same across the whole site.

Defined once

They live in the site's :root alongside the color tokens; each page consumes them. Changing a value here changes it everywhere.

(03)

Breakpoints

base0 – 639px
Mobile

One column, everything stacked. aside above the content. Type at the clamp minimum.

sm≥ 640px
Large mobile

Buttons and metadata in a row; still one content column.

md≥ 768px
Tablet

The aside + content two-column grid appears. Margins grow.

lg≥ 1024px
Desktop

Full 12-column grid; aside can go sticky; 3-card grids.

xl≥ 1280px
Wide desktop

Container caps at 1360px, centered. Margins absorb the extra width.

They match the repo's Tailwind scale. This document also applies fluid type and spacing with clamp(): between breakpoints the size interpolates continuously, with no abrupt jumps.

(04)

Vertical rhythm and spacing

A 4px base scale (Tailwind). The air between sections is the primary tool of hierarchy.

Spacing scale

2xs8px
xs12px
sm16px
md24px
lg32px
xl48px
2xl64px
3xl96px
4xl128px

Rhythm between sections

--section-y · clamp(72 → 144px)
  • Between major sections: --section-y — 72px mobile → 144px desktop.
  • Section title → content: 40px (2.5rem).
  • Between blocks within a section: 24–32px. Optional hairline divider.
  • Every section opens with a 1px var(--border) divider full width.
(05)

Type hierarchy

Bricolage Grotesque (600) for headlines · Inter for text and UI. Fluid sizes: mobile = clamp minimum, desktop = maximum.

Discovery
LevelDisplay
FontBricolage 600
Desktop80px / 5rem
Mobile44px
Line height1.0
UseHero only
Milestones
LevelH1
FontBricolage 600
Desktop52px / 3.25rem
Mobile32px
Line height1.05
UseSection title
How I work
LevelH2
FontBricolage 600
Desktop32px / 2rem
Mobile24px
Line height1.15
UseSubsection
TheTool — SaaS B2B
LevelH3
FontBricolage 600
Desktop20px / 1.25rem
Mobile18px
Line height1.3
UseCard / case title
Results
LevelH4
FontBricolage 600
Desktop16px / 1rem
Mobile16px
Line height1.4
UseMinor heading
I research, prototype, build and measure.
LevelBody L
FontInter 400
Desktop18px / 1.125rem
Mobile17px
Line height1.6
UseSubheadline, intro
Senior Product Manager with 10+ years in B2B and B2C SaaS.
LevelBody
FontInter 400
Desktop16px / 1rem
Mobile16px
Line height1.65
UseRunning text (max 42rem)
Cofounder & PM · May 2016 – Oct 2021
LevelSmall / meta
FontInter 400–500
Desktop14px
Mobile14px
Line height1.5
UseDates, captions, labels
SENIOR PRODUCT MANAGER · UX · SAAS
LevelEyebrow
FontInter 600 · UPPER
Desktop13px
Mobile13px
Line height1.4
UseKicker above title
(06)

Light and dark

Same skeleton, same surface hierarchy: background → card → border. No heavy shadows — depth comes from hairlines and surface contrast. Light is warm paper; dark is deep blue.

Light modeFrom discovery to data.
Download CV
bg #F7F3EC · card #FCFAF6 · border #E7E4DD
Dark modeFrom discovery to data.
Download CV
bg #191D21 · card #21262B · border #2C333B

Color rule

  • primary is the only action color. secondary / muted / accent stay neutral.
  • Links, in two rules: primary for content links; foreground / muted-foreground for navigation chrome (nav, breadcrumb, footer).
  • Brand tones decorate or sign the logo — with one exception: brand-purple-accent is a brand tone used as text over inverted backgrounds (AA-large, ≥3:1). Splits and pastels, never as text.

Use the header toggle to see this same page in both modes.

(07)

Motion

150msMicro-interactions: hover, focus, buttons.
250msState changes: accordions, tabs.
600msSection scroll-reveal on entry.
easingcubic-bezier(.4, 0, .2, 1) — standard.
  • Reveal = fade + 12px rise, staggered ~60ms between children.
  • Restrained motion: it never competes with the content.
  • prefers-reduced-motion: transforms and auto-scroll are disabled. Content always appears, even if the JS fails.
Scroll-reveal demo

Nav transition — shared across the whole site

  • Symbol 48 → 28px and bar 80 → 64px, continuously with scroll.
  • The split's color layers extinguish before the symbol drops below 48px — it never passes through a mis-registration state.
  • The wordmark fades in opacity without clipping glyphs: the gap only collapses once it's invisible.
  • prefers-reduced-motion: a jump between states, no interpolation.
Francisco Lópezon load · 80px
on scroll · 64px · flat

It's the transition you're seeing right now in this page's header.

(08)

Accessibility

The list each page of the site closes with. AA as a non-negotiable floor; AAA whenever it's reached without visual cost.

Measured contrast

MeasurementLightDark
Body textforeground over background13.79:1AAA15.32:1AAA
primary as textlinks and accent7.01:1AAA8.36:1AAA
Text on buttonprimary-foreground over primary7.44:1AAA8.36:1AAA
muted-foregroundmuted over background7.12:1AAA7.08:1AAA
brand-purple-accentLarge text only (≥3:1) over inverted bg3.96:13.48:1

With this change, every text pair in the system reaches AAA in light and dark — none is left at AA. The one intentional exception is brand-purple-accent, which passes only as large text (≥3:1) over inverted backgrounds, never as body.

Closing checklist

  1. 01

    Measured contrast, with a figure, in both themes. AA is the non-negotiable floor; AAA whenever it's reached without visual cost.

  2. 02

    Visible focus: a 2px ring with var(--ring) and a 2px offset on every interactive element. Never outline:none without a replacement.

  3. 03

    Touch targets of 44×44px minimum, including small controls like the breadcrumb or the theme toggle.

  4. 04

    A single h1 per page and an h2–h4 hierarchy with no skips. Reading order is DOM order.

  5. 05

    Breadcrumb on every internal page, with <nav aria-label>, an ordered list and aria-current="page" on the current level.

  6. 06

    Nothing encoded by color alone: any state or category distinguished by color also carries text or shape.

  7. 07

    prefers-reduced-motion respected in every animation.

  8. 08

    Text alternatives: alt and labels where they inform, aria-hidden on the decorative.

Here · Design System

The internal criteria and the measurements. For whoever builds or audits the site.

Accessibility pageComing soon

The public statement: the level the site meets and how to report a problem. For a visitor. It doesn't live here.

(09)

Navigable skeleton

A schematic mockup of the home with placeholders — no defined content. It only demonstrates the vertical rhythm and grid shared by Hero, Milestones, How I work and the rest of the sections.

The mobile version is shown. The Desktop / Tablet / Mobile comparison is available on wide screens.

(01)Hero
(02)Milestones
(03)How I work
(04)Beyond the PM
(05)Career
(06)Education
(07)Toolkit
(08)Contact

Choose which categories you allow. Necessary cookies can't be turned off.