Two inks
Every screen is two inks on paper: one dark ink for all type, one bright ink for accents.
Dua Tinta is Indonesian for two inks. The site reads like a risograph zine printed on newsprint, personal and a little loud, but the layout underneath stays plain and calm so the writing, photos and music carry it. Photographs are the one exception to the two-ink rule: they always show in their original colours, as shot.
- Ink pairs
- Five, switchable in the header
- Typeface
- Archivo, one family
- Corners
- Square, except a round few
- Shadows
- None, it's print
Colour
Three tokens do all the work: --ink, --pop and --paper. Never hard-code a hex value in a component, or the ink switcher stops working.
Ink
#3255A4. All text, headings, outlines, the now-playing bar and halftone dots.
Pop
#FF6C2F. Accents only: divider rules, link underlines, the halftone ground, equalizer bars.
Paper
#F4F4F1. The page ground, and the text colour on ink surfaces.
Ink pairs
Each pair is a type ink and an accent ink, set with data-ink on <html>. Pick one to repaint this page. Shared link previews always use the default pair.
Two fixed colours sit outside the pairs: a black scrim at 85% behind an opened photo, and the white ground of the round avatar.
Type
One family, Archivo, loaded with its width axis. The personality comes from width and weight extremes, not a second typeface. Headlines are always uppercase, condensed and heavy. Everything else is sentence case.
Display
Headline
Section title
Post title goes here
Job title
A short lede introduces the page in a line or two.
Body text runs at normal width and weight, in sentence case.
Blog prose gets a little more air between lines and stops at 68 characters, so long posts stay easy to follow from one line to the next.
Photo caption goes here
Navigation
January 1, 2026
--ink: #3255a4;
Layout
Shape and depth
Print has square corners and no shadows. Hierarchy comes from type size and weight, the pop rules, and overlap: the name in the masthead sits on its photo with mix-blend-mode: multiply, so where it crosses the photo it darkens like overprinted ink.
--popink + popComponents
Links
Read the postInk text with a 2px pop underline, offset 4px. Navigation links show the underline on hover only.
List row
Experience, songs and posts: a display-type title, a regular line under it, tabular figures for dates and counts.
Halftone placeholder
Ink dots on a 14px grid over pop, fading out diagonally. Stands in for any photo or cover that is loading or missing, and pulses gently unless reduced motion is on.
Now-playing bar
Fixed to the bottom of every page. Solid ink with paper text; the three pop bars bounce only while a song is playing. The whole bar is one link.
Ink switcher
Five two-dot swatches in the header. The selected one gets a 2px ink ring. The choice is saved per visitor and applied before first paint.
Do and don't
Do
- Use only the ink, pop and paper tokens, so every pair works.
- Show photographs in their original colours.
- Set headlines uppercase, condensed and heavy.
- Keep body text at 4.5:1 contrast or better, and check new pairs before adding them.
- Give every photo real alt text and keep keyboard focus visible.
- Stop the equalizer and loading pulses when reduced motion is on.
- Credit outside data where it's shown, like “via Last.fm”.
Don't
- Add a third colour or a grey.
- Set text in pop, on paper or on ink.
- Duotone or tint photographs.
- Use uppercase for body text or labels.
- Add drop shadows, rounded cards or gradient washes.
- Round photos or blocks. Only the avatar, swatches and pills are round.
- Centre content blocks. Keep the left edge strong.
Source
This page is drawn from design.md. In code, the source of truth is app/global.css. Drop these tokens into any page to print in Dua Tinta:
:root, [data-ink=orange] { --ink: #3255a4; --pop: #ff6c2f; }
[data-ink=pink] { --ink: #0078bf; --pop: #ff48b0; }
[data-ink=green] { --ink: #407060; --pop: #ffb511; }
[data-ink=burgundy] { --ink: #914e72; --pop: #ffe800; }
[data-ink=black] { --ink: #000; --pop: #ff4c65; }
:root { --paper: #f4f4f1; }