<?php
// Serve the active theme CSS with colour overrides appended
require_once __DIR__ . '/config.php';
if (!IS_INSTALLED) {
header('Content-Type: text/css; charset=UTF-8');
header('Cache-Control: no-store');
readfile(__DIR__ . '/assets/css/os2.css');
exit;
}
require_once ROOT_PATH . '/includes/db.php';
require_once ROOT_PATH . '/includes/functions.php';
$theme = get_active_theme();
$css = $theme ? $theme['css_content'] : @file_get_contents(__DIR__ . '/assets/css/os2.css');
// Build colour overrides — these are APPENDED after the theme CSS so they win over
// any :root {} block already present in the theme file.
$colorMap = [
'--desktop-bg' => ['key' => 'color_desktop_bg', 'default' => '#1A0A2E'],
'--window-bg' => ['key' => 'color_window_bg', 'default' => '#C8C4D0'],
'--titlebar-bg' => ['key' => 'color_titlebar_bg', 'default' => '#5B2D8E'],
'--titlebar-bg-end' => ['key' => 'color_titlebar_bg_end','default' => '#2D1B6B'],
'--titlebar-text' => ['key' => 'color_titlebar_text', 'default' => '#FFFFFF'],
'--text-color' => ['key' => 'color_text', 'default' => '#000000'],
'--link-color' => ['key' => 'color_link', 'default' => '#4A007A'],
'--accent-color' => ['key' => 'color_accent', 'default' => '#5B2D8E'],
'--content-bg' => ['key' => 'color_content_bg', 'default' => '#FFFFFF'],
'--footer-bg' => ['key' => 'color_footer_bg', 'default' => '#9888B0'],
];
$overrides = ":root {\n";
foreach ($colorMap as $var => $cfg) {
$val = get_setting($cfg['key'], $cfg['default']);
$val = preg_replace('/[^a-zA-Z0-9#(),.\s%+-]/', '', $val);
$overrides .= " {$var}: {$val};\n";
}
$overrides .= "}\n";
// Cache-bust via the theme's updated_at timestamp so browsers always get
// fresh CSS after a theme save, while still caching between saves.
$etag = $theme ? md5($theme['updated_at'] . $overrides) : md5($overrides);
$clientEtag = $_SERVER['HTTP_IF_NONE_MATCH'] ?? '';
if ($clientEtag === '"' . $etag . '"') {
http_response_code(304);
exit;
}
header('Content-Type: text/css; charset=UTF-8');
header('Cache-Control: public, max-age=60, must-revalidate');
header('ETag: "' . $etag . '"');
// Readability fixes — appended after theme CSS so they override any hardcoded values
// in older or custom themes. These use CSS variables so they adapt to each palette.
$fixes = "\n/* ── Readability fixes (always applied, override theme CSS) ── */\n";
$fixes .= ".hero-desc { color: var(--titlebar-text) !important; opacity: 0.9; }\n";
$fixes .= ".win-titlebar a, .section-titlebar a { color: var(--titlebar-text) !important; }\n";
$fixes .= ".win-titlebar a:hover, .section-titlebar a:hover { color: var(--titlebar-text) !important; }\n";
// CSS comes first, overrides appended last — last :root {} declaration wins
echo $css . "\n\n/* ── Palette overrides (from Settings → Colour Palette) ── */\n" . $overrides . $fixes;