docs / themes

Themes.

A theme recolours Paperkites and can restyle its type. It never changes the layout, beyond a few layout words described below. You pick themes in :settings: one for light mode and one for dark. See Settings.

The built-in themes

ThemeKindWhat it is
Paperlightthe default: warm paper, serif notes
Daylightlightwhite page, cool greys, blue links
Fjordlightcold, airy, frost accents
Studiolightpure white page, neutral greys, sans notes and mono meta
Pinedarksoft green-grey night, parchment ink; the default dark theme

Making your own

Your themes live in ~/.kites/themes/, never in your notes folder. Any .css file there is a theme, and its name is the file name without .css.

  1. Save a file into ~/.kites/themes/ under a new name, such as ink.css. A built-in's name, such as pine.css, is taken: that file isn't listed.
  2. Say which row it belongs in on its first line: /* kites-theme: light */ or /* kites-theme: dark */. Without it, Paperkites judges by your ground colour.
  3. Change what you want, and pick it in :settings.

The folder is watched: a theme shows in :settings the moment it's saved. :theme reload reads the files again.

The easiest start is paper.css, the built-in look spelled out. You can delete any line you don't change: anything a theme leaves out keeps paper's value. A dark theme has to recolour every surface and every ink it puts text on, so a dark theme usually sets every colour.

What a theme file is

A theme uses CSS syntax, so your editor highlights it, but it isn't CSS. Paperkites reads it, checks every line, and turns it into colours and fonts. Nothing in it reaches the page as written.

/* kites-theme: light */
@format 1;

/* the palette: paper's colours and fonts, by name */
:root {
  ground: #faf9f5;
  ink: #1f1e1b;
  accent-text: #94461a;
  font-ui: 'Inter', system-ui, sans-serif;
}

/* named parts of the app, for fine-tuning */
.page .title { font-family: 'Iowan Old Style', Georgia, serif; font-weight: 700; }
.list .title { color: accent-text; }
.pill        { color: ink; background: fill; }

A file has two levels. Most themes only need the first.

  1. The palette (:root) holds colours and fonts by name, as paper.css lists them, plus the ground pattern and the layout words. Changing a colour there changes everything built on it.
  2. Named parts fine-tune one place, when it should differ from the palette.

@format 1; is optional; a file without it is format 1.

Named parts

A named part is a name, not a CSS selector. .page .title names the page title; which element draws it is Paperkites' business. That's why the app can change without breaking your theme, and why a theme can't reach anything that isn't on this list.

PartAcceptsWhat it is
.page .titlecolor, font-family, font-weight, font-stylethe title of every page: a note, a person, a tag, search
.note .bodycolorthe text of a note, and of the capture box
.list .titlecolor, font-family, font-weight, font-stylea note's title in a list, search results and backlinks
.list .previewcolor, font-style, font-sizethe lines of a note's text under its title in a list
.gutter .datecolorthe date in the gutter (today keeps the accent)
.pillcolor, backgroundthe status pill: messages and the command line
.formatbarcolor, backgroundthe format bar over a selection

Layout words

Besides colours and fonts, a theme picks a few layout words in :root. Paper's value comes first. Leave one out to keep paper's.

WordValuesWhat it sets
list-layoutledger | streamledger: the date in the gutter, the note beside it. stream: no gutter, one card per note, the time on the right
meta-caseupper | lowerdates, section labels and counts: small caps, or lower-case mono
capture-submithint | key | buttonthe end of the capture box: a "⌘↩ save" hint, a ⌘↩ keycap, or a Save button
placeholder-stylenormal | italicthe capture box's placeholder
chip-styleui | plain#tags and @people in the interface face, or in the face of the text around them
titlebarnone | paththe window's top strip: nothing, or the path (~/notes)
column-width560px–760pxthe reading column; your own width setting still wins
row-radius0px–16pxthe corners of list rows and the capture box together
ground-patternplain | dotted | dotted-edgesthe page: plain, dots behind everything, or dots left and right of the column

To try a ground pattern over every theme, run :theme ground plain, :theme ground dotted or :theme ground dotted-edges. It lasts until the app restarts; nothing is saved.

Values

WhereAccepted
a colour in :root#rgb or #rrggbb; rgba() only for scrim
a font in :roota font stack: family names, ending in a generic family (serif, sans-serif, monospace, system-ui, ui-serif, ui-sans-serif, ui-monospace, cursive)
color, background#rgb, #rrggbb, or a palette colour's name such as accent-text, which follows the palette
font-familya font stack, or a palette font's name such as font-ui
font-weightnormal, bold, 100–900
font-stylenormal, italic
font-sizewhole px, 12px–24px

Colour names like red, rgb(), var(), url(), selectors, @import and a second rule for the same part aren't accepted.

Contrast

Paperkites checks your palette so text stays readable:

When a theme has a mistake

A theme file with a mistake isn't used. Paper stands in (Pine, for dark), and the status pill shows the first problem with its file and line:

theme: /Users/you/.kites/themes/ink.css:12: .page .title margin: takes color, font-family, font-weight, font-style
MessageFix
not a primitiveonly the named parts above exist, written exactly as shown
takes color, ...that part doesn't accept that property
isn't a #rgb / #rrggbb colouruse hex, not red, rgb() or var()
isn't a font stack ending in a generic familyend the list with serif, sans-serif, monospace, …
ink-4 on ground is 3.10:1, needs 4.5:1that text would be hard to read; darken the text or lighten the surface

