Theme Development

Introduction

FlatlyPage CMS uses a modern theming system based on CSS Custom Properties (CSS Variables), enabling easy creation and modification of page appearance. The system supports both light and dark themes and ensures full responsiveness across all devices.

Key Features

  • CSS Variables - Centralized color and style management
  • Light/Dark Mode - Automatic theme switching
  • Mobile-first - Responsive design for all devices
  • Modularity - Reusable components
  • Accessibility - WCAG 2.1 compliant

Theme Structure

CSS Reset

Every theme starts with a basic reset ensuring cross-browser consistency:

*,
*::before,
*::after {
    box-sizing: border-box;
    margin: 0;
    padding: 0;
}

Base Configuration

html {
    scroll-behavior: smooth;
}

body {
    font-family: -apple-system, BlinkMacSystemFont, sans-serif;
    background-color: var(--background);
    color: var(--foreground);
    line-height: 1.6;
    -webkit-font-smoothing: antialiased;
}

CSS Variables System

Dark Theme (Default)

:root {
    color-scheme: dark;
    --background: #111111;
    --foreground: #fafafa;
    --card: #1a1a1a;
    --card-hover: #222222;
    --muted: #888888;
    --border: #2a2a2a;
    --success: #22c55e;
    --navbar-bg: rgba(17, 17, 17, 0.8);
    --grid-line: rgba(255, 255, 255, 0.03);
    --avatar-from: #333;
    --avatar-to: #555;
}

Light Theme

:root[data-theme="light"] {
    color-scheme: light;
    --background: #ffffff;
    --foreground: #111111;
    --card: #f5f5f5;
    --card-hover: #efefef;
    --muted: #666666;
    --border: #e0e0e0;
    --success: #16a34a;
    --navbar-bg: rgba(255, 255, 255, 0.8);
    --grid-line: rgba(0, 0, 0, 0.05);
    --avatar-from: #ddd;
    --avatar-to: #bbb;
}

Variable Descriptions

Variable Purpose
--background Main page background
--foreground Main text color
--card Card and panel backgrounds
--card-hover Card background on hover
--muted Muted text (descriptions, captions)
--border Border colors
--success Success/confirmation color
--navbar-bg Navigation background with transparency
--grid-line Decorative grid lines
--avatar-from Avatar gradient start color
--avatar-to Avatar gradient end color

UI Components

Container

Main container limiting content width:

.container {
    max-width: 1200px;
    margin: 0 auto;
    padding: 0 24px;
}

Usage:

<div class="container">
    <!-- Your content -->
</div>

Buttons

Button system offering multiple variants:

Base Button

.btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    padding: 10px 20px;
    font-size: 0.875rem;
    font-weight: 500;
    border-radius: 8px;
    cursor: pointer;
    transition: all 0.2s;
    border: none;
    font-family: inherit;
}

Button Variants

Primary:

.btn-primary {
    background: var(--foreground);
    color: var(--background);
}

Outline:

.btn-outline {
    background: transparent;
    border: 1px solid var(--border);
    color: var(--foreground);
}

Ghost:

.btn-ghost {
    background: transparent;
    color: var(--foreground);
}

Example Usage:

<button class="btn btn-primary">Get Started</button>
<button class="btn btn-outline">Learn More</button>
<button class="btn btn-ghost">Cancel</button>

Cards

Universal card component:

.feature-card {
    background: var(--card);
    border: 1px solid var(--border);
    border-radius: 16px;
    padding: 32px;
    transition: all 0.3s;
}

.feature-card:hover {
    background: var(--card-hover);
    transform: translateY(-4px);
}

Badge

Label/badge with animated dot:

.badge {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    padding: 6px 16px;
    background: var(--card);
    border: 1px solid var(--border);
    border-radius: 100px;
    font-size: 0.875rem;
}

.badge-dot {
    width: 6px;
    height: 6px;
    background: var(--success);
    border-radius: 50%;
    animation: pulse 2s infinite;
}

@keyframes pulse {
    0%, 100% { opacity: 1; }
    50% { opacity: 0.5; }
}

Page Sections

Navigation (Navbar)

Fixed navigation with blur effect:

