Home
Faiz IntifadaDesign Engineer · Bandung, Indonesia
Available for new work

or email hi@faizintifada.com

Foundations

The design system of this site: color, type, layout, shape, motion and interaction, with live samples.

Tokens in src/styles/global.cssPhone 390 to desktop 1440

Contents

Principles

  • One column, one grey. All text sits in a 600px column; secondary text is one grey at 65% black.
  • Photos carry the page. Media may break out to 960px; text never does.
  • Contrast by lightness. Links, names and titles are full black; everything else steps back.
  • Motion is feedback. Short, ease-out, transform and opacity only, and none for keyboard input or reduced motion.
  • Nothing is a dead end. Every control has a 44px hit area, a focus ring, and a real target.

Color

Neutral, near-black on white. The accent is the brand orange, but it never carries text. Ratios are WCAG 2 against white unless the row names another surface.

Text

  • Primarytext-fgTitles, headings, links, names#0a0a0a19.8:1
  • Secondarytext-fg-secondaryBody text, captions, meta, section labels#606060 (65% black)6.3:1
  • On darktext-whiteText on photos (with scrim) and dark bands#ffffff19.8:1 on #0a0a0a
  • On dark, secondarytext-white/65Dates and labels on dark surfaces#a9a9a98.4:1 on #0a0a0a

Surface

  • Pagebg-bgPage background#ffffff
  • Subtlebg-bg-subtleCallouts, code blocks, demo frames#f9f8f6Secondary text 6.2:1
  • Mutedbg-bg-mutedImage placeholders while loading#f2f1ef
  • Hoverbg-bg-hoverHover fill of icon buttons4% black
  • Inversebg-bg-inversePrimary button, dark band, video frame#0a0a0a

Line

  • Borderborder-borderCode block ring, card outlines8% black
  • Dividerborder-border-subtleList rows, footer rule, table rows4% black
  • Photo edgering-black/10 (inset)1px edge inside every photo and screenshot10% black
  • Photo edge, darkring-white/10 (inset)The same edge on dark surfaces10% white

Accent and status

  • AccentaccentBrand, contribution graph. Not for text#ff63082.98:1, fails for text
  • Focus ring--color-focusKeyboard focus outline, 2px, offset 2pxoklch(0.62 0.186 42.2) ≈ #dd54013.9:1 (needs 3:1)
  • Successbg-successOnline dot on the contact avatar only#28c840Not for text (2.2:1)
  • Success texttext-success-text“Copied” on the hero email#0c84634.7:1

Work tile gradients

  • Purple-pink → orange-gold
  • Grey-blue → deep brown
  • Mist-blue → deep sea blue
  • Mist-blue → ink green
  • Lavender → midnight purple
  • Sky-grey → rust red

Shown without blobs and grain. The tiles add four blurred blobs and 1px grain (128 ± 70, overlay 0.4).

Typography

Geist for everything, at two weights: 400 and 500. Paper Mono only for labels on photo prints and for code. Four sizes — 13, 14, 16 and 18 — at 1:1 pixels.

  • Largetext-large · 18 / 1.35–1.5AI Foundation for DeveloperPage title, quote
  • Bodytext-body · 16 / 1.6 · 400I design and build digital products, from the first frame in Figma to the live release.Body text, intro
  • Body strongtext-body · 16 / 1.4 · 500The problemHeadings, card and row titles, names
  • Secondarytext-small · 14 / 1.6 · 400Selected workSection labels, sub-lines, contents list, small links
  • Metatext-meta · 13 / 1.5 · tabularOct 20 · 23:09 · 62 peopleDates, counts, captions, durations
  • MonoPaper Mono 13 / 1.65 · −0.3pxIT Fair Bootcamp UIN SGD Jun 2026Photo-print labels, code, file names
  • Lines stay near 75 characters: 16px in a 600px column.
  • Numbers that line up or change use tabular figures: dates, counts, durations.
  • Titles use text-balance, paragraphs text-pretty. Real characters: “ ” ’ … — ·
  • Weight never changes on hover. State shows with color or an underline.

