Anannyaa Kapur

Design system

The rules this site is built on. Every value and specimen below is read from the same tokens, fonts and components the site uses, so this page can’t drift from the real thing.

Principles

  • One grid. Every page sits on the same columns, so things line up from page to page without special cases.
  • Few decisions, all named. Colors, radii and motion are tokens with a job. A value without a name doesn’t ship.
  • Quiet by default. The work is the loudest thing on the page. Motion is small and only shows up where it helps.
  • Content is data. Case studies are checked files, so adding one never means touching layout code.

Color

Two neutral scales, one for text and one for surfaces, each with a light and a dark value. Text steps down in contrast as it gets less important, and every step clears WCAG AA (4.5:1) on the page background.

Textlight / dark

  • foreground

    Main text, headings and links

    #0a0a0a · 19.8:1#ededed · 16.9:1

  • secondary

    The name at rest in dark mode, so the shimmer shows

    #3d3d3d · 10.9:1#c2c2c2 · 11.1:1

  • tertiary

    Supporting links, like contact links

    #5c5c5c · 6.7:1#a6a6a6 · 8.1:1

  • muted

    Captions, labels and metadata

    #767676 · 4.5:1#8f8f8f · 6.1:1

Surfaceslight / dark

  • background

    Page background

    #ffffff#0a0a0a

  • surface

    Image placeholders and code

    #f2f2f2#171717

  • border

    Dividers and rules

    #e6e6e6#262626

Snake gamelight / dark

  • snake

    The snake. Lighter in dark mode so it stands out

    #2541b2#4d69db

  • snake-eye

    The snake’s eyes

    #ffffff#ffffff

  • snake-board

    The grey squares of the board

    #f7f7f7#121212

Typography

Two typefaces. Switzer does the work, and Geist Pixel is the accent, used in small doses so it stays special. Sizes come from a short scale.

SwitzerPrimary

Everything by default. Italic adds emphasis inside a sentence.

Geist PixelEmbellishment

Used sparingly: the name, work card titles, the word “for” and small labels.

  • LabelKey insight12 / 16
  • BodyProduct strategy + design + code16 / 20
  • ReadingLong-form case study writing16 / 24
  • HeadingSection heading24 / 30
  • DisplayCase study summary30 / 37.5
  • Figure+18%36 / 36

Grid

Four columns on phones, eight on tablets and twelve on desktop. On desktop the intro takes the first three columns, and everything else starts at column four.

BreakpointFromColumnsGutterMargin
Phone0412px16px
Tablet768px816px20px
Desktop1024px1216px20px

Radius

Corners stay nearly sharp. There are three steps, and Tailwind’s larger radius utilities are switched off, so nothing rounder than 6px can ship.

  • rounded-xs2px

    Inline code and small marks

  • rounded-sm4px

    Images, cards and placeholders

  • rounded-md6px

    The ceiling. Nothing is rounder.

Motion

Three motions, all short.

  • Hover over me

    Hover

    Words get slightly darker. Every link uses it.

    brightness 0.8 · 150ms

  • Icon swap

    The light/dark toggle. Click the icon to play it.

    250ms · blur 2px · from 0.25×

  • Anannyaa Kapur

    Shimmer

    A band of light across the name in the header.

    2000ms sweep · every 10s

The icon swap and shimmer come from transitions.dev, and both switch off for anyone who prefers reduced motion.

Components

Built once and reused everywhere.

Data-connected report builder for university funds

2026

Work card. The cover (or a placeholder), the title and the year. The caption darkens when the card is hovered.

A line can mix links, italic and pixel words.

Inline styles. Any line in the site config can be written this way.

Case study blocks

Completion
+18%
Tickets
−32%
Rating
4.8
  • FigureAn image with an optional caption, at text width, wide or edge to edge.
  • GalleryA grid of figures, two or three across.
  • ColumnsText next to a visual. Stacks on phones.
  • CalloutA key insight or pull quote.
  • StatsOutcome numbers.
  • VideoA looping, muted prototype clip.

See them in Publication-grade charting for financial analysts →

Content model

Each case study is a folder in content/work with an index.mdx file. Its details are checked against this schema when the site builds, so a missing field stops the build instead of breaking a page. The table is generated from that schema.

FieldTypeRequiredDescription
captionstringNoSmall grey line above the heading, e.g. the company or the kind of work.
titlestringYesProject name.
rolestringYesYour role on the project.
skillsstring | string[]NoDisciplines the work drew on.
timelinestringYesFree text, e.g. “2024” or “Mar – Aug 2025”.
teamstring | string[]NoWho you worked with.
toolsstring | string[]NoTools used.
statusstringNoWhere the work stands, e.g. “Shipped”. The row is left out without one.
coverimageNoImported image. Without one, a placeholder shows.
coverAltstringNoCover description for screen readers. Required with a cover.
coverVideostringNoPath to a video in /public, e.g. “/work/my-project/cover.mp4”. Plays muted on a loop over `cover`.
coverCarouselany[]NoImported images that cycle across the cover, one in the middle and its neighbours cropped at the edges. Sits on top of `cover`.
coverCardsany[]NoImported images shown as a stack of cards on the cover: every few seconds the front one tilts away and the next moves up. Sits on top of `cover`.
yearintegerYesShown on the gallery card.
ordernumberYesGallery position, lowest first.
draftbooleanNoShown locally with a Draft label, left out of the live site.
summarystringYesOne or two sentences describing the project. Not shown on the page: it's the description search engines and link previews use.
tagsstring[]NoTopics, kept for future filtering.