@dataworkz/crystal 0.1.0-beta.0 → 0.1.0-beta.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.
Files changed (40) hide show
  1. package/CHANGELOG.md +41 -13
  2. package/README.md +6 -0
  3. package/fesm2022/dataworkz-crystal-icons.mjs +31 -321
  4. package/fesm2022/dataworkz-crystal-icons.mjs.map +1 -1
  5. package/fesm2022/dataworkz-crystal-markdown.mjs +1 -1
  6. package/fesm2022/dataworkz-crystal-markdown.mjs.map +1 -1
  7. package/fesm2022/dataworkz-crystal-primeng.mjs +23 -4
  8. package/fesm2022/dataworkz-crystal-primeng.mjs.map +1 -1
  9. package/fesm2022/dataworkz-crystal.mjs +99 -70
  10. package/fesm2022/dataworkz-crystal.mjs.map +1 -1
  11. package/icons/index.d.ts +30 -96
  12. package/icons/svg/files/csv.svg +0 -1
  13. package/icons/svg/files/generic.svg +0 -1
  14. package/icons/svg/files/multimedia.svg +0 -1
  15. package/icons/svg/glyphs/agentBuilder.svg +1 -1
  16. package/icons/svg/glyphs/notesPad.svg +1 -1
  17. package/icons/svg/glyphs/panelCollapse.svg +1 -1
  18. package/icons/svg/glyphs/panelExpand.svg +1 -1
  19. package/icons/svg/glyphs/play.svg +1 -1
  20. package/icons/svg/glyphs/robot.svg +1 -1
  21. package/icons/svg/glyphs/sidebarCollapse.svg +1 -1
  22. package/icons/svg/glyphs/sidebarExpand.svg +1 -1
  23. package/icons/svg/glyphs/tagFilled.svg +1 -1
  24. package/icons/svg/glyphs/testShield.svg +1 -1
  25. package/icons/svg/storage/generic.svg +0 -1
  26. package/icons/svg/storage/legacy/microsoft-mail.svg +0 -1
  27. package/icons/svg/storage/local/microsoft-mail.svg +0 -1
  28. package/index.d.ts +86 -47
  29. package/package.json +1 -1
  30. package/primeng/index.d.ts +33 -4
  31. package/styles/base.css +4 -4
  32. package/styles/components/button.css +3 -0
  33. package/styles/components/content.css +0 -102
  34. package/styles/components/data.css +1 -1
  35. package/styles/components/form.css +3 -2
  36. package/styles/components/surface.css +2 -2
  37. package/styles/components/toast.css +1 -1
  38. package/styles/crystal-no-fonts.css +1 -2
  39. package/styles/tokens/primitives.css +1 -3
  40. package/styles/tokens/semantic-dark.css +1 -1
package/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import * as _angular_core from '@angular/core';
2
- import { OnDestroy, TemplateRef, EnvironmentProviders, InjectionToken } from '@angular/core';
2
+ import { InjectionToken, EnvironmentProviders, OnDestroy, TemplateRef } from '@angular/core';
3
3
  import { StorageIconSet } from '@dataworkz/crystal/icons';
4
4
  export { DW_ICON_NAMES, DW_ICON_PREFIX, DwIconName, IconName, dwIconName, icon } from '@dataworkz/crystal/icons';
5
5
  import { ValidationErrors, AbstractControl, NgModel, NgControl, ControlValueAccessor } from '@angular/forms';
@@ -187,7 +187,7 @@ type DwBadgeKind = 'count' | 'label';
187
187
  * <dw-badge value="Required" tone="accent" kind="label" />
188
188
  * <dw-badge value="admin" [bordered]="true" /> <!-- hairline outline, e.g. role pills -->
189
189
  * <dw-badge value="1 ms" kind="label" size="md" /> <!-- 12px, in detail headers -->
190
- * <dw-badge value="Jira" icon="assets/icons/jira.svg" /> <!-- image path icons work too -->
190
+ * <dw-badge value="Docs" [icon]="logoUrl" /> <!-- an image URL works too -->
191
191
  * ```
192
192
  */
193
193
  declare class DwBadgeComponent {
@@ -434,12 +434,12 @@ declare function initialsOf(name: string | null | undefined, strategy?: DwInitia
434
434
  /** A stable colour per name, for callers that opt in with `[tint]="tintFor(name)"`. */
435
435
  declare function tintFor(name: string | null | undefined): DwAvatarTint;
436
436
  /**
437
- * User / tenant avatar: image or initials on a bordered rounded square, neutral
437
+ * User / account avatar: image or initials on a bordered rounded square, neutral
438
438
  * grey unless a `tint` is given (the backend has no avatar colours).
439
439
  *
440
440
  * ```html
441
441
  * <dw-avatar [name]="user.fullName" size="sm" />
442
- * <dw-avatar [name]="tenant.accountName" initials="split" [presence]="tenant.active" />
442
+ * <dw-avatar [name]="account.name" initials="split" [presence]="account.online" />
443
443
  * ```
444
444
  */
445
445
  declare class DwAvatarComponent {
@@ -451,7 +451,7 @@ declare class DwAvatarComponent {
451
451
  readonly tint: _angular_core.InputSignal<DwAvatarTint>;
452
452
  readonly presence: _angular_core.InputSignal<boolean | null>;
453
453
  readonly tooltip: _angular_core.InputSignal<string>;
454
- /** Darkens the tile's border while its parent button is hovered or open (account menus). */
454
+ /** Darkens the tile's border while its parent button is hovered or open (e.g. an account menu). */
455
455
  readonly ring: _angular_core.InputSignal<boolean>;
456
456
  readonly imageFailed: _angular_core.WritableSignal<boolean>;
457
457
  readonly text: _angular_core.Signal<string>;
@@ -463,12 +463,13 @@ declare class DwAvatarComponent {
463
463
  type DwEntityKind = 'tool' | 'storage' | 'file' | 'image' | 'icon';
464
464
  type DwEntityTint = 'none' | 'neutral' | 'accent' | 'workflow' | 'reasoning' | 'orange' | 'cyan' | 'pink' | 'danger';
465
465
  /**
466
- * Entity / type icon. Resolves artwork through the shared icon utilities so
467
- * every screen picks the same asset for the same type.
466
+ * Entity / type icon: a tool, storage or file-type logo (inlined), an image, or an icon in a tinted tile.
467
+ * For `tool` / `storage`, `type` is a crystal icon key (`snowflake`, `s3`), or your own type value when the app maps
468
+ * it with `provideCrystalIconResolvers()`.
468
469
  *
469
470
  * ```html
