theme-creation
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.
Install
mkdir -p .claude/skills/theme-creation && curl -L -o skill.zip "https://mcp.directory/api/skills/download/2446" && unzip -o skill.zip -d .claude/skills/theme-creation && rm skill.zipInstalls to .claude/skills/theme-creation
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/open-sans@5.2.5/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.
More by etewiah
View all skills by etewiah →You might also like
flutter-development
aj-geddes
Build beautiful cross-platform mobile apps with Flutter and Dart. Covers widgets, state management with Provider/BLoC, navigation, API integration, and material design.
drawio-diagrams-enhanced
jgtolentino
Create professional draw.io (diagrams.net) diagrams in XML format (.drawio files) with integrated PMP/PMBOK methodologies, extensive visual asset libraries, and industry-standard professional templates. Use this skill when users ask to create flowcharts, swimlane diagrams, cross-functional flowcharts, org charts, network diagrams, UML diagrams, BPMN, project management diagrams (WBS, Gantt, PERT, RACI), risk matrices, stakeholder maps, or any other visual diagram in draw.io format. This skill includes access to custom shape libraries for icons, clipart, and professional symbols.
ui-ux-pro-max
nextlevelbuilder
"UI/UX design intelligence. 50 styles, 21 palettes, 50 font pairings, 20 charts, 8 stacks (React, Next.js, Vue, Svelte, SwiftUI, React Native, Flutter, Tailwind). Actions: plan, build, create, design, implement, review, fix, improve, optimize, enhance, refactor, check UI/UX code. Projects: website, landing page, dashboard, admin panel, e-commerce, SaaS, portfolio, blog, mobile app, .html, .tsx, .vue, .svelte. Elements: button, modal, navbar, sidebar, card, table, form, chart. Styles: glassmorphism, claymorphism, minimalism, brutalism, neumorphism, bento grid, dark mode, responsive, skeuomorphism, flat design. Topics: color palette, accessibility, animation, layout, typography, font pairing, spacing, hover, shadow, gradient."
godot
bfollington
This skill should be used when working on Godot Engine projects. It provides specialized knowledge of Godot's file formats (.gd, .tscn, .tres), architecture patterns (component-based, signal-driven, resource-based), common pitfalls, validation tools, code templates, and CLI workflows. The `godot` command is available for running the game, validating scripts, importing resources, and exporting builds. Use this skill for tasks involving Godot game development, debugging scene/resource files, implementing game systems, or creating new Godot components.
nano-banana-pro
garg-aayush
Generate and edit images using Google's Nano Banana Pro (Gemini 3 Pro Image) API. Use when the user asks to generate, create, edit, modify, change, alter, or update images. Also use when user references an existing image file and asks to modify it in any way (e.g., "modify this image", "change the background", "replace X with Y"). Supports both text-to-image generation and image-to-image editing with configurable resolution (1K default, 2K, or 4K for high resolution). DO NOT read the image file first - use this skill directly with the --input-image parameter.
fastapi-templates
wshobson
Create production-ready FastAPI projects with async patterns, dependency injection, and comprehensive error handling. Use when building new FastAPI applications or setting up backend API projects.
Related MCP Servers
Browse all serversIntegrate with Miro's online whiteboard for seamless collaboration. Manage boards, create items, and use 80+ tools for v
Integrate with Google Calendar API to retrieve, create, update, and delete events easily using OAuth2 and secure local t
Discover top AI tools for collaborative document management with Coda. List, create, and update pages using advanced AI
Use our meme generator to quickly create your memes with ImgFlip API. Make your meme easily by adding text and templates
Recraft AI is an ai image generator for creating, editing, and upscaling raster or vector images with advanced artificia
Create realistic AI generated videos with HeyGen's powerful AI video generator API. Access voices, avatars, and easy vid
Stay ahead of the MCP ecosystem
Get weekly updates on new skills and servers.