@nxgt/material 3.3.0 → 3.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (80) hide show
  1. package/CHANGELOG.md +29 -0
  2. package/README.md +5 -5
  3. package/dist/backgrounds/backgrounds.css +30 -1
  4. package/dist/backgrounds/css-react/blobs.css +65 -0
  5. package/dist/backgrounds/css-react/bubbles.css +41 -0
  6. package/dist/backgrounds/css-react/checker.css +47 -0
  7. package/dist/backgrounds/css-react/chevrons.css +46 -0
  8. package/dist/backgrounds/css-react/circuit.css +111 -0
  9. package/dist/backgrounds/css-react/concrete.css +41 -0
  10. package/dist/backgrounds/css-react/diagonal-checker.css +48 -0
  11. package/dist/backgrounds/css-react/glass.css +99 -0
  12. package/dist/backgrounds/css-react/graph-paper.css +74 -0
  13. package/dist/backgrounds/css-react/halo.css +66 -0
  14. package/dist/backgrounds/css-react/hexagons.css +79 -0
  15. package/dist/backgrounds/css-react/illustrated.css +164 -0
  16. package/dist/backgrounds/css-react/leaves.css +41 -0
  17. package/dist/backgrounds/css-react/linen.css +44 -0
  18. package/dist/backgrounds/css-react/marble.css +55 -0
  19. package/dist/backgrounds/css-react/music.css +2 -0
  20. package/dist/backgrounds/css-react/night-sky.css +41 -0
  21. package/dist/backgrounds/css-react/paper.css +49 -0
  22. package/dist/backgrounds/css-react/plasma.css +53 -0
  23. package/dist/backgrounds/css-react/rays.css +67 -0
  24. package/dist/backgrounds/css-react/ripples.css +68 -0
  25. package/dist/backgrounds/css-react/school.css +2 -0
  26. package/dist/backgrounds/css-react/science.css +2 -0
  27. package/dist/backgrounds/css-react/sport.css +2 -0
  28. package/dist/backgrounds/css-react/travel.css +2 -0
  29. package/dist/backgrounds.js +57 -33
  30. package/dist/components/components.css +1 -0
  31. package/dist/components/ui/layout/app-shell/activity-backdrop.css +24 -0
  32. package/dist/{components-p7VoF7gR.js → components-CXpL1zEs.js} +20 -13
  33. package/dist/components.js +1 -1
  34. package/dist/lib/backgrounds/background/available.d.ts +3 -3
  35. package/dist/lib/backgrounds/background/background.d.ts +2 -2
  36. package/dist/lib/backgrounds/index.d.ts +1 -1
  37. package/dist/lib/components/ui/layout/app-shell/activity-layout.d.ts +23 -1
  38. package/dist/main.js +1 -1
  39. package/dist/material.css +1 -1
  40. package/docs/components/navigation-and-layout.md +2 -1
  41. package/docs/getting-started.md +1 -1
  42. package/docs/guides/app-shell.md +47 -0
  43. package/docs/guides/backgrounds.md +101 -17
  44. package/docs/previews/backgrounds-geometry-more.webp +0 -0
  45. package/docs/previews/backgrounds-illustrated-scenes.webp +0 -0
  46. package/docs/previews/backgrounds-light-more.webp +0 -0
  47. package/docs/previews/backgrounds-material-more.webp +0 -0
  48. package/docs/previews/backgrounds-matrix.webp +0 -0
  49. package/docs/previews/backgrounds-motif-shapes.webp +0 -0
  50. package/docs/roadmap.md +16 -4
  51. package/docs/troubleshooting.md +20 -2
  52. package/lib/backgrounds/backgrounds.css +30 -1
  53. package/lib/backgrounds/css-react/blobs.css +65 -0
  54. package/lib/backgrounds/css-react/bubbles.css +41 -0
  55. package/lib/backgrounds/css-react/checker.css +47 -0
  56. package/lib/backgrounds/css-react/chevrons.css +46 -0
  57. package/lib/backgrounds/css-react/circuit.css +111 -0
  58. package/lib/backgrounds/css-react/concrete.css +41 -0
  59. package/lib/backgrounds/css-react/diagonal-checker.css +48 -0
  60. package/lib/backgrounds/css-react/glass.css +99 -0
  61. package/lib/backgrounds/css-react/graph-paper.css +74 -0
  62. package/lib/backgrounds/css-react/halo.css +66 -0
  63. package/lib/backgrounds/css-react/hexagons.css +79 -0
  64. package/lib/backgrounds/css-react/illustrated.css +164 -0
  65. package/lib/backgrounds/css-react/leaves.css +41 -0
  66. package/lib/backgrounds/css-react/linen.css +44 -0
  67. package/lib/backgrounds/css-react/marble.css +55 -0
  68. package/lib/backgrounds/css-react/music.css +2 -0
  69. package/lib/backgrounds/css-react/night-sky.css +41 -0
  70. package/lib/backgrounds/css-react/paper.css +49 -0
  71. package/lib/backgrounds/css-react/plasma.css +53 -0
  72. package/lib/backgrounds/css-react/rays.css +67 -0
  73. package/lib/backgrounds/css-react/ripples.css +68 -0
  74. package/lib/backgrounds/css-react/school.css +2 -0
  75. package/lib/backgrounds/css-react/science.css +2 -0
  76. package/lib/backgrounds/css-react/sport.css +2 -0
  77. package/lib/backgrounds/css-react/travel.css +2 -0
  78. package/lib/components/components.css +1 -0
  79. package/lib/components/ui/layout/app-shell/activity-backdrop.css +24 -0
  80. package/package.json +103 -2
