@loidolt/theme-styles 0.4.0 → 0.6.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.
@@ -76,6 +76,24 @@
76
76
  height: 1rem;
77
77
  accent-color: var(--loidolt-accent);
78
78
  }
79
+ /* A choice with a sentence under it: the control aligns with the label's first line. */
80
+ .ldt-choice--described {
81
+ align-items: flex-start;
82
+ }
83
+ .ldt-choice--described input {
84
+ margin-top: 0.1rem;
85
+ }
86
+ .ldt-choice__text {
87
+ display: grid;
88
+ gap: 0.15rem;
89
+ }
90
+ .ldt-choice__description {
91
+ color: var(--loidolt-text-muted);
92
+ font: var(--loidolt-font-size-sm) / var(--loidolt-font-line-height-normal)
93
+ var(--loidolt-font-display);
94
+ letter-spacing: normal;
95
+ text-transform: none;
96
+ }
79
97
  .ldt-fieldset {
80
98
  min-width: 0;
81
99
  margin: 0;
@@ -139,6 +157,9 @@
139
157
  grid-template-columns: 2rem minmax(0, 1fr) 2rem;
140
158
  border-bottom: var(--loidolt-border-width) solid var(--loidolt-border-control);
141
159
  }
160
+ .ldt-number-field--bare {
161
+ grid-template-columns: minmax(0, 1fr);
162
+ }
142
163
  .ldt-number-field .ldt-number-field__input {
143
164
  border: 0;
144
165
  text-align: center;
@@ -199,3 +220,298 @@
199
220
  opacity: 0.4;
200
221
  cursor: not-allowed;
201
222
  }