.navbar {
    position: fixed;
    top: 0;
    left: 0;
    right: 0;
    z-index: 50;
    background: var(--navbar-bg);
    backdrop-filter: blur(12px);
    border-bottom: 1px solid var(--border);
}

.navbar-inner {
    display: flex;
    align-items: center;
    justify-content: space-between;
    height: 72px;
}

HTML Structure:

<nav class="navbar">
    <div class="container">
        <div class="navbar-inner">
            <div class="logo">Logo</div>
            <div class="nav-links">
                <a href="#features">Features</a>
                <a href="#pricing">Pricing</a>
            </div>
            <div class="nav-buttons">
                <button class="btn btn-outline">Sign In</button>
                <button class="btn btn-primary">Get Started</button>
            </div>
        </div>
    </div>
</nav>

Hero Section

Main welcome section with grid effect:

.hero {
    padding: 160px 0 100px;
    position: relative;
    overflow: hidden;
    margin-top: 42px;
}

.hero-grid {
    position: absolute;
    inset: 0;
    background-image: 
        linear-gradient(var(--grid-line) 1px, transparent 1px),
        linear-gradient(90deg, var(--grid-line) 1px, transparent 1px);
    background-size: 60px 60px;
    mask-image: radial-gradient(ellipse at center, black 20%, transparent 70%);
}

Example Usage:

<section class="hero">
    <div class="hero-grid"></div>
    <div class="container">
        <div class="hero-content">
            <div class="badge">
                <span class="badge-dot"></span>
                New Release
            </div>
            <h1>Welcome to FlatlyPage</h1>
            <p>Create beautiful pages effortlessly</p>
            <div class="hero-buttons">
                <button class="btn btn-primary">Start Free Trial</button>
                <button class="btn btn-outline">View Demo</button>
            </div>
        </div>
    </div>
</section>

Stats Section

.stats {
    padding: 80px 0;
    border-top: 1px solid var(--border);
    border-bottom: 1px solid var(--border);
}

.stats-grid {
    display: grid;
    grid-template-columns: repeat(4, 1fr);
    gap: 48px;
    text-align: center;
}

HTML:

<section class="stats">
    <div class="container">
        <div class="stats-grid">
            <div class="stat-item">
                <h3>10k+</h3>
                <p>Active Users</p>
            </div>
            <!-- more stats -->
        </div>
    </div>
</section>

Features Section

Grid with feature cards:

.features-grid {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: 24px;
}

.feature-icon {
    width: 48px;
    height: 48px;
    background: var(--background);
    border: 1px solid var(--border);
    border-radius: 12px;
    display: flex;
    align-items: center;
    justify-content: center;
    margin-bottom: 20px;
}

Pricing Cards

Pricing cards with featured option:

.pricing-card {
    background: var(--card);
    border: 1px solid var(--border);
    border-radius: 20px;
    padding: 40px;
    position: relative;
    transition: transform 0.3s;
}

.pricing-card.featured {
    border-color: var(--foreground);
    transform: scale(1.02);
}

.pricing-popular {
    position: absolute;
    top: -12px;
    left: 50%;
    transform: translateX(-50%);
    background: var(--foreground);
    color: var(--background);
    padding: 6px 16px;
    border-radius: 100px;
    font-size: 0.75rem;
    font-weight: 600;
    text-transform: uppercase;
}

FAQ (Accordion)

Expandable questions and answers:

.faq-item {
    background: var(--card);
    border: 1px solid var(--border);
    border-radius: 12px;
    margin-bottom: 16px;
    overflow: hidden;
}

.faq-question::after {
    content: '+';
    font-size: 1.5rem;
    transition: transform 0.3s;
}

.faq-item[open] .faq-question::after {
    transform: rotate(45deg);
}

HTML:

<details class="faq-item">
    <summary class="faq-question">How do I get started?</summary>
    <div class="faq-answer">
        <p>It's simple! Just sign up...</p>
    </div>
</details>

Team Section

.team-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
    gap: 32px;
}

.team-avatar {
    width: 80px;
    height: 80px;
    border-radius: 50%;
    background: linear-gradient(135deg, var(--avatar-from) 0%, var(--avatar-to) 100%);
    display: flex;
    align-items: center;
    justify-content: center;
    font-weight: 700;
    font-size: 1.5rem;
    margin: 0 auto 20px;
}

