lostcoords-ui 0.4.1 → 0.5.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 (90) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +303 -89
  3. data/app/assets/tailwind/lostcoords/ui/avatar.css +6 -6
  4. data/app/assets/tailwind/lostcoords/ui/base.css +45 -0
  5. data/app/assets/tailwind/lostcoords/ui/card.css +20 -22
  6. data/app/assets/tailwind/lostcoords/ui/choice.css +39 -0
  7. data/app/assets/tailwind/lostcoords/ui/code-block.css +10 -0
  8. data/app/assets/tailwind/lostcoords/ui/components.css +25 -0
  9. data/app/assets/tailwind/lostcoords/ui/copy-button.css +9 -9
  10. data/app/assets/tailwind/lostcoords/ui/dialog.css +17 -17
  11. data/app/assets/tailwind/lostcoords/ui/disclosure.css +5 -5
  12. data/app/assets/tailwind/lostcoords/ui/emoji-picker.css +43 -43
  13. data/app/assets/tailwind/lostcoords/ui/field.css +2 -2
  14. data/app/assets/tailwind/lostcoords/ui/glass.css +9 -8
  15. data/app/assets/tailwind/lostcoords/ui/layout.css +2 -2
  16. data/app/assets/tailwind/lostcoords/ui/popover.css +14 -14
  17. data/app/assets/tailwind/lostcoords/ui/reading.css +24 -24
  18. data/app/assets/tailwind/lostcoords/ui/sheet.css +60 -60
  19. data/app/assets/tailwind/lostcoords/ui/squircle.css +7 -27
  20. data/app/assets/tailwind/lostcoords/ui/table.css +51 -0
  21. data/app/assets/tailwind/lostcoords/ui/theme.css +194 -225
  22. data/app/assets/tailwind/lostcoords/ui/tooltip.css +50 -0
  23. data/app/assets/tailwind/lostcoords/ui/typography.css +37 -61
  24. data/app/assets/tailwind/lostcoords/ui/ui.css +2 -21
  25. data/app/assets/tailwind/lostcoords/ui/utilities.css +14 -22
  26. data/app/helpers/lostcoords/ui/badge_helper.rb +67 -110
  27. data/app/helpers/lostcoords/ui/button_helper.rb +36 -33
  28. data/app/helpers/lostcoords/ui/card_helper.rb +9 -52
  29. data/app/helpers/lostcoords/ui/choice_helper.rb +83 -0
  30. data/app/helpers/lostcoords/ui/code_block_helper.rb +22 -0
  31. data/app/helpers/lostcoords/ui/copy_button_helper.rb +7 -7
  32. data/app/helpers/lostcoords/ui/description_list_helper.rb +12 -0
  33. data/app/helpers/lostcoords/ui/dialog_helper.rb +6 -13
  34. data/app/helpers/lostcoords/ui/feedback_helper.rb +25 -6
  35. data/app/helpers/lostcoords/ui/form_helper.rb +36 -59
  36. data/app/helpers/lostcoords/ui/glass_helper.rb +7 -7
  37. data/app/helpers/lostcoords/ui/layout_helper.rb +13 -11
  38. data/app/helpers/lostcoords/ui/menu_helper.rb +8 -8
  39. data/app/helpers/lostcoords/ui/navigation_helper.rb +131 -0
  40. data/app/helpers/lostcoords/ui/overlay_helper.rb +17 -0
  41. data/app/helpers/lostcoords/ui/primitives_helper.rb +39 -61
  42. data/app/helpers/lostcoords/ui/reading_helper.rb +2 -2
  43. data/app/helpers/lostcoords/ui/sheet_helper.rb +3 -45
  44. data/app/helpers/lostcoords/ui/structures_helper.rb +55 -64
  45. data/app/helpers/lostcoords/ui/table_helper.rb +11 -0
  46. data/app/helpers/lostcoords/ui/tailwind_helper.rb +13 -4
  47. data/app/helpers/lostcoords/ui/typography_helper.rb +11 -11
  48. data/app/javascript/lostcoords/ui/controllers/lc_code_block_controller.js +23 -0
  49. data/app/javascript/lostcoords/ui/controllers/{disclosure_controller.js → lc_collapsible_controller.js} +3 -3
  50. data/app/javascript/lostcoords/ui/controllers/{confirm_dialog_controller.js → lc_confirm_dialog_controller.js} +4 -4
  51. data/app/javascript/lostcoords/ui/controllers/{modal_controller.js → lc_dialog_controller.js} +1 -1
  52. data/app/javascript/lostcoords/ui/controllers/{emoji_picker_controller.js → lc_emoji_picker_controller.js} +4 -4
  53. data/app/javascript/lostcoords/ui/controllers/{row_menu_controller.js → lc_menu_controller.js} +3 -3
  54. data/app/javascript/lostcoords/ui/controllers/{ui_popover_controller.js → lc_popover_controller.js} +1 -1
  55. data/app/javascript/lostcoords/ui/controllers/{ui_selection_controller.js → lc_selection_controller.js} +1 -1
  56. data/app/javascript/lostcoords/ui/controllers/{sheet_controller.js → lc_sheet_controller.js} +15 -15
  57. data/app/javascript/lostcoords/ui/controllers/lc_tabs_controller.js +39 -0
  58. data/app/javascript/lostcoords/ui/controllers/{toast_controller.js → lc_toast_controller.js} +2 -2
  59. data/app/javascript/lostcoords/ui/controllers/lc_tooltip_controller.js +14 -0
  60. data/app/javascript/lostcoords/ui/helpers/catalog_picker.js +5 -5
  61. data/app/javascript/lostcoords/ui/helpers/context_dialog.js +6 -6
  62. data/app/javascript/lostcoords/ui/helpers/dialog.js +2 -2
  63. data/app/javascript/lostcoords/ui/helpers/dismiss_stack.js +7 -7
  64. data/app/javascript/lostcoords/ui/helpers/floating_panel.js +2 -2
  65. data/app/javascript/lostcoords/ui/helpers/sheet_motion.js +4 -4
  66. data/app/javascript/lostcoords/ui/index.js +51 -0
  67. data/app/views/lostcoords/ui/components/_emoji_picker.html.erb +30 -30
  68. data/app/views/lostcoords/ui/components/_lc_code_block.html.erb +18 -0
  69. data/app/views/lostcoords/ui/components/_lc_collapsible.html.erb +5 -0
  70. data/app/views/lostcoords/ui/components/_lc_dialog.html.erb +11 -8
  71. data/app/views/lostcoords/ui/components/_lc_floating_panel.html.erb +8 -0
  72. data/config/helper_renames.json +23 -25
  73. data/config/importmap.rb +10 -2
  74. data/config/locales/en.yml +23 -0
  75. data/config/locales/es.yml +23 -0
  76. data/config/locales/ja.yml +23 -0
  77. data/lib/lostcoords/ui/action_view.rb +5 -3
  78. data/lib/lostcoords/ui/builders.rb +1 -1
  79. data/lib/lostcoords/ui/form_builder.rb +113 -0
  80. data/lib/lostcoords/ui/parts.rb +154 -0
  81. data/lib/lostcoords/ui/tokens.rb +24 -1
  82. data/lib/lostcoords/ui/version.rb +1 -1
  83. metadata +33 -17
  84. data/app/views/lostcoords/ui/components/_form_alert.html.erb +0 -4
  85. data/app/views/lostcoords/ui/components/_lc_disclosure.html.erb +0 -5
  86. data/app/views/lostcoords/ui/components/_skeleton.html.erb +0 -4
  87. data/app/views/lostcoords/ui/components/_spinner.html.erb +0 -10
  88. data/app/views/lostcoords/ui/components/_ui_floating_panel.html.erb +0 -8
  89. /data/app/javascript/lostcoords/ui/controllers/{ui_copy_controller.js → lc_copy_controller.js} +0 -0
  90. /data/app/javascript/lostcoords/ui/controllers/{ui_toggle_controller.js → lc_toggle_controller.js} +0 -0
