@lepid-labs/styles 1.0.1 → 1.0.2

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.
@@ -0,0 +1,165 @@
1
+ /* luminous-precision — shell chrome: unfilled header and nav (hairlines over
2
+ * the page background), mono uppercase nav labels, the current page lit by the electric-teal path (the
3
+ * same 2px left bar + glow as .ld-link hover). Structure is in layout.css. */
4
+ :where([data-ld-style="luminous-precision"], [data-ld-style="luminous-precision"] *).ld-shell__skip {
5
+ padding: var(--ld-space-2) var(--ld-space-3);
6
+ background: var(--ld-surface);
7
+ border: 1px solid var(--ld-primary-border);
8
+ border-radius: var(--ld-radius);
9
+ color: var(--ld-primary);
10
+ font-size: var(--ld-text-sm);
11
+ }
12
+
13
+ :where([data-ld-style="luminous-precision"], [data-ld-style="luminous-precision"] *).ld-shell__header {
14
+ /* no fill: the shell background runs under the bar; the blur keeps
15
+ * content scrolling beneath it legible */
16
+ background: transparent;
17
+ border-bottom: 1px solid var(--ld-border);
18
+ backdrop-filter: blur(var(--ld-blur));
19
+ }
20
+ :where([data-ld-style="luminous-precision"], [data-ld-style="luminous-precision"] *).ld-shell__toggle {
21
+ background: none;
22
+ border: 1px solid var(--ld-border);
23
+ border-radius: var(--ld-radius);
24
+ color: var(--ld-faint);
25
+ transition: color var(--ld-transition), border-color var(--ld-transition), box-shadow var(--ld-transition);
26
+ }
27
+ :where([data-ld-style="luminous-precision"], [data-ld-style="luminous-precision"] *).ld-shell__toggle:hover,
28
+ :where([data-ld-style="luminous-precision"], [data-ld-style="luminous-precision"] *).ld-shell__toggle:focus-visible {
29
+ color: var(--ld-accent);
30
+ border-color: var(--ld-accent);
31
+ box-shadow: 0 0 10px var(--ld-accent-glow);
32
+ outline: none;
33
+ }
34
+ :where([data-ld-style="luminous-precision"], [data-ld-style="luminous-precision"] *).ld-shell__brand {
35
+ color: var(--ld-on-surface);
36
+ font-family: var(--ld-font-display);
37
+ font-weight: var(--ld-font-weight-bold);
38
+ font-size: 1.05rem;
39
+ letter-spacing: -0.01em;
40
+ }
41
+ :where([data-ld-style="luminous-precision"], [data-ld-style="luminous-precision"] *).ld-shell__brand svg,
42
+ :where([data-ld-style="luminous-precision"], [data-ld-style="luminous-precision"] *).ld-shell__brand img {
43
+ color: var(--ld-primary);
44
+ filter: drop-shadow(0 0 6px var(--ld-primary-glow));
45
+ }
46
+ :where([data-ld-style="luminous-precision"], [data-ld-style="luminous-precision"] *).ld-topnav__item {
47
+ padding: var(--ld-space-2) var(--ld-space-3);
48
+ border-radius: var(--ld-radius);
49
+ color: var(--ld-faint);
50
+ font-family: var(--ld-font-mono);
51
+ font-weight: var(--ld-font-weight-medium);
52
+ font-size: 12px;
53
+ text-transform: uppercase;
54
+ letter-spacing: var(--ld-tracking-wide);
55
+ transition: color var(--ld-transition), background var(--ld-transition);
56
+ }
57
+ :where([data-ld-style="luminous-precision"], [data-ld-style="luminous-precision"] *).ld-topnav__item:hover,
58
+ :where([data-ld-style="luminous-precision"], [data-ld-style="luminous-precision"] *).ld-topnav__item:focus-visible {
59
+ color: var(--ld-on-surface);
60
+ background: var(--ld-surface-glass);
61
+ outline: none;
62
+ }
63
+ :where([data-ld-style="luminous-precision"], [data-ld-style="luminous-precision"] *).ld-topnav__item--active,
64
+ :where([data-ld-style="luminous-precision"], [data-ld-style="luminous-precision"] *).ld-topnav__item[aria-current="page"] {
65
+ color: var(--ld-accent);
66
+ text-shadow: 0 0 8px var(--ld-accent-glow);
67
+ }
68
+
69
+ :where([data-ld-style="luminous-precision"], [data-ld-style="luminous-precision"] *).ld-shell__nav {
70
+ background: transparent; /* the shell background shows through; a hairline divides */
71
+ border-right: 1px solid var(--ld-border);
72
+ }
73
+ :where([data-ld-style="luminous-precision"], [data-ld-style="luminous-precision"] *).ld-shell__scrim {
74
+ background: rgba(0, 0, 0, 0.55);
75
+ backdrop-filter: blur(2px);
76
+ }
77
+ :where([data-ld-style="luminous-precision"], [data-ld-style="luminous-precision"] *).ld-sidenav__heading {
78
+ color: var(--ld-faint);
79
+ font-family: var(--ld-font-mono);
80
+ font-size: 11px;
81
+ font-weight: var(--ld-font-weight-medium);
82
+ text-transform: uppercase;
83
+ letter-spacing: 0.12em;
84
+ opacity: 0.8;
85
+ }
86
+ :where([data-ld-style="luminous-precision"], [data-ld-style="luminous-precision"] *).ld-sidenav__item {
87
+ border-radius: var(--ld-radius);
88
+ color: var(--ld-faint);
89
+ font-family: var(--ld-font-mono);
90
+ font-size: 13px;
91
+ font-weight: var(--ld-font-weight-medium);
92
+ box-shadow: inset 0 0 0 0 var(--ld-accent);
93
+ transition: background var(--ld-transition), color var(--ld-transition), box-shadow var(--ld-transition);
94
+ }
95
+ :where([data-ld-style="luminous-precision"], [data-ld-style="luminous-precision"] *).ld-sidenav__item:hover,
96
+ :where([data-ld-style="luminous-precision"], [data-ld-style="luminous-precision"] *).ld-sidenav__item:focus-visible {
97
+ background: var(--ld-surface-glass);
98
+ color: var(--ld-on-surface);
99
+ outline: none;
100
+ }
101
+ :where([data-ld-style="luminous-precision"], [data-ld-style="luminous-precision"] *).ld-sidenav__item:focus-visible {
102
+ box-shadow: 0 0 0 1px var(--ld-primary-border);
103
+ }
104
+ :where([data-ld-style="luminous-precision"], [data-ld-style="luminous-precision"] *).ld-sidenav__item--active,
105
+ :where([data-ld-style="luminous-precision"], [data-ld-style="luminous-precision"] *).ld-sidenav__item[aria-current="page"] {
106
+ background: var(--ld-surface);
107
+ color: var(--ld-accent);
108
+ box-shadow: inset 2px 0 0 0 var(--ld-accent), 0 0 12px var(--ld-accent-glow);
109
+ }
110
+ :where([data-ld-style="luminous-precision"], [data-ld-style="luminous-precision"] *).ld-sidenav__item--active .ld-sidenav__icon,
111
+ :where([data-ld-style="luminous-precision"], [data-ld-style="luminous-precision"] *).ld-sidenav__item[aria-current="page"] .ld-sidenav__icon {
112
+ filter: drop-shadow(0 0 4px var(--ld-accent-glow));
113
+ }
114
+
115
+ :where([data-ld-style="luminous-precision"], [data-ld-style="luminous-precision"] *).ld-shell__footer {
116
+ border-top: 1px solid var(--ld-border);
117
+ color: var(--ld-faint);
118
+ font-size: 12px;
119
+ }
120
+
121
+ :where([data-ld-style="luminous-precision"], [data-ld-style="luminous-precision"] *).ld-page__eyebrow {
122
+ color: var(--ld-accent);
123
+ font-family: var(--ld-font-mono);
124
+ font-size: 12px;
125
+ font-weight: var(--ld-font-weight-medium);
126
+ text-transform: uppercase;
127
+ letter-spacing: 0.12em;
128
+ }
129
+ :where([data-ld-style="luminous-precision"], [data-ld-style="luminous-precision"] *).ld-page__title {
130
+ font-family: var(--ld-font-display);
131
+ font-size: clamp(1.5rem, 1.2rem + 1vw, 2rem);
132
+ font-weight: var(--ld-font-weight-bold);
133
+ letter-spacing: -0.02em;
134
+ }
135
+ :where([data-ld-style="luminous-precision"], [data-ld-style="luminous-precision"] *).ld-page__subtitle {
136
+ color: var(--ld-faint);
137
+ font-size: var(--ld-text-sm);
138
+ }
139
+
140
+ @media (width <= 48rem) {
141
+ :where([data-ld-style="luminous-precision"], [data-ld-style="luminous-precision"] *).ld-shell__nav {
142
+ background: color-mix(in srgb, var(--ld-bg-blend) 94%, transparent);
143
+ border-right-color: var(--ld-border-lit);
144
+ box-shadow: 12px 0 40px rgba(0, 0, 0, 0.5);
145
+ }
146
+ :where([data-ld-style="luminous-precision"], [data-ld-style="luminous-precision"] *).ld-shell--tabbar .ld-shell__nav {
147
+ border-right: none;
148
+ border-top: 1px solid var(--ld-border-lit);
149
+ box-shadow: 0 -8px 30px rgba(0, 0, 0, 0.45);
150
+ }
151
+ :where([data-ld-style="luminous-precision"], [data-ld-style="luminous-precision"] *).ld-shell--tabbar .ld-sidenav__item--active,
152
+ :where([data-ld-style="luminous-precision"], [data-ld-style="luminous-precision"] *).ld-shell--tabbar .ld-sidenav__item[aria-current="page"] {
153
+ background: none;
154
+ box-shadow: inset 0 2px 0 0 var(--ld-accent);
155
+ border-radius: 0;
156
+ }
157
+ }
158
+
159
+ @media (prefers-reduced-motion: reduce) {
160
+ :where([data-ld-style="luminous-precision"], [data-ld-style="luminous-precision"] *).ld-shell__toggle,
161
+ :where([data-ld-style="luminous-precision"], [data-ld-style="luminous-precision"] *).ld-topnav__item,
162
+ :where([data-ld-style="luminous-precision"], [data-ld-style="luminous-precision"] *).ld-sidenav__item {
163
+ transition: none;
164
+ }
165
+ }
@@ -26,3 +26,23 @@
26
26
  background: var(--ld-surface-glass);
