first commit

This commit is contained in:
douboer
2026-03-21 18:57:10 +08:00
commit c49aa1a5e9
570 changed files with 107167 additions and 0 deletions

View File

@@ -0,0 +1,534 @@
/* global module, wx */
/**
* 小程序主题预设与 shared/Web 保持同一套内部值和顺序:
* 1. 这里保留运行时可直接消费的扁平对象,避免小程序侧额外依赖 TS 共享模块;
* 2. 若 shared 新增主题,这里也要同步补齐,保证多端主题配置可互通;
* 3. shell cursor 仍按当前小程序规则实时推导,因此这里只保留 bg/text 基色。
*/
const THEME_PRESETS = {
tide: {
dark: { bg: "#192b4d", text: "#e6f0ff", accent: "#5bd2ff" },
light: { bg: "#e6f0ff", text: "#192b4d", accent: "#3D86FF" },
shellDark: { bg: "#192b4d", text: "#e6f0ff", cursor: "#5bd2ff" },
shellLight: { bg: "#e6f0ff", text: "#192b4d", cursor: "#3D86FF" }
},
暮砂: {
dark: { bg: "#3D405B", text: "#F4F1DE", accent: "#81B29A" },
light: { bg: "#F4F1DE", text: "#3D405B", accent: "#E07A5F" },
shellDark: { bg: "#3D405B", text: "#F4F1DE", cursor: "#81B29A" },
shellLight: { bg: "#F4F1DE", text: "#3D405B", cursor: "#E07A5F" }
},
霓潮: {
dark: { bg: "#073B4C", text: "#FFD166", accent: "#06D6A0" },
light: { bg: "#FFD166", text: "#073B4C", accent: "#EF476F" },
shellDark: { bg: "#073B4C", text: "#FFD166", cursor: "#06D6A0" },
shellLight: { bg: "#FFD166", text: "#073B4C", cursor: "#EF476F" }
},
苔暮: {
dark: { bg: "#282C75", text: "#A8B868", accent: "#7A71E4" },
light: { bg: "#A8B868", text: "#282C75", accent: "#4E4CC3" },
shellDark: { bg: "#282C75", text: "#A8B868", cursor: "#7A71E4" },
shellLight: { bg: "#A8B868", text: "#282C75", cursor: "#4E4CC3" }
},
焰岩: {
dark: { bg: "#0F4C5C", text: "#FB8B24", accent: "#E36414" },
light: { bg: "#FB8B24", text: "#0F4C5C", accent: "#CB4721" },
shellDark: { bg: "#0F4C5C", text: "#FB8B24", cursor: "#E36414" },
shellLight: { bg: "#FB8B24", text: "#0F4C5C", cursor: "#CB4721" }
},
岩陶: {
dark: { bg: "#283D3B", text: "#EDDDD4", accent: "#E9B5AF" },
light: { bg: "#EDDDD4", text: "#283D3B", accent: "#D99185" },
shellDark: { bg: "#283D3B", text: "#EDDDD4", cursor: "#E9B5AF" },
shellLight: { bg: "#EDDDD4", text: "#283D3B", cursor: "#D99185" }
},
靛雾: {
dark: { bg: "#292281", text: "#F1F0CD", accent: "#9D96BA" },
light: { bg: "#F1F0CD", text: "#292281", accent: "#4A3BA6" },
shellDark: { bg: "#292281", text: "#F1F0CD", cursor: "#9D96BA" },
shellLight: { bg: "#F1F0CD", text: "#292281", cursor: "#4A3BA6" }
},
绛霓: {
dark: { bg: "#3A0CA3", text: "#4CC9F0", accent: "#4895EF" },
light: { bg: "#4CC9F0", text: "#3A0CA3", accent: "#F72585" },
shellDark: { bg: "#3A0CA3", text: "#4CC9F0", cursor: "#4895EF" },
shellLight: { bg: "#4CC9F0", text: "#3A0CA3", cursor: "#F72585" }
},
玫蓝: {
dark: { bg: "#3D1F94", text: "#629FEB", accent: "#D06A79" },
light: { bg: "#629FEB", text: "#3D1F94", accent: "#D06A79" },
shellDark: { bg: "#3D1F94", text: "#629FEB", cursor: "#567BE3" },
shellLight: { bg: "#629FEB", text: "#3D1F94", cursor: "#D06A79" }
},
珊湾: {
dark: { bg: "#37615B", text: "#52DFDD", accent: "#EC5B57" },
light: { bg: "#52DFDD", text: "#37615B", accent: "#EC5B57" },
shellDark: { bg: "#37615B", text: "#52DFDD", cursor: "#44B0AB" },
shellLight: { bg: "#52DFDD", text: "#37615B", cursor: "#EC5B57" }
},
苔荧: {
dark: { bg: "#252157", text: "#D1D942", accent: "#99A32C" },
light: { bg: "#D1D942", text: "#252157", accent: "#909636" },
shellDark: { bg: "#252157", text: "#D1D942", cursor: "#C2CB37" },
shellLight: { bg: "#D1D942", text: "#252157", cursor: "#909636" }
},
铜暮: {
dark: { bg: "#1A375A", text: "#E6B030", accent: "#B27225" },
light: { bg: "#E6B030", text: "#1A375A", accent: "#B27225" },
shellDark: { bg: "#1A375A", text: "#E6B030", cursor: "#D99F27" },
shellLight: { bg: "#E6B030", text: "#1A375A", cursor: "#B27225" }
},
炽潮: {
dark: { bg: "#125554", text: "#F55054", accent: "#C43133" },
light: { bg: "#F55054", text: "#125554", accent: "#AA3E40" },
shellDark: { bg: "#125554", text: "#F55054", cursor: "#E94347" },
shellLight: { bg: "#F55054", text: "#125554", cursor: "#AA3E40" }
},
藕夜: {
dark: { bg: "#322F4F", text: "#DBDD85", accent: "#554C93" },
light: { bg: "#DBDD85", text: "#322F4F", accent: "#D5DB74" },
shellDark: { bg: "#322F4F", text: "#DBDD85", cursor: "#C8CF67" },
shellLight: { bg: "#DBDD85", text: "#322F4F", cursor: "#554C93" }
},
沙海: {
dark: { bg: "#2B3B51", text: "#E2D075", accent: "#3F7690" },
light: { bg: "#E2D075", text: "#2B3B51", accent: "#355971" },
shellDark: { bg: "#2B3B51", text: "#E2D075", cursor: "#DBAA5F" },
shellLight: { bg: "#E2D075", text: "#2B3B51", cursor: "#3F7690" }
},
珀岚: {
dark: { bg: "#274D4C", text: "#E79094", accent: "#2F9595" },
light: { bg: "#E79094", text: "#274D4C", accent: "#2B7171" },
shellDark: { bg: "#274D4C", text: "#E79094", cursor: "#EC7578" },
shellLight: { bg: "#E79094", text: "#274D4C", cursor: "#2F9595" }
},
炫虹: {
dark: { bg: "#8338EC", text: "#FFBE0B", accent: "#FF006E" },
light: { bg: "#FFBE0B", text: "#8338EC", accent: "#FD2B3B" },
shellDark: { bg: "#8338EC", text: "#FFBE0B", cursor: "#3A86FF" },
shellLight: { bg: "#FFBE0B", text: "#8338EC", cursor: "#FF006E" }
},
鎏霓: {
dark: { bg: "#7550D5", text: "#F3D321", accent: "#A2529A" },
light: { bg: "#F3D321", text: "#7550D5", accent: "#D67039" },
shellDark: { bg: "#7550D5", text: "#F3D321", cursor: "#476CEF" },
shellLight: { bg: "#F3D321", text: "#7550D5", cursor: "#A2529A" }
},
珊汐: {
dark: { bg: "#7F9E96", text: "#FB5860", accent: "#3DCAC5" },
light: { bg: "#FB5860", text: "#7F9E96", accent: "#F2292C" },
shellDark: { bg: "#7F9E96", text: "#FB5860", cursor: "#3DCAC5" },
shellLight: { bg: "#FB5860", text: "#7F9E96", cursor: "#F2292C" }
},
黛苔: {
dark: { bg: "#2F2E3B", text: "#E7E8D6", accent: "#788031" },
light: { bg: "#E7E8D6", text: "#2F2E3B", accent: "#788031" },
shellDark: { bg: "#2F2E3B", text: "#E7E8D6", cursor: "#949D3A" },
shellLight: { bg: "#E7E8D6", text: "#2F2E3B", cursor: "#788031" }
},
霜绯: {
dark: { bg: "#293B3B", text: "#ECD7D8", accent: "#1D7575" },
light: { bg: "#ECD7D8", text: "#293B3B", accent: "#993333" },
shellDark: { bg: "#293B3B", text: "#ECD7D8", cursor: "#BD3C3D" },
shellLight: { bg: "#ECD7D8", text: "#293B3B", cursor: "#993333" }
}
};
const DEFAULT_UI = THEME_PRESETS.tide.dark;
const SHELL_ACCENT_BLEND_T = 0.64;
const DEFAULT_SHELL = {
...THEME_PRESETS.tide.shellDark,
cursor: pickShellAccentColor(THEME_PRESETS.tide.shellDark.bg, THEME_PRESETS.tide.shellDark.text)
};
const DEFAULT_SHELL_FONT_FAMILY = 'JetBrains Mono, "SFMono-Regular", Menlo, monospace';
const DEFAULT_SHELL_FONT_SIZE = 15;
const DEFAULT_SHELL_LINE_HEIGHT = 1.4;
const DEFAULT_NAVIGATION_BAR_THEME = {
backgroundColor: DEFAULT_UI.bg,
frontColor: "#ffffff"
};
/**
* 小程序终端当前采用“固定 cell 网格 + 自绘 caret”模型。
* 因此这里只允许已验证度量稳定的终端字体;比例字体或中英文度量不稳定的字体
* 会导致字间空隙拉大、光标横向偏移。
*/
const TERMINAL_SAFE_FONT_OPTIONS = [
{
label: "等宽默认",
value: 'ui-monospace, "SFMono-Regular", Menlo, Consolas, "Liberation Mono", monospace'
},
{
label: "JetBrains Mono",
value: '"JetBrains Mono", "SFMono-Regular", Menlo, Consolas, monospace'
},
{ label: "SF Mono", value: '"SFMono-Regular", Menlo, monospace' },
{ label: "Menlo", value: "Menlo, Monaco, monospace" },
{ label: "Monaco", value: "Monaco, Menlo, monospace" },
{ label: "Consolas", value: 'Consolas, "Courier New", monospace' },
{
label: "Roboto Mono",
value: '"Roboto Mono", "SFMono-Regular", Menlo, Consolas, monospace'
}
];
const TERMINAL_SAFE_FONT_VALUE_SET = new Set(
TERMINAL_SAFE_FONT_OPTIONS.map((item) =>
String(item.value || "")
.trim()
.toLowerCase()
)
);
function clampChannel(value) {
if (!Number.isFinite(value)) return 0;
if (value < 0) return 0;
if (value > 255) return 255;
return Math.round(value);
}
function clampNumber(value, min, max, fallback) {
const parsed = Number(value);
if (!Number.isFinite(parsed)) return fallback;
if (parsed < min) return min;
if (parsed > max) return max;
return parsed;
}
function sanitizeCssToken(value, fallback) {
const raw = String(value == null ? "" : value)
.replace(/[;\n\r]/g, " ")
.trim();
return raw || fallback;
}
function normalizeTerminalFontFamily(value) {
const raw = sanitizeCssToken(value, DEFAULT_SHELL_FONT_FAMILY);
return TERMINAL_SAFE_FONT_VALUE_SET.has(raw.toLowerCase()) ? raw : DEFAULT_SHELL_FONT_FAMILY;
}
function hexToRgb(hex) {
const raw = String(hex || "").trim();
const match = raw.match(/^#([0-9a-fA-F]{3}|[0-9a-fA-F]{6})$/);
if (!match) return null;
const normalized =
match[1].length === 3
? match[1]
.split("")
.map((ch) => ch + ch)
.join("")
: match[1];
return {
r: parseInt(normalized.slice(0, 2), 16),
g: parseInt(normalized.slice(2, 4), 16),
b: parseInt(normalized.slice(4, 6), 16)
};
}
function rgbToHex(rgb) {
const toHex = (value) => clampChannel(value).toString(16).padStart(2, "0");
return `#${toHex(rgb.r)}${toHex(rgb.g)}${toHex(rgb.b)}`;
}
function hexToRgba(hex, alpha, fallback) {
const rgb = hexToRgb(hex);
if (!rgb) return fallback;
const normalizedAlpha = clampNumber(alpha, 0, 1, 1);
return `rgba(${rgb.r}, ${rgb.g}, ${rgb.b}, ${normalizedAlpha})`;
}
function mixHex(a, b, t) {
const left = hexToRgb(a);
const right = hexToRgb(b);
if (!left || !right) return b;
return rgbToHex({
r: left.r + (right.r - left.r) * t,
g: left.g + (right.g - left.g) * t,
b: left.b + (right.b - left.b) * t
});
}
function pickBtnColor(bg, text) {
return mixHex(bg, text, 0.72);
}
/**
* Shell 强调色与 Web/shared 规则保持一致:
* 1. 不直接复用 UI accent避免终端层级过亮
* 2. 在 shell 背景和前景之间取“中间偏前景”的颜色;
* 3. 这样终端按钮、光标和状态提示可以跟随 shell 主体变化。
*/
function pickShellAccentColor(bg, text) {
return mixHex(bg, text, SHELL_ACCENT_BLEND_T);
}
function resolveRelativeLuminance(hex) {
const rgb = hexToRgb(hex);
if (!rgb) return 0;
const channelToLinear = (value) => {
const normalized = clampChannel(value) / 255;
if (normalized <= 0.03928) {
return normalized / 12.92;
}
return ((normalized + 0.055) / 1.055) ** 2.4;
};
return channelToLinear(rgb.r) * 0.2126 + channelToLinear(rgb.g) * 0.7152 + channelToLinear(rgb.b) * 0.0722;
}
/**
* 解析原生导航栏配色:
* 1. backgroundColor 跟随当前 UI 背景色;
* 2. frontColor 仅允许微信支持的 #ffffff / #000000两者按背景亮度择优。
*/
function resolveNavigationBarTheme(settings) {
const palette = resolveRuntimeTheme(settings);
const luminance = resolveRelativeLuminance(palette.bg);
return {
backgroundColor: palette.bg,
frontColor: luminance >= 0.42 ? "#000000" : "#ffffff"
};
}
/**
* 将当前主题同步到微信原生导航栏,解决“页面工具栏上方颜色锁定”的问题。
* 调用失败时静默返回,避免在单测或非微信运行环境中抛错。
*/
function applyNavigationBarTheme(settings, wxLike) {
const theme = resolveNavigationBarTheme(settings);
const api = wxLike || (typeof wx !== "undefined" ? wx : null);
if (!api || typeof api.setNavigationBarColor !== "function") {
return theme;
}
try {
api.setNavigationBarColor({
frontColor: theme.frontColor,
backgroundColor: theme.backgroundColor,
animation: {
duration: 0,
timingFunc: "linear"
}
});
} catch {
return theme;
}
return theme;
}
function getPreset(preset) {
const key = String(preset || "tide");
return THEME_PRESETS[key] || THEME_PRESETS.tide;
}
function getUiThemeVariant(preset, mode) {
const entry = getPreset(preset);
return mode === "light" ? entry.light : entry.dark;
}
function getShellThemeVariant(preset, mode) {
const entry = getPreset(preset);
const variant = mode === "light" ? entry.shellLight : entry.shellDark;
return {
...variant,
cursor: pickShellAccentColor(variant.bg, variant.text)
};
}
function applyUiThemeSelection(form) {
const source = { ...(form || {}) };
const mode = source.uiThemeMode === "light" ? "light" : "dark";
const variant = getUiThemeVariant(source.uiThemePreset, mode);
source.uiBgColor = variant.bg;
source.uiTextColor = variant.text;
source.uiAccentColor = variant.accent;
source.uiBtnColor = pickBtnColor(variant.bg, variant.text);
return source;
}
function applyShellThemeSelection(form) {
const source = { ...(form || {}) };
const mode = source.shellThemeMode === "light" ? "light" : "dark";
const variant = getShellThemeVariant(source.shellThemePreset, mode);
source.shellBgColor = variant.bg;
source.shellTextColor = variant.text;
source.shellAccentColor = pickShellAccentColor(variant.bg, variant.text);
return source;
}
function resolveRuntimeTheme(settings) {
const s = settings || {};
const uiBg = s.uiBgColor || DEFAULT_UI.bg;
const uiText = s.uiTextColor || DEFAULT_UI.text;
const shellBg = s.shellBgColor || DEFAULT_SHELL.bg;
const shellText = s.shellTextColor || DEFAULT_SHELL.text;
return {
bg: uiBg,
text: uiText,
accent: s.uiAccentColor || DEFAULT_UI.accent,
btn: s.uiBtnColor || pickBtnColor(uiBg, uiText),
shellBg,
shellText,
shellAccent: s.shellAccentColor || pickShellAccentColor(shellBg, shellText),
shellFontFamily: normalizeTerminalFontFamily(s.shellFontFamily),
shellFontSize: clampNumber(s.shellFontSize, 12, 22, DEFAULT_SHELL_FONT_SIZE),
shellLineHeight: clampNumber(s.shellLineHeight, 1, 2, DEFAULT_SHELL_LINE_HEIGHT)
};
}
function resolveButtonTokens(palette) {
return {
btnBorder: mixHex(palette.bg, palette.btn, 0.68),
btnBorderStrong: mixHex(palette.bg, palette.btn, 0.84),
btnBg: mixHex(palette.bg, palette.btn, 0.2),
btnBgStrong: mixHex(palette.bg, palette.btn, 0.34),
btnBgActive: mixHex(palette.bg, palette.btn, 0.26),
btnText: mixHex(palette.text, palette.btn, 0.18),
btnDangerBorder: mixHex(palette.bg, palette.accent, 0.8),
btnDangerBg: mixHex(palette.bg, palette.accent, 0.22),
chipBg: mixHex(palette.bg, palette.accent, 0.28),
chipText: palette.text,
accentDivider: hexToRgba(palette.accent, 0.6, "rgba(91, 210, 255, 0.6)"),
switchOnBg: mixHex(palette.bg, palette.btn, 0.58),
switchOffBg: mixHex(palette.bg, palette.text, 0.24),
switchKnob: mixHex(palette.text, "#ffffff", 0.45),
iconBtnBg: mixHex(palette.bg, palette.btn, 0.14),
iconBtnBgStrong: mixHex(palette.bg, palette.btn, 0.24),
accentBg: mixHex(palette.bg, palette.accent, 0.18),
accentBgStrong: mixHex(palette.bg, palette.accent, 0.32),
accentBorder: mixHex(palette.bg, palette.accent, 0.72),
accentRing: hexToRgba(palette.accent, 0.22, "rgba(91, 210, 255, 0.22)"),
accentShadow: hexToRgba(palette.accent, 0.28, "rgba(91, 210, 255, 0.28)"),
shellBtnBg: mixHex(palette.shellBg, palette.shellAccent, 0.42),
shellBtnText: mixHex(palette.shellText, palette.shellAccent, 0.5),
shellAccentBg: mixHex(palette.shellBg, palette.shellAccent, 0.18),
shellAccentBgStrong: mixHex(palette.shellBg, palette.shellAccent, 0.32),
shellAccentBorder: mixHex(palette.shellBg, palette.shellAccent, 0.74),
shellAccentRing: hexToRgba(palette.shellAccent, 0.24, "rgba(156, 169, 191, 0.24)"),
shellAccentShadow: hexToRgba(palette.shellAccent, 0.3, "rgba(156, 169, 191, 0.3)"),
terminalTouchToolsBg: hexToRgba(palette.shellBg, 0.8, "rgba(25, 43, 77, 0.8)")
};
}
/**
* 主界面卡片与 about 卡片共用同一套表面 token
* 1. 浅色模式下边框直接从当前 text 推导,避免继续沿用深色基线;
* 2. 面板底色保持轻微前景混合,保证和页面背景拉开层次;
* 3. 阴影也跟随当前强调色派生,后续其他页面可直接复用。
*/
function resolveSurfaceTokens(palette) {
return {
surface: mixHex(palette.bg, palette.text, 0.05),
surfaceBorder: hexToRgba(palette.text, 0.18, "rgba(230, 240, 255, 0.18)"),
surfaceShadow: hexToRgba(palette.accent, 0.18, "rgba(91, 210, 255, 0.18)")
};
}
/**
* About 页面虽然布局更自由,但配色仍应跟随“界面配置”:
* 1. 面板底色从 bg/text 混合得到,避免再写死一套米白主题;
* 2. 强调色继续复用当前 UI accent保证切换主题后 about 也同步变;
* 3. 背景光斑只作为氛围层,仍从当前主题色推导,不脱离主界面。
*/
function resolveAboutTokens(palette, buttonTokens, surfaceTokens) {
return {
bg: palette.bg,
surface: surfaceTokens.surface,
surfaceBorder: surfaceTokens.surfaceBorder,
glow: surfaceTokens.surfaceShadow,
textStrong: palette.text,
text: mixHex(palette.bg, palette.text, 0.84),
textMuted: mixHex(palette.bg, palette.text, 0.62),
accent: palette.accent,
accentSoft: hexToRgba(palette.accent, 0.22, "rgba(91, 210, 255, 0.22)"),
accentLine: hexToRgba(palette.accent, 0.42, "rgba(91, 210, 255, 0.42)"),
actionBg: buttonTokens.btnBgStrong,
actionText: buttonTokens.btnText,
actionBorder: buttonTokens.btnBorderStrong,
orbLeftStart: palette.accent,
orbLeftEnd: mixHex(palette.accent, palette.bg, 0.56),
orbRightStart: mixHex(palette.btn, palette.bg, 0.34),
orbRightEnd: mixHex(palette.text, palette.bg, 0.16)
};
}
function buildThemeStyle(settings) {
const palette = resolveRuntimeTheme(settings);
const buttonTokens = resolveButtonTokens(palette);
const surfaceTokens = resolveSurfaceTokens(palette);
const aboutTokens = resolveAboutTokens(palette, buttonTokens, surfaceTokens);
const muted = mixHex(palette.bg, palette.text, 0.58);
return [
`--bg:${palette.bg}`,
`--text:${palette.text}`,
`--accent:${palette.accent}`,
`--btn:${palette.btn}`,
`--muted:${muted}`,
`--surface:${surfaceTokens.surface}`,
`--surface-border:${surfaceTokens.surfaceBorder}`,
`--surface-shadow:${surfaceTokens.surfaceShadow}`,
`--shell-bg:${palette.shellBg}`,
`--shell-text:${palette.shellText}`,
`--shell-accent:${palette.shellAccent}`,
`--shell-font-family:${palette.shellFontFamily}`,
`--shell-font-size:${palette.shellFontSize}px`,
`--shell-line-height:${palette.shellLineHeight}`,
`--btn-border:${buttonTokens.btnBorder}`,
`--btn-border-strong:${buttonTokens.btnBorderStrong}`,
`--btn-bg:${buttonTokens.btnBg}`,
`--btn-bg-strong:${buttonTokens.btnBgStrong}`,
`--btn-bg-active:${buttonTokens.btnBgActive}`,
`--btn-text:${buttonTokens.btnText}`,
`--btn-danger-border:${buttonTokens.btnDangerBorder}`,
`--btn-danger-bg:${buttonTokens.btnDangerBg}`,
`--chip-bg:${buttonTokens.chipBg}`,
`--chip-text:${buttonTokens.chipText}`,
`--accent-divider:${buttonTokens.accentDivider}`,
`--switch-on-bg:${buttonTokens.switchOnBg}`,
`--switch-off-bg:${buttonTokens.switchOffBg}`,
`--switch-knob:${buttonTokens.switchKnob}`,
`--icon-btn-bg:${buttonTokens.iconBtnBg}`,
`--icon-btn-bg-strong:${buttonTokens.iconBtnBgStrong}`,
`--accent-bg:${buttonTokens.accentBg}`,
`--accent-bg-strong:${buttonTokens.accentBgStrong}`,
`--accent-border:${buttonTokens.accentBorder}`,
`--accent-ring:${buttonTokens.accentRing}`,
`--accent-shadow:${buttonTokens.accentShadow}`,
`--about-bg:${aboutTokens.bg}`,
`--about-surface:${aboutTokens.surface}`,
`--about-surface-border:${aboutTokens.surfaceBorder}`,
`--about-glow:${aboutTokens.glow}`,
`--about-text-strong:${aboutTokens.textStrong}`,
`--about-text:${aboutTokens.text}`,
`--about-text-muted:${aboutTokens.textMuted}`,
`--about-accent:${aboutTokens.accent}`,
`--about-accent-soft:${aboutTokens.accentSoft}`,
`--about-accent-line:${aboutTokens.accentLine}`,
`--about-action-bg:${aboutTokens.actionBg}`,
`--about-action-text:${aboutTokens.actionText}`,
`--about-action-border:${aboutTokens.actionBorder}`,
`--about-orb-left-start:${aboutTokens.orbLeftStart}`,
`--about-orb-left-end:${aboutTokens.orbLeftEnd}`,
`--about-orb-right-start:${aboutTokens.orbRightStart}`,
`--about-orb-right-end:${aboutTokens.orbRightEnd}`,
`--shell-btn-bg:${buttonTokens.shellBtnBg}`,
`--shell-btn-text:${buttonTokens.shellBtnText}`,
`--shell-accent-bg:${buttonTokens.shellAccentBg}`,
`--shell-accent-bg-strong:${buttonTokens.shellAccentBgStrong}`,
`--shell-accent-border:${buttonTokens.shellAccentBorder}`,
`--shell-accent-ring:${buttonTokens.shellAccentRing}`,
`--shell-accent-shadow:${buttonTokens.shellAccentShadow}`,
`--terminal-touch-tools-bg:${buttonTokens.terminalTouchToolsBg}`
].join(";");
}
module.exports = {
buildThemeStyle,
applyUiThemeSelection,
applyShellThemeSelection,
pickBtnColor,
pickShellAccentColor,
resolveNavigationBarTheme,
applyNavigationBarTheme,
DEFAULT_NAVIGATION_BAR_THEME,
DEFAULT_SHELL_FONT_FAMILY,
TERMINAL_SAFE_FONT_OPTIONS,
normalizeTerminalFontFamily
};