Themes

6 retro themes with 70+ CSS custom properties each. Every pixel reskins.

Overview

Talkie ships with 6 complete themes. Each theme defines over 70 CSS custom properties that control every visual element in the interface — backgrounds, text colors, accent colors, borders, shadows, typography, robot avatar colors, screen states, buttons, inputs, and modals.

Themes are applied via the data-theme attribute on the root element. When the theme changes, every component in the UI transitions smoothly to the new color scheme. No JavaScript re-rendering is needed — CSS custom properties handle the entire transition.

Try it now If you are viewing this site in the Talkie app, open the theme picker in settings to switch themes live and see every element update instantly.

Theme List

TalkBoy (mccallister)

Inspired by the silver cassette recorder from the 90s. Chunky button aesthetics, a dark metallic background, and bold red accents. Typography uses Impact and Arial Black for that toy-packaging feel. This is the default theme.

Bubble (imessage)

Clean, white, and minimal. Modeled after modern Apple messaging interfaces. Uses SF Pro (or system sans-serif) with a blue accent color. Shadows are soft and subtle, borders are nearly invisible, and the overall feel is polished and contemporary.

Dial-Up (aol)

Windows 95-era nostalgia. Gray panels with beveled borders, navy blue accents, and MS Sans Serif typography. Buttons look raised and clickable. The entire interface feels like an instant messenger from 1997.

Finder (classic-mac)

The elegant simplicity of classic Mac OS. Light gray backgrounds with crisp 1px black borders. Geneva and Chicago typography. No gradients, no shadows — just clean, precise lines and a monochrome palette with occasional blue highlights.

Guestbook (geocities)

A love letter to the 90s web. Dark backgrounds with neon green, magenta, and cyan text. Comic Sans typography (yes, really). Glowing borders, high contrast, and the unmistakable energy of a GeoCities homepage under construction.

1984 (apple-1984)

Warm beige and cream tones from the original Macintosh era. Futura typography gives it a retro-futurist feel. The signature rainbow stripe — red, orange, yellow, green, blue, purple — appears as an accent throughout the interface, referencing the classic Apple logo.

CSS Custom Properties

Each theme defines the following CSS custom properties. Use these in your own styles to ensure components stay consistent with the active theme.

Background colors

Property Description
--bg-primary Main background color for the page and large surfaces
--bg-secondary Secondary background for cards, panels, and elevated surfaces
--bg-tertiary Tertiary background for nested elements and subtle depth

Text colors

Property Description
--text-primary Primary text color for headings and important content
--text-secondary Secondary text for body copy and descriptions
--text-muted Muted text for labels, captions, and de-emphasized content

Accent colors

Property Description
--accent Primary accent color for links, active states, and highlights
--accent-hover Accent color on hover/focus states
--accent-glow Glow or shadow color for accent-colored elements
--accent-soft Soft, low-opacity accent for backgrounds and subtle highlights
--accent-secondary Secondary accent for complementary highlights

Robot avatar

Property Description
--robot-body Main body color of the robot avatar
--robot-shadow Shadow/darker tone for robot depth
--robot-highlight Highlight/lighter tone for robot edges

Screen states

Property Description
--screen-idle Robot screen color in idle state
--screen-happy Robot screen color in happy state
--screen-error Robot screen color in error state
--screen-listening Robot screen color in listening state
--screen-thinking Robot screen color in thinking state

Borders

Property Description
--border-subtle Very subtle border for dividers and separators
--border-light Standard border for cards, inputs, and panels

Shadows

Property Description
--shadow-soft Soft shadow for subtle elevation (cards, dropdowns)
--shadow-raised Stronger shadow for raised elements (modals, popovers)

Header

Property Description
--header-bg Background color for the top header bar
--header-border Border color at the bottom of the header
--header-text Text color within the header

Buttons

Property Description
--btn-bg Default button background color
--btn-hover Button background on hover
--btn-border Button border color
--btn-shadow Button box-shadow for pressed/raised effects

Input

Property Description
--input-bg Background for text inputs, textareas, and code blocks
--input-border Border color for input elements

Modal

Property Description
--modal-bg Background color for modal dialogs and overlays

Typography

Property Description
--font-family Primary font stack for body text
--font-weight-normal Normal font weight (typically 400)
--font-weight-bold Bold font weight (typically 600 or 700)
--title-font Font family for headings and display text
--title-style Font style for titles (normal or italic)
--title-transform Text transform for titles (none, uppercase, etc.)
--letter-spacing Letter spacing for body text

Viewport Borders

Each theme decorates the viewport edges with a unique border treatment, adding personality before you even read the content.

TalkBoy

A bold red 4px strip across the top of the viewport. Evokes the red record button on a cassette recorder.

Bubble

A thin blue 2px hairline at the top. Minimal and precise, matching the clean aesthetic of the theme.

Dial-Up

A navy-to-blue gradient strip at the top. Reminiscent of the Windows 95 title bar gradient.