27
27
  box-shadow: inset 2px 0 0 0 var(--ld-accent);
28
28
  }
29
+
30
+ /* Interactive rows (.ld-table--interactive): the cursor is the affordance —
31
+ * plain tables hover too. Focus is an outline so it
32
+ * composes with the selected state (aria-selected="true"), which sits last
33
+ * so it outranks hover. */
34
+ :where([data-ld-style="luminous-precision"], [data-ld-style="luminous-precision"] *).ld-table--interactive tbody tr {
35
+ cursor: pointer;
36
+ }
37
+ :where([data-ld-style="luminous-precision"], [data-ld-style="luminous-precision"] *).ld-table--interactive tbody tr:focus-visible {
38
+ outline: 1px solid var(--ld-primary-border);
39
+ outline-offset: -1px;
40
+ background: var(--ld-surface-glass);
41
+ }
42
+ :where([data-ld-style="luminous-precision"], [data-ld-style="luminous-precision"] *).ld-table--interactive tbody tr:active {
43
+ background: rgba(198, 165, 255, 0.06);
44
+ }
45
+ :where([data-ld-style="luminous-precision"], [data-ld-style="luminous-precision"] *).ld-table--interactive tbody tr[aria-selected="true"] {
46
+ background: rgba(198, 165, 255, 0.1);
47
+ box-shadow: inset 2px 0 0 0 var(--ld-accent), inset 0 0 12px var(--ld-primary-glow);
48
+ }
@@ -83,6 +83,12 @@ Class prefix `ld-` (shared token/class contract with the other themes).
83
83
  (`--ld-slide-lead` / `--ld-slide-trail`, direction from `data-ld-dir`).
