@duyluonganduin/acl-web-components 0.0.63 → 0.0.65

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.
package/dist/tokens.css CHANGED
@@ -148,12 +148,6 @@
148
148
  --radius-24: 24px;
149
149
  --radius-full: 9999px;
150
150
 
151
- /* ===================== Box Shadow ===================== */
152
- --shadow-1: 0px 1px 2px rgba(29, 41, 57, 0.07);
153
- --shadow-2: 0px 1px 2px rgba(29, 41, 57, 0.04), 0px 2px 8px rgba(29, 41, 57, 0.08);
154
- --shadow-3: 0px 2px 8px rgba(29, 41, 57, 0.08), 0px 8px 24px rgba(29, 41, 57, 0.12);
155
- --shadow-4: 0px 4px 8px rgba(29, 41, 57, 0.08), 0px 16px 48px rgba(29, 41, 57, 0.16);
156
-
157
151
  /* ===================== Spacing ===================== */
158
152
  --spacing-px: 1px;
159
153
  --spacing-0: 0;
@@ -185,6 +179,332 @@
185
179
  --z-9999: 9999;
186
180
  }
187
181
 
182
+ /* ===================== Semantic colors =====================
183
+ * Role-based colors, named after shadcn/ui plus the roles ACL needs on top
184
+ * (status fills, soft tints, ramp-based hover/active, disabled, inverse, AI).
185
+ * Build UI against these, not the gray/primary ramps, so it follows the theme.
186
+ *
187
+ * Light is the default. Dark is opt-in: add `class="dark"` (or
188
+ * `data-theme="dark"`) to <html> or to any subtree. `.light` /
189
+ * `data-theme="light"` forces light back inside a dark subtree.
190
+ *
191
+ * Every `*-foreground` is the text/icon color that sits on its fill.
192
+ * Per status family: base fill, -hover, -active, -subtle (tint), -subtle-active
193
+ * (pressed tint), -subtle-foreground (strong text; also status text on plain
194
+ * surfaces), -border (soft border for outlined controls), -icon (an icon, dot
195
+ * or marker on the page or the tint).
196
+ *
197
+ * The dark palette, and the extra roles canvas / table-header / highlight /
198
+ * border-muted / -icon / ai-glow, come from anduin.design: see @semantic-dark.
199
+ */
200
+ /* @semantic-light */
201
+ :root, .light, [data-theme="light"] {
202
+ color-scheme: light;
203
+
204
+ --color-background: var(--color-gray-0);
205
+ --color-foreground: var(--color-gray-8);
206
+ --color-card: var(--color-gray-0);
207
+ --color-card-foreground: var(--color-gray-8);
208
+ --color-popover: var(--color-gray-0);
209
+ --color-popover-foreground: var(--color-gray-8);
210
+ /* Edge for floating surfaces; invisible in light, where the shadow does the job */
211
+ --color-popover-border: transparent;
212
+
213
+ --color-primary: var(--color-primary-4);
214
+ --color-primary-foreground: var(--color-gray-0);
215
+ --color-primary-hover: var(--color-primary-3);
216
+ --color-primary-active: var(--color-primary-5);
217
+ --color-primary-subtle: var(--color-primary-1);
218
+ --color-primary-subtle-foreground: var(--color-primary-5);
219
+ --color-primary-subtle-active: var(--color-primary-2);
220
+ --color-primary-border: var(--color-primary-3);
221
+
222
+ --color-secondary: var(--color-gray-2);
223
+ --color-secondary-foreground: var(--color-gray-8);
224
+ --color-muted: var(--color-gray-1);
225
+ --color-muted-foreground: var(--color-gray-7);
226
+ --color-subtle-foreground: var(--color-gray-6);
227
+ --color-placeholder: var(--color-gray-5);
228
+ --color-accent: var(--color-gray-2);
229
+ /* Faint hover for large areas (table rows) */
230
+ --color-accent-subtle: var(--color-gray-1);
231
+ --color-accent-foreground: var(--color-gray-8);
232
+ --color-accent-active: var(--color-gray-3);
233
+ --color-accent-strong: var(--color-gray-4);
234
+
235
+ /* Solid gray: dark-gray filled button, bold gray badge */
236
+ --color-neutral: var(--color-gray-7);
237
+ --color-neutral-foreground: var(--color-gray-0);
238
+ --color-neutral-hover: var(--color-gray-6);
239
+ --color-neutral-active: var(--color-gray-8);
240
+ --color-neutral-subtle: var(--color-gray-3);
241
+ --color-neutral-subtle-foreground: var(--color-gray-7);
242
+
243
+ --color-destructive: var(--color-danger-4);
244
+ --color-destructive-foreground: var(--color-gray-0);
245
+ --color-destructive-hover: var(--color-danger-3);
246
+ --color-destructive-active: var(--color-danger-5);
247
+ --color-destructive-subtle: var(--color-danger-1);
248
+ --color-destructive-subtle-foreground: var(--color-danger-5);
249
+ --color-destructive-subtle-active: var(--color-danger-2);
250
+ --color-destructive-border: var(--color-danger-3);
251
+
252
+ --color-success: var(--color-success-4);
253
+ --color-success-foreground: var(--color-gray-0);
254
+ --color-success-hover: var(--color-success-3);
255
+ --color-success-active: var(--color-success-5);
256
+ --color-success-subtle: var(--color-success-1);
257
+ --color-success-subtle-foreground: var(--color-success-5);
258
+ --color-success-subtle-active: var(--color-success-2);
259
+ --color-success-border: var(--color-success-3);
260
+
261
+ --color-warning: var(--color-warning-3);
262
+ --color-warning-foreground: var(--color-gray-8);
263
+ --color-warning-hover: var(--color-warning-2);
264
+ --color-warning-active: var(--color-warning-4);
265
+ --color-warning-subtle: var(--color-warning-1);
266
+ --color-warning-subtle-foreground: var(--color-warning-5);
267
+ --color-warning-subtle-active: var(--color-warning-2);
268
+ --color-warning-border: var(--color-warning-3);
269
+
270
+ --color-ai: var(--color-purple-600);
271
+ --color-ai-foreground: var(--color-gray-0);
272
+ --color-ai-hover: var(--color-purple-500);
273
+ --color-ai-active: var(--color-purple-700);
274
+ --color-ai-subtle: var(--color-purple-50);
275
+ --color-ai-subtle-foreground: var(--color-purple-700);
276
+ --color-ai-subtle-active: var(--color-purple-100);
277
+ --color-ai-border: var(--color-purple-300);
278
+
279
+ --color-border: var(--color-gray-3);
280
+ /* Lighter hairline: table row rules */
281
+ --color-border-subtle: var(--color-gray-2);
282
+ --color-input: var(--color-gray-4);
283
+ --color-ring: var(--color-primary-4);
284
+ --color-ring-subtle: var(--color-primary-1);
285
+ /* 2px focus outline on small controls (checkbox, radio) */
286
+ --color-ring-outline: var(--color-primary-2);
287
+
288
+ --color-disabled: var(--color-gray-2);
289
+ --color-disabled-foreground: var(--color-gray-4);
290
+ --color-inverse: var(--color-gray-9);
291
+ --color-inverse-foreground: var(--color-gray-0);
292
+ --color-overlay: rgba(50, 60, 77, 0.6);
293
+ /* Base for custom shadows: color-mix(in srgb, var(--color-shadow) 12%, transparent) */
294
+ --color-shadow: var(--color-gray-9);
295
+
296
+ /* Box shadow — lives here so `.light` restores it inside a `.dark` subtree. */
297
+ --shadow-1: 0px 1px 2px rgba(29, 41, 57, 0.07);
298
+ --shadow-2: 0px 1px 2px rgba(29, 41, 57, 0.04), 0px 2px 8px rgba(29, 41, 57, 0.08);
299
+ --shadow-3: 0px 2px 8px rgba(29, 41, 57, 0.08), 0px 8px 24px rgba(29, 41, 57, 0.12);
300
+ --shadow-4: 0px 4px 8px rgba(29, 41, 57, 0.08), 0px 16px 48px rgba(29, 41, 57, 0.16);
301
+
302
+ /* Roles from anduin.design that ACL had no token for (added in 0.0.65), with
303
+ the design's own light values. Nothing in ACL reads them yet except the
304
+ table header; they are here so apps can build against the design's names. */
305
+ /* The page behind cards in a card layout, and quiet fills a step below a card
306
+ (dropzone, PDF backdrop). Same as `muted` in both themes. */
307
+ --color-canvas: var(--color-gray-1);
308
+ /* A table's header row: gray-1 in light, gray-8 in dark (a step lighter than the gray-9 rows) */
309
+ --color-table-header: var(--color-gray-1);
310
+ /* Hover and selection, translucent so it reads on any surface. ACL's own `accent`
311
+ is the opaque equivalent on the page; use this where nothing scrolls beneath. */
312
+ --color-highlight: oklch(from var(--color-gray-8) l c h / 0.06);
313
+ /* A quieter line inside a surface that already has an edge. Same as `border-subtle`. */
314
+ --color-border-muted: var(--color-gray-2);
315
+ /* `-icon`: an intent-coloured icon, dot or marker on the page or on the intent's
316
+ tint: lighter than the tint's text, and 3:1 on both surfaces in both themes */
317
+ --color-primary-icon: var(--color-primary-4);
318
+ --color-destructive-icon: var(--color-danger-4);
319
+ --color-success-icon: color-mix(in oklab, var(--color-success-4), var(--color-success-5));
320
+ --color-warning-icon: color-mix(in oklab, var(--color-warning-4), var(--color-warning-5));
321
+ --color-ai-icon: var(--color-purple-500);
322
+ --color-neutral-icon: var(--color-gray-7);
323
+ /* The AI spinner's halo: none on a light page, a faint blue glow on a dark one */
324
+ --color-ai-glow: transparent;
325
+ }
326
+
327
+ /* @semantic-dark
328
+ * Ported from anduin.design (`web/css/src/tw/input.css` on its feat/dark-mode
329
+ * branch), which is the authoritative dark palette. 0.0.64 shipped ACL's own
330
+ * first pass instead, where surfaces stepped lighter as they rose
331
+ * (muted < background < card < popover) and every value was a literal oklch().
332
+ * That made each dialog, menu, dropdown panel and toast draw visibly lighter
333
+ * than the page, and none of its values came from ACL's palette, so a brand
334
+ * that overrides a ramp never reached dark mode.
335
+ *
336
+ * The design's reasoning, kept here:
337
+ * - One surface. Page, card and popover are all gray-9. Raised and floating
338
+ * surfaces stand out by an edge (`popover-border` = the white-10% border,
339
+ * drawn as an inset outline) and a black shadow, not by lightness. A gray-9
340
+ * shadow would vanish on a gray-9 page, hence black.
341
+ * - Every value aliases ACL's own ramps (`var(--color-gray-9)`,
342
+ * `oklch(from var(--color-primary-4) l c h / 0.16)`), so a brand theme that
343
+ * overrides a ramp carries through. ACL has no step below gray-9, so the
344
+ * sunken `muted` is gray-9 mixed with 6% black.
345
+ * - Fills keep the brand ramps, exactly as in light: their on-fill contrast is
346
+ * unchanged. Intent text on a plain surface is `-subtle-foreground` (step 2);
347
+ * the bare fill token as text (e.g. an outlined primary button) is about
348
+ * 3:1 on gray-9 and is a known limit of reading a fill as ink.
349
+ * - Text: gray-2; secondary text halfway between gray-4 and gray-5 (5.6:1 on
350
+ * gray-8, ~7:1 on gray-9); gray-5 is the quietest tier that still holds
351
+ * 4.5:1, so `subtle-foreground` and `placeholder` share it.
352
+ * - Lines are translucent white (10% / 6%), so they show on gray-8 fills too,
353
+ * where a solid gray-8 line vanished.
354
+ *
355
+ * Mapped by role, not by name (the design's names differ from ACL's):
356
+ * design `canvas` (sunken page) → ACL `muted`
357
+ * design `muted` (gray-2/gray-8 fill) → ACL `secondary`, `disabled`, and the
358
+ * pressed/selected `accent-active`
359
+ * design `highlight` (hover) → ACL `accent`, `accent-subtle`
360
+ * design `placeholder` (gray-5) → ACL `placeholder`, `subtle-foreground`
361
+ *
362
+ * One deliberate difference: the design's `highlight` and intent tints are
363
+ * translucent. ACL's components were written against opaque fills: a table
364
+ * row's hover and selected colours are inherited by its sticky frozen cells,
365
+ * the sticky header takes `accent` on hover, and a calendar range stacks
366
+ * `-subtle-active` over `-subtle`. A translucent fill there lets scrolled
367
+ * content show through, or doubles up. So every ACL *fill* takes the design
368
+ * value composited over the gray-9 surface:
369
+ * `color-mix(in srgb, var(--color-gray-9), X N%)` is what the browser paints
370
+ * for X at N% alpha over gray-9, so on the shared page/card/popover surface it
371
+ * is the same colour, and it stays opaque. The design's translucent originals
372
+ * are exposed unchanged as the additive `--color-highlight` (and lines stay
373
+ * translucent, as in the design: nothing scrolls under a 1px line).
374
+ */
375
+ .dark, [data-theme="dark"] {
376
+ color-scheme: dark;
377
+
378
+ /* One surface for page, cards and popovers (design: background/card/popover) */
379
+ --color-background: var(--color-gray-9);
380
+ --color-foreground: var(--color-gray-2);
381
+ --color-card: var(--color-gray-9);
382
+ --color-card-foreground: var(--color-gray-2);
383
+ --color-popover: var(--color-gray-9);
384
+ --color-popover-foreground: var(--color-gray-2);
385
+ /* The design's popover-border: the white-10% border, so floating layers get their edge */
386
+ --color-popover-border: var(--color-border);
387
+
388
+ /* Fills keep the brand ramps (same as light); tints are step 4 at 16% over gray-9 */
389
+ --color-primary: var(--color-primary-4);
390
+ --color-primary-foreground: var(--color-gray-0);
391
+ --color-primary-hover: var(--color-primary-3);
392
+ --color-primary-active: var(--color-primary-5);
393
+ --color-primary-subtle: color-mix(in srgb, var(--color-gray-9), var(--color-primary-4) 16%);
394
+ --color-primary-subtle-foreground: var(--color-primary-2);
395
+ /* No design counterpart: the pressed tint, a stronger 28% of the same fill */
396
+ --color-primary-subtle-active: color-mix(in srgb, var(--color-gray-9), var(--color-primary-4) 28%);
397
+ /* No design counterpart as a token; the design's outlined buttons draw their colour at 60% */
398
+ --color-primary-border: oklch(from var(--color-primary-4) l c h / 0.6);
399
+
400
+ /* design `muted`: the gray-8 read-only / neutral fill */
401
+ --color-secondary: var(--color-gray-8);
402
+ --color-secondary-foreground: var(--color-gray-2);
403
+ /* design `canvas`: the sunken surface, a step below the gray-9 page */
404
+ --color-muted: color-mix(in oklab, var(--color-gray-9), black 6%);
405
+ --color-muted-foreground: color-mix(in oklab, var(--color-gray-4), var(--color-gray-5));
406
+ /* design `placeholder`: the quietest tier that still holds 4.5:1 on gray-9 */
407
+ --color-subtle-foreground: var(--color-gray-5);
408
+ --color-placeholder: var(--color-gray-5);
409
+ /* design `highlight` (white 5%), opaque over gray-9: every one of accent's uses is a hover */
410
+ --color-accent: color-mix(in srgb, var(--color-gray-9), var(--color-gray-0) 5%);
411
+ --color-accent-subtle: color-mix(in srgb, var(--color-gray-9), var(--color-gray-0) 5%);
412
+ --color-accent-foreground: var(--color-gray-2);
413
+ /* Pressed / selected: the design's gray-8 `muted`, which is also the gray tag
414
+ (`neutral-subtle`), as in light where both are gray-3 */
415
+ --color-accent-active: var(--color-gray-8);
416
+ /* No design counterpart: one step past gray-8, toward gray-7 */
417
+ --color-accent-strong: color-mix(in oklab, var(--color-gray-8), var(--color-gray-7) 35%);
418
+
419
+ /* The design's neutral intent: the fill keeps gray-7 + white, the tint is gray-8 */
420
+ --color-neutral: var(--color-gray-7);
421
+ --color-neutral-foreground: var(--color-gray-0);
422
+ --color-neutral-hover: var(--color-gray-6);
423
+ --color-neutral-active: var(--color-gray-8);
424
+ --color-neutral-subtle: var(--color-gray-8);
425
+ --color-neutral-subtle-foreground: var(--color-gray-2);
426
+
427
+ --color-destructive: var(--color-danger-4);
428
+ --color-destructive-foreground: var(--color-gray-0);
429
+ --color-destructive-hover: var(--color-danger-3);
430
+ --color-destructive-active: var(--color-danger-5);
431
+ --color-destructive-subtle: color-mix(in srgb, var(--color-gray-9), var(--color-danger-4) 16%);
432
+ --color-destructive-subtle-foreground: var(--color-danger-2);
433
+ --color-destructive-subtle-active: color-mix(in srgb, var(--color-gray-9), var(--color-danger-4) 28%);
434
+ --color-destructive-border: oklch(from var(--color-danger-4) l c h / 0.6);
435
+
436
+ --color-success: var(--color-success-4);
437
+ --color-success-foreground: var(--color-gray-0);
438
+ --color-success-hover: var(--color-success-3);
439
+ --color-success-active: var(--color-success-5);
440
+ --color-success-subtle: color-mix(in srgb, var(--color-gray-9), var(--color-success-4) 16%);
441
+ --color-success-subtle-foreground: var(--color-success-2);
442
+ --color-success-subtle-active: color-mix(in srgb, var(--color-gray-9), var(--color-success-4) 28%);
443
+ --color-success-border: oklch(from var(--color-success-4) l c h / 0.6);
444
+
445
+ /* Warning's fill is step 3 with gray-8 text in both modes; its tint is step 4, as in the design */
446
+ --color-warning: var(--color-warning-3);
447
+ --color-warning-foreground: var(--color-gray-8);
448
+ --color-warning-hover: var(--color-warning-2);
449
+ --color-warning-active: var(--color-warning-4);
450
+ --color-warning-subtle: color-mix(in srgb, var(--color-gray-9), var(--color-warning-4) 16%);
451
+ --color-warning-subtle-foreground: var(--color-warning-2);
452
+ --color-warning-subtle-active: color-mix(in srgb, var(--color-gray-9), var(--color-warning-4) 28%);
453
+ --color-warning-border: oklch(from var(--color-warning-4) l c h / 0.6);
454
+
455
+ /* The design's purple intent */
456
+ --color-ai: var(--color-purple-600);
457
+ --color-ai-foreground: var(--color-gray-0);
458
+ --color-ai-hover: var(--color-purple-500);
459
+ --color-ai-active: var(--color-purple-700);
460
+ --color-ai-subtle: color-mix(in srgb, var(--color-gray-9), var(--color-purple-600) 16%);
461
+ --color-ai-subtle-foreground: var(--color-purple-200);
462
+ --color-ai-subtle-active: color-mix(in srgb, var(--color-gray-9), var(--color-purple-600) 28%);
463
+ --color-ai-border: oklch(from var(--color-purple-600) l c h / 0.6);
464
+
465
+ /* White at 10% (shadcn's dark border): ~1.36:1 on any dark surface, so it
466
+ still shows on gray-8 fills, where a solid gray-8 line vanished */
467
+ --color-border: oklch(from var(--color-gray-0) l c h / 0.1);
468
+ /* design `border-muted`: row rules inside a surface that already has an edge */
469
+ --color-border-subtle: oklch(from var(--color-gray-0) l c h / 0.06);
470
+ --color-input: var(--color-gray-7);
471
+ --color-ring: var(--color-primary-4);
472
+ /* No design counterparts: the focus glow and small-control outline, as the ring at 30% / 60% */
473
+ --color-ring-subtle: oklch(from var(--color-primary-4) l c h / 0.3);
474
+ --color-ring-outline: oklch(from var(--color-primary-4) l c h / 0.6);
475
+
476
+ /* The design keeps read-only and disabled on its gray-8 fills; as in light, disabled = secondary */
477
+ --color-disabled: var(--color-gray-8);
478
+ --color-disabled-foreground: var(--color-gray-7);
479
+ /* No design counterpart. The design's tooltip stays gray-9 and takes the border; ACL's
480
+ tooltip draws no edge, so inverse flips instead: the foreground colour as a surface */
481
+ --color-inverse: var(--color-gray-2);
482
+ --color-inverse-foreground: var(--color-gray-9);
483
+ /* The scrim has to darken the page, so black rather than a lifted gray */
484
+ --color-overlay: oklch(0 0 0 / 0.4);
485
+ --color-shadow: oklch(0 0 0);
486
+
487
+ /* The design's extra roles */
488
+ --color-canvas: color-mix(in oklab, var(--color-gray-9), black 6%);
489
+ --color-table-header: var(--color-gray-8);
490
+ --color-highlight: oklch(from var(--color-gray-0) l c h / 0.05);
491
+ --color-border-muted: oklch(from var(--color-gray-0) l c h / 0.06);
492
+ --color-primary-icon: var(--color-primary-3);
493
+ --color-destructive-icon: var(--color-danger-3);
494
+ --color-success-icon: var(--color-success-3);
495
+ --color-warning-icon: var(--color-warning-4);
496
+ --color-ai-icon: var(--color-purple-400);
497
+ --color-neutral-icon: var(--color-gray-4);
498
+ --color-ai-glow: oklch(from var(--color-primary-3) l c h / 0.25);
499
+
500
+ /* The design's shadows: the light alphas, tinted black. They barely show on
501
+ gray-9, which is why floating surfaces carry the white-10% edge. */
502
+ --shadow-1: 0px 1px 2px oklch(from var(--color-shadow) l c h / 0.07);
503
+ --shadow-2: 0px 1px 2px oklch(from var(--color-shadow) l c h / 0.04), 0px 2px 8px oklch(from var(--color-shadow) l c h / 0.08);
504
+ --shadow-3: 0px 2px 8px oklch(from var(--color-shadow) l c h / 0.08), 0px 8px 24px oklch(from var(--color-shadow) l c h / 0.12);
505
+ --shadow-4: 0px 4px 8px oklch(from var(--color-shadow) l c h / 0.08), 0px 16px 48px oklch(from var(--color-shadow) l c h / 0.16);
506
+ }
507
+
188
508
 
189
509
  body {
190
510
  font-family: var(--font-sans);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@duyluonganduin/acl-web-components",
3
- "version": "0.0.63",
3
+ "version": "0.0.65",
4
4
  "type": "module",
5
5
  "repository": {
6
6
  "type": "git",