spry-theme-glassy.css 8.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266
  1. /*
  2. * Spry CSS theme — "Glassy" (ZL4GQ-faithful)
  3. *
  4. * Solid dark cards (#242424) floating on a deep blue-violet→cyan gradient
  5. * field; glass (blur) reserved for chrome bars only (topbar, hero band,
  6. * drawer shells, dialog/popover titlebars, card strips). Big Cantarell type,
  7. * azure accent, signature wide glow shadow (0 0 80px). Load after spry.css.
  8. * No JavaScript, no external resources, no mode blocks.
  9. */
  10. [data-theme="glassy"],
  11. html:has(#spry-theme-glassy:checked) {
  12. color-scheme: dark;
  13. accent-color: var(--spry-accent);
  14. /* ---- Palette ---- */
  15. --spry-bg: hsl(230 40% 8%);
  16. --spry-bg-alt: #2d2d2d;
  17. --spry-bg-inset: #2d2d2d;
  18. --spry-surface: #242424; /* SOLID card fill — never glass */
  19. --spry-surface-hover: #2d2d2d;
  20. --spry-fg: #fff;
  21. --spry-fg-muted: #949cad;
  22. --spry-border: #2d2d2d;
  23. --spry-border-strong: rgb(120 130 150 / 0.5);
  24. --spry-accent: hsl(207 100% 70%);
  25. --spry-accent-hover: hsl(207 100% 50%);
  26. --spry-accent-fg: #0b1626;
  27. /* deep blue "primary" hsl(200 100% 30%) + pale blue "secondary"
  28. * hsl(200 70% 80%) are used literally below (core has no vars for them) */
  29. --spry-danger: #800000; /* .btn-danger: maroon fill, white text */
  30. --spry-success: hsl(140 60% 60%);
  31. --spry-info: hsl(207 90% 74%);
  32. --spry-warning: hsl(42 90% 62%);
  33. --spry-link: hsl(207 100% 70%);
  34. --spry-link-hover: hsl(207 100% 50%);
  35. --spry-backdrop: rgb(0 0 0 / 0.6);
  36. --spry-focus-ring: 0 0 0 3px hsl(200 100% 30% / 0.45);
  37. /* ---- Typography ---- */
  38. --spry-font: Cantarell, system-ui, -apple-system, "Segoe UI", sans-serif;
  39. --spry-font-heading: var(--spry-font);
  40. --spry-font-size: 1.2rem;
  41. --spry-line-height: 1.5;
  42. --spry-heading-weight: 700;
  43. /* ---- Shape & depth ---- */
  44. --spry-radius: 0.5rem;
  45. --spry-radius-sm: 0.5rem;
  46. --spry-radius-lg: 0.5rem;
  47. --spry-shadow: 0 6px 20px 0 rgb(0 0 0 / 0.38);
  48. --spry-shadow-lg: /* THE signature glow */
  49. 0 0 80px 0 rgb(0 0 0 / 0.4), 0 6px 20px 0 rgb(0 0 0 / 0.38);
  50. --spry-glass: blur(10px); /* chrome bars ONLY, never surfaces */
  51. /* ---- Controls ---- */
  52. --spry-control-bg: #242424;
  53. --spry-control-fg: #fff;
  54. --spry-control-border: #858585;
  55. /* ---- Buttons ---- */
  56. --spry-btn-bg: #242424;
  57. --spry-btn-fg: #fff;
  58. --spry-btn-border: #858585;
  59. --spry-btn-bg-hover: #242424; /* border swap handled below */
  60. --spry-btn-bg-active: hsl(200 70% 80%);
  61. /* ---- Progress / tables / popovers / cards ---- */
  62. --spry-progress-bg: #2d2d2d;
  63. --spry-progress-fg: linear-gradient(90deg, hsl(200 100% 35%), hsl(200 70% 65%));
  64. --spry-table-header-bg: hsl(200 70% 80%);
  65. --spry-table-hover: rgb(255 255 255 / 0.06);
  66. --spry-popover-bg: #242424;
  67. --spry-popover-border: #2d2d2d;
  68. --spry-popover-shadow: var(--spry-shadow-lg);
  69. --spry-card-bg: #242424;
  70. --spry-card-border: #2d2d2d;
  71. --spry-card-padding: 1rem 1.125rem 1.125rem;
  72. --spry-card-shadow: var(--spry-shadow-lg);
  73. /* ---- Structural rules ---- */
  74. /* Two hsla overlays over a still image, approximated as one fixed gradient */
  75. & body {
  76. background: linear-gradient(170deg, hsl(258 60% 13% / 0.55), hsl(195 80% 25% / 0.55))
  77. fixed hsl(230 40% 8%);
  78. }
  79. /* Site subtitle pattern: h2 riding up under h1, in muted gray */
  80. & h1 + h2 {
  81. margin-top: -1.2em;
  82. color: var(--spry-fg-muted);
  83. }
  84. & blockquote {
  85. background: hsl(200 70% 80%);
  86. border-left: 10px solid hsl(200 100% 30%);
  87. color: #1c2733;
  88. font-family: Georgia, serif;
  89. border-radius: 0.5rem;
  90. }
  91. & blockquote p { color: inherit; }
  92. & hr {
  93. background: #fff;
  94. opacity: 0.85;
  95. margin-block: 4rem;
  96. }
  97. & figure {
  98. border: 1px solid hsl(200 100% 30%);
  99. padding: 1rem;
  100. }
  101. /* Tables: pale-blue header, zebra rows, defined grid lines.
  102. * :where() keeps these at (0,1,0)-ish so .table-* modifiers still win. */
  103. & :where(table) :where(th, td) { border: 1px solid rgb(120 130 150 / 0.35); }
  104. & :where(table thead th) {
  105. background: hsl(200 70% 80%);
  106. color: #16222e;
  107. border: 1px solid rgb(120 130 150 / 0.35);
  108. }
  109. & :where(table) tbody tr:nth-child(even) { background: #2d2d2d; }
  110. /* Topbar: the glass banner */
  111. & .topbar {
  112. background: rgb(50 50 50 / 0.5);
  113. backdrop-filter: var(--spry-glass);
  114. border-bottom: 1px solid rgb(100 100 100 / 0.7);
  115. padding-block: 0.9rem;
  116. }
  117. & .topbar-brand {
  118. font-weight: 800;
  119. letter-spacing: 0.04em;
  120. }
  121. /* Card strips: subtle glass over the solid card (#2d2d2d edges via
  122. * --spry-border) */
  123. & :is(.card-header, .card-footer) {
  124. background: rgb(50 50 50 / 0.35);
  125. backdrop-filter: var(--spry-glass);
  126. }
  127. /* Buttons: hover/active border + active text the vars can't carry
  128. * (:where() keeps .btn-* variants winning) */
  129. & :where(.btn, button, input[type="submit"], input[type="reset"], input[type="button"]):hover {
  130. border-color: hsl(200 100% 30%);
  131. }
  132. & :where(.btn, button, input[type="submit"], input[type="reset"], input[type="button"]):active {
  133. color: #2d2d2d;
  134. border-color: hsl(200 100% 30%);
  135. }
  136. /* Primary: deep blue fill, white text, slightly lighter on hover.
  137. * (.btn-danger needs nothing: --spry-danger: #800000 + core white text) */
  138. & .btn-primary {
  139. background: hsl(200 100% 30%);
  140. border-color: hsl(200 100% 30%);
  141. color: #fff;
  142. }
  143. & .btn-primary:hover {
  144. background: hsl(200 100% 38%);
  145. border-color: hsl(200 100% 38%);
  146. }
  147. /* Hero: glass band with a primary→secondary gradient edge */
  148. & .hero {
  149. border: 1px solid transparent;
  150. background:
  151. linear-gradient(rgb(6 14 30 / 0.72), rgb(6 14 30 / 0.45)) padding-box,
  152. linear-gradient(90deg, hsl(200 100% 30%), hsl(200 70% 80%)) border-box;
  153. backdrop-filter: var(--spry-glass);
  154. }
  155. & .hero-eyebrow {
  156. color: #bfe0ff;
  157. }
  158. & .hero-sub {
  159. color: #c9d1e0;
  160. }
  161. & .avatar {
  162. background: #242424;
  163. border: 1px solid hsl(200 100% 30%);
  164. color: #fff;
  165. }
  166. /* Drawers: glass bars; inner body stays solid */
  167. & :is(.drawer-left, .drawer-right) {
  168. background: rgb(50 50 50 / 0.6);
  169. backdrop-filter: var(--spry-glass);
  170. }
  171. & :is(.drawer-left, .drawer-right) .dialog-body { background: #242424; }
  172. & .pagination [aria-current="page"] {
  173. background: hsl(200 70% 80%);
  174. color: #16222e;
  175. }
  176. /* Dialog chrome: glass titlebar strip; dialog/popover bodies stay solid
  177. * #242424 with the big glow via --spry-popover-bg/shadow */
  178. & .dialog-titlebar {
  179. background: rgb(50 50 50 / 0.5);
  180. backdrop-filter: var(--spry-glass);
  181. border-bottom: 1px solid rgb(100 100 100 / 0.7);
  182. }
  183. /* Alerts: solid, not translucent tints. Danger = maroon + white. */
  184. & .alert-danger {
  185. background: #800000;
  186. border-color: rgb(255 255 255 / 0.25);
  187. color: #fff;
  188. }
  189. & .alert-success { background: hsl(140 35% 12%); }
  190. & .alert-info { background: hsl(207 40% 14%); }
  191. & .alert-warning { background: hsl(42 35% 12%); }
  192. /* Maroon stays for fills; text usages of danger (validation hints,
  193. .text-danger) need the bright red or they vanish on #242424 */
  194. & :is(.text-danger, .field .is-invalid ~ .hint) {
  195. color: #ff948b;
  196. }
  197. & .is-invalid {
  198. border-color: #e05252 !important;
  199. }
  200. & .badge-danger { background: #800000; color: #fff; }
  201. & .dialog-close:hover { background: #800000; color: #fff; }
  202. /* Inputs on focus: darker well + primary border (core keeps the ring) */
  203. & input:focus:not([type="checkbox"]):not([type="radio"]):not([type="range"]):not([type="file"]),
  204. & select:focus,
  205. & textarea:focus,
  206. & .input:focus {
  207. background: #2d2d2d;
  208. border-color: hsl(200 100% 30%);
  209. }
  210. /* Progress: gradient fill; engine pseudo rules kept SEPARATE */
  211. & progress::-webkit-progress-value { background: var(--spry-progress-fg); }
  212. & progress::-moz-progress-bar { background: var(--spry-progress-fg); }
  213. & progress:indeterminate {
  214. background:
  215. repeating-linear-gradient(90deg,
  216. rgb(255 255 255 / 0) 0 28px,
  217. rgb(255 255 255 / 0.3) 36px 64px,
  218. rgb(255 255 255 / 0) 72px 128px) 0 0 / 128px 100%,
  219. linear-gradient(90deg, hsl(200 100% 35% / 0.4), hsl(200 70% 65% / 0.4));
  220. animation: glassy-march 1.3s linear infinite;
  221. }
  222. /* OTP inputs, spinner, menus, tabs, expanders, switch: all inherit the
  223. * control/accent vars above — nothing needed here. */
  224. }
  225. /* Keyframes stay TOP-LEVEL: nested keyframes are dropped by browsers.
  226. The pattern tile is 128px wide and advances exactly one tile per loop:
  227. a seamless conveyor — no gap, nothing flying past the edges. */
  228. @keyframes glassy-march {
  229. from { background-position: 0 0, 0 0; }
  230. to { background-position: 128px 0, 0 0; }
  231. }