Sujin Kim.React 19 portfolio website for a graphic designer

Figma to React build · 2025

Sujin is a UI/UX, branding and graphic designer, so the brief was less “show my work” than “the site is a piece of work”. She designed it as a gallery: three rooms rather than pages, and a career you walk through rather than read. I built it.

That framing decides the engineering. A gallery has no address bar and no scrollbar, so the site has neither: one URL, a state machine, and scroll treated as a step rather than a distance. The work was making an interface that behaves like a place while staying something its owner can still add a year to.

The contact page: two cards dropped at slight opposing angles on a near black ground, a dark form card headed Name with phone, email and note fields above a Send Note button, and a bone white card behind it carrying Leave a Note in an oval
The third room. Two cards land at a resting tilt, as though dropped on a desk.
The landing page: A curated archive of, then Design and Perspective set very large in an editorial serif, black on bone white, with Curated by Sujin Kim on a rule between them and a Click here or Scroll to begin prompt at the right
The entrance. At rest the word is real text; the moment a cursor enters it, it is roughly 90,000 particles.
01

Outcomes

3 rooms
Entrance, Exhibition and Invitation, reached without a router and without a single route
12
Chapters of career history, all derived from one data file rather than built by hand
~90k
Particles sampled from the pixels of one word, at 60fps, under the cursor
02

From Figma to build

What arrived was unusually complete: a designer's file, drawn to the pixel, with the type and spacing already decided. What it could not describe is the part that matters most here, because a static frame has no way to say how long a transition takes or what a scroll means. The archive was handed over as one continuous column. The build had to turn it into somewhere you move through.

The Figma
The career archive as a single Figma frame: year blocks for 2024, 2023 and 2022 stacked one under another down a tall dark column, each with a large serif year, an employer, a job title and a description
The archive as delivered: one column, 6,235 pixels tall, every year stacked. This is the top of it.
The exhibition page in Figma: the three-item navigation, five filter pills with ALL filled in white, a search field reading Type to dig through the archive, and the Korean logotype palbangmiin below
The exhibition, with a search field above the archive and twelve project slots waiting to be filled.
The build
One chapter of the built archive filling the viewport: 2023 set large with 2022 beneath it, the ADsologist entry beside them, and a year rail from 1991 to 2025 along the bottom with a warm glow falling from the active dot
One chapter, one screenful, one scroll. The rail along the bottom is the part the column could not have: a sense of where you are in a career.
The built exhibition page: the same navigation and five filter pills, with the Korean logotype palbangmiin large and white below them and the first row of project cards beginning at the foot of the screen
The same page built, with the search field dropped and the logotype turned into something that opens.
  • The archive: one continuous column twelve full-screen chapters, generated from a data file, with a year rail to navigate them
  • Finding work: a search field and five category filters the filters alone, since six projects across five categories is a list to browse rather than a corpus to query
  • The category image: a static logotype two halves that slide apart on hover to expose a dictionary entry underneath
03

Building it in React 19

None of this photographs. A screenshot of the hero is a word, and a screenshot of the archive is a page: the whole argument of the site is what happens between two of them. So the clip below is the honest version of the build.

The site being used end to end: the hero shredding under the cursor, the line wipe out of the entrance, a year per scroll, and the exhibition splitting open.
Sujin Kim / the three rooms
Entrance
The landing page on a phone: A curated archive of Design and Perspective set in a large editorial serif, black on bone white, with Curated by Sujin Kim on a rule and a Scroll to begin prompt
The foyer
Archive
A career chapter on a phone: the year 2023 set large in an editorial serif above ADsologist, Marketing Agency Toronto Canada, the title UIUX Graphic Designer, a paragraph of description and a list of five disciplines, white on near black
One year per scroll
Exhibition
The project grid on a phone: a photograph of red and white takeaway packaging above the title Logo Design, the year 2025, the tools used and a short description, with the next project beginning below
The gallery floor
Arrive in the foyer, walk the archive one year at a time, then reach the gallery floor. The museum language is not decoration: it is the information architecture, and the copy carries it through.
The project grid: four large project photographs in two columns, each captioned with its title, year, the tools used and a short description in white on near black
The gallery floor. Filtering runs on tags rather than a single category, so a logo project can sit under both Branding and Graphic.
A project detail page: a full-width photograph of yellow supplement packaging on a blue and cream ground, under a Back to Exhibition button and the site navigation
Each block of a project page has its own entrance, fired by an observer as it comes into view, so the page assembles rather than simply appearing.

The hero is not text

The word is painted to a canvas once, read back with getImageData, and every pixel above alpha 50 becomes a particle with its own size and its own sensitivity to the cursor. Inside a 100px radius they are pushed away along the vector from the mouse, so the word does not shift, it shreds. Two layers crossfade, which keeps the typography sharp at rest and only pays for particles while someone is touching it.

Scroll read as intent, not distance

The page never scrolls: it is overflow hidden throughout, with a hidden element giving Lenis something to measure and each chapter moved on a transform. Four input sources feed one index, behind a 1000ms lockout and a velocity floor, so one flick of a trackpad advances exactly one year rather than three.

An archive the client can extend

The twelve chapters are not twelve components. They are derived at module scope from one keyed data file, which splits composite keys so a single year can hold several pages and branches when several things happened at once. The file documents the contract in its own comment, so adding a year is duplicating an object.

Also in the build: a nav that scrambles its letters through five randomised phases before resolving, a warm glow that falls from the active year onto the rail below it, seven photographs of the client's dog wired up as cursors, and an explicit filename to import map so the data files can stay plain strings while Vite still gets imports it can fingerprint.

StackReact 19Vite 6styled-components 6LenisCanvas 2DAdobe Typekit
04

Results

  • The metaphor survived the build: Entrance, Exhibition and Invitation are the actual architecture, not section headings, and the copy stays in the same voice all the way down to the archive calling itself a chronicle.
  • The hero is hers, not an effect: the particles are sampled from the letterforms of her chosen display face, so what scatters is the typography rather than a generic field laid over it.
  • She can extend it without me: a new year in the archive is a duplicated object in one data file, which is why the twelve chapters are generated rather than drawn.

“Victor is absolutely amazing developer to work with. He is very responsible professional, and his kind advice will make your project even better. Attentive, caring, professional person to work with. Will definitely work with him again.”

Sujin Kim, via Upwork
05

Reflection

What worked

  • Two layers instead of one: keeping real text at rest and only crossfading to particles on contact meant the hero could be both crisp typography and a physical effect, without paying for 90,000 particles while nobody is there.
  • Deriving the archive rather than drawing it: twelve chapters from one keyed file was more work up front than twelve components, and it is the only reason the site is still hers to edit.

What I'd improve

  • No reduced-motion path: on a site this motion-dependent that is the first thing I would fix. The particles, the chapter transitions and the entrance animations all run regardless of what the visitor has asked their system for.
  • Nothing is linkable: no router means no URL for a project or a year, so a visitor cannot send anyone a specific piece of work. It is a defensible trade for one continuous canvas, but it is a real cost and I would want it priced openly next time.

More work

See all work →

Need something similar?

If you have a design that only makes sense in motion, the interesting work is deciding what the transitions mean. Happy to talk it through.

← Back to all work

We use cookies & Pendo to monitor traffic anonymously, improve experience, and understand usage.

Let's connect