Files
Oxicloud/frontend/src/app.html
T

82 lines
2.6 KiB
HTML
Raw Normal View History

2026-06-17 17:06:30 -06:00
<!doctype html>
<html lang="en" data-color-scheme>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<link rel="icon" href="%sveltekit.assets%/favicon.ico" />
<meta name="color-scheme" content="light dark" />
%sveltekit.head%
2026-06-17 17:06:30 -06:00
<!--
Anti-FOUC theme init — runs synchronously before first paint.
Ported from static/js/core/theme-init.js. Keeps the legacy
`oxicloud_theme` localStorage key and `data-color-scheme` attribute
so existing users keep their preference across the migration.
Placed AFTER %sveltekit.head% so it follows the CSP <meta> SvelteKit
injects there, hence it IS governed by that policy. svelte.config.js
parses this file, finds this <script> by id="theme-init", and adds its
SHA-256 to script-src automatically — so it's allowed inline (zero extra
request, no 'unsafe-inline') and the hash stays in sync if you edit it.
2026-06-17 17:06:30 -06:00
-->
<script id="theme-init">
2026-06-17 17:06:30 -06:00
(function () {
try {
var s = localStorage.getItem('oxicloud_theme');
var h = document.documentElement;
if (s === 'light' || s === 'dark') h.setAttribute('data-color-scheme', s);
else h.removeAttribute('data-color-scheme');
} catch (e) {
/* localStorage unavailable — fall back to OS preference */
}
})();
</script>
<!--
Instant boot splash. Paints on HTML parse (before the app bundle and its
CSS load), covering the otherwise-blank gap during JS download/parse for a
faster perceived first paint. The root layout removes `#app-splash` as soon
as it mounts. `light-dark()` + the early `color-scheme` rules match the
resolved theme so there's no colour flash when the app CSS arrives.
-->
<style>
html[data-color-scheme='dark'] {
color-scheme: dark;
}
html[data-color-scheme='light'] {
color-scheme: light;
}
#app-splash {
position: fixed;
inset: 0;
z-index: 9999;
display: grid;
place-items: center;
background: light-dark(#f5f7fa, #0f172a);
}
#app-splash__spinner {
width: 38px;
height: 38px;
border-radius: 50%;
border: 3px solid light-dark(#e2e8f0, #334155);
border-top-color: #ff5e3a;
animation: app-splash-spin 0.7s linear infinite;
}
@keyframes app-splash-spin {
to {
transform: rotate(360deg);
}
}
@media (prefers-reduced-motion: reduce) {
#app-splash__spinner {
animation: none;
}
}
</style>
2026-06-17 17:06:30 -06:00
</head>
<body data-sveltekit-preload-data="hover">
<div id="app-splash" role="status" aria-label="Loading">
<div id="app-splash__spinner"></div>
</div>
2026-06-17 17:06:30 -06:00
<div style="display: contents">%sveltekit.body%</div>
</body>
</html>