@flytedan/flytebot-design-system 0.8.2 → 0.9.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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@flytedan/flytebot-design-system",
3
- "version": "0.8.2",
3
+ "version": "0.9.0",
4
4
  "description": "flytedesk Design System — shared component library, tokens, and business-logic kits for flytedesk apps.",
5
5
  "type": "module",
6
6
  "license": "UNLICENSED",
@@ -3787,8 +3787,11 @@
3787
3787
  /* Shorter than the row's own fixed slot, not 100% of it — the leftover space
3788
3788
  at the bottom of each slot is what reads as a gap between cards, without
3789
3789
  touching itemHeight itself (that number is load-bearing for the
3790
- scroll/virtualization math in VirtualList.tsx, not just visual spacing). */
3791
- height: calc(100% - 6px);
3790
+ scroll/virtualization math in VirtualList.tsx, not just visual spacing).
3791
+ The size comes from VirtualList's `rowGap` prop via this custom property,
3792
+ since the right gap depends on how tall and heavy the row is; the literal
3793
+ fallback only applies to markup that sets neither. */
3794
+ height: calc(100% - var(--fd-vlist-gap, 6px));
3792
3795
  }
3793
3796
  /* A freshly-added row (e.g. the destination side right after a move) gets a brief
3794
3797
  fade/scale-in instead of popping in instantly. Scale/opacity only — never
@@ -3851,18 +3854,118 @@
3851
3854
  better with the tighter radius; --e-1/--e-2 are the same elevation tokens). */
3852
3855
  .fd-erow {
3853
3856
  background: var(--surface-2);
3854
- border: 1px solid var(--border);
3857
+ border: 1px solid var(--erow-border);
3855
3858
  border-radius: var(--r-md);
3856
3859
  box-shadow: var(--e-1);
3857
3860
  transition:
3858
3861
  box-shadow var(--dur-fast) var(--ease),
3859
3862
  border-color var(--dur-fast) var(--ease),
3863
+ background var(--dur-fast) var(--ease),
3860
3864
  transform var(--dur-fast) var(--ease);
3861
3865
  }
3862
3866
  .fd-erow:hover {
3863
- border-color: var(--border-strong);
3867
+ border-color: var(--erow-border-hover);
3864
3868
  box-shadow: var(--e-2);
3865
3869
  }
3870
+ /* The row's one non-default state colour: this row exists but can't be used
3871
+ (a school with no sellable inventory). Fill, border and title all move, so
3872
+ it survives being scanned at a glance down a long list — a border-only
3873
+ treatment disappears at 60px row pitch. Tokens are --erow-danger-*, defined
3874
+ for both grounds; on dark the fill can't separate from a near-black panel by
3875
+ luminance, so the border and the title colour carry it there. */
3876
+ .fd-erow-danger {
3877
+ background: var(--erow-danger-fill);
3878
+ border-color: var(--erow-danger-border);
3879
+ }
3880
+ .fd-erow-danger:hover {
3881
+ border-color: var(--erow-danger-border);
3882
+ }
3883
+ .fd-erow-danger .fd-erow-title {
3884
+ color: var(--erow-danger-text);
3885
+ }
3886
+
3887
+ /* The row's own two-line body: title line, then the aligned metric strip. The
3888
+ strip line only exists when there are metrics or an accessory, so a plain
3889
+ name-only row is still exactly one line tall. */
3890
+ .fd-erow-body {
3891
+ flex: 1;
3892
+ min-width: 0;
3893
+ display: flex;
3894
+ flex-direction: column;
3895
+ justify-content: center;
3896
+ gap: 3px;
3897
+ }
3898
+ .fd-erow-titleline {
3899
+ display: flex;
3900
+ align-items: baseline;
3901
+ gap: 8px;
3902
+ min-width: 0;
3903
+ }
3904
+ .fd-erow-title {
3905
+ flex: 1;
3906
+ min-width: 0;
3907
+ font-weight: var(--w-semibold);
3908
+ color: var(--text);
3909
+ white-space: nowrap;
3910
+ overflow: hidden;
3911
+ text-overflow: ellipsis;
3912
+ }
3913
+ .fd-erow-meta {
3914
+ flex: none;
3915
+ font-size: var(--overline-size);
3916
+ color: var(--text-muted);
3917
+ white-space: nowrap;
3918
+ }
3919
+ .fd-erow-strip {
3920
+ display: flex;
3921
+ align-items: center;
3922
+ gap: 10px;
3923
+ min-width: 0;
3924
+ }
3925
+ /* Fixed-width cells, not auto-sized ones: the whole point of the strip is that
3926
+ the same column lands at the same x on every row (and on the totals line in
3927
+ TransferList's footer, which renders this very component with the same
3928
+ widths), which auto width cannot give you when the numbers differ in digits. */
3929
+ .fd-erow-metrics {
3930
+ display: flex;
3931
+ align-items: center;
3932
+ min-width: 0;
3933
+ /* Cells are fixed-width, so a strip wider than the row it's in has to lose the
3934
+ tail rather than push it: without this the overflowing cells paint straight
3935
+ through whatever is pinned to the end of the strip. Clipping the last column
3936
+ is the right failure here — the alternative is columns that shift row to row,
3937
+ which is the one thing an aligned strip must never do. */
3938
+ overflow: hidden;
3939
+ }
3940
+ .fd-erow-metric {
3941
+ display: inline-flex;
3942
+ align-items: center;
3943
+ gap: 4px;
3944
+ flex: none;
3945
+ font-size: var(--overline-size);
3946
+ color: var(--text-2);
3947
+ white-space: nowrap;
3948
+ overflow: hidden;
3949
+ }
3950
+ .fd-erow-metric > .ph {
3951
+ font-size: 12px;
3952
+ color: var(--text-muted);
3953
+ flex: none;
3954
+ }
3955
+ .fd-erow-metric-value {
3956
+ font-weight: var(--w-medium);
3957
+ overflow: hidden;
3958
+ text-overflow: ellipsis;
3959
+ }
3960
+ .fd-erow-metric.is-danger > .ph {
3961
+ color: var(--danger-text);
3962
+ }
3963
+ .fd-erow-accessory {
3964
+ margin-left: auto;
3965
+ flex: none;
3966
+ display: inline-flex;
3967
+ align-items: center;
3968
+ }
3866
3969
  .fd-erow[draggable="true"]:active {
3867
3970
  cursor: grabbing;
3868
3971
  }