84
84
  Variants tint the label only; `--block` fills the row with equal-width
85
85
  segments. Use `role="group"` + `aria-label`.
86
+ - **Icon button** `.ld-icon-btn` (+ `--active`, `--danger`) — chromeless
87
+ 2rem square for icon-only actions (`<button>` or `<a>`; always
88
+ `aria-label`). Faint glyph at rest; hover lights it orchid on a faint tint
89
+ with a soft glow. Active (`--active`, `aria-pressed="true"`,
90
+ `aria-current="page"`) is an orchid glyph in a hairline orchid inset.
91
+ `--danger` turns the glyph red on hover. Child `svg` sized to 1.25em.
86
92
  - **Form** `.ld-input`, `.ld-textarea`, `.ld-select`, `.ld-label`,
87
93
  `.ld-field`, `.ld-checkbox`, `.ld-radio`, `.ld-switch`, `.ld-choice` —
88
94
  checked/focus states glow teal.
@@ -96,9 +102,25 @@ Class prefix `ld-` (shared token/class contract with the other themes).
96
102
  teal with text glow; the underline is one lit bar that reaches for the new
97
103
  tab and settles with barely any overshoot (same slide tokens).
98
104
  - **Table** `.ld-table` — lit header rule; row hover shifts glass and lights
99
- the teal left bar.
105
+ the teal left bar. `.ld-table--interactive` adds the pointer, an orchid
106
+ focus outline, and a selected row (`aria-selected`) held in orchid glow
107
+ with the teal bar.
100
108
  - **Progress** `.ld-progress`, **Spinner** `.ld-spinner` — glowing orchid
