@spacesync/client 0.1.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 (100) hide show
  1. package/README.md +39 -0
  2. package/dist/analog-clock-picker.d.ts +10 -0
  3. package/dist/analog-clock-picker.js +408 -0
  4. package/dist/analog-clock-picker.js.map +1 -0
  5. package/dist/api.d.ts +222 -0
  6. package/dist/api.js +167 -0
  7. package/dist/api.js.map +1 -0
  8. package/dist/app-modal.d.ts +25 -0
  9. package/dist/app-modal.js +145 -0
  10. package/dist/app-modal.js.map +1 -0
  11. package/dist/app-shell-mobile-nav.d.ts +29 -0
  12. package/dist/app-shell-mobile-nav.js +122 -0
  13. package/dist/app-shell-mobile-nav.js.map +1 -0
  14. package/dist/app-web-shell.d.ts +20 -0
  15. package/dist/app-web-shell.js +45 -0
  16. package/dist/app-web-shell.js.map +1 -0
  17. package/dist/booking-schedule-calendars.d.ts +95 -0
  18. package/dist/booking-schedule-calendars.js +1343 -0
  19. package/dist/booking-schedule-calendars.js.map +1 -0
  20. package/dist/chat-stick-to-bottom.d.ts +22 -0
  21. package/dist/chat-stick-to-bottom.js +190 -0
  22. package/dist/chat-stick-to-bottom.js.map +1 -0
  23. package/dist/detail-page-header.d.ts +16 -0
  24. package/dist/detail-page-header.js +220 -0
  25. package/dist/detail-page-header.js.map +1 -0
  26. package/dist/dialog-CIdvylPK.d.ts +16 -0
  27. package/dist/errors-D1niseaa.d.ts +34 -0
  28. package/dist/file-picker-field.d.ts +23 -0
  29. package/dist/file-picker-field.js +165 -0
  30. package/dist/file-picker-field.js.map +1 -0
  31. package/dist/file-viewer-dialog.d.ts +15 -0
  32. package/dist/file-viewer-dialog.js +387 -0
  33. package/dist/file-viewer-dialog.js.map +1 -0
  34. package/dist/floor-switcher.d.ts +14 -0
  35. package/dist/floor-switcher.js +416 -0
  36. package/dist/floor-switcher.js.map +1 -0
  37. package/dist/forms.d.ts +52 -0
  38. package/dist/forms.js +66 -0
  39. package/dist/forms.js.map +1 -0
  40. package/dist/image-picker-field.d.ts +11 -0
  41. package/dist/image-picker-field.js +135 -0
  42. package/dist/image-picker-field.js.map +1 -0
  43. package/dist/layout-canvas-view.d.ts +57 -0
  44. package/dist/layout-canvas-view.js +974 -0
  45. package/dist/layout-canvas-view.js.map +1 -0
  46. package/dist/lib/dateDisplay.d.ts +24 -0
  47. package/dist/lib/dateDisplay.js +84 -0
  48. package/dist/lib/dateDisplay.js.map +1 -0
  49. package/dist/live-resource-meta.d.ts +11 -0
  50. package/dist/live-resource-meta.js +27 -0
  51. package/dist/live-resource-meta.js.map +1 -0
  52. package/dist/live-space-pulse-dot.d.ts +8 -0
  53. package/dist/live-space-pulse-dot.js +18 -0
  54. package/dist/live-space-pulse-dot.js.map +1 -0
  55. package/dist/notification-sidebar-preview.d.ts +37 -0
  56. package/dist/notification-sidebar-preview.js +121 -0
  57. package/dist/notification-sidebar-preview.js.map +1 -0
  58. package/dist/page-list-chrome.d.ts +124 -0
  59. package/dist/page-list-chrome.js +970 -0
  60. package/dist/page-list-chrome.js.map +1 -0
  61. package/dist/platform-support-message-composer.d.ts +38 -0
  62. package/dist/platform-support-message-composer.js +446 -0
  63. package/dist/platform-support-message-composer.js.map +1 -0
  64. package/dist/shell-sidebar-nav.d.ts +16 -0
  65. package/dist/shell-sidebar-nav.js +69 -0
  66. package/dist/shell-sidebar-nav.js.map +1 -0
  67. package/dist/shell-theme.d.ts +6 -0
  68. package/dist/shell-theme.js +9 -0
  69. package/dist/shell-theme.js.map +1 -0
  70. package/dist/shell-top-bar-chrome.d.ts +39 -0
  71. package/dist/shell-top-bar-chrome.js +105 -0
  72. package/dist/shell-top-bar-chrome.js.map +1 -0
  73. package/dist/shell-top-bar.d.ts +16 -0
  74. package/dist/shell-top-bar.js +71 -0
  75. package/dist/shell-top-bar.js.map +1 -0
  76. package/dist/styles/theme.css +223 -0
  77. package/dist/styles/theme.css.map +1 -0
  78. package/dist/styles/theme.d.ts +2 -0
  79. package/dist/support-presence-status.d.ts +11 -0
  80. package/dist/support-presence-status.js +92 -0
  81. package/dist/support-presence-status.js.map +1 -0
  82. package/dist/theme-appearance-control.d.ts +5 -0
  83. package/dist/theme-appearance-control.js +114 -0
  84. package/dist/theme-appearance-control.js.map +1 -0
  85. package/dist/theme-boot-script.d.ts +4 -0
  86. package/dist/theme-boot-script.js +9 -0
  87. package/dist/theme-boot-script.js.map +1 -0
  88. package/dist/theme-provider.d.ts +9 -0
  89. package/dist/theme-provider.js +25 -0
  90. package/dist/theme-provider.js.map +1 -0
  91. package/dist/ui.d.ts +765 -0
  92. package/dist/ui.js +5637 -0
  93. package/dist/ui.js.map +1 -0
  94. package/dist/use-client-pagination.d.ts +22 -0
  95. package/dist/use-client-pagination.js +51 -0
  96. package/dist/use-client-pagination.js.map +1 -0
  97. package/dist/use-client-sort.d.ts +20 -0
  98. package/dist/use-client-sort.js +41 -0
  99. package/dist/use-client-sort.js.map +1 -0
  100. package/package.json +208 -0