@@ -1,255 +1,224 @@
1
+ /* Every public setting lives in this file. Hosts override the plain custom
2
+ properties in :root or html[data-theme="dark"] after importing the library;
3
+ the @theme blocks only map those properties to Tailwind utilities. */
4
+
1
5
  @theme inline {
2
- --color-paper: var(--paper);
3
- --color-paper-2: var(--paper-2);
4
- --color-paper-3: var(--paper-3);
5
- --color-ink: var(--ink);
6
- --color-ink-2: var(--ink-2);
7
- --color-ink-3: var(--ink-3);
8
- --color-ink-on-accent: var(--ink-on-accent);
9
- --color-hairline: var(--hairline);
10
-
11
- --color-sky: var(--sky);
12
- --color-sky-deep: var(--sky-deep);
13
- --color-sky-soft: var(--sky-soft);
6
+ --color-background: var(--background);
7
+ --color-foreground: var(--foreground);
8
+ --color-card: var(--card);
9
+ --color-card-foreground: var(--card-foreground);
10
+ --color-popover: var(--popover);
11
+ --color-popover-foreground: var(--popover-foreground);
12
+ --color-primary: var(--primary);
13
+ --color-primary-foreground: var(--primary-foreground);
14
+ --color-secondary: var(--secondary);
15
+ --color-secondary-foreground: var(--secondary-foreground);
16
+ --color-muted: var(--muted);
17
+ --color-muted-foreground: var(--muted-foreground);
14
18
  --color-accent: var(--accent);
15
- --color-leaf: var(--leaf);
16
- --color-leaf-soft: var(--leaf-soft);
17
- --color-gold: var(--gold);
18
- --color-gold-soft: var(--gold-soft);
19
- --color-berry: var(--berry);
20
- --color-berry-soft: var(--berry-soft);
21
- --color-danger: var(--danger);
22
- --color-danger-soft: var(--danger-soft);
23
-
24
- --font-display: var(--f-display);
25
- --font-body: var(--f-body);
26
- --font-mono: var(--f-mono);
19
+ --color-accent-foreground: var(--accent-foreground);
20
+ --color-destructive: var(--destructive);
21
+ --color-success: var(--success);
22
+ --color-warning: var(--warning);
23
+ --color-border: var(--border);
24
+ --color-input: var(--input);
25
+
26
+ /* Unset by default, so the ring follows a scoped --primary. */
27
+ --color-ring: var(--ring, color-mix(in oklab, var(--primary) 50%, transparent));
28
+
29
+ --color-primary-soft: color-mix(in oklab, var(--primary) 12%, var(--background));
30
+ --color-success-soft: color-mix(in oklab, var(--success) 12%, var(--background));
31
+ --color-warning-soft: color-mix(in oklab, var(--warning) 12%, var(--background));
32
+ --color-destructive-soft: color-mix(in oklab, var(--destructive) 12%, var(--background));
33
+
34
+ /* One --radius drives every corner, as in shadcn. The default reproduces
35
+ Tailwind's own scale, so host rounded-* classes keep their sizes until the
36
+ knob moves. rounded-pill collapses to square corners when --radius is 0. */
37
+ --radius-sm: calc(var(--radius) * 0.5 * var(--lc-corner-scale, 1));
38
+ --radius-md: calc(var(--radius) * 0.75 * var(--lc-corner-scale, 1));
39
+ --radius-lg: calc(var(--radius) * var(--lc-corner-scale, 1));
40
+ --radius-xl: calc(var(--radius) * 1.5 * var(--lc-corner-scale, 1));
41
+ --radius-2xl: calc(var(--radius) * 2 * var(--lc-corner-scale, 1));
42
+ --radius-3xl: calc(var(--radius) * 3 * var(--lc-corner-scale, 1));
43
+ --radius-pill: calc(var(--radius) * 1000);
44
+
45
+ /* Semantic spacing: gap-related, p-inset, gap-section and so on. Components
46
+ never set outer margin; these gaps belong to the layout around them. */
47
+ --spacing-tight: calc(var(--spacing) * 1 * var(--lc-density));
48
+ --spacing-related: calc(var(--spacing) * 2 * var(--lc-density));
49
+ --spacing-heading: calc(var(--spacing) * 3 * var(--lc-density));
50
+ --spacing-content: calc(var(--spacing) * 4 * var(--lc-density));
51
+ --spacing-inset: var(--lc-inset);
52
+ --spacing-section: calc(var(--spacing) * 8 * var(--lc-density));
53
+ --spacing-gutter: var(--lc-gutter);
54
+
55
+ /* Buttons, inputs, selects and icon buttons share these heights. */
56
+ --spacing-control-sm: var(--lc-control-sm);
57
+ --spacing-control-md: var(--lc-control-md);
58
+ --spacing-control-lg: var(--lc-control-lg);
27
59
  }
