@nxgt/material 3.3.0 → 3.4.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 (71) hide show
  1. package/CHANGELOG.md +23 -0
  2. package/README.md +3 -3
  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/lib/backgrounds/background/available.d.ts +3 -3
  31. package/dist/lib/backgrounds/background/background.d.ts +2 -2
  32. package/dist/lib/backgrounds/index.d.ts +1 -1
  33. package/dist/material.css +1 -1
  34. package/docs/components/navigation-and-layout.md +1 -1
  35. package/docs/getting-started.md +1 -1
  36. package/docs/guides/backgrounds.md +94 -16
  37. package/docs/previews/backgrounds-geometry-more.webp +0 -0
  38. package/docs/previews/backgrounds-illustrated-scenes.webp +0 -0
  39. package/docs/previews/backgrounds-light-more.webp +0 -0
  40. package/docs/previews/backgrounds-material-more.webp +0 -0
  41. package/docs/previews/backgrounds-matrix.webp +0 -0
  42. package/docs/previews/backgrounds-motif-shapes.webp +0 -0
  43. package/docs/roadmap.md +16 -4
  44. package/docs/troubleshooting.md +2 -2
  45. package/lib/backgrounds/backgrounds.css +30 -1
  46. package/lib/backgrounds/css-react/blobs.css +65 -0
  47. package/lib/backgrounds/css-react/bubbles.css +41 -0
  48. package/lib/backgrounds/css-react/checker.css +47 -0
  49. package/lib/backgrounds/css-react/chevrons.css +46 -0
  50. package/lib/backgrounds/css-react/circuit.css +111 -0
  51. package/lib/backgrounds/css-react/concrete.css +41 -0
  52. package/lib/backgrounds/css-react/diagonal-checker.css +48 -0
  53. package/lib/backgrounds/css-react/glass.css +99 -0
  54. package/lib/backgrounds/css-react/graph-paper.css +74 -0
  55. package/lib/backgrounds/css-react/halo.css +66 -0
  56. package/lib/backgrounds/css-react/hexagons.css +79 -0
  57. package/lib/backgrounds/css-react/illustrated.css +164 -0
  58. package/lib/backgrounds/css-react/leaves.css +41 -0
  59. package/lib/backgrounds/css-react/linen.css +44 -0
  60. package/lib/backgrounds/css-react/marble.css +55 -0
  61. package/lib/backgrounds/css-react/music.css +2 -0
  62. package/lib/backgrounds/css-react/night-sky.css +41 -0
  63. package/lib/backgrounds/css-react/paper.css +49 -0
  64. package/lib/backgrounds/css-react/plasma.css +53 -0
  65. package/lib/backgrounds/css-react/rays.css +67 -0
  66. package/lib/backgrounds/css-react/ripples.css +68 -0
  67. package/lib/backgrounds/css-react/school.css +2 -0
  68. package/lib/backgrounds/css-react/science.css +2 -0
  69. package/lib/backgrounds/css-react/sport.css +2 -0
  70. package/lib/backgrounds/css-react/travel.css +2 -0
  71. package/package.json +103 -2