@@ -3914,6 +4017,159 @@
3914
4017
  box-shadow: var(--e-2);
3915
4018
  color: var(--brand);
3916
4019
  }
4020
+ /* TransferList's per-side slots. The footer is where a running totals line goes;
4021
+ it sits on the panel, not on a card, and is separated by a rule rather than a
4022
+ gap so it reads as a summary OF the list rather than another row IN it. */
4023
+ .fd-tlist-header {
4024
+ display: flex;
4025
+ align-items: center;
4026
+ gap: 8px;
4027
+ min-width: 0;
4028
+ }
4029
+ .fd-tlist-footer {
4030
+ display: flex;
4031
+ align-items: center;
4032
+ gap: 10px;
4033
+ min-width: 0;
4034
+ padding-top: 8px;
4035
+ /* Indented to the x a row's own body starts at, so a totals strip in here lands
4036
+ under the columns it totals rather than a card's width to the left of them.
4037
+ The sum is the card's border and padding-left plus the drag grip and its gap
4038
+ — every row in a TransferList is a drag source, so it is the same on all of
4039
+ them. Spelled out rather than collapsed to 37px so it stays checkable against
4040
+ .fd-erow if that padding ever moves. */
4041
+ padding-left: calc(1px + 12px + 14px + 10px);
4042
+ border-top: 1px solid var(--border);
4043
+ font-size: var(--overline-size);
4044
+ color: var(--text-2);
4045
+ }
4046
+
4047
+ /* --- ScoreMeter — a small categorical 0-100 bar, optionally a trigger ------ */
4048
+ .fd-scoremeter {
4049
+ display: inline-flex;
4050
+ align-items: center;
4051
+ gap: 7px;
4052
+ }
4053
+ .fd-scoremeter-rail {
4054
+ display: block;
4055
+ flex: none;
4056
+ }
4057
+ .fd-scoremeter-value {
4058
+ font-size: var(--overline-size);
4059
+ font-weight: var(--w-semibold);
4060
+ color: var(--text-2);
4061
+ min-width: 2ch;
4062
+ text-align: right;
4063
+ }
4064
+ /* The trigger is a real button (keyboard-operable, and skipped by TransferList's
4065
+ drag arming, which ignores any pointerdown inside a button) — so it has to be
4066
+ stripped of the browser's own button chrome and given this kit's own. */
4067
+ .fd-scoremeter-button {
4068
+ appearance: none;
4069
+ background: transparent;
4070
+ border: 1px solid transparent;
4071
+ border-radius: var(--r-sm);
4072
+ padding: 2px 5px;
4073
+ margin: -2px -5px;
4074
+ cursor: pointer;
4075
+ transition:
4076
+ background var(--dur-fast) var(--ease),
4077
+ border-color var(--dur-fast) var(--ease);
4078
+ }
4079
+ .fd-scoremeter-button:hover {
4080
+ background: var(--surface-3);
4081
+ border-color: var(--border);
4082
+ }
4083
+ .fd-scoremeter-button.is-open {
4084
+ background: var(--surface-brand);
4085
+ border-color: var(--border-brand);
4086
+ }
4087
+
4088
+ /* --- importance scale: the tag, and the score breakdown it appears in ------ */
4089
+ .fd-imp-tag {
4090
+ display: inline-flex;
4091
+ align-items: center;
4092
+ gap: 4px;
4093
+ flex: none;
4094
+ padding: 2px 7px;
4095
+ border: 1px solid transparent;
4096
+ border-radius: var(--r-full);
4097
+ font-size: var(--overline-size);
4098
+ line-height: var(--overline-lh);
4099
+ font-weight: var(--w-semibold);
4100
+ white-space: nowrap;
4101
+ }
4102
+ .fd-imp-tag > .ph {
4103
+ font-size: 12px;
4104
+ }
4105
+ .fd-imp-tag.is-md {
4106
+ padding: 4px 10px;
4107
+ font-size: var(--label-size);
4108
+ }
4109
+ .fd-imp-tag.is-md > .ph {
4110
+ font-size: 14px;
4111
+ }
4112
+ .fd-prefbreak {
4113
+ display: flex;
4114
+ flex-direction: column;
4115
+ gap: 10px;
4116
+ min-width: 0;
4117
+ }
4118
+ .fd-prefbreak-head {
4119
+ display: flex;
4120
+ align-items: baseline;
4121
+ justify-content: space-between;
4122
+ gap: 10px;
4123
+ }
4124
+ .fd-prefbreak-score {
4125
+ font-size: var(--h4-size);
4126
+ font-weight: var(--w-bold);
4127
+ color: var(--text);
4128
+ }
4129
+ .fd-prefbreak-list {
4130
+ list-style: none;
4131
+ margin: 0;
4132
+ padding: 0;
4133
+ display: flex;
4134
+ flex-direction: column;
4135
+ gap: 8px;
4136
+ }
4137
+ .fd-prefbreak-item {
4138
+ display: flex;
4139
+ align-items: flex-start;
4140
+ gap: 8px;
4141
+ min-width: 0;
4142
+ }
4143
+ /* A criterion that earned nothing is dimmed rather than hidden — the reason a
4144
+ score is low is exactly the rows that contributed zero. */
4145
+ .fd-prefbreak-item.is-unmet {
4146
+ opacity: 0.55;
4147
+ }
4148
+ .fd-prefbreak-text {
4149
+ flex: 1;
4150
+ min-width: 0;
4151
+ display: flex;
4152
+ flex-direction: column;
4153
+ gap: 2px;
4154
+ }
4155
+ .fd-prefbreak-label {
4156
+ font-size: var(--body-sm-size);
4157
+ line-height: var(--body-sm-lh);
4158
+ color: var(--text);
4159
+ }
4160
+ .fd-prefbreak-note {
4161
+ font-size: var(--overline-size);
4162
+ color: var(--text-muted);
4163
+ }
4164
+ .fd-prefbreak-val {
4165
+ flex: none;
4166
+ font-size: var(--body-sm-size);
4167
+ color: var(--text-2);
4168
+ }
4169
+ .fd-prefbreak-sep {
4170
+ color: var(--text-muted);
4171
+ padding: 0 2px;
4172
+ }
3917
4173
 
