This repository has been archived on 2026-04-03. You can view files and clone it. You cannot open issues or pull requests or push a commit.
Files
core/server/pages/templates/base.html
Jeffrey Smith 6fff84f40a Feat v0.6.14 visual polish
Fix v0.6.13 spacing regressions with half-step tokens (--sp-1h 6px,
--sp-2h 10px). Purge ~65 stale hex/rgba fallback values from var() calls
including all old gold #b38a4e references. Self-host DM Sans and JetBrains
Mono woff2 fonts, eliminating Google Fonts CDN dependency. Standardize
border-radius to three tokens (--radius-sm 4px, --radius 8px, --radius-lg
12px) across all kernel CSS and 12 extension packages.

Also fixes: theme settings showing resolved mode instead of stored preference,
surface-inner overflow causing notes scrollbar and chat input clipping at
high zoom, user menu drift at scale >100% from zoom-unaware fixed positioning,
and three undefined CSS variable references.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-01 12:59:06 +00:00

161 lines
8.7 KiB
HTML

{{define "base.html"}}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, viewport-fit=cover, interactive-widget=resizes-content">
<title>{{block "title" .}}Armature{{end}}</title>
<link rel="icon" type="image/svg+xml" href="{{.BasePath}}/favicon.svg?v={{.Version}}">
<link rel="icon" type="image/x-icon" href="{{.BasePath}}/favicon.ico?v={{.Version}}">
{{/* Decomposed from monolithic styles.css (v0.22.9) */}}
<link rel="stylesheet" href="{{.BasePath}}/css/variables.css?v={{.Version}}">
<link rel="stylesheet" href="{{.BasePath}}/css/layout.css?v={{.Version}}">
<link rel="stylesheet" href="{{.BasePath}}/css/primitives.css?v={{.Version}}">
<link rel="stylesheet" href="{{.BasePath}}/css/modals.css?v={{.Version}}">
<link rel="stylesheet" href="{{.BasePath}}/css/surfaces.css?v={{.Version}}">
<link rel="stylesheet" href="{{.BasePath}}/css/sw-primitives.css?v={{.Version}}">
<link rel="stylesheet" href="{{.BasePath}}/css/user-menu.css?v={{.Version}}">
<link rel="stylesheet" href="{{.BasePath}}/css/tool-grants.css?v={{.Version}}">
<link rel="stylesheet" href="{{.BasePath}}/css/workflow.css?v={{.Version}}">
<link rel="stylesheet" href="{{.BasePath}}/css/admin-surfaces.css?v={{.Version}}">
<link rel="stylesheet" href="{{.BasePath}}/css/extension-surface.css?v={{.Version}}">
<link rel="stylesheet" href="{{.BasePath}}/css/sw-shell.css?v={{.Version}}">
<link rel="stylesheet" href="{{.BasePath}}/css/sw-debug.css?v={{.Version}}">
{{/* css-chat, css-notes, css-projects templates removed — surfaces provide their own styles */}}
{{/* v0.27.0: Extension surface CSS — loaded from /surfaces/{id}/css/main.css */}}
{{if and .Manifest (eq .Manifest.Source "extension")}}
<link rel="stylesheet" href="{{.BasePath}}/surfaces/{{.Surface}}/css/main.css?v={{.Version}}">
{{end}}
<style>
body { margin: 0; background: var(--bg); color: var(--text); display: flex; flex-direction: column; height: 100vh; height: 100dvh; overflow: hidden; padding: env(safe-area-inset-top, 0) env(safe-area-inset-right, 0) env(safe-area-inset-bottom, 0) env(safe-area-inset-left, 0); }
.surface { flex: 1; min-height: 0; overflow: hidden; }
.surface-inner { width: 100%; height: 100%; overflow: hidden; }
.banner { flex-shrink: 0; }
</style>
<meta name="theme-color" content="#0e0e10" id="metaThemeColor">
<script>
// Early theme application — prevents flash of wrong theme on all surfaces.
// Read from Theme API key (armature_theme) as authoritative source.
(function() {
try {
var mode = localStorage.getItem('armature_theme') || 'system';
var resolved = mode;
if (mode === 'system') resolved = window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light';
document.documentElement.setAttribute('data-theme', resolved);
var meta = document.getElementById('metaThemeColor');
if (meta) meta.content = resolved === 'light' ? '#f7f7fa' : '#0e0e10';
var fav = document.querySelector('link[rel="icon"][type="image/svg+xml"]');
if (fav) fav.href = fav.href.replace(/favicon(-light)?\.svg/, resolved === 'light' ? 'favicon-light.svg' : 'favicon.svg');
} catch(e) {}
})();
// Early appearance — apply scale from localStorage on all surfaces.
// CSS zoom reflows layout correctly (no getBoundingClientRect hacks needed).
(function() {
try {
var p = JSON.parse(localStorage.getItem('sb-appearance') || '{}');
if (p.scale && p.scale !== 100) {
var s = p.scale / 100;
document.addEventListener('DOMContentLoaded', function() {
var el = document.getElementById('surfaceInner');
if (el) { el.style.zoom = s; }
});
}
} catch(e) {}
})();
</script>
</head>
<body data-surface="{{.Surface}}" data-base-path="{{.BasePath}}">
{{if .Banner.Visible}}
<div class="banner banner-top active" style="background:{{.Banner.Background}};color:{{.Banner.Color}};padding:6px 12px;text-align:center;font-size:12px;font-weight:600;line-height:1.3;">
{{.Banner.Text}}
</div>
<script>
(function(){ var b=document.querySelector('.banner-top.active'); if(b) document.documentElement.style.setProperty('--banner-top-height',b.offsetHeight+'px'); })();
</script>
{{end}}
{{if .Message.Visible}}
<div class="sw-shell__announcement" id="shellMessage">
<div class="sw-shell__announcement-inner sw-shell__announcement--{{.Message.Variant}}">
<span class="sw-shell__announcement-text">{{.Message.Text}}</span>
<button class="sw-shell__banner-close" onclick="this.closest('.sw-shell__announcement').remove()" aria-label="Dismiss">&times;</button>
</div>
</div>
{{end}}
<div class="surface" id="surface">
<div class="surface-inner" id="surfaceInner">
{{if eq .Surface "admin"}}{{template "surface-admin" .}}
{{else if eq .Surface "team-admin"}}{{template "surface-team-admin" .}}
{{else if eq .Surface "settings"}}{{template "surface-settings" .}}
{{else if eq .Surface "welcome"}}{{template "surface-welcome" .}}
{{else if eq .Surface "docs"}}{{template "surface-docs" .}}
{{else if and .Manifest (eq .Manifest.Source "extension")}}{{template "surface-extension" .}}
{{else}}<div style="padding:20px">Unknown surface: {{.Surface}}</div>
{{end}}
</div>
</div>
{{if .Footer.Visible}}
<div class="sw-shell__footer">{{.Footer.Text}}</div>
{{end}}
{{if .Banner.Visible}}
<div class="banner banner-bottom active" style="background:{{.Banner.Background}};color:{{.Banner.Color}};padding:6px 12px;text-align:center;font-size:12px;font-weight:600;line-height:1.3;">
{{.Banner.Text}}
</div>
<script>
(function(){ var b=document.querySelector('.banner-bottom.active'); if(b) document.documentElement.style.setProperty('--banner-bottom-height',b.offsetHeight+'px'); })();
</script>
{{end}}
<script nonce="{{.CSPNonce}}">
window.__BASE__ = '{{.BasePath}}';
window.__VERSION__ = '{{.Version}}';
window.__ENV__ = '{{.Environment}}';
window.__BRANDING__ = {};
window.__SURFACE__ = '{{.Surface}}';
{{/* __PAGE_DATA__ and __USER__ removed in v0.37.19 — SDK boot
populates sw.auth.user and sw.auth.policies from API. */}}
{{if .Manifest}}window.__MANIFEST__ = {{.Manifest | toJSON}};{{end}}
</script>
{{/* All surfaces use Preact SDK boot(). Legacy script includes removed.
Standalone utils: debug.js, repl.js (no SDK dependencies). */}}
{{if eq .Surface "admin"}}{{template "scripts-admin" .}}{{end}}
{{if eq .Surface "team-admin"}}{{template "scripts-team-admin" .}}{{end}}
{{if eq .Surface "settings"}}{{template "scripts-settings" .}}{{end}}
{{if eq .Surface "welcome"}}{{template "scripts-welcome" .}}{{end}}
{{if eq .Surface "docs"}}{{template "scripts-docs" .}}{{end}}
{{/* v0.27.0: Extension surface JS — load Preact globals, boot SDK, then extension */}}
{{if and .Manifest (eq .Manifest.Source "extension")}}
<script type="module" nonce="{{.CSPNonce}}">
const { h, render } = await import('{{.BasePath}}/js/sw/vendor/preact.module.js');
const hooksModule = await import('{{.BasePath}}/js/sw/vendor/hooks.module.js');
const { default: htm } = await import('{{.BasePath}}/js/sw/vendor/htm.module.js');
window.preact = window.preact || { h, render };
window.hooks = window.hooks || hooksModule;
window.html = window.html || htm.bind(h);
const { boot } = await import('{{.BasePath}}/js/sw/sdk/index.js?v={{.Version}}');
await boot();
await import('{{.BasePath}}/surfaces/{{.Surface}}/js/main.js?v={{.Version}}');
</script>
{{end}}
{{/* v0.6.5: Browser-tier extension scripts (renderers, etc.)
Loaded after surface scripts so sw:ready fires first. */}}
{{range .BrowserExtensions}}
<script nonce="{{$.CSPNonce}}" src="{{$.BasePath}}/surfaces/{{.}}/js/script.js?v={{$.Version}}"></script>
{{end}}
{{/* v0.37.13: Legacy UserMenu hydration removed — all surfaces use Preact UserMenu. */}}
{{/* ── Debug Modal (Preact, v0.37.18) ───── */}}
<div id="debugMount"></div>
<script type="module" nonce="{{.CSPNonce}}" src="{{.BasePath}}/js/debug.js?v={{.Version}}"></script>
</body>
</html>
{{end}}