Kayhan Atamyildiz

Base

The page ground and all body copy.

--white #fcfcfc
brand active
the page ground; was #fafafa on the pre-Astro site Reached through --surface-primary, --text-secondary
--black #09090b
brand active
all body copy; was #111111 pre-Astro. Tailwind zinc-950 Reached through --text-primary
--transparent rgba(0, 0, 0, 0)
brand reserve
no module references it

Rose

Tailwind's rose, adopted whole. The accent.

--rose-50 #fff1f2
tailwind reserve
--rose-100 #ffe4e6
tailwind reserve
--rose-200 #fecdd3
tailwind reserve
--rose-300 #fda4af
tailwind reserve
via --accent-subtle, itself reserve since 2026-09
--rose-400 #fb7185
tailwind reserve
--rose-500 #f43f5e
tailwind reserve
was --brand-primary until the semantic layer landed
--rose-600 #e11d48
tailwind reserve
--rose-700 #be123c
tailwind active
via --accent. The site's accent colour Reached through --accent
--rose-800 #9f1239
tailwind active
via --accent-strong (button hover) Reached through --accent-strong
--rose-900 #881337
tailwind reserve
--rose-950 #4c0519
tailwind reserve

Teal

A custom ramp — not Tailwind. The case-study chrome.

--teal-50 #eafff8
brand reserve
--teal-100 #cdfeec
brand reserve
--teal-200 #a0fadd
brand active
via --surface-brand (meta rail + glance panels) Reached through --surface-brand
--teal-300 #63f2cd
brand reserve
--teal-400 #25e2b8
brand reserve
--teal-500 #00d2aa
brand active
via --brand-mark (the .cs-kicker dash) Reached through --brand-mark
--teal-600 #00a488
brand reserve
--teal-700 #008370
brand reserve
both roles moved to --teal-800 in 2026-09 on contrast
--teal-800 #006759
brand active
via --text-brand, --text-brand-emphasis and --text-on-brand-muted Reached through --text-brand, --text-brand-emphasis, --text-on-brand-muted
--teal-900 #00554b
brand active
via --text-on-brand (meta rail dt/dd) Reached through --text-on-brand
--teal-950 #00302b
brand active
via --text-on-brand-strong (glance labels) Reached through --text-on-brand-strong

Sage

One step, not a scale. The muted panel ground.

--sage-50 #f0f7f0
inherited active
the .cs-tradeoff / .cs-reflect / editorial ground · via --surface-muted Reached through --surface-muted

Gray

Tailwind v4 slate. Borders, muted copy, disabled states.

--gray-50 #F8FAFC
tailwind reserve
--gray-100 #F1F5F9
tailwind reserve
--gray-200 #E2E8F0
tailwind reserve
--gray-300 #CAD5E2
tailwind active
via --border and --text-inverse Reached through --border
--gray-400 #90A1B9
tailwind active
via --border-dashed (the .cs-tradeoff rule) Reached through --border-dashed
--gray-500 #62748E
tailwind active
via --surface-tertiary, --border-strong, --text-disabled Reached through --text-disabled, --border-strong
--gray-600 #45556C
tailwind active
via --text-muted and --border-rule (footer) Reached through --text-muted, --border-rule
--gray-700 #314158
tailwind reserve
--gray-800 #1D293D
tailwind reserve
via --text-tertiary, which is itself unused
--gray-900 #0F172B
tailwind active
via --text-strong (the .cs-kicker) Reached through --text-strong
--gray-950 #020618
tailwind reserve

Blue

Tailwind's sky ramp under the name blue. Held in reserve.

--blue-50 #f0f9ff
tailwind reserve
--blue-100 #e0f2fe
tailwind reserve
consumed only by --gradient-blue, itself reserve
--blue-200 #bae6fd
tailwind reserve
--blue-300 #7dd3fc
tailwind reserve
consumed only by --gradient-blue, itself reserve
--blue-400 #38bdf8
tailwind reserve
--blue-500 #0ea5e9
tailwind reserve
--blue-600 #0284c7
tailwind reserve
--blue-700 #0369a1
tailwind reserve
--blue-800 #075985
tailwind reserve
--blue-900 #0c4a6e
tailwind reserve
--blue-950 #082f49
tailwind reserve

Highlight

Orange. Chosen, never given a job. Held in reserve.

--highlight-100 #FFE5D9
brand reserve
--highlight-500 #ff4500
brand reserve
orangered
--highlight-700 #C43400
brand reserve

White alpha

Only meaningful over imagery.

