/* ===== uiCookies Glassmorphism kit: design tokens (identical in every set) =====
Retheme the whole kit here. Light scene on :root, dark scene on [data-scene="dark"]
(or any [data-scene] holding a checked [data-scene-switch]). Selectors use :where()
so the fallbacks below always win. */
:where(:root,[data-scene="light"]){
color-scheme:light;
/* background scene: the colour the glass frosts */
--scene-base:linear-gradient(155deg,#eceffe 0%,#fbeef7 52%,#e6f6fb 100%);
--scene-1:linear-gradient(140deg,#7c3aed,#c026d3);
--scene-2:linear-gradient(140deg,#fb7185,#f97316);
--scene-3:linear-gradient(140deg,#22d3ee,#3b82f6);
--scene-4:linear-gradient(140deg,#fde047,#fb923c);
/* glass */
--glass-tint:255 255 255;
--glass-border:rgb(255 255 255 / .8);
--glass-edge:rgb(36 32 88 / .9);
--glass-highlight:inset 0 1px 0 rgb(255 255 255 / .85);
--glass-shadow:0 18px 40px -18px rgb(37 30 102 / .45);
--glass-ink:#16133a;
--glass-ink-soft:#3b3862;
--glass-accent:#4338ca;
--glass-accent-bg:rgb(67 56 202 / .92);
--glass-on-accent:#fff;
--glass-check-icon:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath d='M3.5 8.5l3 3 6-7' fill='none' stroke='%23fff' stroke-width='2.4' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
--glass-focus:#1e1b4b;
--glass-good:#14532d;--glass-good-bg:rgb(220 252 231 / .9);
--glass-bad:#991b1b;--glass-bad-bg:rgb(254 226 226 / .9);
--glass-warn:#7c2d12;--glass-warn-bg:rgb(254 243 199 / .9);
--glass-scrim:rgb(22 19 58 / .3);
}
:where([data-scene="dark"]),:where([data-scene]:has([data-scene-switch]:checked)){
color-scheme:dark;
--scene-base:linear-gradient(155deg,#0a0c22 0%,#170c2c 52%,#06171f 100%);
--scene-1:linear-gradient(140deg,#6d28d9,#a21caf);
--scene-2:linear-gradient(140deg,#e11d48,#ea580c);
--scene-3:linear-gradient(140deg,#0891b2,#2563eb);
--scene-4:linear-gradient(140deg,#ca8a04,#c2410c);
--glass-tint:16 18 44;
--glass-border:rgb(255 255 255 / .2);
--glass-edge:rgb(214 220 255 / .72);
--glass-highlight:inset 0 1px 0 rgb(255 255 255 / .16);
--glass-shadow:0 18px 40px -18px rgb(0 0 0 / .75);
--glass-ink:#f5f6ff;
--glass-ink-soft:#d0d3ee;
--glass-accent:#a5b4fc;
--glass-accent-bg:rgb(165 180 252 / .96);
--glass-on-accent:#14123a;
--glass-check-icon:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath d='M3.5 8.5l3 3 6-7' fill='none' stroke='%2314123a' stroke-width='2.4' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
--glass-focus:#c7d2fe;
--glass-good:#bbf7d0;--glass-good-bg:rgb(20 83 45 / .7);
--glass-bad:#fecaca;--glass-bad-bg:rgb(127 29 29 / .7);
--glass-warn:#fde68a;--glass-warn-bg:rgb(120 53 15 / .7);
--glass-scrim:rgb(0 0 0 / .5);
}
:where(:root){
--glass-alpha:.6; /* panels and cards */
--glass-alpha-strong:.82; /* menus, dialogs, toasts: they cover unknown content */
--glass-alpha-control:.5; /* buttons and fields sitting on a panel */
--glass-blur:18px;
--glass-saturate:150%;
--glass-radius:20px;
}
/* derived: recomputed inside every scene so a dark scene gets dark glass */
:where(:root,[data-scene]){
--glass-bg:rgb(var(--glass-tint) / var(--glass-alpha));
--glass-bg-strong:rgb(var(--glass-tint) / var(--glass-alpha-strong));
--glass-bg-control:rgb(var(--glass-tint) / var(--glass-alpha-control));
}
/* no backdrop-filter: frosting can't happen, so the glass turns nearly solid */
@supports not ((backdrop-filter:blur(1px)) or (-webkit-backdrop-filter:blur(1px))){
:where(:root){--glass-alpha:.94;--glass-alpha-strong:.97;--glass-alpha-control:.9}
}
@media (prefers-reduced-transparency:reduce){
:where(:root){--glass-alpha:.93;--glass-alpha-strong:.97;--glass-alpha-control:.9;--glass-blur:8px}
}
@media (prefers-contrast:more){
:where(:root){--glass-alpha:.96;--glass-alpha-strong:.98;--glass-alpha-control:.96}
:where(:root,[data-scene]){--glass-border:var(--glass-ink);--glass-edge:var(--glass-ink)}
}
/* ===== end of tokens ===== */
/* Tailwind theme: utilities such as bg-glass, border-glass-edge, backdrop-blur-glass and text-ink read the tokens above */
@theme inline {
--color-glass: var(--glass-bg);
--color-glass-strong: var(--glass-bg-strong);
--color-glass-control: var(--glass-bg-control);
--color-glass-border: var(--glass-border);
--color-glass-edge: var(--glass-edge);
--color-ink: var(--glass-ink);
--color-ink-soft: var(--glass-ink-soft);
--color-accent: var(--glass-accent);
--color-accent-glass: var(--glass-accent-bg);
--color-on-accent: var(--glass-on-accent);
--color-focus: var(--glass-focus);
--color-good: var(--glass-good);
--color-good-glass: var(--glass-good-bg);
--color-bad: var(--glass-bad);
--color-bad-glass: var(--glass-bad-bg);
--color-warn: var(--glass-warn);
--color-warn-glass: var(--glass-warn-bg);
--color-scrim: var(--glass-scrim);
--blur-glass: var(--glass-blur);
--radius-glass: var(--glass-radius);
--shadow-glass: var(--glass-shadow);
--inset-shadow-glass: var(--glass-highlight);
--animate-drift: g-drift 32s ease-in-out infinite alternate;
}
@keyframes g-drift { to { transform: translate3d(3vw,4vh,0) scale(1.06); } }
@theme { --animate-fill: g-fill 1s ease-out; }
@keyframes g-fill { from { stroke-dasharray: 0 100; } }
About this set
A complete glass dashboard built from the components of the uiCookies glassmorphism UI kit, with a switch that turns the whole scene from light to dark. The sticky sidebar has the logo, five links with the current page marked, a new-customers count and the signed-in user. The top bar greets the user, holds a search field and the Dark scene switch. Below are three KPI tiles for revenue, active customers and churn, a revenue-by-day bar chart with the value printed above every bar, a sprint progress ring with its task count and end date, and a recent activity feed with times. The scene switch needs no JavaScript. It is a checkbox with data-scene-switch inside the data-scene wrapper, and the token block contains one selector, [data-scene]:has([data-scene-switch]:checked), that applies the dark values, so every glass surface, text colour and edge changes at once. The bar chart is an ordered list of real text with bars drawn by height, so the numbers stay readable and copyable. On tablets the sidebar moves above the content, and on phones the KPI tiles stack. The Bootstrap version feeds the tokens into Bootstrap’s own component variables, and the Tailwind version maps them to theme utilities such as bg-glass, border-glass-edge, backdrop-blur-glass and text-ink.
What’s included
Light and dark scenes switched by a checkbox and :has(), no JavaScript
Sticky glass sidebar, top bar with search, KPI tiles and activity feed
Bar chart as an ordered list with values written as text
Sprint progress ring and legend
Bootstrap version built from .row, .card, .nav-pills, .form-switch and .list-group
Accessibility
The page has nav and main landmarks, the current link uses aria-current, the scene switch is a labelled checkbox with role="switch", and the search field has an aria-label. Chart values and ring figures are text, and decorative bars, icons and avatars are hidden from assistive technology. All text was checked at 4.5:1 and edges at 3:1 in both the light and the dark scene, focus shows a 3px outline, and animations stop under prefers-reduced-motion.
Customise it
Retheme both scenes in the token block; the dark values sit under [data-scene="dark"] and the :has() selector. Change the bar heights through --h in CSS and Bootstrap or the h-[n%] utilities in Tailwind. Remove data-scene-switch from the checkbox to fix the dashboard to one scene.