223
+ /*
224
+ * Combobox and MultiSelect. The wrapper draws the field — underline, or box when `--boxed` —
225
+ * so chips, the text input and the open button all sit inside one boundary.
226
+ */
227
+ .ldt-combobox {
228
+ width: 100%;
229
+ min-height: var(--loidolt-size-control);
230
+ display: flex;
231
+ flex-wrap: wrap;
232
+ align-items: center;
233
+ gap: 0.3rem;
234
+ border-bottom: var(--loidolt-border-width) solid var(--loidolt-border-control);
235
+ padding: 0.2rem 0 0.2rem 0.15rem;
236
+ color: var(--loidolt-text);
237
+ }
238
+ .ldt-combobox--boxed {
239
+ border: var(--loidolt-border-width) solid var(--loidolt-border-control);
240
+ padding-inline: 0.5rem 0;
241
+ background: var(--loidolt-surface-input);
242
+ }
243
+ .ldt-combobox:focus-within {
244
+ border-color: var(--loidolt-accent);
245
+ }
246
+ .ldt-combobox:has([aria-invalid='true']) {
247
+ border-color: var(--loidolt-danger);
248
+ }
249
+ .ldt-combobox[data-disabled],
250
+ .ldt-combobox:has(:disabled) {
251
+ opacity: 0.55;
252
+ }
253
+ .ldt-combobox__input {
254
+ flex: 1 1 6rem;
255
+ min-width: 0;
256
+ min-height: 1.5rem;
257
+ border: 0;
258
+ padding: 0.2rem 0;
259
+ color: inherit;
260
+ background: transparent;
261
+ }
262
+ .ldt-combobox__trigger {
263
+ display: inline-grid;
264
+ place-items: center;
265
+ align-self: stretch;
266
+ width: 1.75rem;
267
+ min-height: 1.5rem;
268
+ border: 0;
269
+ padding: 0;
270
+ color: var(--loidolt-text-muted);
271
+ background: transparent;
272
+ }
273
+ .ldt-combobox__trigger svg {
274
+ transition: transform var(--loidolt-motion-fast) var(--loidolt-motion-easing);
275
+ }
276
+ .ldt-combobox__trigger[data-state='open'] svg {
277
+ transform: rotate(180deg);
278
+ }
279
+ .ldt-multi-select__chips {
280
+ display: flex;
281
+ flex-wrap: wrap;
282
+ gap: 0.3rem;
283
+ margin: 0;
284
+ padding: 0;
285
+ list-style: none;
286
+ }
287
+
288
+ /*
289
+ * Slider. The wrapper's inline padding is half a thumb, so a thumb centred on either end value
290
+ * stays inside the box without the browser measuring it after hydration.
291
+ */
292
+ .ldt-slider {
293
+ --ldt-slider-thumb: 1rem;
294
+ width: 100%;
295
+ display: flex;
296
+ align-items: center;
297
+ gap: var(--loidolt-space-3);
298
+ padding-inline: calc(var(--ldt-slider-thumb) / 2);
299
+ }
300
+ .ldt-slider__control {
301
+ position: relative;
302
+ flex: 1;
303
+ min-height: 1.5rem;
304
+ display: flex;
305
+ align-items: center;
306
+ touch-action: none;
307
+ user-select: none;
308
+ }
309
+ .ldt-slider__track {
310
+ position: relative;
311
+ width: 100%;
312
+ height: var(--ldt-slider-thickness, 0.25rem);
313
+ overflow: hidden;
314
+ background: var(--loidolt-border);
315
+ }
316
+ .ldt-slider__range {
317
+ position: absolute;
318
+ height: 100%;
319
+ background: var(--loidolt-accent);
320
+ }
321
+ .ldt-slider__thumb {
322
+ display: block;
323
+ width: var(--ldt-slider-thumb);
324
+ height: var(--ldt-slider-thumb);
325
+ border: 2px solid var(--loidolt-accent);
326
+ background: var(--loidolt-surface-input);
327
+ cursor: grab;
328
+ transition: background var(--loidolt-motion-fast) var(--loidolt-motion-easing);
329
+ }
330
+ .ldt-slider__thumb[data-active] {
331
+ background: var(--loidolt-accent);
332
+ cursor: grabbing;
333
+ }
334
+ .ldt-slider__tick {
335
+ width: var(--loidolt-border-width);
336
+ height: 0.5rem;
337
+ background: var(--loidolt-border-strong);
338
+ transform: translateY(0.55rem);
339
+ }
340
+ .ldt-slider__value {
341
+ min-width: 3ch;
342
+ color: var(--loidolt-text-muted);
343
+ font: var(--loidolt-font-size-sm) var(--loidolt-font-utility);
344
+ font-variant-numeric: tabular-nums;
345
+ text-align: end;
346
+ }
347
+ .ldt-slider[data-disabled] {
348
+ opacity: 0.45;
349
+ }
350
+ .ldt-slider[data-disabled] .ldt-slider__thumb {
351
+ cursor: not-allowed;
352
+ }
353
+ .ldt-slider--vertical {
354
+ width: auto;
355
+ height: var(--ldt-slider-length, 10rem);
356
+ flex-direction: column;
357
+ padding-inline: 0;
358
+ padding-block: calc(var(--ldt-slider-thumb) / 2);
359
+ }
360
+ .ldt-slider--vertical .ldt-slider__control {
361
+ min-height: 0;
362
+ width: 1.5rem;
363
+ flex-direction: column;
364
+ justify-content: center;
365
+ }
366
+ .ldt-slider--vertical .ldt-slider__track {
367
+ width: var(--ldt-slider-thickness, 0.25rem);
368
+ height: 100%;
369
+ }
370
+ .ldt-slider--vertical .ldt-slider__range {
371
+ width: 100%;
372
+ height: auto;
373
+ }
374
+
375
+ /* Password field: the input and its reveal button share the field's boundary. */
376
+ .ldt-password-input {
377
+ width: 100%;
378
+ min-height: var(--loidolt-size-control);
379
+ display: flex;
380
+ align-items: stretch;
381
+ border-bottom: var(--loidolt-border-width) solid var(--loidolt-border-control);
382
+ }
383
+ .ldt-password-input--boxed {
384
+ border: var(--loidolt-border-width) solid var(--loidolt-border-control);
385
+ background: var(--loidolt-surface-input);
386
+ }
387
+ .ldt-password-input:focus-within {
388
+ border-color: var(--loidolt-accent);
389
+ }
390
+ .ldt-password-input:has([aria-invalid='true']) {
391
+ border-color: var(--loidolt-danger);
392
+ }
393
+ .ldt-password-input__input {
394
+ flex: 1;
395
+ min-width: 0;
396
+ border: 0;
397
+ padding: 0.45rem 0.15rem;
398
+ color: var(--loidolt-text);
399
+ background: transparent;
400
+ }
401
+ .ldt-password-input--boxed .ldt-password-input__input {
402
+ padding-inline: 0.65rem;
403
+ }
404
+ .ldt-password-input__toggle {
405
+ display: inline-grid;
406
+ place-items: center;
407
+ width: 2.25rem;
408
+ min-height: 1.5rem;
409
+ border: 0;
410
+ padding: 0;
411
+ color: var(--loidolt-text-muted);
412
+ background: transparent;
413
+ }
414
+ .ldt-password-input__toggle:hover:not(:disabled),
415
+ .ldt-password-input__toggle[aria-pressed='true'] {
416
+ color: var(--loidolt-text-accent);
417
+ }
418
+
419
+ /* One-time code: one square cell per character over a single hidden input. */
420
+ .ldt-otp-input {
421
+ display: inline-flex;
422
+ align-items: center;
423
+ gap: 0.35rem;
424
+ }
425
+ .ldt-otp-input__cell {
426
+ position: relative;
427
+ width: var(--loidolt-size-control-lg);
428
+ height: var(--loidolt-size-control-lg);
429
+ display: grid;
430
+ place-items: center;
431
+ border: var(--loidolt-border-width) solid var(--loidolt-border-control);
432
+ color: var(--loidolt-text);
433
+ background: var(--loidolt-surface-input);
434
+ font: var(--loidolt-font-size-lg) var(--loidolt-font-utility);
435
+ font-variant-numeric: tabular-nums;
436
+ }
437
+ /* The input is visually hidden, so the active cell carries the focus indicator for it. */
438
+ .ldt-otp-input:focus-within .ldt-otp-input__cell[data-active] {
439
+ border-color: var(--loidolt-accent);
440
+ outline: 2px solid var(--loidolt-focus-ring);
441
+ outline-offset: 1px;
442
+ }
443
+ .ldt-otp-input:has([aria-invalid='true']) .ldt-otp-input__cell {
444
+ border-color: var(--loidolt-danger);
445
+ }
446
+ .ldt-otp-input__gap {
447
+ width: 0.5rem;
448
+ height: var(--loidolt-border-width);
449
+ background: var(--loidolt-border-strong);
450
+ }
451
+ .ldt-otp-input__caret {
452
+ width: 1px;
453
+ height: 1.1em;
454
+ background: currentColor;
455
+ animation: ldt-caret 1s steps(1) infinite;
456
+ }
457
+ @keyframes ldt-caret {
458
+ 50% {
459
+ opacity: 0;
460
+ }
461
+ }
462
+
463
+ /* Signature capture: a paper-toned pad with a baseline, so drawing feels like signing a line. */
464
+ .ldt-signature {
465
+ display: grid;
466
+ gap: var(--loidolt-space-2);
467
+ }
468
+ .ldt-signature__surface {
469
+ position: relative;
470
+ border: var(--loidolt-border-width) solid var(--loidolt-border-control);
471
+ color: var(--loidolt-text);
472
+ background: var(--loidolt-surface-input);
473
+ }
474
+ .ldt-signature__surface::after {
475
+ content: '';
476
+ position: absolute;
477
+ inset: auto var(--loidolt-space-4) 28%;
478
+ border-bottom: var(--loidolt-border-width) dashed var(--loidolt-border-strong);
479
+ pointer-events: none;
480
+ }
481
+ .ldt-signature__canvas {
482
+ display: block;
483
+ width: 100%;
484
+ height: var(--ldt-signature-height, 10rem);
485
+ touch-action: none;
486
+ cursor: crosshair;
487
+ }
488
+ .ldt-signature[data-disabled] .ldt-signature__canvas {
489
+ cursor: not-allowed;
490
+ opacity: 0.5;
491
+ }
492
+ .ldt-signature__hint {
493
+ margin: 0;
494
+ color: var(--loidolt-text-muted);
495
+ font: var(--loidolt-font-size-sm) var(--loidolt-font-utility);
496
+ }
497
+ .ldt-signature__typed {
498
+ display: grid;
499
+ gap: var(--loidolt-space-2);
500
+ }
501
+ .ldt-signature__preview {
502
+ min-height: 4.5rem;
503
+ margin: 0;
504
+ overflow: hidden;
505
+ border-bottom: var(--loidolt-border-width) dashed var(--loidolt-border-strong);
506
+ padding: var(--loidolt-space-2) var(--loidolt-space-3) 0;
507
+ color: var(--loidolt-text);
508
+ font-size: 2.5rem;
509
+ line-height: 1.5;
510
+ text-overflow: ellipsis;
511
+ white-space: nowrap;
512
+ }
513
+ .ldt-signature__actions {
514
+ display: flex;
515
+ justify-content: flex-end;
516
+ gap: var(--loidolt-space-2);
517
+ }
@@ -11,10 +11,10 @@
11
11
  color: var(--loidolt-text);
