Themes

Fork a theme in three steps. Live preview below.

1. Copy a template

Pick the template that matches your design. Each block is complete on its own — palette, shadows, banner, and (for the light variant) shell overrides for the header / navbar / footer.

For dark themes
[data-theme="your-dark-theme"] {
    /* Neutrals (light → dark scale) */
    --text:      #ffffff;
    --subtext1:  #dddddd;
    --subtext0:  #cccccc;
    --overlay2:  #999999;
    --overlay1:  #777777;
    --overlay0:  #555555;
    --surface2:  #333333;
    --surface1:  #2a2a2a;
    --surface0:  #252525;
    --base:      #1e1e1e;
    --mantle:    #1a1a1a;
    --crust:     #181818;

    /* Accents (14 hues) */
    --rosewater: #f5e0dc;
    --flamingo:  #f2cdcd;
    --pink:      #f5c2e7;
    --mauve:     #a371f7;
    --red:       #ff5252;
    --maroon:    #eba0ac;
    --peach:     #d29922;
    --yellow:    #f9e2af;
    --green:     #6bff77;
    --teal:      #94e2d5;
    --sky:       #89dceb;
    --sapphire:  #74c7ec;
    --blue:      #58a6ff;
    --lavender:  #b4befe;

    /* Code surfaces */
    --code-bg:     #0d1117;
    --code-text:   #c9d1d9;
    --code-border: #30363d;

    /* Mix percentages */
    --alpha-strong:  15%;
    --alpha-tint:    15%;
    --alpha-glow:    25%;
    --alpha-callout: 18%;

    /* Solid-accent contrast */
    --on-accent: #0f0f0f;

    /* Shadows */
    --shadow-card:        0 3px 10px rgba(0, 0, 0, 0.2);
    --shadow-card-hover:  0 5px 15px rgba(0, 0, 0, 0.3);

    /* Shell — header / nav / footer */
    --shell-bg: #0f0f0f;
    --shell-bg-overlay: rgba(24, 24, 24, 0.8);
    --shell-bg-overlay-subtle: rgba(24, 24, 24, 0.7);
    --shell-text: #ffffff;
    --shell-text-faded: #777777;
    --shell-accent: #58a6ff;
    --shell-border: #333333;
    --shell-border-strong: #444444;

    /* Banner */
    --logo-image: url(/assets/images/CTLogo.png);
}
For light themes
[data-theme="your-light-theme"] {
    /* Neutrals (light → dark scale) */
    --text:      #4c4f69;
    --subtext1:  #5c5f77;
    --subtext0:  #6c6f85;
    --overlay2:  #7c7f93;
    --overlay1:  #8c8fa1;
    --overlay0:  #9ca0b0;
    --surface2:  #acb0be;
    --surface1:  #bcc0cc;
    --surface0:  #ccd0da;
    --base:      #eff1f5;
    --mantle:    #e6e9ef;
    --crust:     #dce0e8;

    /* Accents (14 hues) */
    --rosewater: #dc8a78;
    --flamingo:  #dd7878;
    --pink:      #ea76cb;
    --mauve:     #8839ef;
    --red:       #d20f39;
    --maroon:    #e64553;
    --peach:     #fe640b;
    --yellow:    #df8e1d;
    --green:     #40a02b;
    --teal:      #179299;
    --sky:       #04a5e5;
    --sapphire:  #209fb5;
    --blue:      #1e66f5;
    --lavender:  #7287fd;

    /* Code surfaces */
    --code-bg:     #eff1f5;
    --code-text:   #4c4f69;
    --code-border: #ccd0da;

    /* Mix percentages */
    --alpha-strong:  15%;
    --alpha-tint:    15%;
    --alpha-glow:    25%;
    --alpha-callout: 18%;

    /* Solid-accent contrast */
    --on-accent: #ffffff;

    /* Shadows */
    --shadow-card:        0 3px 10px rgba(76, 79, 105, 0.08);
    --shadow-card-hover:  0 5px 15px rgba(76, 79, 105, 0.14);

    /* Shell — header / nav / footer */
    --shell-bg: #dce0e8;
    --shell-bg-overlay: rgba(220, 224, 232, 0.8);
    --shell-bg-overlay-subtle: rgba(220, 224, 232, 0.7);
    --shell-text: #4c4f69;
    --shell-text-faded: #8c8fa1;
    --shell-accent: #1e66f5;
    --shell-border: #bcc0cc;
    --shell-border-strong: #acb0be;

    /* Banner */
    --logo-image: url(/assets/images/CTLogo_LightBG.png);
}

2. Two tiny edits

That's it — the rest happens automatically. Open a PR.

  1. Paste the template into assets/css/theme.css and rename the [data-theme="..."] selector to your theme's id.
  2. Add one line to the SITE_THEMES array in _layouts/default.html:
    window.SITE_THEMES = [
      { id: 'ct-dark', label: 'CT Dark' },
      { id: 'your-theme-id', label: 'Your Theme Name' }
    ];

Preview locally without a deploy: localStorage.setItem('theme', 'your-theme-id') in the browser console, reload, done.

Live preview — a sample post rendered with the active theme

Sample Post — every component, in context

This is what a post looks like rendered with the active theme. Every block below uses real tokens from the palette, so swapping themes will flip everything you see here. Use it to spot any color that reads badly against its surface.

Body copy uses --subtext0. Bold goes to --text. Italic goes to --subtext1. Links use --blue with a faint underline derived from --blue-tint. Inline code sits inside a --blue-tint pill.

Info callout — border is --blue, background is --blue mixed with --mantle at --alpha-callout. Use these for orientation, context, and "by the way" notes.

Headings, paragraphs, lists

H1 / H2 / H3 all sit on --text. Captions and metadata use --overlay2 — that's why the date above looks one shade quieter than the rest.

  • Bullet lists exist. Body color is --subtext0.
  • Bullets themselves inherit. Spacing is up to the post template.
  • Don't worry about the markers — those come from the browser default.
Warning callout — --peach family. Soft background, full-saturation border. Use for caveats and gotchas.
Block quotes use a --blue left border and --overlay2 italic text. Quote whatever you want.

Code blocks

Code blocks sit on --code-bg with a --code-border outline and a --blue accent stripe on the left. The syntax tokens below pull from the accent palette directly:

// comment → --overlay2
const value = someFunction('string');
// keyword → --mauve   string → --green
// number → --peach    function → --blue
Success callout — --green-strong family. The -strong companion is automatically derived as 15% darker than the base --green via --alpha-strong.
Danger callout — --red-strong family. Use for hard errors, broken builds, things you really don't want the reader to skim past.

Open questions and side notes

Two more callout flavors round out the set:

Question callout — --mauve family. For open-ended threads, "anyone seen this?", future work.
Note callout — aliased to the info palette. For asides that don't quite need the weight of an info banner.

Custom UI vs callouts

Sometimes a post needs a one-off colored panel that isn't a callout. The rule: pull from the source palette and inline color-mix(). Don't reach for --callout-* tokens — those belong to the callout component.


Custom panel

This block uses color-mix(in srgb, var(--red) var(--alpha-callout), var(--mantle)) for its background — same recipe as the danger callout, but written inline so it stays unambiguous about where the color comes from.

Buttons

Primary buttons sit on --blue with --on-accent text — that's the dark color that contrasts with every accent. Ghost buttons sit on --surface2 with the accent as foreground.

Palette — each color and its variations side-by-side

Neutrals — light → dark scale

Accents — each row: base + every variation derived from it

Borders — derived from --surface2

Scrollbar — derived from --surface2

Callouts — each row: border + bg pair

Code surfaces

Mix percentages

Misc & shell