astryx-dracula 0.2.1 → 0.3.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 (83) hide show
  1. package/BRAND.md +30 -18
  2. package/README.md +17 -12
  3. package/USAGE.md +29 -10
  4. package/astryx-dracula.js +19 -13
  5. package/astryx-dracula.variants.d.ts +15 -0
  6. package/package.json +59 -17
  7. package/shared/auth-chrome-config.ts +18 -0
  8. package/shared/auth-chrome.tsx +25 -0
  9. package/shared/auth-copy.ts +22 -0
  10. package/shared/chaptered-doc-config.ts +92 -0
  11. package/shared/chaptered-doc.tsx +332 -0
  12. package/shared/chart-hues.ts +27 -0
  13. package/shared/chart-labels.tsx +44 -0
  14. package/shared/chart-legend.tsx +100 -0
  15. package/shared/chart-panel-style.ts +13 -0
  16. package/shared/data-bar.tsx +160 -0
  17. package/shared/gallery-image.ts +20 -0
  18. package/shared/login-demo.ts +7 -0
  19. package/shared/metric-delta.tsx +36 -0
  20. package/shared/order-desk.tsx +273 -0
  21. package/shared/revenue-chart.tsx +174 -0
  22. package/shared/scene-castle.tsx +322 -0
  23. package/shared/scene-frame.tsx +88 -0
  24. package/shared/scene-hues.ts +49 -0
  25. package/shared/scene-tile.tsx +128 -0
  26. package/shared/settings-data.ts +125 -0
  27. package/shared/settings-rows.tsx +179 -0
  28. package/shared/sparkline.tsx +94 -0
  29. package/shared/sso-icons.tsx +30 -0
  30. package/templates/ai-chat-landing.tsx +66 -33
  31. package/templates/ai-chat.tsx +36 -19
  32. package/templates/blank.tsx +4 -3
  33. package/templates/centered-hero.tsx +14 -125
  34. package/templates/classic-gallery.tsx +20 -66
  35. package/templates/contact-form.tsx +59 -39
  36. package/templates/dashboard-portfolio.tsx +143 -226
  37. package/templates/dashboard.tsx +122 -122
  38. package/templates/detail-page.tsx +95 -91
  39. package/templates/documentation-design.template.mjs +1 -1
  40. package/templates/documentation-design.tsx +83 -96
  41. package/templates/documentation-technical.template.mjs +1 -1
  42. package/templates/documentation-technical.tsx +29 -19
  43. package/templates/documentation.template.mjs +1 -1
  44. package/templates/documentation.tsx +52 -74
  45. package/templates/editor.tsx +112 -84
  46. package/templates/file-explorer.tsx +131 -84
  47. package/templates/form-two-column.tsx +61 -125
  48. package/templates/gallery-hero.tsx +15 -171
  49. package/templates/ide.tsx +22 -20
  50. package/templates/incident-console.tsx +104 -70
  51. package/templates/kanban-board.tsx +99 -42
  52. package/templates/library.template.mjs +2 -2
  53. package/templates/library.tsx +37 -42
  54. package/templates/login-card.tsx +58 -87
  55. package/templates/login-split.tsx +88 -126
  56. package/templates/login-sso.tsx +105 -64
  57. package/templates/login.tsx +107 -53
  58. package/templates/messaging-shell.tsx +171 -144
  59. package/templates/mixed-gallery.tsx +29 -130
  60. package/templates/payment-form.tsx +368 -290
  61. package/templates/product-detail.tsx +39 -58
  62. package/templates/product-gallery.tsx +30 -41
  63. package/templates/product-tour.template.mjs +6 -0
  64. package/templates/product-tour.tsx +916 -0
  65. package/templates/settings-dialog.tsx +135 -282
  66. package/templates/settings-sidebar.tsx +178 -268
  67. package/templates/settings.tsx +41 -14
  68. package/templates/shell-nav.tsx +31 -24
  69. package/templates/shell-side-nav.tsx +29 -20
  70. package/templates/shell-top-nav.tsx +80 -44
  71. package/templates/side-gallery.tsx +38 -94
  72. package/templates/table-grouped.tsx +62 -34
  73. package/templates/table-page-chart.tsx +23 -302
  74. package/templates/table-page-heatmap-status.tsx +156 -92
  75. package/templates/table-page-shoe-store-heatmap.tsx +18 -293
  76. package/templates/table-page.tsx +23 -7
  77. package/templates/table.tsx +23 -8
  78. package/templates/tech-report.template.mjs +6 -0
  79. package/templates/tech-report.tsx +1486 -0
  80. package/templates/theme-showcase.template.mjs +1 -1
  81. package/templates/theme-showcase.tsx +299 -237
  82. package/theme.css +76 -14
  83. package/tokens.css +425 -30