--white-alpha-10 rgba(255, 255, 255, 0.1)
inherited reserve
--white-alpha-20 rgba(255, 255, 255, 0.2)
inherited reserve
--white-alpha-30 rgba(255, 255, 255, 0.3)
inherited reserve
--white-alpha-40 rgba(255, 255, 255, 0.4)
inherited reserve
--white-alpha-50 rgba(255, 255, 255, 0.5)
inherited reserve
--white-alpha-60 rgba(255, 255, 255, 0.6)
inherited reserve
--white-alpha-70 rgba(255, 255, 255, 0.7)
inherited reserve
--white-alpha-80 rgba(255, 255, 255, 0.8)
inherited reserve
--white-alpha-90 rgba(255, 255, 255, 0.9)
inherited reserve

Black alpha

Only meaningful over imagery.

--black-alpha-10 rgba(0, 0, 0, 0.1)
inherited reserve
--black-alpha-20 rgba(0, 0, 0, 0.2)
inherited reserve
--black-alpha-30 rgba(0, 0, 0, 0.3)
inherited reserve
--black-alpha-40 rgba(0, 0, 0, 0.4)
inherited reserve
--black-alpha-50 rgba(0, 0, 0, 0.5)
inherited active
via --shadow-video Reached through --shadow-video
--black-alpha-60 rgba(0, 0, 0, 0.6)
inherited reserve
--black-alpha-70 rgba(0, 0, 0, 0.7)
inherited reserve
--black-alpha-80 rgba(0, 0, 0, 0.8)
inherited reserve
--black-alpha-90 rgba(0, 0, 0, 0.9)
inherited reserve
TokenChainValueOriginRole
--surface-primary --white #fcfcfc inherited the page ground
--surface-secondary --black #09090b inherited
--surface-tertiary --gray-500 #62748E inherited
--surface-inverse --black #09090b inherited
--surface-muted --sage-50 #f0f7f0 inherited was --surface-green, a raw hex declared in this file · .cs-tradeoff, .cs-reflect, and the editorial page ground
--surface-brand --teal-200 #a0fadd brand the tinted panel ground of the case-study layer · .cs-meta-rail, .cs-glance
--text-primary --black #09090b inherited all body copy
--text-secondary --white #fcfcfc inherited text on a dark or accent-filled ground · the pill CTA label
--text-tertiary --gray-800 #1D293D inherited
--text-inverse --gray-300 #CAD5E2 inherited repointed from the dead --cool-gray-300 in 9802307 · became unreachable when .design-system was retired
--text-strong --gray-900 #0F172B brand near-black section labels, a step lighter than body copy · .cs-kicker
--text-muted --gray-600 #45556C brand .cs-piece metadata
--text-disabled --gray-500 #62748E brand the non-interactive nav item
--accent --rose-700 #be123c brand
--accent-subtle --rose-300 #fda4af brand a placeholder marker has to be legible to work as a warning. --rose-300 on --surface-brand measured 1.55:1, so .cs-stat .n was repointed to --accent (5.15:1) in 2026-09 and this went to reserve
--accent-strong --rose-800 #9f1239 brand the accent one step down, for hover · solid and ghost button hover
--brand-primary --accent → --rose-700 #be123c brand reconciled 2026-09. Was --rose-500, which made the focus ring the one place the "brand" colour appeared while --rose-700 carried every visible accent. Also raises the ring against --surface-primary from 3.58:1 to 6.13:1 · the global :focus-visible ring
--brand-mark --teal-500 #00d2aa brand the .cs-kicker dash
--text-brand --teal-800 #006759 brand .cs-eyebrow
--text-brand-emphasis --teal-800 #006759 brand emphasis inside a callout, on --surface-muted. Darkened from --teal-700 in 2026-09: the contrast table on /design-system caught it at 4.30:1, under AA for body copy. Now 6.25:1 · .cs-tradeoff <b>
--text-on-brand --teal-900 #00554b brand meta-rail terms and definitions
--text-on-brand-strong --teal-950 #00302b brand glance and stat labels
--text-on-brand-muted --teal-800 #006759 brand de-emphasised copy on --surface-brand. Darkened from --teal-700 in 2026-09 (3.84:1, under AA). Now 5.58:1, still a visible step lighter than --text-on-brand. Same value as --text-brand-emphasis but a different role; they may diverge · meta-rail placeholders
--border --gray-300 #CAD5E2 brand .cs-piece at rest
--border-strong --gray-500 #62748E brand .cs-piece on hover
--border-dashed --gray-400 #90A1B9 brand the .cs-tradeoff dashed rule
--border-rule --gray-600 #45556C brand the footer's top rule
ForegroundBackgroundRatioGradeWhere
--text-primary --surface-primary 19.39:1 AAA Body copy on the page
--text-strong --surface-primary 17.38:1 AAA Section kickers
--text-muted --surface-primary 7.39:1 AAA Card metadata
--text-disabled --surface-primary 4.64:1 AA The inactive nav item
--text-brand --surface-primary 6.64:1 AA The case-study eyebrow
--accent --surface-primary 6.13:1 AA Accent copy and the focus ring
--text-secondary --accent 6.13:1 AA Button label, at rest
--text-secondary --accent-strong 7.81:1 AAA Button label, on hover
--text-on-brand --surface-brand 7.17:1 AAA Meta-rail terms and definitions
--text-on-brand-strong --surface-brand 11.81:1 AAA Glance and stat labels
--text-on-brand-muted --surface-brand 5.58:1 AA Meta-rail placeholders
--text-primary --surface-muted 18.25:1 AAA Copy inside a callout
--text-brand-emphasis --surface-muted 6.25:1 AA Emphasis inside a callout
--accent --surface-brand 5.15:1 AA Placeholder markers on a panel