12
12
  background: var(--loidolt-background);
13
13
  }
14
- .ldt-app-shell > :where(header, main, footer) {
14
+ .ldt-app-shell > :where(header, main, footer, .ldt-app-shell__main) {
15
15
  min-width: 0;
16
16
  }
17
- .ldt-app-shell > main,
17
+ .ldt-app-shell > :where(main, .ldt-app-shell__main),
18
18
  .ldt-workspace-container {
19
19
  /* Workspace normally sits directly in AppShell's main row. Naming that row as an inline-size
20
20
  container lets the same compact layout work when the shell itself is embedded or split. The
@@ -247,6 +247,8 @@
247
247
  .ldt-page-header__title {
248
248
  margin: 0;
249
249
  font-size: var(--loidolt-font-size-xl);
250
+ /* A long unbroken title — a file name, an identifier — must still reflow at 320px. */
251
+ overflow-wrap: anywhere;
250
252
  }
251
253
  .ldt-page-header__description {
252
254
  max-width: 48rem;
@@ -289,7 +291,10 @@
289
291
  gap: 0.15rem;
290
292
  }
291
293
  .ldt-contextbar__detail {
292
- display: none;
294
+ overflow: visible;
295
+ text-overflow: clip;
296
+ white-space: normal;
297
+ overflow-wrap: anywhere;
293
298
  }
294
299
  .ldt-workspace,
295
300
  .ldt-workspace--sidebar,
@@ -329,3 +334,66 @@
329
334
  padding: var(--loidolt-space-4);
330
335
  }
