cursedbelt 5.52.1 → 5.53.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.
Files changed (44) hide show
  1. package/dist/react/components/ListPanel.d.ts +40 -0
  2. package/dist/react/components/ListPanel.d.ts.map +1 -0
  3. package/dist/react/components/ListPanel.js +32 -0
  4. package/dist/react/components/ListPanel.js.map +1 -0
  5. package/dist/react/components/Page.js +1 -1
  6. package/dist/react/components/Page.js.map +1 -1
  7. package/dist/react/index.d.ts +1 -0
  8. package/dist/react/index.d.ts.map +1 -1
  9. package/dist/react/index.js +1 -0
  10. package/dist/react/index.js.map +1 -1
  11. package/dist/styles-areas/analytics.css +11 -11
  12. package/dist/styles-areas/calendar.css +14 -15
  13. package/dist/styles-areas/chart-table.css +2 -2
  14. package/dist/styles-areas/companion-link.css +2 -2
  15. package/dist/styles-areas/core.css +26 -25
  16. package/dist/styles-areas/dashboard-grid.css +3 -3
  17. package/dist/styles-areas/data-table.css +2 -2
  18. package/dist/styles-areas/fields.css +2 -2
  19. package/dist/styles-areas/layout-engine.css +10 -10
  20. package/dist/styles-areas/media.css +10 -10
  21. package/dist/styles-areas/rich-text.css +2 -2
  22. package/dist/styles-areas/stats.css +2 -2
  23. package/dist/styles-areas/workbench.css +3 -3
  24. package/dist/styles-utilities.css +13 -0
  25. package/package.json +2 -2
  26. package/scripts/styleAreas.ts +1 -0
  27. package/src/react/components/ListPanel.spec.tsx +73 -0
  28. package/src/react/components/ListPanel.tsx +97 -0
  29. package/src/react/components/Page.tsx +9 -3
  30. package/src/react/index.ts +1 -0
  31. package/src/styles-areas/analytics.css +11 -11
  32. package/src/styles-areas/calendar.css +14 -15
  33. package/src/styles-areas/chart-table.css +2 -2
  34. package/src/styles-areas/companion-link.css +2 -2
  35. package/src/styles-areas/core.css +26 -25
  36. package/src/styles-areas/dashboard-grid.css +3 -3
  37. package/src/styles-areas/data-table.css +2 -2
  38. package/src/styles-areas/fields.css +2 -2
  39. package/src/styles-areas/layout-engine.css +10 -10
  40. package/src/styles-areas/media.css +10 -10
  41. package/src/styles-areas/rich-text.css +2 -2
  42. package/src/styles-areas/stats.css +2 -2
  43. package/src/styles-areas/workbench.css +3 -3
  44. package/src/styles-utilities.css +13 -0
@@ -18,7 +18,7 @@
18
18
  * after an app's responsive variant (task 2124). An app that imports every area gets exactly
19
19
  * what `cursedbelt/styles-utilities.css` emits — proved rule by rule in
20
20
  * src/stylesAreas.spec.ts, which is also what fails when this file is stale.
21
- * 85 candidate(s).
21
+ * 84 candidate(s).
22
22
  *
23
23
  * Written by scripts/generateAreaStyles.ts (`bun run styles:areas`), which
24
24
  * `bun run build` runs. The map of what is in which area, and why the areas are
@@ -27,12 +27,12 @@
27
27
  @source inline("[&_svg]:max-h-10 [&_svg]:min-h-5 [&_svg]:size-1/3 accent-white active:cursor-grabbing appearance");
28
28
  @source inline("appearance-none aspect-square aspect-video backdrop-blur-xs bg-accent/15 bg-background/65");
29
29
  @source inline("bg-background/85 bg-black bg-black/55 bg-black/60 bg-black/85 bg-black/90 bg-card-raised");
30
- @source inline("bg-center bg-cover bg-linear-to-t bg-muted/40 bg-white/90 border-2 border-accent-solid");
31
- @source inline("border-white/90 border-y-2 bottom-1 bottom-1.5 bottom-2 cursor-crosshair cursor-grab");
32
- @source inline("cursor-zoom-in ease-in-out focus-within:opacity-100 from-black/80 g gap-x-4 grayscale");
33
- @source inline("group-focus-within:opacity-100 h-11 hover:bg-black/75 hover:bg-destructive hover:bg-white/20");
34
- @source inline("hover:border-accent-solid invert left-0 left-1 max-h-[40vh] max-h-[var(--media-max-h)]");
35
- @source inline("max-h-full max-w-50 min-h-64 min-h-dvh min-w-10 min-w-28 min-w-40 min-w-48 o op opacity-100");
36
- @source inline("opacity-80 pr-9 pt-8 right-1 right-1.5 right-3 sh shadow-[0_0_0_1px_rgba(0,0,0,0.55)] size-7");
37
- @source inline("size-9 sm:gap-3 sm:grid-cols-3 text-[color:var(--accent)] text-xl to-transparent top-1 top-1.5");
38
- @source inline("translate translate-x-px w-12 w-3 zoom zoom-in");
30
+ @source inline("bg-center bg-cover bg-linear-to-t bg-white/90 border-2 border-accent-solid border-white/90");
31
+ @source inline("border-y-2 bottom-1 bottom-1.5 bottom-2 cursor-crosshair cursor-grab cursor-zoom-in ease-in-out");
32
+ @source inline("focus-within:opacity-100 from-black/80 g gap-x-4 grayscale group-focus-within:opacity-100 h-11");
33
+ @source inline("hover:bg-black/75 hover:bg-destructive hover:bg-white/20 hover:border-accent-solid invert left-0");
34
+ @source inline("left-1 max-h-[40vh] max-h-[var(--media-max-h)] max-h-full max-w-50 min-h-64 min-h-dvh min-w-10");
35
+ @source inline("min-w-28 min-w-40 min-w-48 o op opacity-100 opacity-80 pr-9 pt-8 right-1 right-1.5 right-3 sh");
36
+ @source inline("shadow-[0_0_0_1px_rgba(0,0,0,0.55)] size-7 size-9 sm:gap-3 sm:grid-cols-3");
37
+ @source inline("text-[color:var(--accent)] text-xl to-transparent top-1 top-1.5 translate translate-x-px w-12");
38
+ @source inline("w-3 zoom zoom-in");
@@ -18,11 +18,11 @@
18
18
  * after an app's responsive variant (task 2124). An app that imports every area gets exactly
