style engine updated

This commit is contained in:
2026-04-23 09:07:52 +02:00
parent 573cc5dc74
commit cba94f6e75
5 changed files with 208 additions and 48 deletions

View File

@@ -42,42 +42,107 @@ function restart() {
}
async function loadServerStyles(activeTheme = 'dark') {
const res = await fetch('models/stylesheet.json');
const json = await res.json();
async function loadServerStyles(theme = 'dark') {
const res = await fetch('models/stylesheet.json');
const json = await res.json();
function toCssVars(obj, prefix = '', group = '') {
let vars = [];
function jsonToCssVars(obj, prefix = '') {
let vars = [];
for (const key in obj) {
const value = obj[key];
const newPrefix = prefix ? `${prefix}-${key}` : key;
for (const key in obj) {
const value = obj[key];
const newPrefix = prefix ? `${prefix}-${key}` : key;
if (Array.isArray(value)) {
if (value.length === 3) vars.push(`--theme-${newPrefix}: rgb(${value.join(', ')});`);
else if (value.length === 4) vars.push(`--theme-${newPrefix}: rgba(${value.join(', ')});`);
} else if (typeof value === 'object' && value !== null) {
vars.push(jsonToCssVars(value, newPrefix));
} else if (value !== '') {
vars.push(`--theme-${newPrefix}: ${value};`);
}
// console.log(vars.join('\n'))
if (Array.isArray(value)) {
if (value.length === 3) {
vars.push(`--${group}-${newPrefix}: rgb(${value.join(', ')});`);
} else if (value.length === 4) {
vars.push(`--${group}-${newPrefix}: rgba(${value.join(', ')});`);
}
}
else if (typeof value === 'object' && value !== null) {
vars.push(toCssVars(value, newPrefix, group));
}
else if (value !== '') {
vars.push(`--${group}-${newPrefix}: ${value};`);
}
}
return vars.join('\n');
}
return vars.join('\n');
let css = '';
// =========================
// 1. GLOBAL ROOT (times + base tokens)
// =========================
if (json.times) {
css += `:root {\n${toCssVars(json.times, '', 'times')}\n}\n`;
}
// =========================
// 2. THEME (selected variant)
// =========================
const themeVars = json.theme?.[activeTheme] || {};
css += `
:root {
${toCssVars(themeVars, '', 'theme')}
}
`;
// =========================
// 3. RESPONSIVE (media queries)
// =========================
const responsive = json.responsive || {};
for (const breakpoint in responsive) {
const bpVars = responsive[breakpoint];
// flatten vars
const vars = toCssVars(bpVars, '', 'responsive');
let media = '';
if (breakpoint === 'mobile') {
media = '@media (max-width: 600px)';
}
else if (breakpoint === 'tablet') {
media = '@media (min-width: 601px) and (max-width: 1024px)';
}
else if (breakpoint === 'desktop') {
media = '@media (min-width: 1025px)';
}
else {
continue; // unknown breakpoint skip
}
css += `${media} {
:root {
${vars}
}
}
`;
}
const themeVars = json.theme[theme];
const css = `:root {\n${jsonToCssVars(themeVars)}\n}`;
// =========================
// 4. INJECT STYLE TAG
// =========================
let styleTag = document.getElementById('theme-styles');
if (!styleTag) {
styleTag = document.createElement('style');
styleTag.id = 'theme-styles';
document.head.appendChild(styleTag);
}
styleTag.textContent = css;
document.getElementById('start-menu-icon').src = `../images/radix_os_${theme}_img.png`;
styleTag.textContent = css;
document.getElementById('start-menu-icon').src =
`../images/radix_os_${activeTheme}_img.png`;
console.log(css)
return true;
}