101
109
  indicators (`--accent` bar variant in teal).
110
+ - **App shell** `.ld-shell` (+ `__skip`, `__header`, `__toggle`, `__brand`,
111
+ `__actions`, `__nav`, `__scrim`, `__main`, `__footer`; `.ld-topnav`/`__item`;
112
+ `.ld-sidenav` + `__section`, `__heading`, `__item`, `__icon`, `__label`,
113
+ `__badge`, `__footer`) — brand in Sora with an orchid-glow mark; mono uppercase top-nav and nav labels in faint. The current page takes the electric-teal path (indigo pane, 2px teal left bar, teal glow) — the same language as `.ld-link` hover; in the tab bar it becomes a teal top rule. The header and nav are unfilled — hairline
114
+ borders over the page background (`.ld-bg`), which the shell paints; the
115
+ header blurs what scrolls under it. The drawer and tab bar take a fill. Structure (`components/layout.css`) is shared by every theme:
116
+ collapsed rail on `data-ld-nav-collapsed`, drawer on `data-ld-nav-open`
117
+ below 48rem, `--tabbar` docks the nav at the bottom. The header
118
+ always spans the full width above the nav.
119
+ - **Page layouts** `.ld-page` (`--narrow`/`--wide`/`--full`, `__header`,
120
+ `__eyebrow`, `__title`, `__subtitle`, `__actions`), `.ld-grid`,
121
+ `.ld-split`, `.ld-aside-layout`, `.ld-center` — structure only
122
+ (`components/page.css`, shared by every theme); the page
123
+ title uses the display face.
102
124
  - **Stepper** `.ld-stepper` (+ `__step`, `__node`, `__label`) — milestone
103
125
  rail: glowing orchid fill on a sunken track, 2rem nodes, uppercase mono
104
126
  labels. `__step--complete` is a solid orchid node; `--current` lights the
@@ -110,7 +132,14 @@ Class prefix `ld-` (shared token/class contract with the other themes).
110
132
  `color: var(--ld-faint)`, italic.
111
133
  - **Pre / log block** `.ld-pre` — command/log `<pre>`; the surface-sunken