@@ -1,6 +1,10 @@
1
1
  // Copyright (c) Meta Platforms, Inc. and affiliates.
2
2
  // XLE (canonical structure, validated with `bunx astryx layout check`):
3
- // L > LC > Ctr[h=80vh] > B.primary"Open settings"[opens=#settings] ;; Dlg#settings > L > (LP[w=280 divider p=3] > V[g=4] > Hd"Account settings"[level=2] + (List > LI"Personal information"*8)) + (LC[p=6] > V[g=6] > DH"Account" + (V[g=4] > (H[j=between] > (V[g=0] > Tx"Legal name"[weight=semibold] + Tx"Vlad Dracul"[t=supporting color=secondary]) + Link"Edit")*4))
3
+ // L > LC > Ctr[h=80vh] > B.primary"Open settings"[opens=#settings] ;; Dlg#settings > L > (LP[w=280 divider p=3] > V[g=4] > Tx"Account settings"[t=label] + (UL > LI"Personal information"*8)) + (LC[p=6] > V[g=6] > DH"Account" + SE"Settings section" + (V[g=0] > TabList + (V[g=0] > Hd"Login"[level=3] + D + (H[j=between a=start] > (V[g=0] > Tx"Password"[weight=semibold] + Tx"Not created"[t=supporting]) + Lk"Create") + (H[g=3 a=start] > Ic + (V[g=0] > (H[g=2 a=center wrap] > Tx"OS X 10.15.7 Chrome"[weight=semibold] + SD) + Tx"March 30, 2026"[t=supporting])))))
4
+
5
+ /**
6
+ * Settings Dialog — account sections inside one modal. Frame: the trigger page, then a Dialog that sizes to (Frame/responsive/container: see XLE header above.)
7
+ */
4
8
 
5
9
  import React, {useState, type CSSProperties} from 'react';