Rows graded AA non-text clear 3:1 but not 4.5:1. That is the correct bar for a focus ring, a border or a large figure, and the wrong bar for body copy — check the "where" column before reusing a pairing.

--sans

Aa Gg Rr 24

At Haüss ↗ · Pedro Arilla
Neo-grotesque. Mid-century principles redrawn for screen, across 20 styles. 'At Haüss', sans-serif
brand active
Pedro Arilla, neo-grotesque. Set on * in reset.scss, so it carries the whole interface
--sans-alt

Aa Gg Rr 24

At Textual ↗ · Pedro Arilla
Editorial text face drawn from the texture and honest utility of monospace. 'At Textual', sans-serif
brand reserve
Pedro Arilla, an editorial text face drawn from monospace texture · declared and loadable, no job assigned
--serif

Aa Gg Rr 24

At Gambit ↗ · Andy Lethbridge
High-contrast serif with angular wedge serifs. Sharp, and built for editorial. 'At Gambit', serif
brand active
Andy Lethbridge, high-contrast serif with wedge serifs · .cs-reflect pull-quotes
--serif-alt

Aa Gg Rr 24

At King ↗ · Pedro Arilla
Display serif with sharp serifs and chubby terminals. 'At King', serif
brand reserve
Pedro Arilla, display serif · declared and loadable, no job assigned

All four faces are by Arillatype.Studio — At Haüss, At Textual and At King by Pedro Arilla, At Gambit by Andy Lethbridge. They are licensed to Kayhan Atamyildiz and are not redistributable: this site serves them, it does not offer them. If you like what they do here, buy them from the people who drew them.

--h1 32px → 72px used in 1 file
Twelve projects, one system
--h2 28px → 64px used in 1 file
Twelve projects, one system
--h3 24px → 56px used in 1 file
Twelve projects, one system
--h4 22px → 52px used in 1 file
Twelve projects, one system
--h5 20px → 48px used in 3 files
Twelve projects, one system
--h6 16px → 36px used in 7 files
Twelve projects, one system
--display-sm 32px → 48px deliberately outside the ramp
Twelve projects, one system

32 → 48px. The pre-2026-09 --h4 curve, renamed for what it actually does. Used by the mobile overlay nav and the glance stats

--p-lg 16px → 24px

Every size on this page travels with the viewport. Drag the window and the numbers above stay true, because they describe the token, not the moment.

--p 14px → 20px

Every size on this page travels with the viewport. Drag the window and the numbers above stay true, because they describe the token, not the moment.

--p-sm 14px → 16px

Every size on this page travels with the viewport. Drag the window and the numbers above stay true, because they describe the token, not the moment.

Line heights

TokenValueStatus
--lh-xs1emreserve
--lh-s1.1emactive
--lh-m1.2emactive
--lh-l1.4emactive
--lh-xl1.6emreserve

Weights

TokenSampleStatus
--fw-100 Hauss 100 reserve
--fw-200 Hauss 200 reserve
--fw-300 Hauss 300 reserve
--fw-400 Hauss 400 active
--fw-500 Hauss 500 active
--fw-600 Hauss 600 active
--fw-700 Hauss 700 active
--fw-800 Hauss 800 active
--fw-900 Hauss 900 reserve
--space-4
2px → 4px
--space-8
4px → 8px
--space-12
8px → 12px
--space-16
8px → 16px
--space-20
10px → 20px
--space-24
12px → 24px
--space-32
16px → 32px
--space-48
24px → 48px
--space-64
32px → 64px
--space-72
48px → 64px · reserve
--space-80
60px → 80px
--space-120
80px → 120px · reserve
--space-160
100px → 160px · reserve
--space-240
120px → 240px · reserve

