@nazuraki/styles 0.2.3 → 0.3.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 (42) hide show
  1. package/all.css +10 -0
  2. package/luminous-precision/base.css +24 -16
  3. package/luminous-precision/components/alert.css +10 -10
  4. package/luminous-precision/components/badge.css +6 -6
  5. package/luminous-precision/components/button.css +19 -19
  6. package/luminous-precision/components/card.css +3 -3
  7. package/luminous-precision/components/dialog.css +4 -4
  8. package/luminous-precision/components/form.css +26 -26
  9. package/luminous-precision/components/link.css +4 -4
  10. package/luminous-precision/components/progress.css +7 -7
  11. package/luminous-precision/components/table.css +5 -5
  12. package/luminous-precision/components/tabs.css +6 -6
  13. package/luminous-precision/design.md +13 -0
  14. package/luminous-precision/tokens.css +27 -10
  15. package/manifest.json +23 -0
  16. package/neon-butterfly/base.css +23 -10
  17. package/neon-butterfly/components/alert.css +10 -10
  18. package/neon-butterfly/components/badge.css +6 -6
  19. package/neon-butterfly/components/button.css +11 -11
  20. package/neon-butterfly/components/card.css +3 -3
  21. package/neon-butterfly/components/dialog.css +4 -4
  22. package/neon-butterfly/components/form.css +26 -26
  23. package/neon-butterfly/components/link.css +8 -8
  24. package/neon-butterfly/components/progress.css +7 -7
  25. package/neon-butterfly/components/table.css +5 -5
  26. package/neon-butterfly/components/tabs.css +6 -6
  27. package/neon-butterfly/design.md +12 -0
  28. package/neon-butterfly/tokens.css +29 -2
  29. package/package.json +9 -2
  30. package/summer-cloud/base.css +23 -13
  31. package/summer-cloud/components/alert.css +10 -10
  32. package/summer-cloud/components/badge.css +10 -10
  33. package/summer-cloud/components/button.css +22 -22
  34. package/summer-cloud/components/card.css +7 -7
  35. package/summer-cloud/components/dialog.css +4 -4
  36. package/summer-cloud/components/form.css +31 -31
  37. package/summer-cloud/components/link.css +16 -16
  38. package/summer-cloud/components/progress.css +8 -8
  39. package/summer-cloud/components/table.css +7 -7
  40. package/summer-cloud/components/tabs.css +7 -7
  41. package/summer-cloud/design.md +13 -0
  42. package/summer-cloud/tokens.css +27 -8
package/manifest.json ADDED
@@ -0,0 +1,23 @@
1
+ {
2
+ "contract": 1,
3
+ "themes": {
4
+ "neon-butterfly": {
5
+ "scheme": "dark",
6
+ "fonts": [
7
+ "https://fonts.googleapis.com/css2?family=JetBrains+Mono:wght@450;700&display=swap"
8
+ ]
9
+ },
10
+ "summer-cloud": {
11
+ "scheme": "light",
12
+ "fonts": [
13
+ "https://fonts.googleapis.com/css2?family=Plus+Jakarta+Sans:wght@400;600;700;800&family=Inter:wght@400;600&family=JetBrains+Mono:wght@500;700&display=swap"
14
+ ]
15
+ },
16
+ "luminous-precision": {
17
+ "scheme": "dark",
18
+ "fonts": [
19
+ "https://fonts.googleapis.com/css2?family=Sora:wght@500;600;700&family=JetBrains+Mono:wght@400;600;700&display=swap"
20
+ ]
21
+ }
22
+ }
23
+ }
@@ -1,36 +1,49 @@
1
1
  /* neon-butterfly — base styles
2
- * Global defaults. Requires tokens.css. Apps that need the JetBrains Mono
2
+ * Scoped defaults. Requires tokens.css. Apps that need the JetBrains Mono
3
3
  * webfont should include the Google Fonts <link> (weights 450 + 700) or
4
4
  * self-host; the token stack falls back to ui-monospace.
5
+ *
6
+ * The element carrying data-nb-style is the theme's canvas: it gets the
7
+ * background, text color, and body font — whether that is <html> for a page
8
+ * or a mount container for an embedded island. Page-only rules (body margin,
9
+ * viewport height) apply only when the attribute sits on <html>.
5
10
  */
