+
- {T.passwordTitle}
+ {T.passwordTitle}
setPassword(e.target.value)}
onKeyDown={(e) => e.key === "Enter" && password && unlock()}
placeholder={T.passwordPlaceholder}
- className="w-full rounded-lg bg-slate-800 border border-slate-700 px-3 py-2 text-sm outline-none focus:ring-2 focus:ring-teal-500/40"
+ className="w-full rounded-lg bg-surface border border-border px-3 py-2 text-sm outline-none focus:ring-2 focus:ring-accent/40"
/>
{error &&
{error}
}
{T.watch}
@@ -171,7 +171,7 @@ export default function WatchPage() {
{/* Shrink-wrap the player to the video so a vertical/short clip renders as a narrow
player instead of a wide box with black bars; a landscape clip fills the width. */}
-
+
{meta.uploader}
) : (
- {meta.uploader}
+ {meta.uploader}
))}
{meta.allow_download && (
{T.download}
@@ -217,7 +217,7 @@ export default function WatchPage() {
target="_blank"
rel="noopener noreferrer"
title={url}
- className="inline-flex items-center gap-1.5 text-sm text-slate-400 hover:text-teal-400 hover:underline min-w-0"
+ className="inline-flex items-center gap-1.5 text-sm text-muted hover:text-accent hover:underline min-w-0"
>
{displayUrl(url)}
@@ -228,7 +228,7 @@ export default function WatchPage() {
)}
-
{T.brand}
+
{T.brand}
);
}
diff --git a/frontend/src/main.tsx b/frontend/src/main.tsx
index 6bd188b..869717b 100644
--- a/frontend/src/main.tsx
+++ b/frontend/src/main.tsx
@@ -20,6 +20,13 @@ const queryClient = new QueryClient({
defaultOptions: { queries: { retry: false, staleTime: 30_000, refetchOnWindowFocus: false } },
});
+// Baseline theme so the token CSS vars (--bg/--surface/--accent/…) resolve on first paint — including
+// the standalone public pages (/watch, /privacy, /terms) that render outside
and never call
+// applyTheme. The app overrides this with the user's saved theme once it mounts.
+const de = document.documentElement.dataset;
+de.theme ||= "dark";
+de.scheme ||= "midnight";
+
const path = window.location.pathname;
const root =
path === "/privacy" ? :