28
60
 
29
61
  @theme {
30
- --text-xs--line-height: initial;
31
- --text-sm--line-height: initial;
32
- --text-base--line-height: initial;
33
- --text-lg--line-height: initial;
34
- --text-xl--line-height: initial;
35
- --text-2xl--line-height: initial;
36
-
37
- --z-index-above: 1;
38
- --z-index-raised: 2;
39
- --z-index-art: 3;
40
-
41
- --z-index-sticky-action: 10;
42
- --z-index-float: 10;
43
-
44
- --z-index-nav: 20;
45
- --z-index-nav-popover: 30;
46
- --z-index-popover: 30;
47
- --z-index-mobile-nav: 40;
48
- --z-index-mobile-action: 50;
49
- --z-index-prompt: 51;
50
-
51
- --z-index-overlay: 60;
52
- --z-index-overlay-panel: 61;
53
- --z-index-toast: 70;
54
-
55
- --ease-out: cubic-bezier(0.3, 0, 0, 1);
56
- --ease-out-long: cubic-bezier(0.2, 0.7, 0, 1);
57
- --ease-out-expo: cubic-bezier(0.16, 1, 0.3, 1);
58
- --ease-sheet: cubic-bezier(0.32, 0.72, 0, 1);
59
-
60
- --sheet-duration: 500ms;
61
-
62
- --sheet-offscreen: calc(100% + 2rem);
63
- --ease-out-overshoot-subtle: cubic-bezier(0.25, 1.25, 0.5, 1);
64
- --ease-spring: cubic-bezier(0.34, 1.45, 0.64, 1);
65
- --color-scrim-dock: rgb(10 14 24 / 0.22);
62
+ --font-display: var(--font-sans);
63
+ --font-japanese: "Hiragino Sans", "Yu Gothic", "YuGothic", "Meiryo", ui-sans-serif, system-ui, sans-serif;
64
+
65
+ /* Type roles. Each sets size, line height, tracking and weight together. */
66
+ --text-display: 2.25rem;
67
+ --text-display--line-height: 2.5rem;
68
+ --text-display--letter-spacing: -0.025em;
69
+ --text-display--font-weight: 700;
70
+ --text-title: 1.875rem;
71
+ --text-title--line-height: 2.25rem;
72
+ --text-title--letter-spacing: -0.025em;
73
+ --text-title--font-weight: 700;
74
+ --text-heading: 1.25rem;
75
+ --text-heading--line-height: 1.75rem;
76
+ --text-heading--letter-spacing: -0.02em;
77
+ --text-heading--font-weight: 700;
78
+ --text-subheading: 1.125rem;
79
+ --text-subheading--line-height: 1.5rem;
80
+ --text-subheading--letter-spacing: -0.015em;
81
+ --text-subheading--font-weight: 650;
82
+ --text-body: 1rem;
83
+ --text-body--line-height: 1.5rem;
84
+ --text-small: 0.875rem;
85
+ --text-small--line-height: 1.25rem;
86
+ --text-label: 0.875rem;
87
+ --text-label--line-height: 1.25rem;
88
+ --text-label--font-weight: 500;
89
+ --text-caption: 0.75rem;
90
+ --text-caption--line-height: 1rem;
91
+
92
+ --container-page: 75rem;
93
+ --container-reading: 65ch;
94
+ --container-form: 32rem;
66
95
  }