Newsletter Form

Subscription form:

.newsletter-form {
    display: flex;
    gap: 12px;
    max-width: 500px;
    margin: 0 auto;
}

.newsletter-input {
    flex: 1;
    padding: 14px 20px;
    border: 1px solid var(--border);
    border-radius: 8px;
    background: var(--background);
    color: var(--foreground);
    font-size: 1rem;
}

.newsletter-input:focus {
    outline: none;
    border-color: var(--foreground);
}

Footer

Comprehensive footer with multiple columns:

.footer-grid {
    display: grid;
    grid-template-columns: 2fr repeat(4, 1fr);
    gap: 64px;
    margin-bottom: 64px;
}

.social-links a {
    width: 40px;
    height: 40px;
    background: var(--card);
    border: 1px solid var(--border);
    border-radius: 8px;
    display: flex;
    align-items: center;
    justify-content: center;
    transition: all 0.2s;
}

Responsiveness

Breakpoints

The system uses three main breakpoints:

/* Tablet (≤1024px) */
@media (max-width: 1024px) {
    .features-grid,
    .pricing-grid {
        grid-template-columns: repeat(2, 1fr);
    }
}

/* Mobile (≤768px) */
@media (max-width: 768px) {
    .nav-links,
    .nav-buttons {
        display: none;
    }
    
    .mobile-menu-btn {
        display: block;
    }
    
    .features-grid {
        grid-template-columns: 1fr;
    }
}

/* Small mobile (≤480px) */
@media (max-width: 480px) {
    .hero h1 {
        font-size: 2rem;
    }
    
    .hero-buttons {
        flex-direction: column;
        width: 100%;
    }
}

Responsive Typography

Using clamp() for fluid typography:

.hero h1 {
    font-size: clamp(2.5rem, 6vw, 4rem);
}

Mobile Menu

.mobile-nav {
    display: none;
    position: fixed;
    top: 72px;
    left: 0;
    right: 0;
    background: var(--background);
    border-bottom: 1px solid var(--border);
    padding: 24px;
    z-index: 49;
}

.mobile-nav.active {
    display: block;
}

Best Practices

1. Using CSS Variables

Good:

.custom-card {
    background: var(--card);
    border: 1px solid var(--border);
    color: var(--foreground);
}

Bad:

.custom-card {
    background: #1a1a1a;
    border: 1px solid #2a2a2a;
    color: #fafafa;
}

2. Consistent Padding and Margin

Use values in multiples of 4px or 8px:

/* Good */
padding: 16px 24px;
margin-bottom: 32px;
gap: 12px;

/* Avoid */
padding: 15px 23px;
margin-bottom: 31px;

3. Border Radius

Standard values:

border-radius: 8px;   /* buttons, small elements */
border-radius: 12px;  /* cards, medium elements */
border-radius: 16px;  /* large cards */
border-radius: 100px; /* pill shape (badge) */

4. Transitions

Use consistent transition times:

transition: all 0.2s;  /* quick interactions (hover) */
transition: all 0.3s;  /* medium animations (cards) */
transition: transform 0.3s; /* specific property */

5. Z-index Hierarchy

.navbar {
    z-index: 50;
}

.mobile-nav {
    z-index: 49;
}

.modal {
    z-index: 100;
}

6. Accessibility

/* Focus states */
.btn:focus {
    outline: 2px solid var(--foreground);
    outline-offset: 2px;
}

/* Screen reader only */
.sr-only {
    position: absolute;
    width: 1px;
    height: 1px;
    padding: 0;
    margin: -1px;
    overflow: hidden;
    clip: rect(0, 0, 0, 0);
    border: 0;
}

Summary

The FlatlyPage CMS theme system offers:

  • ✅ Easy customization - everything through CSS variables
  • ✅ Light/Dark mode - automatic switching
  • ✅ Responsiveness - works on all devices
  • ✅ Ready-to-use components - speed up development
  • ✅ Modern standards - CSS Grid, Flexbox, Custom Properties
  • ✅ Accessibility - WCAG compliant

Browser Support

  • Chrome/Edge 88+
  • Firefox 85+
  • Safari 14+
  • Opera 74+