/* * Spry CSS theme — "Glassy" (ZL4GQ-faithful) * * Solid dark cards (#242424) floating on a deep blue-violet→cyan gradient * field; glass (blur) reserved for chrome bars only (topbar, hero band, * drawer shells, dialog/popover titlebars, card strips). Big Cantarell type, * azure accent, signature wide glow shadow (0 0 80px). Load after spry.css. * No JavaScript, no external resources, no mode blocks. */ [data-theme="glassy"], html:has(#spry-theme-glassy:checked) { color-scheme: dark; accent-color: var(--spry-accent); /* ---- Palette ---- */ --spry-bg: hsl(230 40% 8%); --spry-bg-alt: #2d2d2d; --spry-bg-inset: #2d2d2d; --spry-surface: #242424; /* SOLID card fill — never glass */ --spry-surface-hover: #2d2d2d; --spry-fg: #fff; --spry-fg-muted: #949cad; --spry-border: #2d2d2d; --spry-border-strong: rgb(120 130 150 / 0.5); --spry-accent: hsl(207 100% 70%); --spry-accent-hover: hsl(207 100% 50%); --spry-accent-fg: #0b1626; /* deep blue "primary" hsl(200 100% 30%) + pale blue "secondary" * hsl(200 70% 80%) are used literally below (core has no vars for them) */ --spry-danger: #800000; /* .btn-danger: maroon fill, white text */ --spry-success: hsl(140 60% 60%); --spry-info: hsl(207 90% 74%); --spry-warning: hsl(42 90% 62%); --spry-link: hsl(207 100% 70%); --spry-link-hover: hsl(207 100% 50%); --spry-backdrop: rgb(0 0 0 / 0.6); --spry-focus-ring: 0 0 0 3px hsl(200 100% 30% / 0.45); /* ---- Typography ---- */ --spry-font: Cantarell, system-ui, -apple-system, "Segoe UI", sans-serif; --spry-font-heading: var(--spry-font); --spry-font-size: 1.2rem; --spry-line-height: 1.5; --spry-heading-weight: 700; /* ---- Shape & depth ---- */ --spry-radius: 0.5rem; --spry-radius-sm: 0.5rem; --spry-radius-lg: 0.5rem; --spry-shadow: 0 6px 20px 0 rgb(0 0 0 / 0.38); --spry-shadow-lg: /* THE signature glow */ 0 0 80px 0 rgb(0 0 0 / 0.4), 0 6px 20px 0 rgb(0 0 0 / 0.38); --spry-glass: blur(10px); /* chrome bars ONLY, never surfaces */ /* ---- Controls ---- */ --spry-control-bg: #242424; --spry-control-fg: #fff; --spry-control-border: #858585; /* ---- Buttons ---- */ --spry-btn-bg: #242424; --spry-btn-fg: #fff; --spry-btn-border: #858585; --spry-btn-bg-hover: #242424; /* border swap handled below */ --spry-btn-bg-active: hsl(200 70% 80%); /* ---- Progress / tables / popovers / cards ---- */ --spry-progress-bg: #2d2d2d; --spry-progress-fg: linear-gradient(90deg, hsl(200 100% 35%), hsl(200 70% 65%)); --spry-table-header-bg: hsl(200 70% 80%); --spry-table-hover: rgb(255 255 255 / 0.06); --spry-popover-bg: #242424; --spry-popover-border: #2d2d2d; --spry-popover-shadow: var(--spry-shadow-lg); --spry-card-bg: #242424; --spry-card-border: #2d2d2d; --spry-card-padding: 1rem 1.125rem 1.125rem; --spry-card-shadow: var(--spry-shadow-lg); /* ---- Structural rules ---- */ /* Two hsla overlays over a still image, approximated as one fixed gradient */ & body { background: linear-gradient(170deg, hsl(258 60% 13% / 0.55), hsl(195 80% 25% / 0.55)) fixed hsl(230 40% 8%); } /* Site subtitle pattern: h2 riding up under h1, in muted gray */ & h1 + h2 { margin-top: -1.2em; color: var(--spry-fg-muted); } & blockquote { background: hsl(200 70% 80%); border-left: 10px solid hsl(200 100% 30%); color: #1c2733; font-family: Georgia, serif; border-radius: 0.5rem; } & blockquote p { color: inherit; } & hr { background: #fff; opacity: 0.85; margin-block: 4rem; } & figure { border: 1px solid hsl(200 100% 30%); padding: 1rem; } /* Tables: pale-blue header, zebra rows, defined grid lines. * :where() keeps these at (0,1,0)-ish so .table-* modifiers still win. */ & :where(table) :where(th, td) { border: 1px solid rgb(120 130 150 / 0.35); } & :where(table thead th) { background: hsl(200 70% 80%); color: #16222e; border: 1px solid rgb(120 130 150 / 0.35); } & :where(table) tbody tr:nth-child(even) { background: #2d2d2d; } /* Topbar: the glass banner */ & .topbar { background: rgb(50 50 50 / 0.5); backdrop-filter: var(--spry-glass); border-bottom: 1px solid rgb(100 100 100 / 0.7); padding-block: 0.9rem; } & .topbar-brand { font-weight: 800; letter-spacing: 0.04em; } /* Card strips: subtle glass over the solid card (#2d2d2d edges via * --spry-border) */ & :is(.card-header, .card-footer) { background: rgb(50 50 50 / 0.35); backdrop-filter: var(--spry-glass); } /* Buttons: hover/active border + active text the vars can't carry * (:where() keeps .btn-* variants winning) */ & :where(.btn, button, input[type="submit"], input[type="reset"], input[type="button"]):hover { border-color: hsl(200 100% 30%); } & :where(.btn, button, input[type="submit"], input[type="reset"], input[type="button"]):active { color: #2d2d2d; border-color: hsl(200 100% 30%); } /* Primary: deep blue fill, white text, slightly lighter on hover. * (.btn-danger needs nothing: --spry-danger: #800000 + core white text) */ & .btn-primary { background: hsl(200 100% 30%); border-color: hsl(200 100% 30%); color: #fff; } & .btn-primary:hover { background: hsl(200 100% 38%); border-color: hsl(200 100% 38%); } /* Hero: glass band with a primary→secondary gradient edge */ & .hero { border: 1px solid transparent; background: linear-gradient(rgb(6 14 30 / 0.72), rgb(6 14 30 / 0.45)) padding-box, linear-gradient(90deg, hsl(200 100% 30%), hsl(200 70% 80%)) border-box; backdrop-filter: var(--spry-glass); } & .hero-eyebrow { color: #bfe0ff; } & .hero-sub { color: #c9d1e0; } & .avatar { background: #242424; border: 1px solid hsl(200 100% 30%); color: #fff; } /* Drawers: glass bars; inner body stays solid */ & :is(.drawer-left, .drawer-right) { background: rgb(50 50 50 / 0.6); backdrop-filter: var(--spry-glass); } & :is(.drawer-left, .drawer-right) .dialog-body { background: #242424; } & .pagination [aria-current="page"] { background: hsl(200 70% 80%); color: #16222e; } /* Dialog chrome: glass titlebar strip; dialog/popover bodies stay solid * #242424 with the big glow via --spry-popover-bg/shadow */ & .dialog-titlebar { background: rgb(50 50 50 / 0.5); backdrop-filter: var(--spry-glass); border-bottom: 1px solid rgb(100 100 100 / 0.7); } /* Alerts: solid, not translucent tints. Danger = maroon + white. */ & .alert-danger { background: #800000; border-color: rgb(255 255 255 / 0.25); color: #fff; } & .alert-success { background: hsl(140 35% 12%); } & .alert-info { background: hsl(207 40% 14%); } & .alert-warning { background: hsl(42 35% 12%); } /* Maroon stays for fills; text usages of danger (validation hints, .text-danger) need the bright red or they vanish on #242424 */ & :is(.text-danger, .field .is-invalid ~ .hint) { color: #ff948b; } & .is-invalid { border-color: #e05252 !important; } & .badge-danger { background: #800000; color: #fff; } & .dialog-close:hover { background: #800000; color: #fff; } /* Inputs on focus: darker well + primary border (core keeps the ring) */ & input:focus:not([type="checkbox"]):not([type="radio"]):not([type="range"]):not([type="file"]), & select:focus, & textarea:focus, & .input:focus { background: #2d2d2d; border-color: hsl(200 100% 30%); } /* Progress: gradient fill; engine pseudo rules kept SEPARATE */ & progress::-webkit-progress-value { background: var(--spry-progress-fg); } & progress::-moz-progress-bar { background: var(--spry-progress-fg); } & progress:indeterminate { background: repeating-linear-gradient(90deg, rgb(255 255 255 / 0) 0 28px, rgb(255 255 255 / 0.3) 36px 64px, rgb(255 255 255 / 0) 72px 128px) 0 0 / 128px 100%, linear-gradient(90deg, hsl(200 100% 35% / 0.4), hsl(200 70% 65% / 0.4)); animation: glassy-march 1.3s linear infinite; } /* OTP inputs, spinner, menus, tabs, expanders, switch: all inherit the * control/accent vars above — nothing needed here. */ } /* Keyframes stay TOP-LEVEL: nested keyframes are dropped by browsers. The pattern tile is 128px wide and advances exactly one tile per loop: a seamless conveyor — no gap, nothing flying past the edges. */ @keyframes glassy-march { from { background-position: 0 0, 0 0; } to { background-position: 128px 0, 0 0; } }