@xenide-io/the-old-ui-theme 0.2.3

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,1214 @@
1
+ @import "../styles/themes.css";
2
+ @import "../styles/typography.css";
3
+
4
+ @tailwind base;
5
+ @tailwind components;
6
+ @tailwind utilities;
7
+
8
+ /* Open Runde — self-hosted rounded variant of Inter */
9
+ @font-face {
10
+ font-family: "Open Runde";
11
+ src: url("/fonts/OpenRunde-Regular.woff2") format("woff2");
12
+ font-weight: 400;
13
+ font-style: normal;
14
+ font-display: swap;
15
+ }
16
+ @font-face {
17
+ font-family: "Open Runde";
18
+ src: url("/fonts/OpenRunde-Medium.woff2") format("woff2");
19
+ font-weight: 500;
20
+ font-style: normal;
21
+ font-display: swap;
22
+ }
23
+ @font-face {
24
+ font-family: "Open Runde";
25
+ src: url("/fonts/OpenRunde-Semibold.woff2") format("woff2");
26
+ font-weight: 600;
27
+ font-style: normal;
28
+ font-display: swap;
29
+ }
30
+ @font-face {
31
+ font-family: "Open Runde";
32
+ src: url("/fonts/OpenRunde-Bold.woff2") format("woff2");
33
+ font-weight: 700;
34
+ font-style: normal;
35
+ font-display: swap;
36
+ }
37
+
38
+ /* Structural tokens — shared across colour themes */
39
+ :root {
40
+ --ph-shadow-elevation-3000: 0 3px 0 var(--ph-border-3000);
41
+ --ph-chrome-depth: 0.1875rem;
42
+ --ph-chrome-inset-solid-top: inset 0 1px 0 hsl(0deg 0% 100% / 0.26);
43
+ --ph-chrome-inset-solid-bottom: inset 0 -1px 0 hsl(0deg 0% 0% / 0.14);
44
+ --ph-radius-app: 0.375rem;
45
+ --ph-border-control: color-mix(in oklab, var(--ph-border) 68%, var(--ph-border-strong));
46
+ /** Tailwind `ph.brand` maps to `--ph-accent`; plain CSS controls used only this name, so it must exist. */
47
+ --ph-brand: var(--ph-accent);
48
+ }
49
+
50
+ html {
51
+ scroll-behavior: smooth;
52
+ }
53
+
54
+ body {
55
+ @apply bg-ph-canvas text-ph-ink antialiased;
56
+ font-size: 15px;
57
+ line-height: 1.5;
58
+ }
59
+
60
+ @layer components {
61
+ /**
62
+ * PostHog LemonButton — from frontend/src/lib/lemon-ui/LemonButton/LemonButton.scss
63
+ */
64
+ .ph-btn {
65
+ @apply inline-flex shrink-0 cursor-pointer items-center justify-center gap-2 whitespace-nowrap font-medium;
66
+ border-radius: var(--ph-radius-app);
67
+ min-height: 2.3125rem;
68
+ padding: 0.25rem 0.875rem;
69
+ font-size: 0.875rem;
70
+ line-height: 1.5rem;
71
+ transition:
72
+ transform 200ms ease,
73
+ opacity 200ms ease,
74
+ background-color 200ms ease,
75
+ color 200ms ease;
76
+ @apply disabled:pointer-events-none disabled:opacity-[0.65];
77
+ }
78
+
79
+ .ph-btn-sm {
80
+ min-height: 2.0625rem;
81
+ padding: 0.25rem 0.625rem;
82
+ font-size: 0.8125rem;
83
+ }
84
+
85
+ .ph-btn-xs {
86
+ min-height: 1.625rem;
87
+ padding: 0.125rem 0.5rem;
88
+ font-size: 0.6875rem;
89
+ }
90
+
91
+ .ph-btn-lg {
92
+ min-height: 3.0625rem;
93
+ padding: 0.375rem 1.25rem;
94
+ font-size: 1rem;
95
+ }
96
+
97
+ .ph-btn-wide {
98
+ @apply px-10;
99
+ }
100
+
101
+ .ph-btn-circle {
102
+ @apply aspect-square rounded-full p-0;
103
+ min-width: 2.3125rem;
104
+ }
105
+
106
+ .ph-btn-square {
107
+ @apply aspect-square p-0;
108
+ min-width: 2.3125rem;
109
+ }
110
+
111
+ /* Lemon chrome — primary & secondary (LemonButton.scss ::before / ::after on __chrome) */
112
+ .ph-btn-primary,
113
+ .ph-btn-secondary {
114
+ --ph-btn-depth: 0px;
115
+ --ph-btn-chrome-depth: var(--ph-chrome-depth);
116
+ --ph-btn-face: var(--ph-secondary-button-bg);
117
+ --ph-btn-border: var(--ph-secondary-button-border);
118
+ --ph-btn-border-hover: var(--ph-secondary-button-border-hover);
119
+ --ph-btn-frame: var(--ph-secondary-frame-bg);
120
+ --ph-btn-ink: var(--ph-text-secondary);
121
+
122
+ padding: 0;
123
+ min-height: unset;
124
+ border: none;
125
+ background: transparent;
126
+ transition:
127
+ opacity 200ms ease,
128
+ color 200ms ease;
129
+ }
130
+
131
+ .ph-btn-primary {
132
+ --ph-btn-face: var(--ph-primary-button-face);
133
+ --ph-btn-border: var(--ph-primary-button-border);
134
+ --ph-btn-border-hover: var(--ph-primary-button-border-hover);
135
+ --ph-btn-frame: var(--ph-primary-frame-bg);
136
+ --ph-btn-ink: var(--ph-text-3000);
137
+ }
138
+
139
+ .ph-btn-chrome,
140
+ .ph-btn-primary:not(:has(.ph-btn-chrome)),
141
+ .ph-btn-secondary:not(:has(.ph-btn-chrome)) {
142
+ position: relative;
143
+ isolation: isolate;
144
+ display: inline-flex;
145
+ flex: 1;
146
+ align-items: center;
147
+ justify-content: center;
148
+ gap: inherit;
149
+ width: 100%;
150
+ min-height: 2.3125rem;
151
+ padding:
152
+ calc(0.25rem - var(--ph-btn-chrome-depth) * 0.5) 0.875rem
153
+ calc(0.25rem + var(--ph-btn-chrome-depth) * 0.5);
154
+ font-weight: 500;
155
+ color: var(--ph-btn-ink);
156
+ background: transparent;
157
+ border: none;
158
+ }
159
+
160
+ .ph-btn-chrome > *,
161
+ .ph-btn-primary:not(:has(.ph-btn-chrome)) > *,
162
+ .ph-btn-secondary:not(:has(.ph-btn-chrome)) > * {
163
+ position: relative;
164
+ z-index: 1;
165
+ }
166
+
167
+ .ph-btn-sm.ph-btn-primary .ph-btn-chrome,
168
+ .ph-btn-sm.ph-btn-secondary .ph-btn-chrome,
169
+ .ph-btn-sm.ph-btn-primary:not(:has(.ph-btn-chrome)),
170
+ .ph-btn-sm.ph-btn-secondary:not(:has(.ph-btn-chrome)) {
171
+ min-height: 2.0625rem;
172
+ padding:
173
+ calc(0.25rem - var(--ph-btn-chrome-depth) * 0.5) 0.625rem
174
+ calc(0.25rem + var(--ph-btn-chrome-depth) * 0.5);
175
+ font-size: 0.8125rem;
176
+ }
177
+
178
+ .ph-btn-xs.ph-btn-primary .ph-btn-chrome,
179
+ .ph-btn-xs.ph-btn-secondary .ph-btn-chrome,
180
+ .ph-btn-xs.ph-btn-primary:not(:has(.ph-btn-chrome)),
181
+ .ph-btn-xs.ph-btn-secondary:not(:has(.ph-btn-chrome)) {
182
+ min-height: 1.625rem;
183
+ padding:
184
+ calc(0.125rem - var(--ph-btn-chrome-depth) * 0.5) 0.5rem
185
+ calc(0.125rem + var(--ph-btn-chrome-depth) * 0.5);
186
+ font-size: 0.6875rem;
187
+ }
188
+
189
+ .ph-btn-lg.ph-btn-primary .ph-btn-chrome,
190
+ .ph-btn-lg.ph-btn-secondary .ph-btn-chrome,
191
+ .ph-btn-lg.ph-btn-primary:not(:has(.ph-btn-chrome)),
192
+ .ph-btn-lg.ph-btn-secondary:not(:has(.ph-btn-chrome)) {
193
+ min-height: 3.0625rem;
194
+ padding:
195
+ calc(0.375rem - var(--ph-btn-chrome-depth) * 0.5) 1.25rem
196
+ calc(0.375rem + var(--ph-btn-chrome-depth) * 0.5);
197
+ font-size: 1rem;
198
+ }
199
+
200
+ .ph-btn-chrome::before,
201
+ .ph-btn-primary:not(:has(.ph-btn-chrome))::before,
202
+ .ph-btn-secondary:not(:has(.ph-btn-chrome))::before {
203
+ content: "";
204
+ position: absolute;
205
+ inset: -1px;
206
+ bottom: calc(var(--ph-btn-depth) - 1px);
207
+ z-index: -1;
208
+ border: 1px solid var(--ph-btn-border);
209
+ border-radius: var(--ph-radius-app);
210
+ pointer-events: none;
211
+ }
212
+
213
+ .ph-btn-chrome::after,
214
+ .ph-btn-primary:not(:has(.ph-btn-chrome))::after,
215
+ .ph-btn-secondary:not(:has(.ph-btn-chrome))::after {
216
+ content: "";
217
+ position: absolute;
218
+ inset: -1px -1px calc(var(--ph-btn-chrome-depth) - 1px);
219
+ z-index: -1;
220
+ background: var(--ph-btn-face);
221
+ border: 1px solid var(--ph-btn-border);
222
+ border-radius: var(--ph-radius-app);
223
+ box-shadow: 0 var(--ph-btn-chrome-depth) 0 -1px var(--ph-btn-frame);
224
+ pointer-events: none;
225
+ }
226
+
227
+ .ph-btn-primary:hover:not(:disabled),
228
+ .ph-btn-secondary:hover:not(:disabled) {
229
+ --ph-btn-depth: -0.03125rem;
230
+ }
231
+
232
+ .ph-btn-secondary:hover:not(:disabled) {
233
+ --ph-btn-ink: var(--ph-text-primary);
234
+ }
235
+
236
+ .ph-btn-primary:hover:not(:disabled) .ph-btn-chrome,
237
+ .ph-btn-secondary:hover:not(:disabled) .ph-btn-chrome,
238
+ .ph-btn-primary:not(:has(.ph-btn-chrome)):hover:not(:disabled),
239
+ .ph-btn-secondary:not(:has(.ph-btn-chrome)):hover:not(:disabled) {
240
+ transform: translateY(var(--ph-btn-depth));
241
+ color: var(--ph-btn-ink);
242
+ }
243
+
244
+ .ph-btn-primary:hover:not(:disabled) .ph-btn-chrome::before,
245
+ .ph-btn-secondary:hover:not(:disabled) .ph-btn-chrome::before,
246
+ .ph-btn-primary:not(:has(.ph-btn-chrome)):hover:not(:disabled)::before,
247
+ .ph-btn-secondary:not(:has(.ph-btn-chrome)):hover:not(:disabled)::before {
248
+ border-color: var(--ph-btn-border-hover);
249
+ }
250
+
251
+ .ph-btn-primary:hover:not(:disabled) .ph-btn-chrome::after,
252
+ .ph-btn-secondary:hover:not(:disabled) .ph-btn-chrome::after,
253
+ .ph-btn-primary:not(:has(.ph-btn-chrome)):hover:not(:disabled)::after,
254
+ .ph-btn-secondary:not(:has(.ph-btn-chrome)):hover:not(:disabled)::after {
255
+ border-color: var(--ph-btn-border-hover);
256
+ box-shadow: 0 calc(var(--ph-btn-chrome-depth) - var(--ph-btn-depth)) 0 -1px var(--ph-btn-frame);
257
+ }
258
+
259
+ .ph-btn-primary:active:not(:disabled),
260
+ .ph-btn-secondary:active:not(:disabled) {
261
+ --ph-btn-depth: 0.03125rem;
262
+ }
263
+
264
+ .ph-btn-primary:active:not(:disabled) .ph-btn-chrome,
265
+ .ph-btn-secondary:active:not(:disabled) .ph-btn-chrome,
266
+ .ph-btn-primary:not(:has(.ph-btn-chrome)):active:not(:disabled),
267
+ .ph-btn-secondary:not(:has(.ph-btn-chrome)):active:not(:disabled) {
268
+ transform: translateY(var(--ph-btn-depth));
269
+ }
270
+
271
+ .ph-btn-primary:active:not(:disabled) .ph-btn-chrome::after,
272
+ .ph-btn-secondary:active:not(:disabled) .ph-btn-chrome::after,
273
+ .ph-btn-primary:not(:has(.ph-btn-chrome)):active:not(:disabled)::after,
274
+ .ph-btn-secondary:not(:has(.ph-btn-chrome)):active:not(:disabled)::after {
275
+ border-color: var(--ph-btn-border-hover);
276
+ box-shadow: 0 calc(var(--ph-btn-chrome-depth) - var(--ph-btn-depth)) 0 -1px var(--ph-btn-frame);
277
+ }
278
+
279
+ .ph-btn-icon,
280
+ .ph-btn-side-icon {
281
+ @apply inline-flex shrink-0 items-center justify-center opacity-80;
282
+ }
283
+
284
+ .ph-btn-icon .ph-icon,
285
+ .ph-btn-side-icon .ph-icon {
286
+ display: block;
287
+ vertical-align: unset;
288
+ }
289
+
290
+ .ph-btn-primary:hover:not(:disabled) .ph-btn-icon,
291
+ .ph-btn-secondary:hover:not(:disabled) .ph-btn-icon,
292
+ .ph-btn-primary:hover:not(:disabled) .ph-btn-side-icon,
293
+ .ph-btn-secondary:hover:not(:disabled) .ph-btn-side-icon {
294
+ opacity: 0.75;
295
+ }
296
+
297
+ .ph-btn-split-divider {
298
+ align-self: stretch;
299
+ width: 1px;
300
+ margin-block: 0.125rem;
301
+ background: currentColor;
302
+ opacity: 0.28;
303
+ }
304
+
305
+ .ph-btn-signal {
306
+ border: 1px solid color-mix(in oklab, var(--ph-accent) 88%, black);
307
+ background-color: var(--ph-accent);
308
+ color: #fff;
309
+ font-weight: 500;
310
+ box-shadow: 0 var(--ph-chrome-depth) 0 -1px color-mix(in oklab, var(--ph-primary-frame-bg) 75%, var(--ph-accent));
311
+ }
312
+
313
+ .ph-btn-signal:hover:not(:disabled) {
314
+ transform: translateY(-0.03125rem);
315
+ }
316
+
317
+ .ph-btn-signal:active:not(:disabled) {
318
+ transform: translateY(0.03125rem);
319
+ }
320
+
321
+ .ph-btn-accent {
322
+ @apply border-violet-800 bg-violet-600 text-white font-medium;
323
+ box-shadow: 0 var(--ph-chrome-depth) 0 -1px #5b21b6;
324
+ }
325
+
326
+ .ph-btn-neutral {
327
+ @apply border-neutral-900 bg-neutral-900 text-neutral-100 font-medium;
328
+ box-shadow: 0 var(--ph-chrome-depth) 0 -1px rgb(55 55 62);
329
+ }
330
+
331
+ .ph-btn-info {
332
+ @apply border-ph-info bg-ph-info text-white font-medium;
333
+ box-shadow: 0 var(--ph-chrome-depth) 0 -1px color-mix(in oklab, var(--ph-info) 80%, black);
334
+ }
335
+
336
+ .ph-btn-success {
337
+ @apply border-ph-success bg-ph-success text-white font-medium;
338
+ box-shadow: 0 var(--ph-chrome-depth) 0 -1px color-mix(in oklab, var(--ph-success) 80%, black);
339
+ }
340
+
341
+ .ph-btn-warning {
342
+ @apply border-ph-warning bg-ph-warning text-white font-medium;
343
+ box-shadow: 0 var(--ph-chrome-depth) 0 -1px color-mix(in oklab, var(--ph-warning) 80%, black);
344
+ }
345
+
346
+ .ph-btn-danger {
347
+ @apply border-ph-danger bg-ph-danger text-white font-medium;
348
+ box-shadow: 0 var(--ph-chrome-depth) 0 -1px color-mix(in oklab, var(--ph-danger) 80%, black);
349
+ }
350
+
351
+ .ph-btn-accent:hover:not(:disabled),
352
+ .ph-btn-neutral:hover:not(:disabled),
353
+ .ph-btn-info:hover:not(:disabled),
354
+ .ph-btn-success:hover:not(:disabled),
355
+ .ph-btn-warning:hover:not(:disabled),
356
+ .ph-btn-danger:hover:not(:disabled) {
357
+ transform: translateY(-0.03125rem);
358
+ }
359
+
360
+ .ph-btn-accent:active:not(:disabled),
361
+ .ph-btn-neutral:active:not(:disabled),
362
+ .ph-btn-info:active:not(:disabled),
363
+ .ph-btn-success:active:not(:disabled),
364
+ .ph-btn-warning:active:not(:disabled),
365
+ .ph-btn-danger:active:not(:disabled) {
366
+ transform: translateY(0.03125rem);
367
+ }
368
+
369
+ .ph-btn-tertiary,
370
+ .ph-btn-ghost {
371
+ @apply border-transparent bg-transparent text-ph-ink;
372
+ box-shadow: none;
373
+ }
374
+
375
+ .ph-btn-tertiary:hover:not(:disabled),
376
+ .ph-btn-ghost:hover:not(:disabled) {
377
+ background-color: color-mix(in oklab, var(--ph-text-primary) 6%, transparent);
378
+ }
379
+
380
+ .ph-btn-link {
381
+ @apply min-h-0 border-transparent bg-transparent p-0 text-ph-brand underline-offset-4;
382
+ box-shadow: none;
383
+ }
384
+
385
+ .ph-btn-link:hover:not(:disabled) {
386
+ color: var(--ph-accent-hover);
387
+ text-decoration: underline;
388
+ }
389
+
390
+ .ph-btn-outline.ph-btn-primary .ph-btn-chrome::after,
391
+ .ph-btn-outline.ph-btn-secondary .ph-btn-chrome::after,
392
+ .ph-btn-outline.ph-btn-primary:not(:has(.ph-btn-chrome))::after,
393
+ .ph-btn-outline.ph-btn-secondary:not(:has(.ph-btn-chrome))::after {
394
+ background: transparent;
395
+ }
396
+
397
+ /* Surfaces — crisp edge + faint top lip beside elevation */
398
+ .ph-panel {
399
+ @apply border bg-ph-muted p-6;
400
+ border-radius: var(--ph-radius-app);
401
+ border-color: var(--ph-border-control);
402
+ box-shadow:
403
+ var(--ph-chrome-inset-face-top),
404
+ var(--ph-shadow-elevation-3000);
405
+ }
406
+
407
+ .ph-card {
408
+ @apply flex flex-col overflow-hidden border bg-ph-surface;
409
+ border-radius: var(--ph-radius-app);
410
+ border-color: var(--ph-border-control);
411
+ box-shadow:
412
+ var(--ph-chrome-inset-face-top),
413
+ var(--ph-chrome-inset-face-bottom),
414
+ var(--ph-shadow-elevation-3000);
415
+ transition:
416
+ border-color 0.15s ease,
417
+ box-shadow 0.15s ease;
418
+ }
419
+
420
+ .ph-card:hover {
421
+ border-color: var(--ph-border-strong);
422
+ box-shadow:
423
+ var(--ph-chrome-inset-face-top),
424
+ var(--ph-chrome-inset-face-bottom),
425
+ var(--ph-shadow-elevation-3000),
426
+ 0 4px 14px hsl(0deg 0% 0% / 0.06);
427
+ }
428
+
429
+ /* Dashboard / inset insight shells */
430
+ .ph-dashboard-well {
431
+ @apply border border-ph-border bg-ph-canvas p-6;
432
+ border-radius: var(--ph-radius-app);
433
+ box-shadow: inset 0 1px 0 hsl(0deg 0% 100% / 0.6);
434
+ }
435
+
436
+ .ph-insight-shell {
437
+ @apply flex flex-col overflow-hidden bg-ph-surface;
438
+ border-radius: var(--ph-radius-app);
439
+ border: 1px solid var(--ph-border-control);
440
+ box-shadow:
441
+ var(--ph-chrome-inset-face-top),
442
+ var(--ph-chrome-inset-face-bottom),
443
+ var(--ph-shadow-elevation-3000);
444
+ }
445
+
446
+ .ph-insight-shell__ribbon {
447
+ width: 0.28rem;
448
+ flex-shrink: 0;
449
+ border-radius: var(--ph-radius-app) 0 0 var(--ph-radius-app);
450
+ }
451
+
452
+ .ph-dashboard-placeholder {
453
+ @apply flex min-h-[8rem] w-full cursor-pointer flex-col items-center justify-center gap-2 border-2 border-dashed border-ph-border p-6 text-center;
454
+ border-radius: var(--ph-radius-app);
455
+ box-shadow: inset 0 1px 0 hsl(0deg 0% 100% / 0.5);
456
+ background-color: color-mix(in oklab, var(--ph-muted) 65%, var(--ph-canvas));
457
+ }
458
+
459
+ .ph-card-body {
460
+ @apply flex flex-1 flex-col gap-3 p-5;
461
+ }
462
+
463
+ .ph-card-title {
464
+ @apply flex items-center gap-2 text-lg font-semibold text-ph-ink;
465
+ }
466
+
467
+ .ph-card-actions {
468
+ @apply mt-auto flex flex-wrap items-center justify-end gap-2 pt-2;
469
+ }
470
+
471
+ /* Forms */
472
+ .ph-field {
473
+ @apply flex w-full flex-col gap-1.5;
474
+ }
475
+
476
+ .ph-label {
477
+ @apply text-sm font-medium text-ph-subtle;
478
+ }
479
+
480
+ .ph-label-alt {
481
+ @apply text-xs text-ph-mutedtext;
482
+ }
483
+
484
+ /* Forms — control outline + Lemon inset lip + bottom elevation */
485
+ .ph-input-base {
486
+ @apply w-full bg-ph-surface px-3 py-2 text-sm text-ph-ink transition box-border;
487
+ border-radius: var(--ph-radius-app);
488
+ border: 1px solid var(--ph-border-control);
489
+ min-height: 2.3125rem;
490
+ line-height: 1.5rem;
491
+ font-family: inherit;
492
+ box-shadow:
493
+ var(--ph-chrome-inset-face-top),
494
+ var(--ph-chrome-inset-face-bottom),
495
+ var(--ph-shadow-elevation-3000);
496
+ }
497
+
498
+ .ph-input:focus,
499
+ .ph-select:focus,
500
+ .ph-textarea:focus {
501
+ outline: none;
502
+ box-shadow:
503
+ 0 0 0 3px color-mix(in oklab, var(--ph-accent) 18%, transparent),
504
+ var(--ph-chrome-inset-face-top),
505
+ var(--ph-chrome-inset-face-bottom),
506
+ var(--ph-shadow-elevation-3000);
507
+ border-color: color-mix(in oklab, var(--ph-accent) 45%, var(--ph-border));
508
+ }
509
+
510
+ .ph-input {
511
+ @apply ph-input-base;
512
+ }
513
+
514
+ .ph-input-error:focus,
515
+ .ph-select.ph-input-error:focus,
516
+ .ph-textarea.ph-input-error:focus {
517
+ box-shadow:
518
+ 0 0 0 3px color-mix(in oklab, var(--ph-danger) 20%, transparent),
519
+ var(--ph-chrome-inset-face-top),
520
+ var(--ph-chrome-inset-face-bottom),
521
+ var(--ph-shadow-elevation-3000);
522
+ }
523
+
524
+ .ph-input-error {
525
+ @apply border-ph-danger;
526
+ }
527
+
528
+ .ph-input-ghost {
529
+ @apply border-transparent bg-transparent shadow-none;
530
+ box-shadow: none;
531
+ }
532
+
533
+ .ph-input-group-field {
534
+ @apply rounded-none border-0 shadow-none focus:ring-0;
535
+ box-shadow: none;
536
+ padding-left: 1rem;
537
+ padding-right: 0.75rem;
538
+ }
539
+
540
+ .ph-input-group-field:focus {
541
+ box-shadow: none;
542
+ border-color: transparent;
543
+ }
544
+
545
+ /** Search field + submit — single outline, 1px `divide-x` seam, same min-height as `.ph-input` / primary chrome */
546
+ .ph-search-group {
547
+ @apply overflow-hidden rounded-[var(--ph-radius-app)];
548
+ border: 1px solid var(--ph-border-control);
549
+ background-color: var(--ph-surface);
550
+ box-shadow:
551
+ var(--ph-chrome-inset-face-top),
552
+ var(--ph-chrome-inset-face-bottom),
553
+ var(--ph-shadow-elevation-3000);
554
+ }
555
+
556
+ .ph-search-group:focus-within {
557
+ outline: none;
558
+ border-color: color-mix(in oklab, var(--ph-accent) 45%, var(--ph-border));
559
+ box-shadow:
560
+ 0 0 0 3px color-mix(in oklab, var(--ph-accent) 18%, transparent),
561
+ var(--ph-chrome-inset-face-top),
562
+ var(--ph-chrome-inset-face-bottom),
563
+ var(--ph-shadow-elevation-3000);
564
+ }
565
+
566
+ .ph-search-group .ph-input-group-field:focus {
567
+ box-shadow: none;
568
+ border-color: transparent;
569
+ }
570
+
571
+ .ph-search-group__submit.ph-btn {
572
+ @apply flex min-h-0 shrink-0 rounded-none;
573
+ align-self: stretch;
574
+ }
575
+
576
+ .ph-search-group__submit .ph-btn-chrome {
577
+ box-sizing: border-box;
578
+ height: 100%;
579
+ min-height: 2.3125rem;
580
+ padding-left: 0.75rem;
581
+ padding-right: 0.75rem;
582
+ }
583
+
584
+ .ph-select {
585
+ @apply ph-input-base cursor-pointer;
586
+ vertical-align: middle;
587
+ appearance: none;
588
+ -webkit-appearance: none;
589
+ -moz-appearance: none;
590
+ /* Pad past custom chevron (`.ph-select::-ms-expand` removes legacy IE arrow surface) */
591
+ padding-right: 2.4375rem;
592
+ background-image: var(--ph-select-chevron);
593
+ background-repeat: no-repeat;
594
+ background-position: right 0.75rem center;
595
+ background-size: 0.9375rem 0.9375rem;
596
+ }
597
+
598
+ .ph-select::-ms-expand {
599
+ display: none;
600
+ }
601
+
602
+ .ph-select:disabled {
603
+ @apply cursor-not-allowed opacity-[0.65];
604
+ }
605
+
606
+ .ph-textarea {
607
+ @apply ph-input-base min-h-[6rem] resize-y py-2;
608
+ min-height: 6rem;
609
+ }
610
+
611
+ .ph-checkbox,
612
+ .ph-radio {
613
+ @apply shrink-0 cursor-pointer appearance-none transition;
614
+ width: 1rem;
615
+ height: 1rem;
616
+ border: 1px solid var(--ph-border-control);
617
+ background: var(--ph-surface);
618
+ box-shadow:
619
+ var(--ph-chrome-inset-face-top),
620
+ var(--ph-chrome-inset-face-bottom);
621
+ }
622
+
623
+ .ph-checkbox {
624
+ border-radius: 0.25rem;
625
+ }
626
+
627
+ .ph-checkbox:checked {
628
+ border-color: var(--ph-brand);
629
+ background-color: var(--ph-brand);
630
+ background-image: url("data:image/svg+xml,%3csvg viewBox='0 0 16 16' fill='white' xmlns='http://www.w3.org/2000/svg'%3e%3cpath d='M12.207 4.793a1 1 0 010 1.414l-5 5a1 1 0 01-1.414 0l-2-2a1 1 0 011.414-1.414L6.5 9.086l4.293-4.293a1 1 0 011.414 0z'/%3e%3c/svg%3e");
631
+ background-size: 0.75rem 0.75rem;
632
+ background-position: center;
633
+ background-repeat: no-repeat;
634
+ }
635
+
636
+ .ph-checkbox:focus-visible,
637
+ .ph-radio:focus-visible,
638
+ .ph-toggle:focus-visible {
639
+ outline: none;
640
+ box-shadow:
641
+ 0 0 0 3px color-mix(in oklab, var(--ph-accent) 18%, transparent),
642
+ var(--ph-chrome-inset-face-top),
643
+ var(--ph-chrome-inset-face-bottom);
644
+ }
645
+
646
+ .ph-checkbox:disabled,
647
+ .ph-radio:disabled,
648
+ .ph-toggle:disabled {
649
+ @apply cursor-not-allowed opacity-50;
650
+ }
651
+
652
+ .ph-radio {
653
+ border-radius: 9999px;
654
+ }
655
+
656
+ .ph-radio:checked {
657
+ border-color: var(--ph-brand);
658
+ background-color: var(--ph-surface);
659
+ background-image: radial-gradient(circle, var(--ph-brand) 40%, transparent 42%);
660
+ }
661
+
662
+ .ph-toggle {
663
+ @apply relative shrink-0 cursor-pointer appearance-none transition;
664
+ width: 2.75rem;
665
+ height: 1.5rem;
666
+ border-radius: 9999px;
667
+ border: 1px solid var(--ph-border-control);
668
+ background: var(--ph-toolbar);
669
+ box-shadow: var(--ph-chrome-inset-face-bottom);
670
+ }
671
+
672
+ .ph-toggle::before {
673
+ content: "";
674
+ position: absolute;
675
+ top: 0.125rem;
676
+ left: 0.125rem;
677
+ width: 1.125rem;
678
+ height: 1.125rem;
679
+ border-radius: 9999px;
680
+ background: var(--ph-surface);
681
+ box-shadow: 0 1px 2px hsl(0deg 0% 0% / 0.12);
682
+ transition: transform 0.15s ease;
683
+ }
684
+
685
+ .ph-toggle:checked {
686
+ border-color: color-mix(in oklab, var(--ph-brand) 65%, var(--ph-border-control));
687
+ background: var(--ph-brand);
688
+ }
689
+
690
+ .ph-toggle:checked::before {
691
+ transform: translateX(1.25rem);
692
+ }
693
+
694
+ .ph-control-row {
695
+ @apply flex cursor-pointer items-center gap-3 text-sm text-ph-subtle;
696
+ }
697
+
698
+ .ph-control-row-between {
699
+ @apply flex cursor-pointer items-center justify-between gap-3 border-t border-ph-border pt-4 text-sm font-medium text-ph-ink;
700
+ }
701
+
702
+ .ph-range {
703
+ @apply h-2 w-full cursor-pointer appearance-none rounded-full bg-ph-toolbar accent-ph-brand;
704
+ }
705
+
706
+ /* LemonTable.scss — sticky-header border Simulation + row rhythm */
707
+ .ph-table-wrap {
708
+ @apply overflow-x-auto bg-ph-surface;
709
+ border-radius: var(--ph-radius-app);
710
+ border: 1px solid var(--ph-border);
711
+ box-shadow: var(--ph-shadow-elevation-3000);
712
+ }
713
+
714
+ .ph-table {
715
+ @apply w-full border-collapse text-left;
716
+ font-size: 13px;
717
+ }
718
+
719
+ .ph-table thead {
720
+ background: var(--ph-surface);
721
+ color: var(--ph-text-tertiary);
722
+ }
723
+
724
+ .ph-table th {
725
+ @apply whitespace-nowrap px-2 py-2;
726
+ padding-left: 1rem;
727
+ padding-right: 1rem;
728
+ font-size: 0.75rem;
729
+ font-weight: 700;
730
+ text-transform: uppercase;
731
+ letter-spacing: 0.03125rem;
732
+ box-shadow: inset 0 -1px var(--ph-border);
733
+ }
734
+
735
+ .ph-table td {
736
+ @apply px-2 py-[0.3125rem] text-ph-subtle;
737
+ padding-left: 1rem;
738
+ padding-right: 1rem;
739
+ vertical-align: middle;
740
+ color: var(--ph-text-secondary);
741
+ }
742
+
743
+ .ph-table tbody tr + tr td {
744
+ box-shadow: inset 0 1px 0 var(--ph-border);
745
+ }
746
+
747
+ .ph-table tbody tr {
748
+ transition: background-color 0.12s ease;
749
+ }
750
+
751
+ .ph-table tbody tr:hover td {
752
+ background-color: var(--ph-accent-highlight-secondary);
753
+ }
754
+
755
+ .ph-table--ribbon tbody td:first-child {
756
+ position: relative;
757
+ padding-left: calc(1rem + 0.65rem + 0.28rem);
758
+ }
759
+
760
+ .ph-table--ribbon tbody td:first-child::before {
761
+ content: "";
762
+ position: absolute;
763
+ left: 0.65rem;
764
+ top: 6px;
765
+ bottom: 6px;
766
+ width: 0.28rem;
767
+ border-radius: 3px;
768
+ background: var(--row-ribbon, var(--ph-data-1));
769
+ }
770
+
771
+ .ph-table-zebra tbody tr:nth-child(even) td {
772
+ background-color: color-mix(in oklab, var(--ph-muted) 45%, transparent);
773
+ }
774
+
775
+ .ph-table-compact .ph-table td {
776
+ @apply py-1 text-[12px];
777
+ }
778
+
779
+ /* Breadcrumbs */
780
+ .ph-breadcrumbs {
781
+ @apply flex flex-wrap items-center gap-1.5 text-sm;
782
+ }
783
+
784
+ .ph-breadcrumb-link {
785
+ @apply font-medium text-ph-mutedtext transition hover:text-ph-ink;
786
+ }
787
+
788
+ .ph-breadcrumb-current {
789
+ @apply font-medium text-ph-ink;
790
+ }
791
+
792
+ .ph-breadcrumb-sep {
793
+ @apply select-none text-ph-border;
794
+ }
795
+
796
+ /* Pagination */
797
+ .ph-pagination {
798
+ @apply inline-flex overflow-hidden;
799
+ border-radius: var(--ph-radius-app);
800
+ border: 1px solid var(--ph-border-control);
801
+ box-shadow:
802
+ var(--ph-chrome-inset-face-top),
803
+ var(--ph-chrome-inset-face-bottom),
804
+ var(--ph-shadow-elevation-3000);
805
+ }
806
+
807
+ .ph-pagination-btn {
808
+ @apply min-w-[2.25rem] border-r border-ph-border bg-ph-surface px-3 py-1.5 text-sm font-medium text-ph-subtle transition last:border-r-0;
809
+ }
810
+
811
+ .ph-pagination-btn:hover:not(:disabled):not(.ph-pagination-btn-active) {
812
+ background: color-mix(in oklab, var(--ph-muted) 70%, var(--ph-surface));
813
+ @apply text-ph-ink;
814
+ }
815
+
816
+ .ph-pagination-btn-active {
817
+ @apply bg-ph-muted text-ph-ink;
818
+ }
819
+
820
+ .ph-pagination-btn:disabled {
821
+ @apply cursor-not-allowed opacity-45;
822
+ }
823
+
824
+ .ph-pagination-ellipsis {
825
+ @apply flex min-w-[2.25rem] items-center justify-center border-r border-ph-border bg-ph-surface px-2 py-1.5 text-sm text-ph-mutedtext last:border-r-0;
826
+ }
827
+
828
+ /* Skeleton & loading */
829
+ @keyframes ph-skeleton-shimmer {
830
+ 0% {
831
+ background-position: 200% 0;
832
+ }
833
+
834
+ 100% {
835
+ background-position: -200% 0;
836
+ }
837
+ }
838
+
839
+ @keyframes ph-spin {
840
+ to {
841
+ transform: rotate(360deg);
842
+ }
843
+ }
844
+
845
+ @keyframes ph-loading-dot {
846
+ 0%,
847
+ 80%,
848
+ 100% {
849
+ opacity: 0.35;
850
+ transform: scale(0.85);
851
+ }
852
+
853
+ 40% {
854
+ opacity: 1;
855
+ transform: scale(1);
856
+ }
857
+ }
858
+
859
+ .ph-skeleton {
860
+ border-radius: 0.25rem;
861
+ background: linear-gradient(
862
+ 90deg,
863
+ color-mix(in oklab, var(--ph-muted) 85%, transparent) 0%,
864
+ color-mix(in oklab, var(--ph-toolbar) 95%, transparent) 50%,
865
+ color-mix(in oklab, var(--ph-muted) 85%, transparent) 100%
866
+ );
867
+ background-size: 200% 100%;
868
+ animation: ph-skeleton-shimmer 1.5s ease-in-out infinite;
869
+ }
870
+
871
+ .ph-skeleton-title {
872
+ @apply mb-4 h-3 w-1/3;
873
+ }
874
+
875
+ .ph-skeleton-text {
876
+ @apply mb-2 h-2 w-full;
877
+ }
878
+
879
+ .ph-skeleton-text-short {
880
+ @apply h-2 w-5/6;
881
+ }
882
+
883
+ .ph-skeleton-avatar {
884
+ @apply h-10 w-10 shrink-0 rounded-full;
885
+ }
886
+
887
+ .ph-skeleton-card {
888
+ @apply rounded-lg border border-ph-border bg-ph-surface p-4 shadow-ph;
889
+ }
890
+
891
+ .ph-loading {
892
+ @apply inline-block h-6 w-6 rounded-full;
893
+ border: 2px solid var(--ph-border);
894
+ border-top-color: var(--ph-brand);
895
+ animation: ph-spin 0.65s linear infinite;
896
+ }
897
+
898
+ .ph-loading-sm {
899
+ @apply h-4 w-4;
900
+ border-width: 1.5px;
901
+ }
902
+
903
+ .ph-loading-dots {
904
+ @apply inline-flex gap-1;
905
+ }
906
+
907
+ .ph-loading-dots > span {
908
+ @apply h-2 w-2 rounded-full bg-ph-mutedtext;
909
+ animation: ph-loading-dot 1.2s ease-in-out infinite;
910
+ }
911
+
912
+ .ph-loading-dots > span:nth-child(2) {
913
+ animation-delay: 0.15s;
914
+ }
915
+
916
+ .ph-loading-dots > span:nth-child(3) {
917
+ animation-delay: 0.3s;
918
+ }
919
+
920
+ /* Badges — tight pills */
921
+ .ph-badge {
922
+ @apply inline-flex items-center rounded-full px-2 py-0.5 text-[11px] font-semibold uppercase tracking-wide;
923
+ }
924
+
925
+ .ph-badge-neutral {
926
+ @apply bg-ph-toolbar text-ph-subtle;
927
+ }
928
+ .ph-badge-brand {
929
+ background: color-mix(in oklab, var(--ph-accent) 18%, var(--ph-surface));
930
+ color: color-mix(in oklab, var(--ph-accent) 72%, var(--ph-text-primary));
931
+ box-shadow: inset 0 0 0 1px color-mix(in oklab, var(--ph-accent) 38%, transparent);
932
+ }
933
+ .ph-badge-success {
934
+ background: color-mix(in oklab, var(--ph-success) 18%, var(--ph-surface));
935
+ color: color-mix(in oklab, var(--ph-success) 72%, var(--ph-text-primary));
936
+ box-shadow: inset 0 0 0 1px color-mix(in oklab, var(--ph-success) 38%, transparent);
937
+ }
938
+ .ph-badge-warning {
939
+ background: color-mix(in oklab, var(--ph-warning) 20%, var(--ph-surface));
940
+ color: color-mix(in oklab, var(--ph-warning) 75%, var(--ph-text-primary));
941
+ box-shadow: inset 0 0 0 1px color-mix(in oklab, var(--ph-warning) 40%, transparent);
942
+ }
943
+ .ph-badge-danger {
944
+ background: color-mix(in oklab, var(--ph-danger) 18%, var(--ph-surface));
945
+ color: color-mix(in oklab, var(--ph-danger) 72%, var(--ph-text-primary));
946
+ box-shadow: inset 0 0 0 1px color-mix(in oklab, var(--ph-danger) 38%, transparent);
947
+ }
948
+ .ph-badge-info {
949
+ background: color-mix(in oklab, var(--ph-info) 18%, var(--ph-surface));
950
+ color: color-mix(in oklab, var(--ph-info) 72%, var(--ph-text-primary));
951
+ box-shadow: inset 0 0 0 1px color-mix(in oklab, var(--ph-info) 38%, transparent);
952
+ }
953
+ .ph-badge-outline {
954
+ @apply border border-ph-border bg-transparent text-ph-subtle;
955
+ }
956
+
957
+ /* Alerts */
958
+ .ph-alert {
959
+ @apply flex items-start gap-3 rounded-[var(--ph-radius-app)] px-4 py-3 text-sm;
960
+ border: 1px solid var(--ph-border-control);
961
+ border-left-width: 4px;
962
+ box-shadow:
963
+ var(--ph-chrome-inset-face-top),
964
+ var(--ph-shadow-elevation-3000);
965
+ }
966
+
967
+ .ph-alert-info {
968
+ border-left-color: var(--ph-info);
969
+ background: color-mix(in oklab, var(--ph-info) 16%, var(--ph-muted));
970
+ color: var(--ph-text-primary);
971
+ }
972
+ .ph-alert-success {
973
+ border-left-color: var(--ph-success);
974
+ background: color-mix(in oklab, var(--ph-success) 16%, var(--ph-muted));
975
+ color: var(--ph-text-primary);
976
+ }
977
+ .ph-alert-warning {
978
+ border-left-color: var(--ph-warning);
979
+ background: color-mix(in oklab, var(--ph-warning) 18%, var(--ph-muted));
980
+ color: var(--ph-text-primary);
981
+ }
982
+ .ph-alert-danger {
983
+ border-left-color: var(--ph-danger);
984
+ background: color-mix(in oklab, var(--ph-danger) 16%, var(--ph-muted));
985
+ color: var(--ph-text-primary);
986
+ }
987
+
988
+ /* Toasts — same semantic tints as alerts */
989
+ .ph-toast {
990
+ @apply relative flex gap-3 rounded-lg border border-ph-border p-4 text-sm shadow-ph;
991
+ border-left-width: 4px;
992
+ }
993
+ .ph-toast-info {
994
+ border-left-color: var(--ph-info);
995
+ background: color-mix(in oklab, var(--ph-info) 16%, var(--ph-muted));
996
+ color: var(--ph-text-primary);
997
+ }
998
+ .ph-toast-success {
999
+ border-left-color: var(--ph-success);
1000
+ background: color-mix(in oklab, var(--ph-success) 16%, var(--ph-muted));
1001
+ color: var(--ph-text-primary);
1002
+ }
1003
+ .ph-toast-warning {
1004
+ border-left-color: var(--ph-warning);
1005
+ background: color-mix(in oklab, var(--ph-warning) 18%, var(--ph-muted));
1006
+ color: var(--ph-text-primary);
1007
+ }
1008
+ .ph-toast-danger {
1009
+ border-left-color: var(--ph-danger);
1010
+ background: color-mix(in oklab, var(--ph-danger) 16%, var(--ph-muted));
1011
+ color: var(--ph-text-primary);
1012
+ }
1013
+
1014
+ /* Modal */
1015
+ .ph-modal-overlay {
1016
+ @apply fixed inset-0 z-[100] flex items-center justify-center bg-black/40 backdrop-blur-sm p-4;
1017
+ }
1018
+
1019
+ .ph-modal-panel {
1020
+ @apply w-full max-w-lg bg-ph-surface p-6 text-ph-ink;
1021
+ border-radius: var(--ph-radius-app);
1022
+ border: 1px solid var(--ph-border-control);
1023
+ box-shadow:
1024
+ var(--ph-chrome-inset-face-top),
1025
+ var(--ph-chrome-inset-face-bottom),
1026
+ var(--ph-shadow-elevation-3000),
1027
+ 0px 16px 16px -16px rgb(0 0 0 / 35%);
1028
+ }
1029
+
1030
+ /* Dropdown */
1031
+ .ph-dropdown-panel {
1032
+ @apply z-50 mt-2 min-w-[12rem] bg-ph-surface p-1;
1033
+ border-radius: var(--ph-radius-app);
1034
+ border: 1px solid var(--ph-border-control);
1035
+ box-shadow:
1036
+ var(--ph-chrome-inset-face-top),
1037
+ var(--ph-shadow-elevation-3000);
1038
+ }
1039
+
1040
+ .ph-dropdown-item {
1041
+ @apply flex cursor-pointer items-center gap-2 rounded-lg px-3 py-2 text-sm text-ph-subtle transition hover:bg-ph-muted;
1042
+ }
1043
+
1044
+ /* Tabs */
1045
+ .ph-tabs-row {
1046
+ @apply flex flex-wrap gap-1 rounded-lg bg-ph-muted p-1 border border-ph-border;
1047
+ }
1048
+
1049
+ .ph-tab {
1050
+ @apply cursor-pointer rounded-md px-3 py-2 text-sm font-medium text-ph-mutedtext transition hover:text-ph-ink;
1051
+ }
1052
+
1053
+ .ph-tab-active {
1054
+ @apply bg-ph-surface text-ph-ink shadow-sm;
1055
+ }
1056
+
1057
+ /* Navbar */
1058
+ .ph-navbar-demo {
1059
+ @apply flex flex-wrap items-center gap-4 rounded-xl border border-ph-border bg-ph-surface px-4 py-2 shadow-ph;
1060
+ }
1061
+
1062
+ /* Progress */
1063
+ .ph-progress {
1064
+ @apply h-2 w-full overflow-hidden rounded-full bg-ph-toolbar;
1065
+ }
1066
+
1067
+ .ph-progress-bar {
1068
+ @apply h-full rounded-full transition-all duration-300;
1069
+ }
1070
+
1071
+ /* Tooltip (simple title attr used in demos; visual wrapper) */
1072
+ .ph-tip {
1073
+ @apply inline-flex rounded-md border border-dashed border-ph-border px-2 py-1 text-xs text-ph-mutedtext;
1074
+ }
1075
+
1076
+ /* Section heading */
1077
+ .ph-h2-rule {
1078
+ @apply flex items-center gap-4;
1079
+ }
1080
+
1081
+ .ph-h2-rule h2 {
1082
+ @apply text-2xl font-bold tracking-tight text-ph-ink;
1083
+ }
1084
+
1085
+ .ph-h2-rule hr {
1086
+ @apply h-px min-w-[2rem] flex-1 border-0 bg-ph-border;
1087
+ }
1088
+
1089
+ /* Star rating mimic */
1090
+ .ph-rating {
1091
+ @apply flex gap-1 text-amber-400;
1092
+ }
1093
+
1094
+ /* Chat bubbles */
1095
+ .ph-chat-from {
1096
+ @apply max-w-[90%] rounded-2xl rounded-bl-md bg-ph-muted px-4 py-2 text-sm text-ph-ink;
1097
+ }
1098
+
1099
+ .ph-chat-self {
1100
+ @apply max-w-[90%] rounded-2xl rounded-br-md bg-ph-brand px-4 py-2 text-sm text-white;
1101
+ }
1102
+
1103
+ /* Collapse / accordion */
1104
+ .ph-details {
1105
+ @apply rounded-lg border border-ph-border bg-ph-surface;
1106
+ }
1107
+
1108
+ .ph-details > summary {
1109
+ @apply cursor-pointer list-none px-4 py-3 font-medium text-ph-ink;
1110
+ }
1111
+
1112
+ .ph-details > summary::-webkit-details-marker {
1113
+ display: none;
1114
+ }
1115
+
1116
+ .ph-details-inner {
1117
+ @apply border-t border-ph-border px-4 pb-4 pt-3 text-sm text-ph-subtle;
1118
+ }
1119
+
1120
+ /* Steps */
1121
+ .ph-steps {
1122
+ @apply flex flex-wrap gap-8;
1123
+ }
1124
+
1125
+ .ph-step {
1126
+ @apply text-center text-xs font-medium text-ph-mutedtext;
1127
+ }
1128
+
1129
+ /* Stat */
1130
+ .ph-stat {
1131
+ @apply flex flex-1 flex-col gap-1 bg-ph-surface p-6;
1132
+ border-radius: var(--ph-radius-app);
1133
+ border: 1px solid var(--ph-border-control);
1134
+ box-shadow:
1135
+ var(--ph-chrome-inset-face-top),
1136
+ var(--ph-chrome-inset-face-bottom),
1137
+ var(--ph-shadow-elevation-3000);
1138
+ }
1139
+
1140
+ .ph-stat-label {
1141
+ @apply text-[11px] font-semibold uppercase tracking-wider text-ph-mutedtext;
1142
+ }
1143
+
1144
+ .ph-stat-val {
1145
+ @apply text-2xl font-bold tabular-nums text-ph-ink;
1146
+ }
1147
+
1148
+ /* Toast stack */
1149
+ .ph-toast-stack {
1150
+ @apply flex flex-col gap-2 rounded-[var(--ph-radius-app)] bg-ph-surface p-3;
1151
+ border: 1px solid var(--ph-border-control);
1152
+ box-shadow:
1153
+ var(--ph-chrome-inset-face-top),
1154
+ var(--ph-shadow-elevation-3000);
1155
+ }
1156
+
1157
+ /* Icon tiles — mimic colourful Lemon sidebar / product glyphs */
1158
+ .ph-icon-tile {
1159
+ @apply relative flex aspect-square flex-col items-center justify-center rounded-[var(--ph-radius-app)] border text-[10px] font-bold uppercase tracking-wide shadow-sm ring-4 ring-ph-canvas transition hover:brightness-[1.02];
1160
+ }
1161
+
1162
+ /** Token / HogQL snippets — monospace. */
1163
+ .ph-kbd {
1164
+ @apply rounded border border-ph-border bg-ph-muted px-1.5 py-0.5 text-[11px] text-ph-subtle shadow-sm;
1165
+ font-family: var(--ph-font-monospace-stack);
1166
+ font-variant-ligatures: none;
1167
+ font-feature-settings: "liga" off;
1168
+ font-synthesis-weight: none;
1169
+ }
1170
+
1171
+ /** Keyboard shortcuts ⌘ ⌥ ⇧ — system fonts so modifier glyphs resolve. */
1172
+ .ph-shortcut {
1173
+ @apply rounded border border-ph-border bg-ph-muted px-1.5 py-0.5 text-[11px] text-ph-subtle shadow-sm;
1174
+ font-family: var(--ph-font-shortcut-stack);
1175
+ font-variant-numeric: normal;
1176
+ letter-spacing: 0.02em;
1177
+ }
1178
+
1179
+ /* LemonIcon parity — bespoke filled glyphs */
1180
+ .ph-icon {
1181
+ display: inline-block;
1182
+ width: 1em;
1183
+ height: 1em;
1184
+ vertical-align: -0.15em;
1185
+ flex-shrink: 0;
1186
+ }
1187
+
1188
+ /** Two-state icon toggle — stack both glyphs centred in a fixed slot. */
1189
+ .ph-icon-swap {
1190
+ position: relative;
1191
+ display: inline-block;
1192
+ flex-shrink: 0;
1193
+ }
1194
+
1195
+ .ph-icon-swap > .ph-icon {
1196
+ position: absolute;
1197
+ inset: 0;
1198
+ margin: auto;
1199
+ width: 100%;
1200
+ height: 100%;
1201
+ display: block;
1202
+ vertical-align: unset;
1203
+ }
1204
+
1205
+ .ph-icon-spin {
1206
+ animation: ph-spin 0.65s linear infinite;
1207
+ }
1208
+
1209
+ /* Code block */
1210
+ .ph-code {
1211
+ @apply rounded-lg border border-ph-border bg-neutral-950 p-4 text-xs text-neutral-100;
1212
+ font-family: var(--ph-font-monospace-stack);
1213
+ }
1214
+ }