@@ -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
+ }
@@ -0,0 +1,164 @@
1
+ /* The illustrated scenes' shared parts (`school`, `night-sky`, `bubbles`,
2
+ * `leaves`, `science`, `music`, `travel`, `sport`): a faint colour wash under
3
+ * the scene, and the scene itself, fine line drawings (`il` is the root; every
4
+ * path is stroked in `currentColor`, which a `k1..k3` class sets) kept calm in
5
+ * the middle of the frame by a mask, where the content sits. The scene is the
6
+ * one drawn by core's `buildBackgroundScene`. React only: nothing in the shared
7
+ * `css/` folder. Intensity never goes above the default (`vivid` draws as the default). Each preset's file imports this one. */
8
+ @import "../css/scene.css";
9
+
10
+ @layer components {
11
+ /* `vivid` is capped at the default strength: drawings under body text
12
+ * never get stronger (the wash and the strokes read these variables).
13
+ * Three attributes (0,3,0) beat tones.css's (0,2,0) in any import order. */
14
+ :is(
15
+ [data-background="school"],
16
+ [data-background="night-sky"],
17
+ [data-background="bubbles"],
18
+ [data-background="leaves"],
19
+ [data-background="science"],
20
+ [data-background="music"],
21
+ [data-background="travel"],
22
+ [data-background="sport"]
23
+ )[data-intensity="vivid"][data-intensity] {
24
+ --nxgt-bg-a1: 8%;
25
+ --nxgt-bg-a2: 16%;
26
+ --nxgt-bg-a3: 28%;
27
+ --nxgt-bg-op: 0.72;
28
+ }
29
+
30
+ /* The wash: two soft colour pools under the scene. */
31
+ :is(
32
+ [data-background="school"],
33
+ [data-background="night-sky"],
34
+ [data-background="bubbles"],
35
+ [data-background="leaves"],
36
+ [data-background="science"],
37
+ [data-background="music"],
38
+ [data-background="travel"],
39
+ [data-background="sport"]
40
+ ) > [data-layer="wash"] {
41
+ position: absolute;
42
+ inset: 0;
43
+ background:
44
+ radial-gradient(
45
+ ellipse 70% 60% at 22% 18%,
46
+ color-mix(in oklab, var(--nxgt-bg-c1) var(--nxgt-bg-a1), transparent),
47
+ transparent 72%
48
+ ),
49
+ radial-gradient(
50
+ ellipse 60% 55% at 85% 92%,
51
+ color-mix(in oklab, var(--nxgt-bg-c3) var(--nxgt-bg-a1), transparent),
52
+ transparent 70%
53
+ );
54
+ }
55
+
56
+ :is(
57
+ [data-background="school"],
58
+ [data-background="night-sky"],
59
+ [data-background="bubbles"],
60
+ [data-background="leaves"],
61
+ [data-background="science"],
62
+ [data-background="music"],
63
+ [data-background="travel"],
64
+ [data-background="sport"]
65
+ )
66
+ > [data-scene] {
67
+ overflow: hidden;
68
+ }
69
+
70
+ /* The middle stays calm: the mask is in pixels, not in percent of the
71
+ * frame, so the quiet zone always covers a card of content (a percentage
72
+ * would shrink it on a phone). It passes 7 to 9% of the drawings, which
73
+ * keeps 14 px muted text at 4.5:1 or better over the worst stroke pixel. */
74
+ :is(
75
+ [data-background="school"],
76
+ [data-background="night-sky"],
77
+ [data-background="bubbles"],
78
+ [data-background="leaves"],
79
+ [data-background="science"],
80
+ [data-background="music"],
81
+ [data-background="travel"],
82
+ [data-background="sport"]
83
+ )
84
+ > [data-scene]
85
+ .mo {
86
+ opacity: calc(var(--nxgt-bg-op) + 0.2);
87
+ }
88
+ :is(
89
+ [data-background="school"],
90
+ [data-background="night-sky"],
91
+ [data-background="bubbles"],
92
+ [data-background="leaves"],
93
+ [data-background="science"],
94
+ [data-background="music"],
95
+ [data-background="travel"],
96
+ [data-background="sport"]
97
+ )
98
+ > [data-scene]
99
+ > .il {
100
+ -webkit-mask-image: radial-gradient(
101
+ ellipse 380px 290px at 50% 50%,
102
+ rgb(0 0 0 / 0.07) 0%,
103
+ rgb(0 0 0 / 0.09) 55%,
104
+ rgb(0 0 0 / 0.5) 80%,
105
+ black 100%
106
+ );
107
+ mask-image: radial-gradient(
108
+ ellipse 380px 290px at 50% 50%,
109
+ rgb(0 0 0 / 0.07) 0%,
110
+ rgb(0 0 0 / 0.09) 55%,
111
+ rgb(0 0 0 / 0.5) 80%,
112
+ black 100%
113
+ );
114
+ }
115
+ /* A phone: the card fills the width, so the zone is a band across it. */
116
+ @media (max-width: 640px) {
117
+ :is(
118
+ [data-background="school"],
119
+ [data-background="night-sky"],
120
+ [data-background="bubbles"],
121
+ [data-background="leaves"],
122
+ [data-background="science"],
123
+ [data-background="music"],
124
+ [data-background="travel"],
125
+ [data-background="sport"]
126
+ )
127
+ > [data-scene]
128
+ > .il {
129
+ -webkit-mask-image: radial-gradient(
130
+ ellipse 420px 170px at 50% 50%,
131
+ rgb(0 0 0 / 0.07) 0%,
132
+ rgb(0 0 0 / 0.09) 55%,
133
+ rgb(0 0 0 / 0.5) 80%,
134
+ black 100%
135
+ );
136
+ mask-image: radial-gradient(
137
+ ellipse 420px 170px at 50% 50%,
138
+ rgb(0 0 0 / 0.07) 0%,
139
+ rgb(0 0 0 / 0.09) 55%,
140
+ rgb(0 0 0 / 0.5) 80%,
141
+ black 100%
142
+ );
143
+ }
144
+ }
145
+
146
+ :is(
147
+ [data-background="school"],
148
+ [data-background="night-sky"],
149
+ [data-background="bubbles"],
150
+ [data-background="leaves"],
151
+ [data-background="science"],
152
+ [data-background="music"],
153
+ [data-background="travel"],
154
+ [data-background="sport"]
155
+ )
156
+ > [data-scene]
157
+ > .il
158
+ path {
159
+ fill: none;
160
+ stroke: currentColor;
161
+ stroke-linecap: round;
162
+ stroke-linejoin: round;
163
+ }
164
+ }