19
19
  * what `cursedbelt/styles-utilities.css` emits — proved rule by rule in
20
20
  * src/stylesAreas.spec.ts, which is also what fails when this file is stale.
21
- * 9 candidate(s).
21
+ * 8 candidate(s).
22
22
  *
23
23
  * Written by scripts/generateAreaStyles.ts (`bun run styles:areas`), which
24
24
  * `bun run build` runs. The map of what is in which area, and why the areas are
25
25
  * import closures rather than a hand-written list, is scripts/styleAreas.ts.
26
26
  */
27
- @source inline("flex-nowrap focus-within:ring-2 focus-within:ring-offset-0 focus-within:ring-ring h-5 italic");
27
+ @source inline("flex-nowrap focus-within:ring-2 focus-within:ring-offset-0 focus-within:ring-ring italic");
28
28
  @source inline("min-h-32 sm:flex-wrap top-full");
@@ -18,7 +18,7 @@
18
18
  * after an app's responsive variant (task 2124). An app that imports every area gets exactly
19
19
  * what `cursedbelt/styles-utilities.css` emits — proved rule by rule in
20
20
  * src/stylesAreas.spec.ts, which is also what fails when this file is stale.
21
- * 61 candidate(s).
21
+ * 60 candidate(s).
22
22
  *
23
23
  * Written by scripts/generateAreaStyles.ts (`bun run styles:areas`), which
24
24
  * `bun run build` runs. The map of what is in which area, and why the areas are
@@ -30,7 +30,7 @@
30
30
  @source inline("gap-y-0.5 grid-cols-[minmax(0,1fr)_auto] group-focus-visible/meter:opacity-100");
31
31
  @source inline("group-focus-visible/stat:opacity-100 group-focus-visible/tile:opacity-100");
32
32
  @source inline("group-hover/meter:opacity-100 group-hover/stat:opacity-100 group-hover/tile:opacity-100");
33
- @source inline("group/meter group/stat group/tile h-5 hover:bg-muted/50 last:pr-1 left-3");
33
+ @source inline("group/meter group/stat group/tile hover:bg-muted/50 last:pr-1 left-3");
34
34
  @source inline("left-[var(--timeline-rail-x)] list-none min-h-9 min-w-34 min-w-full mr-0.5 normal-case pt-1");
35
35
  @source inline("rounded-b-md rounded-t-md row-start-1 self-stretch shadow-md sm:col-auto sm:col-span-1");
36
36
  @source inline("sm:grid-cols-[minmax(7rem,18rem)_minmax(4rem,1fr)_auto]");
@@ -18,15 +18,15 @@
18
18
  * after an app's responsive variant (task 2124). An app that imports every area gets exactly
19
19
  * what `cursedbelt/styles-utilities.css` emits — proved rule by rule in
20
20
  * src/stylesAreas.spec.ts, which is also what fails when this file is stale.
21
- * 110 candidate(s).
21
+ * 109 candidate(s).
22
22
  *
23
23
  * Written by scripts/generateAreaStyles.ts (`bun run styles:areas`), which
24
24
  * `bun run build` runs. The map of what is in which area, and why the areas are
25
25
  * import closures rather than a hand-written list, is scripts/styleAreas.ts.
26
26
  */
27
27
  @source inline("-my-0.5 [&::-webkit-scrollbar]:hidden [&_svg]:size-3.5 [scrollbar-width:none] bg-accent/15");
28
- @source inline("bg-accent/40 bg-accent/8 bg-card-overlay/85 bg-muted/30 bg-muted/40 bg-muted/60 bg-success/8");
29
- @source inline("border-2 border-8 border-accent-solid border-accent/70 border-border-strong/60 border-border/50");
28
+ @source inline("bg-accent/40 bg-accent/8 bg-card-overlay/85 bg-muted/30 bg-muted/60 bg-success/8 border-2");
29
+ @source inline("border-8 border-accent-solid border-accent/70 border-border-strong/60 border-border/50");
30
30
  @source inline("border-dashed border-l border-r border-solid bottom-6 data-[state=closed]:slide-out-to-bottom");
31
31
  @source inline("data-[state=closed]:slide-out-to-left data-[state=closed]:slide-out-to-right");
32
32
  @source inline("data-[state=open]:slide-in-from-bottom data-[state=open]:slide-in-from-left");
@@ -853,6 +853,9 @@
853
853
  .min-h-full {
854
854
  min-height: 100%;
855
855
  }
856
+ .min-h-row {
857
+ min-height: var(--row-h);
858
+ }
856
859
  .w-0 {
857
860
  width: 0px;
858
861
  }
@@ -2515,6 +2518,9 @@
2515
2518
  .px-6 {
2516
2519
  padding-inline: calc(var(--spacing) * 6);
2517
2520
  }
2521
+ .px-row-x {
2522
+ padding-inline: var(--row-pad-x);
2523
+ }
2518
2524
  .py-0 {
2519
2525
  padding-block: 0px;
2520
2526
  }
@@ -2557,6 +2563,9 @@
2557
2563
  .py-px {
2558
2564
  padding-block: 1px;
2559
2565
  }
2566
+ .py-row-y {
2567
+ padding-block: var(--row-pad-y);
2568
+ }
2560
2569
  .pt-0\.5 {
2561
2570
  padding-top: calc(var(--spacing) * 0.5);
2562
2571
  }
@@ -3531,6 +3540,10 @@
3531
3540
  border-right-style: var(--tw-border-style);
3532
3541
  border-right-width: 0px;
3533
3542
  }
