Port AtomCMS atom theme faithfully (Tailwind v4 + real CSS/assets + shell)
Make the template match the atom theme, not just approximate it: - Add Tailwind v4 (+forms/typography plugins, postcss) and port the real atom CSS (global.css + atom app.css) into globals.css: nav-item underline, currency + navigation icon classes, site-bg, card-base/hover-lift, text utils — asset paths adapted to /assets. - Copy the real theme assets (backgrounds, icons/currency/navigation, profile, leaderboards) into public/assets. - Rebuild the shell 1:1 from the atom Blade: TopHeader (currency pills + user/admin dropdowns, auth-only), SiteHeader (header image + black/50 overlay, logo+online+Nitro client / guest Login+Create-account CTA), Navigation (white bar, nav-item + Community/Assistance dropdowns), Footer. ThemeVars injects the DB-driven CSS custom properties into :root like app.blade.php. Layout uses the atom body/site-bg + grid-cols-12 max-w-7xl content wrapper. Verified: tsc 0, next build exit 0; curl confirms the atom markup, compiled CSS references the assets, and background-light.jpg + currency/navigation icons all serve 200.
This commit is contained in:
1 parent
e668fa85ec
commit
e19debb795
337 files changed
+1172
-398
No files matched your search
@@ -0,0 +1,58 @@
|
||||
import { siteSettings } from "@/lib/services/site-settings";
|
||||
|
||||
// Injects the DB-driven CSS custom properties into :root, exactly like
|
||||
// AtomCMS's app.blade.php. Falls back to the atom defaults when no DB.
|
||||
export async function ThemeVars() {
|
||||
const g = (k: string, d: string) => siteSettings.get(k, d);
|
||||
const [
|
||||
primary,
|
||||
background,
|
||||
surface,
|
||||
dropdown,
|
||||
navbar,
|
||||
navbarText,
|
||||
text,
|
||||
textMuted,
|
||||
accent,
|
||||
buttonColor,
|
||||
buttonText,
|
||||
borderColor,
|
||||
borderRadius,
|
||||
] = await Promise.all([
|
||||
g("color_primary", "#f59e0b"),
|
||||
g("color_background", "#f8fafc"),
|
||||
g("color_surface", "#ffffff"),
|
||||
g("color_dropdown", "#ffffff"),
|
||||
g("color_navbar", "#ffffff"),
|
||||
g("color_navbar_text", "#1e293b"),
|
||||
g("color_text", "#0f172a"),
|
||||
g("color_text_muted", "#64748b"),
|
||||
g("color_accent", "#10b981"),
|
||||
g("button_primary_color", "#f59e0b"),
|
||||
g("button_text_color", "#1e293b"),
|
||||
g("border_color", "#eeb425"),
|
||||
g("border_radius", "12"),
|
||||
]);
|
||||
|
||||
// Only hex/keyword color values are admin-controlled — sanitize defensively.
|
||||
const safe = (v: string | null, d: string) => (v && /^[#a-zA-Z0-9(),.\s%-]+$/.test(v) ? v : d);
|
||||
|
||||
const css = `:root{
|
||||
--color-primary:${safe(primary, "#f59e0b")};
|
||||
--color-background:${safe(background, "#f8fafc")};
|
||||
--color-surface:${safe(surface, "#ffffff")};
|
||||
--color-dropdown:${safe(dropdown, "#ffffff")};
|
||||
--color-navbar:${safe(navbar, "#ffffff")};
|
||||
--color-navbar-text:${safe(navbarText, "#1e293b")};
|
||||
--color-text:${safe(text, "#0f172a")};
|
||||
--color-text-muted:${safe(textMuted, "#64748b")};
|
||||
--color-accent:${safe(accent, "#10b981")};
|
||||
--button-color:${safe(buttonColor, "#f59e0b")};
|
||||
--button-text-color:${safe(buttonText, "#1e293b")};
|
||||
--border-color:${safe(borderColor, "#eeb425")};
|
||||
--border-radius:${/^\d+$/.test(borderRadius ?? "") ? borderRadius : "12"}px;
|
||||
}`;
|
||||
|
||||
// biome-ignore lint/security/noDangerouslySetInnerHtml: server-built CSS from sanitized admin settings
|
||||
return <style dangerouslySetInnerHTML={{ __html: css }} />;
|
||||
}
|
||||
Reference in new issue
Block a user