@breathe-ds/ui 0.3.0 → 0.5.1

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/theme.css CHANGED
@@ -25,6 +25,8 @@
25
25
  --color-action: var(--cg-action); /* CTA/highlight — never plain text */
26
26
  --color-action-text: var(--cg-action-text); /* text in the action color (AA) */
27
27
  --color-on-action: var(--cg-on-action); /* text ON the action color (button) */
28
+ --color-action-tint: var(--cg-action-tint, var(--cg-surface)); /* highlighted panel/card: a 6% wash of the action color */
29
+ --color-action-line: var(--cg-action-line, var(--cg-action)); /* border of a highlighted card (3:1 on surface) */
28
30
  --color-line: var(--cg-line); /* hairlines/borders */
29
31
 
30
32
  /* ── Typography (roles; actual family comes from --cg-font-*) ── */
@@ -57,6 +59,20 @@
57
59
  scroll-behavior: auto;
58
60
  }
59
61
  }
62
+ /* Tailwind v4's reset leaves buttons with the default cursor; in the family
63
+ everything that can be tapped shows the hand: buttons, links, the summary
64
+ of a collapse, labels of controls, selects. Disabled ones keep the arrow. */
65
+ button:not(:disabled),
66
+ [role="button"]:not([aria-disabled="true"]),
67
+ a[href],
68
+ summary,
69
+ label[for],
70
+ select:not(:disabled),
71
+ input[type="checkbox"]:not(:disabled),
72
+ input[type="radio"]:not(:disabled),
73
+ input[type="file"]:not(:disabled) {
74
+ cursor: pointer;
75
+ }
60
76
  }
61
77
 
