Colour primitives
Raw colour spectrums. Components should not reference these directly — always use a semantic token (e.g. --color-section, --color-headline) so that retheming works.
Neutral
Greige
Colour tokens
Semantic tokens resolve to a different primitive per theme. Apply a theme by setting data-theme="light" or data-theme="dark" on any wrapping element.
| Token | Light | Dark |
|---|---|---|
| Section | ||
| section | Greige/greige-200 | Neutral/black |
| section-white | Neutral/white | Neutral/white |
| section-transparent | Greige/greige-900 | rgba(0, 0, 0, 0.38) |
| hero-scroll-fade | rgba(0, 0, 0, 0.45) | rgba(0, 0, 0, 0.45) |
| project-detail-overlay-backdrop | rgba(0, 0, 0, 0.52) | rgba(0, 0, 0, 0.52) |
| footer-reveal-backdrop | rgba(0, 0, 0, 0.48) | rgba(0, 0, 0, 0.48) |
| Text | ||
| headline | Neutral/black | Neutral/white |
| headline-highlight | Greige/greige-300 | Greige/greige-300 |
| copy-default | Neutral/black | Neutral/white |
| copy-highlight | Greige/greige-500 | Greige/greige-300 |
| eyebrow | Greige/greige-600 | Greige/greige-300 |
| Navigation | ||
| nav-item-default | Greige/greige-500 | Greige/greige-400 |
| nav-item-active | Greige/greige-700 | Greige/greige-200 |
| nav-item-underline | Greige/greige-700 | Neutral/white |
| Controls / filled | ||
| btn-filled-bg | Neutral/black | Neutral/white |
| btn-filled-text+icon | Neutral/white | Neutral/black |
| btn-filled-bg-hover | Neutral/white | Greige/greige-300 |
| btn-filled-text+icon-hover | Neutral/black | Neutral/black |
| Border | ||
| border | Greige/greige-300 | Greige/greige-800 |
| Cards | ||
| card-background | Greige/greige-50 | Neutral/neutral-960 |
| icon-card-background | F1F2F2 | Neutral/neutral-960 |
| quote-card-headline | Neutral/black | Greige/greige-300 |
| project-card-title | Neutral/white | Neutral/white |
| card-background-hover | Greige/greige-50 | Greige/greige-800 |
| contact-flyout-background | rgba(255, 255, 255, 0.8) | rgba(255, 255, 255, 0.8) |
| Icon | ||
| icon | Neutral/black | Neutral/white |
| Feedback | ||
| availability | 5CFF00 | 5CFF00 |
| success | 16A34A | 16A34A |
| success-bg | F0FDF4 | F0FDF4 |
| warning | D97706 | D97706 |
| warning-bg | FFFBEB | FFFBEB |
| error | DC2626 | DC2626 |
| error-bg | FEF2F2 | FEF2F2 |
Typography
Self-hosted typeface
Public Sans
--font-sans- Source
- Self-hosted in this repository
- Format
- ttf (variable)
- Files
- Normal:
/public/fonts/PublicSans-Variable.ttfItalic:/public/fonts/PublicSans-Italic-Variable.ttf - Weight availability
- 100 – 900 (variable)
- Weights used across the project
- 400 (Regular), 450 (undefined), 500 (Medium) — Primary typeface. Regular is used by H1–H3, weight 450 by paragraph body copy, and Medium by H4–H6.
Available weight stops
Swapping the typeface
- Drop the new font file or files into
/public/fonts/. - Update the
@font-faceblock insrc/styles/global.css(family name,src: url(), andfont-weightrange). - Update
--font-sansinside@themeto reference the new family name.
Self-hosted typeface
DejaVu Sans Mono
--font-mono- Source
- Self-hosted in this repository
- Format
- ttf
- Files
- Normal:
/public/fonts/DejaVuSansMono.ttf - Weight availability
- 550 only
- Weights used across the project
- 550 (Medium) — Secondary typeface. Used by Button and Eyebrow.
Available weight stops
Swapping the typeface
- Drop the new font file or files into
/public/fonts/. - Update the
@font-faceblock insrc/styles/global.css(family name,src: url(), andfont-weightrange). - Update
--font-monoinside@themeto reference the new family name.
Self-hosted typeface
Fraunces
--font-serif- Source
- Self-hosted in this repository
- Format
- ttf (variable)
- Files
- Light:
/public/fonts/Fraunces-Variable.ttfLight italic:/public/fonts/Fraunces-LightItalic-Variable.ttf - Weight availability
- 300 (Light) only
- Weights used across the project
- 300 (Light) — Tertiary typeface. Reserved for light upright and italic accents.
Available weight stops
Swapping the typeface
- Drop the new font file or files into
/public/fonts/. - Update the
@font-faceblock insrc/styles/global.css(family name,src: url(), andfont-weightrange). - Update
--font-serifinside@themeto reference the new family name.
Heading tokens
Simple spec table for the heading scale, matching the component visualization layout.
| Desktop / Max | Mobile / Min | |
|---|---|---|
| level="h1" | 78 px / 90 px | 40 px / 45 px |
| level="h2" | 50 px / 58 px | 32 px / 40 px |
| level="h3" | 36 px / 42 px | 24 px / 28 px |
| level="h4" | 24 px / 28 px | 20 px / 24 px |
| level="h5" | 20 px / 25 px | 18 px / 20 px |
| level="h6" | 16 px / 24 px | 16 px / 19 px |
Text tokens
Simple spec table for text variants, matching the component visualization layout.
| Desktop / Max | Mobile / Min | |
|---|---|---|
| variant="base" | 14 px / 22 px | 14 px / 22 px |
| variant="sm" | 12 px / 16 px | 12 px / 16 px |
Spacing tokens
Section spacings
A section has four padding options (top and bottom) and an optional 10px radius on either its top or bottom corners. The width is always full. The container inside the section determines the content width — not the section.
| Desktop / Max | Mobile / Min | |
|---|---|---|
| section-padding-big (lg) | 144 px | 64 px |
| section-padding-small (sm) | 64 px | 24 px |
| section-padding-extrasmall (xs) | 16 px | 16 px |
| section-padding-none (none) | 0 | 0 |
| section-rounded-none | 0 | 0 |
| section-rounded | 10 px | 10 px |
Container spacings
Mobile containers are fluid and keep --container-edge-gutter baked into width (8px on mobile and 16px from md). Width caps apply from md using container tokens and no desktop min-width floor, so the gutter stays visible and prevents horizontal overflow. Sections stay unpadded horizontally.
| Desktop / Max | Mobile / Min | |
|---|---|---|
| Container edge gutter (each side when section is narrower than width cap) | 16 px | 8 px |
| container-spacing-big (lg) | 1800 px | 359 px |
| container-spacing-small (sm) | 1020 px | 359 px |
Card paddings
Responsive inner padding tokens used by card components.
| Desktop / Max | Mobile / Min | |
|---|---|---|
| card-padding-xl | 40 px | 16 px |
| card-padding-s | 24 px | 16 px |
| card-padding-xs | 16 px | 8 px |
--button-padding-blockButton vertical padding6px--button-padding-inlineButton horizontal padding7px--button-gapButton content gap16px--eyebrow-padding-bottomEyebrow bottom padding24px--eyebrow-gapEyebrow content gap12px--icon-card-widthIcon card width346px--icon-card-body-gapIcon card body gap24px--icon-card-icon-sizeIcon card icon size12px--icon-card-icon-radiusIcon card icon radius1px--quote-card-padding-topQuote card top padding40px--quote-card-padding-bottomQuote card bottom padding24px--quote-card-padding-inlineQuote card horizontal padding16px--quote-card-content-gapQuote card content gap24px--quote-card-author-padding-bottomQuote card author bottom padding24px--quote-card-author-gapQuote card author content gap16px--quote-card-avatar-sizeQuote card author image size36px--quote-card-meta-font-sizeQuote card workplace font size10px--quote-card-meta-line-heightQuote card workplace line height14px--quote-card-meta-letter-spacingQuote card workplace letter spacing1px--quote-card-sticker-overlapQuote card sticker overlap16px--quote-card-sticker-widthQuote card sticker width114px--quote-card-sticker-heightQuote card sticker height31px--quote-card-arrow-sizeQuote card arrow size16px--project-card-max-widthProject card mobile maximum width375px--project-card-mobile-heightProject card mobile height300px--project-card-default-heightDefault project card desktop height500px--project-card-screen-widthProject card screen responsive width68.4736%--project-card-screen-max-widthProject card screen maximum width480px--project-card-big-heightBig project card desktop height850px--project-card-big-screen-widthBig project card screen responsive width82.1683%--project-card-big-screen-max-widthBig project card screen maximum width576px--project-card-mobile-screen-widthProject card mobile screen width320px--project-card-screen-aspect-ratioProject card screen aspect ratio8 / 5--project-card-screen-hover-scaleProject card screen hover scale1.015--project-card-screen-transition-durationProject card screen transition duration450ms--project-card-screen-transition-easingProject card screen transition easingcubic-bezier(0.22, 1, 0.36, 1)--project-card-meta-padding-inlineProject card metadata horizontal padding16px--project-card-meta-padding-bottomProject card metadata bottom padding16px--project-card-meta-layout-gapProject card metadata layout gap16px--project-card-meta-item-gapProject card metadata item gap10px--project-card-meta-dot-sizeProject card metadata dot size5px--project-card-reveal-durationProject card metadata reveal duration300ms--project-grid-gapProject grid gap6px--service-row-padding-blockService row vertical padding12px--footer-smiley-sizeFooter smiley size44px--footer-reveal-content-min-heightFooter reveal minimum content height100svh--header-nav-padding-blockHeader navigation vertical padding12px--header-nav-padding-inlineHeader navigation horizontal padding24px--header-logo-column-widthHeader logo column preferred percentage width50%--header-nav-items-gapHeader navigation items gap24px--header-nav-item-padding-blockHeader navigation item vertical padding2px--header-nav-item-underline-heightHeader navigation item underline height2px--header-mobile-nav-padding-blockMobile header navigation vertical padding12px--header-mobile-nav-padding-inlineMobile header navigation horizontal padding16px--header-mobile-nav-toggle-hit-sizeMobile header navigation toggle hit area44px--header-mobile-nav-item-underline-heightMobile header navigation item underline height1px--header-mobile-nav-brand-frame-widthMobile navigation brand frame width85px--header-mobile-nav-brand-frame-heightMobile navigation brand frame height21.048px--header-mobile-nav-brand-widthMobile navigation brand width81.582px--header-mobile-nav-brand-heightMobile navigation brand height16.19px--header-mobile-nav-toggle-widthMobile navigation toggle glyph width73px--header-mobile-nav-toggle-heightMobile navigation toggle glyph height16px--header-mobile-menu-padding-topMobile navigation submenu top padding80px--header-mobile-menu-padding-bottomMobile navigation submenu bottom padding40px--header-mobile-menu-row-padding-blockMobile navigation submenu row vertical padding8px--header-mobile-menu-nav-item-heightMobile navigation submenu item height38px--header-mobile-menu-nav-item-max-widthMobile navigation submenu item maximum width335px--header-mobile-menu-contact-heading-gapMobile navigation contact heading gap16px--header-mobile-menu-contact-label-widthMobile navigation contact label width49px--header-mobile-menu-contact-row-min-heightMobile navigation contact row minimum height32px--header-mobile-menu-divider-heightMobile navigation submenu divider height1px--header-mobile-menu-transition-durationMobile navigation overlay transition duration400ms--header-mobile-menu-transition-easingMobile navigation overlay transition easingcubic-bezier(0.22, 1, 0.36, 1)--contact-flyout-widthContact flyout width263px--contact-flyout-padding-blockContact flyout vertical padding12px--contact-flyout-padding-inlineContact flyout horizontal padding8px--contact-flyout-row-padding-blockContact flyout row vertical padding6px--contact-flyout-row-gapContact flyout row content gap24px--contact-flyout-label-widthContact flyout row label width48px--contact-flyout-rows-gapContact flyout rows gap6px--contact-flyout-dot-sizeContact flyout dot size8px--contact-flyout-backdrop-blurContact flyout backdrop blur8px--about-hero-foreground-width-mobileAbout hero foreground mobile width72%--about-hero-foreground-width-desktopAbout hero foreground desktop width35.5%--hero-heading-font-size-mobileHero heading mobile font size40px--hero-heading-font-size-desktopHero heading desktop font size78px--hero-heading-line-height-mobileHero heading mobile line height42px--hero-heading-line-height-desktopHero heading desktop line height80px--hero-entrance-media-durationHero entrance media duration1800ms--hero-entrance-content-durationHero entrance content duration1300ms--hero-entrance-foreground-delayHero entrance foreground delay160ms--hero-entrance-heading-delayHero entrance heading delay320ms--hero-entrance-meta-delayHero entrance metadata delay560ms--work-entrance-projects-delayWork page projects entrance delay720ms--hero-entrance-easingHero entrance easingcubic-bezier(0.16, 1, 0.3, 1)--hero-entrance-offsetHero entrance content offset16px--hero-entrance-media-scaleHero entrance media scale1.025--hero-availability-dot-sizeHero availability indicator size8px--hero-availability-pulse-durationHero availability pulse duration1800ms--hero-availability-pulse-scaleHero availability pulse scale2.25--closing-cta-font-size-fluidClosing CTA fluid font sizeclamp(48px, 7.2vw, 128px)--closing-cta-line-height-fluidClosing CTA fluid line height1--project-list-sticky-offsetSticky all-projects button viewport offset64px--project-detail-sidebar-widthProject detail fixed sidebar width210px--section-min-height-halfSection half viewport minimum height50svh--section-min-height-fullSection full viewport minimum height100svh--project-detail-section-min-height-halfProject detail half overlay minimum heightcalc((100svh - 2 * var(--margin-sm)) / 2)--project-detail-section-min-height-fullProject detail full overlay minimum heightcalc(100svh - 2 * var(--margin-sm))--project-detail-media-height-mobileProject detail mobile media height75svh--project-detail-mobile-content-gapProject detail mobile navigation-to-content gap40px--project-detail-overlay-backdrop-blurProject detail overlay backdrop blur14px--project-detail-overlay-entry-offsetProject detail overlay entry offset12px--project-detail-overlay-transition-durationProject detail overlay transition duration360ms--project-detail-overlay-easingProject detail overlay easingcubic-bezier(0.22, 1, 0.36, 1)--project-detail-related-section-gapProject detail related section top gap40px--project-detail-metadata-label-gapProject detail metadata label-to-value gap16pxGaps
Spacing between elements inside a section and inside a container.
| Desktop / Max | Mobile / Min | |
|---|---|---|
| gap-none | 0 | 0 |
| gap-sm | 8 px | 8 px |
| gap-md | 16 px | 8 px |
| gap-lg | 32 px | 24 px |
| gap-xl | 32 px | 32 px |
Margins
Responsive outer spacing tokens for section and component margins.
| Desktop / Max | Mobile / Min | |
|---|---|---|
| Margin XS | 8 px | 8 px |
| Margin SM | 16 px | 16 px |
| Margin MD | 32 px | 24 px |
| Margin LG | 100 px | 64 px |
Border radius tokens
radius-full
radius-xl
24px
radius-lg
16px
radius-md
8px
radius-sm
6px
radius-xs
4px
radius-2xs
2px
Shadow tokens
Small
--shadow-smMedium
--shadow-mdLarge
--shadow-lgQuick reference — all CSS tokens
| Variable | Default value | Usage in Tailwind |
|---|---|---|
| --color-black | #000000 | bg-[var(--color-black)] |
| --color-white | #FFFFFF | bg-[var(--color-white)] |
| --color-neutral-960 | #141414 | bg-[var(--color-neutral-960)] |
| --color-greige-50 | #FAFAFA | bg-[var(--color-greige-50)] |
| --color-greige-100 | #F4F5F5 | bg-[var(--color-greige-100)] |
| --color-greige-200 | #E7E9E9 | bg-[var(--color-greige-200)] |
| --color-greige-300 | #CCD1D0 | bg-[var(--color-greige-300)] |
| --color-greige-400 | #A1AAA8 | bg-[var(--color-greige-400)] |
| --color-greige-500 | #717A79 | bg-[var(--color-greige-500)] |
| --color-greige-600 | #525C5A | bg-[var(--color-greige-600)] |
| --color-greige-700 | #3F4947 | bg-[var(--color-greige-700)] |
| --color-greige-800 | #26302F | bg-[var(--color-greige-800)] |
| --color-greige-900 | #172120 | bg-[var(--color-greige-900)] |
| --color-greige-950 | #070E0E | bg-[var(--color-greige-950)] |
| --color-section | light: Greige/greige-200 · dark: Neutral/black | bg-[var(--color-section)] or text-[var(--color-section)] |
| --color-section-white | light: Neutral/white · dark: Neutral/white | bg-[var(--color-section-white)] or text-[var(--color-section-white)] |
| --color-section-transparent | light: Greige/greige-900 · dark: rgba(0, 0, 0, 0.38) | bg-[var(--color-section-transparent)] or text-[var(--color-section-transparent)] |
| --color-hero-scroll-fade | light: rgba(0, 0, 0, 0.45) · dark: rgba(0, 0, 0, 0.45) | bg-[var(--color-hero-scroll-fade)] or text-[var(--color-hero-scroll-fade)] |
| --color-project-detail-overlay-backdrop | light: rgba(0, 0, 0, 0.52) · dark: rgba(0, 0, 0, 0.52) | bg-[var(--color-project-detail-overlay-backdrop)] or text-[var(--color-project-detail-overlay-backdrop)] |
| --color-footer-reveal-backdrop | light: rgba(0, 0, 0, 0.48) · dark: rgba(0, 0, 0, 0.48) | bg-[var(--color-footer-reveal-backdrop)] or text-[var(--color-footer-reveal-backdrop)] |
| --color-headline | light: Neutral/black · dark: Neutral/white | bg-[var(--color-headline)] or text-[var(--color-headline)] |
| --color-headline-highlight | light: Greige/greige-300 · dark: Greige/greige-300 | bg-[var(--color-headline-highlight)] or text-[var(--color-headline-highlight)] |
| --color-copy-default | light: Neutral/black · dark: Neutral/white | bg-[var(--color-copy-default)] or text-[var(--color-copy-default)] |
| --color-copy-highlight | light: Greige/greige-500 · dark: Greige/greige-300 | bg-[var(--color-copy-highlight)] or text-[var(--color-copy-highlight)] |
| --color-eyebrow | light: Greige/greige-600 · dark: Greige/greige-300 | bg-[var(--color-eyebrow)] or text-[var(--color-eyebrow)] |
| --color-nav-item-default | light: Greige/greige-500 · dark: Greige/greige-400 | bg-[var(--color-nav-item-default)] or text-[var(--color-nav-item-default)] |
| --color-nav-item-active | light: Greige/greige-700 · dark: Greige/greige-200 | bg-[var(--color-nav-item-active)] or text-[var(--color-nav-item-active)] |
| --color-nav-item-underline | light: Greige/greige-700 · dark: Neutral/white | bg-[var(--color-nav-item-underline)] or text-[var(--color-nav-item-underline)] |
| --color-btn-filled-bg | light: Neutral/black · dark: Neutral/white | bg-[var(--color-btn-filled-bg)] or text-[var(--color-btn-filled-bg)] |
| --color-btn-filled-text-icon | light: Neutral/white · dark: Neutral/black | bg-[var(--color-btn-filled-text-icon)] or text-[var(--color-btn-filled-text-icon)] |
| --color-btn-filled-bg-hover | light: Neutral/white · dark: Greige/greige-300 | bg-[var(--color-btn-filled-bg-hover)] or text-[var(--color-btn-filled-bg-hover)] |
| --color-btn-filled-text-icon-hover | light: Neutral/black · dark: Neutral/black | bg-[var(--color-btn-filled-text-icon-hover)] or text-[var(--color-btn-filled-text-icon-hover)] |
| --color-border | light: Greige/greige-300 · dark: Greige/greige-800 | bg-[var(--color-border)] or text-[var(--color-border)] |
| --color-card-background | light: Greige/greige-50 · dark: Neutral/neutral-960 | bg-[var(--color-card-background)] or text-[var(--color-card-background)] |
| --color-icon-card-background | light: F1F2F2 · dark: Neutral/neutral-960 | bg-[var(--color-icon-card-background)] or text-[var(--color-icon-card-background)] |
| --color-quote-card-headline | light: Neutral/black · dark: Greige/greige-300 | bg-[var(--color-quote-card-headline)] or text-[var(--color-quote-card-headline)] |
| --color-project-card-title | light: Neutral/white · dark: Neutral/white | bg-[var(--color-project-card-title)] or text-[var(--color-project-card-title)] |
| --color-card-background-hover | light: Greige/greige-50 · dark: Greige/greige-800 | bg-[var(--color-card-background-hover)] or text-[var(--color-card-background-hover)] |
| --color-contact-flyout-background | light: rgba(255, 255, 255, 0.8) · dark: rgba(255, 255, 255, 0.8) | bg-[var(--color-contact-flyout-background)] or text-[var(--color-contact-flyout-background)] |
| --color-icon | light: Neutral/black · dark: Neutral/white | bg-[var(--color-icon)] or text-[var(--color-icon)] |
| --color-availability | light: 5CFF00 · dark: 5CFF00 | bg-[var(--color-availability)] or text-[var(--color-availability)] |
| --color-success | light: 16A34A · dark: 16A34A | bg-[var(--color-success)] or text-[var(--color-success)] |
| --color-success-bg | light: F0FDF4 · dark: F0FDF4 | bg-[var(--color-success-bg)] or text-[var(--color-success-bg)] |
| --color-warning | light: D97706 · dark: D97706 | bg-[var(--color-warning)] or text-[var(--color-warning)] |
| --color-warning-bg | light: FFFBEB · dark: FFFBEB | bg-[var(--color-warning-bg)] or text-[var(--color-warning-bg)] |
| --color-error | light: DC2626 · dark: DC2626 | bg-[var(--color-error)] or text-[var(--color-error)] |
| --color-error-bg | light: FEF2F2 · dark: FEF2F2 | bg-[var(--color-error-bg)] or text-[var(--color-error-bg)] |
| --font-sans | 'Public Sans', ui-sans-serif, system-ui, sans-serif | style={{ fontFamily: 'var(--font-sans)' }} |
| --font-mono | 'DejaVu Sans Mono', ui-monospace, SFMono-Regular, monospace | style={{ fontFamily: 'var(--font-mono)' }} |
| --font-serif | 'Fraunces', ui-serif, Georgia, serif | style={{ fontFamily: 'var(--font-serif)' }} |
| --button-padding-block | 6px | p-[var(--button-padding-block)] |
| --button-padding-inline | 7px | p-[var(--button-padding-inline)] |
| --button-gap | 16px | p-[var(--button-gap)] |
| --eyebrow-padding-bottom | 24px | p-[var(--eyebrow-padding-bottom)] |
| --eyebrow-gap | 12px | p-[var(--eyebrow-gap)] |
| --icon-card-width | 346px | p-[var(--icon-card-width)] |
| --icon-card-body-gap | 24px | p-[var(--icon-card-body-gap)] |
| --icon-card-icon-size | 12px | p-[var(--icon-card-icon-size)] |
| --icon-card-icon-radius | 1px | p-[var(--icon-card-icon-radius)] |
| --quote-card-padding-top | 40px | p-[var(--quote-card-padding-top)] |
| --quote-card-padding-bottom | 24px | p-[var(--quote-card-padding-bottom)] |
| --quote-card-padding-inline | 16px | p-[var(--quote-card-padding-inline)] |
| --quote-card-content-gap | 24px | p-[var(--quote-card-content-gap)] |
| --quote-card-author-padding-bottom | 24px | p-[var(--quote-card-author-padding-bottom)] |
| --quote-card-author-gap | 16px | p-[var(--quote-card-author-gap)] |
| --quote-card-avatar-size | 36px | p-[var(--quote-card-avatar-size)] |
| --quote-card-meta-font-size | 10px | p-[var(--quote-card-meta-font-size)] |
| --quote-card-meta-line-height | 14px | p-[var(--quote-card-meta-line-height)] |
| --quote-card-meta-letter-spacing | 1px | p-[var(--quote-card-meta-letter-spacing)] |
| --quote-card-sticker-overlap | 16px | p-[var(--quote-card-sticker-overlap)] |
| --quote-card-sticker-width | 114px | p-[var(--quote-card-sticker-width)] |
| --quote-card-sticker-height | 31px | p-[var(--quote-card-sticker-height)] |
| --quote-card-arrow-size | 16px | p-[var(--quote-card-arrow-size)] |
| --project-card-max-width | 375px | p-[var(--project-card-max-width)] |
| --project-card-mobile-height | 300px | p-[var(--project-card-mobile-height)] |
| --project-card-default-height | 500px | p-[var(--project-card-default-height)] |
| --project-card-screen-width | 68.4736% | p-[var(--project-card-screen-width)] |
| --project-card-screen-max-width | 480px | p-[var(--project-card-screen-max-width)] |
| --project-card-big-height | 850px | p-[var(--project-card-big-height)] |
| --project-card-big-screen-width | 82.1683% | p-[var(--project-card-big-screen-width)] |
| --project-card-big-screen-max-width | 576px | p-[var(--project-card-big-screen-max-width)] |
| --project-card-mobile-screen-width | 320px | p-[var(--project-card-mobile-screen-width)] |
| --project-card-screen-aspect-ratio | 8 / 5 | p-[var(--project-card-screen-aspect-ratio)] |
| --project-card-screen-hover-scale | 1.015 | p-[var(--project-card-screen-hover-scale)] |
| --project-card-screen-transition-duration | 450ms | p-[var(--project-card-screen-transition-duration)] |
| --project-card-screen-transition-easing | cubic-bezier(0.22, 1, 0.36, 1) | p-[var(--project-card-screen-transition-easing)] |
| --project-card-meta-padding-inline | 16px | p-[var(--project-card-meta-padding-inline)] |
| --project-card-meta-padding-bottom | 16px | p-[var(--project-card-meta-padding-bottom)] |
| --project-card-meta-layout-gap | 16px | p-[var(--project-card-meta-layout-gap)] |
| --project-card-meta-item-gap | 10px | p-[var(--project-card-meta-item-gap)] |
| --project-card-meta-dot-size | 5px | p-[var(--project-card-meta-dot-size)] |
| --project-card-reveal-duration | 300ms | p-[var(--project-card-reveal-duration)] |
| --project-grid-gap | 6px | p-[var(--project-grid-gap)] |
| --service-row-padding-block | 12px | p-[var(--service-row-padding-block)] |
| --footer-smiley-size | 44px | p-[var(--footer-smiley-size)] |
| --footer-reveal-content-min-height | 100svh | p-[var(--footer-reveal-content-min-height)] |
| --header-nav-padding-block | 12px | p-[var(--header-nav-padding-block)] |
| --header-nav-padding-inline | 24px | p-[var(--header-nav-padding-inline)] |
| --header-logo-column-width | 50% | p-[var(--header-logo-column-width)] |
| --header-nav-items-gap | 24px | p-[var(--header-nav-items-gap)] |
| --header-nav-item-padding-block | 2px | p-[var(--header-nav-item-padding-block)] |
| --header-nav-item-underline-height | 2px | p-[var(--header-nav-item-underline-height)] |
| --header-mobile-nav-padding-block | 12px | p-[var(--header-mobile-nav-padding-block)] |
| --header-mobile-nav-padding-inline | 16px | p-[var(--header-mobile-nav-padding-inline)] |
| --header-mobile-nav-toggle-hit-size | 44px | p-[var(--header-mobile-nav-toggle-hit-size)] |
| --header-mobile-nav-item-underline-height | 1px | p-[var(--header-mobile-nav-item-underline-height)] |
| --header-mobile-nav-brand-frame-width | 85px | p-[var(--header-mobile-nav-brand-frame-width)] |
| --header-mobile-nav-brand-frame-height | 21.048px | p-[var(--header-mobile-nav-brand-frame-height)] |
| --header-mobile-nav-brand-width | 81.582px | p-[var(--header-mobile-nav-brand-width)] |
| --header-mobile-nav-brand-height | 16.19px | p-[var(--header-mobile-nav-brand-height)] |
| --header-mobile-nav-toggle-width | 73px | p-[var(--header-mobile-nav-toggle-width)] |
| --header-mobile-nav-toggle-height | 16px | p-[var(--header-mobile-nav-toggle-height)] |
| --header-mobile-menu-padding-top | 80px | p-[var(--header-mobile-menu-padding-top)] |
| --header-mobile-menu-padding-bottom | 40px | p-[var(--header-mobile-menu-padding-bottom)] |
| --header-mobile-menu-row-padding-block | 8px | p-[var(--header-mobile-menu-row-padding-block)] |
| --header-mobile-menu-nav-item-height | 38px | p-[var(--header-mobile-menu-nav-item-height)] |
| --header-mobile-menu-nav-item-max-width | 335px | p-[var(--header-mobile-menu-nav-item-max-width)] |
| --header-mobile-menu-contact-heading-gap | 16px | p-[var(--header-mobile-menu-contact-heading-gap)] |
| --header-mobile-menu-contact-label-width | 49px | p-[var(--header-mobile-menu-contact-label-width)] |
| --header-mobile-menu-contact-row-min-height | 32px | p-[var(--header-mobile-menu-contact-row-min-height)] |
| --header-mobile-menu-divider-height | 1px | p-[var(--header-mobile-menu-divider-height)] |
| --header-mobile-menu-transition-duration | 400ms | p-[var(--header-mobile-menu-transition-duration)] |
| --header-mobile-menu-transition-easing | cubic-bezier(0.22, 1, 0.36, 1) | p-[var(--header-mobile-menu-transition-easing)] |
| --contact-flyout-width | 263px | p-[var(--contact-flyout-width)] |
| --contact-flyout-padding-block | 12px | p-[var(--contact-flyout-padding-block)] |
| --contact-flyout-padding-inline | 8px | p-[var(--contact-flyout-padding-inline)] |
| --contact-flyout-row-padding-block | 6px | p-[var(--contact-flyout-row-padding-block)] |
| --contact-flyout-row-gap | 24px | p-[var(--contact-flyout-row-gap)] |
| --contact-flyout-label-width | 48px | p-[var(--contact-flyout-label-width)] |
| --contact-flyout-rows-gap | 6px | p-[var(--contact-flyout-rows-gap)] |
| --contact-flyout-dot-size | 8px | p-[var(--contact-flyout-dot-size)] |
| --contact-flyout-backdrop-blur | 8px | p-[var(--contact-flyout-backdrop-blur)] |
| --about-hero-foreground-width-mobile | 72% | p-[var(--about-hero-foreground-width-mobile)] |
| --about-hero-foreground-width-desktop | 35.5% | p-[var(--about-hero-foreground-width-desktop)] |
| --hero-heading-font-size-mobile | 40px | p-[var(--hero-heading-font-size-mobile)] |
| --hero-heading-font-size-desktop | 78px | p-[var(--hero-heading-font-size-desktop)] |
| --hero-heading-line-height-mobile | 42px | p-[var(--hero-heading-line-height-mobile)] |
| --hero-heading-line-height-desktop | 80px | p-[var(--hero-heading-line-height-desktop)] |
| --hero-entrance-media-duration | 1800ms | p-[var(--hero-entrance-media-duration)] |
| --hero-entrance-content-duration | 1300ms | p-[var(--hero-entrance-content-duration)] |
| --hero-entrance-foreground-delay | 160ms | p-[var(--hero-entrance-foreground-delay)] |
| --hero-entrance-heading-delay | 320ms | p-[var(--hero-entrance-heading-delay)] |
| --hero-entrance-meta-delay | 560ms | p-[var(--hero-entrance-meta-delay)] |
| --work-entrance-projects-delay | 720ms | p-[var(--work-entrance-projects-delay)] |
| --hero-entrance-easing | cubic-bezier(0.16, 1, 0.3, 1) | p-[var(--hero-entrance-easing)] |
| --hero-entrance-offset | 16px | p-[var(--hero-entrance-offset)] |
| --hero-entrance-media-scale | 1.025 | p-[var(--hero-entrance-media-scale)] |
| --hero-availability-dot-size | 8px | p-[var(--hero-availability-dot-size)] |
| --hero-availability-pulse-duration | 1800ms | p-[var(--hero-availability-pulse-duration)] |
| --hero-availability-pulse-scale | 2.25 | p-[var(--hero-availability-pulse-scale)] |
| --closing-cta-font-size-fluid | clamp(48px, 7.2vw, 128px) | p-[var(--closing-cta-font-size-fluid)] |
| --closing-cta-line-height-fluid | 1 | p-[var(--closing-cta-line-height-fluid)] |
| --project-list-sticky-offset | 64px | p-[var(--project-list-sticky-offset)] |
| --project-detail-sidebar-width | 210px | p-[var(--project-detail-sidebar-width)] |
| --section-min-height-half | 50svh | p-[var(--section-min-height-half)] |
| --section-min-height-full | 100svh | p-[var(--section-min-height-full)] |
| --project-detail-section-min-height-half | calc((100svh - 2 * var(--margin-sm)) / 2) | p-[var(--project-detail-section-min-height-half)] |
| --project-detail-section-min-height-full | calc(100svh - 2 * var(--margin-sm)) | p-[var(--project-detail-section-min-height-full)] |
| --project-detail-media-height-mobile | 75svh | p-[var(--project-detail-media-height-mobile)] |
| --project-detail-mobile-content-gap | 40px | p-[var(--project-detail-mobile-content-gap)] |
| --project-detail-overlay-backdrop-blur | 14px | p-[var(--project-detail-overlay-backdrop-blur)] |
| --project-detail-overlay-entry-offset | 12px | p-[var(--project-detail-overlay-entry-offset)] |
| --project-detail-overlay-transition-duration | 360ms | p-[var(--project-detail-overlay-transition-duration)] |
| --project-detail-overlay-easing | cubic-bezier(0.22, 1, 0.36, 1) | p-[var(--project-detail-overlay-easing)] |
| --project-detail-related-section-gap | 40px | p-[var(--project-detail-related-section-gap)] |
| --project-detail-metadata-label-gap | 16px | p-[var(--project-detail-metadata-label-gap)] |
| --gap-none | 0px | gap-[var(--gap-none)] |
| --gap-sm | 8px | gap-[var(--gap-sm)] |
| --gap-md | min 8px · max 16px (viewport ≥768px) | gap-[var(--gap-md)] |
| --gap-lg | min 24px · max 32px (viewport ≥768px) | gap-[var(--gap-lg)] |
| --gap-xl | 32px | gap-[var(--gap-xl)] |
| --margin-xs | 8px | mt-[var(--margin-xs)] · mb-[var(--margin-xs)] |
| --margin-sm | 16px | mt-[var(--margin-sm)] · mb-[var(--margin-sm)] |
| --margin-md | min 24px · max 32px (viewport ≥768px) | mt-[var(--margin-md)] · mb-[var(--margin-md)] |
| --margin-lg | min 64px · max 100px (viewport ≥768px) | mt-[var(--margin-lg)] · mb-[var(--margin-lg)] |
| --section-padding-lg | min 64px · max 144px (viewport ≥768px) | py-[var(--section-padding-lg)] · Section padding prop |
| --section-padding-sm | min 24px · max 64px (viewport ≥768px) | py-[var(--section-padding-sm)] · Section padding prop |
| --section-padding-xs | 16px | py-[var(--section-padding-xs)] · Section padding prop |
| --section-padding-none | 0px | py-[var(--section-padding-none)] · Section padding prop |
| --section-rounded-none | 0px | rounded-[var(--section-rounded-none)] · Section rounded prop |
| --section-rounded | 10px | rounded-[var(--section-rounded)] · Section rounded prop |
| --container-edge-gutter | min 8px · max 16px (viewport ≥768px) | w-[calc(100%-2*var(--container-edge-gutter))] · Container mobile |
| --container-max-width | min 359px · max 1800px (viewport ≥768px) | md:w-[min(var(--container-max-width),calc(100%-2*var(--container-edge-gutter)))] · Container big |
| --container-min-width | min 359px · max 1020px (viewport ≥768px) | md:w-[min(var(--container-min-width),calc(100%-2*var(--container-edge-gutter)))] · Container small |
| --card-padding-xl | min 16px · max 40px (viewport ≥768px) | p-[var(--card-padding-xl)] · Card padding |
| --card-padding-sm | min 16px · max 24px (viewport ≥768px) | p-[var(--card-padding-sm)] · Card padding |
| --card-padding-xs | min 8px · max 16px (viewport ≥768px) | p-[var(--card-padding-xs)] · Card padding |
| --radius-full | 9999px | rounded-[var(--radius-full)] |
| --radius-xl | 24px | rounded-[var(--radius-xl)] |
| --radius-lg | 16px | rounded-[var(--radius-lg)] |
| --radius-md | 8px | rounded-[var(--radius-md)] |
| --radius-sm | 6px | rounded-[var(--radius-sm)] |
| --radius-xs | 4px | rounded-[var(--radius-xs)] |
| --radius-2xs | 2px | rounded-[var(--radius-2xs)] |
| --shadow-sm | 0 1px 2px 0 rgb(0 0 0 / 0.05) | shadow-[var(--shadow-sm)] |
| --shadow-md | 0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -2px rgb(0 0 0 / 0.1) | shadow-[var(--shadow-md)] |
| --shadow-lg | 0 10px 15px -3px rgb(0 0 0 / 0.1), 0 4px 6px -4px rgb(0 0 0 / 0.1) | shadow-[var(--shadow-lg)] |