clio-design-system 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.
package/dist/index.cjs ADDED
@@ -0,0 +1,2162 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/index.ts
21
+ var index_exports = {};
22
+ __export(index_exports, {
23
+ AnnotationPanel: () => AnnotationPanel,
24
+ AnnotationToggle: () => AnnotationToggle,
25
+ Avatar: () => Avatar,
26
+ Badge: () => Badge,
27
+ BottomSheet: () => BottomSheet,
28
+ Button: () => Button,
29
+ CardHeader: () => CardHeader,
30
+ CardShell: () => CardShell,
31
+ CodeCard: () => CodeCard,
32
+ ColorSwatch: () => ColorSwatch,
33
+ ContextMenu: () => ContextMenu,
34
+ DragHandle: () => DragHandle,
35
+ EquationBlock: () => EquationBlock,
36
+ ExportRow: () => ExportRow,
37
+ FillBlankInput: () => FillBlankInput,
38
+ Flashcard: () => Flashcard,
39
+ IconButton: () => IconButton,
40
+ ImageCard: () => ImageCard,
41
+ ImportExportModal: () => ImportExportModal,
42
+ IntuitionCallout: () => IntuitionCallout,
43
+ McqOption: () => McqOption,
44
+ NavTabs: () => NavTabs,
45
+ NoteRow: () => NoteRow,
46
+ QuizCard: () => QuizCard,
47
+ RateButtons: () => RateButtons,
48
+ ReferencesCard: () => ReferencesCard,
49
+ RelatedCard: () => RelatedCard,
50
+ ScenarioBox: () => ScenarioBox,
51
+ Sidebar: () => Sidebar,
52
+ SolvedStatusButton: () => SolvedStatusButton,
53
+ TableCard: () => TableCard,
54
+ TagChip: () => TagChip,
55
+ TextArea: () => TextArea,
56
+ TextBlock: () => TextBlock,
57
+ TextInput: () => TextInput,
58
+ TocFab: () => TocFab,
59
+ TocRail: () => TocRail,
60
+ TocSheetList: () => TocSheetList,
61
+ TopicRow: () => TopicRow,
62
+ WalkthroughCard: () => WalkthroughCard
63
+ });
64
+ module.exports = __toCommonJS(index_exports);
65
+
66
+ // src/components/Button/Button.tsx
67
+ var import_jsx_runtime = require("react/jsx-runtime");
68
+ var SIZE = {
69
+ sm: { padY: "6px", padX: "14px", font: "var(--font-size-sm)" },
70
+ md: { padY: "9px", padX: "18px", font: "var(--font-size-base)" }
71
+ };
72
+ function Button({
73
+ variant = "secondary",
74
+ size = "md",
75
+ active = false,
76
+ disabled = false,
77
+ icon = null,
78
+ children,
79
+ onClick,
80
+ title,
81
+ ...rest
82
+ }) {
83
+ const s = SIZE[size] ?? SIZE.md;
84
+ const base = {
85
+ fontFamily: "var(--font-family-mono)",
86
+ fontSize: s.font,
87
+ letterSpacing: "var(--letter-spacing-mono-label)",
88
+ padding: `${s.padY} ${s.padX}`,
89
+ borderRadius: "var(--radius-pill)",
90
+ border: "none",
91
+ display: "inline-flex",
92
+ alignItems: "center",
93
+ gap: "7px",
94
+ cursor: disabled ? "default" : "pointer",
95
+ opacity: disabled ? 0.4 : 1,
96
+ transition: "background var(--duration-fast) ease, color var(--duration-fast) ease"
97
+ };
98
+ let style = { ...base };
99
+ if (variant === "primary") {
100
+ style = { ...style, background: "var(--color-accent)", color: "#FFFFFF" };
101
+ } else if (variant === "dark") {
102
+ style = { ...style, background: "var(--color-ink-900)", color: "var(--color-cream-50)" };
103
+ } else if (variant === "secondary") {
104
+ style = {
105
+ ...style,
106
+ background: "var(--color-surface)",
107
+ color: "var(--color-text-secondary)",
108
+ border: "1px solid var(--border-medium)"
109
+ };
110
+ } else if (variant === "ghost") {
111
+ style = { ...style, background: "transparent", color: "var(--color-text-muted)", padding: "2px 4px" };
112
+ } else if (variant === "nav") {
113
+ style = {
114
+ ...style,
115
+ background: active ? "var(--color-ink-900)" : "transparent",
116
+ color: active ? "var(--color-cream-50)" : "var(--color-text-muted)"
117
+ };
118
+ }
119
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("button", { type: "button", title, disabled, onClick, ...rest, style, children: [
120
+ icon ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { "aria-hidden": "true", style: { fontSize: "13px", lineHeight: 1 }, children: icon }) : null,
121
+ children
122
+ ] });
123
+ }
124
+
125
+ // src/internal/useHover.ts
126
+ var import_react = require("react");
127
+ function useHover(options = {}) {
128
+ const [hovered, setHovered] = (0, import_react.useState)(false);
129
+ const [focused, setFocused] = (0, import_react.useState)(false);
130
+ return {
131
+ hovered,
132
+ focused,
133
+ active: hovered || focused,
134
+ interactionHandlers: {
135
+ onMouseEnter: (e) => {
136
+ setHovered(true);
137
+ options.onMouseEnter?.(e);
138
+ },
139
+ onMouseLeave: (e) => {
140
+ setHovered(false);
141
+ options.onMouseLeave?.(e);
142
+ },
143
+ onFocus: (e) => {
144
+ setFocused(true);
145
+ options.onFocus?.(e);
146
+ },
147
+ onBlur: (e) => {
148
+ setFocused(false);
149
+ options.onBlur?.(e);
150
+ }
151
+ }
152
+ };
153
+ }
154
+
155
+ // src/components/IconButton/IconButton.tsx
156
+ var import_jsx_runtime2 = require("react/jsx-runtime");
157
+ function IconButton({
158
+ size = 26,
159
+ children,
160
+ onClick,
161
+ title,
162
+ bordered = false,
163
+ hoverColor = "var(--color-text-secondary)",
164
+ disabled = false,
165
+ radius = "var(--radius-md)",
166
+ onMouseEnter,
167
+ onMouseLeave,
168
+ onFocus,
169
+ onBlur,
170
+ ...rest
171
+ }) {
172
+ const { active, interactionHandlers } = useHover({ onMouseEnter, onMouseLeave, onFocus, onBlur });
173
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
174
+ "button",
175
+ {
176
+ type: "button",
177
+ title,
178
+ "aria-label": title,
179
+ onClick,
180
+ disabled,
181
+ ...rest,
182
+ ...interactionHandlers,
183
+ style: {
184
+ width: size,
185
+ height: size,
186
+ border: bordered ? "1px solid var(--border-medium)" : "none",
187
+ background: active ? "rgba(17,17,17,0.08)" : bordered ? "var(--color-surface)" : "transparent",
188
+ borderRadius: radius,
189
+ color: active ? hoverColor : "var(--color-text-muted)",
190
+ display: "flex",
191
+ alignItems: "center",
192
+ justifyContent: "center",
193
+ fontSize: "15px",
194
+ lineHeight: 1,
195
+ padding: 0,
196
+ cursor: disabled ? "default" : "pointer",
197
+ opacity: disabled ? 0.4 : 1,
198
+ transition: "background var(--duration-fast) ease, color var(--duration-fast) ease"
199
+ },
200
+ children
201
+ }
202
+ );
203
+ }
204
+
205
+ // src/components/TagChip/TagChip.tsx
206
+ var import_jsx_runtime3 = require("react/jsx-runtime");
207
+ function TagChip({
208
+ label,
209
+ color = "var(--color-ink-500)",
210
+ active = false,
211
+ onClick,
212
+ removable = false,
213
+ onRemove,
214
+ size = "md",
215
+ ...rest
216
+ }) {
217
+ const tint = active ? color : `color-mix(in srgb, ${color} 14%, transparent)`;
218
+ const textColor = active ? "#FFFFFF" : color;
219
+ const font = size === "sm" ? "9px" : "10.5px";
220
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
221
+ "span",
222
+ {
223
+ style: {
224
+ display: "inline-flex",
225
+ alignItems: "center",
226
+ gap: 5,
227
+ borderRadius: "var(--radius-pill)",
228
+ padding: removable ? "3px 6px 3px 9px" : "3px 10px",
229
+ fontFamily: "var(--font-family-mono)",
230
+ fontSize: font,
231
+ background: tint,
232
+ color: textColor,
233
+ whiteSpace: "nowrap"
234
+ },
235
+ children: [
236
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
237
+ "button",
238
+ {
239
+ type: "button",
240
+ onClick,
241
+ ...rest,
242
+ style: { border: "none", background: "none", padding: 0, font: "inherit", color: "inherit", cursor: "pointer" },
243
+ children: [
244
+ "#",
245
+ label
246
+ ]
247
+ }
248
+ ),
249
+ removable && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
250
+ "button",
251
+ {
252
+ type: "button",
253
+ onClick: (e) => {
254
+ e.stopPropagation();
255
+ onRemove?.();
256
+ },
257
+ "aria-label": `Remove ${label} tag`,
258
+ style: {
259
+ border: "none",
260
+ background: "none",
261
+ padding: "0 1px",
262
+ opacity: 0.7,
263
+ fontSize: "12px",
264
+ lineHeight: 1,
265
+ color: "inherit",
266
+ cursor: "pointer"
267
+ },
268
+ children: "\xD7"
269
+ }
270
+ )
271
+ ]
272
+ }
273
+ );
274
+ }
275
+
276
+ // src/components/Badge/Badge.tsx
277
+ var import_jsx_runtime4 = require("react/jsx-runtime");
278
+ function Badge({ variant = "mono", children, color, tint }) {
279
+ if (variant === "topic") {
280
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
281
+ "span",
282
+ {
283
+ style: {
284
+ fontFamily: "var(--font-family-mono)",
285
+ fontSize: "var(--font-size-sm)",
286
+ letterSpacing: "0.06em",
287
+ fontWeight: 500,
288
+ color: color || "var(--color-accent)",
289
+ background: tint || "color-mix(in srgb, var(--color-accent) 10%, transparent)",
290
+ padding: "3px 9px",
291
+ borderRadius: "var(--radius-xs)",
292
+ whiteSpace: "nowrap",
293
+ display: "inline-block"
294
+ },
295
+ children
296
+ }
297
+ );
298
+ }
299
+ if (variant === "eyebrow") {
300
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
301
+ "span",
302
+ {
303
+ style: {
304
+ fontFamily: "var(--font-family-mono)",
305
+ fontSize: "var(--font-size-xs)",
306
+ letterSpacing: "var(--letter-spacing-mono-wide)",
307
+ color: color || "var(--color-accent)",
308
+ whiteSpace: "nowrap"
309
+ },
310
+ children
311
+ }
312
+ );
313
+ }
314
+ if (variant === "count") {
315
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
316
+ "span",
317
+ {
318
+ style: {
319
+ minWidth: 17,
320
+ height: 17,
321
+ padding: "0 4px",
322
+ boxSizing: "border-box",
323
+ borderRadius: "var(--radius-full)",
324
+ display: "inline-flex",
325
+ alignItems: "center",
326
+ justifyContent: "center",
327
+ fontSize: "9.5px",
328
+ background: tint || "color-mix(in srgb, var(--color-accent) 14%, transparent)",
329
+ color: color || "var(--color-accent)"
330
+ },
331
+ children
332
+ }
333
+ );
334
+ }
335
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
336
+ "span",
337
+ {
338
+ style: {
339
+ fontFamily: "var(--font-family-mono)",
340
+ fontSize: "var(--font-size-xs)",
341
+ letterSpacing: "0.1em",
342
+ color: "var(--color-text-muted)",
343
+ background: "var(--border-hairline)",
344
+ padding: "2px 8px",
345
+ borderRadius: "var(--radius-xs)"
346
+ },
347
+ children
348
+ }
349
+ );
350
+ }
351
+
352
+ // src/components/SolvedStatusButton/SolvedStatusButton.tsx
353
+ var import_jsx_runtime5 = require("react/jsx-runtime");
354
+ function SolvedStatusButton({ solved = false, onClick, ...rest }) {
355
+ return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
356
+ "button",
357
+ {
358
+ type: "button",
359
+ onClick,
360
+ ...rest,
361
+ style: {
362
+ border: `1px solid ${solved ? "color-mix(in srgb, var(--color-success) 35%, transparent)" : "var(--border-medium)"}`,
363
+ background: solved ? "var(--color-success-tint)" : "transparent",
364
+ color: solved ? "var(--color-success)" : "var(--color-text-muted)",
365
+ borderRadius: "var(--radius-sm)",
366
+ padding: "3px 10px",
367
+ fontFamily: "var(--font-family-mono)",
368
+ fontSize: "var(--font-size-xs)",
369
+ letterSpacing: "0.06em"
370
+ },
371
+ children: solved ? "\u2713 SOLVED" : "MARK SOLVED"
372
+ }
373
+ );
374
+ }
375
+
376
+ // src/components/TextInput/TextInput.tsx
377
+ var import_jsx_runtime6 = require("react/jsx-runtime");
378
+ function TextInput({
379
+ value,
380
+ onChange,
381
+ placeholder,
382
+ mono = false,
383
+ autoFocus = false,
384
+ style,
385
+ "aria-label": ariaLabel,
386
+ type = "text",
387
+ ...rest
388
+ }) {
389
+ return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
390
+ "input",
391
+ {
392
+ type,
393
+ value,
394
+ onChange,
395
+ placeholder,
396
+ autoFocus,
397
+ "aria-label": ariaLabel,
398
+ ...rest,
399
+ style: {
400
+ border: "1px solid var(--border-medium)",
401
+ borderRadius: "var(--radius-md)",
402
+ background: "var(--color-surface)",
403
+ fontFamily: mono ? "var(--font-family-mono)" : "inherit",
404
+ fontSize: mono ? "var(--font-size-base)" : "var(--font-size-lg)",
405
+ color: "var(--color-text-primary)",
406
+ padding: "7px 11px",
407
+ boxSizing: "border-box",
408
+ ...style
409
+ }
410
+ }
411
+ );
412
+ }
413
+
414
+ // src/components/TextArea/TextArea.tsx
415
+ var import_jsx_runtime7 = require("react/jsx-runtime");
416
+ function TextArea({
417
+ value,
418
+ onChange,
419
+ placeholder,
420
+ rows = 6,
421
+ mono = true,
422
+ "aria-label": ariaLabel,
423
+ ...rest
424
+ }) {
425
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
426
+ "textarea",
427
+ {
428
+ value,
429
+ onChange,
430
+ placeholder,
431
+ rows,
432
+ "aria-label": ariaLabel,
433
+ ...rest,
434
+ style: {
435
+ width: "100%",
436
+ boxSizing: "border-box",
437
+ resize: "vertical",
438
+ border: "1px solid var(--border-medium)",
439
+ borderRadius: "var(--radius-xl)",
440
+ background: "var(--color-surface)",
441
+ padding: "12px 14px",
442
+ fontFamily: mono ? "var(--font-family-mono)" : "inherit",
443
+ fontSize: mono ? "var(--font-size-md)" : "var(--font-size-lg)",
444
+ lineHeight: 1.55,
445
+ color: "var(--color-text-body)"
446
+ }
447
+ }
448
+ );
449
+ }
450
+
451
+ // src/components/Avatar/Avatar.tsx
452
+ var import_jsx_runtime8 = require("react/jsx-runtime");
453
+ function Avatar({ initial = "M", size = 28, dark = false, style, ...rest }) {
454
+ return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
455
+ "div",
456
+ {
457
+ ...rest,
458
+ style: {
459
+ width: size,
460
+ height: size,
461
+ borderRadius: "50%",
462
+ background: dark ? "var(--color-surface-inverse)" : "var(--color-stone-100)",
463
+ color: dark ? "var(--color-text-on-inverse)" : "var(--color-text-secondary)",
464
+ display: "flex",
465
+ alignItems: "center",
466
+ justifyContent: "center",
467
+ fontSize: size * 0.43,
468
+ fontWeight: 600,
469
+ fontFamily: "var(--font-family-sans)",
470
+ ...style
471
+ },
472
+ children: initial
473
+ }
474
+ );
475
+ }
476
+
477
+ // src/components/ColorSwatch/ColorSwatch.tsx
478
+ var import_react2 = require("react");
479
+ var import_jsx_runtime9 = require("react/jsx-runtime");
480
+ var ColorSwatch = (0, import_react2.forwardRef)(function ColorSwatch2({ color, active = false, onClick, size = 17, title = "Recolor", ...rest }, ref) {
481
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
482
+ "button",
483
+ {
484
+ ref,
485
+ type: "button",
486
+ onClick,
487
+ title,
488
+ "aria-label": title,
489
+ ...rest,
490
+ style: {
491
+ width: size,
492
+ height: size,
493
+ borderRadius: "50%",
494
+ background: color,
495
+ padding: 0,
496
+ border: `2px solid ${active ? "var(--color-ink-900)" : "transparent"}`
497
+ }
498
+ }
499
+ );
500
+ });
501
+
502
+ // src/components/DragHandle/DragHandle.tsx
503
+ var import_jsx_runtime10 = require("react/jsx-runtime");
504
+ function DragHandle({ onDragStart, title = "Drag to reorder", style, ...rest }) {
505
+ return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
506
+ "span",
507
+ {
508
+ draggable: true,
509
+ onDragStart,
510
+ title,
511
+ "aria-hidden": "true",
512
+ ...rest,
513
+ style: {
514
+ cursor: "grab",
515
+ width: 16,
516
+ height: 22,
517
+ display: "flex",
518
+ alignItems: "center",
519
+ justifyContent: "center",
520
+ color: "var(--color-ink-300)",
521
+ fontSize: 19,
522
+ letterSpacing: "-2px",
523
+ lineHeight: 1,
524
+ userSelect: "none",
525
+ ...style
526
+ },
527
+ children: "\u22EE\u22EE"
528
+ }
529
+ );
530
+ }
531
+
532
+ // src/components/NavTabs/NavTabs.tsx
533
+ var import_react3 = require("react");
534
+ var import_jsx_runtime11 = require("react/jsx-runtime");
535
+ var TAB_ORDER = ["notes", "practice", "review"];
536
+ var TAB_LABEL = { notes: "LEARN", practice: "PRACTICE", review: "REVIEW" };
537
+ function Tab({ id, active, badge, onSelect, onKeyDown, buttonRef }) {
538
+ return /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(
539
+ "button",
540
+ {
541
+ ref: buttonRef,
542
+ type: "button",
543
+ role: "tab",
544
+ "aria-selected": active,
545
+ tabIndex: active ? 0 : -1,
546
+ onClick: () => onSelect(id),
547
+ onKeyDown: (e) => onKeyDown(e, id),
548
+ style: {
549
+ display: "flex",
550
+ alignItems: "center",
551
+ gap: 7,
552
+ border: "none",
553
+ fontFamily: "var(--font-family-mono)",
554
+ fontSize: "var(--font-size-sm)",
555
+ letterSpacing: "var(--letter-spacing-mono-label)",
556
+ padding: "7px 18px",
557
+ borderRadius: "var(--radius-pill)",
558
+ background: active ? "var(--color-ink-900)" : "transparent",
559
+ color: active ? "var(--color-cream-50)" : "var(--color-text-muted)",
560
+ transition: "background var(--duration-fast) ease, color var(--duration-fast) ease"
561
+ },
562
+ children: [
563
+ TAB_LABEL[id],
564
+ badge != null && badge > 0 && /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(Badge, { variant: "count", color: "inherit", tint: "rgba(255,255,255,0.22)", children: badge })
565
+ ]
566
+ }
567
+ );
568
+ }
569
+ function NavTabs({ active = "notes", onChange, reviewCount = 0, ...rest }) {
570
+ const buttonRefs = (0, import_react3.useRef)({});
571
+ const select = (id) => onChange?.(id);
572
+ const focusTab = (id) => {
573
+ buttonRefs.current[id]?.focus();
574
+ };
575
+ const handleKeyDown = (event, id) => {
576
+ const currentIndex = TAB_ORDER.indexOf(id);
577
+ let nextIndex = null;
578
+ if (event.key === "ArrowRight") {
579
+ nextIndex = (currentIndex + 1) % TAB_ORDER.length;
580
+ } else if (event.key === "ArrowLeft") {
581
+ nextIndex = (currentIndex - 1 + TAB_ORDER.length) % TAB_ORDER.length;
582
+ } else if (event.key === "Home") {
583
+ nextIndex = 0;
584
+ } else if (event.key === "End") {
585
+ nextIndex = TAB_ORDER.length - 1;
586
+ }
587
+ if (nextIndex !== null) {
588
+ event.preventDefault();
589
+ const nextId = TAB_ORDER[nextIndex];
590
+ select(nextId);
591
+ focusTab(nextId);
592
+ }
593
+ };
594
+ return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { role: "tablist", "aria-label": "Sections", ...rest, style: { display: "flex", alignItems: "center", gap: 6, ...rest.style }, children: TAB_ORDER.map((id) => /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
595
+ Tab,
596
+ {
597
+ id,
598
+ active: active === id,
599
+ badge: id === "review" ? reviewCount : void 0,
600
+ onSelect: select,
601
+ onKeyDown: handleKeyDown,
602
+ buttonRef: (el) => {
603
+ buttonRefs.current[id] = el;
604
+ }
605
+ },
606
+ id
607
+ )) });
608
+ }
609
+
610
+ // src/components/Sidebar/Sidebar.tsx
611
+ var import_react4 = require("react");
612
+ var import_jsx_runtime12 = require("react/jsx-runtime");
613
+ function Sidebar({
614
+ collapsed = false,
615
+ onToggle,
616
+ label,
617
+ width = 222,
618
+ children,
619
+ borderSide = "right",
620
+ style,
621
+ ...rest
622
+ }) {
623
+ const contentId = (0, import_react4.useId)();
624
+ return /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(
625
+ "div",
626
+ {
627
+ ...rest,
628
+ style: {
629
+ display: "flex",
630
+ flexShrink: 0,
631
+ borderRight: borderSide === "right" ? "1px solid var(--border-hairline)" : "none",
632
+ ...style
633
+ },
634
+ children: [
635
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("div", { style: { width: 26, flexShrink: 0, display: "flex", flexDirection: "column", alignItems: "center", paddingTop: 16 }, children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
636
+ IconButton,
637
+ {
638
+ title: collapsed ? "Expand" : "Collapse",
639
+ onClick: onToggle,
640
+ size: 22,
641
+ radius: "var(--radius-sm)",
642
+ "aria-expanded": !collapsed,
643
+ "aria-controls": contentId,
644
+ children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
645
+ "span",
646
+ {
647
+ "aria-hidden": "true",
648
+ style: {
649
+ display: "flex",
650
+ fontSize: 12,
651
+ transform: `rotate(${collapsed ? 180 : 0}deg)`,
652
+ transition: "transform var(--duration-standard) var(--ease-standard)"
653
+ },
654
+ children: "\u2039"
655
+ }
656
+ )
657
+ }
658
+ ) }),
659
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
660
+ "div",
661
+ {
662
+ id: contentId,
663
+ inert: collapsed,
664
+ style: {
665
+ width: collapsed ? 0 : width,
666
+ opacity: collapsed ? 0 : 1,
667
+ overflow: "hidden",
668
+ transition: "width var(--duration-standard) var(--ease-standard), opacity var(--duration-fast) ease"
669
+ },
670
+ children: /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { style: { width, minHeight: "100%", boxSizing: "border-box", padding: "16px 10px 16px 0", display: "flex", flexDirection: "column", gap: 3 }, children: [
671
+ label && /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
672
+ "div",
673
+ {
674
+ style: {
675
+ fontFamily: "var(--font-family-mono)",
676
+ fontSize: "var(--font-size-xs)",
677
+ letterSpacing: "var(--letter-spacing-mono-wider)",
678
+ color: "var(--color-text-muted)",
679
+ padding: "4px 12px 10px"
680
+ },
681
+ children: label
682
+ }
683
+ ),
684
+ children
685
+ ] })
686
+ }
687
+ )
688
+ ]
689
+ }
690
+ );
691
+ }
692
+
693
+ // src/components/TopicRow/TopicRow.tsx
694
+ var import_jsx_runtime13 = require("react/jsx-runtime");
695
+ function TopicRow({
696
+ name,
697
+ color,
698
+ notesLabel,
699
+ selected = false,
700
+ onClick,
701
+ onMenuClick,
702
+ draggable = true,
703
+ onDragStart,
704
+ dense = false,
705
+ style,
706
+ ...rest
707
+ }) {
708
+ return /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(
709
+ "div",
710
+ {
711
+ ...rest,
712
+ style: {
713
+ display: "flex",
714
+ alignItems: "flex-start",
715
+ gap: 8,
716
+ padding: dense ? "12px 8px" : "9px 32px 9px 8px",
717
+ borderRadius: "var(--radius-row)",
718
+ background: selected ? "var(--color-surface-sunken)" : "transparent",
719
+ position: "relative",
720
+ ...style
721
+ },
722
+ children: [
723
+ draggable && !dense && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(DragHandle, { onDragStart }),
724
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(
725
+ "button",
726
+ {
727
+ type: "button",
728
+ onClick,
729
+ style: {
730
+ display: "flex",
731
+ alignItems: "flex-start",
732
+ gap: 8,
733
+ flex: 1,
734
+ minWidth: 0,
735
+ border: "none",
736
+ background: "none",
737
+ padding: 0,
738
+ textAlign: "left",
739
+ font: "inherit",
740
+ cursor: "pointer"
741
+ },
742
+ children: [
743
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { style: { width: 7, height: 7, borderRadius: "50%", flexShrink: 0, background: color, marginTop: 6 } }),
744
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("span", { style: { display: "flex", flexDirection: "column", gap: 5, flex: 1, minWidth: 0 }, children: [
745
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
746
+ "span",
747
+ {
748
+ style: {
749
+ fontSize: "var(--font-size-base)",
750
+ fontWeight: selected ? 600 : 500,
751
+ color: selected ? "var(--color-text-primary)" : "var(--color-text-secondary)"
752
+ },
753
+ children: name
754
+ }
755
+ ),
756
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
757
+ "span",
758
+ {
759
+ style: {
760
+ fontFamily: "var(--font-family-mono)",
761
+ fontSize: "var(--font-size-2xs)",
762
+ color: "var(--color-text-faint)",
763
+ paddingLeft: dense ? 0 : 15
764
+ },
765
+ children: notesLabel
766
+ }
767
+ )
768
+ ] })
769
+ ]
770
+ }
771
+ ),
772
+ onMenuClick && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { style: { position: "absolute", top: 8, right: 6 }, children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
773
+ IconButton,
774
+ {
775
+ title: "Topic options",
776
+ onClick: (e) => {
777
+ e.stopPropagation();
778
+ onMenuClick(e);
779
+ },
780
+ size: 22,
781
+ radius: "var(--radius-sm)",
782
+ children: "\u22EF"
783
+ }
784
+ ) })
785
+ ]
786
+ }
787
+ );
788
+ }
789
+
790
+ // src/components/NoteRow/NoteRow.tsx
791
+ var import_jsx_runtime14 = require("react/jsx-runtime");
792
+ function NoteRow({
793
+ title,
794
+ meta,
795
+ selected = false,
796
+ showTopic = false,
797
+ topicColor,
798
+ topicName,
799
+ tags = [],
800
+ onClick,
801
+ onMenuClick,
802
+ draggable = true,
803
+ onDragStart,
804
+ style,
805
+ ...rest
806
+ }) {
807
+ return /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(
808
+ "div",
809
+ {
810
+ ...rest,
811
+ style: {
812
+ display: "flex",
813
+ alignItems: "flex-start",
814
+ gap: 8,
815
+ padding: "9px 32px 9px 8px",
816
+ borderRadius: "var(--radius-row)",
817
+ background: selected ? "var(--color-surface-sunken)" : "transparent",
818
+ position: "relative",
819
+ ...style
820
+ },
821
+ children: [
822
+ draggable && /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(DragHandle, { onDragStart, style: { marginTop: 1 } }),
823
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(
824
+ "button",
825
+ {
826
+ type: "button",
827
+ onClick,
828
+ style: {
829
+ display: "flex",
830
+ flexDirection: "column",
831
+ gap: 4,
832
+ flex: 1,
833
+ minWidth: 0,
834
+ border: "none",
835
+ background: "none",
836
+ padding: 0,
837
+ textAlign: "left",
838
+ font: "inherit",
839
+ cursor: "pointer"
840
+ },
841
+ children: [
842
+ showTopic && /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("span", { style: { display: "flex", alignItems: "center", gap: 6 }, children: [
843
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("span", { style: { width: 6, height: 6, borderRadius: "50%", background: topicColor } }),
844
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
845
+ "span",
846
+ {
847
+ style: {
848
+ fontFamily: "var(--font-family-mono)",
849
+ fontSize: "9px",
850
+ letterSpacing: "0.08em",
851
+ color: "var(--color-text-faint)",
852
+ textTransform: "uppercase"
853
+ },
854
+ children: topicName
855
+ }
856
+ )
857
+ ] }),
858
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
859
+ "span",
860
+ {
861
+ style: {
862
+ fontSize: "var(--font-size-base)",
863
+ lineHeight: 1.4,
864
+ fontWeight: selected ? 600 : 500,
865
+ color: selected ? "var(--color-text-primary)" : "var(--color-text-secondary)"
866
+ },
867
+ children: title
868
+ }
869
+ ),
870
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("span", { style: { fontFamily: "var(--font-family-mono)", fontSize: "var(--font-size-2xs)", color: "var(--color-text-faint)" }, children: meta }),
871
+ tags.length > 0 && !selected && /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("span", { style: { display: "flex", flexWrap: "wrap", gap: 4, marginTop: 1 }, children: tags.map((t, i) => /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(
872
+ "span",
873
+ {
874
+ style: {
875
+ fontFamily: "var(--font-family-mono)",
876
+ fontSize: "9px",
877
+ color: t.color,
878
+ background: `color-mix(in srgb, ${t.color} 14%, transparent)`,
879
+ padding: "1px 7px",
880
+ borderRadius: "var(--radius-pill)"
881
+ },
882
+ children: [
883
+ "#",
884
+ t.label
885
+ ]
886
+ },
887
+ `${t.label}-${i}`
888
+ )) })
889
+ ]
890
+ }
891
+ ),
892
+ onMenuClick && /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("div", { style: { position: "absolute", top: 7, right: 4 }, children: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
893
+ IconButton,
894
+ {
895
+ title: "Concept options",
896
+ onClick: (e) => {
897
+ e.stopPropagation();
898
+ onMenuClick(e);
899
+ },
900
+ size: 22,
901
+ radius: "var(--radius-sm)",
902
+ children: "\u22EF"
903
+ }
904
+ ) })
905
+ ]
906
+ }
907
+ );
908
+ }
909
+
910
+ // src/components/ContextMenu/ContextMenu.tsx
911
+ var import_react5 = require("react");
912
+ var import_jsx_runtime15 = require("react/jsx-runtime");
913
+ function ContextMenu({
914
+ items = [],
915
+ swatches,
916
+ width = 176,
917
+ style,
918
+ onClose,
919
+ "aria-label": ariaLabel,
920
+ ...rest
921
+ }) {
922
+ const nonDividerCount = items.filter((it) => !it.divider).length;
923
+ const itemFocusIndex = items.map((it, i) => it.divider ? -1 : items.slice(0, i).filter((x) => !x.divider).length);
924
+ const swatchFocusIndex = (swatches ?? []).map((_, i) => nonDividerCount + i);
925
+ const focusableCount = nonDividerCount + (swatches?.length ?? 0);
926
+ const controlRefs = (0, import_react5.useRef)([]);
927
+ const [activeIndex, setActiveIndex] = (0, import_react5.useState)(0);
928
+ (0, import_react5.useEffect)(() => {
929
+ controlRefs.current[0]?.focus();
930
+ }, []);
931
+ const focusIndex = (index) => {
932
+ const clamped = (index + focusableCount) % focusableCount;
933
+ controlRefs.current[clamped]?.focus();
934
+ };
935
+ const handleKeyDown = (event) => {
936
+ if (event.key === "Escape") {
937
+ onClose?.();
938
+ return;
939
+ }
940
+ if (focusableCount === 0) return;
941
+ if (event.key === "ArrowDown") {
942
+ event.preventDefault();
943
+ focusIndex(activeIndex + 1);
944
+ } else if (event.key === "ArrowUp") {
945
+ event.preventDefault();
946
+ focusIndex(activeIndex - 1);
947
+ } else if (event.key === "Home") {
948
+ event.preventDefault();
949
+ focusIndex(0);
950
+ } else if (event.key === "End") {
951
+ event.preventDefault();
952
+ focusIndex(focusableCount - 1);
953
+ }
954
+ };
955
+ return /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(
956
+ "div",
957
+ {
958
+ role: "menu",
959
+ tabIndex: -1,
960
+ "aria-label": ariaLabel,
961
+ onClick: (e) => e.stopPropagation(),
962
+ onKeyDown: handleKeyDown,
963
+ ...rest,
964
+ style: {
965
+ width,
966
+ background: "var(--color-surface)",
967
+ border: "1px solid var(--border-medium)",
968
+ borderRadius: "var(--radius-xl)",
969
+ boxShadow: "var(--shadow-md)",
970
+ padding: 6,
971
+ display: "flex",
972
+ flexDirection: "column",
973
+ gap: 1,
974
+ ...style
975
+ },
976
+ children: [
977
+ items.map((it, i) => {
978
+ if (it.divider) {
979
+ return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("div", { role: "separator", "aria-orientation": "horizontal", style: { height: 1, background: "var(--border-subtle)", margin: "2px 4px" } }, i);
980
+ }
981
+ const index = itemFocusIndex[i];
982
+ return /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(
983
+ "button",
984
+ {
985
+ role: "menuitem",
986
+ ref: (el) => {
987
+ controlRefs.current[index] = el;
988
+ },
989
+ tabIndex: activeIndex === index ? 0 : -1,
990
+ onFocus: () => setActiveIndex(index),
991
+ onClick: it.onClick,
992
+ style: {
993
+ textAlign: "left",
994
+ border: "none",
995
+ background: "none",
996
+ borderRadius: "var(--radius-sm)",
997
+ padding: "7px 9px",
998
+ fontFamily: "inherit",
999
+ fontSize: "var(--font-size-base)",
1000
+ color: it.danger ? "var(--color-danger)" : "var(--color-text-secondary)"
1001
+ },
1002
+ children: [
1003
+ it.icon && /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("span", { "aria-hidden": "true", style: { marginRight: 7 }, children: it.icon }),
1004
+ it.label
1005
+ ]
1006
+ },
1007
+ i
1008
+ );
1009
+ }),
1010
+ swatches && /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("div", { role: "group", "aria-label": "Color", style: { display: "flex", gap: 5, padding: "7px 9px 4px" }, children: swatches.map((sw, i) => {
1011
+ const index = swatchFocusIndex[i];
1012
+ return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
1013
+ ColorSwatch,
1014
+ {
1015
+ ref: (el) => {
1016
+ controlRefs.current[index] = el;
1017
+ },
1018
+ tabIndex: activeIndex === index ? 0 : -1,
1019
+ onFocus: () => setActiveIndex(index),
1020
+ color: sw.color,
1021
+ active: sw.active,
1022
+ onClick: sw.pick,
1023
+ role: "menuitemradio",
1024
+ "aria-checked": !!sw.active
1025
+ },
1026
+ i
1027
+ );
1028
+ }) })
1029
+ ]
1030
+ }
1031
+ );
1032
+ }
1033
+
1034
+ // src/internal/useDialog.ts
1035
+ var import_react6 = require("react");
1036
+ var FOCUSABLE_SELECTOR = [
1037
+ "a[href]",
1038
+ "button:not([disabled])",
1039
+ "input:not([disabled])",
1040
+ "select:not([disabled])",
1041
+ "textarea:not([disabled])",
1042
+ '[tabindex]:not([tabindex="-1"])'
1043
+ ].join(",");
1044
+ function useDialog({ open, onClose }) {
1045
+ const containerRef = (0, import_react6.useRef)(null);
1046
+ const previouslyFocusedRef = (0, import_react6.useRef)(null);
1047
+ (0, import_react6.useEffect)(() => {
1048
+ if (!open) return;
1049
+ previouslyFocusedRef.current = document.activeElement;
1050
+ const container = containerRef.current;
1051
+ const focusables = container?.querySelectorAll(FOCUSABLE_SELECTOR);
1052
+ (focusables?.[0] ?? container)?.focus();
1053
+ return () => {
1054
+ previouslyFocusedRef.current?.focus?.();
1055
+ };
1056
+ }, [open]);
1057
+ (0, import_react6.useEffect)(() => {
1058
+ if (!open) return;
1059
+ const handleKeyDown = (event) => {
1060
+ if (event.key === "Escape") {
1061
+ if (containerRef.current?.contains(document.activeElement)) {
1062
+ onClose?.();
1063
+ }
1064
+ return;
1065
+ }
1066
+ if (event.key !== "Tab") return;
1067
+ const container = containerRef.current;
1068
+ if (!container) return;
1069
+ const focusables = Array.from(container.querySelectorAll(FOCUSABLE_SELECTOR));
1070
+ if (focusables.length === 0) {
1071
+ event.preventDefault();
1072
+ return;
1073
+ }
1074
+ const first = focusables[0];
1075
+ const last = focusables[focusables.length - 1];
1076
+ if (event.shiftKey && document.activeElement === first) {
1077
+ event.preventDefault();
1078
+ last.focus();
1079
+ } else if (!event.shiftKey && document.activeElement === last) {
1080
+ event.preventDefault();
1081
+ first.focus();
1082
+ }
1083
+ };
1084
+ document.addEventListener("keydown", handleKeyDown);
1085
+ return () => document.removeEventListener("keydown", handleKeyDown);
1086
+ }, [open, onClose]);
1087
+ return containerRef;
1088
+ }
1089
+
1090
+ // src/components/BottomSheet/BottomSheet.tsx
1091
+ var import_jsx_runtime16 = require("react/jsx-runtime");
1092
+ function BottomSheet({
1093
+ open,
1094
+ onClose,
1095
+ children,
1096
+ maxHeight = "70%",
1097
+ style,
1098
+ "aria-label": ariaLabel,
1099
+ ...rest
1100
+ }) {
1101
+ const dialogRef = useDialog({ open, onClose });
1102
+ if (!open) return null;
1103
+ return (
1104
+ // Escape (handled by useDialog) is the keyboard-equivalent way to
1105
+ // dismiss the sheet; clicking the backdrop is a mouse-only convenience,
1106
+ // not the only way to close it.
1107
+ // eslint-disable-next-line jsx-a11y/no-static-element-interactions, jsx-a11y/click-events-have-key-events
1108
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
1109
+ "div",
1110
+ {
1111
+ onClick: onClose,
1112
+ style: { position: "absolute", inset: 0, zIndex: 60, background: "rgba(24,23,20,0.4)", display: "flex", alignItems: "flex-end" },
1113
+ children: /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(
1114
+ "div",
1115
+ {
1116
+ ref: dialogRef,
1117
+ role: "dialog",
1118
+ "aria-modal": "true",
1119
+ "aria-label": ariaLabel,
1120
+ tabIndex: -1,
1121
+ onClick: (e) => e.stopPropagation(),
1122
+ ...rest,
1123
+ style: {
1124
+ width: "100%",
1125
+ boxSizing: "border-box",
1126
+ background: "var(--color-background)",
1127
+ borderRadius: "var(--radius-surface) var(--radius-surface) 0 0",
1128
+ padding: "18px 18px 26px",
1129
+ display: "flex",
1130
+ flexDirection: "column",
1131
+ gap: 12,
1132
+ maxHeight,
1133
+ overflowY: "auto",
1134
+ boxShadow: "var(--shadow-sheet)",
1135
+ ...style
1136
+ },
1137
+ children: [
1138
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("div", { "aria-hidden": "true", style: { width: 36, height: 4, borderRadius: 2, background: "rgba(17,17,17,0.15)", margin: "0 auto 4px" } }),
1139
+ children
1140
+ ]
1141
+ }
1142
+ )
1143
+ }
1144
+ )
1145
+ );
1146
+ }
1147
+
1148
+ // src/components/ImportExportModal/ImportExportModal.tsx
1149
+ var import_react7 = require("react");
1150
+ var import_jsx_runtime17 = require("react/jsx-runtime");
1151
+ var TAB_ORDER2 = ["import", "export"];
1152
+ var TAB_LABEL2 = { import: "IMPORT", export: "EXPORT" };
1153
+ function ImportExportModal({ open, tab = "import", onTabChange, onClose, children, ...rest }) {
1154
+ const dialogRef = useDialog({ open, onClose });
1155
+ const tabRefs = (0, import_react7.useRef)({});
1156
+ (0, import_react7.useEffect)(() => {
1157
+ if (!open) return;
1158
+ const original = document.body.style.overflow;
1159
+ document.body.style.overflow = "hidden";
1160
+ return () => {
1161
+ document.body.style.overflow = original;
1162
+ };
1163
+ }, [open]);
1164
+ if (!open) return null;
1165
+ const selectTab = (id) => onTabChange?.(id);
1166
+ const handleTabKeyDown = (event, id) => {
1167
+ const currentIndex = TAB_ORDER2.indexOf(id);
1168
+ let nextIndex = null;
1169
+ if (event.key === "ArrowRight") nextIndex = (currentIndex + 1) % TAB_ORDER2.length;
1170
+ else if (event.key === "ArrowLeft") nextIndex = (currentIndex - 1 + TAB_ORDER2.length) % TAB_ORDER2.length;
1171
+ else if (event.key === "Home") nextIndex = 0;
1172
+ else if (event.key === "End") nextIndex = TAB_ORDER2.length - 1;
1173
+ if (nextIndex !== null) {
1174
+ event.preventDefault();
1175
+ const nextId = TAB_ORDER2[nextIndex];
1176
+ selectTab(nextId);
1177
+ tabRefs.current[nextId]?.focus();
1178
+ }
1179
+ };
1180
+ return (
1181
+ // Escape (handled by useDialog) is the keyboard-equivalent way to
1182
+ // dismiss the modal; clicking the backdrop is a mouse-only convenience,
1183
+ // not the only way to close it.
1184
+ // eslint-disable-next-line jsx-a11y/no-static-element-interactions, jsx-a11y/click-events-have-key-events
1185
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
1186
+ "div",
1187
+ {
1188
+ onClick: onClose,
1189
+ style: { position: "fixed", inset: 0, zIndex: 100, background: "rgba(24,23,20,0.42)", display: "flex", alignItems: "center", justifyContent: "center", padding: 24 },
1190
+ children: /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(
1191
+ "div",
1192
+ {
1193
+ ref: dialogRef,
1194
+ role: "dialog",
1195
+ "aria-modal": "true",
1196
+ "aria-label": "Import or export notes",
1197
+ tabIndex: -1,
1198
+ onClick: (e) => e.stopPropagation(),
1199
+ ...rest,
1200
+ style: {
1201
+ width: 640,
1202
+ maxWidth: "100%",
1203
+ maxHeight: "86vh",
1204
+ background: "var(--color-background)",
1205
+ borderRadius: "var(--radius-surface)",
1206
+ boxShadow: "var(--shadow-lg)",
1207
+ padding: "20px 24px 22px",
1208
+ boxSizing: "border-box",
1209
+ display: "flex",
1210
+ flexDirection: "column",
1211
+ gap: 14,
1212
+ overflowY: "auto"
1213
+ },
1214
+ children: [
1215
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("div", { style: { display: "flex", alignItems: "center", justifyContent: "space-between" }, children: [
1216
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
1217
+ "div",
1218
+ {
1219
+ role: "tablist",
1220
+ "aria-label": "Import or export",
1221
+ style: { display: "flex", alignItems: "center", gap: 4, background: "var(--color-stone-100)", borderRadius: "var(--radius-pill)", padding: 3 },
1222
+ children: TAB_ORDER2.map((id) => /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
1223
+ "button",
1224
+ {
1225
+ ref: (el) => {
1226
+ tabRefs.current[id] = el;
1227
+ },
1228
+ type: "button",
1229
+ role: "tab",
1230
+ "aria-selected": tab === id,
1231
+ tabIndex: tab === id ? 0 : -1,
1232
+ onClick: () => selectTab(id),
1233
+ onKeyDown: (e) => handleTabKeyDown(e, id),
1234
+ style: {
1235
+ border: "none",
1236
+ borderRadius: 17,
1237
+ padding: "6px 16px",
1238
+ fontFamily: "var(--font-family-mono)",
1239
+ fontSize: "var(--font-size-sm)",
1240
+ letterSpacing: "0.1em",
1241
+ background: tab === id ? "var(--color-ink-900)" : "transparent",
1242
+ color: tab === id ? "var(--color-cream-50)" : "var(--color-text-muted)"
1243
+ },
1244
+ children: TAB_LABEL2[id]
1245
+ },
1246
+ id
1247
+ ))
1248
+ }
1249
+ ),
1250
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(IconButton, { title: "Close", onClick: onClose, children: "\xD7" })
1251
+ ] }),
1252
+ children
1253
+ ]
1254
+ }
1255
+ )
1256
+ }
1257
+ )
1258
+ );
1259
+ }
1260
+ function ExportRow({ title, sub, onCopy, copyLabel = "COPY", onDownload }) {
1261
+ return /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("div", { style: { display: "flex", alignItems: "center", gap: 12, background: "var(--color-surface)", border: "1px solid var(--border-default)", borderRadius: "var(--radius-xl)", padding: "12px 16px" }, children: [
1262
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("div", { style: { flex: 1, minWidth: 0, display: "flex", flexDirection: "column", gap: 2 }, children: [
1263
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("span", { style: { fontSize: "var(--font-size-base)", fontWeight: 600, color: "var(--color-text-primary)" }, children: title }),
1264
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)("span", { style: { fontFamily: "var(--font-family-mono)", fontSize: "var(--font-size-sm)", color: "var(--color-text-faint)", whiteSpace: "nowrap", overflow: "hidden", textOverflow: "ellipsis" }, children: sub })
1265
+ ] }),
1266
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
1267
+ "button",
1268
+ {
1269
+ type: "button",
1270
+ onClick: onCopy,
1271
+ style: { border: "1px solid var(--border-medium)", background: "var(--color-surface)", color: "var(--color-text-secondary)", fontFamily: "var(--font-family-mono)", fontSize: "var(--font-size-xs)", letterSpacing: "0.08em", padding: "7px 14px", borderRadius: "var(--radius-md)" },
1272
+ children: copyLabel
1273
+ }
1274
+ ),
1275
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
1276
+ "button",
1277
+ {
1278
+ type: "button",
1279
+ onClick: onDownload,
1280
+ style: { border: "none", background: "var(--color-ink-900)", color: "var(--color-cream-50)", fontFamily: "var(--font-family-mono)", fontSize: "var(--font-size-xs)", letterSpacing: "0.08em", padding: "8px 14px", borderRadius: "var(--radius-md)" },
1281
+ children: "DOWNLOAD"
1282
+ }
1283
+ )
1284
+ ] });
1285
+ }
1286
+
1287
+ // src/components/TocRail/TocRail.tsx
1288
+ var import_jsx_runtime18 = require("react/jsx-runtime");
1289
+ function TocRail({
1290
+ items,
1291
+ hovered,
1292
+ onHoverIn,
1293
+ onHoverOut,
1294
+ "aria-label": ariaLabel = "Page outline",
1295
+ style,
1296
+ ...rest
1297
+ }) {
1298
+ return /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
1299
+ "nav",
1300
+ {
1301
+ "aria-label": ariaLabel,
1302
+ onMouseEnter: onHoverIn,
1303
+ onMouseLeave: onHoverOut,
1304
+ onFocus: onHoverIn,
1305
+ onBlur: (e) => {
1306
+ if (!e.currentTarget.contains(e.relatedTarget)) onHoverOut?.();
1307
+ },
1308
+ ...rest,
1309
+ style: { padding: "6px 4px", ...style },
1310
+ children: /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("ol", { role: "list", style: { listStyle: "none", margin: 0, padding: 0, display: "flex", flexDirection: "column", gap: 10 }, children: items.map((t, i) => /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("li", { children: /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(
1311
+ "button",
1312
+ {
1313
+ onClick: t.go,
1314
+ "aria-current": t.active ? "true" : void 0,
1315
+ style: {
1316
+ display: "flex",
1317
+ alignItems: "center",
1318
+ gap: 8,
1319
+ border: "none",
1320
+ background: "none",
1321
+ padding: "2px 4px",
1322
+ fontFamily: "var(--font-family-mono)",
1323
+ fontSize: "var(--font-size-sm)",
1324
+ textAlign: "left"
1325
+ },
1326
+ children: [
1327
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
1328
+ "span",
1329
+ {
1330
+ "aria-hidden": "true",
1331
+ style: {
1332
+ width: 7,
1333
+ height: 7,
1334
+ borderRadius: "50%",
1335
+ flexShrink: 0,
1336
+ background: t.active ? "var(--color-accent)" : "rgba(17,17,17,0.22)",
1337
+ transform: t.active ? "scale(1.4)" : "scale(1)"
1338
+ }
1339
+ }
1340
+ ),
1341
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
1342
+ "span",
1343
+ {
1344
+ style: {
1345
+ width: hovered ? 82 : 0,
1346
+ overflow: "hidden",
1347
+ whiteSpace: "nowrap",
1348
+ color: t.active ? "var(--color-accent)" : "var(--color-text-muted)",
1349
+ fontWeight: t.active ? 600 : 500,
1350
+ transition: "width var(--duration-standard) var(--ease-standard)"
1351
+ },
1352
+ children: t.label
1353
+ }
1354
+ )
1355
+ ]
1356
+ }
1357
+ ) }, i)) })
1358
+ }
1359
+ );
1360
+ }
1361
+
1362
+ // src/components/TocFab/TocFab.tsx
1363
+ var import_jsx_runtime19 = require("react/jsx-runtime");
1364
+ function TocFab({ onClick, "aria-label": ariaLabel = "Open outline", style, ...rest }) {
1365
+ return /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
1366
+ "button",
1367
+ {
1368
+ type: "button",
1369
+ onClick,
1370
+ "aria-label": ariaLabel,
1371
+ ...rest,
1372
+ style: {
1373
+ position: "absolute",
1374
+ right: 16,
1375
+ bottom: 16,
1376
+ width: 46,
1377
+ height: 46,
1378
+ borderRadius: "50%",
1379
+ border: "none",
1380
+ background: "var(--color-surface-inverse)",
1381
+ color: "var(--color-text-on-inverse)",
1382
+ fontSize: 17,
1383
+ boxShadow: "var(--shadow-fab)",
1384
+ display: "flex",
1385
+ alignItems: "center",
1386
+ justifyContent: "center",
1387
+ zIndex: 20,
1388
+ ...style
1389
+ },
1390
+ children: /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("span", { "aria-hidden": "true", children: "\u2630" })
1391
+ }
1392
+ );
1393
+ }
1394
+
1395
+ // src/components/TocSheetList/TocSheetList.tsx
1396
+ var import_react8 = require("react");
1397
+ var import_jsx_runtime20 = require("react/jsx-runtime");
1398
+ function TocSheetList({ items }) {
1399
+ const headingId = (0, import_react8.useId)();
1400
+ return /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("nav", { "aria-labelledby": headingId, children: [
1401
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
1402
+ "div",
1403
+ {
1404
+ id: headingId,
1405
+ style: {
1406
+ fontFamily: "var(--font-family-mono)",
1407
+ fontSize: "var(--font-size-xs)",
1408
+ letterSpacing: "var(--letter-spacing-mono-wide)",
1409
+ color: "var(--color-text-muted)",
1410
+ marginBottom: 6
1411
+ },
1412
+ children: "OUTLINE"
1413
+ }
1414
+ ),
1415
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("ol", { role: "list", style: { listStyle: "none", margin: 0, padding: 0 }, children: items.map((t, i) => /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("li", { children: /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(
1416
+ "button",
1417
+ {
1418
+ onClick: t.go,
1419
+ "aria-current": t.active ? "true" : void 0,
1420
+ style: {
1421
+ display: "flex",
1422
+ alignItems: "center",
1423
+ gap: 10,
1424
+ border: "none",
1425
+ background: "none",
1426
+ padding: "10px 4px",
1427
+ fontFamily: "var(--font-family-mono)",
1428
+ fontSize: "var(--font-size-base)",
1429
+ textAlign: "left",
1430
+ width: "100%",
1431
+ boxSizing: "border-box"
1432
+ },
1433
+ children: [
1434
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
1435
+ "span",
1436
+ {
1437
+ "aria-hidden": "true",
1438
+ style: { width: 7, height: 7, borderRadius: "50%", flexShrink: 0, background: t.active ? "var(--color-accent)" : "rgba(17,17,17,0.22)" }
1439
+ }
1440
+ ),
1441
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { style: { color: t.active ? "var(--color-accent)" : "var(--color-text-muted)", fontWeight: t.active ? 600 : 500 }, children: t.label })
1442
+ ]
1443
+ }
1444
+ ) }, i)) })
1445
+ ] });
1446
+ }
1447
+
1448
+ // src/components/CardShell/CardShell.tsx
1449
+ var import_jsx_runtime21 = require("react/jsx-runtime");
1450
+ function CardShell({ children, dark = false, tint = false, style, ...rest }) {
1451
+ return /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
1452
+ "div",
1453
+ {
1454
+ ...rest,
1455
+ style: {
1456
+ background: dark ? "var(--color-surface-code)" : tint ? "var(--color-accent-tint)" : "var(--color-surface)",
1457
+ border: dark ? "none" : `1px solid ${tint ? "color-mix(in srgb, var(--color-accent) 22%, transparent)" : "var(--border-default)"}`,
1458
+ borderRadius: "var(--radius-card)",
1459
+ margin: "24px 0",
1460
+ ...style
1461
+ },
1462
+ children
1463
+ }
1464
+ );
1465
+ }
1466
+
1467
+ // src/components/CardHeader/CardHeader.tsx
1468
+ var import_jsx_runtime22 = require("react/jsx-runtime");
1469
+ function CardHeader({
1470
+ eyebrow,
1471
+ eyebrowColor = "var(--color-accent)",
1472
+ title,
1473
+ as: TitleTag = "span",
1474
+ subtitle,
1475
+ right,
1476
+ dark = false,
1477
+ style,
1478
+ ...rest
1479
+ }) {
1480
+ return /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { ...rest, style: { display: "flex", alignItems: "baseline", gap: 10, padding: "13px 16px 9px", minWidth: 0, ...style }, children: [
1481
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
1482
+ "span",
1483
+ {
1484
+ style: {
1485
+ fontFamily: "var(--font-family-mono)",
1486
+ fontSize: "var(--font-size-xs)",
1487
+ letterSpacing: "var(--letter-spacing-mono-wide)",
1488
+ color: eyebrowColor,
1489
+ whiteSpace: "nowrap",
1490
+ flexShrink: 0
1491
+ },
1492
+ children: eyebrow
1493
+ }
1494
+ ),
1495
+ title && /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
1496
+ TitleTag,
1497
+ {
1498
+ style: {
1499
+ margin: 0,
1500
+ fontSize: "var(--font-size-base)",
1501
+ fontWeight: 600,
1502
+ color: dark ? "#EDEBE3" : "var(--color-text-primary)",
1503
+ whiteSpace: "nowrap",
1504
+ overflow: "hidden",
1505
+ textOverflow: "ellipsis",
1506
+ minWidth: 0
1507
+ },
1508
+ children: title
1509
+ }
1510
+ ),
1511
+ subtitle && /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("span", { style: { fontSize: "var(--font-size-md)", color: dark ? "var(--color-ink-500)" : "var(--color-text-faint)", whiteSpace: "nowrap", flexShrink: 0 }, children: subtitle }),
1512
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("span", { style: { flex: 1, minWidth: 4 } }),
1513
+ right
1514
+ ] });
1515
+ }
1516
+
1517
+ // src/components/TextBlock/TextBlock.tsx
1518
+ var import_jsx_runtime23 = require("react/jsx-runtime");
1519
+ function TextBlock({ text, style, ...rest }) {
1520
+ return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("p", { ...rest, style: { margin: "18px 0", color: "var(--color-text-body)", textWrap: "pretty", ...style }, children: text });
1521
+ }
1522
+
1523
+ // src/components/EquationBlock/EquationBlock.tsx
1524
+ var import_jsx_runtime24 = require("react/jsx-runtime");
1525
+ function EquationBlock({ tex, style, ...rest }) {
1526
+ return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("div", { ...rest, style: { margin: "18px 0", textAlign: "center", padding: "10px 0", ...style }, children: /* @__PURE__ */ (0, import_jsx_runtime24.jsx)("span", { style: { fontFamily: "Georgia, serif", fontStyle: "italic", fontSize: "17px", color: "var(--color-text-primary)" }, children: tex }) });
1527
+ }
1528
+
1529
+ // src/components/IntuitionCallout/IntuitionCallout.tsx
1530
+ var import_jsx_runtime25 = require("react/jsx-runtime");
1531
+ function IntuitionCallout({ text, label = "INTUITION", style, ...rest }) {
1532
+ return /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(
1533
+ "div",
1534
+ {
1535
+ ...rest,
1536
+ style: {
1537
+ margin: "18px 0",
1538
+ padding: "13px 16px",
1539
+ borderRadius: "var(--radius-lg)",
1540
+ background: "var(--color-warning-tint)",
1541
+ border: "1px solid var(--color-warning-border)",
1542
+ fontSize: "var(--font-size-lg)",
1543
+ color: "var(--color-text-secondary)",
1544
+ ...style
1545
+ },
1546
+ children: [
1547
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("span", { style: { display: "block", fontFamily: "var(--font-family-mono)", fontSize: "var(--font-size-xs)", letterSpacing: "0.12em", color: "var(--color-warning)", marginBottom: 6 }, children: label }),
1548
+ text
1549
+ ]
1550
+ }
1551
+ );
1552
+ }
1553
+
1554
+ // src/components/WalkthroughCard/WalkthroughCard.tsx
1555
+ var import_jsx_runtime26 = require("react/jsx-runtime");
1556
+ function WalkthroughCard({ title, steps, currentStep, onPrev, onNext, style, ...rest }) {
1557
+ const visible = steps.slice(0, currentStep + 1);
1558
+ const atStart = currentStep === 0;
1559
+ const atEnd = currentStep === steps.length - 1;
1560
+ return /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)(
1561
+ "div",
1562
+ {
1563
+ ...rest,
1564
+ style: {
1565
+ background: "var(--color-surface)",
1566
+ border: "1px solid var(--border-default)",
1567
+ borderRadius: "var(--radius-card)",
1568
+ margin: "24px 0",
1569
+ padding: "16px 20px 14px",
1570
+ ...style
1571
+ },
1572
+ children: [
1573
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("div", { style: { display: "flex", alignItems: "baseline", justifyContent: "space-between", marginBottom: 12 }, children: [
1574
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("div", { style: { display: "flex", alignItems: "baseline", gap: 10 }, children: [
1575
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("span", { style: { fontFamily: "var(--font-family-mono)", fontSize: "var(--font-size-xs)", letterSpacing: "var(--letter-spacing-mono-wide)", color: "var(--color-accent)" }, children: "WALKTHROUGH" }),
1576
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("span", { style: { fontSize: "var(--font-size-base)", fontWeight: 600, color: "var(--color-text-primary)", whiteSpace: "nowrap", overflow: "hidden", textOverflow: "ellipsis", minWidth: 0 }, children: title })
1577
+ ] }),
1578
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("span", { style: { fontFamily: "var(--font-family-mono)", fontSize: "var(--font-size-sm)", color: "var(--color-text-faint)", whiteSpace: "nowrap" }, children: [
1579
+ "STEP ",
1580
+ currentStep + 1,
1581
+ " OF ",
1582
+ steps.length
1583
+ ] })
1584
+ ] }),
1585
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("div", { "aria-live": "polite", children: visible.map((s, i) => /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)(
1586
+ "div",
1587
+ {
1588
+ style: {
1589
+ display: "grid",
1590
+ gridTemplateColumns: "26px 1fr",
1591
+ gap: 12,
1592
+ padding: "9px 0",
1593
+ borderTop: "1px solid var(--border-subtle)",
1594
+ opacity: i === currentStep ? 1 : 0.65
1595
+ },
1596
+ children: [
1597
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
1598
+ "span",
1599
+ {
1600
+ style: {
1601
+ width: 24,
1602
+ height: 24,
1603
+ borderRadius: "50%",
1604
+ display: "flex",
1605
+ alignItems: "center",
1606
+ justifyContent: "center",
1607
+ fontFamily: "var(--font-family-mono)",
1608
+ fontSize: "var(--font-size-sm)",
1609
+ marginTop: 4,
1610
+ background: i === currentStep ? "var(--color-accent)" : "var(--color-stone-100)",
1611
+ color: i === currentStep ? "#fff" : "var(--color-text-faint)"
1612
+ },
1613
+ children: i + 1
1614
+ }
1615
+ ),
1616
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("div", { style: { minWidth: 0 }, children: [
1617
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("div", { style: { fontFamily: "Georgia, serif", fontStyle: "italic", textAlign: "center", fontSize: 15, color: "var(--color-text-primary)" }, children: s.tex }),
1618
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("div", { style: { fontSize: "var(--font-size-base)", color: "var(--color-text-muted)", textAlign: "center" }, children: s.note })
1619
+ ] })
1620
+ ]
1621
+ },
1622
+ i
1623
+ )) }),
1624
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("div", { style: { display: "flex", alignItems: "center", gap: 8, marginTop: 12 }, children: [
1625
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
1626
+ "button",
1627
+ {
1628
+ type: "button",
1629
+ onClick: onPrev,
1630
+ disabled: atStart,
1631
+ style: {
1632
+ border: "1px solid var(--border-strong)",
1633
+ background: "#fff",
1634
+ borderRadius: "var(--radius-sm)",
1635
+ padding: "5px 14px",
1636
+ fontFamily: "var(--font-family-mono)",
1637
+ fontSize: "var(--font-size-sm)",
1638
+ color: "var(--color-text-secondary)",
1639
+ opacity: atStart ? 0.4 : 1
1640
+ },
1641
+ children: "\u2039 Back"
1642
+ }
1643
+ ),
1644
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
1645
+ "button",
1646
+ {
1647
+ type: "button",
1648
+ onClick: onNext,
1649
+ disabled: atEnd,
1650
+ style: {
1651
+ border: "none",
1652
+ background: "var(--color-accent)",
1653
+ borderRadius: "var(--radius-sm)",
1654
+ padding: "6px 16px",
1655
+ fontFamily: "var(--font-family-mono)",
1656
+ fontSize: "var(--font-size-sm)",
1657
+ color: "#fff",
1658
+ opacity: atEnd ? 0.4 : 1
1659
+ },
1660
+ children: atEnd ? "Done \u2713" : "Next step \u203A"
1661
+ }
1662
+ )
1663
+ ] })
1664
+ ]
1665
+ }
1666
+ );
1667
+ }
1668
+
1669
+ // src/components/CodeCard/CodeCard.tsx
1670
+ var import_jsx_runtime27 = require("react/jsx-runtime");
1671
+ function CodeCard({ title, lang, code, copyLabel = "Copy", onCopy, style, ...rest }) {
1672
+ return /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("div", { ...rest, style: { background: "var(--color-surface-code)", borderRadius: "var(--radius-card)", margin: "24px 0", overflow: "hidden", ...style }, children: [
1673
+ /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)("div", { style: { display: "flex", alignItems: "baseline", gap: 10, padding: "12px 18px", minWidth: 0 }, children: [
1674
+ /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("span", { style: { fontFamily: "var(--font-family-mono)", fontSize: "var(--font-size-xs)", letterSpacing: "var(--letter-spacing-mono-wide)", color: "var(--color-code-green)", whiteSpace: "nowrap", flexShrink: 0 }, children: "CODE" }),
1675
+ /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("span", { style: { fontSize: "var(--font-size-base)", fontWeight: 600, color: "#EDEBE3", whiteSpace: "nowrap", overflow: "hidden", textOverflow: "ellipsis", minWidth: 0 }, children: title }),
1676
+ /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("span", { style: { fontFamily: "var(--font-family-mono)", fontSize: "var(--font-size-sm)", color: "var(--color-ink-500)", whiteSpace: "nowrap", flexShrink: 0 }, children: lang }),
1677
+ /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("span", { style: { flex: 1, minWidth: 4 } }),
1678
+ /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
1679
+ "button",
1680
+ {
1681
+ type: "button",
1682
+ onClick: onCopy,
1683
+ style: { border: "none", background: "none", fontFamily: "var(--font-family-mono)", fontSize: "var(--font-size-sm)", color: "var(--color-ink-400)", padding: "2px 7px", borderRadius: 5, whiteSpace: "nowrap", flexShrink: 0 },
1684
+ children: copyLabel
1685
+ }
1686
+ )
1687
+ ] }),
1688
+ /* @__PURE__ */ (0, import_jsx_runtime27.jsx)("pre", { style: { margin: 0, padding: "4px 20px 18px", overflowX: "auto", fontFamily: "var(--font-family-mono)", fontSize: "var(--font-size-base)", lineHeight: "var(--line-height-relaxed)", color: "var(--color-text-on-code)", whiteSpace: "pre-wrap" }, children: code })
1689
+ ] });
1690
+ }
1691
+
1692
+ // src/components/TableCard/TableCard.tsx
1693
+ var import_jsx_runtime28 = require("react/jsx-runtime");
1694
+ var srOnly = {
1695
+ position: "absolute",
1696
+ width: 1,
1697
+ height: 1,
1698
+ padding: 0,
1699
+ margin: -1,
1700
+ overflow: "hidden",
1701
+ clip: "rect(0, 0, 0, 0)",
1702
+ whiteSpace: "nowrap",
1703
+ border: 0
1704
+ };
1705
+ function TableCard({ title, header, rows, style, ...rest }) {
1706
+ return /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)(
1707
+ "div",
1708
+ {
1709
+ ...rest,
1710
+ style: { background: "var(--color-surface)", border: "1px solid var(--border-default)", borderRadius: "var(--radius-card)", margin: "24px 0", padding: "16px 20px 18px", ...style },
1711
+ children: [
1712
+ /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)("div", { style: { display: "flex", alignItems: "baseline", gap: 10, marginBottom: 12 }, children: [
1713
+ /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("span", { style: { fontFamily: "var(--font-family-mono)", fontSize: "var(--font-size-xs)", letterSpacing: "var(--letter-spacing-mono-wide)", color: "var(--color-accent)" }, children: "COMPARE" }),
1714
+ /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("span", { style: { fontSize: "var(--font-size-base)", fontWeight: 600, color: "var(--color-text-primary)", whiteSpace: "nowrap", overflow: "hidden", textOverflow: "ellipsis", minWidth: 0 }, children: title })
1715
+ ] }),
1716
+ /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)("table", { style: { width: "100%", borderCollapse: "collapse", fontSize: "var(--font-size-base)" }, children: [
1717
+ /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("thead", { children: /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("tr", { children: header.map((h, i) => /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
1718
+ "th",
1719
+ {
1720
+ scope: "col",
1721
+ style: {
1722
+ textAlign: "left",
1723
+ padding: "8px 10px",
1724
+ fontWeight: i === 0 ? 400 : 600,
1725
+ color: i === 0 ? "var(--color-text-muted)" : "var(--color-text-primary)",
1726
+ fontFamily: i === 0 ? "var(--font-family-mono)" : "inherit",
1727
+ fontSize: i === 0 ? "var(--font-size-sm)" : "inherit",
1728
+ borderBottom: "1px solid var(--border-subtle)"
1729
+ },
1730
+ children: h || /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("span", { style: srOnly, children: "Row label" })
1731
+ },
1732
+ i
1733
+ )) }) }),
1734
+ /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("tbody", { children: rows.map((r, ri) => /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("tr", { children: r.map((c, ci) => {
1735
+ const cellStyle = {
1736
+ padding: "8px 10px",
1737
+ color: ci === 0 ? "var(--color-text-muted)" : "var(--color-text-secondary)",
1738
+ fontFamily: ci === 0 ? "var(--font-family-mono)" : "inherit",
1739
+ fontSize: ci === 0 ? "var(--font-size-sm)" : "inherit",
1740
+ borderBottom: ri === rows.length - 1 ? "none" : "1px solid var(--border-subtle)"
1741
+ };
1742
+ return ci === 0 ? /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("th", { scope: "row", style: { ...cellStyle, textAlign: "left", fontWeight: 400 }, children: c }, ci) : /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("td", { style: cellStyle, children: c }, ci);
1743
+ }) }, ri)) })
1744
+ ] })
1745
+ ]
1746
+ }
1747
+ );
1748
+ }
1749
+
1750
+ // src/components/QuizCard/QuizCard.tsx
1751
+ var import_react9 = require("react");
1752
+ var import_jsx_runtime29 = require("react/jsx-runtime");
1753
+ function QuizCard({ question, answerOpen, answer, quizLabel, onToggleQuiz, addFlashLabel, onAddFlash, style, ...rest }) {
1754
+ const answerId = (0, import_react9.useId)();
1755
+ return /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)(
1756
+ "div",
1757
+ {
1758
+ ...rest,
1759
+ style: {
1760
+ background: "var(--color-accent-tint)",
1761
+ border: "1px solid color-mix(in srgb, var(--color-accent) 22%, transparent)",
1762
+ borderRadius: "var(--radius-card)",
1763
+ margin: "24px 0",
1764
+ padding: "16px 20px 18px",
1765
+ ...style
1766
+ },
1767
+ children: [
1768
+ /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)("div", { style: { display: "flex", alignItems: "baseline", gap: 10, marginBottom: 10 }, children: [
1769
+ /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("span", { style: { fontFamily: "var(--font-family-mono)", fontSize: "var(--font-size-xs)", letterSpacing: "var(--letter-spacing-mono-wide)", color: "var(--color-accent)" }, children: "CHECKPOINT" }),
1770
+ /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("span", { style: { fontSize: "var(--font-size-base)", fontWeight: 600, color: "var(--color-text-primary)", whiteSpace: "nowrap" }, children: "Still with it?" })
1771
+ ] }),
1772
+ /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("p", { style: { margin: "0 0 10px", fontSize: "var(--font-size-lg)", color: "var(--color-text-body)" }, children: question }),
1773
+ /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
1774
+ "button",
1775
+ {
1776
+ type: "button",
1777
+ onClick: onToggleQuiz,
1778
+ "aria-expanded": answerOpen,
1779
+ "aria-controls": answerId,
1780
+ style: { border: "none", background: "none", padding: 0, fontFamily: "var(--font-family-mono)", fontSize: "var(--font-size-base)", color: "var(--color-accent)", whiteSpace: "nowrap" },
1781
+ children: quizLabel
1782
+ }
1783
+ ),
1784
+ /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
1785
+ "button",
1786
+ {
1787
+ type: "button",
1788
+ onClick: onAddFlash,
1789
+ style: { marginLeft: 14, border: "none", background: "none", padding: 0, fontFamily: "var(--font-family-mono)", fontSize: "var(--font-size-base)", color: "var(--color-text-muted)", whiteSpace: "nowrap" },
1790
+ children: addFlashLabel
1791
+ }
1792
+ ),
1793
+ answerOpen && /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
1794
+ "div",
1795
+ {
1796
+ id: answerId,
1797
+ style: {
1798
+ marginTop: 10,
1799
+ padding: "12px 15px",
1800
+ borderRadius: "var(--radius-lg)",
1801
+ background: "var(--color-surface)",
1802
+ border: "1px solid color-mix(in srgb, var(--color-accent) 18%, transparent)",
1803
+ fontSize: "var(--font-size-base)",
1804
+ color: "var(--color-text-secondary)"
1805
+ },
1806
+ children: answer
1807
+ }
1808
+ )
1809
+ ]
1810
+ }
1811
+ );
1812
+ }
1813
+
1814
+ // src/components/ImageCard/ImageCard.tsx
1815
+ var import_jsx_runtime30 = require("react/jsx-runtime");
1816
+ function ImageCard({ label = "UPLOAD", title, slotId, placeholder, height = 230, caption, style, ...rest }) {
1817
+ return /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("div", { ...rest, style: { background: "var(--color-surface)", border: "1px solid var(--border-default)", borderRadius: "var(--radius-card)", margin: "24px 0", padding: "16px 20px 20px", ...style }, children: [
1818
+ /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("div", { style: { display: "flex", alignItems: "baseline", gap: 10, marginBottom: 12 }, children: [
1819
+ /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("span", { style: { fontFamily: "var(--font-family-mono)", fontSize: "var(--font-size-xs)", letterSpacing: "var(--letter-spacing-mono-wide)", color: "var(--color-accent)" }, children: label }),
1820
+ /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("span", { style: { fontSize: "var(--font-size-base)", fontWeight: 600, color: "var(--color-text-primary)", whiteSpace: "nowrap", overflow: "hidden", textOverflow: "ellipsis", minWidth: 0 }, children: title })
1821
+ ] }),
1822
+ /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("image-slot", { id: slotId, shape: "rounded", radius: "10", placeholder, style: { width: "100%", height, display: "block" } }),
1823
+ caption && /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("div", { style: { marginTop: 8, fontSize: "var(--font-size-md)", color: "var(--color-text-muted)", textAlign: "center" }, children: caption })
1824
+ ] });
1825
+ }
1826
+
1827
+ // src/components/RelatedCard/RelatedCard.tsx
1828
+ var import_react10 = require("react");
1829
+ var import_jsx_runtime31 = require("react/jsx-runtime");
1830
+ function RelatedCard({ items, style, ...rest }) {
1831
+ return /* @__PURE__ */ (0, import_jsx_runtime31.jsxs)("div", { ...rest, style: { background: "var(--color-surface)", border: "1px solid var(--border-default)", borderRadius: "var(--radius-card)", margin: "24px 0", padding: 16, ...style }, children: [
1832
+ /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("div", { style: { display: "flex", alignItems: "baseline", gap: 10, marginBottom: 10 }, children: /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("span", { style: { fontFamily: "var(--font-family-mono)", fontSize: "var(--font-size-xs)", letterSpacing: "var(--letter-spacing-mono-wide)", color: "var(--color-accent)" }, children: "RELATED" }) }),
1833
+ /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("ul", { role: "list", style: { listStyle: "none", margin: 0, padding: 0, display: "flex", flexDirection: "column", gap: 8 }, children: items.map((it, i) => {
1834
+ const Element = it.as ?? (it.href ? "a" : "button");
1835
+ return /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("li", { children: (0, import_react10.createElement)(
1836
+ Element,
1837
+ {
1838
+ type: Element === "button" ? "button" : void 0,
1839
+ href: it.href,
1840
+ onClick: it.onClick,
1841
+ style: {
1842
+ display: "flex",
1843
+ alignItems: "center",
1844
+ gap: 6,
1845
+ width: "100%",
1846
+ boxSizing: "border-box",
1847
+ border: "1px solid var(--border-medium)",
1848
+ background: "var(--color-background)",
1849
+ borderRadius: "var(--radius-xl)",
1850
+ padding: "9px 12px",
1851
+ fontFamily: "inherit",
1852
+ fontSize: "var(--font-size-base)",
1853
+ color: "var(--color-text-secondary)",
1854
+ textAlign: "left",
1855
+ textDecoration: "none"
1856
+ }
1857
+ },
1858
+ /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("span", { "aria-hidden": "true", style: { width: 6, height: 6, borderRadius: "50%", background: it.color, flexShrink: 0 } }),
1859
+ /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("span", { style: { flex: 1 }, children: it.label }),
1860
+ /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("span", { "aria-hidden": "true", style: { color: "var(--color-ink-300)" }, children: "\u203A" })
1861
+ ) }, i);
1862
+ }) })
1863
+ ] });
1864
+ }
1865
+
1866
+ // src/components/ReferencesCard/ReferencesCard.tsx
1867
+ var import_jsx_runtime32 = require("react/jsx-runtime");
1868
+ function ReferencesCard({ items, style, ...rest }) {
1869
+ return /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)("div", { ...rest, style: { background: "var(--color-surface)", border: "1px solid var(--border-default)", borderRadius: "var(--radius-card)", margin: "24px 0", padding: 16, ...style }, children: [
1870
+ /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("div", { style: { display: "flex", alignItems: "baseline", gap: 10, marginBottom: 10 }, children: /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("span", { style: { fontFamily: "var(--font-family-mono)", fontSize: "var(--font-size-xs)", letterSpacing: "var(--letter-spacing-mono-wide)", color: "var(--color-accent)" }, children: "REFERENCES" }) }),
1871
+ /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("ul", { role: "list", style: { listStyle: "none", margin: 0, padding: 0, display: "flex", flexDirection: "column", gap: 8 }, children: items.map((t, i) => /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)("li", { style: { display: "flex", alignItems: "baseline", gap: 8, fontSize: "var(--font-size-base)" }, children: [
1872
+ /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("span", { "aria-hidden": "true", style: { color: "var(--color-ink-300)" }, children: "\u203A" }),
1873
+ /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("span", { style: { color: "var(--color-text-secondary)" }, children: t })
1874
+ ] }, i)) })
1875
+ ] });
1876
+ }
1877
+
1878
+ // src/components/AnnotationPanel/AnnotationPanel.tsx
1879
+ var import_react11 = require("react");
1880
+ var import_jsx_runtime33 = require("react/jsx-runtime");
1881
+ function AnnotationPanel({ open, value, onChange, placeholder = "Jot your own take here\u2026", ...rest }) {
1882
+ const labelId = (0, import_react11.useId)();
1883
+ if (!open) return null;
1884
+ return /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)("div", { style: { marginTop: 10, background: "var(--color-annotation-fill)", borderLeft: "3px solid var(--color-annotation-border)", borderRadius: "0 8px 8px 0", padding: "10px 14px" }, children: [
1885
+ /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("div", { id: labelId, style: { fontFamily: "var(--font-family-mono)", fontSize: "9.5px", letterSpacing: "0.14em", color: "var(--color-annotation-label)", marginBottom: 5 }, children: "MY NOTE" }),
1886
+ /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
1887
+ "textarea",
1888
+ {
1889
+ "aria-labelledby": labelId,
1890
+ value,
1891
+ onChange,
1892
+ rows: 2,
1893
+ placeholder,
1894
+ ...rest,
1895
+ style: { width: "100%", boxSizing: "border-box", border: "none", background: "none", fontFamily: "var(--font-family-hand)", fontSize: "14.5px", color: "var(--color-annotation-text)", resize: "vertical", padding: 0 }
1896
+ }
1897
+ )
1898
+ ] });
1899
+ }
1900
+
1901
+ // src/components/AnnotationToggle/AnnotationToggle.tsx
1902
+ var import_jsx_runtime34 = require("react/jsx-runtime");
1903
+ function AnnotationToggle({
1904
+ hasText = false,
1905
+ open = false,
1906
+ onClick,
1907
+ hot = false,
1908
+ onMouseEnter,
1909
+ onMouseLeave,
1910
+ onFocus,
1911
+ onBlur,
1912
+ ...rest
1913
+ }) {
1914
+ const { active, interactionHandlers } = useHover({ onMouseEnter, onMouseLeave, onFocus, onBlur });
1915
+ const visible = hot || open || hasText || active;
1916
+ return /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
1917
+ "button",
1918
+ {
1919
+ type: "button",
1920
+ onClick,
1921
+ ...rest,
1922
+ ...interactionHandlers,
1923
+ style: {
1924
+ border: "none",
1925
+ background: "none",
1926
+ fontFamily: "var(--font-family-mono)",
1927
+ fontSize: "var(--font-size-xs)",
1928
+ letterSpacing: "0.06em",
1929
+ color: "var(--color-annotation-label)",
1930
+ padding: "2px 7px",
1931
+ borderRadius: 5,
1932
+ whiteSpace: "nowrap",
1933
+ opacity: visible ? 1 : 0
1934
+ },
1935
+ children: hasText ? "\u270E My note" : "+ My note"
1936
+ }
1937
+ );
1938
+ }
1939
+
1940
+ // src/components/McqOption/McqOption.tsx
1941
+ var import_jsx_runtime35 = require("react/jsx-runtime");
1942
+ var STATE_TEXT = { correct: "Correct", wrong: "Incorrect" };
1943
+ function McqOption({ label, state = "default", onClick, ...rest }) {
1944
+ let border = "var(--border-medium)";
1945
+ let bg = "var(--color-surface)";
1946
+ let color = "var(--color-text-body)";
1947
+ let mark = "";
1948
+ if (state === "correct") {
1949
+ border = "var(--color-success-border)";
1950
+ bg = "var(--color-success-tint)";
1951
+ color = "var(--color-success)";
1952
+ mark = "\u2713";
1953
+ }
1954
+ if (state === "wrong") {
1955
+ border = "var(--color-danger-border)";
1956
+ bg = "var(--color-danger-tint)";
1957
+ color = "var(--color-danger)";
1958
+ mark = "\u2715";
1959
+ }
1960
+ return /* @__PURE__ */ (0, import_jsx_runtime35.jsxs)(
1961
+ "button",
1962
+ {
1963
+ type: "button",
1964
+ onClick,
1965
+ disabled: state !== "default",
1966
+ ...rest,
1967
+ style: {
1968
+ display: "flex",
1969
+ alignItems: "flex-start",
1970
+ justifyContent: "space-between",
1971
+ gap: 10,
1972
+ textAlign: "left",
1973
+ border: `1px solid ${border}`,
1974
+ background: bg,
1975
+ color,
1976
+ borderRadius: "var(--radius-lg)",
1977
+ padding: "9px 13px",
1978
+ fontFamily: "inherit",
1979
+ fontSize: "var(--font-size-lg)",
1980
+ width: "100%",
1981
+ boxSizing: "border-box"
1982
+ },
1983
+ children: [
1984
+ /* @__PURE__ */ (0, import_jsx_runtime35.jsx)("span", { style: { flex: 1, minWidth: 0, textWrap: "pretty" }, children: label }),
1985
+ mark && /* @__PURE__ */ (0, import_jsx_runtime35.jsxs)("span", { style: { fontWeight: 700, flexShrink: 0 }, children: [
1986
+ /* @__PURE__ */ (0, import_jsx_runtime35.jsx)("span", { "aria-hidden": "true", children: mark }),
1987
+ /* @__PURE__ */ (0, import_jsx_runtime35.jsxs)(
1988
+ "span",
1989
+ {
1990
+ style: {
1991
+ position: "absolute",
1992
+ width: 1,
1993
+ height: 1,
1994
+ padding: 0,
1995
+ margin: -1,
1996
+ overflow: "hidden",
1997
+ clip: "rect(0, 0, 0, 0)",
1998
+ whiteSpace: "nowrap",
1999
+ border: 0
2000
+ },
2001
+ children: [
2002
+ " ",
2003
+ "(",
2004
+ STATE_TEXT[state],
2005
+ ")"
2006
+ ]
2007
+ }
2008
+ )
2009
+ ] })
2010
+ ]
2011
+ }
2012
+ );
2013
+ }
2014
+
2015
+ // src/components/FillBlankInput/FillBlankInput.tsx
2016
+ var import_jsx_runtime36 = require("react/jsx-runtime");
2017
+ function FillBlankInput({ value, onChange, checked = false, correct = false, onCheck, resultLabel, style, ...rest }) {
2018
+ const borderColor = checked ? correct ? "var(--color-success-border)" : "var(--color-danger-border)" : "var(--border-medium)";
2019
+ return /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)("div", { ...rest, style, children: [
2020
+ /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)("div", { style: { display: "flex", gap: 8, marginTop: 10 }, children: [
2021
+ /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
2022
+ TextInput,
2023
+ {
2024
+ value,
2025
+ onChange,
2026
+ placeholder: "Your answer",
2027
+ "aria-label": "Your answer",
2028
+ "aria-invalid": checked ? !correct : void 0,
2029
+ style: { flex: 1, border: `1px solid ${borderColor}`, background: "var(--color-background)", fontSize: "var(--font-size-lg)" }
2030
+ }
2031
+ ),
2032
+ !checked && /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
2033
+ "button",
2034
+ {
2035
+ type: "button",
2036
+ onClick: onCheck,
2037
+ style: { border: "none", background: "var(--color-accent)", color: "#fff", borderRadius: "var(--radius-md)", padding: "0 16px", fontFamily: "inherit", fontSize: "var(--font-size-base)", fontWeight: 600 },
2038
+ children: "Check"
2039
+ }
2040
+ )
2041
+ ] }),
2042
+ checked && /* @__PURE__ */ (0, import_jsx_runtime36.jsx)("div", { "aria-live": "polite", style: { marginTop: 12, padding: "13px 16px", borderRadius: "var(--radius-lg)", background: "var(--color-surface-sunken)", border: "1px solid var(--border-subtle)" }, children: /* @__PURE__ */ (0, import_jsx_runtime36.jsx)("span", { style: { fontFamily: "var(--font-family-mono)", fontSize: "var(--font-size-xs)", letterSpacing: "0.1em", color: correct ? "var(--color-success)" : "var(--color-danger)" }, children: resultLabel }) })
2043
+ ] });
2044
+ }
2045
+
2046
+ // src/components/ScenarioBox/ScenarioBox.tsx
2047
+ var import_jsx_runtime37 = require("react/jsx-runtime");
2048
+ function ScenarioBox({ text, style, ...rest }) {
2049
+ return /* @__PURE__ */ (0, import_jsx_runtime37.jsxs)(
2050
+ "div",
2051
+ {
2052
+ ...rest,
2053
+ style: { margin: "2px 0 12px", padding: "12px 14px", borderRadius: "var(--radius-lg)", background: "var(--color-warning-tint)", border: "1px solid var(--color-warning-border)", ...style },
2054
+ children: [
2055
+ /* @__PURE__ */ (0, import_jsx_runtime37.jsx)("span", { style: { display: "block", fontFamily: "var(--font-family-mono)", fontSize: "var(--font-size-xs)", letterSpacing: "0.12em", color: "var(--color-warning)", marginBottom: 5 }, children: "SCENARIO" }),
2056
+ /* @__PURE__ */ (0, import_jsx_runtime37.jsx)("p", { style: { margin: 0, fontSize: "var(--font-size-base)", color: "var(--color-ink-700)", textWrap: "pretty" }, children: text })
2057
+ ]
2058
+ }
2059
+ );
2060
+ }
2061
+
2062
+ // src/components/Flashcard/Flashcard.tsx
2063
+ var import_jsx_runtime38 = require("react/jsx-runtime");
2064
+ function Flashcard({ flipped, front, back, boxLabel, onFlip, ...rest }) {
2065
+ return /* @__PURE__ */ (0, import_jsx_runtime38.jsxs)("div", { children: [
2066
+ /* @__PURE__ */ (0, import_jsx_runtime38.jsx)("div", { style: { textAlign: "right", marginBottom: 6 }, children: /* @__PURE__ */ (0, import_jsx_runtime38.jsx)("span", { style: { fontFamily: "var(--font-family-mono)", fontSize: "9.5px", letterSpacing: "0.1em", color: "var(--color-ink-300)" }, children: boxLabel }) }),
2067
+ /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(
2068
+ "button",
2069
+ {
2070
+ type: "button",
2071
+ onClick: onFlip,
2072
+ "aria-pressed": flipped,
2073
+ ...rest,
2074
+ style: {
2075
+ display: "block",
2076
+ width: "100%",
2077
+ minHeight: 220,
2078
+ background: "var(--color-surface)",
2079
+ border: "1px solid var(--border-medium)",
2080
+ borderRadius: "var(--radius-surface)",
2081
+ padding: "30px 34px",
2082
+ fontFamily: "inherit",
2083
+ textAlign: "center",
2084
+ boxShadow: "var(--shadow-sm)",
2085
+ boxSizing: "border-box"
2086
+ },
2087
+ children: /* @__PURE__ */ (0, import_jsx_runtime38.jsx)("div", { "aria-live": "polite", children: !flipped ? /* @__PURE__ */ (0, import_jsx_runtime38.jsxs)("div", { children: [
2088
+ /* @__PURE__ */ (0, import_jsx_runtime38.jsx)("div", { style: { fontFamily: "var(--font-family-mono)", fontSize: "var(--font-size-xs)", letterSpacing: "var(--letter-spacing-mono-wider)", color: "var(--color-text-faint)", marginBottom: 18 }, children: "PROMPT" }),
2089
+ /* @__PURE__ */ (0, import_jsx_runtime38.jsx)("div", { style: { fontSize: "var(--font-size-2xl)", fontWeight: 600, color: "var(--color-text-primary)", marginBottom: 14, textWrap: "pretty" }, children: front }),
2090
+ /* @__PURE__ */ (0, import_jsx_runtime38.jsx)("div", { style: { fontFamily: "var(--font-family-mono)", fontSize: "var(--font-size-sm)", color: "var(--color-ink-300)", marginTop: 26 }, children: "tap to reveal" })
2091
+ ] }) : /* @__PURE__ */ (0, import_jsx_runtime38.jsxs)("div", { children: [
2092
+ /* @__PURE__ */ (0, import_jsx_runtime38.jsx)("div", { style: { fontFamily: "var(--font-family-mono)", fontSize: "var(--font-size-xs)", letterSpacing: "var(--letter-spacing-mono-wider)", color: "var(--color-accent)", marginBottom: 18 }, children: "ANSWER" }),
2093
+ /* @__PURE__ */ (0, import_jsx_runtime38.jsx)("div", { style: { fontSize: "var(--font-size-lg)", color: "var(--color-text-tertiary)", textWrap: "pretty" }, children: back })
2094
+ ] }) })
2095
+ }
2096
+ )
2097
+ ] });
2098
+ }
2099
+
2100
+ // src/components/RateButtons/RateButtons.tsx
2101
+ var import_jsx_runtime39 = require("react/jsx-runtime");
2102
+ var buttonStyle = (border, bg, color) => ({
2103
+ border: `1px solid ${border}`,
2104
+ background: bg,
2105
+ color,
2106
+ borderRadius: "var(--radius-lg)",
2107
+ padding: "8px 22px",
2108
+ fontFamily: "inherit",
2109
+ fontSize: "var(--font-size-lg)",
2110
+ fontWeight: 600
2111
+ });
2112
+ function RateButtons({ enabled = false, onAgain, onGood, onEasy, style, ...rest }) {
2113
+ return /* @__PURE__ */ (0, import_jsx_runtime39.jsxs)("div", { role: "group", "aria-label": "Rate your recall", ...rest, style: { display: "flex", gap: 10, justifyContent: "center", marginTop: 18, opacity: enabled ? 1 : 0.25, ...style }, children: [
2114
+ /* @__PURE__ */ (0, import_jsx_runtime39.jsx)("button", { type: "button", onClick: onAgain, disabled: !enabled, style: buttonStyle("var(--color-danger-border)", "var(--color-danger-tint)", "var(--color-danger)"), children: "Again" }),
2115
+ /* @__PURE__ */ (0, import_jsx_runtime39.jsx)("button", { type: "button", onClick: onGood, disabled: !enabled, style: buttonStyle("var(--color-warning-border)", "var(--color-warning-tint)", "var(--color-warning)"), children: "Good" }),
2116
+ /* @__PURE__ */ (0, import_jsx_runtime39.jsx)("button", { type: "button", onClick: onEasy, disabled: !enabled, style: buttonStyle("var(--color-success-border)", "var(--color-success-tint)", "var(--color-success)"), children: "Easy" })
2117
+ ] });
2118
+ }
2119
+ // Annotate the CommonJS export names for ESM import in node:
2120
+ 0 && (module.exports = {
2121
+ AnnotationPanel,
2122
+ AnnotationToggle,
2123
+ Avatar,
2124
+ Badge,
2125
+ BottomSheet,
2126
+ Button,
2127
+ CardHeader,
2128
+ CardShell,
2129
+ CodeCard,
2130
+ ColorSwatch,
2131
+ ContextMenu,
2132
+ DragHandle,
2133
+ EquationBlock,
2134
+ ExportRow,
2135
+ FillBlankInput,
2136
+ Flashcard,
2137
+ IconButton,
2138
+ ImageCard,
2139
+ ImportExportModal,
2140
+ IntuitionCallout,
2141
+ McqOption,
2142
+ NavTabs,
2143
+ NoteRow,
2144
+ QuizCard,
2145
+ RateButtons,
2146
+ ReferencesCard,
2147
+ RelatedCard,
2148
+ ScenarioBox,
2149
+ Sidebar,
2150
+ SolvedStatusButton,
2151
+ TableCard,
2152
+ TagChip,
2153
+ TextArea,
2154
+ TextBlock,
2155
+ TextInput,
2156
+ TocFab,
2157
+ TocRail,
2158
+ TocSheetList,
2159
+ TopicRow,
2160
+ WalkthroughCard
2161
+ });
2162
+ //# sourceMappingURL=index.cjs.map