theme-creation
Handles theme registration and customization within the PropertyWebBuilder system.
Install
mkdir -p .claude/skills/theme-creation && curl -L -o skill.zip "https://agentskills.codes/api/skills/download/2446" && unzip -o skill.zip -d .claude/skills/theme-creation && rm skill.zipInstalls to .claude/skills/theme-creation
Activation
This is the description your AI agent reads to decide when to run this skill — the better it matches your request, the more reliably it fires.
Create new themes for PropertyWebBuilder. Use when creating custom themes, styling websites, or modifying theme templates. Handles theme registration, view templates, CSS, and asset configuration.Key capabilities
- →Compile dynamic CSS templates via ERB
- →Validate color palettes against WCAG AA
- →Register new theme configurations
- →Implement theme inheritance mapping
How it works
It interfaces with the Palette Compiler and Styleable concern to transform JSON palette definitions into CSS variables and template partials.
Inputs & outputs
When to use theme-creation
- →Creating a custom website theme
- →Applying a new color palette
- →Configuring CSS variables for a theme
About this skill
Theme Creation for PropertyWebBuilder
Theme System Overview
PropertyWebBuilder uses a multi-tenant theme system where each website can have its own theme. The system supports:
- Theme inheritance - Child themes extend parent themes
- Color palettes - Multiple pre-defined color schemes per theme
- Page Part Library - 20+ pre-built, customizable sections
- CSS custom properties - Native CSS variables for easy customization
- Per-tenant customization - Each website can override theme defaults
- WCAG AA accessibility - Built-in contrast checking utilities
- Dark mode support - Automatic or explicit dark mode colors
Current Themes (January 2025)
| Theme | Parent | Status | Palettes | Description |
|---|---|---|---|---|
default | None | Active | 6 | Base Tailwind/Flowbite theme |
brisbane | default | Active | 6 | Luxury real estate (gold/navy) |
bologna | default | Active | 4 | Traditional European style |
barcelona | default | Disabled | 4 | Incomplete - needs work |
biarritz | default | Disabled | 4 | Needs accessibility fixes |
Key Components
| Component | Location | Purpose |
|---|---|---|
| Theme Registry | app/themes/config.json | Theme definitions |
| Theme Model | app/models/pwb/theme.rb | ActiveJSON model with inheritance |
| Palette Loader | app/services/pwb/palette_loader.rb | Load palettes from JSON |
| Palette Validator | app/services/pwb/palette_validator.rb | Validate against schema |
| Color Utils | app/services/pwb/color_utils.rb | WCAG contrast, shade generation |
| Palette Compiler | app/services/pwb/palette_compiler.rb | Compile CSS for production |
| Website Styleable | app/models/concerns/pwb/website_styleable.rb | Per-website styles |
| CSS Templates | app/views/pwb/custom_css/_*.css.erb | Dynamic CSS generation |
Theme Resolution Flow
- Request comes in with subdomain (tenant identification)
ApplicationController#set_theme_pathdetermines theme from:- URL parameter
?theme=name(if whitelisted) - Website's
theme_namefield - Fallback to "default"
- URL parameter
- Theme view paths are prepended (child first, then parent)
- Views render from theme directory, falling back through inheritance chain
Creating a New Theme
Step 1: Register the Theme in config.json
Add to app/themes/config.json:
{
"name": "mytheme",
"friendly_name": "My Custom Theme",
"id": "mytheme",
"version": "1.0.0",
"enabled": true,
"parent_theme": "default",
"description": "A custom theme for my agency",
"author": "Your Name",
"tags": ["modern", "clean"],
"supports": {
"page_parts": [
"heroes/hero_centered",
"heroes/hero_split",
"features/feature_grid_3col",
"testimonials/testimonial_carousel",
"cta/cta_banner"
],
"layouts": ["default", "landing", "full_width"],
"color_schemes": ["light", "dark"],
"features": {
"sticky_header": true,
"back_to_top": true,
"animations": true
}
},
"style_variables": {
"colors": {
"primary_color": {
"type": "color",
"default": "#your-brand-color",
"label": "Primary Color"
},
"secondary_color": {
"type": "color",
"default": "#your-secondary-color",
"label": "Secondary Color"
}
},
"typography": {
"font_primary": {
"type": "font_select",
"default": "Open Sans",
"label": "Primary Font",
"options": ["Open Sans", "Roboto", "Montserrat"]
}
}
}
}
Step 2: Create Directory Structure
mkdir -p app/themes/mytheme/views/layouts/pwb
mkdir -p app/themes/mytheme/views/pwb/welcome
mkdir -p app/themes/mytheme/views/pwb/components
mkdir -p app/themes/mytheme/views/pwb/sections
mkdir -p app/themes/mytheme/views/pwb/pages
mkdir -p app/themes/mytheme/views/pwb/props
mkdir -p app/themes/mytheme/views/pwb/search
mkdir -p app/themes/mytheme/views/pwb/shared
mkdir -p app/themes/mytheme/palettes # For color palette JSON files
mkdir -p app/themes/mytheme/page_parts # For custom page part templates
Step 3: Create Default Palette
Create app/themes/mytheme/palettes/default.json:
{
"id": "default",
"name": "Default",
"description": "Default color scheme for mytheme",
"is_default": true,
"preview_colors": ["#3498db", "#2c3e50", "#e74c3c"],
"colors": {
"primary_color": "#3498db",
"secondary_color": "#2c3e50",
"accent_color": "#e74c3c",
"background_color": "#ffffff",
"text_color": "#333333",
"header_background_color": "#ffffff",
"header_text_color": "#333333",
"footer_background_color": "#2c3e50",
"footer_text_color": "#ffffff",
"light_color": "#f8f9fa",
"link_color": "#3498db",
"action_color": "#3498db"
}
}
Step 4: Copy and Customize Layout
Copy from parent theme:
cp app/themes/default/views/layouts/pwb/application.html.erb app/themes/mytheme/views/layouts/pwb/
Edit app/themes/mytheme/views/layouts/pwb/application.html.erb:
<!DOCTYPE html>
<html lang="<%= I18n.locale %>">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title><%= yield(:page_title) || @current_website&.site_name %></title>
<%= yield(:page_head) %>
<%# Tailwind CSS for this theme %>
<%= stylesheet_link_tag "tailwind-mytheme", "data-turbo-track": "reload" %>
<%# Flowbite components %>
<link href="https://cdnjs.cloudflare.com/ajax/libs/flowbite/2.3.0/flowbite.min.css" rel="stylesheet" />
<%# Material Symbols for icons %>
<link href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,GRAD@24,400,0,0&display=swap" rel="stylesheet" />
<%# Dynamic CSS variables %>
<style>
<%= custom_styles("mytheme") %>
</style>
<%= javascript_include_tag "pwb/application", async: false %>
<script src="https://cdnjs.cloudflare.com/ajax/libs/flowbite/2.3.0/flowbite.min.js"></script>
<%= csrf_meta_tags %>
</head>
<body class="tnt-body mytheme-theme <%= @current_website&.body_style %> bg-gray-50 text-gray-900">
<div class="flex flex-col min-h-screen">
<%= render partial: '/pwb/header', locals: { not_devise: true } %>
<main class="flex-grow">
<%= render 'devise/shared/messages' %>
<%= yield %>
</main>
<%= render partial: '/pwb/footer', locals: {} %>
</div>
<%= yield(:page_script) %>
</body>
</html>
Step 5: Create Theme CSS Partial
Create app/views/pwb/custom_css/_mytheme.css.erb:
/* Theme: mytheme */
<%
# Get palette colors merged with website overrides
styles = @current_website&.style_variables || {}
primary_color = styles["primary_color"] || "#3498db"
secondary_color = styles["secondary_color"] || "#2c3e50"
accent_color = styles["accent_color"] || "#e74c3c"
background_color = styles["background_color"] || "#ffffff"
text_color = styles["text_color"] || "#333333"
header_bg = styles["header_background_color"] || "#ffffff"
header_text = styles["header_text_color"] || "#333333"
footer_bg = styles["footer_background_color"] || "#2c3e50"
footer_text = styles["footer_text_color"] || "#ffffff"
font_primary = styles["font_primary"] || "Open Sans"
border_radius = styles["border_radius"] || "0.5rem"
%>
<%= render partial: 'pwb/custom_css/base_variables',
locals: {
primary_color: primary_color,
secondary_color: secondary_color,
accent_color: accent_color,
background_color: background_color,
text_color: text_color,
font_primary: font_primary,
border_radius: border_radius
} %>
:root {
--header-bg: <%= header_bg %>;
--header-text: <%= header_text %>;
--footer-bg: <%= footer_bg %>;
--footer-text: <%= footer_text %>;
}
/* Theme-specific overrides */
.mytheme-theme header {
background-color: var(--header-bg);
color: var(--header-text);
}
.mytheme-theme footer {
background-color: var(--footer-bg);
color: var(--footer-text);
}
/* Custom raw CSS from admin */
<%= @current_website&.raw_css %>
Step 6: Create Tailwind Input File
Create app/assets/stylesheets/tailwind-mytheme.css:
@import "tailwindcss";
/* Font imports */
@font-face {
font-family: 'Open Sans';
font-weight: 400;
src: url('https://cdn.jsdelivr.net/npm/@fontsource/[email protected]/files/open-sans-latin-400-normal.woff2');
}
/* Theme configuration */
@theme {
--color-primary: var(--primary-color, #3498db);
--color-secondary: var(--secondary-color, #2c3e50);
--color-accent: var(--accent-color, #e74c3c);
--font-family-sans: 'Open Sans', var(--font-primary, system-ui, sans-serif);
--radius: var(--border-radius, 0.375rem);
}
/* PWB utility classes */
@layer utilities {
.bg-pwb-primary { background-color: var(--pwb-primary); }
.bg-pwb-secondary { background-color: var(--pwb-secondary); }
.text-pwb-primary { color: var(--pwb-primary); }
.text-pwb-secondary { color: var(--pwb-secondary); }
.border-pwb-primary { border-color: var(--pwb-primary); }
}
Step 7: Add Build Scripts
Add to package.json:
{
"scripts": {
"tailwind:mytheme": "npx @tailwindcss/cli -i ./app/assets/stylesheets/tailwind-mytheme.css -o ./app/assets/builds/tailwind-mytheme.css --watch",
"tailwind:mytheme:prod": "npx @tailwindcss/cli -i ./app/assets/stylesheets/tailwind-mytheme.css -o ./app/assets/builds/tailwind-mytheme.css --minify"
}
}
Step 8: Test the Theme
# Via Rails console
theme = Pwb::Theme.find_by(name: 'mytheme')
theme.view_paths # Verify path resolution
theme.palettes # Check palettes loaded
theme.default_palette_id # Verify default palette
# Update a website to use the theme
website = Pwb::Website.first
website.update(theme_name: 'mytheme')
`
Content truncated.
When not to use it
- →Direct database schema migrations
- →General Tailwind CSS configuration
Prerequisites
Limitations
- →Requires PropertyWebBuilder model access
- →Accessibility check is automated/advisory only
How it compares
It manages specific tenant-based theme inheritance rather than standard global CSS styling.
Compared to similar skills
theme-creation side by side with the closest alternatives in the catalog.
| Skill | Installs | Updated | Safety | Difficulty |
|---|---|---|---|---|
| theme-creation (this skill) | 3 | 7mo | Review | Advanced |
| theme-evaluation | 1 | 7mo | Review | Intermediate |
| mobile-android-design | 101 | 2mo | No flags | Intermediate |
| elegant-design | 21 | 5mo | Review | Intermediate |
Try saying
Example prompts that trigger this skill in your AI assistant.
More by etewiah
View all by etewiah →You might also like
theme-evaluation
etewiah
Evaluate themes for accessibility, contrast, and design issues. Use when auditing themes for WCAG compliance, checking color contrast ratios, or identifying visual/UX problems.
mobile-android-design
wshobson
Master Material Design 3 and Jetpack Compose patterns for building native Android apps. Use when designing Android interfaces, implementing Compose UI, or following Google's Material Design guidelines.
elegant-design
rand
Create world-class, accessible, responsive interfaces with sophisticated interactive elements including chat, terminals, code display, and streaming content. Use when building user interfaces that need professional polish and developer-focused features.
tailwind-design-system
wshobson
Build scalable design systems with Tailwind CSS, design tokens, component libraries, and responsive patterns. Use when creating component libraries, implementing design systems, or standardizing UI patterns.
web-design-reviewer
github
This skill enables visual inspection of websites running locally or remotely to identify and fix design issues. Triggers on requests like "review website design", "check the UI", "fix the layout", "find design problems". Detects issues with responsive design, accessibility, visual consistency, and layout breakage, then performs fixes at the source code level.
epic-ui-guidelines
epicweb-dev
Guide on UI/UX guidelines, accessibility, and component usage for Epic Stack