470
- * <dw-entity-icon kind="tool" [type]="tool.typeId" [toolId]="tool.id" />
471
- * <dw-entity-icon kind="storage" [type]="conn.storageType" size="lg" [framed]="true" />
471
+ * <dw-entity-icon kind="tool" type="snowflake" />
472
+ * <dw-entity-icon kind="storage" type="s3" size="lg" [framed]="true" />
472
473
  * <dw-entity-icon kind="file" type="pdf" size="sm" />
473
474
  * <dw-entity-icon kind="icon" type="pi pi-sitemap" tint="accent" [framed]="true" />
474
475
  * <dw-entity-icon kind="icon" type="dwi-robot" tint="accent" [framed]="true" /> <!-- a dw-icon glyph, in the tint colour -->
@@ -476,8 +477,9 @@ type DwEntityTint = 'none' | 'neutral' | 'accent' | 'workflow' | 'reasoning' | '
476
477
  */
477
478
  declare class DwEntityIconComponent {
478
479
  readonly kind: _angular_core.InputSignal<DwEntityKind>;
479
- /** Tool typeId, storage type, file extension, image src, or icon class / `dwi-<name>` (per `kind`). */
480
+ /** Tool or storage icon key (or your type, see provideCrystalIconResolvers), file extension, image src, or icon class / `dwi-<name>` (per `kind`). */
480
481
  readonly type: _angular_core.InputSignal<string | null>;
482
+ /** Passed to your tool resolver (provideCrystalIconResolvers), for mappings that depend on the tool's id. */
481
483
  readonly toolId: _angular_core.InputSignal<string | null>;
482
484
  readonly src: _angular_core.InputSignal<string | null>;
483
485
  readonly fallback: _angular_core.InputSignal<string | undefined>;
@@ -488,6 +490,7 @@ declare class DwEntityIconComponent {
488
490
  readonly alt: _angular_core.InputSignal<string>;
489
491
  readonly failed: _angular_core.WritableSignal<boolean>;
490
492
  private readonly icons;
493
+ private readonly resolvers;
491
494
  /** kind `icon` with a `dwi-<name>` glyph or a registered icon name: drawn by dw-icon, in the tile's colour. */
492
495
  readonly svgIcon: _angular_core.Signal<string | null>;
493
496
  readonly iconClass: _angular_core.Signal<string>;
@@ -497,6 +500,31 @@ declare class DwEntityIconComponent {
497
500
  static ɵcmp: _angular_core.ɵɵComponentDeclaration<DwEntityIconComponent, "dw-entity-icon", never, { "kind": { "alias": "kind"; "required": false; "isSignal": true; }; "type": { "alias": "type"; "required": false; "isSignal": true; }; "toolId": { "alias": "toolId"; "required": false; "isSignal": true; }; "src": { "alias": "src"; "required": false; "isSignal": true; }; "fallback": { "alias": "fallback"; "required": false; "isSignal": true; }; "storageSet": { "alias": "storageSet"; "required": false; "isSignal": true; }; "size": { "alias": "size"; "required": false; "isSignal": true; }; "framed": { "alias": "framed"; "required": false; "isSignal": true; }; "tint": { "alias": "tint"; "required": false; "isSignal": true; }; "alt": { "alias": "alt"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
498
501
  }
499
502
 
503
+ /**
504
+ * Maps an app's own type values to crystal's icon keys, for `dw-entity-icon kind="tool" | "storage"`. Crystal knows only
505
+ * its artwork names (`snowflake`, `s3`…); an app whose data says e.g. `RELATIONAL_POSTGRES` tells it which icon that is.
506
+ * Return `null` / `undefined` for "no artwork" (the generic or fallback icon shows).
507
+ */
508
+ interface DwIconResolvers {
509
+ /** Your tool `type` → a tool icon key. `toolId` is the element's `toolId` input, if your mapping needs it. */
510
+ tool?: (type: string, context: {
511
+ toolId: string | null;
512
+ }) => string | null | undefined;
513
+ /** Your storage `type` → a storage icon key. */
514
+ storage?: (type: string) => string | null | undefined;
515
+ }
516
+ /** The resolvers given to `provideCrystalIconResolvers()`; none by default (`type` is then the icon key itself). */
517
+ declare const DW_ICON_RESOLVERS: InjectionToken<DwIconResolvers>;
518
+ /**
519
+ * Lets `dw-entity-icon` take your own type values:
520
+ *
521
+ * ```ts
522
+ * providers: [provideCrystalIconResolvers({ tool: (typeId) => myToolIconKey(typeId), storage: (t) => myStorageKey(t) })]
523
+ * // <dw-entity-icon kind="tool" [type]="tool.typeId" />
524
+ * ```
525
+ */
526
+ declare function provideCrystalIconResolvers(resolvers: DwIconResolvers): EnvironmentProviders;
527
+
500
528
  /**
501
529
  * The one spinner. Replaces `fa-spinner fa-spin`, ad-hoc `pi-spin`,
502
530
  * cosmetic `p-progressSpinner`, `.loading-state` and `.loading-overlay`.
@@ -811,7 +839,7 @@ declare class DwResizerComponent {
811
839
  }
812
840
 
813
841
  /**
814
- * Overlay anchors: a bar (e.g. the app header) marked `data-dw-overlay-anchor` makes every
842
+ * Overlay anchors: a bar (e.g. a fixed page header) marked `data-dw-overlay-anchor` makes every
815
843
  * dw-menu / dw-popover opened from inside it start just below the bar, rather than below
816
844
  * the individual trigger — so menus from a short avatar button and a full-height nav tab
817
845
  * line up on the same edge.
@@ -855,7 +883,7 @@ declare class DwCopyButtonComponent implements OnDestroy {
855
883
  }
856
884
 
857
885
  /**
858
- * The app-wide entity ID badge: a muted monospace ID (truncated to
886
+ * Entity ID badge: a muted monospace ID (truncated to
859
887
  * `first8...last4` by default) that reveals a copy icon on hover and copies
860
888
  * the full ID on click, flashing a "Copied!" confirmation.
861
889
  *
@@ -875,18 +903,28 @@ declare class IdBlockComponent implements OnDestroy {
875
903
  static ɵcmp: _angular_core.ɵɵComponentDeclaration<IdBlockComponent, "app-id-block, dw-id-block", never, { "value": { "alias": "value"; "required": false; "isSignal": true; }; "truncate": { "alias": "truncate"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
876
904
  }
877
905
 
878
- type MessageFn = (error: unknown, label: string) => string;
906
+ /** A message, or a function building one from the validator's error value and the field's label. */
907
+ type DwFieldMessage = string | ((error: unknown, label: string) => string);
908
+ /**
909
+ * Default validation messages for Angular's built-in validators, keyed by error key. An app adds messages for its own
910
+ * validators with `provideCrystalFieldMessages()`; a single field can override any of them through `dw-field [errors]`.
911
+ */
912
+ declare const DW_FIELD_MESSAGES: Readonly<Record<string, DwFieldMessage>>;
913
+ /** The app's own validator messages (provideCrystalFieldMessages), merged over the defaults; none by default. */
914
+ declare const DW_APP_FIELD_MESSAGES: InjectionToken<Readonly<Record<string, DwFieldMessage>>>;
879
915
  /**
880
- * Default validation messages, keyed by validator error key. Screens can
881
- * override any of them per field through `dw-field [errors]`.
916
+ * Messages for the app's own validators (and replacements for the defaults), used by every dw-field:
917
+ *
918
+ * ```ts
919
+ * providers: [provideCrystalFieldMessages({ phone: 'Enter a phone number', duplicate: 'This name already exists' })]
920
+ * ```
882
921
  */
883
- declare const DW_FIELD_MESSAGES: Readonly<Record<string, string | MessageFn>>;
922
+ declare function provideCrystalFieldMessages(messages: Readonly<Record<string, DwFieldMessage>>): EnvironmentProviders;
884
923
  /**
885
- * First matching message for a control's errors. Override map wins, then a
886
- * string error value (validators that return their own message), then the
887
- * defaults, then a generic fallback.
924
+ * First matching message for a control's errors. Override map wins, then a string error value (validators that
925
+ * return their own message), then the app's messages, then the defaults, then a generic fallback.
888
926
  */
889
- declare function fieldErrorMessage(errors: ValidationErrors | null | undefined, overrides?: Readonly<Record<string, string>> | null, label?: string): string;
927
+ declare function fieldErrorMessage(errors: ValidationErrors | null | undefined, overrides?: Readonly<Record<string, string>> | null, label?: string, appMessages?: Readonly<Record<string, DwFieldMessage>>): string;
890
928
 
891
929
  type DwShowErrorsWhen = 'touched' | 'dirty' | 'touchedOrDirty' | 'always';
892
930
  /**
@@ -911,6 +949,7 @@ type DwShowErrorsWhen = 'touched' | 'dirty' | 'touchedOrDirty' | 'always';
911
949
  declare class DwFieldComponent {
912
950
  private readonly host;
913
951
  private readonly destroyRef;
952
+ private readonly appMessages;
914
953
  readonly label: _angular_core.InputSignal<string>;
915
954
  /** Explicit control id; generated when omitted. */
916
955
  readonly for: _angular_core.InputSignal<string | null>;
@@ -1233,7 +1272,7 @@ type DwCardTint = 'neutral' | 'accent' | 'workflow' | 'reasoning' | 'orange' | '
1233
1272
  * <dw-card variant="stat" label="Runs" [value]="1204" [interactive]="true" [selected]="filter === 'runs'" />
1234
1273
  *
1235
1274
  * <!-- Stat with the info icon and an expand chevron at the end of the label row, a muted suffix -->
1236
- * <dw-card variant="stat" label="Invoices" [value]="'1,341'" valueSuffix="/ 1,500" tooltip="…" infoPosition="end">
1275
+ * <dw-card variant="stat" label="Orders" [value]="'1,341'" valueSuffix="/ 1,500" tooltip="…" infoPosition="end">
1237
1276
  * <i dwStatLabelEnd class="pi pi-chevron-down"></i>
1238
1277
  * </dw-card>
1239
1278
  *
@@ -1307,7 +1346,7 @@ declare class DwToggleCardBodyDirective {
1307
1346
  *
1308
1347
  * ```html
1309
1348
  * <dw-toggle-card title="Full Text Search Index" description="Enable full text search"
1310
- * icon="assets/images/svgIcon/text-search.svg" [expanded]="form.value.fullTextSearchIndex"
1349
+ * icon="pi pi-search" [expanded]="form.value.fullTextSearchIndex"
1311
1350
  * [disabledReason]="graphDbOn ? '' : 'Requires Graph Database Storage to be enabled'">
1312
1351
  * <p-toggleswitch dwToggleCardControl formControlName="fullTextSearchIndex" />
1313
1352
  * <ng-template dwToggleCardBody>…configuration fields…</ng-template>
@@ -1340,7 +1379,7 @@ declare const DW_TOGGLE_CARD: readonly [typeof DwToggleCardComponent, typeof DwT
1340
1379
  *
1341
1380
  * ```html
1342
1381
  * <div class="dw-tile-grid">
1343
- * <dw-tile label="Snowflake" icon="assets/snowflake.svg" [count]="3" (activate)="open('snowflake')" />
1382
+ * <dw-tile label="Snowflake" icon="pi pi-database" [count]="3" (activate)="open('snowflake')" />
1344
1383
  * <dw-tile label="Slack" icon="pi pi-slack" badge="Coming soon" [disabled]="true" />
1345
1384
  * </div>
1346
1385
  * ```
@@ -1561,14 +1600,14 @@ declare class DwBreadcrumbComponent {
1561
1600
  * subtitle, count, deprecated badge, meta row and right-side actions.
1562
1601
  *
1563
1602
  * ```html
1564
- * <dw-page-header title="My agents" [count]="total">
1603
+ * <dw-page-header title="Projects" [count]="total">
1565
1604
  * <dw-button dwPageHeaderActions label="Create" icon="pi pi-plus" (clicked)="create()" />
1566
1605
  * </dw-page-header>
1567
1606
  *
1568
- * <dw-page-header [breadcrumbs]="[{label:'LLM Configuration', action: back}, {label: cfg.name}]"
1569
- * icon="assets/images/svgIcon/llm.svg" variant="panel" [showClose]="true" (close)="close()" />
1607
+ * <dw-page-header [breadcrumbs]="[{label:'Settings', action: back}, {label: item.name}]"
1608
+ * icon="pi pi-cog" variant="panel" [showClose]="true" (close)="close()" />
1570
1609
  *
1571
- * <dw-page-header variant="list" [flush]="true" title="Tenant Analytics" /> <!-- on the content edge -->
1610
+ * <dw-page-header variant="list" [flush]="true" title="Analytics" /> <!-- on the content edge -->
1572
1611
  *
1573
1612
  * <dw-page-header [title]="agent.name" [editableTitle]="true" (titleChange)="rename($event)"
1574
1613
  * [showBack]="true" (back)="goBack()">
@@ -1782,8 +1821,8 @@ declare class DwNavListComponent {
1782
1821
  /** Nested items hang off guide lines instead of plain indentation (reference trees). */
1783
1822
  readonly treeLines: _angular_core.InputSignal<boolean>;
1784
1823
  /**
1785
- * The accent left border on the selected item. Only the agents list page's sidebar uses it;
1786
- * everywhere else a selection is the plain selected fill.
1824
+ * The accent left border on the selected item, for a sidebar that wants a stronger marker;
1825
+ * otherwise a selection is the plain selected fill.
1787
1826
  */
1788
1827
  readonly marker: _angular_core.InputSignal<boolean>;
1789
1828
  /** Where item tooltips open: beside a sidebar (right, the default) or above, e.g. in a wide panel. */
@@ -1934,10 +1973,10 @@ interface DwConfirmSummaryRow {
1934
1973
  * copied `.delete-modal-*` markup.
1935
1974
  *
1936
1975
  * ```html
1937
- * <dw-confirm-dialog [(visible)]="confirmOpen" header="Delete workspace"
1938
- * [message]="'Delete “' + ws.name + '”? This cannot be undone.'"
1976
+ * <dw-confirm-dialog [(visible)]="confirmOpen" header="Delete project"
1977
+ * [message]="'Delete “' + project.name + '”? This cannot be undone.'"
1939
1978
  * acceptLabel="Delete" loadingLabel="Deleting…" [loading]="deleting"
1940
- * [warning]="{ title: 'In use', text: '3 collections use this workspace' }"
1979
+ * [warning]="{ title: 'In use', text: '3 reports use this project' }"
1941
1980
  * (accept)="delete()" />
1942
1981
  * ```
1943
1982
  * Project extra body content (radio options, dependency lists) as children.
@@ -2087,7 +2126,7 @@ declare class DwDrawerComponent {
2087
2126
  readonly breadcrumbs: _angular_core.InputSignal<readonly DwBreadcrumb[]>;
2088
2127
  readonly showBack: _angular_core.InputSignal<boolean>;
2089
2128
  readonly showCloseIcon: _angular_core.InputSignal<boolean>;
2090
- /** False when the body brings its own header and close control (e.g. the probe view). */
2129
+ /** False when the body brings its own header and close control. */
2091
2130
  readonly showHeader: _angular_core.InputSignal<boolean>;
2092
2131
  readonly modal: _angular_core.InputSignal<boolean>;
2093
2132
  /** Close on mask click. */
@@ -2154,8 +2193,8 @@ declare class DwPopoverFooterDirective {
2154
2193
  * and footer actions.
2155
2194
  *
2156
2195
  * ```html
2157
- * <dw-button label="New tenant" (clicked)="pop.toggle($event)" />
2158
- * <dw-popover #pop header="Create tenant" width="320px">
2196
+ * <dw-button label="New project" (clicked)="pop.toggle($event)" />
2197
+ * <dw-popover #pop header="Create project" width="320px">
2159
2198
  * <input pInputText [(ngModel)]="name" />
2160
2199
  * <div dwPopoverFooter>
2161
2200
  * <dw-button label="Cancel" variant="secondary" appearance="text" (clicked)="pop.hide()" />
@@ -2234,7 +2273,7 @@ interface DwToast {
2234
2273
  *
2235
2274
  * ```ts
2236
2275
  * this.toast.success('Agent saved');
2237
- * this.toast.error('Could not delete workspace', { sticky: true });
2276
+ * this.toast.error('Could not delete the project', { sticky: true });
2238
2277
  * ```
2239
2278
  */
2240
2279
  declare class DwToastService implements OnDestroy {
@@ -2261,7 +2300,7 @@ declare class DwToastService implements OnDestroy {
2261
2300
  type DwToastPosition = 'top-center' | 'top-right' | 'bottom-center' | 'bottom-right';
2262
2301
  /**
2263
2302
  * Renders the DwToastService stack. Place it once, in the app's root component; every screen pushes toasts through
2264
- * DwToastService and they all show here, with one position and one look (dataworkz-ui's toasts as they look today).
2303
+ * DwToastService and they all show here, with one position and one look.
2265
2304
  *
2266
2305
  * ```html
2267
2306
  * <router-outlet />
@@ -2270,7 +2309,7 @@ type DwToastPosition = 'top-center' | 'top-right' | 'bottom-center' | 'bottom-ri
2270
2309
  */
2271
2310
  declare class DwToastHostComponent {
2272
2311
  private readonly toasts;
2273
- /** Where the stack sits. Default: centred under the top edge, as in dataworkz-ui today. */
2312
+ /** Where the stack sits. Default: centred under the top edge. */
2274
2313
  readonly position: _angular_core.InputSignal<DwToastPosition>;
2275
2314
  /** Most toasts shown at once; the newest win, older ones wait until these go. */
2276
2315
  readonly max: _angular_core.InputSignal<number>;
@@ -2502,7 +2541,7 @@ declare class DwTableComponent<T = any> {
2502
2541
  readonly rowClass: _angular_core.InputSignal<((row: T) => string | string[] | Record<string, boolean> | null) | null>;
2503
2542
  readonly actionsHeader: _angular_core.InputSignal<string>;
2504
2543
  readonly actionsWidth: _angular_core.InputSignal<string>;
2505
- /** `start`: the actions column comes right after the first column, frozen left (agents list). */
2544
+ /** `start`: the actions column comes right after the first column, frozen left. */
2506
2545
  readonly actionsPlacement: _angular_core.InputSignal<"start" | "end">;
2507
2546
  /** A row's menu (Edit, Delete…): the actions column gets a ⋮ that opens it. */
2508
2547
  readonly rowMenuItems: _angular_core.InputSignal<((row: T) => DwMenuItem<T>[]) | null>;
@@ -2655,7 +2694,7 @@ declare class DwIconComponent {
2655
2694
  static ɵcmp: _angular_core.ɵɵComponentDeclaration<DwIconComponent, "dw-icon", never, { "name": { "alias": "name"; "required": true; "isSignal": true; }; "size": { "alias": "size"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
2656
2695
  }
2657
2696
 
2658
- /** Icon names starting with this (any case) are crystal's: `dw…` and `dwi-…` (MIGRATION-PLAN D16). */
2697
+ /** Icon names starting with this (any case) are crystal's: `dw…` and `dwi-…`. */
2659
2698
  declare const DW_RESERVED_ICON_PREFIX = "dw";
2660
2699
  /**
2661
2700
  * The consumer's own SVG icons, by name. A consumer registers markup under any name that doesn't start with `dw`, and
@@ -2770,10 +2809,10 @@ interface CrystalThemeConfig {
2770
2809
  apply?: boolean;
2771
2810
  /** Theme used until the viewer picks one. Default 'light'. */
2772
2811
  initial?: DwTheme;
2773
- /** localStorage key for the viewer's choice. Default 'dw-theme' (dataworkz-ui's key, so stored choices survive). */
2812
+ /** localStorage key for the viewer's choice. Default 'dw-theme' (kept stable, so stored choices survive upgrades). */
2774
2813
  storageKey?: string;
2775
2814
  }
2776
- /** What `provideCrystal()` configures. Theme only (MIGRATION-PLAN §3.2). */
2815
+ /** What `provideCrystal()` configures: the theme. */
2777
2816
  interface CrystalConfig {
2778
2817
  theme?: CrystalThemeConfig;
2779
2818
  }
@@ -2787,7 +2826,7 @@ declare const DW_CRYSTAL_CONFIG: InjectionToken<CrystalConfig>;
2787
2826
  *
2788
2827
  * `provideCrystal()` applies it once at start-up so a stored dark choice
2789
2828
  * doesn't flash light. With `theme.apply: false` (federated elements on a
2790
- * legacy host page) it never touches <html>.
2829
+ * page crystal doesn't own) it never touches <html>.
2791
2830
  */
2792
2831
  declare class ThemeService {
2793
2832
  private readonly document;
@@ -2806,7 +2845,7 @@ declare class ThemeService {
2806
2845
  }
2807
2846
 
2808
2847
  /**
2809
- * Crystal's app-level setup: the theme (MIGRATION-PLAN §3.2). With `theme.apply` (the default) it puts the stored or
2848
+ * Crystal's app-level setup: the theme. With `theme.apply` (the default) it puts the stored or
2810
2849
  * initial theme on <html> before the first render, so a dark choice doesn't flash light.
2811
2850
  *
2812
2851
  * ```ts
@@ -2823,7 +2862,7 @@ interface CrystalHostThemeOptions {
2823
2862
  fonts?: boolean;
2824
2863
  }
2825
2864
  /**
2826
- * Themes a page crystal doesn't own: for components delivered as federated custom elements (MIGRATION-PLAN §3.5).
2865
+ * Themes a page crystal doesn't own: for components delivered as federated custom elements.
2827
2866
  * Prepends one `<style data-dw-crystal-theme>` ahead of the host's stylesheets (so the host wins equal-specificity
2828
2867
  * ties) holding the host-safe theme: tokens incl. dark, the element base, component CSS and utilities, no resets and
2829
2868
  * no html / body rules. Fonts are embedded, since relative URLs can't resolve from an injected `<style>`.
@@ -2840,5 +2879,5 @@ declare function installCrystalHostTheme({ fonts }?: CrystalHostThemeOptions): v
2840
2879
  /** Removes the host theme again (e.g. a host that unloads crystal, or a test). */
2841
2880
  declare function removeCrystalHostTheme(): void;
2842
2881
 
2843
- export { DW_CLOCK_TICK_MS, DW_CRYSTAL_CONFIG, DW_DIALOG, DW_DRAWER, DW_FIELD_MESSAGES, DW_HOST_THEME_ATTR, DW_IN_PROGRESS_STATUSES, DW_LAYOUT, DW_MENU_PLAIN_GROUP, DW_OVERLAY_ANCHOR_ATTR, DW_OVERLAY_ANCHOR_GAP, DW_POPOVER, DW_RESERVED_ICON_PREFIX, DW_STATUS_TONES, DW_TABLE, DW_TAG_PALETTE, DW_THEME_STORAGE_KEY, DW_TOGGLE_CARD, DwActionBarComponent, DwAvatarComponent, DwBadgeComponent, DwBannerComponent, DwBoxComponent, DwBreadcrumbComponent, DwButtonComponent, DwCardComponent, DwCellDirective, DwCheckToggleComponent, DwChipComponent, DwClockService, DwColumnPickerComponent, DwConfirmDialogComponent, DwConfirmHostComponent, DwConfirmService, DwCopyButtonComponent, DwDialogComponent, DwDialogFooterDirective, DwDialogHeaderDirective, DwDialogTitleSuffixDirective, DwDividerComponent, DwDrawerComponent, DwDrawerFooterDirective, DwDrawerHeaderDirective, DwDrawerSubheaderDirective, DwEmptyStateComponent, DwEntityIconComponent, DwFieldComponent, DwFileDropzoneComponent, DwFileListComponent, DwFormSectionHeaderComponent, DwGridDirective, DwHeaderDirective, DwHstackDirective, DwIconButtonComponent, DwIconComponent, DwIconRegistry, IdBlockComponent as DwIdBlockComponent, DwMenuComponent, DwMenuHeaderDirective, DwMeterComponent, DwNavItemActionsDirective, DwNavItemExtraDirective, DwNavListComponent, DwPageHeaderComponent, DwPopoverComponent, DwPopoverFooterDirective, DwRailTabsComponent, DwResizerComponent, DwRowActionsDirective, DwRowExpansionDirective, DwSearchInputComponent, DwSectionComponent, DwSkeletonComponent, DwSpinnerComponent, DwStackDirective, DwStatusPillComponent, DwTabPanelDirective, DwTableComponent, DwTableEmptyComponent, DwTabsComponent, DwTagColorButtonComponent, DwTagColorPickerComponent, DwTagComponent, DwTagListComponent, DwTileComponent, DwTimestampComponent, DwToastHostComponent, DwToastService, DwToggleCardBodyDirective, DwToggleCardComponent, DwToggleCardControlDirective, DwTooltipIfTruncatedDirective, ThemeService, alignUnderOverlayAnchor, extensionOf, fieldErrorMessage, formatBytes, gapToken, hashTagIndex, humanizeStatus, initialsOf, installCrystalHostTheme, isImageIcon, isTruncated, normalizeStatus, provideCrystal, provideCrystalIcons, removeCrystalHostTheme, tagColorVar, tintFor, toneForStatus };
2844
- export type { CrystalConfig, CrystalHostThemeOptions, CrystalThemeConfig, DwAlign, DwAvatarTint, DwBadgeKind, DwBadgeTone, DwBreadcrumb, DwButtonAppearance, DwButtonSize, DwButtonVariant, DwCanClose, DwCardTint, DwCardVariant, DwColumn, DwConfirmOptions, DwConfirmSeverity, DwConfirmSummaryRow, DwConfirmWarning, DwDialogSize, DwDividerOrientation, DwDividerSpacing, DwDrawerAction, DwDrawerSize, DwEntityKind, DwEntityTint, DwFileItem, DwFileRejectReason, DwFileRejection, DwFileStatus, DwGap, DwIconButtonVariant, DwInitialsStrategy, DwJustify, DwMenuItem, DwNavGroup, DwNavItem, DwNavItemDot, DwNavReorder, DwRailTab, DwResizerDrag, DwRowClickEvent, DwSeverity, DwShowErrorsWhen, DwSkeletonPreset, DwSupportedType, DwTabOption, DwTabValue, DwTagItem, DwTheme, DwToast, DwToastOptions, DwToastPosition, DwToastSeverity, DwTone };
2882
+ export { DW_APP_FIELD_MESSAGES, DW_CLOCK_TICK_MS, DW_CRYSTAL_CONFIG, DW_DIALOG, DW_DRAWER, DW_FIELD_MESSAGES, DW_HOST_THEME_ATTR, DW_ICON_RESOLVERS, DW_IN_PROGRESS_STATUSES, DW_LAYOUT, DW_MENU_PLAIN_GROUP, DW_OVERLAY_ANCHOR_ATTR, DW_OVERLAY_ANCHOR_GAP, DW_POPOVER, DW_RESERVED_ICON_PREFIX, DW_STATUS_TONES, DW_TABLE, DW_TAG_PALETTE, DW_THEME_STORAGE_KEY, DW_TOGGLE_CARD, DwActionBarComponent, DwAvatarComponent, DwBadgeComponent, DwBannerComponent, DwBoxComponent, DwBreadcrumbComponent, DwButtonComponent, DwCardComponent, DwCellDirective, DwCheckToggleComponent, DwChipComponent, DwClockService, DwColumnPickerComponent, DwConfirmDialogComponent, DwConfirmHostComponent, DwConfirmService, DwCopyButtonComponent, DwDialogComponent, DwDialogFooterDirective, DwDialogHeaderDirective, DwDialogTitleSuffixDirective, DwDividerComponent, DwDrawerComponent, DwDrawerFooterDirective, DwDrawerHeaderDirective, DwDrawerSubheaderDirective, DwEmptyStateComponent, DwEntityIconComponent, DwFieldComponent, DwFileDropzoneComponent, DwFileListComponent, DwFormSectionHeaderComponent, DwGridDirective, DwHeaderDirective, DwHstackDirective, DwIconButtonComponent, DwIconComponent, DwIconRegistry, IdBlockComponent as DwIdBlockComponent, DwMenuComponent, DwMenuHeaderDirective, DwMeterComponent, DwNavItemActionsDirective, DwNavItemExtraDirective, DwNavListComponent, DwPageHeaderComponent, DwPopoverComponent, DwPopoverFooterDirective, DwRailTabsComponent, DwResizerComponent, DwRowActionsDirective, DwRowExpansionDirective, DwSearchInputComponent, DwSectionComponent, DwSkeletonComponent, DwSpinnerComponent, DwStackDirective, DwStatusPillComponent, DwTabPanelDirective, DwTableComponent, DwTableEmptyComponent, DwTabsComponent, DwTagColorButtonComponent, DwTagColorPickerComponent, DwTagComponent, DwTagListComponent, DwTileComponent, DwTimestampComponent, DwToastHostComponent, DwToastService, DwToggleCardBodyDirective, DwToggleCardComponent, DwToggleCardControlDirective, DwTooltipIfTruncatedDirective, ThemeService, alignUnderOverlayAnchor, extensionOf, fieldErrorMessage, formatBytes, gapToken, hashTagIndex, humanizeStatus, initialsOf, installCrystalHostTheme, isImageIcon, isTruncated, normalizeStatus, provideCrystal, provideCrystalFieldMessages, provideCrystalIconResolvers, provideCrystalIcons, removeCrystalHostTheme, tagColorVar, tintFor, toneForStatus };
2883
+ export type { CrystalConfig, CrystalHostThemeOptions, CrystalThemeConfig, DwAlign, DwAvatarTint, DwBadgeKind, DwBadgeTone, DwBreadcrumb, DwButtonAppearance, DwButtonSize, DwButtonVariant, DwCanClose, DwCardTint, DwCardVariant, DwColumn, DwConfirmOptions, DwConfirmSeverity, DwConfirmSummaryRow, DwConfirmWarning, DwDialogSize, DwDividerOrientation, DwDividerSpacing, DwDrawerAction, DwDrawerSize, DwEntityKind, DwEntityTint, DwFieldMessage, DwFileItem, DwFileRejectReason, DwFileRejection, DwFileStatus, DwGap, DwIconButtonVariant, DwIconResolvers, DwInitialsStrategy, DwJustify, DwMenuItem, DwNavGroup, DwNavItem, DwNavItemDot, DwNavReorder, DwRailTab, DwResizerDrag, DwRowClickEvent, DwSeverity, DwShowErrorsWhen, DwSkeletonPreset, DwSupportedType, DwTabOption, DwTabValue, DwTagItem, DwTheme, DwToast, DwToastOptions, DwToastPosition, DwToastSeverity, DwTone };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dataworkz/crystal",
3
- "version": "0.1.0-beta.0",
3
+ "version": "0.1.0-beta.2",
4
4
  "description": "Dataworkz core UI for Angular: dw-* components, icons, toasts, design tokens, theme CSS and bundled fonts.",
5
5
  "license": "MIT",
6
6
  "author": "Dataworkz",
@@ -5,7 +5,7 @@ import { PrimeNGConfigType } from 'primeng/config';
5
5
 
6
6
  /**
7
7
  * Azure Electric primary ramp. Same hex values as `--dw-primary-*` in
8
- * src/styles/tokens/primitives.css — PrimeNG needs literal hex for the
8
+ * tokens/primitives.css — PrimeNG needs literal hex for the
9
9
  * primitive ramp because it derives other tokens from it at build time.
10
10
  */
11
11
  declare const AZURE_PRIMARY_RAMP: {
@@ -23,8 +23,8 @@ declare const AZURE_PRIMARY_RAMP: {
23
23
  };
24
24
  /**
25
25
  * PrimeNG color scheme, used for both light and dark. Every value points at a
26
- * design-system CSS variable, so PrimeNG follows src/styles/tokens/semantic.css
27
- * and semantic-dark.css: switching theme re-points the variables, the preset
26
+ * design-system CSS variable, so PrimeNG follows the semantic tokens (tokens/semantic.css
27
+ * and semantic-dark.css): switching theme re-points the variables, the preset
28
28
  * never changes. (The surface ramp is the raw neutral scale, light → dark,
29
29
  * which is the order Aura's own light and dark schemes expect.)
30
30
  */
@@ -610,6 +610,35 @@ declare const DwPreset: _primeuix_themes_types.Preset<_primeuix_themes_aura_base
610
610
 
611
611
  /** PrimeNG's dark mode follows the attribute ThemeService (and provideCrystal()) put on <html>. */
612
612
  declare const DW_DARK_MODE_SELECTOR = "[data-theme=\"dark\"]";
613
+ /** Panel class that sizes a select's option list for a small trigger (components/form.css). */
614
+ declare const DW_SELECT_PANEL_SM = "dw-select-panel--sm";
615
+ type SizedInstance = {
616
+ size?: () => string | null | undefined;
617
+ };
618
+ /**
619
+ * Crystal's pass-through defaults: a small `p-select` / `p-multiselect` gets small options even when its list is
620
+ * appended to <body> (where CSS can't see the trigger).
621
+ */
622
+ declare const DW_PRIMENG_PT: {
623
+ readonly select: {
624
+ readonly overlay: ({ instance }: {
625
+ instance?: SizedInstance;
626
+ }) => {
627
+ class: string;
628
+ } | {
629
+ class?: undefined;
630
+ };
631
+ };
632
+ readonly multiselect: {
633
+ readonly overlay: ({ instance }: {
634
+ instance?: SizedInstance;
635
+ }) => {
636
+ class: string;
637
+ } | {
638
+ class?: undefined;
639
+ };
640
+ };
641
+ };
613
642
  /**
614
643
  * PrimeNG with the Dataworkz preset, dark mode on `[data-theme="dark"]`. Pass app-specific PrimeNG settings
615
644
  * (ripple, zIndex, translation…) as `config`; its `theme.options` are merged over crystal's.
@@ -620,4 +649,4 @@ declare const DW_DARK_MODE_SELECTOR = "[data-theme=\"dark\"]";
620
649
  */
621
650
  declare function provideCrystalPrimeNG(config?: PrimeNGConfigType): EnvironmentProviders;
622
651
 
623
- export { AZURE_PRIMARY_RAMP, DW_COLOR_SCHEME, DW_DARK_MODE_SELECTOR, DW_PRESET_OVERRIDES, DwPreset, provideCrystalPrimeNG };
652
+ export { AZURE_PRIMARY_RAMP, DW_COLOR_SCHEME, DW_DARK_MODE_SELECTOR, DW_PRESET_OVERRIDES, DW_PRIMENG_PT, DW_SELECT_PANEL_SM, DwPreset, provideCrystalPrimeNG };
package/styles/base.css CHANGED
@@ -1,12 +1,12 @@
1
1
  /* ============================================================================
2
2
  Dataworkz Design System — BASE
3
- The ONLY place in the app that declares font-family (element-base.css is
4
- its equivalent for the federated elements on the legacy page). Everything else
3
+ The ONLY place in the theme that declares font-family (element-base.css is
4
+ its equivalent for components embedded in a page crystal doesn't own). Everything else
5
5
  inherits (`font: inherit`) or uses the typography classes.
6
6
  ============================================================================ */
7
7
 
8
- /* ── Reset — the element defaults the app was built on (ported from the
9
- Bootstrap 4 Reboot when Bootstrap was removed) ── */
8
+ /* ── Reset — the element defaults the components are built on (in the spirit of the
9
+ Bootstrap 4 Reboot) ── */
10
10
  *,
11
11
  *::before,
12
12
  *::after {
@@ -325,6 +325,9 @@
325
325
  .dw-icon-btn.is-active { background: var(--dw-accent-tint); color: var(--dw-accent); }
326
326
  /* Hovering the active (selected) button keeps it accented, a step stronger */
327
327
  .dw-icon-btn.is-active:hover:not(:disabled) { background: var(--dw-accent-tint-strong); color: var(--dw-accent); }
328
+ /* A selected danger toggle (e.g. a "not helpful" rating) keeps its danger colour instead of the accent. */
329
+ .dw-icon-btn--danger.is-active,
330
+ .dw-icon-btn--danger.is-active:hover:not(:disabled) { background: var(--dw-danger-tint); color: var(--dw-danger-solid); }
328
331
  .dw-icon-btn--inverse { color: var(--dw-text-muted); }
329
332
  .dw-icon-btn--inverse:hover:not(:disabled),
330
333
  .dw-icon-btn--inverse.is-active { background: color-mix(in srgb, var(--dw-text-inverse) 12%, transparent); color: var(--dw-text-inverse); }
@@ -153,108 +153,6 @@ dw-markdown.dw-prose { display: block; }
153
153
  .dw-prose--compact { font-size: var(--dw-font-size-12); line-height: 1.5; }
154
154
  .dw-prose--compact p { margin-bottom: var(--dw-space-1); }
155
155
 
156
- /* ── Citation chip — numbered source reference in rendered answers (RAG run,
157
- Q&A history, probe). The markup is generated by the RAG answer services. ── */
158
- .dw-rag-cite-chip {
159
- display: inline-flex;
160
- align-items: center;
161
- justify-content: center;
162
- min-width: 22px;
163
- height: 22px;
164
- padding: 0 6px;
165
- margin: 0 2px;
166
- border-radius: var(--dw-radius-sm);
167
- border: 1px solid var(--dw-border-accent);
168
- background: var(--dw-accent-tint);
169
- color: var(--dw-accent-text);
170
- font-size: var(--dw-font-size-12);
171
- font-weight: var(--dw-font-weight-semibold);
172
- line-height: var(--dw-line-height-20);
173
- text-decoration: none;
174
- vertical-align: middle;
175
- }
176
-
177
- a.dw-rag-cite-chip:hover {
178
- background: var(--dw-accent-tint-strong);
179
- text-decoration: none;
180
- }
181
-
182
156
  /* ── dw-icon: app SVG glyphs, drawn in currentColor at the text size ── */
183
157
  .dw-icon { display: inline-flex; flex-shrink: 0; align-items: center; justify-content: center; line-height: 0; vertical-align: -0.125em; }
184
158
  .dw-icon svg { display: block; }
185
-
186
- /* ── Chat message: avatar · author line · bubble ──
187
- <div class="dw-msg dw-msg--user"><span class="dw-msg__avatar"><i class="pi pi-user"></i></span>
188
- <div class="dw-msg__main"><div class="dw-msg__head"><span class="dw-msg__author">Ana</span>
189
- <span class="dw-msg__role">User query</span></div><div class="dw-msg__bubble">…</div></div></div> */
190
- .dw-msg { display: flex; gap: 10px; }
191
- .dw-msg + .dw-msg { margin-top: 14px; }
192
- .dw-msg__avatar {
193
- display: inline-flex;
194
- flex-shrink: 0;
195
- align-items: center;
196
- justify-content: center;
197
- width: 30px;
198
- height: 30px;
199
- margin-top: 2px;
200
- border: 1px solid var(--dw-border);
201
- border-radius: var(--dw-radius-full);
202
- background: var(--dw-surface-pressed);
203
- color: var(--dw-text-secondary);
204
- font-size: var(--dw-font-size-12);
205
- }
206
- .dw-msg__main { flex: 1; min-width: 0; }
207
- .dw-msg__head { display: flex; align-items: center; gap: 6px; margin-bottom: var(--dw-space-1); }
208
- .dw-msg__author { color: var(--dw-text); font-size: var(--dw-font-size-12); font-weight: var(--dw-font-weight-semibold); }
209
- .dw-msg__role { color: var(--dw-text-secondary); font-size: var(--dw-font-size-12); }
210
- .dw-msg__bubble {
211
- padding: 10px 14px;
212
- border: 1px solid var(--dw-border);
213
- border-radius: var(--dw-radius-md) var(--dw-radius-md) var(--dw-radius-md) 2px;
214
- background: var(--dw-surface-pressed);
215
- color: var(--dw-text);
216
- font-size: var(--dw-font-size-14);
217
- line-height: var(--dw-line-height-20);
218
- white-space: pre-wrap;
219
- overflow-wrap: anywhere;
220
- }
221
- .dw-msg--user .dw-msg__avatar { border-color: var(--dw-border-accent); background: var(--dw-accent-tint); color: var(--dw-accent); }
222
- .dw-msg--user .dw-msg__bubble { border-color: var(--dw-border-accent); background: var(--dw-accent-tint); color: var(--dw-accent-text); }
223
- .dw-msg--agent .dw-msg__avatar { border-color: var(--dw-status-success-border); background: var(--dw-status-success-bg); color: var(--dw-status-success-fg); }
224
-
225
- /* ── Chat composer: a borderless textarea + toolbar inside one card ──
226
- <div class="dw-composer"><textarea class="dw-composer__input" …></textarea>
227
- <div class="dw-composer__toolbar"><dw-button …/><span class="dw-composer__spacer"></span>
228
- <span class="dw-composer__hint">⌘ Enter</span><dw-button label="Send" …/></div></div> */
229
- .dw-composer {
230
- display: flex;
231
- flex-direction: column;
232
- gap: var(--dw-space-2);
233
- padding: var(--dw-space-3) var(--dw-space-3) var(--dw-space-2);
234
- border: 1px solid var(--dw-border);
235
- border-radius: var(--dw-radius-xl);
236
- background: var(--dw-surface);
237
- box-shadow: var(--dw-shadow-sm);
238
- transition: border-color var(--dw-dur-micro) var(--dw-ease), box-shadow var(--dw-dur-micro) var(--dw-ease);
239
- }
240
- .dw-composer:focus-within { border-color: var(--dw-border-accent); box-shadow: var(--dw-focus-ring); }
241
- .dw-composer__input {
242
- width: 100%;
243
- min-height: 84px;
244
- max-height: 220px;
245
- padding: 0;
246
- border: 0;
247
- outline: none;
248
- resize: none;
249
- background: transparent;
250
- color: var(--dw-text);
251
- font-size: var(--dw-font-size-14);
252
- line-height: var(--dw-line-height-20);
253
- }
254
- .dw-composer__input::placeholder { color: var(--dw-text-muted); }
255
- .dw-composer__toolbar { display: flex; align-items: center; gap: var(--dw-space-2); }
256
- .dw-composer__spacer { flex: 1; }
257
- .dw-composer__hint {
258
- color: var(--dw-text-muted);
259
- font-size: var(--dw-font-size-12);
260
- }
@@ -79,7 +79,7 @@
79
79
  overflow-wrap: anywhere;
80
80
  word-break: break-word;
81
81
  }
82
- /* Dense detail panels (e.g. the Probe): 13px values; key column and spacing unchanged. */
82
+ /* Dense detail panels: 13px values; key column and spacing unchanged. */
83
83
  .dw-kv-list--sm .dw-kv-list__value { font-size: var(--dw-font-size-13); }
84
84
  .dw-kv-list__action { flex-shrink: 0; opacity: 0; transition: opacity var(--dw-dur-micro) var(--dw-ease); }
85
85
  .dw-kv-list__row:hover .dw-kv-list__action,
@@ -470,8 +470,9 @@ p-slider {
470
470
 
471
471
 
472
472
  /* Small selects (size="small"): their option list matches the 12px trigger instead of the default
473
- 14px rows. The list renders inside the select unless it is appended elsewhere (appendTo); a list
474
- appended to <body> takes the panel class `dw-select-panel--sm` for the same sizing. */
473
+ 14px rows. A list rendered inside the select matches `.p-select-sm`; a list appended elsewhere
474
+ (appendTo="body") gets `dw-select-panel--sm` from provideCrystalPrimeNG()'s pass-through, so no
475
+ screen sets it by hand. */
475
476
  .p-select-sm .p-select-option,
476
477
  .p-multiselect-sm .p-multiselect-option,
477
478
  .dw-select-panel--sm .p-select-option,
@@ -406,8 +406,8 @@
406
406
  .dw-avatar--tint-cyan { background: var(--dw-icon-tint-cyan); color: var(--dw-icon-tint-cyan-fg); }
407
407
  .dw-avatar--tint-pink { background: var(--dw-icon-tint-pink); color: var(--dw-icon-tint-pink-fg); }
408
408
 
409
- /* Ring (account menus): the border darkens while its button is hovered or open,
410
- like the other header controls (e.g. the tenant switcher). */
409
+ /* Ring (e.g. an account menu button): the border darkens while its button is hovered or open,
410
+ like other header controls. */
411
411
  .dw-avatar--ring { transition: border-color var(--dw-dur-micro); }
412
412
 
413
413
  button:hover > dw-avatar .dw-avatar--ring,
@@ -1,4 +1,4 @@
1
- /* ── Toasts (dw-toast-host): today's dataworkz-ui look, ported from app-notifications ──
1
+ /* ── Toasts (dw-toast-host) ──
2
2
  Rounded pills in the status colours, stacked under the top edge, centred on half the page width.
3
3
  z-index 9999 as today: it keeps toasts above PrimeNG overlays, whose z-index grows with every one opened. */
4
4
  .dw-toast-host { display: contents; }
@@ -1,7 +1,6 @@
1
1
  /*
2
2
  * @dataworkz/crystal — the full app theme without @font-face, shipped as @dataworkz/crystal/styles/crystal-no-fonts.css.
3
- * For a page that already loads Inter and IBM Plex Mono itself. Same order as dataworkz-ui's src/styles/index.css,
4
- * minus its legacy CSS and app-header.css (they stay in the app).
3
+ * For a page that already loads Inter and IBM Plex Mono itself. Same layers and order as crystal.css.
5
4
  *
6
5
  * Rules: colours only in tokens/primitives.css (everything else uses semantic tokens); font-family only in base.css.
7
6
  */
@@ -1,8 +1,6 @@
1
1
  /* ============================================================================
2
2
  Dataworkz Design System — PRIMITIVE tokens
3
- Source of truth: designs/dataworkz-design-system/handoff/design-system.html
4
-
5
- This is the ONLY file in the app allowed to contain raw color literals.
3
+ This is the ONLY file in the theme allowed to contain raw color literals.
6
4
  Components never consume primitives directly — they consume the semantic
7
5
  role tokens in semantic.css, which point at these. A future dark theme only
8
6
  re-points the semantic layer.