3918
4174
  /* uniform staging strip — one row, scrolls sideways */
3919
4175
  .fd-filestrip {
package/styles/tokens.css CHANGED
@@ -63,6 +63,33 @@
63
63
  --csi-ramp-1:#F1F4F5;--csi-ramp-2:#D9EDE6;--csi-ramp-3:#A9DECB;
64
64
  --csi-ramp-4:#6CC7AE;--csi-ramp-5:#2E9E85;--csi-ramp-6:#0B5F50;
65
65
 
66
+ /* criterion importance — the five-level planner priority scale, ordered
67
+ Nudge < Lean < Priority < Driver < Deal-breaker on a slate -> blue -> indigo
68
+ -> amber -> red ramp. Same shape as the CSI ramp above (fill/edge/text/mark
69
+ per stop) because it is used the same two ways: `mark` is the solid the meter
70
+ segments and glyphs are drawn in, `fill`+`edge` tint a criterion card's
71
+ background and border, `text` is the AA-safe label colour ON that fill.
72
+ Deliberately NOT aliases of --info/--warn/--danger: importance is an ordered
73
+ scale, not a status, and a Driver criterion is not a warning. */
74
+ --imp-1-fill:#EEF0F3;--imp-1-edge:#D2D7DF;--imp-1-text:#414958;--imp-1-mark:#7C8698;
75
+ --imp-2-fill:#DEEBF7;--imp-2-edge:#C3DDF1;--imp-2-text:#144674;--imp-2-mark:#2272BA;
76
+ --imp-3-fill:#E7E3F8;--imp-3-edge:#C9C1EE;--imp-3-text:#342A6B;--imp-3-mark:#6E5BC9;
77
+ --imp-4-fill:#FDF1DA;--imp-4-edge:#F0D49A;--imp-4-text:#6B4A05;--imp-4-mark:#BD800A;
78
+ --imp-5-fill:#FCE7E5;--imp-5-edge:#F2BDB8;--imp-5-text:#7A241D;--imp-5-mark:#D0473D;
79
+
80
+ /* EntityRow — the list card's own hairline, and its one non-default row tone.
81
+ The border is a purpose-built token rather than --border because an EntityRow
82
+ card is --surface-2 sitting on a --surface panel, and those two differ by only
83
+ 1.06:1 in light mode: the gap between two cards is invisible unless the
84
+ hairline itself carries it. --erow-border is 1.46:1 against the panel and
85
+ 1.38:1 against the card (vs --border's 1.23 / 1.16), which is what actually
86
+ makes the gap read. --erow-border-hover keeps a distinct hover step on top. */
87
+ --erow-border:#CFD6E0;
88
+ --erow-border-hover:#B6C0CE;
89
+ --erow-danger-fill:#FCE9E6;
90
+ --erow-danger-border:#EFB7B1;
91
+ --erow-danger-text:#7A241D;
92
+
66
93
  --ok-fill:#DFF3E8;--ok-border:#A8DDC2;--ok-text:#0E5233;--ok-solid:#34A26B;--ok-emph:#57C68C;
67
94
  --warn-fill:#FDF1DA;--warn-border:#F0D49A;--warn-text:#6B4A05;--warn-solid:#C8890B;
68
95
  --danger-fill:#FCE7E5;--danger-border:#F2BDB8;--danger-text:#7A241D;--danger-solid:#D0473D;
@@ -190,6 +217,25 @@
190
217
  --danger-fill:#2E1512;--danger-border:#5E2A24;--danger-text:#F0A79F;
191
218
  --info-fill:#12283D;--info-border:#1E3F5E;--info-text:#9CC7EC;
192
219
 
220
+ /* importance ramp on dark ground — see the :root block above for what each stop
221
+ is for. Same five hues, re-struck so `text` stays AA on `fill` and `mark`
222
+ clears 3:1 against the dark meter rail (--surface-3). */
223
+ --imp-1-fill:#23272E;--imp-1-edge:#333A44;--imp-1-text:#A3ACB9;--imp-1-mark:#8892A0;
224
+ --imp-2-fill:#12283D;--imp-2-edge:#1E3F5E;--imp-2-text:#9CC7EC;--imp-2-mark:#6FA8E8;
225
+ --imp-3-fill:#221C3D;--imp-3-edge:#372E5C;--imp-3-text:#BFB4F2;--imp-3-mark:#9B8DE0;
226
+ --imp-4-fill:#2C2210;--imp-4-edge:#5C4614;--imp-4-text:#E9C377;--imp-4-mark:#E0A93F;
227
+ --imp-5-fill:#2E1512;--imp-5-edge:#5E2A24;--imp-5-text:#F0A79F;--imp-5-mark:#E2756B;
228
+
229
+ /* EntityRow — see the :root block above. On dark ground the hairline does even
230
+ more of the work (1.56:1 against the panel), since --surface-2 and --surface
231
+ sit only 1.09:1 apart here too. A dark red row fill cannot separate from a
232
+ near-black panel by luminance, so the danger row reads by border and hue. */
233
+ --erow-border:#333A44;
234
+ --erow-border-hover:#4A5260;
235
+ --erow-danger-fill:#331813;
236
+ --erow-danger-border:#7A342C;
237
+ --erow-danger-text:#F0A79F;
238
+
193
239
  /* chat kit — see the :root block above */
194
240
  --chat-code-bg:#12151B;
195
241
  --code-kw:#B3A6F0;--code-str:#E9C377;--code-num:#EFA8BE;--code-com:#6C7686;