feat: add Nous Research skin

Adds a cold steel-blue/monospace skin inspired by nousresearch.com:
- Steel-blue accent (#4682B4) replacing warm gold
- Monospace typography (SF Mono, Roboto Mono, Courier New)
- Sharp corners, technical dashed borders
- Dark navy palette (#0A0E14) for dark mode

Files changed:
- static/style.css — Nous skin CSS variables and component overrides
- static/boot.js — Nous skin entry in _SKINS array
- static/index.html — nous in inline skin validation list
- api/config.py — nous + sienna in server-side _SETTINGS_SKIN_VALUES
This commit is contained in:
linuxid10t
2026-05-15 00:28:34 -05:00
parent 5e518b1c10
commit b2d4f13c5b
4 changed files with 80 additions and 1 deletions
+2
View File
@@ -3960,6 +3960,8 @@ _SETTINGS_SKIN_VALUES = {
"poseidon",
"sisyphus",
"charizard",
"sienna",
"nous",
}
_SETTINGS_LEGACY_THEME_MAP = {
# Legacy full themes now map onto the closest supported theme + accent skin pair.
+1
View File
@@ -1168,6 +1168,7 @@ const _SKINS=[
{name:'Sisyphus', colors:['#A78BFA','#8B5CF6','#7C3AED']},
{name:'Charizard',colors:['#FB923C','#F97316','#EA580C']},
{name:'Sienna', colors:['#D97757','#C06A49','#9A523A']},
{name:'Nous', colors:['#4682B4','#3A6E9A','#2C5F88']},
];
const _VALID_THEMES=new Set((_THEMES||[]).map(t=>t.value));
const _VALID_SKINS=new Set((_SKINS||[]).map(s=>s.name.toLowerCase()));
+1 -1
View File
@@ -17,7 +17,7 @@
<meta name="apple-mobile-web-app-status-bar-style" content="default">
<meta name="apple-mobile-web-app-title" content="Hermes">
<link rel="apple-touch-icon" sizes="512x512" href="static/apple-touch-icon.png">
<script>(function(){var themes={light:1,dark:1,system:1},skins={default:1,ares:1,mono:1,slate:1,poseidon:1,sisyphus:1,charizard:1,sienna:1},legacy={slate:['dark','slate'],solarized:['dark','poseidon'],monokai:['dark','sisyphus'],nord:['dark','slate'],oled:['dark','default']},t=(localStorage.getItem('hermes-theme')||'dark').toLowerCase(),s=(localStorage.getItem('hermes-skin')||'').toLowerCase(),m=legacy[t],theme=m?m[0]:(themes[t]?t:'dark'),skin=skins[s]?s:(m?m[1]:'default');localStorage.setItem('hermes-theme',theme);localStorage.setItem('hermes-skin',skin);if(theme==='system')theme=window.matchMedia('(prefers-color-scheme:dark)').matches?'dark':'light';if(theme==='dark')document.documentElement.classList.add('dark');if(skin!=='default')document.documentElement.dataset.skin=skin;})()</script>
<script>(function(){var themes={light:1,dark:1,system:1},skins={default:1,ares:1,mono:1,slate:1,poseidon:1,sisyphus:1,charizard:1,sienna:1,nous:1},legacy={slate:['dark','slate'],solarized:['dark','poseidon'],monokai:['dark','sisyphus'],nord:['dark','slate'],oled:['dark','default']},t=(localStorage.getItem('hermes-theme')||'dark').toLowerCase(),s=(localStorage.getItem('hermes-skin')||'').toLowerCase(),m=legacy[t],theme=m?m[0]:(themes[t]?t:'dark'),skin=skins[s]?s:(m?m[1]:'default');localStorage.setItem('hermes-theme',theme);localStorage.setItem('hermes-skin',skin);if(theme==='system')theme=window.matchMedia('(prefers-color-scheme:dark)').matches?'dark':'light';if(theme==='dark')document.documentElement.classList.add('dark');if(skin!=='default')document.documentElement.dataset.skin=skin;})()</script>
<script>(function(){var fs=localStorage.getItem('hermes-font-size');if(fs&&fs!=='default')document.documentElement.dataset.fontSize=fs;})()</script>
<!-- theme-color: surfaces the active app chrome color to native status bars (Safari status bar, PWA, native WKWebView wrappers). Updated dynamically by boot.js when theme/skin changes. The light/dark default values match style.css :root --sidebar / :root.dark --sidebar. -->
<meta name="theme-color" content="#FAF7F0" media="(prefers-color-scheme: light)">
+76
View File
@@ -175,6 +175,82 @@
:root[data-skin="sienna"] .session-item.active{border-left:2px solid var(--accent);}
:root[data-skin="sienna"] .composer-box{border-radius:18px;}
/* Skin: Nous Research (steel blue, monospace, sharp corners, deep navy dark)
Full palette rewrite inspired by the Nous Research visual identity.
Monochromatic steel blue accent, monospace typography, near-sharp corners,
dashed borders on structural elements, and deep navy dark mode.
Opt-in via Settings Skin picker. */
:root[data-skin="nous"]{
--bg:#FFFFFF;--sidebar:#F5F5F5;--border:#D0D8E0;--border2:rgba(0,0,0,0.15);
--text:#1A2A3A;--muted:#6B7B8B;--accent:#4682B4;--blue:#4682B4;--gold:#4682B4;--code-bg:#F0F2F5;
--surface:#FFFFFF;--topbar-bg:rgba(255,255,255,.98);--main-bg:rgba(255,255,255,0.5);
--focus-ring:rgba(70,130,180,.3);--focus-glow:rgba(70,130,180,.08);
--input-bg:rgba(0,0,0,.03);--hover-bg:rgba(0,0,0,.05);
--strong:#0A1A2A;--em:#5C5344;--code-text:#2C5F88;--code-inline-bg:rgba(70,130,180,.08);--pre-text:#1A2A3A;
--accent-hover:#3A6E9A;--accent-bg:rgba(70,130,180,0.06);--accent-bg-strong:rgba(70,130,180,0.12);--accent-text:#2C5F88;
--error:#C62828;--success:#3D8B40;--warning:#E68A00;--info:#4682B4;
--radius-sm:1px;--radius-md:2px;--radius-card:2px;--radius-lg:4px;
--font-ui:"SF Mono","Roboto Mono","Courier New",monospace;
--surface-subtle:rgba(0,0,0,.025);--surface-subtle-hover:rgba(0,0,0,.045);
--border-subtle:rgba(0,0,0,.08);--border-muted:rgba(0,0,0,.12);
font-family:var(--font-ui);font-size:14.5px;line-height:1.7;
}
:root.dark[data-skin="nous"]{
--bg:#0A0E14;--sidebar:#0F1419;--border:#1E2A3A;--border2:rgba(255,255,255,0.14);
--text:#C8D6E5;--muted:#5A6A7A;--accent:#4682B4;--blue:#4682B4;--gold:#4682B4;--code-bg:#111820;
--surface:#111820;--topbar-bg:rgba(10,14,20,.98);--main-bg:rgba(10,14,20,0.5);
--focus-ring:rgba(70,130,180,.3);--focus-glow:rgba(70,130,180,.08);
--input-bg:rgba(255,255,255,.04);--hover-bg:rgba(255,255,255,.06);
--strong:#E2E8F0;--em:#5A6A7A;--code-text:#7EB6E0;--code-inline-bg:rgba(70,130,180,.12);--pre-text:#C8D6E5;
--accent-hover:#5A9AD0;--accent-bg:rgba(70,130,180,0.1);--accent-bg-strong:rgba(70,130,180,0.2);--accent-text:#7EB6E0;
--error:#EF5350;--success:#4CAF50;--warning:#FFA726;--info:#4682B4;
--surface-subtle:rgba(255,255,255,.025);--surface-subtle-hover:rgba(255,255,255,.045);
--border-subtle:rgba(255,255,255,.075);--border-muted:rgba(255,255,255,.12);
}
/* ── Nous skin: component-level overrides ── */
/* Topbar: dashed border */
:root[data-skin="nous"] .topbar{border-bottom-style:dashed;}
:root.dark[data-skin="nous"] .topbar{border-bottom-style:dashed;}
/* Sidebar: dashed border */
:root[data-skin="nous"] .sidebar{border-right-style:dashed;}
:root.dark[data-skin="nous"] .sidebar{border-right-style:dashed;}
/* Scrollbar: steel blue */
:root[data-skin="nous"]::-webkit-scrollbar-thumb{background:rgba(70,130,180,.25);border-radius:3px;}
:root[data-skin="nous"]::-webkit-scrollbar-thumb:hover{background:rgba(70,130,180,.4);}
:root[data-skin="nous"]{scrollbar-width:thin;scrollbar-color:rgba(70,130,180,.25) transparent;}
:root.dark[data-skin="nous"]::-webkit-scrollbar-thumb{background:rgba(70,130,180,.25);border-radius:3px;}
:root.dark[data-skin="nous"]::-webkit-scrollbar-thumb:hover{background:rgba(70,130,180,.4);}
:root.dark[data-skin="nous"]{scrollbar-width:thin;scrollbar-color:rgba(70,130,180,.25) transparent;}
/* Tree viewer: blue family */
:root[data-skin="nous"] .tree-key{color:#4682B4;}
:root[data-skin="nous"] .tree-str{color:#7EB6E0;}
:root[data-skin="nous"] .tree-num{color:#4682B4;}
:root[data-skin="nous"] .tree-bool{color:#4682B4;}
:root.dark[data-skin="nous"] .tree-key{color:#4682B4;}
:root.dark[data-skin="nous"] .tree-str{color:#7EB6E0;}
:root.dark[data-skin="nous"] .tree-num{color:#4682B4;}
:root.dark[data-skin="nous"] .tree-bool{color:#4682B4;}
/* Session badges/tags */
:root[data-skin="nous"] .session-child-count{background:rgba(99,179,237,.16);color:#4682B4;}
:root[data-skin="nous"] .session-child-count:hover{background:rgba(99,179,237,.26);color:#7EB6E0;}
:root[data-skin="nous"] .session-tree-badge{background:rgba(99,179,237,.2);color:#4682B4;}
:root[data-skin="nous"] .session-tag{background:rgba(99,179,237,.2);color:#4682B4;}
:root.dark[data-skin="nous"] .session-child-count{background:rgba(99,179,237,.16);color:#4682B4;}
:root.dark[data-skin="nous"] .session-child-count:hover{background:rgba(99,179,237,.26);color:#7EB6E0;}
:root.dark[data-skin="nous"] .session-tree-badge{background:rgba(99,179,237,.2);color:#4682B4;}
:root.dark[data-skin="nous"] .session-tag{background:rgba(99,179,237,.2);color:#4682B4;}
/* Image lightbox close */
:root[data-skin="nous"] .img-lightbox-close:hover{background:rgba(70,130,180,.4);}
:root.dark[data-skin="nous"] .img-lightbox-close:hover{background:rgba(70,130,180,.4);}
/* Diff blocks */
:root[data-skin="nous"] .diff-block .diff-plus{color:#4682B4;}
:root.dark[data-skin="nous"] .diff-block .diff-plus{color:#7EB6E0;}
/* MCP status */
:root[data-skin="nous"] .mcp-http{color:#4682B4;}
:root[data-skin="nous"] .mcp-status-active{color:#4682B4;}
:root.dark[data-skin="nous"] .mcp-http{color:#7EB6E0;}
:root.dark[data-skin="nous"] .mcp-status-active{color:#7EB6E0;}
/* #594: app-dialog light mode overrides — base styles use hardcoded dark gradients */
:root:not(.dark) .app-dialog{
background:linear-gradient(180deg,rgba(240,237,232,.99),rgba(228,224,216,.99));