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.
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);
}