62
78
  /* Outbound/anchor arrow on links: takes a small step toward where the link
@@ -104,3 +120,127 @@
104
120
  .cg-lockup--entrance .cg-lockup__mark, .cg-lockup--entrance .cg-lockup__name, .cg-lockup--entrance .cg-lockup__tag{ animation: cg-lockup-fade 240ms ease var(--cg-entrance-delay,0ms) both; }
105
121
  @keyframes cg-lockup-fade{ from{ opacity:0; } }
106
122
  }
123
+
124
+ /* Rail: the horizontal list hides its scrollbar (the progress bar under it says how much is left). */
125
+ .cg-no-scrollbar {
126
+ scrollbar-width: none;
127
+ }
128
+ .cg-no-scrollbar::-webkit-scrollbar {
129
+ display: none;
130
+ }
131
+
132
+ /* ── Care flow drawings (CareSteps): ChatPreview, PlanTimeline, PhotoSequence ──
133
+ Ported from novo.creeta's globals.css. Only opacity and transform. */
134
+
135
+ /* ChatPreview: each bubble animates when it enters; the component sets the
136
+ rhythm (and the loop). Nothing animates without data-state="playing". */
137
+ @keyframes cg-bubble-in {
138
+ from {
139
+ opacity: 0;
140
+ transform: translateY(8px) scale(0.96);
141
+ }
142
+ }
143
+ @keyframes cg-dot-pulse {
144
+ 0%,
145
+ 60%,
146
+ 100% {
147
+ opacity: 0.35;
148
+ transform: none;
149
+ }
150
+ 30% {
151
+ opacity: 1;
152
+ transform: translateY(-2px);
153
+ }
154
+ }
155
+ .cg-chat[data-state="playing"] .cg-bubble {
156
+ animation: cg-bubble-in 320ms cubic-bezier(0.23, 1, 0.32, 1) both;
157
+ }
158
+ .cg-chat[data-state="playing"] .cg-typing i {
159
+ animation: cg-dot-pulse 900ms ease-in-out calc(var(--n) * 140ms) infinite;
160
+ }
161
+ .cg-chat[data-paused] .cg-bubble,
162
+ .cg-chat[data-paused] .cg-typing i {
163
+ animation-play-state: paused;
164
+ }
165
+
166
+ /* PlanTimeline, 6s loop: the line comes down from 0.2s to 1.7s and each dot
167
+ lights up when it arrives (0.2s, 0.95s, 1.7s); everything stays lit until
168
+ 5.1s, goes off and restarts. One set of keyframes per dot. */
169
+ @keyframes cg-plan-line {
170
+ 0%, 3.3% { opacity: 1; transform: scaleY(0); }
171
+ 28.3%, 85% { opacity: 1; transform: scaleY(1); }
172
+ 92%, 100% { opacity: 0; transform: scaleY(1); }
173
+ }
174
+ @keyframes cg-plan-dot-1 {
175
+ 0%, 3.3% { opacity: 0; transform: scale(0.3); }
176
+ 8.6%, 85% { opacity: 1; transform: none; }
177
+ 92%, 100% { opacity: 0; transform: scale(0.3); }
178
+ }
179
+ @keyframes cg-plan-dot-2 {
180
+ 0%, 15.8% { opacity: 0; transform: scale(0.3); }
181
+ 21.1%, 85% { opacity: 1; transform: none; }
182
+ 92%, 100% { opacity: 0; transform: scale(0.3); }
183
+ }
184
+ @keyframes cg-plan-dot-3 {
185
+ 0%, 28.3% { opacity: 0; transform: scale(0.3); }
186
+ 33.6%, 85% { opacity: 1; transform: none; }
187
+ 92%, 100% { opacity: 0; transform: scale(0.3); }
188
+ }
189
+ /* The name out of turn stays at 75%, not less: ink at 75% over the card still
190
+ passes AA (creeta measured 5.03:1; at 45% it failed, WCAG 1.4.3). */
191
+ @keyframes cg-plan-name-1 {
192
+ 0%, 3.3%, 92%, 100% { opacity: 0.75; }
193
+ 8.6%, 85% { opacity: 1; }
194
+ }
195
+ @keyframes cg-plan-name-2 {
196
+ 0%, 15.8%, 92%, 100% { opacity: 0.75; }
197
+ 21.1%, 85% { opacity: 1; }
198
+ }
199
+ @keyframes cg-plan-name-3 {
200
+ 0%, 28.3%, 92%, 100% { opacity: 0.75; }
201
+ 33.6%, 85% { opacity: 1; }
202
+ }
203
+ .cg-plan[data-state="waiting"] .cg-plan-line { transform: scaleY(0); }
204
+ .cg-plan[data-state="waiting"] .cg-plan-dot { opacity: 0; }
205
+ .cg-plan[data-state="waiting"] .cg-plan-name { opacity: 0.75; }
206
+ .cg-plan[data-state="playing"] .cg-plan-line { animation: cg-plan-line 6s linear infinite; }
207
+ .cg-plan[data-state="playing"] .cg-plan-step[data-n="1"] .cg-plan-dot { animation: cg-plan-dot-1 6s cubic-bezier(0.23, 1, 0.32, 1) infinite; }
208
+ .cg-plan[data-state="playing"] .cg-plan-step[data-n="2"] .cg-plan-dot { animation: cg-plan-dot-2 6s cubic-bezier(0.23, 1, 0.32, 1) infinite; }
209
+ .cg-plan[data-state="playing"] .cg-plan-step[data-n="3"] .cg-plan-dot { animation: cg-plan-dot-3 6s cubic-bezier(0.23, 1, 0.32, 1) infinite; }
210
+ .cg-plan[data-state="playing"] .cg-plan-step[data-n="1"] .cg-plan-name { animation: cg-plan-name-1 6s ease infinite; }
211
+ .cg-plan[data-state="playing"] .cg-plan-step[data-n="2"] .cg-plan-name { animation: cg-plan-name-2 6s ease infinite; }
212
+ .cg-plan[data-state="playing"] .cg-plan-step[data-n="3"] .cg-plan-name { animation: cg-plan-name-3 6s ease infinite; }
213
+ /* Paused on the button, or off screen. Same weight as the rules above and after them. */
214
+ .cg-plan[data-state][data-stopped] .cg-plan-line,
215
+ .cg-plan[data-state][data-stopped] .cg-plan-step .cg-plan-dot,
216
+ .cg-plan[data-state][data-stopped] .cg-plan-step .cg-plan-name {
217
+ animation-play-state: paused;
218
+ }
219
+
220
+ /* PhotoSequence: the hidden checkbox pauses the photos through CSS. */
221
+ .cg-seq-pause:checked ~ .cg-seq img {
222
+ animation-play-state: paused !important;
223
+ }
224
+
225
+ /* Reduced motion: the components do not even start; this is the second lock,
226
+ in case the preference changes with the page open. The sequence keeps the
227
+ first photo and loses the control (a nameless checkbox in the tab order
228
+ would fail WCAG 4.1.2). */
229
+ @media (prefers-reduced-motion: reduce) {
230
+ .cg-chat .cg-bubble,
231
+ .cg-chat .cg-typing i,
232
+ .cg-plan .cg-plan-line,
233
+ .cg-plan .cg-plan-dot,
234
+ .cg-plan .cg-plan-name {
235
+ animation: none !important;
236
+ opacity: 1;
237
+ transform: none;
238
+ }
239
+ .cg-seq img {
240
+ animation: none !important;
241
+ }
242
+ .cg-seq-control,
243
+ .cg-seq-pause {
244
+ display: none;
245
+ }
246
+ }
package/tokens/creeta.css CHANGED
@@ -16,6 +16,8 @@
16
16
  --cg-ink-body: #1e4f5b;