@@ -0,0 +1,46 @@
1
+ /* The `chevrons` preset: a few large, very pale chevron bands leaning across
2
+ * the frame, c1 and c2 in turn, over a faint tint. Layers: `wash` (a tint) and
3
+ * the SVG scene (`ch-a`, `ch-b` the bands, in the group `ch-field`). The SVG
4
+ * covers the background, so the bands are sized by the viewport. `animated`
5
+ * drifts the group slowly down and back. `ch-m`: small motifs along the bands. React only: nothing in the shared
6
+ * `css/` folder. */
7
+ @import "../css/scene.css";
8
+
9
+ @layer components {
10
+ [data-background="chevrons"] > [data-layer="wash"] {
11
+ position: absolute;
12
+ inset: 0;
13
+ background-image: linear-gradient(
14
+ 0deg,
15
+ color-mix(in oklab, var(--nxgt-bg-c1) var(--nxgt-bg-a1), transparent),
16
+ transparent 65%
17
+ );
18
+ }
19
+ [data-background="chevrons"] > [data-scene] .ch-a {
20
+ fill: var(--nxgt-bg-c1);
21
+ fill-opacity: calc(var(--nxgt-bg-op) * 0.16);
22
+ }
23
+ [data-background="chevrons"] > [data-scene] .ch-b {
24
+ fill: var(--nxgt-bg-c2);
25
+ fill-opacity: calc(var(--nxgt-bg-op) * 0.12);
26
+ }
27
+ [data-background="chevrons"] > [data-scene] .ch-m {
28
+ color: var(--nxgt-bg-c1);
29
+ fill-opacity: 0.55;
30
+ }
31
+ }
32
+
33
+ @media (prefers-reduced-motion: no-preference) {
34
+ @keyframes nxgt-bg-chevrons-drift {
35
+ to {
36
+ transform: translateY(40px);
37
+ }
38
+ }
39
+
40
+ @layer components {
41
+ [data-background="chevrons"][data-animated] > [data-scene] .ch-field {
42
+ animation: nxgt-bg-chevrons-drift 18s ease-in-out infinite alternate
43
+ var(--nxgt-bg-play, running);
44
+ }
45
+ }
46
+ }
@@ -0,0 +1,111 @@
1
+ /* The `circuit` preset: a printed circuit board. Layers: `wash` (a tint) and
2
+ * the SVG scene (`cb-trace` and `cb-l1..3` the traces, `cb-pin`, `cb-chip`,
3
+ * `cb-pad`, and `cb-sig`, the dash that runs along a trace when `animated`).
4
+ * React only: nothing in the shared `css/` folder. */
5
+ @import "../css/scene.css";
6
+
7
+ @layer components {
8
+ [data-background="circuit"] > [data-layer="wash"] {
9
+ position: absolute;
10
+ inset: 0;
11
+ background-image: linear-gradient(
12
+ 160deg,
13
+ color-mix(in oklab, var(--nxgt-bg-c1) var(--nxgt-bg-a2), transparent),
14
+ transparent 65%
15
+ );
16
+ }
17
+ [data-background="circuit"] > [data-scene] {
18
+ -webkit-mask-image: radial-gradient(
19
+ ellipse 75% 75% at 50% 50%,
20
+ rgb(0 0 0 / 0.4) 0%,
21
+ black 100%
22
+ );
23
+ mask-image: radial-gradient(
24
+ ellipse 75% 75% at 50% 50%,
25
+ rgb(0 0 0 / 0.4) 0%,
26
+ black 100%
27
+ );
28
+ }
29
+ [data-background="circuit"] > [data-scene] :is(.cb-trace, .cb-pin, .cb-sig) {
30
+ fill: none;
31
+ stroke: var(--nxgt-bg-c1);
32
+ stroke-linecap: round;
33
+ stroke-linejoin: round;
34
+ }
35
+ [data-background="circuit"] > [data-scene] .cb-trace {
36
+ stroke-width: 2.2;
37
+ stroke-opacity: calc(var(--nxgt-bg-op) * 0.85);
38
+ }
39
+ [data-background="circuit"] > [data-scene] .cb-l1 {
40
+ stroke: var(--nxgt-bg-c1);
41
+ }
42
+ [data-background="circuit"] > [data-scene] .cb-l2 {
43
+ stroke: var(--nxgt-bg-c2);
44
+ }
45
+ [data-background="circuit"] > [data-scene] .cb-l3 {
46
+ stroke: var(--nxgt-bg-c3);
47
+ }
48
+ [data-background="circuit"] > [data-scene] .cb-pin {
49
+ stroke-width: 2.2;
50
+ stroke-opacity: calc(var(--nxgt-bg-op) * 0.85);
51
+ }
52
+ [data-background="circuit"] > [data-scene] .cb-chip {
53
+ fill: var(--nxgt-bg-c1);
54
+ fill-opacity: calc(var(--nxgt-bg-op) * 0.16);
55
+ stroke: var(--nxgt-bg-c1);
56
+ stroke-width: 2.2;
57
+ stroke-opacity: calc(var(--nxgt-bg-op) * 0.7);
58
+ }
59
+ [data-background="circuit"] > [data-scene] .cb-pad {
60
+ fill: var(--nxgt-bg-c1);
61
+ fill-opacity: calc(var(--nxgt-bg-op) * 0.2);
62
+ stroke: var(--nxgt-bg-c1);
63
+ stroke-width: 2.2;
64
+ stroke-opacity: calc(var(--nxgt-bg-op) * 0.8);
65
+ }
66
+ /* The signals are only drawn while they move (below). */
67
+ [data-background="circuit"] > [data-scene] .cb-signals {
68
+ display: none;
69
+ }
70
+ [data-background="circuit"] > [data-scene] .cb-sig {
71
+ stroke: color-mix(in oklab, var(--nxgt-bg-c2) 55%, white);
72
+ stroke-width: 3.4;
73
+ stroke-opacity: 0.9;
74
+ stroke-dashoffset: 14;
75
+ }
76
+ }
77
+
78
+ @media (prefers-reduced-motion: no-preference) {
79
+ /* The dash starts 14 units before the trace and runs 540 units, past the
80
+ * end of the longest one. */
81
+ @keyframes nxgt-bg-circuit-signal {
82
+ from {
83
+ stroke-dashoffset: 14;
84
+ }
85
+ to {
86
+ stroke-dashoffset: -540;
87
+ }
88
+ }
89
+
90
+ @layer components {
91
+ [data-background="circuit"][data-animated] > [data-scene] .cb-signals {
92
+ display: inline;
93
+ }
94
+ [data-background="circuit"][data-animated] > [data-scene] .cb-sig {
95
+ animation: nxgt-bg-circuit-signal 7s linear infinite
96
+ var(--nxgt-bg-play, running);
97
+ }
98
+ [data-background="circuit"][data-animated]
99
+ > [data-scene]
100
+ .cb-sig:nth-child(3n + 1) {
101
+ animation-duration: 9s;
102
+ animation-delay: -2s;
103
+ }
104
+ [data-background="circuit"][data-animated]
105
+ > [data-scene]
106
+ .cb-sig:nth-child(3n + 2) {
107
+ animation-duration: 11s;
108
+ animation-delay: -6s;
109
+ }
110
+ }
111
+ }
@@ -0,0 +1,41 @@
1
+ /* The `concrete` preset: poured concrete. A seeded mottle and small pores (an
2
+ * SVG of `feTurbulence` specks on a seamless 640 px tile: black in light,
3
+ * white in dark) over a cool grey tint that takes a little of the tone
4
+ * (`wash`). Intensity never goes above the default (`vivid` draws as the default). Static: `animated` does nothing. React only: nothing in the
5
+ * shared `css/` folder. */
6
+ @import "../css/scene.css";
7
+
8
+ @layer components {
9
+ /* `vivid` is capped at the default strength: a texture under body text
10
+ * never gets stronger (the tint and the specks read these two). */
11
+ [data-background="concrete"][data-intensity="vivid"][data-intensity] {
12
+ --nxgt-bg-a1: 8%;
13
+ --nxgt-bg-op: 0.72;
14
+ }
15
+ [data-background="concrete"] > [data-layer="wash"] {
16
+ position: absolute;
17
+ inset: 0;
18
+ background-image: linear-gradient(
19
+ 160deg,
20
+ color-mix(
21
+ in oklab,
22
+ var(--nxgt-bg-c1) var(--nxgt-bg-a1),
23
+ color-mix(in oklab, var(--foreground) 5%, transparent)
24
+ ),
25
+ color-mix(in oklab, var(--foreground) 3%, transparent)
26
+ );
27
+ }
28
+ [data-background="concrete"] > [data-scene] > svg {
29
+ filter: invert(var(--nxgt-bg-grain-invert));
30
+ opacity: calc(1 - var(--nxgt-bg-grain-invert) * 0.3);
31
+ }
32
+ [data-background="concrete"] > [data-scene] .tx1 {
33
+ opacity: calc(var(--nxgt-bg-op) * 0.12);
34
+ }
35
+ [data-background="concrete"] > [data-scene] .tx2 {
36
+ opacity: calc(var(--nxgt-bg-op) * 0.26);
37
+ }
38
+ [data-background="concrete"] > [data-scene] .tx3 {
39
+ opacity: calc(var(--nxgt-bg-op) * 0.12);
40
+ }
41
+ }
@@ -0,0 +1,48 @@
1
+ /* The `diagonal-checker` preset: the fine checkerboard turned 45 degrees
2
+ * (diamonds of c1 touching at their corners, c2 between them), in two tints
3
+ * that sit close together, fading out toward the edges, with a seeded sixth of
4
+ * the cells near the edges carrying a small tonal motif. One layer, the SVG
5
+ * scene (`dc-a` the diamonds, `dc-b` the corners, `dc-m` the motifs), with
6
+ * nothing over it. The scene covers the background, so the cells follow the
7
+ * viewport. React only: nothing in the shared `css/` folder. */
8
+ @import "../css/scene.css";
9
+
10
+ @layer components {
11
+ [data-background="diagonal-checker"] > [data-scene] .fade-1 {
12
+ stop-color: white;
13
+ }
14
+ [data-background="diagonal-checker"] > [data-scene] .fade-0 {
15
+ stop-color: black;
16
+ }
17
+ [data-background="diagonal-checker"] > [data-scene] .dc-a {
18
+ fill: var(--nxgt-bg-c1);
19
+ fill-opacity: calc(var(--nxgt-bg-op) * 0.11 * var(--nxgt-bg-iso-k));
20
+ }
21
+ [data-background="diagonal-checker"] > [data-scene] .dc-b {
22
+ fill: var(--nxgt-bg-c2);
23
+ fill-opacity: calc(var(--nxgt-bg-op) * 0.055 * var(--nxgt-bg-iso-k));
24
+ }
25
+ [data-background="diagonal-checker"] > [data-scene] .dc-m,
26
+ [data-background="diagonal-checker"] > [data-scene] .dc-p {
27
+ color: var(--nxgt-bg-c1);
28
+ stroke-opacity: 0.85;
29
+ fill-opacity: calc(0.4 * var(--nxgt-bg-iso-k));
30
+ }
31
+ }
32
+
33
+ @media (prefers-reduced-motion: no-preference) {
34
+ @keyframes nxgt-bg-diagonal-checker-drift {
35
+ to {
36
+ transform: translate(17px, 17px);
37
+ }
38
+ }
39
+
40
+ @layer components {
41
+ [data-background="diagonal-checker"][data-animated]
42
+ > [data-scene]
43
+ .dc-drift {
44
+ animation: nxgt-bg-diagonal-checker-drift 22s ease-in-out infinite
45
+ alternate var(--nxgt-bg-play, running);
46
+ }
47
+ }
48
+ }
@@ -0,0 +1,99 @@
1
+ /* The `glass` preset: frosted panes over soft colour. A background layer has
2
+ * no backdrop to blur, so the frost is faked: soft blobs (radial
3
+ * gradients in the tone's three colours, `gl-b`) under a grid of pale panes with a bright edge
4
+ * (`gl-p`, `gl-p1..3` for how frosted), over a tint (`wash`). Motion
5
+ * (opt-in, `animated`): the blobs drift behind the panes. React only: nothing
6
+ * in the shared `css/` folder. */
7
+ @import "../css/scene.css";
8
+
9
+ @layer components {
10
+ [data-background="glass"] > [data-layer="wash"] {
11
+ position: absolute;
12
+ inset: 0;
13
+ background-image: linear-gradient(
14
+ 135deg,
15
+ color-mix(in oklab, var(--nxgt-bg-c1) var(--nxgt-bg-a1), transparent),
16
+ color-mix(in oklab, var(--nxgt-bg-c2) var(--nxgt-bg-a1), transparent)
17
+ );
18
+ }
19
+ [data-background="glass"] > [data-scene] .gl-b {
20
+ fill-opacity: calc(var(--nxgt-bg-op) * 0.8);
21
+ }
22
+ [data-background="glass"] > [data-scene] .gl-p {
23
+ stroke: color-mix(in oklab, white 55%, transparent);
24
+ stroke-width: 1.5;
25
+ }
26
+ [data-background="glass"] > [data-scene] .gl-p1 {
27
+ fill: color-mix(in oklab, white 10%, transparent);
28
+ }
29
+ [data-background="glass"] > [data-scene] .gl-p2 {
30
+ fill: color-mix(in oklab, white 18%, transparent);
31
+ }
32
+ [data-background="glass"] > [data-scene] .gl-p3 {
33
+ fill: color-mix(in oklab, white 26%, transparent);
34
+ }
35
+ :is(.dark, [data-theme="dark"])
36
+ [data-background="glass"]
37
+ > [data-scene]
38
+ .gl-p,
39
+ [data-background="glass"]:is(.dark, [data-theme="dark"])
40
+ > [data-scene]
41
+ .gl-p {
42
+ stroke: color-mix(in oklab, white 22%, transparent);
43
+ }
44
+ :is(.dark, [data-theme="dark"])
45
+ [data-background="glass"]
46
+ > [data-scene]
47
+ .gl-p1,
48
+ [data-background="glass"]:is(.dark, [data-theme="dark"])
49
+ > [data-scene]
50
+ .gl-p1 {
51
+ fill: color-mix(in oklab, white 4%, transparent);
52
+ }
53
+ :is(.dark, [data-theme="dark"])
54
+ [data-background="glass"]
55
+ > [data-scene]
56
+ .gl-p2,
57
+ [data-background="glass"]:is(.dark, [data-theme="dark"])
58
+ > [data-scene]
59
+ .gl-p2 {
60
+ fill: color-mix(in oklab, white 8%, transparent);
61
+ }
62
+ :is(.dark, [data-theme="dark"])
63
+ [data-background="glass"]
64
+ > [data-scene]
65
+ .gl-p3,
66
+ [data-background="glass"]:is(.dark, [data-theme="dark"])
67
+ > [data-scene]
68
+ .gl-p3 {
69
+ fill: color-mix(in oklab, white 12%, transparent);
70
+ }
71
+ }
72
+
73
+ @media (prefers-reduced-motion: no-preference) {
74
+ @keyframes nxgt-bg-glass-drift {
75
+ from {
76
+ transform: translate(-90px, -40px);
77
+ }
78
+ to {
79
+ transform: translate(90px, 50px);
80
+ }
81
+ }
82
+
83
+ @layer components {
84
+ [data-background="glass"][data-animated] > [data-scene] .gl-d {
85
+ animation: nxgt-bg-glass-drift 26s ease-in-out infinite alternate
86
+ var(--nxgt-bg-play, running);
87
+ }
88
+ [data-background="glass"][data-animated] > [data-scene] .gl-d1 {
89
+ animation-direction: alternate;
90
+ }
91
+ [data-background="glass"][data-animated] > [data-scene] .gl-d2 {
92
+ animation-duration: 33s;
93
+ animation-direction: alternate-reverse;
94
+ }
95
+ [data-background="glass"][data-animated] > [data-scene] .gl-d3 {
96
+ animation-duration: 41s;
97
+ }
98
+ }
99
+ }
@@ -0,0 +1,74 @@
1
+ /* The `graph-paper` preset: a soft squared grid, 20 px cells with a line every
2
+ * fifth (100 px) barely stronger, drawn from the top left corner so every line
3
+ * lands on a whole pixel. Thin, pale lines in the tone's colour, fading out
4
+ * toward the edges, with fine line doodles (`gp-d`) in an SVG scene, sparse
5
+ * and none around the content. Layers: `wash` (a tint), `grid` and the scene.
6
+ * React only: nothing in the shared `css/` folder. */
7
+ @import "../css/scene.css";
8
+
9
+ @layer components {
10
+ [data-background="graph-paper"] > [data-layer="wash"] {
11
+ position: absolute;
12
+ inset: 0;
13
+ background-image: linear-gradient(
14
+ 180deg,
15
+ color-mix(in oklab, var(--nxgt-bg-c1) var(--nxgt-bg-a1), transparent),
16
+ transparent 70%
17
+ );
18
+ }
19
+ [data-background="graph-paper"] > [data-layer="grid"] {
20
+ --nxgt-bg-l1: color-mix(
21
+ in oklab,
22
+ var(--nxgt-bg-c1) calc(var(--nxgt-bg-a2) * 0.5),
23
+ transparent
24
+ );
25
+ --nxgt-bg-l2: color-mix(
26
+ in oklab,
27
+ var(--nxgt-bg-c1) calc(var(--nxgt-bg-a2) * 0.8),
28
+ transparent
29
+ );
30
+ position: absolute;
31
+ inset: 0;
32
+ background-image:
33
+ linear-gradient(to right, var(--nxgt-bg-l2) 1px, transparent 1px),
34
+ linear-gradient(to bottom, var(--nxgt-bg-l2) 1px, transparent 1px),
35
+ linear-gradient(to right, var(--nxgt-bg-l1) 1px, transparent 1px),
36
+ linear-gradient(to bottom, var(--nxgt-bg-l1) 1px, transparent 1px);
37
+ background-size:
38
+ 100px 100px,
39
+ 100px 100px,
40
+ 20px 20px,
41
+ 20px 20px;
42
+ background-position: 0 0;
43
+ -webkit-mask-image: radial-gradient(
44
+ ellipse 75% 70% at 50% 45%,
45
+ black 15%,
46
+ transparent 100%
47
+ );
48
+ mask-image: radial-gradient(
49
+ ellipse 75% 70% at 50% 45%,
50
+ black 15%,
51
+ transparent 100%
52
+ );
53
+ }
54
+ [data-background="graph-paper"] > [data-scene] .gp-d {
55
+ color: var(--nxgt-bg-c1);
56
+ opacity: calc(var(--nxgt-bg-op) * 0.7);
57
+ }
58
+ }
59
+
60
+ @media (prefers-reduced-motion: no-preference) {
61
+ /* One major cell (100 px, five minor ones), so the loop has no jump. */
62
+ @keyframes nxgt-bg-graph-paper-pan {
63
+ to {
64
+ background-position: 100px 100px;
65
+ }
66
+ }
67
+
68
+ @layer components {
69
+ [data-background="graph-paper"][data-animated] > [data-layer="grid"] {
70
+ animation: nxgt-bg-graph-paper-pan 24s linear infinite
71
+ var(--nxgt-bg-play, running);
72
+ }
73
+ }
74
+ }
@@ -0,0 +1,66 @@
1
+ /* The `halo` preset: a ring of light. A conic gradient through the tone's
2
+ * three colours, cut to a soft ring and blurred (`halo`, a square centred a
3
+ * little above the middle), over a tint (`wash`). CSS only. Blended with the
4
+ * page: it adds light in dark. Motion (opt-in, `animated`): the colours turn
5
+ * round the ring. React only: nothing in the shared `css/` folder. */
6
+ @layer components {
7
+ [data-background="halo"] {
8
+ overflow: clip;
9
+ isolation: isolate;
10
+ }
11
+ [data-background="halo"] > [data-layer="wash"] {
12
+ position: absolute;
13
+ inset: 0;
14
+ background-image: radial-gradient(
15
+ circle at 50% 44%,
16
+ color-mix(in oklab, var(--nxgt-bg-c1) var(--nxgt-bg-a2), transparent),
17
+ transparent 60%
18
+ );
19
+ }
20
+ [data-background="halo"] > [data-layer="halo"] {
21
+ position: absolute;
22
+ top: 44%;
23
+ left: 50%;
24
+ width: max(70vmin, 22rem);
25
+ aspect-ratio: 1 / 1;
26
+ margin: calc(max(70vmin, 22rem) / -2) 0 0 calc(max(70vmin, 22rem) / -2);
27
+ border-radius: 9999px;
28
+ opacity: var(--nxgt-bg-op);
29
+ mix-blend-mode: var(--nxgt-bg-glow-blend);
30
+ filter: blur(18px);
31
+ background-image: conic-gradient(
32
+ from 0deg,
33
+ var(--nxgt-bg-c1),
34
+ var(--nxgt-bg-c2),
35
+ var(--nxgt-bg-c3),
36
+ var(--nxgt-bg-c1)
37
+ );
38
+ -webkit-mask-image: radial-gradient(
39
+ closest-side,
40
+ transparent 56%,
41
+ black 72%,
42
+ transparent 90%
43
+ );
44
+ mask-image: radial-gradient(
45
+ closest-side,
46
+ transparent 56%,
47
+ black 72%,
48
+ transparent 90%
49
+ );
50
+ }
51
+ }
52
+
53
+ @media (prefers-reduced-motion: no-preference) {
54
+ @keyframes nxgt-bg-halo-turn {
55
+ to {
56
+ transform: rotate(360deg);
57
+ }
58
+ }
59
+
60
+ @layer components {
61
+ [data-background="halo"][data-animated] > [data-layer="halo"] {
62
+ animation: nxgt-bg-halo-turn 40s linear infinite
63
+ var(--nxgt-bg-play, running);
64
+ }
65
+ }
66
+ }
@@ -0,0 +1,79 @@
1
+ /* The `hexagons` preset: a honeycomb, fading out toward the edges, with a
2
+ * seeded tenth of its cells tinted. Layers: `wash` (a tint) and the SVG scene
3
+ * (`hx-line` the edges, `hx-lit` and `hx-lit1..3` the tinted cells in c1, c2
4
+ * and c3). React only: nothing in the shared `css/` folder. */
5
+ @import "../css/scene.css";
6
+
7
+ @layer components {
8
+ [data-background="hexagons"] > [data-layer="wash"] {
9
+ position: absolute;
10
+ inset: 0;
11
+ background-image: linear-gradient(
12
+ 180deg,
13
+ color-mix(in oklab, var(--nxgt-bg-c1) var(--nxgt-bg-a1), transparent),
14
+ transparent 70%
15
+ );
16
+ }
17
+ [data-background="hexagons"] > [data-scene] {
18
+ -webkit-mask-image: radial-gradient(
19
+ ellipse 80% 80% at 50% 50%,
20
+ rgb(0 0 0 / 0.45) 0%,
21
+ black 100%
22
+ );
23
+ mask-image: radial-gradient(
24
+ ellipse 80% 80% at 50% 50%,
25
+ rgb(0 0 0 / 0.45) 0%,
26
+ black 100%
27
+ );
28
+ }
29
+ [data-background="hexagons"] > [data-scene] .hx-line {
30
+ fill: none;
31
+ stroke: var(--nxgt-bg-c1);
32
+ stroke-width: 1.4;
33
+ stroke-linejoin: round;
34
+ stroke-opacity: calc(var(--nxgt-bg-op) * 0.65);
35
+ }
36
+ [data-background="hexagons"] > [data-scene] .hx-lit1 {
37
+ fill: var(--nxgt-bg-c1);
38
+ fill-opacity: calc(var(--nxgt-bg-op) * 0.2);
39
+ stroke: none;
40
+ }
41
+ [data-background="hexagons"] > [data-scene] .hx-lit2 {
42
+ fill: var(--nxgt-bg-c2);
43
+ fill-opacity: calc(var(--nxgt-bg-op) * 0.26);
44
+ }
45
+ [data-background="hexagons"] > [data-scene] .hx-lit3 {
46
+ fill: var(--nxgt-bg-c3);
47
+ fill-opacity: calc(var(--nxgt-bg-op) * 0.34);
48
+ }
49
+ }
50
+
51
+ @media (prefers-reduced-motion: no-preference) {
52
+ @keyframes nxgt-bg-hexagons-pulse {
53
+ from {
54
+ opacity: 1;
55
+ }
56
+ to {
57
+ opacity: 0.15;
58
+ }
59
+ }
60
+
61
+ @layer components {
62
+ [data-background="hexagons"][data-animated] > [data-scene] .hx-lit {
63
+ animation: nxgt-bg-hexagons-pulse 7s ease-in-out infinite alternate
64
+ var(--nxgt-bg-play, running);
65
+ }
66
+ [data-background="hexagons"][data-animated]
67
+ > [data-scene]
68
+ .hx-lit:nth-child(3n + 1) {
69
+ animation-duration: 9s;
70
+ animation-delay: -3s;
71
+ }
72
+ [data-background="hexagons"][data-animated]
73
+ > [data-scene]
74
+ .hx-lit:nth-child(3n + 2) {
75
+ animation-duration: 11s;
76
+ animation-delay: -7s;
77
+ }
78
+ }
79
+ }