@nazuraki/styles 0.2.2 → 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 (43) hide show
  1. package/all.css +10 -0
  2. package/luminous-precision/base.css +58 -0
  3. package/luminous-precision/components/alert.css +26 -0
  4. package/luminous-precision/components/badge.css +19 -0
  5. package/luminous-precision/components/button.css +88 -0
  6. package/luminous-precision/components/card.css +12 -0
  7. package/luminous-precision/components/dialog.css +31 -0
  8. package/luminous-precision/components/form.css +126 -0
  9. package/luminous-precision/components/link.css +46 -0
  10. package/luminous-precision/components/progress.css +41 -0
  11. package/luminous-precision/components/table.css +28 -0
  12. package/luminous-precision/components/tabs.css +33 -0
  13. package/luminous-precision/design.md +89 -0
  14. package/luminous-precision/index.css +13 -0
  15. package/luminous-precision/tokens.css +72 -0
  16. package/manifest.json +23 -0
  17. package/neon-butterfly/base.css +23 -10
  18. package/neon-butterfly/components/alert.css +10 -10
  19. package/neon-butterfly/components/badge.css +6 -6
  20. package/neon-butterfly/components/button.css +11 -11
  21. package/neon-butterfly/components/card.css +3 -3
  22. package/neon-butterfly/components/dialog.css +4 -4
  23. package/neon-butterfly/components/form.css +26 -26
  24. package/neon-butterfly/components/link.css +8 -8
  25. package/neon-butterfly/components/progress.css +7 -7
  26. package/neon-butterfly/components/table.css +5 -5
  27. package/neon-butterfly/components/tabs.css +6 -6
  28. package/neon-butterfly/design.md +12 -0
  29. package/neon-butterfly/tokens.css +29 -2
  30. package/package.json +15 -3
  31. package/summer-cloud/base.css +23 -13
  32. package/summer-cloud/components/alert.css +10 -10
  33. package/summer-cloud/components/badge.css +10 -10
  34. package/summer-cloud/components/button.css +22 -22
  35. package/summer-cloud/components/card.css +7 -7
  36. package/summer-cloud/components/dialog.css +4 -4
  37. package/summer-cloud/components/form.css +31 -31
  38. package/summer-cloud/components/link.css +16 -16
  39. package/summer-cloud/components/progress.css +8 -8
  40. package/summer-cloud/components/table.css +7 -7
  41. package/summer-cloud/components/tabs.css +7 -7
  42. package/summer-cloud/design.md +13 -0
  43. package/summer-cloud/tokens.css +27 -8