6
10
  import {
@@ -22,29 +26,15 @@ import {Card} from '@astryxdesign/core/Card';
22
26
  import {Switch} from '@astryxdesign/core/Switch';
23
27
  import {Link} from '@astryxdesign/core/Link';
24
28
  import {TabList, Tab} from '@astryxdesign/core/TabList';
25
- import {Badge} from '@astryxdesign/core/Badge';
29
+ import {StatusDot} from '@astryxdesign/core/StatusDot';
26
30
  import {Icon} from '@astryxdesign/core/Icon';
27
31
  import {Center} from '@astryxdesign/core/Center';
28
32
  import {useMediaQuery} from '@astryxdesign/core/hooks';
29
- import {
30
- User,
31
- Lock,
32
- Globe,
33
- ShieldCheck,
34
- Monitor,
35
- Bell,
36
- FileText,
37
- CreditCard,
38
- Briefcase,
39
- SquarePen,
40
- Share2,
41
- } from 'lucide-react';
42
-
43
- const iconBox: CSSProperties = {
44
- borderRadius: 'var(--radius-container)',
45
- backgroundColor: 'var(--color-background-surface)',
46
- flexShrink: 0,
47
- };
33
+ import {Lock, ShieldCheck, Monitor} from 'lucide-react';
34
+ import {NAV_ITEMS, LOGIN_ROWS, SOCIAL_ROWS, DEVICE_ROWS, INFO_TILES, iconBox, actionNoWrap, sideNavHeading} from 'astryx-dracula/shared/settings-data';
35
+ import {InfoRowItem, ExpandableRow} from 'astryx-dracula/shared/settings-rows';
36
+ import type {DeviceRow, InfoTileData} from 'astryx-dracula/shared/settings-data';
37
+
48
38
  // Sticky dialog header bar — no Astryx prop for sticky/background/z-index.
49
39
  // Inline + block padding comes from the parent LayoutContent `padding`.
50
40
  const headerSticky: CSSProperties = {
@@ -58,63 +48,14 @@ const headerSticky: CSSProperties = {
58
48
  const contentMaxWidth: CSSProperties = {
59
49
  maxWidth: 680,
60
50
  };
61
- // Aligns the sidebar heading with list-item label text. No heading margin prop.
62
- const sideNavHeading: CSSProperties = {
63
- marginInline: 'var(--spacing-4)',
64
- };
65
51
  const dialogHeight: CSSProperties = {
66
52
  height: '85vh',
67
53
  };
68
- // Keeps row actions ("Log out", "Deactivate") on one line: without this the
69
- // action column wraps mid-phrase at tablet widths while the info column still
70
- // has room to wrap instead.
71
- const actionNoWrap: CSSProperties = {
72
- flexShrink: 0,
73
- whiteSpace: 'nowrap',
74
- };
75
54
 
76
55
  // Same-route hash: demo links stay focusable anchors without escaping the
77
56
  // template through the hash router (bare "#" would drop back to the home page).
78
57
  const SELF_HASH = '#/templates/settings-dialog';
79
58
 
80
- const NAV_ITEMS = [
81
- {label: 'Personal information', icon: User},
82
- {label: 'Login & security', icon: Lock},
83
- {label: 'Privacy', icon: ShieldCheck},
84
- {label: 'Notifications', icon: Bell},
85
- {label: 'Taxes', icon: FileText},
86
- {label: 'Payments', icon: CreditCard},
87
- {label: 'Languages & currency', icon: Globe},
88
- {label: 'Travel for work', icon: Briefcase},
89
- ];
90
-
91
- const LOGIN_ROWS = [
92
- {label: 'Password', value: 'Not created', action: 'Create'},
93
- ];
94
-
95
- const SOCIAL_ROWS = [
96
- {label: 'Google', value: 'Connected', action: 'Disconnect'},
97
- ];
98
-
99
- const DEVICE_ROWS: {
100
- label: string;
101
- badge?: string;
102
- location: string;
103
- action?: string;
104
- }[] = [
105
- {
106
- label: 'OS X 10.15.7 · Chrome',
107
- badge: 'CURRENT SESSION',
108
- location: 'Brașov, Transylvania · March 30, 2026 at 19:31',
109
- },
110
- {label: 'Session', location: 'August 9, 2023 at 04:19', action: 'Log out'},
111
- {
112
- label: 'OS X 10.15.7 · unknown',
113
- location: 'Whitby, England · April 14, 2023 at 17:47',
114
- action: 'Log out',
115
- },
116
- ];
117
-
118
59
  const LANGUAGES = [
119
60
  {label: 'English (Canada)', value: 'en-CA'},
120
61
  {label: 'English (US)', value: 'en-US'},
@@ -141,84 +82,62 @@ const TIMEZONES = [
141
82
  {label: '(GMT+01:00) London', value: 'GMT+1'},
142
83
  ];
143
84
 
144
- interface ExpandableRowProps {
145
- label: string;
146
- value: string;
147
- children: React.ReactNode;
148
- isExpanded: boolean;
149
- onEdit: () => void;
150
- onCancel: () => void;
151
- onSave: () => void;
85
+
86
+ function InfoTile({icon, title, body}: InfoTileData) {
87
+ return (
88
+ <HStack gap={3} vAlign="start">
89
+ <Center width={48} height={48} style={iconBox}>
90
+ <Icon icon={icon} />
91
+ </Center>
92
+ <VStack gap={0}>
93
+ <Text type="body" weight="semibold" display="block">
94
+ {title}
95
+ </Text>
96
+ <Text type="body" color="secondary" display="block">
97
+ {body}
98
+ </Text>
99
+ </VStack>
100
+ </HStack>
101
+ );
152
102
  }
153
103
 
154
- function ExpandableRow({
155
- label,
156
- value,
157
- children,
158
- isExpanded,
159
- onEdit,
160
- onCancel,
161
- onSave,
162
- }: ExpandableRowProps) {
104
+
105
+ function DeviceRowItem({label, isCurrent, location, action}: DeviceRow) {
163
106
  return (
164
107
  <>
165
- {isExpanded ? (
166
- <VStack gap={4}>
167
- <Text type="body" weight="semibold" display="block">
168
- {label}
169
- </Text>
170
- {children}
171
- <HStack gap={2}>
172
- <Button label="Save" variant="primary" onClick={onSave} />
173
- <Button label="Cancel" variant="ghost" onClick={onCancel} />
174
- </HStack>
175
- </VStack>
176
- ) : (
177
- <HStack hAlign="between" vAlign="start">
108
+ <HStack gap={3} vAlign="start">
109
+ <Icon icon={Monitor} />
110
+ <StackItem size="fill">
178
111
  <VStack gap={0}>
179
- <Text type="body" weight="semibold" display="block">
180
- {label}
181
- </Text>
182
- <Text type="supporting" color="secondary" display="block">
183
- {value}
112
+ {/* wrap: the label plus the session status exceed the compact
113
+ content width (~280px). */}
114
+ <HStack gap={2} vAlign="center" wrap="wrap">
115
+ <Text type="body" weight="semibold">
116
+ {label}
117
+ </Text>
118
+ {isCurrent && (
119
+ <HStack gap={1} vAlign="center">
120
+ <StatusDot variant="success" label="Current session" />
121
+ <Text type="supporting" color="secondary">
122
+ Current session
123
+ </Text>
124
+ </HStack>
125
+ )}
126
+ </HStack>
127
+ <Text
128
+ type="supporting"
129
+ color="secondary"
130
+ display="block"
131
+ hasTabularNumbers>
132
+ {location}
184
133
  </Text>
185
134
  </VStack>
186
- <Link
187
- href={SELF_HASH}
188
- onClick={(e: React.MouseEvent) => {
189
- e.preventDefault();
190
- onEdit();
191
- }}>
192
- Edit
135
+ </StackItem>
136
+ {action && (
137
+ <Link href={SELF_HASH} style={actionNoWrap}>
138
+ {action}
193
139
  </Link>
194
- </HStack>
195
- )}
196
- <Divider />
197
- </>
198
- );
199
- }
200
-
201
- function InfoRowItem({
202
- label,
203
- value,
204
- action,
205
- }: {
206
- label: string;
207
- value: string;
208
- action: string;
209
- }) {
210
- return (
211
- <>
212
- <HStack hAlign="between" vAlign="start">
213
- <VStack gap={0}>
214
- <Text type="body" weight="semibold" display="block">
215
- {label}
216
- </Text>
217
- <Text type="supporting" color="secondary" display="block">
218
- {value}
219
- </Text>
220
- </VStack>
221
- {action && <Link href={SELF_HASH}>{action}</Link>}
140
+ )}
222
141
  </HStack>
223
142
  <Divider />
224
143
  </>
@@ -264,6 +183,7 @@ export default function SettingsDialog() {
264
183
  return (
265
184
  <>
266
185
  <Layout
186
+ height="auto"
267
187
  content={
268
188
  <LayoutContent padding={0}>
269
189
  <Center height="80vh">
@@ -280,7 +200,9 @@ export default function SettingsDialog() {
280
200
  <Dialog
281
201
  isOpen={isOpen}
282
202
  onOpenChange={open => setIsOpen(open)}
283
- width={isCompact ? 'calc(100vw - 32px)' : 900}
203
+ // One width for every viewport: below 932px the dialog shrinks with the
204
+ // window instead of clipping, so no compact branch is needed.
205
+ width="min(900px, calc(100vw - 32px))"
284
206
  maxHeight="85vh"
285
207
  padding={0}
286
208
  purpose="form"
@@ -291,9 +213,9 @@ export default function SettingsDialog() {
291
213
  isCompact ? undefined : (
292
214
  <LayoutPanel width={280} hasDivider role="navigation" padding={3}>
293
215
  <VStack gap={4}>
294
- <Heading level={2} style={sideNavHeading}>
216
+ <Text type="label" style={sideNavHeading}>
295
217
  Account settings
296
- </Heading>
218
+ </Text>
297
219
  <List density="spacious">
298
220
  {NAV_ITEMS.map(item => (
299
221
  <ListItem
@@ -351,7 +273,8 @@ export default function SettingsDialog() {
351
273
  isExpanded={expandedRow === 'legalName'}
352
274
  onEdit={() => handleEdit('legalName')}
353
275
  onCancel={handleCancel}
354
- onSave={handleSave}>
276
+ onSave={handleSave}
277
+ href={SELF_HASH}>
355
278
  <TextInput
356
279
  label="Legal name"
357
280
  isLabelHidden
@@ -365,7 +288,8 @@ export default function SettingsDialog() {
365
288
  isExpanded={expandedRow === 'preferredName'}
366
289
  onEdit={() => handleEdit('preferredName')}
367
290
  onCancel={handleCancel}
368
- onSave={handleSave}>
291
+ onSave={handleSave}
292
+ href={SELF_HASH}>
369
293
  <TextInput
370
294
  label="Preferred first name"
371
295
  isLabelHidden
@@ -379,7 +303,8 @@ export default function SettingsDialog() {
379
303
  isExpanded={expandedRow === 'email'}
380
304
  onEdit={() => handleEdit('email')}
381
305
  onCancel={handleCancel}
382
- onSave={handleSave}>
306
+ onSave={handleSave}
307
+ href={SELF_HASH}>
383
308
  <TextInput
384
309
  label="Email address"
385
310
  isLabelHidden
@@ -393,7 +318,8 @@ export default function SettingsDialog() {
393
318
  isExpanded={expandedRow === 'phone'}
394
319
  onEdit={() => handleEdit('phone')}
395
320
  onCancel={handleCancel}
396
- onSave={handleSave}>
321
+ onSave={handleSave}
322
+ href={SELF_HASH}>
397
323
  <TextInput
398
324
  label="Phone number"
399
325
  isLabelHidden
@@ -405,6 +331,7 @@ export default function SettingsDialog() {
405
331
  label="Identity verification"
406
332
  value="Verified"
407
333
  action=""
334
+ href={SELF_HASH}
408
335
  />
409
336
  <ExpandableRow
410
337
  label="Residential address"
@@ -412,7 +339,8 @@ export default function SettingsDialog() {
412
339
  isExpanded={expandedRow === 'address'}
413
340
  onEdit={() => handleEdit('address')}
414
341
  onCancel={handleCancel}
415
- onSave={handleSave}>
342
+ onSave={handleSave}
343
+ href={SELF_HASH}>
416
344
  <TextInput
417
345
  label="Residential address"
418
346
  isLabelHidden
@@ -426,7 +354,8 @@ export default function SettingsDialog() {
426
354
  isExpanded={expandedRow === 'mailingAddress'}
427
355
  onEdit={() => handleEdit('mailingAddress')}
428
356
  onCancel={handleCancel}
429
- onSave={handleSave}>
357
+ onSave={handleSave}
358
+ href={SELF_HASH}>
430
359
  <TextInput
431
360
  label="Mailing address"
432
361
  isLabelHidden
@@ -440,7 +369,8 @@ export default function SettingsDialog() {
440
369
  isExpanded={expandedRow === 'emergencyContact'}
441
370
  onEdit={() => handleEdit('emergencyContact')}
442
371
  onCancel={handleCancel}
443
- onSave={handleSave}>
372
+ onSave={handleSave}
373
+ href={SELF_HASH}>
444
374
  <TextInput
445
375
  label="Emergency contact"
446
376
  isLabelHidden
@@ -452,70 +382,12 @@ export default function SettingsDialog() {
452
382
 
453
383
  <Card padding={4}>
454
384
  <VStack gap={4}>
455
- <HStack gap={3} vAlign="start">
456
- <Center width={48} height={48} style={iconBox}>
457
- <Icon icon={Lock} />
458
- </Center>
459
- <VStack gap={0}>
460
- <Text
461
- type="body"
462
- weight="semibold"
463
- display="block">
464
- Why isn&apos;t my info shown here?
465
- </Text>
466
- <Text
467
- type="supporting"
468
- color="secondary"
469
- display="block">
470
- We&apos;re hiding some account details to
471
- protect your identity.
472
- </Text>
473
- </VStack>
474
- </HStack>
475
- <Divider />
476
- <HStack gap={3} vAlign="start">
477
- <Center width={48} height={48} style={iconBox}>
478
- <Icon icon={SquarePen} />
479
- </Center>
480
- <VStack gap={0}>
481
- <Text
482
- type="body"
483
- weight="semibold"
484
- display="block">
485
- Which details can be edited?
486
- </Text>
487
- <Text
488
- type="supporting"
489
- color="secondary"
490
- display="block">
491
- Contact info and personal details can be edited.
492
- If this info was used to verify your identity,
493
- you&apos;ll need to get verified again the next
494
- time you book—or to continue hosting.
495
- </Text>
496
- </VStack>
497
- </HStack>
498
- <Divider />
499
- <HStack gap={3} vAlign="start">
500
- <Center width={48} height={48} style={iconBox}>
501
- <Icon icon={Share2} />
502
- </Center>
503
- <VStack gap={0}>
504
- <Text
505
- type="body"
506
- weight="semibold"
507
- display="block">
508
- What info is shared with others?
509
- </Text>
510
- <Text
511
- type="supporting"
512
- color="secondary"
513
- display="block">
514
- We only release contact information after a
515
- reservation is confirmed.
516
- </Text>
517
- </VStack>
518
- </HStack>
385
+ {INFO_TILES.map((tile, i) => (
386
+ <React.Fragment key={tile.title}>
387
+ {i > 0 && <Divider />}
388
+ <InfoTile {...tile} />
389
+ </React.Fragment>
390
+ ))}
519
391
  </VStack>
520
392
  </Card>
521
393
  </VStack>
@@ -533,60 +405,34 @@ export default function SettingsDialog() {
533
405
 
534
406
  {activeTab === 'login' && (
535
407
  <VStack gap={8}>
536
- <VStack gap={4}>
408
+ <VStack gap={0}>
537
409
  <Heading level={3}>Login</Heading>
538
410
  <Divider />
539
411
  {LOGIN_ROWS.map(row => (
540
- <InfoRowItem key={row.label} {...row} />
412
+ <InfoRowItem key={row.label} {...row} href={SELF_HASH} />
541
413
  ))}
542
414
  </VStack>
543
415
 
544
- <VStack gap={4}>
416
+ <VStack gap={0}>
545
417
  <Heading level={3}>Social accounts</Heading>
546
418
  <Divider />
547
419
  {SOCIAL_ROWS.map(row => (
548
- <InfoRowItem key={row.label} {...row} />
420
+ <InfoRowItem key={row.label} {...row} href={SELF_HASH} />
549
421
  ))}
550
422
  </VStack>
551
423
 
552
- <VStack gap={4}>
424
+ <VStack gap={0}>
553
425
  <Heading level={3}>Device history</Heading>
554
426
  <Divider />
555
- {DEVICE_ROWS.map((device, i) => (
556
- <React.Fragment key={i}>
557
- <HStack gap={3} vAlign="start">
558
- <Icon icon={Monitor} />
559
- <StackItem size="fill">
560
- <VStack gap={0}>
561
- <HStack gap={2} vAlign="center">
562
- <Text type="body" weight="semibold">
563
- {device.label}
564
- </Text>
565
- {device.badge && (
566
- <Badge label={device.badge} />
567
- )}
568
- </HStack>
569
- <Text
570
- type="supporting"
571
- color="secondary"
572
- display="block"
573
- hasTabularNumbers>
574
- {device.location}
575
- </Text>
576
- </VStack>
577
- </StackItem>
578
- {device.action && (
579
- <Link href={SELF_HASH} style={actionNoWrap}>
580
- {device.action}
581
- </Link>
582
- )}
583
- </HStack>
584
- <Divider />
585
- </React.Fragment>
427
+ {DEVICE_ROWS.map(device => (
428
+ <DeviceRowItem
429
+ key={device.location}
430
+ {...device}
431
+ />
586
432
  ))}
587
433
  </VStack>
588
434
 
589
- <VStack gap={4}>
435
+ <VStack gap={0}>
590
436
  <Heading level={3}>Account</Heading>
591
437
  <Divider />
592
438
  <HStack hAlign="between" vAlign="start">
@@ -618,9 +464,9 @@ export default function SettingsDialog() {
618
464
  <Divider />
619
465
  <Text type="body" color="secondary">
620
466
  Review each request carefully before approving
621
- access. We&apos;ll email your employee or
622
- co-worker a 4-digit code that lets them log into
623
- your account with their trusted device.
467
+ access. We&apos;ll email your kin or coven-mate
468
+ a 4-digit code that lets them enter your crypt
469
+ from their trusted device.
624
470
  </Text>
625
471
  </VStack>
626
472
 
@@ -630,13 +476,13 @@ export default function SettingsDialog() {
630
476
  <Icon icon={Lock} />
631
477
  </Center>
632
478
  <VStack gap={1}>
633
- <Text type="body" weight="bold">
634
- Adding devices from people you trust
479
+ <Text type="body">
480
+ Adding devices for your trusted coven
635
481
  </Text>
636
482
  <Text type="body" color="secondary">
637
- When you approve a request, you grant someone
638
- full access to your account. They&apos;ll be
639
- able to change reservations and send messages
483
+ When you approve a request, you grant them
484
+ full passage through your crypt. They&apos;ll
485
+ be able to change bookings and send ravens
640
486
  on your behalf.
641
487
  </Text>
642
488
  </VStack>
@@ -659,7 +505,8 @@ export default function SettingsDialog() {
659
505
  isExpanded={expandedRow === 'language'}
660
506
  onEdit={() => handleEdit('language')}
661
507
  onCancel={handleCancel}
662
- onSave={handleSave}>
508
+ onSave={handleSave}
509
+ href={SELF_HASH}>
663
510
  <Selector
664
511
  label="Language"
665
512
  isLabelHidden
@@ -678,7 +525,8 @@ export default function SettingsDialog() {
678
525
  isExpanded={expandedRow === 'currency'}
679
526
  onEdit={() => handleEdit('currency')}
680
527
  onCancel={handleCancel}
681
- onSave={handleSave}>
528
+ onSave={handleSave}
529
+ href={SELF_HASH}>
682
530
  <Selector
683
531
  label="Currency"
684
532
  isLabelHidden
@@ -697,7 +545,8 @@ export default function SettingsDialog() {
697
545
  isExpanded={expandedRow === 'timezone'}
698
546
  onEdit={() => handleEdit('timezone')}
699
547
  onCancel={handleCancel}
700
- onSave={handleSave}>
548
+ onSave={handleSave}
549
+ href={SELF_HASH}>
701
550
  <Selector
702
551
  label="Time zone"
703
552
  isLabelHidden
@@ -717,7 +566,7 @@ export default function SettingsDialog() {
717
566
  <Heading level={3}>Notifications</Heading>
718
567
  <Switch
719
568
  label="Email notifications"
720
- description="Booking updates, reminders, and policy changes."
569
+ description="Booking updates, reminders, and coven decrees."
721
570
  value={emailNotif}
722
571
  onChange={setEmailNotif}
723
572
  labelPosition="start"
@@ -726,7 +575,7 @@ export default function SettingsDialog() {
726
575
  <Divider />
727
576
  <Switch
728
577
  label="Push notifications"
729
- description="Time-sensitive alerts on this device."
578
+ description="Time-sensitive alerts, delivered by raven."
730
579
  value={pushNotif}
731
580
  onChange={setPushNotif}
732
581
  labelPosition="start"
@@ -743,14 +592,16 @@ export default function SettingsDialog() {
743
592
  <Heading level={3}>Payments</Heading>
744
593
  <Divider />
745
594
  <InfoRowItem
746
- label="Payout method"
595
+ label="Payout crypt"
747
596
  value="Visa ending in 4821"
748
597
  action=""
598
+ href={SELF_HASH}
749
599
  />
750
600
  <InfoRowItem
751
- label="Billing history"
752
- value="No invoices yet"
601
+ label="Past payouts"
602
+ value="No tributes yet"
753
603
  action=""
604
+ href={SELF_HASH}
754
605
  />
755
606
  </VStack>
756
607
  </VStack>
@@ -762,14 +613,16 @@ export default function SettingsDialog() {
762
613
  <Heading level={3}>Taxes</Heading>
763
614
  <Divider />
764
615
  <InfoRowItem
765
- label="Tax profile"
616
+ label="Tax scrolls"
766
617
  value="Not submitted"
767
618
  action=""
619
+ href={SELF_HASH}
768
620
  />
769
621
  <InfoRowItem
770
- label="Tax documents"
771
- value="Available after your first payout"
622
+ label="Past scrolls"
623
+ value="Available after your first tribute"
772
624
  action=""
625
+ href={SELF_HASH}
773
626
  />
774
627
  </VStack>
775
628
  </VStack>
@@ -780,8 +633,8 @@ export default function SettingsDialog() {
780
633
  <VStack gap={4}>
781
634
  <Heading level={3}>Travel for work</Heading>
782
635
  <Switch
783
- label="Show work-trip options"
784
- description="Adds a work-trip toggle at checkout."
636
+ label="Show night-errand options at checkout"
637
+ description="Adds a night-errand toggle to your account."
785
638
  value={workTravel}
786
639
  onChange={setWorkTravel}
787
640
  labelPosition="start"
@@ -816,8 +669,8 @@ export default function SettingsDialog() {
816
669
  <VStack gap={4}>
817
670
  <Heading level={3}>Listings</Heading>
818
671
  <Switch
819
- label="Include my listing(s) in search engines"
820
- description="Turning this on means search engines, like Google, will display your listing page(s) in search results."
672
+ label="List my wares in the scrying mirrors"
673
+ description="Turning this on means scrying engines, like Google, will show your wares to seekers."
821
674
  value={searchEngines}
822
675
  onChange={setSearchEngines}
823
676
  labelPosition="start"
@@ -828,13 +681,13 @@ export default function SettingsDialog() {
828
681
 
829
682
  <VStack gap={4}>
830
683
  <Heading level={3}>Reviews</Heading>
831
- <Text type="supporting" color="secondary">
684
+ <Text type="body" color="secondary">
832
685
  Choose what&apos;s shared when you write a review.{' '}
833
686
  <Link href={SELF_HASH}>Learn more</Link>
834
687
  </Text>
835
688
  <VStack gap={4}>
836
689
  <Switch
837
- label="Show my home city and country"
690
+ label="Show my home haunt and country"
838
691
  description="Ex: City and country"
839
692
  value={showCity}
840
693
  onChange={setShowCity}
@@ -842,8 +695,8 @@ export default function SettingsDialog() {
842
695
  labelSpacing="spread"
843
696
  />
844
697
  <Switch
845
- label="Show my trip type"
846
- description="Ex: Stayed with kids or pets"
698
+ label="Show my journey type"
699
+ description="Ex: Rested with kin or familiars"
847
700
  value={showTripType}
848
701
  onChange={setShowTripType}
849
702
  labelPosition="start"
@@ -858,8 +711,8 @@ export default function SettingsDialog() {
858
711
  labelSpacing="spread"
859
712
  />
860
713
  <Switch
861
- label="Show my booked services"
862
- description="Ex: Gourmet brunch or tasting menu"
714
+ label="Show my booked revels"
715
+ description="Ex: Midnight feasts and tasting rituals"
863
716
  value={showServices}
864
717
  onChange={setShowServices}
865
718
  labelPosition="start"
@@ -897,10 +750,10 @@ export default function SettingsDialog() {
897
750
  <Icon icon={ShieldCheck} />
898
751
  </Center>
899
752
  <VStack gap={1}>
900
- <Text type="body" weight="bold">
753
+ <Text type="body">
901
754
  Committed to privacy
902
755
  </Text>
903
- <Text type="supporting" color="secondary">
756
+ <Text type="body" color="secondary">
904
757
  We&apos;re committed to keeping your data
905
758
  protected. See details in our{' '}
906
759
  <Link href={SELF_HASH}>