17
17
  --cg-action: #ab2781; /* magenta (Agendar) */
18
18
  --cg-action-text: #8f1f6c; /* darker magenta for text */
19
+ --cg-action-tint: #eae7ed; /* 6% magenta over mist: highlighted card */
20
+ --cg-action-line: #ab2781; /* magenta itself: 5.62:1 on mist */
19
21
  --cg-on-action: #ffffff; /* white on magenta */
20
22
  --cg-line: rgb(20 71 83 / 0.16);
21
23
  --cg-font-heading: var(--font-quicksand), system-ui, sans-serif; /* Quicksand */
@@ -20,6 +20,8 @@
20
20
  --cg-ink-body: #3f3f46;
21
21
  --cg-action: #18181b;
22
22
  --cg-action-text: #52525b;
23
+ --cg-action-tint: #e9e9ea;
24
+ --cg-action-line: #18181b;
23
25
  --cg-on-action: #ffffff;
24
26
  --cg-line: rgb(0 0 0 / 0.12);
25
27
  --cg-font-heading: var(--font-quicksand), system-ui, sans-serif; /* Quicksand (fixed across the family) */
package/tokens/ttcab.css CHANGED
@@ -3,9 +3,15 @@
3
3
  - surface #fbf5e9 / ink #144753 ............ 9.41:1 (AAA)
4
4
  - surface #fbf5e9 / ink-soft #54707a ....... 4.86:1 (AA)
5
5
  - surface #fbf5e9 / ink-body #1e4f5b ....... 8.32:1 (AAA)
6
- - surface #fbf5e9 / action-text #9a5d07 .... 4.90:1 (AA)
6
+ - surface #fbf5e9 / action-text #bd3f0c .... 4.98:1 (AA)
7
7
  - surface-panel #144753 / surface (text) ... 9.41:1 (AAA)
8
- - action #f6a22a is DECORATIVE/CTA — never text on cream.
8
+ - action #e8541e / on-action #ffffff ...... 3.67:1 — the accent button
9
+ The action color is a vivid red-orange with WHITE text (decided 2026-10-29,
10
+ the Cloudflare/Airbnb route): 3.67:1 passes the 3:1 of UI components and of
11
+ large text, NOT the 4.5:1 of normal text. Conscious exception, limited to the
12
+ accent Button (one per block, same type scale as the other buttons). Small
13
+ controls never put white on it (ink, or action-tint + action-text). The logo
14
+ keeps its own #f6a22a.
9
15
  */
10
16
  :root {
11
17
  --cg-surface: #fbf5e9;
@@ -14,9 +20,11 @@
14
20
  --cg-ink: #144753;
15
21
  --cg-ink-soft: #54707a;
16
22
  --cg-ink-body: #1e4f5b;
17
- --cg-action: #f6a22a;
18
- --cg-on-action: #144753; /* ink on orange */
19
- --cg-action-text: #9a5d07;
23
+ --cg-action: #e8541e; /* vivid red-orange: white on it 3.67:1 (large text / UI 3:1) */
24
+ --cg-on-action: #ffffff;
25
+ --cg-action-text: #bd3f0c; /* 4.98:1 on cream, 4.64:1 on the tint */
26
+ --cg-action-tint: #faebdd; /* 6% action over cream: highlighted card (ink 8.75:1) */
27
+ --cg-action-line: #e8541e; /* the action color itself: 3.38:1 on cream */
20
28
  --cg-line: rgb(20 71 83 / 0.16);
21
29
  --cg-font-heading: var(--font-quicksand), system-ui, sans-serif; /* Quicksand */
22
30
  --cg-font-body: var(--font-figtree), system-ui, sans-serif; /* Figtree */