Back to Documentation

theme

# Dark Mode / Light Mode Theme System

Akoto Verify supports dark and light mode across all pages with automatic preference persistence.

## Features

- **Toggle Switch**: Sun/moon toggle in navigation bar (left side)
- **Dual Logos**: AkotoVerify3.png (light mode) / AkotoVerify5.png (dark mode)
- **Persistence**: Theme preference saved to localStorage
- **Professional Themes**: Light mode (white/slate) and dark mode (navy blue)
- **Fixed Navigation Bar**: Consistent across all pages with blur backdrop
- **Animations**: fadeInUp, float, scroll-triggered effects

## Design System

### Colors
| Element | Light Mode | Dark Mode |
|---------|------------|-----------|
| Background | #f8fafc | #0f172a |
| Secondary BG | #e2e8f0 | #1e3a5f |
| Text | #334155 | #e2e8f0 |
| Muted Text | #64748b | #94a3b8 |
| Cards | #fff | rgba(30, 58, 95, 0.5) |
| Accent | #3b82f6 | #3b82f6 |
| Success | #22c55e | #22c55e |
| Warning | #fcd34d | #fcd34d |
| Error | #ef4444 | #ef4444 |

### Typography
- Font: Inter (Google Fonts)
- Fallback: -apple-system, BlinkMacSystemFont, sans-serif

### Animations
- `fadeInUp`: Page load entrance animation
- `float`: Continuous floating effect on logos
- `pulse`: Step number indicators
- Scroll-triggered: IntersectionObserver for cards/features

## Navigation Bar

All pages share the same fixed navigation bar:
```html
<nav class="nav">
    <div class="theme-toggle">...</div>
    <div class="nav-links">
        <a href="/about">About</a>
        <a href="/how-to-use">How It Works</a>
        <a href="/plans">Pricing</a>
        <a href="/faq">FAQ</a>
        <a href="/plans/free" class="nav-cta">Get Started</a>
    </div>
</nav>
```

## Themed Pages (20+ total)

### Public Pages
| Page | Template | Path |
|------|----------|------|
| Landing | landing.html | `/` |
| About | about.html | `/about` |
| How To Use | how-to-use.html | `/how-to-use` |
| Plans | plans.html | `/plans` |
| FAQ | faq.html | `/faq` |
| Privacy | privacy.html | `/privacy` |
| Contact | contact.html | `/contact` |
| Free Signup | plans_free.html | `/plans/free` |

### Admin Pages
| Page | Template | Path |
|------|----------|------|
| Backoffice | backoffice.html | `/backoffice` |
| Companies | companies.html | `/companies` |
| Company Landing | company_landing.html | `/<company>` |
| Company Admin | company_admin.html | `/<company>/admin` |
| Settings | settings.html | `/<company>/settings` |
| Search/Payroll | search_logs.html | `/<company>/search` |
| Security | security_notifications.html | `/<company>/security` |

### Employee Pages
| Page | Template | Path |
|------|----------|------|
| Login | login.html | `/<company>/login` |
| Dashboard | logged_in.html | `/<company>/logged-in` |
| Logout | logout.html | `/<company>/logout` |
| My Logs | employee_search.html | `/<company>/mylogs` |

## Implementation Pattern

Each template follows this structure:

```html
<!DOCTYPE html>
<html lang="en">
<head>
    <link rel="stylesheet" href="/static/theme.css">
    <link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap" rel="stylesheet">
    <style>
        /* Base styles */
        body { 
            font-family: 'Inter', -apple-system, BlinkMacSystemFont, sans-serif;
            background: #f8fafc;
            color: #334155;
        }
        
        /* Animations */
        @keyframes fadeInUp { from { opacity: 0; transform: translateY(20px); } to { opacity: 1; transform: translateY(0); } }
        @keyframes float { 0%, 100% { transform: translateY(0); } 50% { transform: translateY(-8px); } }
        .animate { animation: fadeInUp 0.6s ease forwards; opacity: 0; }
        .float { animation: float 4s ease-in-out infinite; }
        
        /* Dark mode */
        body.dark { background: #0f172a; color: #e2e8f0; }
        body.dark .nav { background: rgba(30, 58, 95, 0.9); }
        /* ... more dark mode overrides */
    </style>
</head>
<body>
    <script src="/static/theme.js"></script>
    
    <nav class="nav">
        <div class="theme-toggle">...</div>
        <div class="nav-links">...</div>
    </nav>

    <div class="container">
        <!-- Logo with switching -->
        <img src="/static/AkotoVerify3.png" class="logo-light float">
        <img src="/static/AkotoVerify5.png" class="logo-dark float">
        
        <!-- Content with animations -->
        <div class="section animate delay-1">...</div>
    </div>

    <script>
        // Logo switching
        function updateLogos() {
            const isDark = document.body.classList.contains('dark');
            document.querySelectorAll('.logo-light').forEach(l => l.style.display = isDark ? 'none' : 'block');
            document.querySelectorAll('.logo-dark').forEach(l => l.style.display = isDark ? 'block' : 'none');
        }
        new MutationObserver(updateLogos).observe(document.body, { attributes: true, attributeFilter: ['class'] });
        updateLogos();
        
        // Fix dark mode colors (override theme.js globals)
        function fixDarkModeColors() {
            if (document.body.classList.contains('dark')) {
                const style = document.createElement('style');
                style.id = 'page-dark-fix';
                style.textContent = `/* !important overrides for theme.js */`;
                if (!document.getElementById('page-dark-fix')) document.head.appendChild(style);
            } else {
                const el = document.getElementById('page-dark-fix');
                if (el) el.remove();
            }
        }
        fixDarkModeColors();
        new MutationObserver(fixDarkModeColors).observe(document.body, { attributes: true, attributeFilter: ['class'] });
    </script>
</body>
</html>
```

## Dark Mode Fix Pattern

theme.js applies global `!important` rules that can override page-specific CSS. To fix this, each page injects a style tag with higher specificity:

```javascript
function fixDarkModeColors() {
    if (document.body.classList.contains('dark')) {
        const style = document.createElement('style');
        style.id = 'page-dark-fix';
        style.textContent = `
            body.dark .section h2 { color: #60a5fa !important; }
            body.dark label { color: #e2e8f0 !important; }
            /* ... page-specific overrides */
        `;
        if (!document.getElementById('page-dark-fix')) document.head.appendChild(style);
    }
}
```

## Files

- `static/theme.css` - Base dark mode styles
- `static/theme.js` - Toggle logic and localStorage persistence
- `templates/*.html` - Individual page templates with inline styles

## Backup Files

- `templates/landing_update2.html` - Backup of Update 2
- `templates/landing_update3.html` - Backup of Update 3