package/all.css ADDED
@@ -0,0 +1,10 @@
1
+ /* @nazuraki/styles — every theme in one import.
2
+ *
3
+ * Safe to load together: every rule in every theme is guarded by its
4
+ * data-nb-style attribute value, so nothing applies until an element opts in.
5
+ * Use this in apps that switch themes at runtime; single-theme apps should
6
+ * import just their theme's index.css.
7
+ */
8
+ @import "./neon-butterfly/index.css";
9
+ @import "./summer-cloud/index.css";
10
+ @import "./luminous-precision/index.css";
@@ -0,0 +1,58 @@
1
+ /* luminous-precision — base styles
2
+ * Scoped defaults. Requires tokens.css. Apps that need webfonts should
3
+ * include the Google Fonts <link>s for Sora (500, 600, 700) and
4
+ * JetBrains Mono (400, 600, 700) or self-host; the token stacks fall back
5
+ * to system families.
6
+ *
7
+ * The element carrying data-nb-style is the theme's canvas: it gets the
8
+ * background, text color, and body font — whether that is <html> for a page
9
+ * or a mount container for an embedded island. Page-only rules (body margin,
10
+ * viewport height) apply only when the attribute sits on <html>.
11
+ */
12
+ :where([data-nb-style="luminous-precision"]) {
13
+ background-color: var(--nb-bg);
14
+ color: var(--nb-on-surface);
15
+ font-family: var(--nb-font-body);
16
+ font-weight: var(--nb-font-weight);
17
+ }
18
+
19
+ :where([data-nb-style="luminous-precision"], [data-nb-style="luminous-precision"] *),
20
+ :where([data-nb-style="luminous-precision"], [data-nb-style="luminous-precision"] *)::before,
21
+ :where([data-nb-style="luminous-precision"], [data-nb-style="luminous-precision"] *)::after {
22
+ box-sizing: border-box;
23
+ }
24
+
25
+ :where(html[data-nb-style="luminous-precision"]) body {
26
+ margin: 0;
27
+ min-height: 100vh;
28
+ background-color: var(--nb-bg);
29
+ color: var(--nb-on-surface);
30
+ font-family: var(--nb-font-body);
31
+ font-weight: var(--nb-font-weight);
32
+ }
33
+
34
+ /* Opt-in page background: soft out-of-focus orchid/teal underlays over the
35
+ * obsidian base — the "luminous underlay" treatment. Apply to <body>, or to
36
+ * the attributed container itself. */
37
+ :where([data-nb-style="luminous-precision"], [data-nb-style="luminous-precision"] *).nb-bg {
38
+ background:
39
+ radial-gradient(50rem 30rem at 12% -5%, rgba(198, 165, 255, 0.08), transparent 70%),
40
+ radial-gradient(55rem 35rem at 90% 105%, rgba(0, 245, 255, 0.05), transparent 70%),
41
+ var(--nb-bg);
42
+ background-attachment: fixed;
43
+ }
44
+
45
+ :where([data-nb-style="luminous-precision"], [data-nb-style="luminous-precision"] *):where(h1, h2, h3, h4, h5, h6) {
46
+ font-family: var(--nb-font-display);
47
+ font-weight: var(--nb-font-weight-medium);
48
+ letter-spacing: -0.01em;
49
+ }
50
+
51
+ :where([data-nb-style="luminous-precision"], [data-nb-style="luminous-precision"] *):where(a) {
52
+ color: var(--nb-primary);
53
+ }
54
+
55
+ :where([data-nb-style="luminous-precision"], [data-nb-style="luminous-precision"] *)::selection {
56
+ background: var(--nb-primary);
57
+ color: var(--nb-bg);
58
+ }
@@ -0,0 +1,26 @@
1
+ /* luminous-precision — alert / callout */
2
+ :where([data-nb-style="luminous-precision"], [data-nb-style="luminous-precision"] *).nb-alert {
3
+ padding: var(--nb-space-3) var(--nb-space-4);
4
+ background: var(--nb-surface-glass);
5
+ border: 1px solid var(--nb-border);
6
+ border-left-width: 3px;
7
+ border-radius: var(--nb-radius);
8
+ backdrop-filter: blur(var(--nb-blur));
9
+ color: var(--nb-on-surface);
10
+ font-size: var(--nb-text-sm);
11
+ }
12
+ :where([data-nb-style="luminous-precision"], [data-nb-style="luminous-precision"] *).nb-alert--info { border-left-color: var(--nb-info); }
13
+ :where([data-nb-style="luminous-precision"], [data-nb-style="luminous-precision"] *).nb-alert--success { border-left-color: var(--nb-success); }
14
+ :where([data-nb-style="luminous-precision"], [data-nb-style="luminous-precision"] *).nb-alert--warning { border-left-color: var(--nb-warning); }
15
+ :where([data-nb-style="luminous-precision"], [data-nb-style="luminous-precision"] *).nb-alert--danger { border-left-color: var(--nb-danger); }
16
+ :where([data-nb-style="luminous-precision"], [data-nb-style="luminous-precision"] *).nb-alert__title {
17
+ display: block;
18
+ margin-bottom: var(--nb-space-1);
19
+ text-transform: uppercase;
20
+ font-weight: var(--nb-font-weight-medium);
21
+ letter-spacing: var(--nb-tracking-wide);
22
+ }
23
+ :where([data-nb-style="luminous-precision"], [data-nb-style="luminous-precision"] *).nb-alert--info .nb-alert__title { color: var(--nb-info); }
24
+ :where([data-nb-style="luminous-precision"], [data-nb-style="luminous-precision"] *).nb-alert--success .nb-alert__title { color: var(--nb-success); }
25
+ :where([data-nb-style="luminous-precision"], [data-nb-style="luminous-precision"] *).nb-alert--warning .nb-alert__title { color: var(--nb-warning); }
26
+ :where([data-nb-style="luminous-precision"], [data-nb-style="luminous-precision"] *).nb-alert--danger .nb-alert__title { color: var(--nb-danger); }
@@ -0,0 +1,19 @@
1
+ /* luminous-precision — badge: pill chip, 15% tint of its hue behind
2
+ * full-saturation text */
3
+ :where([data-nb-style="luminous-precision"], [data-nb-style="luminous-precision"] *).nb-badge {
4
+ display: inline-block;
5
+ padding: 0.15rem var(--nb-space-2);
6
+ background: rgba(255, 255, 255, 0.08);
7
+ border: none;
8
+ border-radius: 9999px;
9
+ color: var(--nb-faint);
10
+ text-transform: uppercase;
11
+ font-size: 11px;
12
+ font-weight: var(--nb-font-weight-medium);
13
+ letter-spacing: var(--nb-tracking-wide);
14
+ }
15
+ :where([data-nb-style="luminous-precision"], [data-nb-style="luminous-precision"] *).nb-badge--primary { background: rgba(198, 165, 255, 0.15); color: var(--nb-primary); }
16
+ :where([data-nb-style="luminous-precision"], [data-nb-style="luminous-precision"] *).nb-badge--info { background: rgba(131, 183, 255, 0.15); color: var(--nb-info); }
17
+ :where([data-nb-style="luminous-precision"], [data-nb-style="luminous-precision"] *).nb-badge--success { background: rgba(71, 227, 78, 0.15); color: var(--nb-success); }
18
+ :where([data-nb-style="luminous-precision"], [data-nb-style="luminous-precision"] *).nb-badge--warning { background: rgba(255, 184, 108, 0.15); color: var(--nb-warning); }
19
+ :where([data-nb-style="luminous-precision"], [data-nb-style="luminous-precision"] *).nb-badge--danger { background: rgba(255, 77, 109, 0.15); color: var(--nb-danger); }
@@ -0,0 +1,88 @@
1
+ /* luminous-precision — button */
2
+ :where([data-nb-style="luminous-precision"], [data-nb-style="luminous-precision"] *).nb-btn {
3
+ display: inline-flex;
4
+ align-items: center;
5
+ gap: var(--nb-space-2);
6
+ padding: var(--nb-space-2) var(--nb-space-3);
7
+ background: transparent;
8
+ border: 1px solid var(--nb-border-lit);
9
+ border-radius: var(--nb-radius);
10
+ color: var(--nb-on-surface);
11
+ text-transform: uppercase;
12
+ font-family: var(--nb-font-mono);
13
+ font-weight: var(--nb-font-weight-medium);
14
+ font-size: var(--nb-text-sm);
15
+ letter-spacing: var(--nb-tracking-wide);
16
+ cursor: pointer;
17
+ transition:
18
+ border-color var(--nb-transition),
19
+ color var(--nb-transition),
20
+ box-shadow var(--nb-transition);
21
+ }
22
+ :where([data-nb-style="luminous-precision"], [data-nb-style="luminous-precision"] *).nb-btn:hover,
23
+ :where([data-nb-style="luminous-precision"], [data-nb-style="luminous-precision"] *).nb-btn:focus-visible {
24
+ border-color: var(--nb-primary-border);
25
+ color: var(--nb-primary);
26
+ animation: nb-lp-pulse-glow 2s infinite;
27
+ outline: none;
28
+ }
29
+
30
+ /* primary: solid orchid fill, dark text, glow pulse on hover */
31
+ :where([data-nb-style="luminous-precision"], [data-nb-style="luminous-precision"] *).nb-btn--primary {
32
+ background: var(--nb-primary);
33
+ border-color: var(--nb-primary);
34
+ color: var(--nb-on-primary);
35
+ }
36
+ :where([data-nb-style="luminous-precision"], [data-nb-style="luminous-precision"] *).nb-btn--primary:hover,
37
+ :where([data-nb-style="luminous-precision"], [data-nb-style="luminous-precision"] *).nb-btn--primary:focus-visible {
38
+ border-color: var(--nb-primary);
39
+ color: var(--nb-on-primary);
40
+ }
41
+
42
+ /* accent: teal ghost — critical navigation paths */
43
+ :where([data-nb-style="luminous-precision"], [data-nb-style="luminous-precision"] *).nb-btn--accent {
44
+ border-color: var(--nb-accent);
45
+ color: var(--nb-accent);
46
+ }
47
+ :where([data-nb-style="luminous-precision"], [data-nb-style="luminous-precision"] *).nb-btn--accent:hover,
48
+ :where([data-nb-style="luminous-precision"], [data-nb-style="luminous-precision"] *).nb-btn--accent:focus-visible {
49
+ border-color: var(--nb-accent);
50
+ color: var(--nb-accent);
51
+ animation-name: nb-lp-pulse-glow-accent;
52
+ }
53
+
54
+ :where([data-nb-style="luminous-precision"], [data-nb-style="luminous-precision"] *).nb-btn--danger {
55
+ border-color: var(--nb-danger);
56
+ color: var(--nb-danger);
57
+ }
58
+ :where([data-nb-style="luminous-precision"], [data-nb-style="luminous-precision"] *).nb-btn--danger:hover,
59
+ :where([data-nb-style="luminous-precision"], [data-nb-style="luminous-precision"] *).nb-btn--danger:focus-visible {
60
+ border-color: var(--nb-danger);
61
+ color: var(--nb-danger);
62
+ }
63
+
64
+ :where([data-nb-style="luminous-precision"], [data-nb-style="luminous-precision"] *).nb-btn:disabled {
65
+ opacity: 0.5;
66
+ cursor: not-allowed;
67
+ animation: none;
68
+ }
69
+
70
+ @keyframes nb-lp-pulse-glow-accent {
71
+ 0%,
72
+ 100% {
73
+ box-shadow: 0 0 5px rgba(0, 245, 255, 0.15);
74
+ }
75
+ 50% {
76
+ box-shadow: 0 0 20px var(--nb-accent-glow);
77
+ }
78
+ }
79
+
80
+ @media (prefers-reduced-motion: reduce) {
81
+ :where([data-nb-style="luminous-precision"], [data-nb-style="luminous-precision"] *).nb-btn {
82
+ transition: none;
83
+ }
84
+ :where([data-nb-style="luminous-precision"], [data-nb-style="luminous-precision"] *).nb-btn:hover,
85
+ :where([data-nb-style="luminous-precision"], [data-nb-style="luminous-precision"] *).nb-btn:focus-visible {
86
+ animation: none;
87
+ }
88
+ }
@@ -0,0 +1,12 @@
1
+ /* luminous-precision — card: glass pane with a lit top edge */
2
+ :where([data-nb-style="luminous-precision"], [data-nb-style="luminous-precision"] *).nb-card {
3
+ padding: var(--nb-space-4);
4
+ background: var(--nb-surface-glass);
5
+ border: 1px solid var(--nb-border);
6
+ border-top-color: var(--nb-border-lit);
7
+ border-radius: var(--nb-radius-lg);
8
+ backdrop-filter: blur(var(--nb-blur));
9
+ color: var(--nb-on-surface);
10
+ }
11
+ :where([data-nb-style="luminous-precision"], [data-nb-style="luminous-precision"] *).nb-card > :first-child { margin-top: 0; }
12
+ :where([data-nb-style="luminous-precision"], [data-nb-style="luminous-precision"] *).nb-card > :last-child { margin-bottom: 0; }
@@ -0,0 +1,31 @@
1
+ /* luminous-precision — dialog (native <dialog>) */
2
+ :where([data-nb-style="luminous-precision"], [data-nb-style="luminous-precision"] *).nb-dialog {
3
+ padding: var(--nb-space-4);
4
+ max-width: 32rem;
5
+ width: calc(100vw - 2rem);
6
+ background: var(--nb-surface);
7
+ border: 1px solid var(--nb-border);
8
+ border-top-color: var(--nb-border-lit);
9
+ border-radius: var(--nb-radius-lg);
10
+ color: var(--nb-on-surface);
11
+ font-family: var(--nb-font-mono);
12
+ box-shadow: 0 0 40px var(--nb-primary-glow);
13
+ }
14
+ :where([data-nb-style="luminous-precision"], [data-nb-style="luminous-precision"] *).nb-dialog::backdrop {
15
+ background: rgba(10, 12, 16, 0.6);
16
+ backdrop-filter: blur(var(--nb-blur));
17
+ }
18
+ :where([data-nb-style="luminous-precision"], [data-nb-style="luminous-precision"] *).nb-dialog__title {
19
+ margin: 0 0 var(--nb-space-3);
20
+ color: var(--nb-primary);
21
+ font-family: var(--nb-font-display);
22
+ font-size: 1.25rem;
23
+ font-weight: var(--nb-font-weight-medium);
24
+ letter-spacing: -0.01em;
25
+ }
26
+ :where([data-nb-style="luminous-precision"], [data-nb-style="luminous-precision"] *).nb-dialog__actions {
27
+ display: flex;
28
+ justify-content: flex-end;
29
+ gap: var(--nb-space-2);
30
+ margin-top: var(--nb-space-4);
31
+ }
@@ -0,0 +1,126 @@
1
+ /* luminous-precision — form controls: input, textarea, select, checkbox,
2
+ * radio, switch. Focus drops the resting border for an electric-teal line
3
+ * with a soft outer glow. */
4
+ :where([data-nb-style="luminous-precision"], [data-nb-style="luminous-precision"] *).nb-input,
5
+ :where([data-nb-style="luminous-precision"], [data-nb-style="luminous-precision"] *).nb-select,
6
+ :where([data-nb-style="luminous-precision"], [data-nb-style="luminous-precision"] *).nb-textarea {
7
+ display: block;
8
+ width: 100%;
9
+ padding: var(--nb-space-2) var(--nb-space-3);
10
+ background: rgba(26, 29, 41, 0.6);
11
+ border: 1px solid var(--nb-border);
12
+ border-radius: var(--nb-radius);
13
+ color: var(--nb-on-surface);
14
+ font-family: var(--nb-font-mono);
15
+ font-weight: var(--nb-font-weight);
16
+ font-size: var(--nb-text-sm);
17
+ transition: border-color var(--nb-transition), box-shadow var(--nb-transition);
18
+ }
19
+ :where([data-nb-style="luminous-precision"], [data-nb-style="luminous-precision"] *).nb-select {
20
+ appearance: none;
21
+ padding-right: 2.25rem;
22
+ 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='%23958e9b' stroke-width='1.5'/%3E%3C/svg%3E");
23
+ background-repeat: no-repeat;
24
+ background-position: right 0.75rem center;
25
+ }
26
+ :where([data-nb-style="luminous-precision"], [data-nb-style="luminous-precision"] *).nb-input::placeholder,
27
+ :where([data-nb-style="luminous-precision"], [data-nb-style="luminous-precision"] *).nb-textarea::placeholder {
28
+ color: var(--nb-faint);
29
+ }
30
+ :where([data-nb-style="luminous-precision"], [data-nb-style="luminous-precision"] *).nb-input:focus,
31
+ :where([data-nb-style="luminous-precision"], [data-nb-style="luminous-precision"] *).nb-select:focus,
32
+ :where([data-nb-style="luminous-precision"], [data-nb-style="luminous-precision"] *).nb-textarea:focus {
33
+ outline: none;
34
+ border-color: var(--nb-accent);
35
+ box-shadow: 0 0 8px var(--nb-accent-glow);
36
+ }
37
+ :where([data-nb-style="luminous-precision"], [data-nb-style="luminous-precision"] *).nb-input[aria-invalid="true"],
38
+ :where([data-nb-style="luminous-precision"], [data-nb-style="luminous-precision"] *).nb-textarea[aria-invalid="true"] {
39
+ border-color: var(--nb-danger);
40
+ }
41
+
42
+ :where([data-nb-style="luminous-precision"], [data-nb-style="luminous-precision"] *).nb-label {
43
+ display: block;
44
+ margin-bottom: var(--nb-space-1);
45
+ color: var(--nb-faint);
46
+ text-transform: uppercase;
47
+ font-size: 12px;
48
+ font-weight: var(--nb-font-weight-medium);
49
+ letter-spacing: var(--nb-tracking-wide);
50
+ }
51
+
52
+ :where([data-nb-style="luminous-precision"], [data-nb-style="luminous-precision"] *).nb-field {
53
+ margin-bottom: var(--nb-space-3);
54
+ }
55
+
56
+ /* checkbox & radio */
57
+ :where([data-nb-style="luminous-precision"], [data-nb-style="luminous-precision"] *).nb-checkbox,
58
+ :where([data-nb-style="luminous-precision"], [data-nb-style="luminous-precision"] *).nb-radio {
59
+ appearance: none;
60
+ width: 1.1rem;
61
+ height: 1.1rem;
62
+ margin: 0;
63
+ vertical-align: text-bottom;
64
+ background: var(--nb-surface);
65
+ border: 1px solid var(--nb-border-lit);
66
+ border-radius: 0.25rem;
67
+ cursor: pointer;
68
+ transition: border-color var(--nb-transition), box-shadow var(--nb-transition);
69
+ }
70
+ :where([data-nb-style="luminous-precision"], [data-nb-style="luminous-precision"] *).nb-radio {
71
+ border-radius: 50%;
72
+ }
73
+ :where([data-nb-style="luminous-precision"], [data-nb-style="luminous-precision"] *).nb-checkbox:checked,
74
+ :where([data-nb-style="luminous-precision"], [data-nb-style="luminous-precision"] *).nb-radio:checked {
75
+ border-color: var(--nb-accent);
76
+ box-shadow: inset 0 0 0 3px var(--nb-surface), inset 0 0 0 1rem var(--nb-accent),
77
+ 0 0 6px var(--nb-accent-glow);
78
+ }
79
+ :where([data-nb-style="luminous-precision"], [data-nb-style="luminous-precision"] *).nb-checkbox:focus-visible,
80
+ :where([data-nb-style="luminous-precision"], [data-nb-style="luminous-precision"] *).nb-radio:focus-visible,
81
+ :where([data-nb-style="luminous-precision"], [data-nb-style="luminous-precision"] *).nb-switch:focus-visible {
82
+ outline: none;
83
+ border-color: var(--nb-primary-border);
84
+ }
85
+ :where([data-nb-style="luminous-precision"], [data-nb-style="luminous-precision"] *).nb-choice {
86
+ display: inline-flex;
87
+ align-items: center;
88
+ gap: var(--nb-space-2);
89
+ color: var(--nb-on-surface);
90
+ font-size: var(--nb-text-sm);
91
+ cursor: pointer;
92
+ }
93
+
94
+ /* switch */
95
+ :where([data-nb-style="luminous-precision"], [data-nb-style="luminous-precision"] *).nb-switch {
96
+ appearance: none;
97
+ width: 2.4rem;
98
+ height: 1.3rem;
99
+ margin: 0;
100
+ vertical-align: text-bottom;
101
+ background: var(--nb-surface);
102
+ border: 1px solid var(--nb-border-lit);
103
+ border-radius: 1rem;
104
+ cursor: pointer;
105
+ position: relative;
106
+ transition: border-color var(--nb-transition);
107
+ }
108
+ :where([data-nb-style="luminous-precision"], [data-nb-style="luminous-precision"] *).nb-switch::after {
109
+ content: "";
110
+ position: absolute;
111
+ top: 2px;
112
+ left: 2px;
113
+ width: calc(1.3rem - 6px);
114
+ height: calc(1.3rem - 6px);
115
+ border-radius: 50%;
116
+ background: var(--nb-faint);
117
+ transition: transform var(--nb-transition), background var(--nb-transition);
118
+ }
119
+ :where([data-nb-style="luminous-precision"], [data-nb-style="luminous-precision"] *).nb-switch:checked {
120
+ border-color: var(--nb-accent);
121
+ }
122
+ :where([data-nb-style="luminous-precision"], [data-nb-style="luminous-precision"] *).nb-switch:checked::after {
123
+ transform: translateX(1.1rem);
124
+ background: var(--nb-accent);
125
+ box-shadow: 0 0 6px var(--nb-accent-glow);
126
+ }
@@ -0,0 +1,46 @@
1
+ /* luminous-precision — nav link: glass list row; hover shifts the indigo and
2
+ * lights a 2px electric-teal bar on the left edge */
3
+ :where([data-nb-style="luminous-precision"], [data-nb-style="luminous-precision"] *).nb-link {
4
+ display: flex;
5
+ align-items: baseline;
6
+ gap: var(--nb-space-3);
7
+ padding: 1rem var(--nb-space-4);
8
+ background: var(--nb-surface-glass);
9
+ border: 1px solid var(--nb-border);
10
+ border-radius: var(--nb-radius);
11
+ backdrop-filter: blur(var(--nb-blur));
12
+ color: var(--nb-on-surface);
13
+ text-decoration: none;
14
+ text-transform: uppercase;
15
+ font-weight: var(--nb-font-weight-medium);
16
+ font-size: var(--nb-text-sm);
17
+ letter-spacing: var(--nb-tracking-wide);
18
+ box-shadow: inset 0 0 0 0 var(--nb-accent);
19
+ transition:
20
+ background var(--nb-transition),
21
+ color var(--nb-transition),
22
+ box-shadow var(--nb-transition);
23
+ }
24
+ :where([data-nb-style="luminous-precision"], [data-nb-style="luminous-precision"] *).nb-link:hover {
25
+ background: var(--nb-surface);
26
+ color: var(--nb-accent);
27
+ box-shadow:
28
+ inset 2px 0 0 0 var(--nb-accent),
29
+ 0 0 12px var(--nb-accent-glow);
30
+ }
31
+
32
+ @keyframes nb-lp-pulse-glow {
33
+ 0%,
34
+ 100% {
35
+ box-shadow: 0 0 5px rgba(198, 165, 255, 0.15);
36
+ }
37
+ 50% {
38
+ box-shadow: 0 0 20px var(--nb-primary-glow);
39
+ }
40
+ }
41
+
42
+ @media (prefers-reduced-motion: reduce) {
43
+ :where([data-nb-style="luminous-precision"], [data-nb-style="luminous-precision"] *).nb-link {
44
+ transition: none;
45
+ }
46
+ }
@@ -0,0 +1,41 @@
1
+ /* luminous-precision — progress bar & spinner */
2
+ :where([data-nb-style="luminous-precision"], [data-nb-style="luminous-precision"] *).nb-progress {
3
+ display: block;
4
+ width: 100%;
5
+ height: 0.5rem;
6
+ background: var(--nb-surface-sunken);
7
+ border: 1px solid var(--nb-border);
8
+ border-radius: 1rem;
9
+ overflow: hidden;
10
+ }
11
+ :where([data-nb-style="luminous-precision"], [data-nb-style="luminous-precision"] *).nb-progress__bar {
12
+ height: 100%;
13
+ background: var(--nb-primary);
14
+ box-shadow: 0 0 8px var(--nb-primary-glow);
15
+ border-radius: 1rem;
16
+ transition: width var(--nb-transition);
17
+ }
18
+ :where([data-nb-style="luminous-precision"], [data-nb-style="luminous-precision"] *).nb-progress__bar--accent {
19
+ background: var(--nb-accent);
20
+ box-shadow: 0 0 8px var(--nb-accent-glow);
21
+ }
22
+
23
+ :where([data-nb-style="luminous-precision"], [data-nb-style="luminous-precision"] *).nb-spinner {
24
+ display: inline-block;
25
+ width: 1.5rem;
26
+ height: 1.5rem;
27
+ border: 2px solid var(--nb-border);
28
+ border-top-color: var(--nb-primary);
29
+ border-radius: 50%;
30
+ animation: nb-lp-spin 0.8s linear infinite;
31
+ }
32
+ @keyframes nb-lp-spin {
33
+ to {
34
+ transform: rotate(360deg);
35
+ }
36
+ }
37
+ @media (prefers-reduced-motion: reduce) {
38
+ :where([data-nb-style="luminous-precision"], [data-nb-style="luminous-precision"] *).nb-spinner {
39
+ animation-duration: 2s;
40
+ }
41
+ }
@@ -0,0 +1,28 @@
1
+ /* luminous-precision — table */
2
+ :where([data-nb-style="luminous-precision"], [data-nb-style="luminous-precision"] *).nb-table {
3
+ width: 100%;
4
+ border-collapse: collapse;
5
+ font-size: var(--nb-text-sm);
6
+ color: var(--nb-on-surface);
7
+ }
8
+ :where([data-nb-style="luminous-precision"], [data-nb-style="luminous-precision"] *).nb-table th {
9
+ padding: var(--nb-space-2) var(--nb-space-3);
10
+ border-bottom: 1px solid var(--nb-border-lit);
11
+ color: var(--nb-faint);
12
+ text-align: left;
13
+ text-transform: uppercase;
14
+ font-size: 12px;
15
+ font-weight: var(--nb-font-weight-medium);
16
+ letter-spacing: var(--nb-tracking-wide);
17
+ }
18
+ :where([data-nb-style="luminous-precision"], [data-nb-style="luminous-precision"] *).nb-table td {
19
+ padding: var(--nb-space-2) var(--nb-space-3);
20
+ border-bottom: 1px solid var(--nb-border);
21
+ }
22
+ :where([data-nb-style="luminous-precision"], [data-nb-style="luminous-precision"] *).nb-table tbody tr {
23
+ transition: background var(--nb-transition), box-shadow var(--nb-transition);
24
+ }
25
+ :where([data-nb-style="luminous-precision"], [data-nb-style="luminous-precision"] *).nb-table tbody tr:hover {
26
+ background: var(--nb-surface-glass);
27
+ box-shadow: inset 2px 0 0 0 var(--nb-accent);
28
+ }
@@ -0,0 +1,33 @@
1
+ /* luminous-precision — tabs: active tab carries the electric-teal path */
2
+ :where([data-nb-style="luminous-precision"], [data-nb-style="luminous-precision"] *).nb-tabs {
3
+ display: flex;
4
+ gap: var(--nb-space-2);
5
+ border-bottom: 1px solid var(--nb-border);
6
+ }
7
+ :where([data-nb-style="luminous-precision"], [data-nb-style="luminous-precision"] *).nb-tab {
8
+ padding: var(--nb-space-2) var(--nb-space-3);
9
+ margin-bottom: -1px;
10
+ background: none;
11
+ border: none;
12
+ border-bottom: 2px solid transparent;
13
+ color: var(--nb-faint);
14
+ text-transform: uppercase;
15
+ font-family: var(--nb-font-mono);
16
+ font-weight: var(--nb-font-weight-medium);
17
+ font-size: var(--nb-text-sm);
18
+ letter-spacing: var(--nb-tracking-wide);
19
+ cursor: pointer;
20
+ transition: color var(--nb-transition), border-color var(--nb-transition);
21
+ }
22
+ :where([data-nb-style="luminous-precision"], [data-nb-style="luminous-precision"] *).nb-tab:hover {
23
+ color: var(--nb-on-surface);
24
+ }
25
+ :where([data-nb-style="luminous-precision"], [data-nb-style="luminous-precision"] *).nb-tab--active,
26
+ :where([data-nb-style="luminous-precision"], [data-nb-style="luminous-precision"] *).nb-tab[aria-selected="true"] {
27
+ color: var(--nb-accent);
28
+ border-bottom-color: var(--nb-accent);
29
+ text-shadow: 0 0 8px var(--nb-accent-glow);
30
+ }
31
+ :where([data-nb-style="luminous-precision"], [data-nb-style="luminous-precision"] *).nb-tabpanel {
32
+ padding: var(--nb-space-3) 0;
33
+ }
@@ -0,0 +1,89 @@
1
+ # luminous-precision
2
+
3
+ Professional, nocturnal evolution of neon-butterfly — "Luminous Precision".
4
+ Deep obsidian foundation, glassmorphic indigo surfaces, and light used as the
5
+ interaction language: instead of heavy borders, elements glow. Vibrant orchid
6
+ is the primary voice; electric teal marks active paths and critical signals.
7
+ Sora headlines over JetBrains Mono body give it a commanding, high-tech,
8
+ developer-console feel without going full terminal. Derived from the
9
+ InfraPulse Stitch mockups (Stitch project 18185577263375001507).
10
+
11
+ ## Color
12
+
13
+ | Role | Value | Usage |
14
+ | --- | --- | --- |
15
+ | Background | `#0a0c10` (deep obsidian) | Page background; `.nb-bg` adds soft orchid/teal radial underlays |
16
+ | Surface | `#1a1d29` (indigo) | Solid panels, dialogs |
17
+ | Surface sunken | `#0c0e14` | Inset fields, log wells, progress troughs |
18
+ | Surface glass | `rgba(26,29,41,0.4)` + 12px blur | Cards, nav links, alerts |
19
+ | On-surface | `#e2e2eb` | Body text |
20
+ | Faint | `#958e9b` | Secondary text, labels, idle tabs |
21
+ | Primary | `#c6a5ff` (vibrant orchid) | Primary buttons (solid fill), emphasis, glow |
22
+ | Accent | `#00f5ff` (electric teal) | Active states, focus rings, success paths, list-edge bars |
23
+ | Info | `#83b7ff` | Informational callouts and chips |
24
+ | Success | `#47e34e` | Live/healthy status |
25
+ | Warning | `#ffb86c` (amber) | Caution states |
26
+ | Danger | `#ff4d6d` (rose) | Destructive actions, errors |
27
+ | Border | `rgba(255,255,255,0.08)` | Resting borders |
28
+ | Border lit | `rgba(255,255,255,0.2)` | Top edge of glass panes — simulates overhead light |
29
+
30
+ Rules: color is functional, never decorative. Resting UI stays obsidian/faint;
31
+ orchid and teal appear on interaction, focus, and state. Depth comes from
32
+ tonal layers and glow, not drop shadows. Never pure white or pure black.
33
+
34
+ ## Typography
35
+
36
+ - **Headlines:** Sora (500 md / 600 lg / 700 xl), tight letter-spacing
37
+ (−0.01 to −0.02em); fallback `ui-sans-serif`.
38
+ - **Body & UI:** JetBrains Mono 400; fallback `ui-monospace`.
39
+ - **Labels & interactive text** (buttons, tabs, table headers): uppercase,
40
+ 600, 12–14px, letter-spacing `0.05em`.
41
+
42
+ ## Shape & effects
43
+
44
+ - Radius `0.5rem` for buttons and inputs; `1rem` for cards, dialogs, and large
45
+ containers. Pills reserved strictly for chips/badges and switches.
46
+ - Glass panes: 1px hairline borders with a lighter top edge
47
+ (`--nb-border-lit`) to simulate overhead lighting; `backdrop-filter` 12px.
48
+ - Focus is electric teal: inputs drop the resting border for a teal line plus
49
+ soft teal outer glow.
50
+ - Elevation = glow (`nb-pulse-glow` orchid, `nb-pulse-glow-accent` teal), not
51
+ dark shadows. Transitions 0.3s. Respect `prefers-reduced-motion`.
52
+ - 8px spacing rhythm; generous negative space so glows can breathe.
53
+
54
+ ## Components
55
+
56
+ Class prefix `nb-` (shared token/class contract with the other themes).
57
+
58
+ - **Card** `.nb-card` — glass pane, 1rem radius, lit top edge.
59
+ - **NavLink** `.nb-link` — glass list row; hover shifts to solid indigo and
60
+ lights a 2px teal bar on the left edge.
61
+ - **Button** `.nb-btn` — ghost by default; `--primary` is the one solid fill
62
+ (orchid, dark text), `--accent` teal ghost, `--danger` rose ghost.
63
+ - **Form** `.nb-input`, `.nb-textarea`, `.nb-select`, `.nb-label`,
64
+ `.nb-field`, `.nb-checkbox`, `.nb-radio`, `.nb-switch`, `.nb-choice` —
65
+ checked/focus states glow teal.
66
+ - **Badge** `.nb-badge` — pill chip: 15% tint of its hue behind
67
+ full-saturation text (+ semantic modifiers).
68
+ - **Alert** `.nb-alert` — glass, 3px left bar carries the semantic color.
69
+ - **Dialog** `.nb-dialog` — native `<dialog>`, indigo pane with orchid glow,
70
+ Sora title, blurred obsidian backdrop.
71
+ - **Tabs** `.nb-tabs`/`.nb-tab`/`.nb-tabpanel` — active tab underlined in
72
+ teal with text glow.
73
+ - **Table** `.nb-table` — lit header rule; row hover shifts glass and lights
74
+ the teal left bar.
75
+ - **Progress** `.nb-progress`, **Spinner** `.nb-spinner` — glowing orchid
76
+ indicators (`--accent` bar variant in teal).
77
+
78
+ ## Code syntax
79
+
80
+ Tokens `--nb-code-*`, part of the baseline contract. Orchid keywords, teal
81
+ types, info-blue functions, amber numbers, success-green strings, soft-rose
82
+ variables, dimmed-faint comments, faint meta — palette voices reused, never
83
+ new hues for decoration.
84
+
85
+ ## Scoping
86
+
87
+ Every rule is guarded by `data-nb-style="luminous-precision"` (self or
88
+ ancestor), wrapped in zero-specificity `:where()`. Set the attribute on
89
+ `<html>` for a page or on a container for an embedded island.
@@ -0,0 +1,13 @@
1
+ /* luminous-precision — full theme entry point */
2
+ @import "./tokens.css";
3
+ @import "./base.css";
4
+ @import "./components/card.css";
5
+ @import "./components/link.css";
6
+ @import "./components/button.css";
7
+ @import "./components/form.css";
8
+ @import "./components/badge.css";
9
+ @import "./components/alert.css";
10
+ @import "./components/dialog.css";
11
+ @import "./components/tabs.css";
12
+ @import "./components/table.css";
13
+ @import "./components/progress.css";