331
336
  }
337
+ /* A row of list controls — search, filters, view options — on the recessed surface. */
338
+ .ldt-toolbar {
339
+ display: flex;
340
+ flex-wrap: wrap;
341
+ align-items: center;
342
+ gap: var(--loidolt-space-2);
343
+ border: var(--loidolt-border-width) solid var(--loidolt-border);
344
+ padding: var(--loidolt-space-2) var(--loidolt-space-3);
345
+ color: var(--loidolt-text);
346
+ background: var(--loidolt-surface-alt);
347
+ }
348
+ .ldt-toolbar--vertical {
349
+ flex-direction: column;
350
+ align-items: stretch;
351
+ }
352
+ .ldt-toolbar__end {
353
+ display: flex;
354
+ flex-wrap: wrap;
355
+ align-items: center;
356
+ gap: var(--loidolt-space-2);
357
+ margin-inline-start: auto;
358
+ }
359
+ .ldt-toolbar--vertical .ldt-toolbar__end {
360
+ flex-direction: column;
361
+ align-items: stretch;
362
+ margin-inline-start: 0;
363
+ margin-block-start: auto;
364
+ }
365
+
366
+ /*
367
+ * A filter area that expands under its toggle. Rows animate from `0fr` to `1fr`, which lets the
368
+ * height follow the content without measuring it.
369
+ */
370
+ .ldt-filter-panel {
371
+ display: grid;
372
+ grid-template-rows: 0fr;
373
+ transition: grid-template-rows var(--loidolt-motion-slow) var(--loidolt-motion-easing);
374
+ }
375
+ .ldt-filter-panel[data-state='open'] {
376
+ grid-template-rows: 1fr;
377
+ }
378
+ .ldt-filter-panel__clip {
379
+ min-height: 0;
380
+ overflow: hidden;
381
+ }
382
+ .ldt-filter-panel__body {
383
+ margin-top: var(--loidolt-space-2);
384
+ border: var(--loidolt-border-width) solid var(--loidolt-border);
385
+ padding: var(--loidolt-space-4);
386
+ color: var(--loidolt-text);
387
+ background: var(--loidolt-surface-alt);
388
+ }
389
+ .ldt-filter-panel__grid {
390
+ display: grid;
391
+ grid-template-columns: repeat(auto-fit, minmax(min(100%, var(--ldt-min, 12rem)), 1fr));
392
+ align-items: end;
393
+ gap: var(--ldt-gap, var(--loidolt-space-4));
394
+ }
395
+ .ldt-filter-panel__footer {
396
+ display: flex;
397
+ justify-content: flex-end;
398
+ margin-top: var(--loidolt-space-3);
399
+ }