112
134
  well (already documented above as this theme's "log wells" token),
113
- hairline border, radius, small mono, horizontal scroll.
135
+ hairline border, radius, small mono, horizontal scroll. `.ld-pre--log`
136
+ bounds it (`--ld-log-max-height`, 420px), scrolls both ways, wraps long
137
+ lines, and lays faint teal scanlines over the well.
138
+ - **Copy control** `.ld-pre-copy` — an `.ld-icon-btn` pinned top-right in
139
+ a `.ld-pre-wrap`; fades in on hover/focus-within, always shown on touch
140
+ (`hover: none`). `data-ld-copy="copied"` swaps the copy glyph for a
141
+ success-tinted check; `"failed"` tints it danger. Status goes to a
142
+ visually hidden `aria-live` `.ld-pre-copy-status`.
114
143
 
115
144
  ## Code syntax
116
145
 
@@ -1,12 +1,16 @@
1
1
  /* luminous-precision — full theme entry point */
2
2
  @import "./tokens.css";
3
3
  @import "./base.css";
4
+ @import "./components/layout.css";
5
+ @import "./components/shell.css";
6
+ @import "./components/page.css";
4
7
  @import "./components/card.css";
5
8
  @import "./components/status-card.css";
6
9
  @import "./components/link.css";
7
10
  @import "./components/button.css";
8
11
  @import "./components/button-hold.css";
9
12
  @import "./components/button-group.css";
13
+ @import "./components/icon-button.css";
10
14
  @import "./components/form.css";
11
15
  @import "./components/badge.css";
12
16
  @import "./components/alert.css";
@@ -32,8 +32,12 @@
32
32
 
33
33
  /* Opt-in page background: the butterfly circuit artwork blended into the navy.
34
34
  * Matches the switchboard landing page. Apply to <body>, or to the attributed
35
- * container itself. */
36
- :where([data-ld-style="neon-butterfly"], [data-ld-style="neon-butterfly"] *).ld-bg {
35
+ * container itself. An app shell
36
+ * (.ld-shell) always paints it, and so does the <body> around one, so the
37
+ * page stays covered past the shell (overscroll, short pages). */
38
+ :where([data-ld-style="neon-butterfly"], [data-ld-style="neon-butterfly"] *).ld-bg,
39
+ :where(html[data-ld-style="neon-butterfly"]) body:has(.ld-shell),
40
+ :where([data-ld-style="neon-butterfly"], [data-ld-style="neon-butterfly"] *).ld-shell {
37
41
  background: var(--ld-bg) url("./assets/butterfly-circuit.png") center / cover fixed;
38
42
  background-blend-mode: luminosity;
39
43
  background-color: var(--ld-bg-blend);
@@ -0,0 +1,66 @@
1
+ /* neon-butterfly — icon button: chromeless square, faint glyph that lights lilac (backplane's .icon-btn).
2
+ * Icon-only control (<button> or <a>): give it an accessible name (aria-label).
3
+ * Active/current: .ld-icon-btn--active, [aria-pressed="true"], [aria-current="page"]. */
4
+ :where([data-ld-style="neon-butterfly"], [data-ld-style="neon-butterfly"] *).ld-icon-btn {
5
+ display: inline-flex;
6
+ align-items: center;
7
+ justify-content: center;
8
+ flex: none;
9
+ width: 2rem;
10
+ height: 2rem;
11
+ padding: 0;
12
+ background: none;
13
+ border: none;
14
+ border-radius: var(--ld-radius);
15
+ color: var(--ld-faint);
16
+ font: inherit;
17
+ line-height: 1;
18
+ text-decoration: none;
19
+ cursor: pointer;
20
+ transition: color var(--ld-transition), box-shadow var(--ld-transition);
21
+ }
22
+ :where([data-ld-style="neon-butterfly"], [data-ld-style="neon-butterfly"] *).ld-icon-btn > svg {
23
+ width: 1.25em;
24
+ height: 1.25em;
25
+ flex: none;
26
+ }
27
+ :where([data-ld-style="neon-butterfly"], [data-ld-style="neon-butterfly"] *).ld-icon-btn:hover,
28
+ :where([data-ld-style="neon-butterfly"], [data-ld-style="neon-butterfly"] *).ld-icon-btn:focus-visible {
29
+ color: var(--ld-primary);
30
+ outline: none;
31
+ }
32
+ :where([data-ld-style="neon-butterfly"], [data-ld-style="neon-butterfly"] *).ld-icon-btn:focus-visible {
33
+ box-shadow: 0 0 0 1px var(--ld-primary-border), 0 0 8px var(--ld-primary-glow);
34
+ }
35
+ :where([data-ld-style="neon-butterfly"], [data-ld-style="neon-butterfly"] *).ld-icon-btn--active,
36
+ :where([data-ld-style="neon-butterfly"], [data-ld-style="neon-butterfly"] *).ld-icon-btn[aria-pressed="true"],
37
+ :where([data-ld-style="neon-butterfly"], [data-ld-style="neon-butterfly"] *).ld-icon-btn[aria-current="page"] {
38
+ color: var(--ld-primary);
39
+ text-shadow: 0 0 8px var(--ld-primary-glow);
40
+ }
41
+
42
+ /* danger: destructive action (delete, remove) — faint at rest, red on hover */
43
+ :where([data-ld-style="neon-butterfly"], [data-ld-style="neon-butterfly"] *).ld-icon-btn--danger:hover,
44
+ :where([data-ld-style="neon-butterfly"], [data-ld-style="neon-butterfly"] *).ld-icon-btn--danger:focus-visible {
45
+ color: var(--ld-danger);
46
+ }
47
+
48
+ /* disabled: dimmed and inert — hover never lights it; [aria-disabled] covers <a> */
49
+ :where([data-ld-style="neon-butterfly"], [data-ld-style="neon-butterfly"] *).ld-icon-btn:disabled,
50
+ :where([data-ld-style="neon-butterfly"], [data-ld-style="neon-butterfly"] *).ld-icon-btn[aria-disabled="true"] {
51
+ opacity: 0.4;
52
+ color: var(--ld-faint);
53
+ background: none;
54
+ box-shadow: none;
55
+ transform: none;
56
+ cursor: not-allowed;
57
+ }
58
+ :where([data-ld-style="neon-butterfly"], [data-ld-style="neon-butterfly"] *).ld-icon-btn[aria-disabled="true"] {
59
+ pointer-events: none;
60
+ }
61
+
62
+ @media (prefers-reduced-motion: reduce) {
63
+ :where([data-ld-style="neon-butterfly"], [data-ld-style="neon-butterfly"] *).ld-icon-btn {
64
+ transition: none;
65
+ }
66
+ }