67
96
 
68
97
  @custom-variant dark (&:where(html[data-theme="dark"], html[data-theme="dark"] *));
69
98
 
70
- @theme {
71
- --animate-alert-in: alert-in 360ms var(--ease-out-expo) both;
72
-
73
- @keyframes alert-in {
74
- from { opacity: 0; transform: translateY(-0.25rem); }
75
- }
76
- }
77
-
78
99
  @layer theme {
79
100
  :root {
80
- --ui-motion-quick: 140ms;
81
- --ui-motion-control: 180ms;
82
- --ui-motion-feedback: 160ms;
83
- --ui-press-scale: 0.96;
84
-
85
- --lch-sky: 55.6% 0.176 256.6;
86
- --lch-sky-deep: 51.5% 0.169 259.2;
87
- --lch-leaf: 58.6% 0.089 144.3;
88
- --lch-gold: 73.8% 0.130 86;
89
- --lch-berry: 63.5% 0.151 41.4;
90
-
91
- --paper: oklch(100% 0 0deg);
92
- --paper-2: oklch(97.6% 0.003 264.5deg);
93
- --paper-3: oklch(95.2% 0.006 264.5deg);
94
- --ink: oklch(23.1% 0.010 268.2deg);
95
- --ink-2: oklch(39.4% 0.012 267deg);
96
- --ink-3: oklch(52.0% 0.014 267deg);
97
- --ink-on-accent: #fff;
98
- --hairline: oklch(93.1% 0.006 264.5deg);
99
-
100
- --scrim: color-mix(in oklab, var(--ink) 55%, transparent);
101
- --scrim-soft: color-mix(in oklab, var(--ink) 12%, transparent);
102
-
103
- --scrim-sheet: rgb(0 0 0 / 0.28);
104
-
105
- --sky: oklch(var(--lch-sky));
106
- --sky-deep: oklch(var(--lch-sky-deep));
107
- --sky-soft: oklch(95.2% 0.023 258.4deg);
108
- --accent: var(--sky-deep);
109
-
110
- --leaf: oklch(var(--lch-leaf));
111
- --leaf-soft: oklch(95.0% 0.015 136deg);
112
- --gold: oklch(var(--lch-gold));
113
- --gold-soft: oklch(95.5% 0.040 88deg);
114
- --berry: oklch(var(--lch-berry));
115
- --berry-soft: oklch(95.4% 0.020 58deg);
116
- --danger: var(--berry);
117
- --danger-soft: var(--berry-soft);
118
-
119
- --f-display: ui-sans-serif, system-ui, sans-serif;
120
- --f-body: ui-sans-serif, system-ui, sans-serif;
121
- --f-japanese: "Hiragino Sans", "Yu Gothic", "YuGothic", "Meiryo", ui-sans-serif, system-ui, sans-serif;
122
- --f-mono: ui-monospace, "SFMono-Regular", "SF Mono", menlo, consolas, monospace;
123
-
124
- --shadow-sm: 0 1px 2px rgb(16 24 40 / 0.05);
125
- --shadow:
126
- 0 1px 3px rgb(16 24 40 / 0.05),
127
- 0 8px 24px -8px rgb(16 24 40 / 0.09);
128
- --shadow-lg:
129
- 0 1px 3px rgb(16 24 40 / 0.06),
130
- 0 24px 48px -12px rgb(16 24 40 / 0.18);
131
-
132
- --glass-fill: color-mix(in oklab, var(--paper) 74%, transparent);
133
- --glass-edge: rgb(255 255 255 / 0.4);
134
- --glass-bar-edge: var(--glass-edge);
135
- --glass-rim:
101
+ --radius: 0.5rem;
102
+ --lc-density: 1;
103
+ --lc-inset: calc(var(--spacing) * 5 * var(--lc-density));
104
+ --lc-gutter: clamp(1rem, 3vw, 1.5rem);
105
+ --lc-control-sm: calc(var(--spacing) * 8 * var(--lc-density));
106
+ --lc-control-md: calc(var(--spacing) * 10 * var(--lc-density));
107
+ --lc-control-lg: calc(var(--spacing) * 12 * var(--lc-density));
108
+
109
+ --lc-motion-quick: 140ms;
110
+ --lc-motion-control: 180ms;
111
+ --lc-motion-feedback: 160ms;
112
+ --lc-press-scale: 0.96;
113
+ --lc-ease-out: cubic-bezier(0.3, 0, 0, 1);
114
+ --lc-ease-out-expo: cubic-bezier(0.16, 1, 0.3, 1);
115
+ --lc-ease-sheet: cubic-bezier(0.32, 0.72, 0, 1);
116
+ --lc-sheet-duration: 500ms;
117
+ --lc-sheet-offscreen: calc(100% + 2rem);
118
+
119
+ --lc-z-popover: 30;
120
+ --lc-z-sheet: 50;
121
+ --lc-z-overlay: 60;
122
+ --lc-z-toast: 70;
123
+
124
+ --background: oklch(100% 0 0deg);
125
+ --foreground: oklch(23.1% 0 0deg);
126
+
127
+ /* Cards and secondary buttons follow --muted and --accent unless set. */
128
+ --card: var(--muted);
129
+ --card-foreground: var(--foreground);
130
+ --popover: var(--background);
131
+ --popover-foreground: var(--foreground);
132
+ --primary: oklch(23.1% 0 0deg);
133
+ --primary-foreground: #fff;
134
+ --secondary: var(--accent);
135
+ --secondary-foreground: var(--foreground);
136
+ --muted: oklch(97.6% 0 0deg);
137
+ --muted-foreground: oklch(48% 0 0deg);
138
+ --accent: oklch(95.2% 0 0deg);
139
+ --accent-foreground: var(--foreground);
140
+ --destructive: oklch(50% 0.151 41.4deg);
141
+ --success: oklch(48% 0.089 144.3deg);
142
+ --warning: oklch(48% 0.090 86deg);
143
+ --border: oklch(93.1% 0 0deg);
144
+ --input: color-mix(in oklab, var(--foreground) 8%, var(--accent));
145
+
146
+ --lc-scrim: color-mix(in oklab, var(--foreground) 55%, transparent);
147
+ --lc-scrim-soft: color-mix(in oklab, var(--foreground) 12%, transparent);
148
+ --lc-scrim-sheet: rgb(0 0 0 / 0.28);
149
+ --lc-input-hover: color-mix(in oklab, var(--foreground) 13%, var(--accent));
150
+
151
+ --lc-shadow-sm: 0 1px 2px rgb(0 0 0 / 0.05);
152
+ --lc-shadow:
153
+ 0 1px 3px rgb(0 0 0 / 0.05),
154
+ 0 8px 24px -8px rgb(0 0 0 / 0.09);
155
+ --lc-shadow-lg:
156
+ 0 1px 3px rgb(0 0 0 / 0.06),
157
+ 0 24px 48px -12px rgb(0 0 0 / 0.18);
158
+
159
+ --lc-glass-fill: color-mix(in oklab, var(--background) 74%, transparent);
160
+ --lc-glass-edge: rgb(255 255 255 / 0.4);
161
+ --lc-glass-bar-edge: var(--lc-glass-edge);
162
+ --lc-glass-rim:
136
163
  inset 0 1px 0 rgb(255 255 255 / 0.6),
137
164
  inset 0 0 0 1px rgb(255 255 255 / 0.22);
138
- --glass-shadow: var(--glass-rim), var(--shadow);
165
+ --lc-glass-shadow: var(--lc-glass-rim), var(--lc-shadow);
139
166
 
140
- --glass-hud-fill:
167
+ --lc-glass-hud-fill:
141
168
  linear-gradient(rgb(255 255 255 / 0.6), rgb(255 255 255 / 0) 60%),
142
- color-mix(in oklab, var(--paper) 82%, transparent);
143
- --glass-hud-ink: var(--ink);
144
- --glass-hud-solid: var(--paper);
145
- --glass-hud-shadow:
146
- inset 0 0 0 1px rgb(16 24 40 / 0.08),
147
- 0 1px 2px rgb(16 24 40 / 0.06),
148
- 0 6px 16px -6px rgb(16 24 40 / 0.16);
149
-
150
- --pill-rim: linear-gradient(135deg, #fff 0%, #dcdce0 30%, #f7f7f8 55%, #c9c9ce 100%);
151
- --pill-surface: linear-gradient(#fff, #f1f1f4);
152
- --pill-light: inset 0 1px 0 #fff, inset 0 -1px 1px rgb(0 0 0 / 0.06);
153
- --pill-depth: 0 1px 1px rgb(0 0 0 / 0.08), 0 8px 18px -6px rgb(0 0 0 / 0.18);
154
-
155
- --focus-halo-color: color-mix(in oklab, var(--sky) 50%, transparent);
156
- --focus-halo: 0 0 0 calc(var(--spacing) * 0.5) var(--focus-halo-color);
157
-
158
- color-scheme: light;
159
-
160
- }
161
-
162
- html:lang(ja) {
163
- --f-display: var(--f-japanese);
164
- --f-body: var(--f-japanese);
169
+ color-mix(in oklab, var(--background) 82%, transparent);
170
+ --lc-glass-hud-ink: var(--foreground);
171
+ --lc-glass-hud-solid: var(--background);
172
+ --lc-glass-hud-shadow:
173
+ inset 0 0 0 1px rgb(0 0 0 / 0.08),
174
+ 0 1px 2px rgb(0 0 0 / 0.06),
175
+ 0 6px 16px -6px rgb(0 0 0 / 0.16);
176
+
177
+ /* Touch targets stay at least 40 and 44px. */
178
+ @media (pointer: coarse) {
179
+ --lc-control-sm: max(2.5rem, calc(var(--spacing) * 8 * var(--lc-density)));
180
+ --lc-control-md: max(2.75rem, calc(var(--spacing) * 10 * var(--lc-density)));
181
+ }
165
182
  }
166
183
 
167
184
  html[data-theme="dark"] {
168
- color-scheme: dark;
169
-
170
- --paper: oklch(20.5% 0.002 75deg);
171
- --paper-2: oklch(24.2% 0.003 75deg);
172
- --paper-3: oklch(28.4% 0.004 75deg);
173
- --ink: oklch(91.5% 0.006 85deg);
174
- --ink-2: color-mix(in oklab, var(--ink) 76%, var(--paper));
175
- --ink-3: color-mix(in oklab, var(--ink) 68%, var(--paper));
176
- --hairline: color-mix(in oklab, var(--ink) 16%, transparent);
177
-
178
- --scrim: rgb(0 0 0 / 0.6);
179
- --scrim-soft: rgb(0 0 0 / 0.32);
180
-
181
- --ink-on-accent: var(--paper);
182
- --sky: oklch(65.5% 0.150 255deg);
183
- --sky-deep: oklch(61.5% 0.155 257deg);
184
- --sky-soft: color-mix(in oklab, var(--sky) 18%, var(--paper));
185
- --accent: var(--sky);
186
-
187
- --leaf-soft: color-mix(in oklab, var(--leaf) 16%, var(--paper));
188
- --gold-soft: color-mix(in oklab, var(--gold) 16%, var(--paper));
189
- --berry-soft: color-mix(in oklab, var(--berry) 16%, var(--paper));
190
-
191
- --shadow-sm: 0 1px 2px rgb(0 0 0 / 0.2);
192
- --shadow:
185
+ --background: oklch(20.5% 0 0deg);
186
+ --foreground: oklch(91.5% 0 0deg);
187
+ --primary: oklch(91.5% 0 0deg);
188
+ --primary-foreground: var(--background);
189
+ --muted: oklch(24.2% 0 0deg);
190
+ --muted-foreground: color-mix(in oklab, var(--foreground) 76%, var(--background));
191
+ --accent: oklch(28.4% 0 0deg);
192
+ --destructive: oklch(78% 0.120 41.4deg);
193
+ --success: oklch(78% 0.089 144.3deg);
194
+ --warning: oklch(80% 0.110 86deg);
195
+ --border: color-mix(in oklab, var(--foreground) 16%, transparent);
196
+
197
+ --lc-scrim: rgb(0 0 0 / 0.6);
198
+ --lc-scrim-soft: rgb(0 0 0 / 0.32);
199
+
200
+ --lc-shadow-sm: 0 1px 2px rgb(0 0 0 / 0.2);
201
+ --lc-shadow:
193
202
  0 1px 2px rgb(0 0 0 / 0.16),
194
203
  0 8px 24px -8px rgb(0 0 0 / 0.32);
195
- --shadow-lg:
204
+ --lc-shadow-lg:
196
205
  0 1px 3px rgb(0 0 0 / 0.2),
197
206
  0 24px 48px -12px rgb(0 0 0 / 0.55);
198
207
 
199
- --glass-fill: color-mix(in oklab, var(--paper) 80%, transparent);
200
- --glass-edge: transparent;
201
- --glass-rim: 0 0 #0000;
202
- --glass-bar-edge: rgb(255 255 255 / 0.06);
203
- --glass-shadow: 0 1px 3px rgb(0 0 0 / 0.04), 0 4px 12px rgb(0 0 0 / 0.03);
204
- --glass-hud-fill:
208
+ --lc-glass-fill: color-mix(in oklab, var(--background) 80%, transparent);
209
+ --lc-glass-edge: transparent;
210
+ --lc-glass-rim: 0 0 #0000;
211
+ --lc-glass-bar-edge: rgb(255 255 255 / 0.06);
212
+ --lc-glass-shadow: 0 1px 3px rgb(0 0 0 / 0.04), 0 4px 12px rgb(0 0 0 / 0.03);
213
+ --lc-glass-hud-fill:
205
214
  linear-gradient(rgb(255 255 255 / 0.06), rgb(255 255 255 / 0) 60%),
206
- color-mix(in oklab, var(--paper-3) 90%, transparent);
207
- --glass-hud-solid: var(--paper-3);
208
- --glass-hud-shadow:
215
+ color-mix(in oklab, var(--accent) 90%, transparent);
216
+ --lc-glass-hud-solid: var(--accent);
217
+ --lc-glass-hud-shadow:
209
218
  inset 0 1px 0 rgb(255 255 255 / 0.1),
210
219
  inset 0 0 0 1px rgb(255 255 255 / 0.1),
211
220
  0 8px 20px -8px rgb(0 0 0 / 0.6);
212
-
213
- --pill-rim: linear-gradient(135deg, rgb(255 255 255 / 0.22) 0%, rgb(255 255 255 / 0.06) 30%, rgb(255 255 255 / 0.12) 55%, rgb(0 0 0 / 0.3) 100%);
214
- --pill-surface: linear-gradient(var(--paper-3), var(--paper-2));
215
- --pill-light: inset 0 1px 0 rgb(255 255 255 / 0.08), inset 0 -1px 1px rgb(0 0 0 / 0.2);
216
- --pill-depth: 0 1px 1px rgb(0 0 0 / 0.3), 0 8px 18px -6px rgb(0 0 0 / 0.5);
217
221
  }
218
- }
219
-
220
- @layer base {
221
- body {
222
- background-color: var(--paper);
223
- color: var(--ink);
224
- font-family: var(--f-body);
225
- line-height: 1.5;
226
- }
227
-
228
- :is(h1, h2, h3, h4, h5) {
229
- font-family: var(--f-display);
230
- line-height: 1.2;
231
- color: var(--ink);
232
- }
233
-
234
- button { cursor: pointer; background: none; }
235
-
236
- dialog { background: transparent; color: inherit; }
237
222
 
238
- :where([popover]) { color: inherit; }
239
-
240
- :is(a, button, input, textarea, select, summary, [tabindex]):focus-visible,
241
- label:has(input.sr-only:focus-visible) {
242
- outline: calc(var(--spacing) * 0.5) solid var(--focus-halo-color);
243
- outline-offset: 0;
244
- }
245
-
246
- dialog:focus-visible { outline: none; }
247
-
248
- @media (prefers-reduced-motion: reduce) {
249
- *, *::before, *::after {
250
- animation-duration: 0.01ms !important;
251
- animation-iteration-count: 1 !important;
252
- transition-duration: 0.01ms !important;
253
- }
254
- }
223
+ html:lang(ja) { --font-sans: var(--font-japanese); }
255
224
  }
@@ -0,0 +1,50 @@
1
+ @layer components {
2
+ .lc-tooltip__content {
3
+ position: absolute;
4
+ inset-block-end: calc(100% + var(--spacing-related));
5
+ inset-inline-start: 50%;
6
+ z-index: var(--lc-z-popover);
7
+ inline-size: max-content;
8
+ max-inline-size: min(16rem, calc(100vw - 2rem));
9
+ padding: var(--spacing-tight) var(--spacing-related);
10
+ border-radius: var(--radius-md);
11
+ background: var(--foreground);
12
+ color: var(--background);
13
+ font-size: var(--text-caption);
14
+ line-height: var(--text-caption--line-height);
15
+ font-weight: 500;
16
+ text-align: center;
17
+ pointer-events: none;
18
+ opacity: 0;
19
+ visibility: hidden;
20
+ translate: -50% 0.125rem;
21
+ transition:
22
+ opacity 120ms var(--lc-ease-out),
23
+ translate 120ms var(--lc-ease-out),
24
+ visibility 120ms;
25
+
26
+ &:dir(rtl) { translate: 50% 0.125rem; }
27
+ }
28
+
29
+ .lc-tooltip[data-side="bottom"] > .lc-tooltip__content {
30
+ inset-block: calc(100% + var(--spacing-related)) auto;
31
+ translate: -50% -0.125rem;
32
+ }
33
+
34
+ .lc-tooltip:is(:hover, :has(:focus-visible)) > .lc-tooltip__content {
35
+ opacity: 1;
36
+ visibility: visible;
37
+ translate: -50% 0;
38
+ transition-delay: 300ms;
39
+ }
40
+
41
+ .lc-tooltip:is(:hover, :has(:focus-visible)) > .lc-tooltip__content:dir(rtl) {
42
+ translate: 50% 0;
43
+ }
44
+
45
+ .lc-tooltip[data-dismissed] > .lc-tooltip__content {
46
+ opacity: 0;
47
+ visibility: hidden;
48
+ transition: none;
49
+ }
50
+ }
@@ -1,81 +1,57 @@
1
+ /* Type roles are utilities from theme.css (text-title, text-heading, text-body
2
+ …). These classes add what a role cannot carry: the display family, wrapping
3
+ and Japanese line breaking. */
1
4
  @layer components {
2
- :where(.ui-heading) {
3
- font-family: var(--font-display, var(--font-body, inherit));
4
- font-weight: var(--ui-heading-weight, 700);
5
- letter-spacing: var(--ui-heading-tracking, -0.025em);
5
+ :where(.lc-heading) {
6
+ font-family: var(--font-display);
6
7
  overflow-wrap: anywhere;
7
8
  text-wrap: balance;
8
9
  }
9
10
 
10
- :where(.ui-heading-page) {
11
- font-size: var(--ui-heading-page-size, 1.875rem);
12
- line-height: var(--ui-heading-page-line-height, 2.25rem);
13
- }
14
-
15
- :where(.ui-heading-section) {
16
- font-size: var(--ui-heading-section-size, 1.25rem);
17
- line-height: var(--ui-heading-section-line-height, 1.5rem);
18
- }
19
-
20
- :where(.ui-heading-card) {
21
- font-size: var(--ui-heading-card-size, 1.125rem);
22
- line-height: var(--ui-heading-card-line-height, 1.5rem);
23
- }
24
-
25
- :where(.ui-heading:lang(ja)) {
26
- letter-spacing: var(--ui-heading-ja-tracking, 0);
27
- line-break: strict;
28
- }
29
-
30
- :where(.ui-text) {
31
- font-family: var(--font-body, inherit);
32
- font-weight: var(--ui-text-weight, 400);
33
- letter-spacing: var(--ui-text-tracking, normal);
11
+ :where(.lc-text) {
34
12
  overflow-wrap: anywhere;
35
13
  }
36
14
 
37
- :where(.ui-text-body) {
38
- font-size: var(--ui-text-body-size, 1rem);
39
- line-height: var(--ui-text-body-line-height, 1.5rem);
40
- }
41
-
42
- :where(.ui-text-small) {
43
- font-size: var(--ui-text-small-size, 0.875rem);
44
- line-height: var(--ui-text-small-line-height, 1.25rem);
45
- }
46
-
47
- :where(.ui-text-caption) {
48
- font-size: var(--ui-text-caption-size, 0.75rem);
49
- line-height: var(--ui-text-caption-line-height, 1rem);
50
- }
51
-
52
- :where(.ui-text:lang(ja)) {
15
+ /* Type role utilities read --tw-tracking first, so this wins over their tracking. */
16
+ :where(.lc-heading, .lc-text):lang(ja) {
17
+ --tw-tracking: 0;
53
18
  line-break: strict;
54
19
  }
55
20
 
56
21
  @supports (word-break: auto-phrase) {
57
- :where(.ui-heading:lang(ja)) {
22
+ :where(.lc-heading:lang(ja)) {
58
23
  word-break: auto-phrase;
59
24
  }
60
25
  }
61
26
  }
62
27
 
63
- @layer utilities {
64
- :where(code):not(:where(pre code)),
65
- .ui-prose :where(code):not(:where(pre code)) {
66
- font-family: var(--f-mono);
67
- font-size: 0.875em;
68
- font-weight: inherit;
69
- line-height: inherit;
70
- color: var(--ink);
71
- background-color: var(--paper-3);
72
- border-radius: var(--radius-sm);
73
- padding: 0.125em 0.375em;
74
- overflow-wrap: anywhere;
28
+ /* Trims the space above the cap height and below the baseline, so padding and
29
+ gaps measure the visible text. Browsers without text-box keep the leading. */
30
+ @utility lc-trim {
31
+ text-box: trim-both cap alphabetic; /* browser-compat: enhancement */
32
+ }
75
33
 
76
- &::before,
77
- &::after {
78
- content: none;
79
- }
34
+ /* Inline code inside running text. base.css applies it to every <code>; prose
35
+ applies it inside .lc-prose. */
36
+ @utility lc-inline-code {
37
+ font-family: var(--font-mono);
38
+ font-size: 0.875em;
39
+ font-weight: inherit;
40
+ line-height: inherit;
41
+ color: var(--foreground);
42
+ background-color: var(--accent);
43
+ border-radius: var(--radius-sm);
44
+ padding: 0.125em 0.375em;
45
+ overflow-wrap: anywhere;
46
+
47
+ &::before,
48
+ &::after {
49
+ content: none;
50
+ }
51
+ }
52
+
53
+ @layer utilities {
54
+ .lc-prose :where(code):not(:where(pre code)) {
55
+ @apply lc-inline-code;
80
56
  }
81
57
  }
@@ -1,21 +1,2 @@
1
- @import "./theme.css";
2
- @source "../../../../helpers/**/*.rb";
3
- @source "../../../../javascript/**/*.js";
4
- @source "../../../../views/**/*.erb";
5
- @source not "../../../../../lib";
6
-
7
- @import "./glass.css";
8
- @import "./copy-button.css";
9
- @import "./disclosure.css";
10
- @import "./emoji-picker.css";
11
- @import "./popover.css";
12
- @import "./sheet.css";
13
- @import "./card.css";
14
- @import "./dialog.css";
15
- @import "./avatar.css";
16
- @import "./squircle.css";
17
- @import "./utilities.css";
18
- @import "./typography.css";
19
- @import "./layout.css";
20
- @import "./reading.css";
21
- @import "./field.css";
1
+ @import "./components.css";
2
+ @import "./base.css";