mirror of
https://github.com/PR0M3TH3AN/bitvid.git
synced 2026-10-27 07:52:24 +00:00
Add light theme overrides and documentation
This commit is contained in:
1 parent
317463619c
commit
b20895ec32
4 files changed
+110
-8
No files matched your search
@@ -38,7 +38,7 @@
|
||||
}
|
||||
|
||||
.btn-ghost {
|
||||
@apply btn border border-border border-opacity-60 bg-transparent text-white shadow-none;
|
||||
@apply btn border border-border border-opacity-60 bg-transparent text-text shadow-none;
|
||||
}
|
||||
|
||||
.btn-ghost:hover {
|
||||
@@ -280,7 +280,7 @@
|
||||
}
|
||||
|
||||
.bv-modal__panel {
|
||||
@apply focus-ring relative z-[var(--z-modal-content)] w-full max-w-3xl rounded-xl border border-border border-opacity-40 bg-surface px-6 py-8 text-left text-white shadow-modal transition duration-base ease-out;
|
||||
@apply focus-ring relative z-[var(--z-modal-content)] w-full max-w-3xl rounded-xl border border-border border-opacity-40 bg-surface px-6 py-8 text-left text-text shadow-modal transition duration-base ease-out;
|
||||
}
|
||||
|
||||
.bv-modal__panel:focus-visible {
|
||||
@@ -556,7 +556,7 @@
|
||||
}
|
||||
|
||||
.profile-switcher__add {
|
||||
@apply card hover:bg-info/10 flex cursor-pointer items-center gap-4 border border-dashed border-border border-opacity-40 bg-surface text-left text-muted transition duration-base ease-out hover:border-info hover:border-opacity-60 hover:text-white focus-visible:border-info focus-visible:border-opacity-60;
|
||||
@apply card hover:bg-info/10 flex cursor-pointer items-center gap-4 border border-dashed border-border border-opacity-40 bg-surface text-left text-muted transition duration-base ease-out hover:border-info hover:border-opacity-60 hover:text-text focus-visible:border-info focus-visible:border-opacity-60;
|
||||
}
|
||||
|
||||
.profile-switcher__addAvatar {
|
||||
@@ -600,7 +600,7 @@
|
||||
}
|
||||
|
||||
.watch-history-card__thumbnail {
|
||||
@apply block flex-none text-white no-underline sm:w-56;
|
||||
@apply block flex-none text-text no-underline sm:w-56;
|
||||
}
|
||||
|
||||
.watch-history-card__thumbnailInner {
|
||||
@@ -616,7 +616,7 @@
|
||||
}
|
||||
|
||||
.watch-history-card__title {
|
||||
@apply cursor-pointer text-lg font-semibold leading-snug text-white transition duration-base ease-out;
|
||||
@apply cursor-pointer text-lg font-semibold leading-snug text-text transition duration-base ease-out;
|
||||
display: -webkit-box;
|
||||
-webkit-line-clamp: 2;
|
||||
-webkit-box-orient: vertical;
|
||||
@@ -661,7 +661,7 @@
|
||||
}
|
||||
|
||||
.watch-history-card__action {
|
||||
@apply inline-flex items-center justify-center gap-2 rounded-full border border-transparent bg-panel px-4 py-2 text-sm font-medium text-muted transition duration-base ease-out hover:border-border hover:bg-surface-alt hover:text-white focus-visible:border-border focus-visible:bg-surface-alt focus-visible:text-white;
|
||||
@apply inline-flex items-center justify-center gap-2 rounded-full border border-transparent bg-panel px-4 py-2 text-sm font-medium text-muted transition duration-base ease-out hover:border-border hover:bg-surface-alt hover:text-text focus-visible:border-border focus-visible:bg-surface-alt focus-visible:text-text;
|
||||
}
|
||||
|
||||
.watch-history-card__action--primary {
|
||||
|
||||
@@ -170,3 +170,44 @@
|
||||
--motion-ease-in-out: cubic-bezier(0.4, 0, 0.2, 1);
|
||||
--modal-motion-duration: var(--motion-duration-base);
|
||||
}
|
||||
|
||||
[data-theme="light"] {
|
||||
/* Light theme overrides */
|
||||
--color-surface: rgb(248 250 252);
|
||||
--color-surface-alt: rgb(241 245 249);
|
||||
--color-bg: var(--color-surface);
|
||||
--color-card: rgb(255 255 255);
|
||||
--color-card-private: rgb(244 236 255);
|
||||
--color-card-critical: rgb(255 228 230);
|
||||
--color-panel: rgb(255 255 255);
|
||||
--color-panel-hover: rgb(226 232 240);
|
||||
--color-border: rgb(148 163 184);
|
||||
--color-border-subtle: rgb(203 213 225);
|
||||
--color-primary: rgb(220 38 38);
|
||||
--color-text: rgb(15 23 42);
|
||||
--color-text-strong: rgb(15 23 42);
|
||||
--color-muted: rgb(71 85 105);
|
||||
--color-muted-alt: rgb(100 116 139);
|
||||
--color-muted-strong: rgb(51 65 85);
|
||||
--color-overlay: rgb(15 23 42 / 0.55);
|
||||
--color-overlay-muted: rgb(15 23 42 / 0.35);
|
||||
--color-overlay-strong: rgb(15 23 42 / 0.65);
|
||||
--color-overlay-darker: rgb(15 23 42 / 0.72);
|
||||
--color-overlay-panel: rgb(15 23 42 / 0.78);
|
||||
--color-overlay-panel-soft: rgb(15 23 42 / 0.6);
|
||||
--color-overlay-panel-tint: rgb(148 163 184 / 0.2);
|
||||
--color-overlay-panel-glass: rgb(255 255 255 / 0.82);
|
||||
--color-overlay-veil: rgb(148 163 184 / 0.5);
|
||||
--color-overlay-panel-gradient-start: rgb(255 255 255 / 0.92);
|
||||
--color-overlay-panel-gradient-end: rgb(226 232 240 / 0.92);
|
||||
--color-surface-tint-subtle: rgb(15 23 42 / 0.08);
|
||||
--color-border-translucent: rgb(148 163 184 / 0.18);
|
||||
--color-border-translucent-strong: rgb(148 163 184 / 0.22);
|
||||
--color-border-translucent-bright: rgb(148 163 184 / 0.28);
|
||||
--color-border-translucent-stronger: rgb(148 163 184 / 0.32);
|
||||
--color-border-translucent-strongest: rgb(148 163 184 / 0.36);
|
||||
--color-border-translucent-glow: rgb(148 163 184 / 0.45);
|
||||
--color-border-translucent-medium: rgb(148 163 184 / 0.2);
|
||||
--color-border-neutral-soft: rgb(148 163 184 / 0.25);
|
||||
--color-overlay-banner: rgb(148 163 184 / 0.7);
|
||||
}
|
||||
@@ -2,6 +2,18 @@
|
||||
|
||||
bitvid's visual language is now powered by Tailwind utilities backed by our design tokens. This document lists the primitives available via `css/tailwind.source.css`, how they behave across states, and when to mix them with Tailwind utilities.
|
||||
|
||||
## Theme System
|
||||
|
||||
The default experience renders the production dark palette. Pages and embeds can opt into alternates by setting the `data-theme` attribute on the `<html>` (or any ancestor that wraps the component). `data-theme="light"` promotes the light tokens defined in `css/tokens.css`, swapping surface, panel, border, muted, and overlay colors while keeping semantic accents consistent. Omit the attribute or set it back to `default` to inherit the dark baseline. Reserve additional theme keys (for example, `data-theme="contrast"`) for upcoming accessibility palettes—the same hook will activate them once their tokens land.
|
||||
|
||||
### Per-page overrides
|
||||
|
||||
Add `<html data-theme="light">` to force a page into light mode. The attribute can also target specific islands—wrap your component tree in a container with `data-theme="light"` when you need to render light cards inside a dark shell.
|
||||
|
||||
### Embedding in third-party surfaces
|
||||
|
||||
Components consume design tokens via CSS custom properties, so they pick up the active theme from the closest ancestor. When embedding widgets into a host site, include the `css/tokens.css` bundle and set `data-theme` on the wrapper to control contrast. If the host already defines its own theme, namespace our tokens (e.g., nest them inside a dedicated `.bitvid-embed[data-theme="light"]`) to avoid collisions while still letting overlay, border, and panel tokens cascade.
|
||||
|
||||
## Focus Handling
|
||||
|
||||
All interactive primitives mix in the shared `.focus-ring` helper. It removes default outlines and applies a branded ring using `focus-visible` only. When building bespoke components, add `.focus-ring` to your root interactive element or replicate its rules:
|
||||
|
||||
+51
-2
@@ -10,10 +10,18 @@
|
||||
<div class="min-h-screen bg-page-alt">
|
||||
<header class="bg-surface text-text shadow-modal">
|
||||
<div
|
||||
class="mx-auto flex max-w-6xl items-center justify-between px-md py-sm"
|
||||
class="mx-auto flex max-w-6xl items-center justify-between gap-sm px-md py-sm"
|
||||
>
|
||||
<h1 class="text-2xl font-semibold">bitvid UI Kitchen Sink</h1>
|
||||
<button class="btn">Primary Action</button>
|
||||
<div class="flex items-center gap-sm">
|
||||
<label class="sr-only" for="themeSwitcher">Theme</label>
|
||||
<select id="themeSwitcher" class="select h-10" aria-label="Select theme">
|
||||
<option value="default">Default (Dark)</option>
|
||||
<option value="light">Light</option>
|
||||
<option value="contrast">High Contrast (Preview)</option>
|
||||
</select>
|
||||
<button class="btn">Primary Action</button>
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
@@ -708,5 +716,46 @@
|
||||
</section>
|
||||
</main>
|
||||
</div>
|
||||
<script>
|
||||
(() => {
|
||||
const storageKey = "bitvid-docs-theme";
|
||||
const root = document.documentElement;
|
||||
const switcher = document.getElementById("themeSwitcher");
|
||||
|
||||
const applyTheme = (value) => {
|
||||
if (!value || value === "default") {
|
||||
delete root.dataset.theme;
|
||||
} else {
|
||||
root.dataset.theme = value;
|
||||
}
|
||||
};
|
||||
|
||||
let savedTheme;
|
||||
try {
|
||||
savedTheme = window.localStorage.getItem(storageKey) || undefined;
|
||||
} catch (error) {
|
||||
savedTheme = undefined;
|
||||
}
|
||||
|
||||
applyTheme(savedTheme);
|
||||
|
||||
if (switcher) {
|
||||
switcher.value = savedTheme ?? "default";
|
||||
switcher.addEventListener("change", (event) => {
|
||||
const { value } = event.target;
|
||||
applyTheme(value);
|
||||
try {
|
||||
if (!value || value === "default") {
|
||||
window.localStorage.removeItem(storageKey);
|
||||
} else {
|
||||
window.localStorage.setItem(storageKey, value);
|
||||
}
|
||||
} catch (error) {
|
||||
/* Ignore storage failures (private mode, etc.) */
|
||||
}
|
||||
});
|
||||
}
|
||||
})();
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
Reference in new issue
Block a user