3543
+ .last\:border-b-0:last-child {
3544
+ border-bottom-style: var(--tw-border-style);
3545
+ border-bottom-width: 0px;
3546
+ }
3534
3547
  .last\:pr-1:last-child {
3535
3548
  padding-right: var(--spacing);
3536
3549
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "cursedbelt",
3
- "version": "5.52.1",
3
+ "version": "5.53.0",
4
4
  "license": "ISC",
5
5
  "type": "module",
6
6
  "description": "The React design system of the cursedbelt split — components, styles, theme. cursedbelt-core below it; server tier in cursedbelt-server.",
@@ -890,7 +890,7 @@
890
890
  "clsx": "^2.1.1",
891
891
  "cmdk": "^1.1.1",
892
892
  "cursedbelt-core": "^2.10.0",
893
- "cwip": "^4.6.0",
893
+ "cwip": "^4.11.1",
894
894
  "lucide-react": "^1.21.0",
895
895
  "react-hook-form": "^7.80.0",
896
896
  "react-resizable-panels": "^4.12.0",
@@ -174,6 +174,7 @@ export const AREAS: readonly Area[] = [
174
174
  'components/InfoHint.tsx',
175
175
  'components/InfoHintImpl.tsx',
176
176
  'components/Input.tsx',
177
+ 'components/ListPanel.tsx',
177
178
  'components/Menu.tsx',
178
179
  'components/Modal.tsx',
179
180
  'components/OnlineDot.tsx',
@@ -0,0 +1,73 @@
1
+ import { afterEach, describe, expect, test } from 'bun:test';
2
+ import { cleanup, render } from '@testing-library/react';
3
+ import { Button } from './Button.js';
4
+ import { ListPanel, ListRow } from './ListPanel.js';
5
+
6
+ afterEach(cleanup);
7
+
8
+ /**
9
+ * ListPanel replaced roms' hand-written `.roms-panel` / `.roms-row` (forge task 2729). What a
10
+ * consumer relies on: the bands render only when given, the rows ride the density tokens rather
11
+ * than literal paddings (so a compact theme reaches them), and `label` / `value` land on the two
12
+ * sides with the value never shrinking.
13
+ */
14
+ describe('ListPanel', () => {
15
+ test('draws the head and foot bands only when given', () => {
16
+ const { container, rerender } = render(
17
+ <ListPanel>
18
+ <ListRow label='Volume' value='80%' />
19
+ </ListPanel>,
20
+ );
21
+ expect(container.querySelector('[data-cb-list-panel-head]')).toBeNull();
22
+ expect(container.querySelector('[data-cb-list-panel-foot]')).toBeNull();
23
+
24
+ rerender(
25
+ <ListPanel head='Audio' foot='Changes apply at once'>
26
+ <ListRow label='Volume' value='80%' />
27
+ </ListPanel>,
28
+ );
29
+ expect(container.querySelector('[data-cb-list-panel-head]')?.textContent).toBe('Audio');
30
+ expect(container.querySelector('[data-cb-list-panel-foot]')?.textContent).toBe('Changes apply at once');
31
+ });
32
+
33
+ test('the frame clips its rows to its radius', () => {
34
+ const { container } = render(<ListPanel head='x' />);
35
+ const panel = container.querySelector('[data-cb-list-panel]');
36
+ expect(panel?.className).toContain('overflow-hidden');
37
+ expect(panel?.className).toContain('rounded-lg');
38
+ });
39
+ });
40
+
41
+ describe('ListRow', () => {
42
+ test('rides the row density tokens and rules every row but the last', () => {
43
+ const { container } = render(<ListRow label='a' value='b' />);
44
+ const row = container.querySelector('[data-cb-list-row]');
45
+ for (const cls of ['min-h-row', 'px-row-x', 'py-row-y', 'border-b', 'last:border-b-0']) {
46
+ expect(row?.className.split(' ')).toContain(cls);
47
+ }
48
+ });
49
+
50
+ test('label left and truncated, value right and unshrinking, children between', () => {
51
+ const { container } = render(
52
+ <ListRow label='Save slot 1' value={<Button size='sm' tooltip='Load this slot'>Load</Button>}>
53
+ <span data-testid='middle'>middle</span>
54
+ </ListRow>,
55
+ );
56
+ const row = container.querySelector('[data-cb-list-row]');
57
+ const kids = Array.from(row?.children ?? []);
58
+ expect(kids.map((k) => k.getAttribute('data-cb-list-row-label') ?? k.getAttribute('data-cb-list-row-value') ?? 'child')).toEqual(['', 'child', '']);
59
+ expect(kids[0]?.className).toContain('truncate');
60
+ expect(kids[2]?.className).toContain('shrink-0');
61
+ });
62
+
63
+ test('with neither label nor value, children are the whole row', () => {
64
+ const { container } = render(
65
+ <ListRow>
66
+ <span>only</span>
67
+ </ListRow>,
68
+ );
69
+ const row = container.querySelector('[data-cb-list-row]');
70
+ expect(row?.children).toHaveLength(1);
71
+ expect(row?.querySelector('[data-cb-list-row-label]')).toBeNull();
72
+ });
73
+ });
@@ -0,0 +1,97 @@
1
+ import type { HTMLAttributes, ReactNode } from 'react';
2
+ import { cn } from '../lib/cn.js';
3
+ import { CardFrameContext, useCardNestingWarning } from './cardFrame.js';
4
+
5
+ export interface ListPanelProps extends Omit<HTMLAttributes<HTMLDivElement>, 'title'> {
6
+ /**
7
+ * The head band: a title on the left, its actions on the right (they wrap under it on a phone).
8
+ * Anything — a string, a title plus a `Badge`, a title plus a `Switch`.
9
+ */
10
+ head?: ReactNode;
11
+ /** The foot band: small muted text and secondary actions under the rows (a hint, a "reset all"). */
12
+ foot?: ReactNode;
13
+ }
14
+
15
+ /**
16
+ * A bordered panel of ruled rows — a settings tab's binding list, a save-slot list, a key/value
17
+ * sheet. An optional washed head band and muted foot band frame the rows; `ListRow`s go between
18
+ * them, each separated by a hairline.
19
+ *
20
+ * It is the shape `Section variant="card"` is not: Section pads its body, so its rows cannot run
21
+ * edge to edge, and its title is an eyebrow rather than a band. Roms' ⚙ menu (seven tabs) drew this
22
+ * by hand as `.roms-panel` / `.roms-row` until forge task 2729 moved it here, so a change to the
23
+ * row rule, the radius or the head wash now reaches every list drawn this way.
24
+ *
25
+ * Content that is not a row (an intro paragraph, a column-flowed group of row lists) can sit inside
26
+ * too — give it its own padding (`px-row-x py-row-y`).
27
+ */
28
+ export function ListPanel({ head, foot, children, className, ...rest }: ListPanelProps) {
29
+ useCardNestingWarning(true, 'ListPanel');
30
+ return (
31
+ <CardFrameContext.Provider value>
32
+ <div
33
+ data-cb-list-panel=''
34
+ className={cn('overflow-hidden rounded-lg border border-border text-sm', className)}
35
+ {...rest}
36
+ >
37
+ {head != null && (
38
+ <div
39
+ data-cb-list-panel-head=''
40
+ className='flex flex-wrap items-center justify-between gap-2 border-b border-border bg-muted/40 px-row-x py-2 font-semibold text-foreground'
41
+ >
42
+ {head}
43
+ </div>
44
+ )}
45
+ {children}
46
+ {foot != null && (
47
+ <div
48
+ data-cb-list-panel-foot=''
49
+ className='flex flex-wrap items-center gap-x-3 gap-y-2 border-t border-border px-row-x py-2 text-xs text-muted-foreground'
50
+ >
51
+ {foot}
52
+ </div>
53
+ )}
54
+ </div>
55
+ </CardFrameContext.Provider>
56
+ );
57
+ }
58
+
59
+ export interface ListRowProps extends HTMLAttributes<HTMLDivElement> {
60
+ /** The left side, muted and truncated to one line. Omit to lay the row out with `children`. */
61
+ label?: ReactNode;
62
+ /** The right side — a value, a `KeyBadge`, a button cluster. Never shrinks. */
63
+ value?: ReactNode;
64
+ }
65
+
66
+ /**
67
+ * One row of a {@link ListPanel}: `label` left, `value` right, on the `--row-h` / `--row-pad-*`
68
+ * density tokens, with a hairline under every row but the last.
69
+ *
70
+ * With neither `label` nor `value`, `children` are the row's whole content and the row is still a
71
+ * space-between flex line — the shape for a label that is two lines (a name over its hint) or a
72
+ * leading thumbnail.
73
+ */
74
+ export function ListRow({ label, value, children, className, ...rest }: ListRowProps) {
75
+ return (
76
+ <div
77
+ data-cb-list-row=''
78
+ className={cn(
79
+ 'flex min-h-row items-center justify-between gap-3 border-b border-border/60 px-row-x py-row-y last:border-b-0',
80
+ className,
81
+ )}
82
+ {...rest}
83
+ >
84
+ {label != null && (
85
+ <span data-cb-list-row-label='' className='min-w-0 truncate text-muted-foreground'>
86
+ {label}
87
+ </span>
88
+ )}
89
+ {children}
90
+ {value != null && (
91
+ <span data-cb-list-row-value='' className='flex shrink-0 items-center gap-1.5'>
92
+ {value}
93
+ </span>
94
+ )}
95
+ </div>
96
+ );
97
+ }
@@ -211,9 +211,15 @@ function PageSubtitle({ children, dense }: { children: ReactNode; dense: boolean
211
211
  {children}
212
212
  </p>
213
213
  {clipped ? (
214
- <InfoHint label='The full description'>
215
- <span data-cb-prose=''>{children}</span>
216
- </InfoHint>
214
+ // One text line tall, whatever the trigger is: on a coarse pointer the ⓘ carries a 44px
215
+ // TAP_TARGET, and as a flex child it grew the row 24px a frame AFTER first paint, so the
216
+ // browser's scroll anchoring moved a restored Back by 24px (forge task 2717). Centred in
217
+ // a box this short it overflows evenly instead — the hit area stays 44px, the row 20px.
218
+ <span data-cb-page-subtitle-hint='' className='inline-flex h-5 shrink-0 items-center'>
219
+ <InfoHint label='The full description'>
220
+ <span data-cb-prose=''>{children}</span>
221
+ </InfoHint>
222
+ </span>
217
223
  ) : null}
218
224
  </div>
219
225
  );
@@ -587,6 +587,7 @@ export {
587
587
  type PanelGridProps,
588
588
  type PanelGridSplit,
589
589
  } from './components/PanelGrid.js';
590
+ export { ListPanel, type ListPanelProps, ListRow, type ListRowProps } from './components/ListPanel.js';
590
591
  export { MeterList, type MeterListItem, type MeterListProps } from './components/MeterList.js';
591
592
  export { PanelSeparator, type PanelSeparatorProps } from './components/PanelSeparator.js';
592
593
  export {
@@ -18,7 +18,7 @@
18
18
  * after an app's responsive variant (task 2124). An app that imports every area gets exactly
19
19
  * what `cursedbelt/styles-utilities.css` emits — proved rule by rule in
20
20
  * src/stylesAreas.spec.ts, which is also what fails when this file is stale.
21
- * 168 candidate(s).
21
+ * 166 candidate(s).
22
22
  *
23
23
  * Written by scripts/generateAreaStyles.ts (`bun run styles:areas`), which
24
24
  * `bun run build` runs. The map of what is in which area, and why the areas are
@@ -31,16 +31,16 @@
31
31
  @source inline("@max-6xl:border-0 @max-6xl:min-w-0! @max-6xl:p-0! @max-6xl:w-0! @max-xl:contents @xl:basis-auto");
32
32
  @source inline("@xl:block @xl:hidden [&>*]:hidden [&>*]:max-w-none [&>svg]:size-3.5 [&_svg]:size-3");
33
33
  @source inline("[overflow-wrap:anywhere] active:cursor-grabbing appearance appearance-none basis basis-full");
34
- @source inline("bg-[var(--cb-frozen-bg)] bg-card/95 bg-gradient-to-t bg-muted/30 bg-muted/40 bg-muted/50");
35
- @source inline("border-accent-solid border-accent/60 border-field-error border-l border-r border-t-2 col");
36
- @source inline("collapse cursor-grab data-[ending-style]:opacity-0 data-[ending-style]:scale-95");
37
- @source inline("data-[highlighted]:bg-accent/10 data-[highlighted]:text-accent-strong");
38
- @source inline("data-[starting-style]:opacity-0 data-[starting-style]:scale-95");
39
- @source inline("data-[state=closed]:slide-out-to-bottom data-[state=closed]:slide-out-to-left");
40
- @source inline("data-[state=closed]:slide-out-to-right data-[state=open]:slide-in-from-bottom");
41
- @source inline("data-[state=open]:slide-in-from-left data-[state=open]:slide-in-from-right disabled:opacity-40");
42
- @source inline("duration-100 fade-in focus-visible:ring-field-ring/40 focus-within:border-field-ring");
43
- @source inline("focus-within:ring-2 focus-within:ring-field-ring/30 from-card gap-x-6 h-105 h-5");
34
+ @source inline("bg-[var(--cb-frozen-bg)] bg-card/95 bg-gradient-to-t bg-muted/30 bg-muted/50 border-accent-solid");
35
+ @source inline("border-accent/60 border-field-error border-l border-r border-t-2 col collapse cursor-grab");
36
+ @source inline("data-[ending-style]:opacity-0 data-[ending-style]:scale-95 data-[highlighted]:bg-accent/10");
37
+ @source inline("data-[highlighted]:text-accent-strong data-[starting-style]:opacity-0");
38
+ @source inline("data-[starting-style]:scale-95 data-[state=closed]:slide-out-to-bottom");
39
+ @source inline("data-[state=closed]:slide-out-to-left data-[state=closed]:slide-out-to-right");
40
+ @source inline("data-[state=open]:slide-in-from-bottom data-[state=open]:slide-in-from-left");
41
+ @source inline("data-[state=open]:slide-in-from-right disabled:opacity-40 duration-100 fade-in");
42
+ @source inline("focus-visible:ring-field-ring/40 focus-within:border-field-ring focus-within:ring-2");
43
+ @source inline("focus-within:ring-field-ring/30 from-card gap-x-6 h-105");
44
44
  @source inline("has-[[aria-invalid=true]]:border-field-error hover:bg-background hover:bg-border");
45
45
  @source inline("hover:bg-muted/40 hover:border-field-ring hover:text-warning italic justify-self-end");
46
46
  @source inline("last:border-0 left-0 left-11 left-2.5 list-none max-h-64 max-h-88 max-h-[var(--sheet-h-lg)]");
@@ -18,24 +18,23 @@
18
18
  * after an app's responsive variant (task 2124). An app that imports every area gets exactly
19
19
  * what `cursedbelt/styles-utilities.css` emits — proved rule by rule in
20
20
  * src/stylesAreas.spec.ts, which is also what fails when this file is stale.
21
- * 79 candidate(s).
21
+ * 78 candidate(s).
22
22
  *
23
23
  * Written by scripts/generateAreaStyles.ts (`bun run styles:areas`), which
24
24
  * `bun run build` runs. The map of what is in which area, and why the areas are
25
25
  * import closures rather than a hand-written list, is scripts/styleAreas.ts.
26
26
  */
27
27
  @source inline("bg-amber-100 bg-amber-500 bg-blue-100 bg-blue-500 bg-emerald-500 bg-green-100 bg-green-500");
28
- @source inline("bg-muted/40 bg-muted/60 bg-purple-100 bg-purple-500 bg-rose-100 bg-rose-500 bg-sky-100");
29
- @source inline("bg-sky-500 bg-slate-200 bg-slate-500 bg-teal-100 bg-teal-500 bg-violet-100 bg-violet-500");
30
- @source inline("border-border/40 border-r collapse dark:bg-amber-900/40 dark:bg-blue-900/40");
31
- @source inline("dark:bg-emerald-900/40 dark:bg-green-900/40 dark:bg-purple-900/40 dark:bg-rose-900/40");
32
- @source inline("dark:bg-sky-900/40 dark:bg-slate-800 dark:bg-teal-900/40 dark:bg-violet-900/40");
33
- @source inline("dark:text-amber-200 dark:text-blue-200 dark:text-emerald-200 dark:text-green-200");
34
- @source inline("dark:text-purple-200 dark:text-rose-200 dark:text-sky-200 dark:text-slate-200 dark:text-teal-200");
35
- @source inline("dark:text-violet-200 focus:opacity-100 grid-cols-[repeat(7,minmax(0,1fr))]");
36
- @source inline("group-focus-within:opacity-100 h-3.5 hover:bg-muted/30 hover:bg-muted/40 hover:border-border/80");
37
- @source inline("last:border-r-0 line-through min-h-28 min-h-40 opacity-85 outline-1 outline-dashed");
38
- @source inline("outline-tone-amber-ink p-1.5 sm:inline sm:min-h-0 sm:min-h-24 sm:px-1.5 sm:text-xs");
39
- @source inline("text-accent-solid-foreground text-amber-900 text-blue-800 text-emerald-800 text-green-800");
40
- @source inline("text-purple-800 text-rose-800 text-sky-800 text-slate-800 text-teal-800 text-tone-amber-ink");
41
- @source inline("text-violet-800 w-20 w-3.5");
28
+ @source inline("bg-muted/60 bg-purple-100 bg-purple-500 bg-rose-100 bg-rose-500 bg-sky-100 bg-sky-500");
29
+ @source inline("bg-slate-200 bg-slate-500 bg-teal-100 bg-teal-500 bg-violet-100 bg-violet-500 border-border/40");
30
+ @source inline("border-r collapse dark:bg-amber-900/40 dark:bg-blue-900/40 dark:bg-emerald-900/40");
31
+ @source inline("dark:bg-green-900/40 dark:bg-purple-900/40 dark:bg-rose-900/40 dark:bg-sky-900/40");
32
+ @source inline("dark:bg-slate-800 dark:bg-teal-900/40 dark:bg-violet-900/40 dark:text-amber-200");
33
+ @source inline("dark:text-blue-200 dark:text-emerald-200 dark:text-green-200 dark:text-purple-200");
34
+ @source inline("dark:text-rose-200 dark:text-sky-200 dark:text-slate-200 dark:text-teal-200 dark:text-violet-200");
35
+ @source inline("focus:opacity-100 grid-cols-[repeat(7,minmax(0,1fr))] group-focus-within:opacity-100 h-3.5");
36
+ @source inline("hover:bg-muted/30 hover:bg-muted/40 hover:border-border/80 last:border-r-0 line-through min-h-28");
37
+ @source inline("min-h-40 opacity-85 outline-1 outline-dashed outline-tone-amber-ink p-1.5 sm:inline sm:min-h-0");
38
+ @source inline("sm:min-h-24 sm:px-1.5 sm:text-xs text-accent-solid-foreground text-amber-900 text-blue-800");
39
+ @source inline("text-emerald-800 text-green-800 text-purple-800 text-rose-800 text-sky-800 text-slate-800");
40
+ @source inline("text-teal-800 text-tone-amber-ink text-violet-800 w-20 w-3.5");
@@ -20,10 +20,10 @@
20
20
  * after an app's responsive variant (task 2124). An app that imports every area gets exactly
21
21
  * what `cursedbelt/styles-utilities.css` emits — proved rule by rule in
22
22
  * src/stylesAreas.spec.ts, which is also what fails when this file is stale.
23
- * 4 candidate(s).
23
+ * 3 candidate(s).
24
24
  *
25
25
  * Written by scripts/generateAreaStyles.ts (`bun run styles:areas`), which
26
26
  * `bun run build` runs. The map of what is in which area, and why the areas are
27
27
  * import closures rather than a hand-written list, is scripts/styleAreas.ts.
28
28
  */
29
- @source inline("bg-muted/40 min-w-20 shrink-[2] w-0");
29
+ @source inline("min-w-20 shrink-[2] w-0");
@@ -18,10 +18,10 @@
18
18
  * after an app's responsive variant (task 2124). An app that imports every area gets exactly
19
19
  * what `cursedbelt/styles-utilities.css` emits — proved rule by rule in
20
20
  * src/stylesAreas.spec.ts, which is also what fails when this file is stale.
21
- * 4 candidate(s).
21
+ * 3 candidate(s).
22
22
  *
23
23
  * Written by scripts/generateAreaStyles.ts (`bun run styles:areas`), which
24
24
  * `bun run build` runs. The map of what is in which area, and why the areas are
25
25
  * import closures rather than a hand-written list, is scripts/styleAreas.ts.
26
26
  */
27
- @source inline("divide-y-0 gap-x-4 h-5 list-none");
27
+ @source inline("divide-y-0 gap-x-4 list-none");
@@ -15,7 +15,7 @@
15
15
  * after an app's responsive variant (task 2124). An app that imports every area gets exactly
16
16
  * what `cursedbelt/styles-utilities.css` emits — proved rule by rule in
17
17
  * src/stylesAreas.spec.ts, which is also what fails when this file is stale.
18
- * 829 candidate(s).
18
+ * 836 candidate(s).
19
19
  *
20
20
  * Written by scripts/generateAreaStyles.ts (`bun run styles:areas`), which
21
21
  * `bun run build` runs. The map of what is in which area, and why the areas are
@@ -49,22 +49,22 @@
49
49
  @source inline("bg-background/80 bg-background/90 bg-background/95 bg-black/50 bg-border bg-border-strong");
50
50
  @source inline("bg-card bg-current bg-destructive bg-destructive-solid bg-destructive/15 bg-destructive/5");
51
51
  @source inline("bg-destructive/8 bg-emerald-100 bg-field-bg bg-muted bg-muted-foreground/40");
52
- @source inline("bg-muted-foreground/50 bg-muted-foreground/60 bg-muted/20 bg-popover bg-popover! bg-success");
53
- @source inline("bg-success-solid bg-success/15 bg-success/5 bg-surface bg-surface-sunken bg-tone-amber-bg");
54
- @source inline("bg-tone-cyan-bg bg-tone-emerald-bg bg-tone-fuchsia-bg bg-tone-lime-bg bg-tone-orange-bg");
55
- @source inline("bg-tone-purple-bg bg-tone-rose-bg bg-tone-sky-bg bg-tone-slate-bg bg-tone-teal-bg");
56
- @source inline("bg-tone-violet-bg bg-transparent bg-warning bg-warning/15 bg-warning/5 bg-warning/8 bg-white");
57
- @source inline("block blur border border-0 border-accent border-accent/40 border-accent/50 border-b border-b-0");
58
- @source inline("border-b-2 border-b-[length:var(--status-glyph-h)] border-b-current border-border border-border!");
59
- @source inline("border-border-strong border-border/60 border-collapse border-current border-destructive/30");
60
- @source inline("border-destructive/40 border-destructive/50 border-field-border border-rule border-success/30");
61
- @source inline("border-success/40 border-success/50 border-t border-tone-sky-fg/30 border-tone-slate-fg/30");
62
- @source inline("border-transparent border-warning/30 border-warning/40 border-warning/50 border-x-4");
63
- @source inline("border-x-transparent bot bottom bottom-0 break break-all break-words c ca cap capitalize co com");
64
- @source inline("contain container content contents cursor cursor-col-resize cursor-default cursor-ew-resize");
65
- @source inline("cursor-not-allowed cursor-pointer cursor-row-resize d dark dark:bg-card-overlay");
66
- @source inline("dark:bg-card-raised dark:bg-gray-800 data data-[disabled]:hover:bg-border");
67
- @source inline("data-[disabled]:opacity-50 data-[disabled]:pointer-events-none");
52
+ @source inline("bg-muted-foreground/50 bg-muted-foreground/60 bg-muted/20 bg-muted/40 bg-popover bg-popover!");
53
+ @source inline("bg-success bg-success-solid bg-success/15 bg-success/5 bg-surface bg-surface-sunken");
54
+ @source inline("bg-tone-amber-bg bg-tone-cyan-bg bg-tone-emerald-bg bg-tone-fuchsia-bg bg-tone-lime-bg");
55
+ @source inline("bg-tone-orange-bg bg-tone-purple-bg bg-tone-rose-bg bg-tone-sky-bg bg-tone-slate-bg");
56
+ @source inline("bg-tone-teal-bg bg-tone-violet-bg bg-transparent bg-warning bg-warning/15 bg-warning/5");
57
+ @source inline("bg-warning/8 bg-white block blur border border-0 border-accent border-accent/40 border-accent/50");
58
+ @source inline("border-b border-b-0 border-b-2 border-b-[length:var(--status-glyph-h)] border-b-current");
59
+ @source inline("border-border border-border! border-border-strong border-border/60 border-collapse");
60
+ @source inline("border-current border-destructive/30 border-destructive/40 border-destructive/50");
61
+ @source inline("border-field-border border-rule border-success/30 border-success/40 border-success/50 border-t");
62
+ @source inline("border-tone-sky-fg/30 border-tone-slate-fg/30 border-transparent border-warning/30");
63
+ @source inline("border-warning/40 border-warning/50 border-x-4 border-x-transparent bot bottom bottom-0 break");
64
+ @source inline("break-all break-words c ca cap capitalize co com contain container content contents cursor");
65
+ @source inline("cursor-col-resize cursor-default cursor-ew-resize cursor-not-allowed cursor-pointer");
66
+ @source inline("cursor-row-resize d dark dark:bg-card-overlay dark:bg-card-raised dark:bg-gray-800 data");
67
+ @source inline("data-[disabled]:hover:bg-border data-[disabled]:opacity-50 data-[disabled]:pointer-events-none");
68
68
  @source inline("data-[interactive=true]:duration-[var(--duration-base)]");
69
69
  @source inline("data-[interactive=true]:ease-[var(--ease-out)] data-[interactive=true]:hover:-translate-y-0.5");
70
70
  @source inline("data-[interactive=true]:hover:border-border-strong data-[interactive=true]:transition-all");
@@ -105,7 +105,7 @@
105
105
  @source inline("group-active/sep:opacity-100 group-data-[state=open]:rotate-180");
106
106
  @source inline("group-focus-visible/sep:opacity-100 group-hover group-hover/path:opacity-100");
107
107
  @source inline("group-hover/sep:opacity-100 group-hover:opacity-100 group/path group/sep grow h h-0.5 h-1 h-1.5");
108
- @source inline("h-10 h-14 h-16 h-2 h-2.5 h-24 h-3 h-32 h-4 h-6 h-7 h-8 h-9 h-[calc(100dvh-…)]");
108
+ @source inline("h-10 h-14 h-16 h-2 h-2.5 h-24 h-3 h-32 h-4 h-5 h-6 h-7 h-8 h-9 h-[calc(100dvh-…)]");
109
109
  @source inline("h-[min(var(--region-h-lg),var(--region-h-phone))]");
110
110
  @source inline("h-[min(var(--region-h-md),var(--region-h-phone))]");
111
111
  @source inline("h-[min(var(--region-h-sm),var(--region-h-phone))] h-[var(--control-h-lg)]");
@@ -117,9 +117,10 @@
117
117
  @source inline("hover:text-destructive-foreground hover:text-foreground hover:text-foreground! hover:underline i");
118
118
  @source inline("in inline inline-block inline-flex inline-grid inset inset-0 inset-x-0 inset-y-0 invisible is");
119
119
  @source inline("iso isolate it item items items-baseline items-center items-end items-start just justify-between");
120
- @source inline("justify-center justify-end justify-start l leading leading-none leading-relaxed leading-snug");
121
- @source inline("leading-tight left left-1/2 left-2 lg lg:px-8 line line-clamp-2 low lower lowercase m m-0 max");
122
- @source inline("max-h max-h-[80vh] max-h-[calc(var(--radix-popper-available-height,100dvh)-1rem)]");
120
+ @source inline("justify-center justify-end justify-start l last last:border-b-0 leading leading-none");
121
+ @source inline("leading-relaxed leading-snug leading-tight left left-1/2 left-2 lg lg:px-8 line line-clamp-2 low");
122
+ @source inline("lower lowercase m m-0 max max-h max-h-[80vh]");
123
+ @source inline("max-h-[calc(var(--radix-popper-available-height,100dvh)-1rem)]");
123
124
  @source inline("max-h-[var(--guide-popover-max-h)] max-h-[var(--radix-select-content-available-height)]");
124
125
  @source inline("max-sm:border-b-0 max-sm:border-x-0 max-sm:bottom-0");
125
126
  @source inline("max-sm:data-[state=closed]:slide-out-to-bottom max-sm:data-[state=open]:slide-in-from-bottom");
@@ -130,8 +131,8 @@
130
131
  @source inline("max-w-[var(--page-w-wide)] max-w-[var(--reading-width)] max-w-full max-w-lg max-w-md max-w-xl");
131
132
  @source inline("max-w-xs mb-0.5 mb-1 mb-3 md md:divide-border md:divide-x md:flex-none md:flex-row");
132
133
  @source inline("md:grid-cols-4 md:inline md:w-1/3 md:w-2/5 min min-h-0 min-h-11 min-h-[1lh]");
133
- @source inline("min-h-[var(--control-h-lg)] min-h-[var(--control-h-md)] min-h-[var(--control-h-sm)] min-w-0");
134
- @source inline("min-w-11 min-w-32 min-w-[var(--radix-select-trigger-width)] ml-1 ml-auto motion");
134
+ @source inline("min-h-[var(--control-h-lg)] min-h-[var(--control-h-md)] min-h-[var(--control-h-sm)] min-h-row");
135
+ @source inline("min-w-0 min-w-11 min-w-32 min-w-[var(--radix-select-trigger-width)] ml-1 ml-auto motion");
135
136
  @source inline("motion-reduce:animate-none mt-0.5 mt-1 mt-2 mx-auto my my-1 object object-cover opacity");
136
137
  @source inline("opacity-0 opacity-30 opacity-40 opacity-50 opacity-60 opacity-70 out outline outline-none over");
137
138
  @source inline("overflow overflow-auto overflow-hidden overflow-x-auto overflow-x-clip overflow-y-auto");
@@ -142,8 +143,8 @@
142
143
  @source inline("pointer-coarse:h-11 pointer-coarse:min-h-11 pointer-coarse:min-w-11 pointer-coarse:opacity-100");
143
144
  @source inline("pointer-coarse:size-5 pointer-coarse:size-9 pointer-coarse:w-11 pointer-coarse:w-18");
144
145
  @source inline("pointer-events pointer-events-auto pointer-events-none pr-8 pt-2 pt-3 px px-0 px-1 px-1.5 px-2");
145
- @source inline("px-2.5 px-3 px-4 px-5 px-6 py-0 py-0.5 py-1 py-1.5 py-12 py-2 py-2.5 py-3 py-4 py-6");
146
- @source inline("py-[var(--panel-pad)] py-px r re relative res resize right right-0 right-2 ring ring-2");
146
+ @source inline("px-2.5 px-3 px-4 px-5 px-6 px-row-x py-0 py-0.5 py-1 py-1.5 py-12 py-2 py-2.5 py-3 py-4 py-6");
147
+ @source inline("py-[var(--panel-pad)] py-px py-row-y r re relative res resize right right-0 right-2 ring ring-2");
147
148
  @source inline("ring-background ro rotate-180 round rounded rounded-[calc(var(--radius-md)-0.25rem)]");
148
149
  @source inline("rounded-field rounded-full rounded-l-full rounded-lg rounded-md rounded-none rounded-r-full");
149
150
  @source inline("rounded-sm rounded-xl ru run running s select select-all select-none self-start shadow");
@@ -18,11 +18,11 @@
18
18
  * after an app's responsive variant (task 2124). An app that imports every area gets exactly
19
19
  * what `cursedbelt/styles-utilities.css` emits — proved rule by rule in
20
20
  * src/stylesAreas.spec.ts, which is also what fails when this file is stale.
21
- * 10 candidate(s).
21
+ * 9 candidate(s).
22
22
  *
23
23
  * Written by scripts/generateAreaStyles.ts (`bun run styles:areas`), which
24
24
  * `bun run build` runs. The map of what is in which area, and why the areas are
25
25
  * import closures rather than a hand-written list, is scripts/styleAreas.ts.
26
26
  */
27
- @source inline("active:cursor-grabbing bg-muted/40 cursor-grab focus-visible:-outline-offset-2");
28
- @source inline("focus-visible:outline focus-visible:outline-2 focus-visible:outline-ring min-w-20 shrink-[2] w-0");
27
+ @source inline("active:cursor-grabbing cursor-grab focus-visible:-outline-offset-2 focus-visible:outline");
28
+ @source inline("focus-visible:outline-2 focus-visible:outline-ring min-w-20 shrink-[2] w-0");
@@ -18,7 +18,7 @@
18
18
  * after an app's responsive variant (task 2124). An app that imports every area gets exactly
19
19
  * what `cursedbelt/styles-utilities.css` emits — proved rule by rule in
20
20
  * src/stylesAreas.spec.ts, which is also what fails when this file is stale.
21
- * 162 candidate(s).
21
+ * 161 candidate(s).
22
22
  *
23
23
  * Written by scripts/generateAreaStyles.ts (`bun run styles:areas`), which
24
24
  * `bun run build` runs. The map of what is in which area, and why the areas are
@@ -40,7 +40,7 @@
40
40
  @source inline("data-[state=open]:slide-in-from-bottom data-[state=open]:slide-in-from-left");
41
41
  @source inline("data-[state=open]:slide-in-from-right disabled:opacity-40 duration-100 fade-in");
42
42
  @source inline("focus-visible:ring-field-ring/40 focus-within:border-field-ring focus-within:ring-2");
43
- @source inline("focus-within:ring-field-ring/30 from-card gap-x-6 h-105 h-5");
43
+ @source inline("focus-within:ring-field-ring/30 from-card gap-x-6 h-105");
44
44
  @source inline("has-[[aria-invalid=true]]:border-field-error hover:bg-background hover:bg-border");
45
45
  @source inline("hover:bg-muted/40 hover:border-field-ring hover:text-warning justify-self-end last:border-0");
46
46
  @source inline("left-0 left-11 left-2.5 list-none max-h-64 max-h-88 max-h-[var(--sheet-h-lg)]");
@@ -18,7 +18,7 @@
18
18
  * after an app's responsive variant (task 2124). An app that imports every area gets exactly
19
19
  * what `cursedbelt/styles-utilities.css` emits — proved rule by rule in
20
20
  * src/stylesAreas.spec.ts, which is also what fails when this file is stale.
21
- * 111 candidate(s).
21
+ * 110 candidate(s).
22
22
  *
23
23
  * Written by scripts/generateAreaStyles.ts (`bun run styles:areas`), which
24
24
  * `bun run build` runs. The map of what is in which area, and why the areas are
@@ -36,7 +36,7 @@
36
36
  @source inline("data-[state=open]:slide-in-from-right disabled:hover:scale-100 disabled:opacity-40 duration-100");
37
37
  @source inline("focus-visible:border-border-strong focus-visible:ring-0 focus-visible:ring-field-ring/40");
38
38
  @source inline("focus-within:border-field-ring focus-within:ring-2 focus-within:ring-field-ring/30");
39
- @source inline("group-focus-within:opacity-100 h-105 h-12 h-3.5 h-5 has-[[aria-invalid=true]]:border-field-error");
39
+ @source inline("group-focus-within:opacity-100 h-105 h-12 h-3.5 has-[[aria-invalid=true]]:border-field-error");
40
40
  @source inline("hover:bg-border hover:bg-muted/50 hover:border-field-ring hover:scale-110 hover:text-warning");
41
41
  @source inline("italic leading-5 left-0 left-2.5 li list-none max-h-64 max-h-[var(--sheet-h-lg)]");
42
42
  @source inline("max-h-[var(--sheet-h-md)] max-h-[var(--sheet-h-sm)] max-w-sm min-h-20 min-w-24 min-w-64");