The dark bar is the value at 390px, the light bar at 1920px. --space-72 and --space-64 land on the same maximum and differ only below it — visible above, and worth knowing before you reach for one.

Fixed sizes

TokenValueStatusRole
--size-0 0 reserve
--size-1 0.0625rem active hairline · meta-rail gutters
--size-1half 0.09375rem reserve
--size-2 0.125rem active meta-rail and .cs-meta gutters
--size-4 0.25rem active the .next link's internal gap
--size-8 0.5rem reserve
--size-12 0.75rem active added in 9802307 to resolve a gap in the ladder · .cs-piece metadata label
--size-14 0.875rem active .cs-piece link, footer copyright
--size-16 1rem active the fixed-position body span, .cs-tradeoff copy
--size-18 1.125rem reserve
--size-20 1.25rem active the header logo/title gap
--size-24 1.5rem active header and nav gutters
--size-32 2rem active small button height, mobile overlay nav label
--size-40 2.5rem active medium button height
--size-48 3rem active large button height
--size-60 3.75rem active added in 9802307 to resolve a gap in the ladder · the pill CTA height, the compact header logo
--size-64 4rem reserve
--size-72 4.5rem active the swatch chip on /design-system
--size-80 5rem active the header logo
--size-100 6.25rem reserve
--size-120 7.5rem reserve
--size-160 10rem reserve

Radius

--radius-4 2px → 4px active
--radius-8 2px → 8px active
--radius-16 8px → 16px reserve
--radius-24 16px → 24px reserve
--radius-full 62rem active
--shadow-sm
cleanup reserve
--shadow-base
cleanup reserve
--shadow-md
cleanup reserve
--shadow-lg
cleanup reserve
--shadow-xl
cleanup reserve
--shadow-2xl
cleanup reserve
--shadow-inner
cleanup reserve
--shadow-video
brand active
the halo under a framed video, lifting it off the mat. Was a hardcoded rgba literal in work-modules.scss until 2026-09
--shadow-card-hover
brand active
the six-layer lift under a hovered project card. Was a hardcoded literal in work-modules.scss until it was named here (2026-09). Deliberately not part of the -sm…-2xl scale; it is a bespoke ramp
--gradient-blue
brand reserve
defined in the restructure, never given a job
--gradient-mint
brand active
the mat behind framed video. Was a hardcoded literal in work-modules.scss until it was named here (2026-09)

Motion

TokenValueDrives
--duration-fast0.2s.cs-piece border and lift
--duration-quick0.25sthe "view case study" arrow
--duration-base0.3sthe next-project link
--duration-slow0.6sthe project-card image scale
--duration-reveal0.7sthe scroll-reveal fade and rise
--easeease-outthe only easing curve in the system

One easing curve, five durations. Every transition on the site now sits behind a prefers-reduced-motion guard — the card scale and the next-project lift were unguarded until 2026-09.

Layering

TokenValueRole
--z-content10lifts copy above a full-bleed figure · .metadata-container
--z-header30the mobile nav overlay, above everything · header.nav-open

Two stacking contexts on the whole site. A third should be a conversation, not a commit.

Variants Sizes
<Button href={url} variant="solid" size="xl" pill external>
  Read the case study
</Button>

Shape, colour and size are three independent decisions. Heights are fixed --size-* on purpose — a control whose height changes with the viewport is a tap target you cannot reason about. The site's own CTA is xl + pill, 60px tall.

Live, from the CMS — this is “Mobile Streaming in a Multi-Device Ecosystem”. Hovering scales the image 1.025 and lifts it on --shadow-card-hover, while the arrow travels 6px. Both are suppressed under reduced motion.

Role
Design systems lead
Team
Four engineers, one PM
Duration
Nine months
Platform
Web, iOS, Android
In one line

Cut the component library from 240 pieces to 61, and shipped the first release in a quarter.

61
components, from 240
faster to first build
Reflection
The hard part was never the components. It was agreeing what a component was.
Post-mortem, 2025

The blocks above run on representative props so they render whether or not the CMS is reachable. QuoteBlock is the one place a serif earns its keep — the pull-quote is At Gambit.

Mobile app home page
Priority feature components in a 3D format