Fix the file and save it, or run :theme reload.

What a theme can't change

Your reading settings beat the theme. A body font chosen in :settings wins over the theme's font-body, and your column width wins over its column-width.

paper.css

Every colour, font and layout word a theme can set, and every named part, at paper's values. Copy it into ~/.kites/themes/, rename it, and change what you like. You can also download it.

@format 1;

/* ~/.kites/themes/paper.css
   The palette: every token a theme can set, with paper's values. Colours are #rgb or #rrggbb;
   scrim alone may be rgba(). Fonts are a font stack ending in a generic family. */
:root {
  /* surfaces */
  ground: #faf9f5; /* the page */
  paper: #ffffff; /* floating surfaces: summon, peek card, picker */
  tint-active: #f6f3ea; /* the active (raw markdown) block */
  fill: #f4f2ec; /* code blocks, quiet panels */
  fill-warm: #f6f1e9; /* selected row in a list or picker */
  bar: #f2efe6; /* not drawn since the status pill; kept, tokens are never removed */
  highlight: #f4e3cd; /* search match */
  mention: #f2e9dd; /* unlinked mention of a note title */
  sidebar: #ebe7dc; /* the floating sidebar */
  sidebar-selected: #ddd7c9; /* selected sidebar row */
  pill: #f0ece3; /* the status pill */
  selection: #efd6c3; /* text selection */
  switch-off: #d9d4c8; /* vim switch, off */
  scrim: rgba(36, 34, 30, 0.26); /* behind summon */

  /* ink */
  ink: #1f1e1b; /* titles, primary UI */
  ink-body: #26241f; /* note body prose */
  ink-2: #56534d; /* secondary UI, inactive pane body */
  ink-3: #67635b; /* de-emphasised prose, backlink context */
  ink-4: #6a665e; /* SMALLEST INK THAT PASSES 4.5:1 on --k-ground */
  muted: #9c9890; /* decorative only — never body or label text */
  faint: #b4b0a6; /* markdown markers, list bullets, the # and / */
  marker: #bab5a8; /* raw ** [[ ]] markers inside an active block */

  /* accent */
  accent: #c2622f; /* cursor, glyphs, dots, marks — non-text */
  accent-text: #a3501d; /* any accent used AS TEXT (4.5:1 on ground) */
  accent-soft: #e6cbb2; /* resting link underline */
  mode-insert: #4f6b4a; /* INSERT badge */
  person: #5f6a3a; /* a person: @mentions, the username on a person page */
  formatbar: #1f1e1b; /* the format bar over a selection */
  formatbar-ink: #f1eee6; /* ink on the format bar */

  /* todos */
  task-marker: #b0552a; /* [ ] [x] [<] [/] [!] */
  task-marker-muted: #67635a; /* [-] cancelled, [>] moved */
  task-done: #67635a; /* text of a done, cancelled or moved todo */
  task-strike: #67635a; /* the line through a done todo */
  task-label: #767167; /* trailing label and date chips */
  task-hover: #efeae0; /* behind a marker under the pointer */

  /* graph */
  cluster-1: #c2622f;
  cluster-2: #7d8a4f;
  cluster-3: #5b7a8c;
  cluster-4: #9c6b4f;
  cluster-none: #cfcabf; /* orphan node */
  edge: #e0dcd1; /* link inside a cluster */
  edge-cross: #c4b5a2; /* link between clusters — deliberately darker */

  /* ground */
  dot: #e8e4da; /* the dot grid on the ground: 1.05 to 1.40:1 on ground, keep it quiet */
  ground-pattern: dotted-edges; /* plain | dotted | dotted-edges */

  /* type */
  font-body: 'Source Serif 4', Georgia, serif;
  font-ui: 'IBM Plex Sans', system-ui, sans-serif;
  font-mono: 'IBM Plex Mono', ui-monospace, monospace;

  /* layout: paper's word first; see THEMES.md › Layout */
  list-layout: ledger; /* ledger | stream */
  meta-case: upper; /* upper | lower */
  capture-submit: hint; /* hint | key | button */
  placeholder-style: normal; /* normal | italic */
  chip-style: ui; /* ui | plain */
  titlebar: none; /* none | path */
  column-width: 620px; /* 560px to 760px */
  /* row-radius: 0px to 16px, for list rows and the capture box together; paper's are 8px and 12px */
}

/* Primitives: named parts of the app, for when one place should differ from the palette.
   A colour can name a token (ink, accent-text, ...) so it follows the palette, or be a #hex. */

/* the title of every page: a note, a person, a tag, search */
.page .title {
  color: ink;
  font-family: font-body;
  font-weight: 600;
  font-style: normal;
}

/* the text of a note, and of the capture box */
.note .body {
  color: ink-body;
}

/* a note's title in a list, search results and backlinks */
.list .title {
  color: ink;
  font-family: font-body;
  font-weight: 600;
  font-style: normal;
}

/* the lines of a note's text under its title in a list */
.list .preview {
  color: ink-3;
  font-style: normal;
  font-size: 16px;
}

/* the date in the gutter (today keeps the accent) */
.gutter .date {
  color: ink-2;
}

/* the status pill: messages and the command line */
.pill {
  color: ink-4;
  background: pill;
}

/* the format bar over a selection: bold, italic, link, tag, mention, code */
.formatbar {
  color: formatbar-ink;
  background: formatbar;
}