@@ -0,0 +1,223 @@
1
+ @import "@fontsource-variable/inter";
2
+
3
+ /* src/styles/theme.css */
4
+ @custom-variant dark (&:is(.dark *));
5
+ :root {
6
+ --font-size: 16px;
7
+ --background: #ffffff;
8
+ --foreground: oklch(0.145 0 0);
9
+ --card: #ffffff;
10
+ --card-foreground: oklch(0.145 0 0);
11
+ --popover: #030213;
12
+ --popover-foreground: oklch(0.985 0 0);
13
+ --primary: #030213;
14
+ --primary-foreground: oklch(1 0 0);
15
+ --secondary: oklch(0.95 0.0058 264.53);
16
+ --secondary-foreground: #030213;
17
+ --muted: #f5f5f7;
18
+ --muted-foreground: #8a8a9a;
19
+ --accent: #f1f2f4;
20
+ --accent-foreground: #030213;
21
+ --destructive: #d4183d;
22
+ --destructive-foreground: #ffffff;
23
+ --border: #eceef2;
24
+ --input: #eceef2;
25
+ --input-background: #f7f7f8;
26
+ --switch-background: #cbced4;
27
+ --font-weight-medium: 500;
28
+ --font-weight-normal: 400;
29
+ --ring: oklch(0.708 0 0);
30
+ --chart-1: oklch(0.646 0.222 41.116);
31
+ --chart-2: oklch(0.6 0.118 184.704);
32
+ --chart-3: oklch(0.398 0.07 227.392);
33
+ --chart-4: oklch(0.828 0.189 84.429);
34
+ --chart-5: oklch(0.769 0.188 70.08);
35
+ --radius: 0.625rem;
36
+ --sidebar: #f5f5f7;
37
+ --sidebar-foreground: #13131a;
38
+ --sidebar-primary: #13131a;
39
+ --sidebar-primary-foreground: #f5f5f7;
40
+ --sidebar-accent: #eceef2;
41
+ --sidebar-accent-foreground: #13131a;
42
+ --sidebar-border: #e0e0e5;
43
+ --sidebar-ring: oklch(0.708 0 0);
44
+ --scrollbar-thumb: oklch(0.55 0 0 / 0.28);
45
+ --scrollbar-thumb-hover: oklch(0.45 0 0 / 0.4);
46
+ }
47
+ :root[data-shell-theme=light],
48
+ :root:not([data-shell-theme]) {
49
+ --sidebar: #f5f5f7;
50
+ --sidebar-foreground: #13131a;
51
+ --sidebar-primary: #13131a;
52
+ --sidebar-primary-foreground: #f5f5f7;
53
+ --sidebar-accent: #eceef2;
54
+ --sidebar-accent-foreground: #13131a;
55
+ --sidebar-border: #e0e0e5;
56
+ --sidebar-ring: oklch(0.708 0 0);
57
+ }
58
+ :root[data-shell-theme=dark] {
59
+ --sidebar: #13131a;
60
+ --sidebar-foreground: oklch(0.93 0 0);
61
+ --sidebar-primary: oklch(0.93 0 0);
62
+ --sidebar-primary-foreground: #13131a;
63
+ --sidebar-accent: oklch(0.24 0.01 264);
64
+ --sidebar-accent-foreground: oklch(0.95 0 0);
65
+ --sidebar-border: oklch(0.3 0.01 264);
66
+ --sidebar-ring: oklch(0.55 0 0);
67
+ }
68
+ .dark {
69
+ --background: oklch(0.145 0 0);
70
+ --foreground: oklch(0.985 0 0);
71
+ --card: oklch(0.145 0 0);
72
+ --card-foreground: oklch(0.985 0 0);
73
+ --popover: oklch(0.145 0 0);
74
+ --popover-foreground: oklch(0.985 0 0);
75
+ --primary: oklch(0.985 0 0);
76
+ --primary-foreground: oklch(0.205 0 0);
77
+ --secondary: oklch(0.269 0 0);
78
+ --secondary-foreground: oklch(0.985 0 0);
79
+ --muted: oklch(0.269 0 0);
80
+ --muted-foreground: oklch(0.708 0 0);
81
+ --accent: oklch(0.269 0 0);
82
+ --accent-foreground: oklch(0.985 0 0);
83
+ --destructive: oklch(0.396 0.141 25.723);
84
+ --destructive-foreground: oklch(0.637 0.237 25.331);
85
+ --border: oklch(0.269 0 0);
86
+ --input: oklch(0.269 0 0);
87
+ --ring: oklch(0.439 0 0);
88
+ --font-weight-medium: 500;
89
+ --font-weight-normal: 400;
90
+ --chart-1: oklch(0.488 0.243 264.376);
91
+ --chart-2: oklch(0.696 0.17 162.48);
92
+ --chart-3: oklch(0.769 0.188 70.08);
93
+ --chart-4: oklch(0.627 0.265 303.9);
94
+ --chart-5: oklch(0.645 0.246 16.439);
95
+ --scrollbar-thumb: oklch(0.985 0 0 / 0.22);
96
+ --scrollbar-thumb-hover: oklch(0.985 0 0 / 0.35);
97
+ }
98
+ .dark[data-shell-theme=light] {
99
+ --sidebar: #f5f5f7;
100
+ --sidebar-foreground: #13131a;
101
+ --sidebar-primary: #13131a;
102
+ --sidebar-primary-foreground: #f5f5f7;
103
+ --sidebar-accent: #eceef2;
104
+ --sidebar-accent-foreground: #13131a;
105
+ --sidebar-border: #e0e0e5;
106
+ --sidebar-ring: oklch(0.708 0 0);
107
+ }
108
+ .dark[data-shell-theme=dark] {
109
+ --sidebar: oklch(0.205 0 0);
110
+ --sidebar-foreground: oklch(0.985 0 0);
111
+ --sidebar-primary: oklch(0.488 0.243 264.376);
112
+ --sidebar-primary-foreground: oklch(0.985 0 0);
113
+ --sidebar-accent: oklch(0.269 0 0);
114
+ --sidebar-accent-foreground: oklch(0.985 0 0);
115
+ --sidebar-border: oklch(0.269 0 0);
116
+ --sidebar-ring: oklch(0.439 0 0);
117
+ }
118
+ @theme inline { --font-sans: "Inter Variable", "Inter", ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji"; --color-background: var(--background); --color-foreground: var(--foreground); --color-card: var(--card); --color-card-foreground: var(--card-foreground); --color-popover: var(--popover); --color-popover-foreground: var(--popover-foreground); --color-primary: var(--primary); --color-primary-foreground: var(--primary-foreground); --color-secondary: var(--secondary); --color-secondary-foreground: var(--secondary-foreground); --color-muted: var(--muted); --color-muted-foreground: var(--muted-foreground); --color-accent: var(--accent); --color-accent-foreground: var(--accent-foreground); --color-destructive: var(--destructive); --color-destructive-foreground: var(--destructive-foreground); --color-border: var(--border); --color-input: var(--input); --color-input-background: var(--input-background); --color-switch-background: var(--switch-background); --color-ring: var(--ring); --color-chart-1: var(--chart-1); --color-chart-2: var(--chart-2); --color-chart-3: var(--chart-3); --color-chart-4: var(--chart-4); --color-chart-5: var(--chart-5); --radius-sm: calc(var(--radius) - 4px); --radius-md: calc(var(--radius) - 2px); --radius-lg: var(--radius); --radius-xl: calc(var(--radius) + 4px); --color-sidebar: var(--sidebar); --color-sidebar-foreground: var(--sidebar-foreground); --color-sidebar-primary: var(--sidebar-primary); --color-sidebar-primary-foreground: var(--sidebar-primary-foreground); --color-sidebar-accent: var(--sidebar-accent); --color-sidebar-accent-foreground: var(--sidebar-accent-foreground); --color-sidebar-border: var(--sidebar-border); --color-sidebar-ring: var(--sidebar-ring); }
119
+ @layer base {
120
+ * {
121
+ @apply border-border outline-ring/50;
122
+ }
123
+ body {
124
+ @apply bg-background text-foreground font-sans;
125
+ }
126
+ html {
127
+ font-size: var(--font-size);
128
+ }
129
+ h1 {
130
+ font-size: var(--text-2xl);
131
+ font-weight: var(--font-weight-medium);
132
+ line-height: 1.5;
133
+ }
134
+ h2 {
135
+ font-size: var(--text-xl);
136
+ font-weight: var(--font-weight-medium);
137
+ line-height: 1.5;
138
+ }
139
+ h3 {
140
+ font-size: var(--text-lg);
141
+ font-weight: var(--font-weight-medium);
142
+ line-height: 1.5;
143
+ }
144
+ h4 {
145
+ font-size: var(--text-base);
146
+ font-weight: var(--font-weight-medium);
147
+ line-height: 1.5;
148
+ }
149
+ label {
150
+ font-size: var(--text-base);
151
+ font-weight: var(--font-weight-medium);
152
+ line-height: 1.5;
153
+ }
154
+ button {
155
+ font-size: var(--text-base);
156
+ font-weight: var(--font-weight-medium);
157
+ line-height: 1.5;
158
+ cursor: pointer;
159
+ }
160
+ button:disabled {
161
+ cursor: not-allowed;
162
+ }
163
+ input {
164
+ font-size: var(--text-base);
165
+ font-weight: var(--font-weight-normal);
166
+ line-height: 1.5;
167
+ }
168
+ }
169
+ @layer components {
170
+ :root[data-shell-theme=dark] [data-slot=shell-top-bar-title] .text-foreground,
171
+ :root[data-shell-theme=dark] [data-slot=shell-top-bar-actions] .text-foreground {
172
+ color: var(--sidebar-foreground) !important;
173
+ }
174
+ :root[data-shell-theme=dark] [data-slot=shell-top-bar-title] .text-muted-foreground,
175
+ :root[data-shell-theme=dark] [data-slot=shell-top-bar-actions] .text-muted-foreground {
176
+ color: color-mix(in oklch, var(--sidebar-foreground) 62%, transparent) !important;
177
+ }
178
+ :root[data-shell-theme=dark] [data-slot=shell-top-bar-actions] :is([data-slot=button], [data-shell-top-bar-action]):hover,
179
+ :root[data-shell-theme=dark] [data-slot=shell-top-bar-actions] :is([data-slot=button], [data-shell-top-bar-action]):active {
180
+ color: var(--sidebar-foreground) !important;
181
+ }
182
+ :root[data-shell-theme=dark] [data-slot=shell-top-bar-actions] :is([data-slot=button], [data-shell-top-bar-action]).border-sidebar-border:hover,
183
+ :root[data-shell-theme=dark] [data-slot=shell-top-bar-actions] :is([data-slot=button], [data-shell-top-bar-action]).border-sidebar-border:active {
184
+ background-color: color-mix(in oklch, var(--sidebar-foreground) 12%, var(--sidebar-accent)) !important;
185
+ border-color: color-mix(in oklch, var(--sidebar-foreground) 25%, var(--sidebar-border)) !important;
186
+ }
187
+ :root[data-shell-theme=light] [data-slot=shell-top-bar-actions] :is([data-slot=button], [data-shell-top-bar-action]).border-sidebar-border:hover,
188
+ :root[data-shell-theme=light] [data-slot=shell-top-bar-actions] :is([data-slot=button], [data-shell-top-bar-action]).border-sidebar-border:active {
189
+ background-color: color-mix(in oklch, var(--sidebar-foreground) 6%, var(--sidebar-accent)) !important;
190
+ border-color: color-mix(in oklch, var(--sidebar-foreground) 14%, var(--sidebar-border)) !important;
191
+ color: var(--sidebar-foreground) !important;
192
+ }
193
+ :is([data-slot=popover-content], [data-slot=hover-card-content], [data-slot=dropdown-menu-content], [data-slot=dropdown-menu-sub-content], [data-slot=select-content], [data-slot=context-menu-content], [data-slot=context-menu-sub-content], [data-slot=menubar-content], [data-slot=menubar-sub-content]),
194
+ :is([data-slot=popover-content], [data-slot=hover-card-content], [data-slot=dropdown-menu-content], [data-slot=dropdown-menu-sub-content], [data-slot=select-content], [data-slot=context-menu-content], [data-slot=context-menu-sub-content], [data-slot=menubar-content], [data-slot=menubar-sub-content]) :is(.overflow-y-auto, .overflow-x-auto, .overflow-auto) {
195
+ scrollbar-width: thin;
196
+ scrollbar-color: var(--scrollbar-thumb) transparent;
197
+ }
198
+ :is([data-slot=popover-content], [data-slot=hover-card-content], [data-slot=dropdown-menu-content], [data-slot=dropdown-menu-sub-content], [data-slot=select-content], [data-slot=context-menu-content], [data-slot=context-menu-sub-content], [data-slot=menubar-content], [data-slot=menubar-sub-content])::-webkit-scrollbar,
199
+ :is([data-slot=popover-content], [data-slot=hover-card-content], [data-slot=dropdown-menu-content], [data-slot=dropdown-menu-sub-content], [data-slot=select-content], [data-slot=context-menu-content], [data-slot=context-menu-sub-content], [data-slot=menubar-content], [data-slot=menubar-sub-content]) :is(.overflow-y-auto, .overflow-x-auto, .overflow-auto)::-webkit-scrollbar {
200
+ width: 6px;
201
+ height: 6px;
202
+ }
203
+ :is([data-slot=popover-content], [data-slot=hover-card-content], [data-slot=dropdown-menu-content], [data-slot=dropdown-menu-sub-content], [data-slot=select-content], [data-slot=context-menu-content], [data-slot=context-menu-sub-content], [data-slot=menubar-content], [data-slot=menubar-sub-content])::-webkit-scrollbar-track,
204
+ :is([data-slot=popover-content], [data-slot=hover-card-content], [data-slot=dropdown-menu-content], [data-slot=dropdown-menu-sub-content], [data-slot=select-content], [data-slot=context-menu-content], [data-slot=context-menu-sub-content], [data-slot=menubar-content], [data-slot=menubar-sub-content]) :is(.overflow-y-auto, .overflow-x-auto, .overflow-auto)::-webkit-scrollbar-track {
205
+ background: transparent;
206
+ }
207
+ :is([data-slot=popover-content], [data-slot=hover-card-content], [data-slot=dropdown-menu-content], [data-slot=dropdown-menu-sub-content], [data-slot=select-content], [data-slot=context-menu-content], [data-slot=context-menu-sub-content], [data-slot=menubar-content], [data-slot=menubar-sub-content])::-webkit-scrollbar-thumb,
208
+ :is([data-slot=popover-content], [data-slot=hover-card-content], [data-slot=dropdown-menu-content], [data-slot=dropdown-menu-sub-content], [data-slot=select-content], [data-slot=context-menu-content], [data-slot=context-menu-sub-content], [data-slot=menubar-content], [data-slot=menubar-sub-content]) :is(.overflow-y-auto, .overflow-x-auto, .overflow-auto)::-webkit-scrollbar-thumb {
209
+ background-color: var(--scrollbar-thumb);
210
+ border-radius: 9999px;
211
+ }
212
+ :is([data-slot=popover-content], [data-slot=hover-card-content], [data-slot=dropdown-menu-content], [data-slot=dropdown-menu-sub-content], [data-slot=select-content], [data-slot=context-menu-content], [data-slot=context-menu-sub-content], [data-slot=menubar-content], [data-slot=menubar-sub-content])::-webkit-scrollbar-thumb:hover,
213
+ :is([data-slot=popover-content], [data-slot=hover-card-content], [data-slot=dropdown-menu-content], [data-slot=dropdown-menu-sub-content], [data-slot=select-content], [data-slot=context-menu-content], [data-slot=context-menu-sub-content], [data-slot=menubar-content], [data-slot=menubar-sub-content]) :is(.overflow-y-auto, .overflow-x-auto, .overflow-auto)::-webkit-scrollbar-thumb:hover {
214
+ background-color: var(--scrollbar-thumb-hover);
215
+ }
216
+ :is([data-slot=popover-content], [data-slot=hover-card-content], [data-slot=dropdown-menu-content], [data-slot=dropdown-menu-sub-content], [data-slot=select-content], [data-slot=context-menu-content], [data-slot=context-menu-sub-content], [data-slot=menubar-content], [data-slot=menubar-sub-content]) [data-slot=scroll-area-thumb] {
217
+ background-color: var(--scrollbar-thumb);
218
+ }
219
+ :is([data-slot=popover-content], [data-slot=hover-card-content], [data-slot=dropdown-menu-content], [data-slot=dropdown-menu-sub-content], [data-slot=select-content], [data-slot=context-menu-content], [data-slot=context-menu-sub-content], [data-slot=menubar-content], [data-slot=menubar-sub-content]) [data-slot=scroll-area-thumb]:hover {
220
+ background-color: var(--scrollbar-thumb-hover);
221
+ }
222
+ }
223
+ /*# sourceMappingURL=theme.css.map */
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/styles/theme.css"],"sourcesContent":["@import \"@fontsource-variable/inter\";\n\n@custom-variant dark (&:is(.dark *));\n\n:root {\n --font-size: 16px;\n --background: #ffffff;\n --foreground: oklch(0.145 0 0);\n --card: #ffffff;\n --card-foreground: oklch(0.145 0 0);\n --popover: #030213;\n --popover-foreground: oklch(0.985 0 0);\n --primary: #030213;\n --primary-foreground: oklch(1 0 0);\n --secondary: oklch(0.95 0.0058 264.53);\n --secondary-foreground: #030213;\n --muted: #f5f5f7;\n --muted-foreground: #8a8a9a;\n --accent: #f1f2f4;\n --accent-foreground: #030213;\n --destructive: #d4183d;\n --destructive-foreground: #ffffff;\n --border: #eceef2;\n --input: #eceef2;\n --input-background: #f7f7f8;\n --switch-background: #cbced4;\n --font-weight-medium: 500;\n --font-weight-normal: 400;\n --ring: oklch(0.708 0 0);\n --chart-1: oklch(0.646 0.222 41.116);\n --chart-2: oklch(0.6 0.118 184.704);\n --chart-3: oklch(0.398 0.07 227.392);\n --chart-4: oklch(0.828 0.189 84.429);\n --chart-5: oklch(0.769 0.188 70.08);\n --radius: 0.625rem;\n --sidebar: #f5f5f7;\n --sidebar-foreground: #13131a;\n --sidebar-primary: #13131a;\n --sidebar-primary-foreground: #f5f5f7;\n --sidebar-accent: #eceef2;\n --sidebar-accent-foreground: #13131a;\n --sidebar-border: #e0e0e5;\n --sidebar-ring: oklch(0.708 0 0);\n --scrollbar-thumb: oklch(0.55 0 0 / 0.28);\n --scrollbar-thumb-hover: oklch(0.45 0 0 / 0.4);\n}\n\n:root[data-shell-theme=\"light\"],\n:root:not([data-shell-theme]) {\n --sidebar: #f5f5f7;\n --sidebar-foreground: #13131a;\n --sidebar-primary: #13131a;\n --sidebar-primary-foreground: #f5f5f7;\n --sidebar-accent: #eceef2;\n --sidebar-accent-foreground: #13131a;\n --sidebar-border: #e0e0e5;\n --sidebar-ring: oklch(0.708 0 0);\n}\n\n:root[data-shell-theme=\"dark\"] {\n --sidebar: #13131a;\n --sidebar-foreground: oklch(0.93 0 0);\n --sidebar-primary: oklch(0.93 0 0);\n --sidebar-primary-foreground: #13131a;\n --sidebar-accent: oklch(0.24 0.01 264);\n --sidebar-accent-foreground: oklch(0.95 0 0);\n --sidebar-border: oklch(0.3 0.01 264);\n --sidebar-ring: oklch(0.55 0 0);\n}\n\n.dark {\n --background: oklch(0.145 0 0);\n --foreground: oklch(0.985 0 0);\n --card: oklch(0.145 0 0);\n --card-foreground: oklch(0.985 0 0);\n --popover: oklch(0.145 0 0);\n --popover-foreground: oklch(0.985 0 0);\n --primary: oklch(0.985 0 0);\n --primary-foreground: oklch(0.205 0 0);\n --secondary: oklch(0.269 0 0);\n --secondary-foreground: oklch(0.985 0 0);\n --muted: oklch(0.269 0 0);\n --muted-foreground: oklch(0.708 0 0);\n --accent: oklch(0.269 0 0);\n --accent-foreground: oklch(0.985 0 0);\n --destructive: oklch(0.396 0.141 25.723);\n --destructive-foreground: oklch(0.637 0.237 25.331);\n --border: oklch(0.269 0 0);\n --input: oklch(0.269 0 0);\n --ring: oklch(0.439 0 0);\n --font-weight-medium: 500;\n --font-weight-normal: 400;\n --chart-1: oklch(0.488 0.243 264.376);\n --chart-2: oklch(0.696 0.17 162.48);\n --chart-3: oklch(0.769 0.188 70.08);\n --chart-4: oklch(0.627 0.265 303.9);\n --chart-5: oklch(0.645 0.246 16.439);\n --scrollbar-thumb: oklch(0.985 0 0 / 0.22);\n --scrollbar-thumb-hover: oklch(0.985 0 0 / 0.35);\n}\n\n.dark[data-shell-theme=\"light\"] {\n --sidebar: #f5f5f7;\n --sidebar-foreground: #13131a;\n --sidebar-primary: #13131a;\n --sidebar-primary-foreground: #f5f5f7;\n --sidebar-accent: #eceef2;\n --sidebar-accent-foreground: #13131a;\n --sidebar-border: #e0e0e5;\n --sidebar-ring: oklch(0.708 0 0);\n}\n\n.dark[data-shell-theme=\"dark\"] {\n --sidebar: oklch(0.205 0 0);\n --sidebar-foreground: oklch(0.985 0 0);\n --sidebar-primary: oklch(0.488 0.243 264.376);\n --sidebar-primary-foreground: oklch(0.985 0 0);\n --sidebar-accent: oklch(0.269 0 0);\n --sidebar-accent-foreground: oklch(0.985 0 0);\n --sidebar-border: oklch(0.269 0 0);\n --sidebar-ring: oklch(0.439 0 0);\n}\n\n@theme inline {\n --font-sans:\n \"Inter Variable\", \"Inter\", ui-sans-serif, system-ui, sans-serif, \"Apple Color Emoji\",\n \"Segoe UI Emoji\", \"Segoe UI Symbol\", \"Noto Color Emoji\";\n --color-background: var(--background);\n --color-foreground: var(--foreground);\n --color-card: var(--card);\n --color-card-foreground: var(--card-foreground);\n --color-popover: var(--popover);\n --color-popover-foreground: var(--popover-foreground);\n --color-primary: var(--primary);\n --color-primary-foreground: var(--primary-foreground);\n --color-secondary: var(--secondary);\n --color-secondary-foreground: var(--secondary-foreground);\n --color-muted: var(--muted);\n --color-muted-foreground: var(--muted-foreground);\n --color-accent: var(--accent);\n --color-accent-foreground: var(--accent-foreground);\n --color-destructive: var(--destructive);\n --color-destructive-foreground: var(--destructive-foreground);\n --color-border: var(--border);\n --color-input: var(--input);\n --color-input-background: var(--input-background);\n --color-switch-background: var(--switch-background);\n --color-ring: var(--ring);\n --color-chart-1: var(--chart-1);\n --color-chart-2: var(--chart-2);\n --color-chart-3: var(--chart-3);\n --color-chart-4: var(--chart-4);\n --color-chart-5: var(--chart-5);\n --radius-sm: calc(var(--radius) - 4px);\n --radius-md: calc(var(--radius) - 2px);\n --radius-lg: var(--radius);\n --radius-xl: calc(var(--radius) + 4px);\n --color-sidebar: var(--sidebar);\n --color-sidebar-foreground: var(--sidebar-foreground);\n --color-sidebar-primary: var(--sidebar-primary);\n --color-sidebar-primary-foreground: var(--sidebar-primary-foreground);\n --color-sidebar-accent: var(--sidebar-accent);\n --color-sidebar-accent-foreground: var(--sidebar-accent-foreground);\n --color-sidebar-border: var(--sidebar-border);\n --color-sidebar-ring: var(--sidebar-ring);\n}\n\n@layer base {\n * {\n @apply border-border outline-ring/50;\n }\n\n body {\n @apply bg-background text-foreground font-sans;\n }\n\n /**\n * Default typography styles for HTML elements (h1-h4, p, label, button, input).\n * These are in @layer base, so Tailwind utility classes (like text-sm, text-lg) automatically override them.\n */\n\n html {\n font-size: var(--font-size);\n }\n\n h1 {\n font-size: var(--text-2xl);\n font-weight: var(--font-weight-medium);\n line-height: 1.5;\n }\n\n h2 {\n font-size: var(--text-xl);\n font-weight: var(--font-weight-medium);\n line-height: 1.5;\n }\n\n h3 {\n font-size: var(--text-lg);\n font-weight: var(--font-weight-medium);\n line-height: 1.5;\n }\n\n h4 {\n font-size: var(--text-base);\n font-weight: var(--font-weight-medium);\n line-height: 1.5;\n }\n\n label {\n font-size: var(--text-base);\n font-weight: var(--font-weight-medium);\n line-height: 1.5;\n }\n\n button {\n font-size: var(--text-base);\n font-weight: var(--font-weight-medium);\n line-height: 1.5;\n cursor: pointer;\n }\n\n button:disabled {\n cursor: not-allowed;\n }\n\n input {\n font-size: var(--text-base);\n font-weight: var(--font-weight-normal);\n line-height: 1.5;\n }\n}\n\n@layer components {\n /* Dark shell top bar — remap light page chrome utilities inside title/actions */\n :root[data-shell-theme=\"dark\"] [data-slot=\"shell-top-bar-title\"] .text-foreground,\n :root[data-shell-theme=\"dark\"] [data-slot=\"shell-top-bar-actions\"] .text-foreground {\n color: var(--sidebar-foreground) !important;\n }\n\n :root[data-shell-theme=\"dark\"] [data-slot=\"shell-top-bar-title\"] .text-muted-foreground,\n :root[data-shell-theme=\"dark\"] [data-slot=\"shell-top-bar-actions\"] .text-muted-foreground {\n color: color-mix(in oklch, var(--sidebar-foreground) 62%, transparent) !important;\n }\n\n /* shadcn Button outline/ghost hover utilities use accent tokens (light on dark shell) */\n :root[data-shell-theme=\"dark\"] [data-slot=\"shell-top-bar-actions\"]\n :is([data-slot=\"button\"], [data-shell-top-bar-action]):hover,\n :root[data-shell-theme=\"dark\"] [data-slot=\"shell-top-bar-actions\"]\n :is([data-slot=\"button\"], [data-shell-top-bar-action]):active {\n color: var(--sidebar-foreground) !important;\n }\n\n :root[data-shell-theme=\"dark\"] [data-slot=\"shell-top-bar-actions\"]\n :is([data-slot=\"button\"], [data-shell-top-bar-action]).border-sidebar-border:hover,\n :root[data-shell-theme=\"dark\"] [data-slot=\"shell-top-bar-actions\"]\n :is([data-slot=\"button\"], [data-shell-top-bar-action]).border-sidebar-border:active {\n background-color: color-mix(\n in oklch,\n var(--sidebar-foreground) 12%,\n var(--sidebar-accent)\n ) !important;\n border-color: color-mix(\n in oklch,\n var(--sidebar-foreground) 25%,\n var(--sidebar-border)\n ) !important;\n }\n\n /* Light shell top bar — keep shadcn outline buttons from using page accent hover on shell */\n :root[data-shell-theme=\"light\"] [data-slot=\"shell-top-bar-actions\"]\n :is([data-slot=\"button\"], [data-shell-top-bar-action]).border-sidebar-border:hover,\n :root[data-shell-theme=\"light\"] [data-slot=\"shell-top-bar-actions\"]\n :is([data-slot=\"button\"], [data-shell-top-bar-action]).border-sidebar-border:active {\n background-color: color-mix(\n in oklch,\n var(--sidebar-foreground) 6%,\n var(--sidebar-accent)\n ) !important;\n border-color: color-mix(\n in oklch,\n var(--sidebar-foreground) 14%,\n var(--sidebar-border)\n ) !important;\n color: var(--sidebar-foreground) !important;\n }\n\n :is(\n [data-slot=\"popover-content\"],\n [data-slot=\"hover-card-content\"],\n [data-slot=\"dropdown-menu-content\"],\n [data-slot=\"dropdown-menu-sub-content\"],\n [data-slot=\"select-content\"],\n [data-slot=\"context-menu-content\"],\n [data-slot=\"context-menu-sub-content\"],\n [data-slot=\"menubar-content\"],\n [data-slot=\"menubar-sub-content\"]\n ),\n :is(\n [data-slot=\"popover-content\"],\n [data-slot=\"hover-card-content\"],\n [data-slot=\"dropdown-menu-content\"],\n [data-slot=\"dropdown-menu-sub-content\"],\n [data-slot=\"select-content\"],\n [data-slot=\"context-menu-content\"],\n [data-slot=\"context-menu-sub-content\"],\n [data-slot=\"menubar-content\"],\n [data-slot=\"menubar-sub-content\"]\n )\n :is(.overflow-y-auto, .overflow-x-auto, .overflow-auto) {\n scrollbar-width: thin;\n scrollbar-color: var(--scrollbar-thumb) transparent;\n }\n\n :is(\n [data-slot=\"popover-content\"],\n [data-slot=\"hover-card-content\"],\n [data-slot=\"dropdown-menu-content\"],\n [data-slot=\"dropdown-menu-sub-content\"],\n [data-slot=\"select-content\"],\n [data-slot=\"context-menu-content\"],\n [data-slot=\"context-menu-sub-content\"],\n [data-slot=\"menubar-content\"],\n [data-slot=\"menubar-sub-content\"]\n )::-webkit-scrollbar,\n :is(\n [data-slot=\"popover-content\"],\n [data-slot=\"hover-card-content\"],\n [data-slot=\"dropdown-menu-content\"],\n [data-slot=\"dropdown-menu-sub-content\"],\n [data-slot=\"select-content\"],\n [data-slot=\"context-menu-content\"],\n [data-slot=\"context-menu-sub-content\"],\n [data-slot=\"menubar-content\"],\n [data-slot=\"menubar-sub-content\"]\n )\n :is(.overflow-y-auto, .overflow-x-auto, .overflow-auto)::-webkit-scrollbar {\n width: 6px;\n height: 6px;\n }\n\n :is(\n [data-slot=\"popover-content\"],\n [data-slot=\"hover-card-content\"],\n [data-slot=\"dropdown-menu-content\"],\n [data-slot=\"dropdown-menu-sub-content\"],\n [data-slot=\"select-content\"],\n [data-slot=\"context-menu-content\"],\n [data-slot=\"context-menu-sub-content\"],\n [data-slot=\"menubar-content\"],\n [data-slot=\"menubar-sub-content\"]\n )::-webkit-scrollbar-track,\n :is(\n [data-slot=\"popover-content\"],\n [data-slot=\"hover-card-content\"],\n [data-slot=\"dropdown-menu-content\"],\n [data-slot=\"dropdown-menu-sub-content\"],\n [data-slot=\"select-content\"],\n [data-slot=\"context-menu-content\"],\n [data-slot=\"context-menu-sub-content\"],\n [data-slot=\"menubar-content\"],\n [data-slot=\"menubar-sub-content\"]\n )\n :is(.overflow-y-auto, .overflow-x-auto, .overflow-auto)::-webkit-scrollbar-track {\n background: transparent;\n }\n\n :is(\n [data-slot=\"popover-content\"],\n [data-slot=\"hover-card-content\"],\n [data-slot=\"dropdown-menu-content\"],\n [data-slot=\"dropdown-menu-sub-content\"],\n [data-slot=\"select-content\"],\n [data-slot=\"context-menu-content\"],\n [data-slot=\"context-menu-sub-content\"],\n [data-slot=\"menubar-content\"],\n [data-slot=\"menubar-sub-content\"]\n )::-webkit-scrollbar-thumb,\n :is(\n [data-slot=\"popover-content\"],\n [data-slot=\"hover-card-content\"],\n [data-slot=\"dropdown-menu-content\"],\n [data-slot=\"dropdown-menu-sub-content\"],\n [data-slot=\"select-content\"],\n [data-slot=\"context-menu-content\"],\n [data-slot=\"context-menu-sub-content\"],\n [data-slot=\"menubar-content\"],\n [data-slot=\"menubar-sub-content\"]\n )\n :is(.overflow-y-auto, .overflow-x-auto, .overflow-auto)::-webkit-scrollbar-thumb {\n background-color: var(--scrollbar-thumb);\n border-radius: 9999px;\n }\n\n :is(\n [data-slot=\"popover-content\"],\n [data-slot=\"hover-card-content\"],\n [data-slot=\"dropdown-menu-content\"],\n [data-slot=\"dropdown-menu-sub-content\"],\n [data-slot=\"select-content\"],\n [data-slot=\"context-menu-content\"],\n [data-slot=\"context-menu-sub-content\"],\n [data-slot=\"menubar-content\"],\n [data-slot=\"menubar-sub-content\"]\n )::-webkit-scrollbar-thumb:hover,\n :is(\n [data-slot=\"popover-content\"],\n [data-slot=\"hover-card-content\"],\n [data-slot=\"dropdown-menu-content\"],\n [data-slot=\"dropdown-menu-sub-content\"],\n [data-slot=\"select-content\"],\n [data-slot=\"context-menu-content\"],\n [data-slot=\"context-menu-sub-content\"],\n [data-slot=\"menubar-content\"],\n [data-slot=\"menubar-sub-content\"]\n )\n :is(.overflow-y-auto, .overflow-x-auto, .overflow-auto)::-webkit-scrollbar-thumb:hover {\n background-color: var(--scrollbar-thumb-hover);\n }\n\n :is(\n [data-slot=\"popover-content\"],\n [data-slot=\"hover-card-content\"],\n [data-slot=\"dropdown-menu-content\"],\n [data-slot=\"dropdown-menu-sub-content\"],\n [data-slot=\"select-content\"],\n [data-slot=\"context-menu-content\"],\n [data-slot=\"context-menu-sub-content\"],\n [data-slot=\"menubar-content\"],\n [data-slot=\"menubar-sub-content\"]\n )\n [data-slot=\"scroll-area-thumb\"] {\n background-color: var(--scrollbar-thumb);\n }\n\n :is(\n [data-slot=\"popover-content\"],\n [data-slot=\"hover-card-content\"],\n [data-slot=\"dropdown-menu-content\"],\n [data-slot=\"dropdown-menu-sub-content\"],\n [data-slot=\"select-content\"],\n [data-slot=\"context-menu-content\"],\n [data-slot=\"context-menu-sub-content\"],\n [data-slot=\"menubar-content\"],\n [data-slot=\"menubar-sub-content\"]\n )\n [data-slot=\"scroll-area-thumb\"]:hover {\n background-color: var(--scrollbar-thumb-hover);\n }\n}\n"],"mappings":"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","names":[]}
@@ -0,0 +1,2 @@
1
+
2
+ export { }
@@ -0,0 +1,11 @@
1
+ import * as react_jsx_runtime from 'react/jsx-runtime';
2
+
3
+ /** Green pulse when online; gray dot + last-seen otherwise. Ticks so "3m ago" stays current. */
4
+ declare function SupportPresenceStatus({ lastSeenAt, onlineLabel, neverSeenLabel, className, }: {
5
+ lastSeenAt: string | null;
6
+ onlineLabel?: string;
7
+ neverSeenLabel?: string;
8
+ className?: string;
9
+ }): react_jsx_runtime.JSX.Element;
10
+
11
+ export { SupportPresenceStatus };
@@ -0,0 +1,92 @@
1
+ import { useState, useEffect } from 'react';
2
+ import { clsx } from 'clsx';
3
+ import { twMerge } from 'tailwind-merge';
4
+ import { jsxs, jsx } from 'react/jsx-runtime';
5
+
6
+ // src/support/support-presence-status.tsx
7
+
8
+ // src/lib/dateDisplay.ts
9
+ var MS_MIN = 6e4;
10
+ var MS_HOUR = 60 * MS_MIN;
11
+ var MS_DAY = 24 * MS_HOUR;
12
+ function formatRelativeTimeAgo(iso, now = /* @__PURE__ */ new Date()) {
13
+ try {
14
+ const d = new Date(iso.trim());
15
+ if (!Number.isFinite(d.getTime())) return "";
16
+ let diffMs = now.getTime() - d.getTime();
17
+ if (diffMs < 0) diffMs = 0;
18
+ const sec = Math.floor(diffMs / 1e3);
19
+ if (sec < 60) return "just now";
20
+ const min = Math.floor(diffMs / MS_MIN);
21
+ if (min < 60) return `${min}m ago`;
22
+ const hr = Math.floor(diffMs / MS_HOUR);
23
+ if (hr < 24) return `${hr}h ago`;
24
+ const day = Math.floor(diffMs / MS_DAY);
25
+ if (day < 7) return `${day}d ago`;
26
+ const week = Math.floor(day / 7);
27
+ if (week < 5) return `${week}w ago`;
28
+ const mo = Math.floor(day / 30);
29
+ if (mo < 12) return `${mo}mo ago`;
30
+ const yr = Math.floor(day / 365);
31
+ return `${Math.max(1, yr)}y ago`;
32
+ } catch {
33
+ return "";
34
+ }
35
+ }
36
+ function cn(...inputs) {
37
+ return twMerge(clsx(inputs));
38
+ }
39
+ function LiveSpacePulseDot({ className }) {
40
+ return /* @__PURE__ */ jsxs("span", { className: cn("relative flex h-2 w-2 shrink-0", className), "aria-hidden": "true", children: [
41
+ /* @__PURE__ */ jsx("span", { className: "absolute inline-flex h-full w-full animate-ping rounded-full bg-emerald-400 opacity-40" }),
42
+ /* @__PURE__ */ jsx("span", { className: "relative inline-flex h-2 w-2 rounded-full bg-emerald-500" })
43
+ ] });
44
+ }
45
+ var SUPPORT_PRESENCE_ONLINE_MS = 45e3;
46
+ function supportPresenceFromLastSeen(lastSeenAt, nowMs = Date.now()) {
47
+ if (!lastSeenAt) return { lastSeenAt: null, online: false };
48
+ const ts = new Date(lastSeenAt).getTime();
49
+ if (!Number.isFinite(ts)) return { lastSeenAt: null, online: false };
50
+ return {
51
+ lastSeenAt,
52
+ online: nowMs - ts < SUPPORT_PRESENCE_ONLINE_MS
53
+ };
54
+ }
55
+ function formatSupportPresenceLabel(snapshot, opts) {
56
+ if (snapshot.online) return opts.onlineLabel;
57
+ if (!snapshot.lastSeenAt) return opts.neverSeenLabel;
58
+ const ago = formatRelativeTimeAgo(snapshot.lastSeenAt);
59
+ if (!ago) return opts.neverSeenLabel;
60
+ return ago === "just now" ? "Last seen just now" : `Last seen ${ago}`;
61
+ }
62
+ function OfflineDot({ className }) {
63
+ return /* @__PURE__ */ jsx(
64
+ "span",
65
+ {
66
+ className: cn("inline-flex h-2 w-2 shrink-0 rounded-full bg-muted-foreground/45", className),
67
+ "aria-hidden": "true"
68
+ }
69
+ );
70
+ }
71
+ function SupportPresenceStatus({
72
+ lastSeenAt,
73
+ onlineLabel = "Online",
74
+ neverSeenLabel = "Offline",
75
+ className
76
+ }) {
77
+ const [, setTick] = useState(0);
78
+ useEffect(() => {
79
+ const id = window.setInterval(() => setTick((n) => n + 1), 15e3);
80
+ return () => window.clearInterval(id);
81
+ }, []);
82
+ const snapshot = supportPresenceFromLastSeen(lastSeenAt);
83
+ const label = formatSupportPresenceLabel(snapshot, { onlineLabel, neverSeenLabel });
84
+ return /* @__PURE__ */ jsxs("span", { className: cn("inline-flex min-w-0 items-center gap-1.5", className), children: [
85
+ snapshot.online ? /* @__PURE__ */ jsx(LiveSpacePulseDot, {}) : /* @__PURE__ */ jsx(OfflineDot, {}),
86
+ /* @__PURE__ */ jsx("span", { className: "truncate", children: label })
87
+ ] });
88
+ }
89
+
90
+ export { SupportPresenceStatus };
91
+ //# sourceMappingURL=support-presence-status.js.map
92
+ //# sourceMappingURL=support-presence-status.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/lib/dateDisplay.ts","../src/ui/utils.ts","../src/live-space/live-space-pulse-dot.tsx","../src/support/support-presence-status.tsx"],"names":["jsx","jsxs"],"mappings":"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","file":"support-presence-status.js","sourcesContent":["/** Parse `HH:mm` wall-clock time. */\nexport function parseWallClockHm(value: string): { h: number; m: number } | undefined {\n const m = /^([01]\\d|2[0-3]):([0-5]\\d)$/.exec(value.trim());\n if (!m) return undefined;\n const h = Number(m[1]);\n const min = Number(m[2]);\n if (h > 23 || min > 59) return undefined;\n return { h, m: min };\n}\n\nexport function toWallClockHmStr(h: number, m: number): string {\n return `${String(h).padStart(2, \"0\")}:${String(m).padStart(2, \"0\")}`;\n}\n\n/** Format stored `HH:mm` without timezone conversion. */\nexport function formatWallClockTime(value: string, timeFormat: \"12h\" | \"24h\"): string {\n const p = parseWallClockHm(value);\n if (!p) return value.trim() || \"—\";\n if (timeFormat === \"24h\") return toWallClockHmStr(p.h, p.m);\n const ap = p.h >= 12 ? \"PM\" : \"AM\";\n const h12 = p.h % 12 || 12;\n return `${h12}:${String(p.m).padStart(2, \"0\")} ${ap}`;\n}\n\n/** Add minutes to a wall-clock `HH:mm`, wrapping at 24h. */\nexport function addWallClockMinutes(value: string, minutes: number): string {\n const p = parseWallClockHm(value);\n if (!p) return value;\n const total = p.h * 60 + p.m + minutes;\n const wrapped = ((total % (24 * 60)) + 24 * 60) % (24 * 60);\n return toWallClockHmStr(Math.floor(wrapped / 60), wrapped % 60);\n}\n\n/** Format `YYYY-MM-DD` as a calendar date (no timezone shift). */\nexport function formatCalendarDate(ymd: string): string {\n if (!ymd || !/^\\d{4}-\\d{2}-\\d{2}$/.test(ymd)) return ymd || \"—\";\n const [y, m, d] = ymd.split(\"-\").map(Number);\n return new Date(y, m - 1, d).toLocaleDateString(\"en-US\", {\n month: \"short\",\n day: \"numeric\",\n year: \"numeric\",\n });\n}\n\n/** ISO `yyyy-mm-dd` for a local calendar date. */\nexport function toDateStr(date: Date): string {\n const y = date.getFullYear();\n const m = String(date.getMonth() + 1).padStart(2, \"0\");\n const d = String(date.getDate()).padStart(2, \"0\");\n return `${y}-${m}-${d}`;\n}\n\nexport function isSameDay(a: Date, b: Date): boolean {\n return (\n a.getFullYear() === b.getFullYear() &&\n a.getMonth() === b.getMonth() &&\n a.getDate() === b.getDate()\n );\n}\n\n/** Short label for a date; shows \"Today\" when it matches the current local day. */\nexport function formatDate(date: Date): string {\n if (isSameDay(date, new Date())) return \"Today\";\n return date.toLocaleDateString(\"en-US\", {\n weekday: \"short\",\n month: \"short\",\n day: \"numeric\",\n });\n}\n\nconst MS_MIN = 60_000;\nconst MS_HOUR = 60 * MS_MIN;\nconst MS_DAY = 24 * MS_HOUR;\n\n/**\n * Compact relative time for feeds (e.g. announcements, notifications): `2m ago`, `2d ago`.\n * Uses elapsed wall time from `now` (defaults to current time). Returns \"\" if `iso` is unparseable.\n */\nexport function formatRelativeTimeAgo(iso: string, now: Date = new Date()): string {\n try {\n const d = new Date(iso.trim());\n if (!Number.isFinite(d.getTime())) return \"\";\n let diffMs = now.getTime() - d.getTime();\n if (diffMs < 0) diffMs = 0;\n const sec = Math.floor(diffMs / 1000);\n if (sec < 60) return \"just now\";\n const min = Math.floor(diffMs / MS_MIN);\n if (min < 60) return `${min}m ago`;\n const hr = Math.floor(diffMs / MS_HOUR);\n if (hr < 24) return `${hr}h ago`;\n const day = Math.floor(diffMs / MS_DAY);\n if (day < 7) return `${day}d ago`;\n const week = Math.floor(day / 7);\n if (week < 5) return `${week}w ago`;\n const mo = Math.floor(day / 30);\n if (mo < 12) return `${mo}mo ago`;\n const yr = Math.floor(day / 365);\n return `${Math.max(1, yr)}y ago`;\n } catch {\n return \"\";\n }\n}\n","import { clsx, type ClassValue } from \"clsx\";\nimport { twMerge } from \"tailwind-merge\";\n\nexport function cn(...inputs: ClassValue[]) {\n return twMerge(clsx(inputs));\n}\n","import { cn } from \"../ui/utils\";\n\n/** Ping + solid emerald marker used on Live space page title and sidebar nav. */\nexport function LiveSpacePulseDot({ className }: { className?: string }) {\n return (\n <span className={cn(\"relative flex h-2 w-2 shrink-0\", className)} aria-hidden=\"true\">\n <span className=\"absolute inline-flex h-full w-full animate-ping rounded-full bg-emerald-400 opacity-40\" />\n <span className=\"relative inline-flex h-2 w-2 rounded-full bg-emerald-500\" />\n </span>\n );\n}\n","import { useEffect, useState } from \"react\";\nimport { formatRelativeTimeAgo } from \"../lib/dateDisplay\";\nimport { LiveSpacePulseDot } from \"../live-space/live-space-pulse-dot\";\nimport { cn } from \"../ui/utils\";\n\nconst SUPPORT_PRESENCE_ONLINE_MS = 45_000;\n\nfunction supportPresenceFromLastSeen(\n lastSeenAt: string | null | undefined,\n nowMs = Date.now(),\n): { lastSeenAt: string | null; online: boolean } {\n if (!lastSeenAt) return { lastSeenAt: null, online: false };\n const ts = new Date(lastSeenAt).getTime();\n if (!Number.isFinite(ts)) return { lastSeenAt: null, online: false };\n return {\n lastSeenAt,\n online: nowMs - ts < SUPPORT_PRESENCE_ONLINE_MS,\n };\n}\n\nfunction formatSupportPresenceLabel(\n snapshot: { online: boolean; lastSeenAt: string | null },\n opts: { onlineLabel: string; neverSeenLabel: string },\n): string {\n if (snapshot.online) return opts.onlineLabel;\n if (!snapshot.lastSeenAt) return opts.neverSeenLabel;\n const ago = formatRelativeTimeAgo(snapshot.lastSeenAt);\n if (!ago) return opts.neverSeenLabel;\n return ago === \"just now\" ? \"Last seen just now\" : `Last seen ${ago}`;\n}\n\nfunction OfflineDot({ className }: { className?: string }) {\n return (\n <span\n className={cn(\"inline-flex h-2 w-2 shrink-0 rounded-full bg-muted-foreground/45\", className)}\n aria-hidden=\"true\"\n />\n );\n}\n\n/** Green pulse when online; gray dot + last-seen otherwise. Ticks so \"3m ago\" stays current. */\nexport function SupportPresenceStatus({\n lastSeenAt,\n onlineLabel = \"Online\",\n neverSeenLabel = \"Offline\",\n className,\n}: {\n lastSeenAt: string | null;\n onlineLabel?: string;\n neverSeenLabel?: string;\n className?: string;\n}) {\n const [, setTick] = useState(0);\n\n useEffect(() => {\n const id = window.setInterval(() => setTick((n) => n + 1), 15_000);\n return () => window.clearInterval(id);\n }, []);\n\n const snapshot = supportPresenceFromLastSeen(lastSeenAt);\n const label = formatSupportPresenceLabel(snapshot, { onlineLabel, neverSeenLabel });\n\n return (\n <span className={cn(\"inline-flex min-w-0 items-center gap-1.5\", className)}>\n {snapshot.online ? <LiveSpacePulseDot /> : <OfflineDot />}\n <span className=\"truncate\">{label}</span>\n </span>\n );\n}\n"]}
@@ -0,0 +1,5 @@
1
+ import * as react_jsx_runtime from 'react/jsx-runtime';
2
+
3
+ declare function ThemeAppearanceControl(): react_jsx_runtime.JSX.Element;
4
+
5
+ export { ThemeAppearanceControl };
@@ -0,0 +1,114 @@
1
+ import { Monitor, Sun, Moon } from 'lucide-react';
2
+ import * as LabelPrimitive from '@radix-ui/react-label';
3
+ import { clsx } from 'clsx';
4
+ import { twMerge } from 'tailwind-merge';
5
+ import { jsxs, jsx } from 'react/jsx-runtime';
6
+ import * as RadioGroupPrimitive from '@radix-ui/react-radio-group';
7
+ import { useTheme } from 'next-themes';
8
+
9
+ // src/theme/theme-appearance-control.tsx
10
+ function cn(...inputs) {
11
+ return twMerge(clsx(inputs));
12
+ }
13
+ function Label({ className, ...props }) {
14
+ return /* @__PURE__ */ jsx(
15
+ LabelPrimitive.Root,
16
+ {
17
+ "data-slot": "label",
18
+ className: cn(
19
+ "flex items-center gap-2 text-sm leading-none font-medium select-none group-data-[disabled=true]:pointer-events-none group-data-[disabled=true]:opacity-50 peer-disabled:cursor-not-allowed peer-disabled:opacity-50",
20
+ className
21
+ ),
22
+ ...props
23
+ }
24
+ );
25
+ }
26
+ function RadioGroup({
27
+ className,
28
+ ...props
29
+ }) {
30
+ return /* @__PURE__ */ jsx(
31
+ RadioGroupPrimitive.Root,
32
+ {
33
+ "data-slot": "radio-group",
34
+ className: cn("grid gap-3", className),
35
+ ...props
36
+ }
37
+ );
38
+ }
39
+ function RadioGroupItem({
40
+ className,
41
+ ...props
42
+ }) {
43
+ return /* @__PURE__ */ jsx(
44
+ RadioGroupPrimitive.Item,
45
+ {
46
+ "data-slot": "radio-group-item",
47
+ className: cn(
48
+ "flex size-[18px] shrink-0 items-center justify-center rounded-full border border-border bg-card shadow-sm outline-none transition-[border-color,box-shadow]",
49
+ "focus-visible:border-blue-500 focus-visible:ring-[3px] focus-visible:ring-blue-500/25",
50
+ "aria-invalid:border-red-400 aria-invalid:ring-red-500/20",
51
+ "disabled:cursor-not-allowed disabled:opacity-50",
52
+ "data-[state=checked]:border-blue-600",
53
+ className
54
+ ),
55
+ ...props,
56
+ children: /* @__PURE__ */ jsx(
57
+ RadioGroupPrimitive.Indicator,
58
+ {
59
+ "data-slot": "radio-group-indicator",
60
+ className: "flex items-center justify-center",
61
+ children: /* @__PURE__ */ jsx("span", { className: "size-2.5 rounded-full bg-blue-600" })
62
+ }
63
+ )
64
+ }
65
+ );
66
+ }
67
+ var OPTIONS = [
68
+ {
69
+ value: "system",
70
+ label: "System",
71
+ description: "Follow your device appearance",
72
+ icon: Monitor
73
+ },
74
+ { value: "light", label: "Light (default)", description: "Always use light mode", icon: Sun },
75
+ { value: "dark", label: "Dark", description: "Always use dark mode", icon: Moon }
76
+ ];
77
+ function ThemeAppearanceControl() {
78
+ const { theme, setTheme } = useTheme();
79
+ const value = theme ?? "light";
80
+ return /* @__PURE__ */ jsxs("div", { className: "space-y-3", children: [
81
+ /* @__PURE__ */ jsx(Label, { className: "text-sm font-medium text-foreground", children: "Appearance" }),
82
+ /* @__PURE__ */ jsx(
83
+ RadioGroup,
84
+ {
85
+ value,
86
+ onValueChange: (next) => setTheme(next),
87
+ className: "flex flex-col gap-2",
88
+ children: OPTIONS.map((opt) => {
89
+ const Icon = opt.icon;
90
+ return /* @__PURE__ */ jsxs(
91
+ "label",
92
+ {
93
+ htmlFor: `theme-${opt.value}`,
94
+ className: "flex cursor-pointer items-start gap-3 rounded-lg border border-border bg-card px-3 py-2.5 transition-colors has-[:focus-visible]:ring-2 has-[:focus-visible]:ring-ring/50 hover:bg-accent/50",
95
+ children: [
96
+ /* @__PURE__ */ jsx(RadioGroupItem, { id: `theme-${opt.value}`, value: opt.value, className: "mt-0.5" }),
97
+ /* @__PURE__ */ jsx(Icon, { size: 16, className: "mt-0.5 shrink-0 text-muted-foreground", strokeWidth: 1.75 }),
98
+ /* @__PURE__ */ jsxs("span", { className: "min-w-0 flex-1", children: [
99
+ /* @__PURE__ */ jsx("span", { className: "block text-sm font-medium text-foreground", children: opt.label }),
100
+ /* @__PURE__ */ jsx("span", { className: "block text-xs text-muted-foreground", children: opt.description })
101
+ ] })
102
+ ]
103
+ },
104
+ opt.value
105
+ );
106
+ })
107
+ }
108
+ )
109
+ ] });
110
+ }
111
+
112
+ export { ThemeAppearanceControl };
113
+ //# sourceMappingURL=theme-appearance-control.js.map
114
+ //# sourceMappingURL=theme-appearance-control.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/ui/utils.ts","../src/ui/label.tsx","../src/ui/radio-group.tsx","../src/theme/theme-appearance-control.tsx"],"names":["jsx"],"mappings":"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","file":"theme-appearance-control.js","sourcesContent":["import { clsx, type ClassValue } from \"clsx\";\nimport { twMerge } from \"tailwind-merge\";\n\nexport function cn(...inputs: ClassValue[]) {\n return twMerge(clsx(inputs));\n}\n","\"use client\";\n\nimport * as React from \"react\";\nimport * as LabelPrimitive from \"@radix-ui/react-label\";\n\nimport { cn } from \"./utils\";\n\nfunction Label({ className, ...props }: React.ComponentProps<typeof LabelPrimitive.Root>) {\n return (\n <LabelPrimitive.Root\n data-slot=\"label\"\n className={cn(\n \"flex items-center gap-2 text-sm leading-none font-medium select-none group-data-[disabled=true]:pointer-events-none group-data-[disabled=true]:opacity-50 peer-disabled:cursor-not-allowed peer-disabled:opacity-50\",\n className,\n )}\n {...props}\n />\n );\n}\n\nexport { Label };\n","\"use client\";\n\nimport * as React from \"react\";\nimport * as RadioGroupPrimitive from \"@radix-ui/react-radio-group\";\n\nimport { cn } from \"./utils\";\n\nfunction RadioGroup({\n className,\n ...props\n}: React.ComponentProps<typeof RadioGroupPrimitive.Root>) {\n return (\n <RadioGroupPrimitive.Root\n data-slot=\"radio-group\"\n className={cn(\"grid gap-3\", className)}\n {...props}\n />\n );\n}\n\nfunction RadioGroupItem({\n className,\n ...props\n}: React.ComponentProps<typeof RadioGroupPrimitive.Item>) {\n return (\n <RadioGroupPrimitive.Item\n data-slot=\"radio-group-item\"\n className={cn(\n \"flex size-[18px] shrink-0 items-center justify-center rounded-full border border-border bg-card shadow-sm outline-none transition-[border-color,box-shadow]\",\n \"focus-visible:border-blue-500 focus-visible:ring-[3px] focus-visible:ring-blue-500/25\",\n \"aria-invalid:border-red-400 aria-invalid:ring-red-500/20\",\n \"disabled:cursor-not-allowed disabled:opacity-50\",\n \"data-[state=checked]:border-blue-600\",\n className,\n )}\n {...props}\n >\n <RadioGroupPrimitive.Indicator\n data-slot=\"radio-group-indicator\"\n className=\"flex items-center justify-center\"\n >\n <span className=\"size-2.5 rounded-full bg-blue-600\" />\n </RadioGroupPrimitive.Indicator>\n </RadioGroupPrimitive.Item>\n );\n}\n\nexport { RadioGroup, RadioGroupItem };\n","import { Monitor, Moon, Sun } from \"lucide-react\";\nimport { Label } from \"../ui/label\";\nimport { RadioGroup, RadioGroupItem } from \"../ui/radio-group\";\nimport { useTheme } from \"./theme-provider\";\nimport type { WebThemeMode } from \"./constants\";\n\nconst OPTIONS: ReadonlyArray<{\n value: WebThemeMode;\n label: string;\n description: string;\n icon: typeof Sun;\n}> = [\n {\n value: \"system\",\n label: \"System\",\n description: \"Follow your device appearance\",\n icon: Monitor,\n },\n { value: \"light\", label: \"Light (default)\", description: \"Always use light mode\", icon: Sun },\n { value: \"dark\", label: \"Dark\", description: \"Always use dark mode\", icon: Moon },\n];\n\nexport function ThemeAppearanceControl() {\n const { theme, setTheme } = useTheme();\n const value = (theme ?? \"light\") as WebThemeMode;\n\n return (\n <div className=\"space-y-3\">\n <Label className=\"text-sm font-medium text-foreground\">Appearance</Label>\n <RadioGroup\n value={value}\n onValueChange={(next) => setTheme(next as WebThemeMode)}\n className=\"flex flex-col gap-2\"\n >\n {OPTIONS.map((opt) => {\n const Icon = opt.icon;\n return (\n <label\n key={opt.value}\n htmlFor={`theme-${opt.value}`}\n className=\"flex cursor-pointer items-start gap-3 rounded-lg border border-border bg-card px-3 py-2.5 transition-colors has-[:focus-visible]:ring-2 has-[:focus-visible]:ring-ring/50 hover:bg-accent/50\"\n >\n <RadioGroupItem id={`theme-${opt.value}`} value={opt.value} className=\"mt-0.5\" />\n <Icon size={16} className=\"mt-0.5 shrink-0 text-muted-foreground\" strokeWidth={1.75} />\n <span className=\"min-w-0 flex-1\">\n <span className=\"block text-sm font-medium text-foreground\">{opt.label}</span>\n <span className=\"block text-xs text-muted-foreground\">{opt.description}</span>\n </span>\n </label>\n );\n })}\n </RadioGroup>\n </div>\n );\n}\n"]}
@@ -0,0 +1,4 @@
1
+ /** Inline script for index.html — prevents light flash before React hydrates */
2
+ declare const THEME_BOOT_SCRIPT: string;
3
+
4
+ export { THEME_BOOT_SCRIPT };
@@ -0,0 +1,9 @@
1
+ // src/theme/constants.ts
2
+ var WEB_THEME_STORAGE_KEY = "coworking.web.theme";
3
+
4
+ // src/theme/theme-boot-script.ts
5
+ var THEME_BOOT_SCRIPT = `(function(){try{var k=${JSON.stringify(WEB_THEME_STORAGE_KEY)};var t=localStorage.getItem(k)||"light";var d=t==="dark"||(t==="system"&&window.matchMedia("(prefers-color-scheme: dark)").matches);document.documentElement.classList.toggle("dark",d);}catch(e){}})();`;
6
+
7
+ export { THEME_BOOT_SCRIPT };
8
+ //# sourceMappingURL=theme-boot-script.js.map
9
+ //# sourceMappingURL=theme-boot-script.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/theme/constants.ts","../src/theme/theme-boot-script.ts"],"names":[],"mappings":";AACO,IAAM,qBAAA,GAAwB,qBAAA;;;ACE9B,IAAM,iBAAA,GAAoB,CAAA,sBAAA,EAAyB,IAAA,CAAK,SAAA,CAAU,qBAAqB,CAAC,CAAA,wMAAA","file":"theme-boot-script.js","sourcesContent":["/** localStorage key used by next-themes and the index.html boot script */\nexport const WEB_THEME_STORAGE_KEY = \"coworking.web.theme\";\n\nexport type WebThemeMode = \"system\" | \"light\" | \"dark\";\n","import { WEB_THEME_STORAGE_KEY } from \"./constants\";\n\n/** Inline script for index.html — prevents light flash before React hydrates */\nexport const THEME_BOOT_SCRIPT = `(function(){try{var k=${JSON.stringify(WEB_THEME_STORAGE_KEY)};var t=localStorage.getItem(k)||\"light\";var d=t===\"dark\"||(t===\"system\"&&window.matchMedia(\"(prefers-color-scheme: dark)\").matches);document.documentElement.classList.toggle(\"dark\",d);}catch(e){}})();`;\n"]}
@@ -0,0 +1,9 @@
1
+ import * as react_jsx_runtime from 'react/jsx-runtime';
2
+ import { ReactNode } from 'react';
3
+ export { useTheme } from 'next-themes';
4
+
5
+ declare function ThemeProvider({ children }: {
6
+ children: ReactNode;
7
+ }): react_jsx_runtime.JSX.Element;
8
+
9
+ export { ThemeProvider };
@@ -0,0 +1,25 @@
1
+ import { ThemeProvider as ThemeProvider$1 } from 'next-themes';
2
+ export { useTheme } from 'next-themes';
3
+ import { jsx } from 'react/jsx-runtime';
4
+
5
+ // src/theme/theme-provider.tsx
6
+
7
+ // src/theme/constants.ts
8
+ var WEB_THEME_STORAGE_KEY = "coworking.web.theme";
9
+ function ThemeProvider({ children }) {
10
+ return /* @__PURE__ */ jsx(
11
+ ThemeProvider$1,
12
+ {
13
+ attribute: "class",
14
+ defaultTheme: "light",
15
+ enableSystem: true,
16
+ storageKey: WEB_THEME_STORAGE_KEY,
17
+ disableTransitionOnChange: true,
18
+ children
19
+ }
20
+ );
21
+ }
22
+
23
+ export { ThemeProvider };
24
+ //# sourceMappingURL=theme-provider.js.map
25
+ //# sourceMappingURL=theme-provider.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/theme/constants.ts","../src/theme/theme-provider.tsx"],"names":["NextThemesProvider"],"mappings":";;;;;;;AACO,IAAM,qBAAA,GAAwB,qBAAA;ACG9B,SAAS,aAAA,CAAc,EAAE,QAAA,EAAS,EAA4B;AACnE,EAAA,uBACE,GAAA;AAAA,IAACA,eAAA;AAAA,IAAA;AAAA,MACC,SAAA,EAAU,OAAA;AAAA,MACV,YAAA,EAAa,OAAA;AAAA,MACb,YAAA,EAAY,IAAA;AAAA,MACZ,UAAA,EAAY,qBAAA;AAAA,MACZ,yBAAA,EAAyB,IAAA;AAAA,MAExB;AAAA;AAAA,GACH;AAEJ","file":"theme-provider.js","sourcesContent":["/** localStorage key used by next-themes and the index.html boot script */\nexport const WEB_THEME_STORAGE_KEY = \"coworking.web.theme\";\n\nexport type WebThemeMode = \"system\" | \"light\" | \"dark\";\n","import { ThemeProvider as NextThemesProvider } from \"next-themes\";\nimport type { ReactNode } from \"react\";\nimport { WEB_THEME_STORAGE_KEY } from \"./constants\";\n\nexport function ThemeProvider({ children }: { children: ReactNode }) {\n return (\n <NextThemesProvider\n attribute=\"class\"\n defaultTheme=\"light\"\n enableSystem\n storageKey={WEB_THEME_STORAGE_KEY}\n disableTransitionOnChange\n >\n {children}\n </NextThemesProvider>\n );\n}\n\nexport { useTheme } from \"next-themes\";\n"]}