Finder

A 1px black border on all four sides with a white inner highlight. Replicates the classic Mac OS window chrome — a precise frame around the entire viewport.

Guestbook

Neon magenta rail on the left edge and a cyan rail on the right edge. The viewport becomes a glowing portal, framed in the signature GeoCities palette.

1984

A rainbow stripe across the top — red, orange, yellow, green, blue, and purple bands. The iconic Apple rainbow, rendered as a horizontal gradient strip.

Tool Category Colors

The activity feed and chat timeline use 6 tool categories, each with a color accent that adapts per-theme. Categories are rendered as a subtle left-border and tinted background on tool badges.

Category CSS Class TalkBoy Bubble Dial-Up Finder Guestbook 1984
fs tool-cat--fs Steel blue iOS blue Navy Mac blue Cyan Apple blue
exec tool-cat--exec Orange iOS orange Red Muted red Magenta Apple red
voice tool-cat--voice Purple iOS purple Purple Deep purple Lime Violet
data tool-cat--data Green iOS green Teal Forest green Yellow Apple green
plan tool-cat--plan Rose iOS pink Fuchsia Maroon Hot pink Amber
media tool-cat--media Amber iOS cyan Olive Brown Red Gold

Override category colors in theme-specific CSS using the .tool-cat--* class selectors:

.theme-geocities .tool-badge.tool-cat--voice {
  border-left-color: rgba(0, 255, 0, 0.6);
  background: rgba(0, 255, 0, 0.08);
}

.theme-geocities .activity-feed__item.tool-cat--voice {
  border-left-color: rgba(0, 255, 0, 0.5);
}

How Theme Switching Works

Talkie uses two mechanisms for applying themes, depending on context.

Global page theming

For the full-page theme, a class like .theme-mccallister is added to the <html> element. Each theme class defines all the CSS custom properties that child elements consume. Only one theme class is active at a time.

Scoped theme islands

For isolated theme previews (like the theme showcase on the homepage), the data-theme attribute is applied to a local wrapper element. This lets you render a component in a specific theme without affecting the rest of the page.

<div data-theme="geocities">
  <!-- This component renders in the Guestbook theme -->
  <div class="robot robot--idle">...</div>
</div>

localStorage persistence

The selected theme is stored under the talkie_theme key in localStorage. On page load, the saved theme is read and applied before the first paint to avoid a flash of the wrong theme.

setTheme function

The theme switching logic removes all theme classes, adds the new one, and persists the choice:

type ThemeName = 'mccallister' | 'imessage' | 'aol'
  | 'classic-mac' | 'geocities' | 'apple-1984'

const themes: ThemeName[] = [
  'mccallister', 'imessage', 'aol',
  'classic-mac', 'geocities', 'apple-1984'
]

function setTheme(name: ThemeName) {
  themes.forEach(t =>
    document.documentElement.classList.remove(`theme-${t}`)
  )
  document.documentElement.classList.add(`theme-${name}`)
  localStorage.setItem('talkie_theme', name)
}

Using Themes in Components

To build components that respect the active theme, reference CSS custom properties instead of hardcoded colors.

Basic usage

Use var() to reference theme properties in your CSS:

.my-card {
  background: var(--bg-secondary);
  color: var(--text-primary);
  border: 1px solid var(--border-light);
  border-radius: 8px;
  box-shadow: var(--shadow-soft);
  font-family: var(--font-family);
}

.my-card__title {
  font-family: var(--title-font);
  font-style: var(--title-style);
  font-weight: var(--font-weight-bold);
  color: var(--text-primary);
}

.my-card__body {
  color: var(--text-secondary);
}

.my-card__link {
  color: var(--accent);
}

.my-card__link:hover {
  color: var(--accent-hover);
}

Smooth transitions

All CSS custom properties transition smoothly when the theme changes. Add a transition to your elements to participate in theme switching animations:

.my-element {
  background: var(--bg-primary);
  color: var(--text-primary);
  transition: background-color 0.3s ease, color 0.3s ease;
}

Theme-specific overrides

If you need different behavior in a specific theme, use the theme class selector:

/* Default styling */
.my-button {
  border-radius: 8px;
}

/* Sharper corners in the Dial-Up theme */
.theme-aol .my-button {
  border-radius: 0;
  border: 2px outset var(--btn-border);
}

/* Neon glow in the Guestbook theme */
.theme-geocities .my-button {
  box-shadow: 0 0 8px var(--accent-glow);
}

Robot state colors

If you are building components that reflect the robot's state (or any state-based UI), use the screen state variables:

.status-indicator {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  background: var(--screen-idle);
}

.status-indicator--listening {
  background: var(--screen-listening);
}

.status-indicator--error {
  background: var(--screen-error);
}
Tip Always test your components in all 6 themes. Some themes have light backgrounds with dark text, while others have dark backgrounds with light text. Using CSS custom properties consistently ensures your component works everywhere.