← Case study

Detail 12 · Resume

One markup, three outputs

One resume component as a page, a living thumbnail and a one-page PDF printed from CSS. 7 minutes, 2 demos.

Try it: one résumé, three outputs

Sujoy Kumar Haldar

Design Engineer · UI/UX & Frontend

Kolkata, India · sujoykrhaldar@gmail.com

Designer and engineer who takes products from first sketch to shipped interface. Currently the founding designer & engineer at Coder's Gyan, where I design and build both the marketing site and the learning platform used by software developers. Grounded in software engineering, equally at home designing in Figma and building in React and Next.js.

Experience

Founding Designer & EngineerJul 2025 — Present

Coder's Gyan

  • Designed and built the learning platform at learn.codersgyan.com, end to end from UX to front-end.
  • Designed and built the marketing site at codersgyan.com, helping grow its traffic.

Career BreakApr 2023 — Jul 2025

  • Prepared full-time for the GATE (CSE) exam for postgraduate studies, taking on freelance design and development work alongside.

Skills

Expertise

Design · UI/UX · Design Engineering · Frontend · Backend

Programming

JavaScript · TypeScript

Frameworks

Node.js · React · Next.js · Express.js

APIs & Databases

REST APIs · SQL · MongoDB

Sized in cqw: the same page at any width

Output

01 · The idea

Write it once

The résumé lives in three places: as a page on the site, as a thumbnail in the résumé island, and as the PDF you can download. The usual way is three things to keep in step: a page, a screenshot and a document exported from somewhere else. Here it’s one component, written once, and the three are just three ways of showing it.

The words are data, in one file. One component lays them out. The page shows it, the island shows it small, and the PDF is the page printed with a stylesheet of its own. Change a line of the résumé and all three change with it.

02 · The sheet

A document, not a layout

On a tablet or a desktop the résumé is a sheet of paper: two columns, at least as tall as A4. A web layout reflows as it gets narrower, and lines break in new places. A sheet of paper doesn’t: smaller, it’s the same page.

So every size on the sheet is a share of the sheet’s own width, in cqw (a hundredth of its container’s width). The type, the gaps and the margins all grow and shrink together, and the lines break at the same words at any size. Below is the real component; drag its width and watch the summary keep its lines.

The real résumé, at any width

Every width is the same page, only larger or smaller

One type scale: px on a phone, cqw on the sheet
// Shared type steps: phone (px) → sheet (cqw); `rs-*` → print size (globals.css)
const TYPE = {
  body: "rs-body text-[14px] sm:text-[1.75cqw]",
  meta: "rs-meta text-[12.5px] sm:text-[1.5cqw]",
  role: "rs-role text-[15px] sm:text-[1.95cqw]",
};

That’s what makes the island’s thumbnail possible. It isn’t a picture of the résumé; it’s the résumé, 308 pixels wide. And the flight from thumbnail to page in the previous detail only works because the two are the same layout at two sizes.

Which layout to use, the sheet or the phone column, follows the screen, not the sheet. Had it followed the sheet’s own width, the 308-pixel thumbnail would have turned into the phone column. On a desktop, the thumbnail has to be a miniature of the page you’re about to open.

03 · Three outputs

Sheet, phone and paper

On a phone a scaled sheet would be unreadable: the type would shrink with the screen. So there the résumé becomes a single column, sized in pixels, that reads like any page. And printed, it becomes light paper with dark ink, in print sizes. Same markup each time; only the styles change.

Below is the résumé in miniature, with the real sizes of each output: cqw on the sheet, pixels on the phone, and the print styles’ points, turned into a share of an A4 page.

One résumé, three outputs

Sujoy Kumar Haldar

Design Engineer · UI/UX & Frontend

Kolkata, India · sujoykrhaldar@gmail.com

Designer and engineer who takes products from first sketch to shipped interface. Currently the founding designer & engineer at Coder's Gyan, where I design and build both the marketing site and the learning platform used by software developers. Grounded in software engineering, equally at home designing in Figma and building in React and Next.js.

Experience

Founding Designer & EngineerJul 2025 — Present

Coder's Gyan

  • Designed and built the learning platform at learn.codersgyan.com, end to end from UX to front-end.
  • Designed and built the marketing site at codersgyan.com, helping grow its traffic.

Career BreakApr 2023 — Jul 2025

  • Prepared full-time for the GATE (CSE) exam for postgraduate studies, taking on freelance design and development work alongside.

Skills

Expertise

Design · UI/UX · Design Engineering · Frontend · Backend

Programming

JavaScript · TypeScript

Frameworks

Node.js · React · Next.js · Express.js

APIs & Databases

REST APIs · SQL · MongoDB

Sized in cqw: the same page at any width

Output

04 · The PDF

A PDF from CSS

“Download PDF” opens the browser’s print dialog, and “Save as PDF” does the rest. What makes it a good PDF is the print stylesheet. It flips the colour tokens to dark on white, so everything that uses them recolours at once. It hides the site around the résumé. It shows every block whatever its reveal animation is doing. And it sets real print sizes, in points.

The page, printed
@media print {
  :root {
    --color-background: #ffffff;
    --color-foreground: #141414;
    --color-muted: #555555;
    --color-heading: #333333;
  }

  /* No page margin: that's where browsers print their own header and footer
     (date, title, URL, page number). The resume page adds the margin itself. */
  @page {
    size: A4;
    margin: 0;
  }

  .noise-overlay {
    display: none;
  }

  /* Print the resume whole, whatever its reveal animation is doing */
  [data-resume-sheet] [data-wf="block"] {
    opacity: 1 !important;
    filter: none !important;
    transform: none !important;
  }

  /* The resume page becomes the A4 sheet, with its margins inside.
     !important beats the page's inline on-screen width and spacing. */
  [data-resume-page] {
    width: 100% !important;
    padding: 12mm !important;
  }

The page margin is zero on purpose. A browser prints its own header and footer in the page margin: the date, the title, the address and the page number. With no margin there’s no room for them, and the résumé page puts its 12 mm of margin back as padding inside itself. Switch on “Browser header & footer” above to see what that avoids.

The sizes are tuned so it all fits on one A4 page. That matters more than it sounds: the two-column part can’t split across pages, so if it didn’t quite fit, all of it would jump to page two.

05 · Decisions

Why it’s built this way

One source

The words live in one file and one component. There’s no screenshot or exported PDF to fall out of date.

Sized by the sheet

cqw makes the sheet a document: the same page at any width, so a thumbnail is just a smaller page.

Laid out by the screen

Sheet or column is chosen by the screen, so the thumbnail on a desktop is a true miniature of the page.

Let the browser make the PDF

No PDF library and no file to host: a print stylesheet, and the browser’s own Save as PDF.

06 · Takeaways

What to keep

  • When the same thing appears in several places, render the real thing in each, not copies of it.
  • Size a document in container units, and it scales like paper instead of reflowing like a page.
  • For a PDF, a print stylesheet is often enough: flip the tokens, hide the chrome, set the sizes, and take the page margin away from the browser.
Print the real one→

Open the résumé and press “Download PDF”, or open it from the résumé island to watch the thumbnail become the page.