6
- *,
7
- *::before,
8
- *::after {
11
+ :where([data-nb-style="neon-butterfly"]) {
12
+ background-color: var(--nb-bg);
13
+ color: var(--nb-on-surface);
14
+ font-family: var(--nb-font-body);
15
+ font-weight: var(--nb-font-weight);
16
+ }
17
+
18
+ :where([data-nb-style="neon-butterfly"], [data-nb-style="neon-butterfly"] *),
19
+ :where([data-nb-style="neon-butterfly"], [data-nb-style="neon-butterfly"] *)::before,
20
+ :where([data-nb-style="neon-butterfly"], [data-nb-style="neon-butterfly"] *)::after {
9
21
  box-sizing: border-box;
10
22
  }
11
23
 
12
- body {
24
+ :where(html[data-nb-style="neon-butterfly"]) body {
13
25
  margin: 0;
14
26
  min-height: 100vh;
15
27
  background-color: var(--nb-bg);
16
28
  color: var(--nb-on-surface);
17
- font-family: var(--nb-font-mono);
29
+ font-family: var(--nb-font-body);
18
30
  font-weight: var(--nb-font-weight);
19
31
  }
20
32
 
21
33
  /* Opt-in page background: the butterfly circuit artwork blended into the navy.
22
- * Matches the switchboard landing page. Apply to <body>. */
23
- .nb-bg {
34
+ * Matches the switchboard landing page. Apply to <body>, or to the attributed
35
+ * container itself. */
36
+ :where([data-nb-style="neon-butterfly"], [data-nb-style="neon-butterfly"] *).nb-bg {
24
37
  background: var(--nb-bg) url("./assets/butterfly-circuit.png") center / cover fixed;
25
38
  background-blend-mode: luminosity;
26
39
  background-color: var(--nb-bg-blend);
27
40
  }
28
41
 
29
- a {
42
+ :where([data-nb-style="neon-butterfly"], [data-nb-style="neon-butterfly"] *):where(a) {
30
43
  color: var(--nb-primary);
31
44
  }
32
45
 
33
- ::selection {
46
+ :where([data-nb-style="neon-butterfly"], [data-nb-style="neon-butterfly"] *)::selection {
34
47
  background: var(--nb-primary);
35
48
  color: var(--nb-bg);
36
49
  }
@@ -1,5 +1,5 @@
1
1
  /* neon-butterfly — alert / callout */
2
- .nb-alert {
2
+ :where([data-nb-style="neon-butterfly"], [data-nb-style="neon-butterfly"] *).nb-alert {
3
3
  padding: var(--nb-space-3) var(--nb-space-4);
4
4
  background: var(--nb-surface-glass);
5
5
  border: 1px solid var(--nb-border);
@@ -9,18 +9,18 @@
9
9
  color: var(--nb-on-surface);
10
10
  font-size: var(--nb-text-sm);
11
11
  }
12
- .nb-alert--info { border-left-color: var(--nb-info); }
13
- .nb-alert--success { border-left-color: var(--nb-success); }
14
- .nb-alert--warning { border-left-color: var(--nb-warning); }
15
- .nb-alert--danger { border-left-color: var(--nb-danger); }
16
- .nb-alert__title {
12
+ :where([data-nb-style="neon-butterfly"], [data-nb-style="neon-butterfly"] *).nb-alert--info { border-left-color: var(--nb-info); }
13
+ :where([data-nb-style="neon-butterfly"], [data-nb-style="neon-butterfly"] *).nb-alert--success { border-left-color: var(--nb-success); }
14
+ :where([data-nb-style="neon-butterfly"], [data-nb-style="neon-butterfly"] *).nb-alert--warning { border-left-color: var(--nb-warning); }
15
+ :where([data-nb-style="neon-butterfly"], [data-nb-style="neon-butterfly"] *).nb-alert--danger { border-left-color: var(--nb-danger); }
16
+ :where([data-nb-style="neon-butterfly"], [data-nb-style="neon-butterfly"] *).nb-alert__title {
17
17
  display: block;
18
18
  margin-bottom: var(--nb-space-1);
19
19
  text-transform: uppercase;
20
20
  font-weight: var(--nb-font-weight-bold);
21
21
  letter-spacing: var(--nb-tracking-wide);
22
22
  }
23
- .nb-alert--info .nb-alert__title { color: var(--nb-info); }
24
- .nb-alert--success .nb-alert__title { color: var(--nb-success); }
25
- .nb-alert--warning .nb-alert__title { color: var(--nb-warning); }
26
- .nb-alert--danger .nb-alert__title { color: var(--nb-danger); }
23
+ :where([data-nb-style="neon-butterfly"], [data-nb-style="neon-butterfly"] *).nb-alert--info .nb-alert__title { color: var(--nb-info); }
24
+ :where([data-nb-style="neon-butterfly"], [data-nb-style="neon-butterfly"] *).nb-alert--success .nb-alert__title { color: var(--nb-success); }
25
+ :where([data-nb-style="neon-butterfly"], [data-nb-style="neon-butterfly"] *).nb-alert--warning .nb-alert__title { color: var(--nb-warning); }
26
+ :where([data-nb-style="neon-butterfly"], [data-nb-style="neon-butterfly"] *).nb-alert--danger .nb-alert__title { color: var(--nb-danger); }
@@ -1,5 +1,5 @@
1
1
  /* neon-butterfly — badge */
2
- .nb-badge {
2
+ :where([data-nb-style="neon-butterfly"], [data-nb-style="neon-butterfly"] *).nb-badge {
3
3
  display: inline-block;
4
4
  padding: 0.15rem var(--nb-space-2);
5
5
  border: 1px solid var(--nb-border);
@@ -10,8 +10,8 @@
10
10
  font-weight: var(--nb-font-weight-bold);
11
11
  letter-spacing: var(--nb-tracking-wide);
12
12
  }
13
- .nb-badge--primary { border-color: var(--nb-primary-border); color: var(--nb-primary); }
14
- .nb-badge--info { border-color: var(--nb-info); color: var(--nb-info); }
15
- .nb-badge--success { border-color: var(--nb-success); color: var(--nb-success); }
16
- .nb-badge--warning { border-color: var(--nb-warning); color: var(--nb-warning); }
17
- .nb-badge--danger { border-color: var(--nb-danger); color: var(--nb-danger); }
13
+ :where([data-nb-style="neon-butterfly"], [data-nb-style="neon-butterfly"] *).nb-badge--primary { border-color: var(--nb-primary-border); color: var(--nb-primary); }
14
+ :where([data-nb-style="neon-butterfly"], [data-nb-style="neon-butterfly"] *).nb-badge--info { border-color: var(--nb-info); color: var(--nb-info); }
15
+ :where([data-nb-style="neon-butterfly"], [data-nb-style="neon-butterfly"] *).nb-badge--success { border-color: var(--nb-success); color: var(--nb-success); }
16
+ :where([data-nb-style="neon-butterfly"], [data-nb-style="neon-butterfly"] *).nb-badge--warning { border-color: var(--nb-warning); color: var(--nb-warning); }
17
+ :where([data-nb-style="neon-butterfly"], [data-nb-style="neon-butterfly"] *).nb-badge--danger { border-color: var(--nb-danger); color: var(--nb-danger); }
@@ -1,5 +1,5 @@
1
1
  /* neon-butterfly — button */
2
- .nb-btn {
2
+ :where([data-nb-style="neon-butterfly"], [data-nb-style="neon-butterfly"] *).nb-btn {
3
3
  display: inline-flex;
4
4
  align-items: center;
5
5
  gap: var(--nb-space-2);
@@ -18,37 +18,37 @@
18
18
  border-color var(--nb-transition),
19
19
  color var(--nb-transition);
20
20
  }
21
- .nb-btn:hover,
22
- .nb-btn:focus-visible {
21
+ :where([data-nb-style="neon-butterfly"], [data-nb-style="neon-butterfly"] *).nb-btn:hover,
22
+ :where([data-nb-style="neon-butterfly"], [data-nb-style="neon-butterfly"] *).nb-btn:focus-visible {
23
23
  border-color: var(--nb-primary-border);
24
24
  color: var(--nb-primary);
25
- animation: nb-pulse-glow 2s infinite;
25
+ animation: nb-nb-pulse-glow 2s infinite;
26
26
  outline: none;
27
27
  }
28
- .nb-btn--primary {
28
+ :where([data-nb-style="neon-butterfly"], [data-nb-style="neon-butterfly"] *).nb-btn--primary {
29
29
  border-color: var(--nb-primary-border);
30
30
  color: var(--nb-primary);
31
31
  }
32
- .nb-btn--accent {
32
+ :where([data-nb-style="neon-butterfly"], [data-nb-style="neon-butterfly"] *).nb-btn--accent {
33
33
  border-color: var(--nb-accent);
34
34
  color: var(--nb-accent);
35
35
  }
36
- .nb-btn--danger {
36
+ :where([data-nb-style="neon-butterfly"], [data-nb-style="neon-butterfly"] *).nb-btn--danger {
37
37
  border-color: var(--nb-danger);
38
38
  color: var(--nb-danger);
39
39
  }
40
- .nb-btn:disabled {
40
+ :where([data-nb-style="neon-butterfly"], [data-nb-style="neon-butterfly"] *).nb-btn:disabled {
41
41
  opacity: 0.5;
42
42
  cursor: not-allowed;
43
43
  animation: none;
44
44
  }
45
45
 
46
46
  @media (prefers-reduced-motion: reduce) {
47
- .nb-btn {
47
+ :where([data-nb-style="neon-butterfly"], [data-nb-style="neon-butterfly"] *).nb-btn {
48
48
  transition: none;
49
49
  }
50
- .nb-btn:hover,
51
- .nb-btn:focus-visible {
50
+ :where([data-nb-style="neon-butterfly"], [data-nb-style="neon-butterfly"] *).nb-btn:hover,
51
+ :where([data-nb-style="neon-butterfly"], [data-nb-style="neon-butterfly"] *).nb-btn:focus-visible {
52
52
  animation: none;
53
53
  }
54
54
  }
@@ -1,5 +1,5 @@
1
1
  /* neon-butterfly — card */
2
- .nb-card {
2
+ :where([data-nb-style="neon-butterfly"], [data-nb-style="neon-butterfly"] *).nb-card {
3
3
  padding: var(--nb-space-4);
4
4
  background: var(--nb-surface-glass);
5
5
  border: 1px solid var(--nb-border);
@@ -7,5 +7,5 @@
7
7
  backdrop-filter: blur(var(--nb-blur));
8
8
  color: var(--nb-on-surface);
9
9
  }
10
- .nb-card > :first-child { margin-top: 0; }
11
- .nb-card > :last-child { margin-bottom: 0; }
10
+ :where([data-nb-style="neon-butterfly"], [data-nb-style="neon-butterfly"] *).nb-card > :first-child { margin-top: 0; }
11
+ :where([data-nb-style="neon-butterfly"], [data-nb-style="neon-butterfly"] *).nb-card > :last-child { margin-bottom: 0; }
@@ -1,5 +1,5 @@
1
1
  /* neon-butterfly — dialog (native <dialog>) */
2
- .nb-dialog {
2
+ :where([data-nb-style="neon-butterfly"], [data-nb-style="neon-butterfly"] *).nb-dialog {
3
3
  padding: var(--nb-space-4);
4
4
  max-width: 32rem;
5
5
  width: calc(100vw - 2rem);
@@ -10,18 +10,18 @@
10
10
  font-family: var(--nb-font-mono);
11
11
  box-shadow: 0 0 30px rgba(210, 187, 255, 0.25);
12
12
  }
13
- .nb-dialog::backdrop {
13
+ :where([data-nb-style="neon-butterfly"], [data-nb-style="neon-butterfly"] *).nb-dialog::backdrop {
14
14
  background: rgba(11, 19, 38, 0.7);
15
15
  backdrop-filter: blur(4px);
16
16
  }
17
- .nb-dialog__title {
17
+ :where([data-nb-style="neon-butterfly"], [data-nb-style="neon-butterfly"] *).nb-dialog__title {
18
18
  margin: 0 0 var(--nb-space-3);
19
19
  color: var(--nb-primary);
20
20
  text-transform: uppercase;
21
21
  font-size: 1rem;
22
22
  letter-spacing: var(--nb-tracking-wide);
23
23
  }
24
- .nb-dialog__actions {
24
+ :where([data-nb-style="neon-butterfly"], [data-nb-style="neon-butterfly"] *).nb-dialog__actions {
25
25
  display: flex;
26
26
  justify-content: flex-end;
27
27
  gap: var(--nb-space-2);
@@ -1,7 +1,7 @@
1
1
  /* neon-butterfly — form controls: input, textarea, select, checkbox, radio, switch */
2
- .nb-input,
3
- .nb-select,
4
- .nb-textarea {
2
+ :where([data-nb-style="neon-butterfly"], [data-nb-style="neon-butterfly"] *).nb-input,
3
+ :where([data-nb-style="neon-butterfly"], [data-nb-style="neon-butterfly"] *).nb-select,
4
+ :where([data-nb-style="neon-butterfly"], [data-nb-style="neon-butterfly"] *).nb-textarea {
5
5
  display: block;
6
6
  width: 100%;
7
7
  padding: var(--nb-space-2) var(--nb-space-3);
@@ -14,30 +14,30 @@
14
14
  font-size: var(--nb-text-sm);
15
15
  transition: border-color var(--nb-transition), box-shadow var(--nb-transition);
16
16
  }
17
- .nb-select {
17
+ :where([data-nb-style="neon-butterfly"], [data-nb-style="neon-butterfly"] *).nb-select {
18
18
  appearance: none;
19
19
  padding-right: 2.25rem;
20
20
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='10' height='6' viewBox='0 0 10 6'%3E%3Cpath d='M1 1l4 4 4-4' fill='none' stroke='%23958da1' stroke-width='1.5'/%3E%3C/svg%3E");
21
21
  background-repeat: no-repeat;
22
22
  background-position: right 0.75rem center;
23
23
  }
24
- .nb-input::placeholder,
25
- .nb-textarea::placeholder {
24
+ :where([data-nb-style="neon-butterfly"], [data-nb-style="neon-butterfly"] *).nb-input::placeholder,
25
+ :where([data-nb-style="neon-butterfly"], [data-nb-style="neon-butterfly"] *).nb-textarea::placeholder {
26
26
  color: var(--nb-faint);
27
27
  }
28
- .nb-input:focus,
29
- .nb-select:focus,
30
- .nb-textarea:focus {
28
+ :where([data-nb-style="neon-butterfly"], [data-nb-style="neon-butterfly"] *).nb-input:focus,
29
+ :where([data-nb-style="neon-butterfly"], [data-nb-style="neon-butterfly"] *).nb-select:focus,
30
+ :where([data-nb-style="neon-butterfly"], [data-nb-style="neon-butterfly"] *).nb-textarea:focus {
31
31
  outline: none;
32
32
  border-color: var(--nb-primary-border);
33
33
  box-shadow: 0 0 8px rgba(210, 187, 255, 0.3);
34
34
  }
35
- .nb-input[aria-invalid="true"],
36
- .nb-textarea[aria-invalid="true"] {
35
+ :where([data-nb-style="neon-butterfly"], [data-nb-style="neon-butterfly"] *).nb-input[aria-invalid="true"],
36
+ :where([data-nb-style="neon-butterfly"], [data-nb-style="neon-butterfly"] *).nb-textarea[aria-invalid="true"] {
37
37
  border-color: var(--nb-danger);
38
38
  }
39
39
 
40
- .nb-label {
40
+ :where([data-nb-style="neon-butterfly"], [data-nb-style="neon-butterfly"] *).nb-label {
41
41
  display: block;
42
42
  margin-bottom: var(--nb-space-1);
43
43
  color: var(--nb-faint);
@@ -47,13 +47,13 @@
47
47
  letter-spacing: var(--nb-tracking-wide);
48
48
  }
49
49
 
50
- .nb-field {
50
+ :where([data-nb-style="neon-butterfly"], [data-nb-style="neon-butterfly"] *).nb-field {
51
51
  margin-bottom: var(--nb-space-3);
52
52
  }
53
53
 
54
54
  /* checkbox & radio */
55
- .nb-checkbox,
56
- .nb-radio {
55
+ :where([data-nb-style="neon-butterfly"], [data-nb-style="neon-butterfly"] *).nb-checkbox,
56
+ :where([data-nb-style="neon-butterfly"], [data-nb-style="neon-butterfly"] *).nb-radio {
57
57
  appearance: none;
58
58
  width: 1.1rem;
59
59
  height: 1.1rem;
@@ -65,22 +65,22 @@
65
65
  cursor: pointer;
66
66
  transition: border-color var(--nb-transition), box-shadow var(--nb-transition);
67
67
  }
68
- .nb-radio {
68
+ :where([data-nb-style="neon-butterfly"], [data-nb-style="neon-butterfly"] *).nb-radio {
69
69
  border-radius: 50%;
70
70
  }
71
- .nb-checkbox:checked,
72
- .nb-radio:checked {
71
+ :where([data-nb-style="neon-butterfly"], [data-nb-style="neon-butterfly"] *).nb-checkbox:checked,
72
+ :where([data-nb-style="neon-butterfly"], [data-nb-style="neon-butterfly"] *).nb-radio:checked {
73
73
  border-color: var(--nb-accent);
74
74
  box-shadow: inset 0 0 0 3px var(--nb-surface), inset 0 0 0 1rem var(--nb-accent),
75
75
  0 0 6px var(--nb-accent-glow);
76
76
  }
77
- .nb-checkbox:focus-visible,
78
- .nb-radio:focus-visible,
79
- .nb-switch:focus-visible {
77
+ :where([data-nb-style="neon-butterfly"], [data-nb-style="neon-butterfly"] *).nb-checkbox:focus-visible,
78
+ :where([data-nb-style="neon-butterfly"], [data-nb-style="neon-butterfly"] *).nb-radio:focus-visible,
79
+ :where([data-nb-style="neon-butterfly"], [data-nb-style="neon-butterfly"] *).nb-switch:focus-visible {
80
80
  outline: none;
81
81
  border-color: var(--nb-primary-border);
82
82
  }
83
- .nb-choice {
83
+ :where([data-nb-style="neon-butterfly"], [data-nb-style="neon-butterfly"] *).nb-choice {
84
84
  display: inline-flex;
85
85
  align-items: center;
86
86
  gap: var(--nb-space-2);
@@ -90,7 +90,7 @@
90
90
  }
91
91
 
92
92
  /* switch */
93
- .nb-switch {
93
+ :where([data-nb-style="neon-butterfly"], [data-nb-style="neon-butterfly"] *).nb-switch {
94
94
  appearance: none;
95
95
  width: 2.4rem;
96
96
  height: 1.3rem;
@@ -103,7 +103,7 @@
103
103
  position: relative;
104
104
  transition: border-color var(--nb-transition);
105
105
  }
106
- .nb-switch::after {
106
+ :where([data-nb-style="neon-butterfly"], [data-nb-style="neon-butterfly"] *).nb-switch::after {
107
107
  content: "";
108
108
  position: absolute;
109
109
  top: 2px;
@@ -114,10 +114,10 @@
114
114
  background: var(--nb-faint);
115
115
  transition: transform var(--nb-transition), background var(--nb-transition);
116
116
  }
117
- .nb-switch:checked {
117
+ :where([data-nb-style="neon-butterfly"], [data-nb-style="neon-butterfly"] *).nb-switch:checked {
118
118
  border-color: var(--nb-accent);
119
119
  }
120
- .nb-switch:checked::after {
120
+ :where([data-nb-style="neon-butterfly"], [data-nb-style="neon-butterfly"] *).nb-switch:checked::after {
121
121
  transform: translateX(1.1rem);
122
122
  background: var(--nb-accent);
123
123
  box-shadow: 0 0 6px var(--nb-accent-glow);
@@ -1,5 +1,5 @@
1
1
  /* neon-butterfly — nav link: uppercase mono link with ">" chevron and glow hover */
2
- .nb-link {
2
+ :where([data-nb-style="neon-butterfly"], [data-nb-style="neon-butterfly"] *).nb-link {
3
3
  display: flex;
4
4
  align-items: baseline;
5
5
  gap: var(--nb-space-3);
@@ -19,23 +19,23 @@
19
19
  color var(--nb-transition),
20
20
  transform var(--nb-transition);
21
21
  }
22
- .nb-link::before {
22
+ :where([data-nb-style="neon-butterfly"], [data-nb-style="neon-butterfly"] *).nb-link::before {
23
23
  content: ">";
24
24
  color: var(--nb-faint);
25
25
  transition: color var(--nb-transition);
26
26
  }
27
- .nb-link:hover {
27
+ :where([data-nb-style="neon-butterfly"], [data-nb-style="neon-butterfly"] *).nb-link:hover {
28
28
  border-color: var(--nb-primary-border);
29
29
  color: var(--nb-primary);
30
30
  transform: translateX(4px);
31
- animation: nb-pulse-glow 2s infinite;
31
+ animation: nb-nb-pulse-glow 2s infinite;
32
32
  }
33
- .nb-link:hover::before {
33
+ :where([data-nb-style="neon-butterfly"], [data-nb-style="neon-butterfly"] *).nb-link:hover::before {
34
34
  color: var(--nb-accent);
35
35
  text-shadow: 0 0 5px var(--nb-accent-glow);
36
36
  }
37
37
 
38
- @keyframes nb-pulse-glow {
38
+ @keyframes nb-nb-pulse-glow {
39
39
  0%,
40
40
  100% {
41
41
  box-shadow: 0 0 5px rgba(210, 187, 255, 0.2);
@@ -46,10 +46,10 @@
46
46
  }
47
47
 
48
48
  @media (prefers-reduced-motion: reduce) {
49
- .nb-link {
49
+ :where([data-nb-style="neon-butterfly"], [data-nb-style="neon-butterfly"] *).nb-link {
50
50
  transition: none;
51
51
  }
52
- .nb-link:hover {
52
+ :where([data-nb-style="neon-butterfly"], [data-nb-style="neon-butterfly"] *).nb-link:hover {
53
53
  animation: none;
54
54
  }
55
55
  }
@@ -1,5 +1,5 @@
1
1
  /* neon-butterfly — progress bar & spinner */
2
- .nb-progress {
2
+ :where([data-nb-style="neon-butterfly"], [data-nb-style="neon-butterfly"] *).nb-progress {
3
3
  display: block;
4
4
  width: 100%;
5
5
  height: 0.5rem;
@@ -8,34 +8,34 @@
8
8
  border-radius: 1rem;
9
9
  overflow: hidden;
10
10
  }
11
- .nb-progress__bar {
11
+ :where([data-nb-style="neon-butterfly"], [data-nb-style="neon-butterfly"] *).nb-progress__bar {
12
12
  height: 100%;
13
13
  background: var(--nb-primary);
14
14
  box-shadow: 0 0 8px var(--nb-primary-glow);
15
15
  border-radius: 1rem;
16
16
  transition: width var(--nb-transition);
17
17
  }
18
- .nb-progress__bar--accent {
18
+ :where([data-nb-style="neon-butterfly"], [data-nb-style="neon-butterfly"] *).nb-progress__bar--accent {
19
19
  background: var(--nb-accent);
20
20
  box-shadow: 0 0 8px var(--nb-accent-glow);
21
21
  }
22
22
 
23
- .nb-spinner {
23
+ :where([data-nb-style="neon-butterfly"], [data-nb-style="neon-butterfly"] *).nb-spinner {
24
24
  display: inline-block;
25
25
  width: 1.5rem;
26
26
  height: 1.5rem;
27
27
  border: 2px solid var(--nb-border);
28
28
  border-top-color: var(--nb-primary);
29
29
  border-radius: 50%;
30
- animation: nb-spin 0.8s linear infinite;
30
+ animation: nb-nb-spin 0.8s linear infinite;
31
31
  }
32
- @keyframes nb-spin {
32
+ @keyframes nb-nb-spin {
33
33
  to {
34
34
  transform: rotate(360deg);
35
35
  }
36
36
  }
37
37
  @media (prefers-reduced-motion: reduce) {
38
- .nb-spinner {
38
+ :where([data-nb-style="neon-butterfly"], [data-nb-style="neon-butterfly"] *).nb-spinner {
39
39
  animation-duration: 2s;
40
40
  }
41
41
  }
@@ -1,11 +1,11 @@
1
1
  /* neon-butterfly — table */
2
- .nb-table {
2
+ :where([data-nb-style="neon-butterfly"], [data-nb-style="neon-butterfly"] *).nb-table {
3
3
  width: 100%;
4
4
  border-collapse: collapse;
5
5
  font-size: var(--nb-text-sm);
6
6
  color: var(--nb-on-surface);
7
7
  }
8
- .nb-table th {
8
+ :where([data-nb-style="neon-butterfly"], [data-nb-style="neon-butterfly"] *).nb-table th {
9
9
  padding: var(--nb-space-2) var(--nb-space-3);
10
10
  border-bottom: 1px solid var(--nb-primary-border);
11
11
  color: var(--nb-faint);
@@ -15,13 +15,13 @@
15
15
  font-weight: var(--nb-font-weight-bold);
16
16
  letter-spacing: var(--nb-tracking-wide);
17
17
  }
18
- .nb-table td {
18
+ :where([data-nb-style="neon-butterfly"], [data-nb-style="neon-butterfly"] *).nb-table td {
19
19
  padding: var(--nb-space-2) var(--nb-space-3);
20
20
  border-bottom: 1px solid var(--nb-border);
21
21
  }
22
- .nb-table tbody tr {
22
+ :where([data-nb-style="neon-butterfly"], [data-nb-style="neon-butterfly"] *).nb-table tbody tr {
23
23
  transition: background var(--nb-transition);
24
24
  }
25
- .nb-table tbody tr:hover {
25
+ :where([data-nb-style="neon-butterfly"], [data-nb-style="neon-butterfly"] *).nb-table tbody tr:hover {
26
26
  background: var(--nb-surface-glass);
27
27
  }
@@ -1,10 +1,10 @@
1
1
  /* neon-butterfly — tabs */
2
- .nb-tabs {
2
+ :where([data-nb-style="neon-butterfly"], [data-nb-style="neon-butterfly"] *).nb-tabs {
3
3
  display: flex;
4
4
  gap: var(--nb-space-2);
5
5
  border-bottom: 1px solid var(--nb-border);
6
6
  }
7
- .nb-tab {
7
+ :where([data-nb-style="neon-butterfly"], [data-nb-style="neon-butterfly"] *).nb-tab {
8
8
  padding: var(--nb-space-2) var(--nb-space-3);
9
9
  margin-bottom: -1px;
10
10
  background: none;
@@ -19,15 +19,15 @@
19
19
  cursor: pointer;
20
20
  transition: color var(--nb-transition), border-color var(--nb-transition);
21
21
  }
22
- .nb-tab:hover {
22
+ :where([data-nb-style="neon-butterfly"], [data-nb-style="neon-butterfly"] *).nb-tab:hover {
23
23
  color: var(--nb-on-surface);
24
24
  }
25
- .nb-tab--active,
26
- .nb-tab[aria-selected="true"] {
25
+ :where([data-nb-style="neon-butterfly"], [data-nb-style="neon-butterfly"] *).nb-tab--active,
26
+ :where([data-nb-style="neon-butterfly"], [data-nb-style="neon-butterfly"] *).nb-tab[aria-selected="true"] {
27
27
  color: var(--nb-primary);
28
28
  border-bottom-color: var(--nb-primary);
29
29
  text-shadow: 0 0 8px var(--nb-primary-glow);
30
30
  }
31
- .nb-tabpanel {
31
+ :where([data-nb-style="neon-butterfly"], [data-nb-style="neon-butterfly"] *).nb-tabpanel {
32
32
  padding: var(--nb-space-3) 0;
33
33
  }
@@ -60,3 +60,15 @@ Class prefix `nb-`. Variants use BEM-ish modifiers (`nb-btn--accent`).
60
60
  - **Tabs** `.nb-tabs`/`.nb-tab`/`.nb-tabpanel` — active tab underlined in lilac with text glow.
61
61
  - **Table** `.nb-table` — lilac header rule, glass row hover.
62
62
  - **Progress** `.nb-progress`, **Spinner** `.nb-spinner` — glowing lilac indicators.
63
+
64
+ ## Code syntax
65
+
66
+ Tokens `--nb-code-*`, part of the baseline contract. Lilac keywords, neon-lime
67
+ strings, gold numbers, info-cyan functions, light-cyan types, softened-pink
68
+ variables, dimmed-faint comments, faint meta.
69
+
70
+ ## Scoping
71
+
72
+ Every rule is guarded by `data-nb-style="neon-butterfly"` (self or ancestor),
73
+ wrapped in zero-specificity `:where()`. Set the attribute on `<html>` for a
74
+ page or on a container for an embedded island.
@@ -2,21 +2,34 @@
2
2
  * Source of truth for the neon-butterfly theme. Consume via:
3
3
  * @import "@nazuraki/styles/neon-butterfly/tokens";
4
4
  * or pull the whole theme with ./index.css.
5
+ *
6
+ * Nothing applies until an element carries data-nb-style="neon-butterfly"
7
+ * — set it on <html> for a page, or on any container for an embedded island.
8
+ * The :where() keeps specificity at zero, so any consumer rule overrides.
9
+ *
10
+ * Every theme declares the same baseline token set (styles/test enforces
11
+ * parity); names marked (extra) are additions beyond it that only this
12
+ * theme's own component CSS may rely on.
5
13
  */
6
- :root {
14
+ :where([data-nb-style="neon-butterfly"]) {
15
+ color-scheme: dark;
16
+
7
17
  /* color */
8
18
  --nb-bg: #0b1326;
9
19
  --nb-bg-blend: #1a1f2e;
10
20
  --nb-surface: #171f33;
21
+ --nb-surface-sunken: #0e1526; /* inset fields */
11
22
  --nb-surface-glass: rgba(23, 31, 51, 0.55);
12
23
  --nb-on-surface: #dae2fd;
13
24
  --nb-faint: #958da1;
14
25
  --nb-primary: #d2bbff;
15
26
  --nb-primary-glow: rgba(210, 187, 255, 0.6);
16
27
  --nb-primary-border: rgba(210, 187, 255, 0.8);
28
+ --nb-on-primary: #0b1326; /* text on solid lilac fills */
17
29
  --nb-accent: #39ff14;
18
30
  --nb-accent-glow: rgba(57, 255, 20, 0.5);
19
31
  --nb-border: rgba(255, 255, 255, 0.1);
32
+ --nb-border-lit: rgba(255, 255, 255, 0.25); /* lit top edge of glass panes */
20
33
 
21
34
  /* semantic color */
22
35
  --nb-info: #4dc9ff;
@@ -24,15 +37,29 @@
24
37
  --nb-warning: #ffd23f;
25
38
  --nb-danger: #ff2d78;
26
39
 
27
- /* typography */
40
+ /* code syntax — lilac keywords, neon strings, palette-derived accents */
41
+ --nb-code-keyword: #d2bbff;
42
+ --nb-code-string: #39ff14;
43
+ --nb-code-number: #ffd23f;
44
+ --nb-code-comment: #8a8199;
45
+ --nb-code-function: #4dc9ff;
46
+ --nb-code-variable: #ff6ba0;
47
+ --nb-code-type: #7fdcff;
48
+ --nb-code-meta: #958da1;
49
+
50
+ /* typography — all-mono aesthetic: display and body share the mono stack */
51
+ --nb-font-display: "JetBrains Mono", ui-monospace, SFMono-Regular, Menlo, monospace;
52
+ --nb-font-body: "JetBrains Mono", ui-monospace, SFMono-Regular, Menlo, monospace;
28
53
  --nb-font-mono: "JetBrains Mono", ui-monospace, SFMono-Regular, Menlo, monospace;
29
54
  --nb-font-weight: 450;
55
+ --nb-font-weight-medium: 700; /* only 450 + 700 webfont weights load */
30
56
  --nb-font-weight-bold: 700;
31
57
  --nb-text-sm: 14px;
32
58
  --nb-tracking-wide: 0.1em;
33
59
 
34
60
  /* shape & effects */
35
61
  --nb-radius: 0.5rem;
62
+ --nb-radius-lg: 0.5rem; /* one radius everywhere is the look */
36
63
  --nb-blur: 12px;
37
64
  --nb-transition: 0.3s;
38
65
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nazuraki/styles",
3
- "version": "0.2.3",
3
+ "version": "0.3.0",
4
4
  "description": "Shared design-system styles: tokens, base styles, and component classes per theme.",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -11,12 +11,19 @@
11
11
  "publishConfig": {
12
12
  "access": "public"
13
13
  },
14
+ "scripts": {
15
+ "test": "node --test"
16
+ },
14
17
  "files": [
15
18
  "neon-butterfly",
16
19
  "summer-cloud",
17
- "luminous-precision"
20
+ "luminous-precision",
21
+ "all.css",
22
+ "manifest.json"
18
23
  ],
19
24
  "exports": {
25
+ "./all": "./all.css",
26
+ "./manifest": "./manifest.json",
20
27
  "./neon-butterfly": "./neon-butterfly/index.css",
21
28
  "./neon-butterfly/tokens": "./neon-butterfly/tokens.css",
22
29
  "./neon-butterfly/base": "./neon-butterfly/base.css",