Layout and spacing

Three tracks on one page grid (.page-grid). They shrink on their own: at 768px the breakout is 720px, and on a 390px phone both content and breakout are 350px. Side gutters are 20px, and 24px from 640px.

fullbreakout 960content 600
A child picks its track with col-breakout or col-full; the default is content.
  • Full1440pxEdge to edge (the work carousel and swipe rows scroll here)
  • Breakout960pxWide images, galleries, video grid, photo stack
  • Column600pxAll text: about 75 characters per line at 16px

Spacing in use

  • 4Icon to text in small links
  • 8Inline gaps, list item gap
  • 12Image to caption, gallery gap
  • 16Heading to content
  • 24Gap between cards, between carousel tiles
  • 40Header to article body
  • 64Body to footer
  • 96Between home sections
  • 120Before Selected work and before the footer (80 on phones)

Shape and depth

Radius grows with size. A nested surface takes the outer radius minus the gap between them.

  • rounded-md6px · Duration badge
  • rounded-lg8px · Small thumbnails, buttons in code bars
  • rounded-xl12px · Code blocks, callouts, list rows
  • rounded-2xl16px · Photos, video thumbnails, demo frames
  • rounded-[18px]18px · Avatar (56px)
  • squircle32px · Work tiles, with corner-shape: squircle (16 elsewhere)
  • rounded-full∞px · Icon buttons, pills, status dot

Edges and shadows

  • Photo edge. 1px inset ring, 10% black (10% white on dark). Every photo has it.
  • Avatar. shadow-avatar with a 2px white outline.
  • Photo print. shadow-print: a 1px ring, a tight shadow, a soft one. A lifted print adds shadow-print-lift.

Elevation

One light from above, so every shadow falls down and is pure black: a tint looks dirty next to the photos. A surface that sits higher gets a larger, softer shadow. Floating surfaces add a hairline, so the edge stays sharp on white.

  • shadow-printPhoto prints at rest
  • + print-liftAdded when a print lifts
  • shadow-avatarAvatar in the hero
  • shadow-buttonPlay button on a video
  • shadow-pillComposer pill
  • shadow-floatContribution tooltip
  • shadow-overlayHover card of a tool or link
  • shadow-dialogContact card

Motion

Four timings. Press a row to play it on its real curve.

  • Animate transform and opacity (and color). Never width, height or position.
  • Keyboard switches are instant: no fade when arrow keys or Tab change a preview.
  • Hover effects only on devices that can hover. Reduced motion turns all of it off.

Interaction

  • I founded VibeDev ID.Text link. Black, underline at 30%, full on hover.
  • YouTube channel Small link. 14px grey, black on hover, 44px tall hit area.
  • Icon button. 32px circle, 44px hit area (dashed). Off: 35% opacity.
  • FocusedFocus ring. 2px, offset 2px, --color-focus (3.9:1). Keyboard only.
  • No href="#": items without a page are plain text.
  • Hover never hides content: captions also show on keyboard focus and on touch screens.
  • Phones have no fixed contact avatar (it would cover text); the header avatar opens the contact card.

Icons

One set, 24px grid, 2px stroke, currentColor. Icons are decoration: a button with only an icon gets anaria-label. Sizes in use: 12, 14, 16 and 22.

  • arrow-left
  • arrow-right
  • arrow-up-right
  • download
  • copy
  • check
  • play
  • lightbulb
  • presentation
  • video
  • link
  • chevron-down

Tokens

In src/styles/global.css:

  • --color-fg-secondary: 65% black (6.3:1), all secondary text.
  • --color-focus: oklch(0.62 0.186 42.2), used by :focus-visible.
  • text-meta, text-small, text-body, text-large: 13 / 14 / 16 / 18 with their line heights.
  • --shadow-*: the elevation scale, from print to dialog.
  • --ease-out, --ease-in-out and --ease-lift.
  • .page-grid, .page-sub, col-breakout, col-full and pad-content.