astryx-dracula 0.2.0 → 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 +22 -11
  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 +67 -32
  31. package/templates/ai-chat.tsx +41 -20
  32. package/templates/blank.tsx +5 -2
  33. package/templates/centered-hero.tsx +15 -124
  34. package/templates/classic-gallery.tsx +21 -65
  35. package/templates/contact-form.tsx +62 -40
  36. package/templates/dashboard-portfolio.tsx +146 -227
  37. package/templates/dashboard.tsx +123 -121
  38. package/templates/detail-page.tsx +101 -95
  39. package/templates/documentation-design.template.mjs +1 -1
  40. package/templates/documentation-design.tsx +85 -96
  41. package/templates/documentation-technical.template.mjs +1 -1
  42. package/templates/documentation-technical.tsx +33 -21
  43. package/templates/documentation.template.mjs +1 -1
  44. package/templates/documentation.tsx +54 -74
  45. package/templates/editor.tsx +119 -89
  46. package/templates/file-explorer.tsx +133 -84
  47. package/templates/form-two-column.tsx +62 -124
  48. package/templates/gallery-hero.tsx +17 -171
  49. package/templates/ide.tsx +27 -21
  50. package/templates/incident-console.tsx +105 -69
  51. package/templates/kanban-board.tsx +100 -41
  52. package/templates/library.template.mjs +2 -2
  53. package/templates/library.tsx +38 -41
  54. package/templates/login-card.tsx +59 -86
  55. package/templates/login-split.tsx +88 -128
  56. package/templates/login-sso.tsx +107 -68
  57. package/templates/login.tsx +108 -52
  58. package/templates/messaging-shell.tsx +172 -143
  59. package/templates/mixed-gallery.tsx +31 -130
  60. package/templates/payment-form.tsx +369 -289
  61. package/templates/product-detail.tsx +40 -57
  62. package/templates/product-gallery.tsx +31 -40
  63. package/templates/product-tour.template.mjs +6 -0
  64. package/templates/product-tour.tsx +916 -0
  65. package/templates/settings-dialog.tsx +145 -286
  66. package/templates/settings-sidebar.tsx +179 -267
  67. package/templates/settings.tsx +42 -13
  68. package/templates/shell-nav.tsx +32 -23
  69. package/templates/shell-side-nav.tsx +30 -19
  70. package/templates/shell-top-nav.tsx +81 -43
  71. package/templates/side-gallery.tsx +39 -93
  72. package/templates/table-grouped.tsx +63 -33
  73. package/templates/table-page-chart.tsx +24 -297
  74. package/templates/table-page-heatmap-status.tsx +157 -91
  75. package/templates/table-page-shoe-store-heatmap.tsx +19 -288
  76. package/templates/table-page.tsx +24 -6
  77. package/templates/table.tsx +24 -7
  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 +313 -249
  82. package/theme.css +76 -14
  83. package/tokens.css +425 -30
@@ -1,4 +1,10 @@
1
1
  // Copyright (c) Meta Platforms, Inc. and affiliates.
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] > 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
+ */
2
8
 
3
9
  import React, {useState, type CSSProperties} from 'react';
4
10
  import {
@@ -20,29 +26,15 @@ import {Card} from '@astryxdesign/core/Card';
20
26
  import {Switch} from '@astryxdesign/core/Switch';
21
27
  import {Link} from '@astryxdesign/core/Link';
22
28
  import {TabList, Tab} from '@astryxdesign/core/TabList';
23
- import {Badge} from '@astryxdesign/core/Badge';
29
+ import {StatusDot} from '@astryxdesign/core/StatusDot';
24
30
  import {Icon} from '@astryxdesign/core/Icon';
25
31
  import {Center} from '@astryxdesign/core/Center';
26
32
  import {useMediaQuery} from '@astryxdesign/core/hooks';
27
- import {
28
- User,
29
- Lock,
30
- Globe,
31
- ShieldCheck,
32
- Monitor,
33
- Bell,
34
- FileText,
35
- CreditCard,
36
- Briefcase,
37
- SquarePen,
38
- Share2,
39
- } from 'lucide-react';
40
-
41
- const iconBox: CSSProperties = {
42
- borderRadius: 'var(--radius-container)',
43
- backgroundColor: 'var(--color-background-surface)',
44
- flexShrink: 0,
45
- };
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
+
46
38
  // Sticky dialog header bar — no Astryx prop for sticky/background/z-index.
47
39
  // Inline + block padding comes from the parent LayoutContent `padding`.
48
40
  const headerSticky: CSSProperties = {
@@ -56,58 +48,13 @@ const headerSticky: CSSProperties = {
56
48
  const contentMaxWidth: CSSProperties = {
57
49
  maxWidth: 680,
58
50
  };
59
- // Aligns the sidebar heading with list-item label text. No heading margin prop.
60
- const sideNavHeading: CSSProperties = {
61
- marginInline: 'var(--spacing-4)',
62
- };
63
51
  const dialogHeight: CSSProperties = {
64
52
  height: '85vh',
65
53
  };
66
- // Keeps row actions ("Log out", "Deactivate") on one line: without this the
67
- // action column wraps mid-phrase at tablet widths while the info column still
68
- // has room to wrap instead.
69
- const actionNoWrap: CSSProperties = {
70
- flexShrink: 0,
71
- whiteSpace: 'nowrap',
72
- };
73
-
74
- const NAV_ITEMS = [
75
- {label: 'Personal information', icon: User},
76
- {label: 'Login & security', icon: Lock},
77
- {label: 'Privacy', icon: ShieldCheck},
78
- {label: 'Notifications', icon: Bell},
79
- {label: 'Taxes', icon: FileText},
80
- {label: 'Payments', icon: CreditCard},
81
- {label: 'Languages & currency', icon: Globe},
82
- {label: 'Travel for work', icon: Briefcase},
83
- ];
84
54
 
85
- const LOGIN_ROWS = [
86
- {label: 'Password', value: 'Not created', action: 'Create'},
87
- ];
88
-
89
- const SOCIAL_ROWS = [
90
- {label: 'Google', value: 'Connected', action: 'Disconnect'},
91
- ];
92
-
93
- const DEVICE_ROWS: {
94
- label: string;
95
- badge?: string;
96
- location: string;
97
- action?: string;
98
- }[] = [
99
- {
100
- label: 'OS X 10.15.7 · Chrome',
101
- badge: 'CURRENT SESSION',
102
- location: 'Brașov, Transylvania · March 30, 2026 at 19:31',
103
- },
104
- {label: 'Session', location: 'August 9, 2023 at 04:19', action: 'Log out'},
105
- {
106
- label: 'OS X 10.15.7 · unknown',
107
- location: 'Whitby, England · April 14, 2023 at 17:47',
108
- action: 'Log out',
109
- },
110
- ];
55
+ // Same-route hash: demo links stay focusable anchors without escaping the
56
+ // template through the hash router (bare "#" would drop back to the home page).
57
+ const SELF_HASH = '#/templates/settings-dialog';
111
58
 
112
59
  const LANGUAGES = [
113
60
  {label: 'English (Canada)', value: 'en-CA'},
@@ -135,84 +82,62 @@ const TIMEZONES = [
135
82
  {label: '(GMT+01:00) London', value: 'GMT+1'},
136
83
  ];
137
84
 
138
- interface ExpandableRowProps {
139
- label: string;
140
- value: string;
141
- children: React.ReactNode;
142
- isExpanded: boolean;
143
- onEdit: () => void;
144
- onCancel: () => void;
145
- 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
+ );
146
102
  }
147
103
 
148
- function ExpandableRow({
149
- label,
150
- value,
151
- children,
152
- isExpanded,
153
- onEdit,
154
- onCancel,
155
- onSave,
156
- }: ExpandableRowProps) {
104
+
105
+ function DeviceRowItem({label, isCurrent, location, action}: DeviceRow) {
157
106
  return (
158
107
  <>
159
- {isExpanded ? (
160
- <VStack gap={4}>
161
- <Text type="body" weight="semibold" display="block">
162
- {label}
163
- </Text>
164
- {children}
165
- <HStack gap={2}>
166
- <Button label="Save" variant="primary" onClick={onSave} />
167
- <Button label="Cancel" variant="ghost" onClick={onCancel} />
168
- </HStack>
169
- </VStack>
170
- ) : (
171
- <HStack hAlign="between" vAlign="start">
108
+ <HStack gap={3} vAlign="start">
109
+ <Icon icon={Monitor} />
110
+ <StackItem size="fill">
172
111
  <VStack gap={0}>
173
- <Text type="body" weight="semibold" display="block">
174
- {label}
175
- </Text>
176
- <Text type="supporting" color="secondary" display="block">
177
- {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}
178
133
  </Text>
179
134
  </VStack>
180
- <Link
181
- href="#/templates/settings-dialog"
182
- onClick={(e: React.MouseEvent) => {
183
- e.preventDefault();
184
- onEdit();
185
- }}>
186
- Edit
135
+ </StackItem>
136
+ {action && (
137
+ <Link href={SELF_HASH} style={actionNoWrap}>
138
+ {action}
187
139
  </Link>
188
- </HStack>
189
- )}
190
- <Divider />
191
- </>
192
- );
193
- }
194
-
195
- function InfoRowItem({
196
- label,
197
- value,
198
- action,
199
- }: {
200
- label: string;
201
- value: string;
202
- action: string;
203
- }) {
204
- return (
205
- <>
206
- <HStack hAlign="between" vAlign="start">
207
- <VStack gap={0}>
208
- <Text type="body" weight="semibold" display="block">
209
- {label}
210
- </Text>
211
- <Text type="supporting" color="secondary" display="block">
212
- {value}
213
- </Text>
214
- </VStack>
215
- {action && <Link>{action}</Link>}
140
+ )}
216
141
  </HStack>
217
142
  <Divider />
218
143
  </>
@@ -258,6 +183,7 @@ export default function SettingsDialog() {
258
183
  return (
259
184
  <>
260
185
  <Layout
186
+ height="auto"
261
187
  content={
262
188
  <LayoutContent padding={0}>
263
189
  <Center height="80vh">
@@ -274,7 +200,9 @@ export default function SettingsDialog() {
274
200
  <Dialog
275
201
  isOpen={isOpen}
276
202
  onOpenChange={open => setIsOpen(open)}
277
- 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))"
278
206
  maxHeight="85vh"
279
207
  padding={0}
280
208
  purpose="form"
@@ -285,9 +213,9 @@ export default function SettingsDialog() {
285
213
  isCompact ? undefined : (
286
214
  <LayoutPanel width={280} hasDivider role="navigation" padding={3}>
287
215
  <VStack gap={4}>
288
- <Heading level={2} style={sideNavHeading}>
216
+ <Text type="label" style={sideNavHeading}>
289
217
  Account settings
290
- </Heading>
218
+ </Text>
291
219
  <List density="spacious">
292
220
  {NAV_ITEMS.map(item => (
293
221
  <ListItem
@@ -345,7 +273,8 @@ export default function SettingsDialog() {
345
273
  isExpanded={expandedRow === 'legalName'}
346
274
  onEdit={() => handleEdit('legalName')}
347
275
  onCancel={handleCancel}
348
- onSave={handleSave}>
276
+ onSave={handleSave}
277
+ href={SELF_HASH}>
349
278
  <TextInput
350
279
  label="Legal name"
351
280
  isLabelHidden
@@ -359,7 +288,8 @@ export default function SettingsDialog() {
359
288
  isExpanded={expandedRow === 'preferredName'}
360
289
  onEdit={() => handleEdit('preferredName')}
361
290
  onCancel={handleCancel}
362
- onSave={handleSave}>
291
+ onSave={handleSave}
292
+ href={SELF_HASH}>
363
293
  <TextInput
364
294
  label="Preferred first name"
365
295
  isLabelHidden
@@ -373,7 +303,8 @@ export default function SettingsDialog() {
373
303
  isExpanded={expandedRow === 'email'}
374
304
  onEdit={() => handleEdit('email')}
375
305
  onCancel={handleCancel}
376
- onSave={handleSave}>
306
+ onSave={handleSave}
307
+ href={SELF_HASH}>
377
308
  <TextInput
378
309
  label="Email address"
379
310
  isLabelHidden
@@ -387,7 +318,8 @@ export default function SettingsDialog() {
387
318
  isExpanded={expandedRow === 'phone'}
388
319
  onEdit={() => handleEdit('phone')}
389
320
  onCancel={handleCancel}
390
- onSave={handleSave}>
321
+ onSave={handleSave}
322
+ href={SELF_HASH}>
391
323
  <TextInput
392
324
  label="Phone number"
393
325
  isLabelHidden
@@ -399,6 +331,7 @@ export default function SettingsDialog() {
399
331
  label="Identity verification"
400
332
  value="Verified"
401
333
  action=""
334
+ href={SELF_HASH}
402
335
  />
403
336
  <ExpandableRow
404
337
  label="Residential address"
@@ -406,7 +339,8 @@ export default function SettingsDialog() {
406
339
  isExpanded={expandedRow === 'address'}
407
340
  onEdit={() => handleEdit('address')}
408
341
  onCancel={handleCancel}
409
- onSave={handleSave}>
342
+ onSave={handleSave}
343
+ href={SELF_HASH}>
410
344
  <TextInput
411
345
  label="Residential address"
412
346
  isLabelHidden
@@ -420,7 +354,8 @@ export default function SettingsDialog() {
420
354
  isExpanded={expandedRow === 'mailingAddress'}
421
355
  onEdit={() => handleEdit('mailingAddress')}
422
356
  onCancel={handleCancel}
423
- onSave={handleSave}>
357
+ onSave={handleSave}
358
+ href={SELF_HASH}>
424
359
  <TextInput
425
360
  label="Mailing address"
426
361
  isLabelHidden
@@ -434,7 +369,8 @@ export default function SettingsDialog() {
434
369
  isExpanded={expandedRow === 'emergencyContact'}
435
370
  onEdit={() => handleEdit('emergencyContact')}
436
371
  onCancel={handleCancel}
437
- onSave={handleSave}>
372
+ onSave={handleSave}
373
+ href={SELF_HASH}>
438
374
  <TextInput
439
375
  label="Emergency contact"
440
376
  isLabelHidden
@@ -446,70 +382,12 @@ export default function SettingsDialog() {
446
382
 
447
383
  <Card padding={4}>
448
384
  <VStack gap={4}>
449
- <HStack gap={3} vAlign="start">
450
- <Center width={48} height={48} style={iconBox}>
451
- <Icon icon={Lock} />
452
- </Center>
453
- <VStack gap={0}>
454
- <Text
455
- type="body"
456
- weight="semibold"
457
- display="block">
458
- Why isn&apos;t my info shown here?
459
- </Text>
460
- <Text
461
- type="supporting"
462
- color="secondary"
463
- display="block">
464
- We&apos;re hiding some account details to
465
- protect your identity.
466
- </Text>
467
- </VStack>
468
- </HStack>
469
- <Divider />
470
- <HStack gap={3} vAlign="start">
471
- <Center width={48} height={48} style={iconBox}>
472
- <Icon icon={SquarePen} />
473
- </Center>
474
- <VStack gap={0}>
475
- <Text
476
- type="body"
477
- weight="semibold"
478
- display="block">
479
- Which details can be edited?
480
- </Text>
481
- <Text
482
- type="supporting"
483
- color="secondary"
484
- display="block">
485
- Contact info and personal details can be edited.
486
- If this info was used to verify your identity,
487
- you&apos;ll need to get verified again the next
488
- time you book—or to continue hosting.
489
- </Text>
490
- </VStack>
491
- </HStack>
492
- <Divider />
493
- <HStack gap={3} vAlign="start">
494
- <Center width={48} height={48} style={iconBox}>
495
- <Icon icon={Share2} />
496
- </Center>
497
- <VStack gap={0}>
498
- <Text
499
- type="body"
500
- weight="semibold"
501
- display="block">
502
- What info is shared with others?
503
- </Text>
504
- <Text
505
- type="supporting"
506
- color="secondary"
507
- display="block">
508
- We only release contact information after a
509
- reservation is confirmed.
510
- </Text>
511
- </VStack>
512
- </HStack>
385
+ {INFO_TILES.map((tile, i) => (
386
+ <React.Fragment key={tile.title}>
387
+ {i > 0 && <Divider />}
388
+ <InfoTile {...tile} />
389
+ </React.Fragment>
390
+ ))}
513
391
  </VStack>
514
392
  </Card>
515
393
  </VStack>
@@ -527,60 +405,34 @@ export default function SettingsDialog() {
527
405
 
528
406
  {activeTab === 'login' && (
529
407
  <VStack gap={8}>
530
- <VStack gap={4}>
408
+ <VStack gap={0}>
531
409
  <Heading level={3}>Login</Heading>
532
410
  <Divider />
533
411
  {LOGIN_ROWS.map(row => (
534
- <InfoRowItem key={row.label} {...row} />
412
+ <InfoRowItem key={row.label} {...row} href={SELF_HASH} />
535
413
  ))}
536
414
  </VStack>
537
415
 
538
- <VStack gap={4}>
416
+ <VStack gap={0}>
539
417
  <Heading level={3}>Social accounts</Heading>
540
418
  <Divider />
541
419
  {SOCIAL_ROWS.map(row => (
542
- <InfoRowItem key={row.label} {...row} />
420
+ <InfoRowItem key={row.label} {...row} href={SELF_HASH} />
543
421
  ))}
544
422
  </VStack>
545
423
 
546
- <VStack gap={4}>
424
+ <VStack gap={0}>
547
425
  <Heading level={3}>Device history</Heading>
548
426
  <Divider />
549
- {DEVICE_ROWS.map((device, i) => (
550
- <React.Fragment key={i}>
551
- <HStack gap={3} vAlign="start">
552
- <Icon icon={Monitor} />
553
- <StackItem size="fill">
554
- <VStack gap={0}>
555
- <HStack gap={2} vAlign="center">
556
- <Text type="body" weight="semibold">
557
- {device.label}
558
- </Text>
559
- {device.badge && (
560
- <Badge label={device.badge} />
561
- )}
562
- </HStack>
563
- <Text
564
- type="supporting"
565
- color="secondary"
566
- display="block"
567
- hasTabularNumbers>
568
- {device.location}
569
- </Text>
570
- </VStack>
571
- </StackItem>
572
- {device.action && (
573
- <Link style={actionNoWrap}>
574
- {device.action}
575
- </Link>
576
- )}
577
- </HStack>
578
- <Divider />
579
- </React.Fragment>
427
+ {DEVICE_ROWS.map(device => (
428
+ <DeviceRowItem
429
+ key={device.location}
430
+ {...device}
431
+ />
580
432
  ))}
581
433
  </VStack>
582
434
 
583
- <VStack gap={4}>
435
+ <VStack gap={0}>
584
436
  <Heading level={3}>Account</Heading>
585
437
  <Divider />
586
438
  <HStack hAlign="between" vAlign="start">
@@ -598,7 +450,7 @@ export default function SettingsDialog() {
598
450
  This action cannot be undone
599
451
  </Text>
600
452
  </VStack>
601
- <Link>Deactivate</Link>
453
+ <Link href={SELF_HASH}>Deactivate</Link>
602
454
  </HStack>
603
455
  <Divider />
604
456
  </VStack>
@@ -612,9 +464,9 @@ export default function SettingsDialog() {
612
464
  <Divider />
613
465
  <Text type="body" color="secondary">
614
466
  Review each request carefully before approving
615
- access. We&apos;ll email your employee or
616
- co-worker a 4-digit code that lets them log into
617
- 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.
618
470
  </Text>
619
471
  </VStack>
620
472
 
@@ -624,13 +476,13 @@ export default function SettingsDialog() {
624
476
  <Icon icon={Lock} />
625
477
  </Center>
626
478
  <VStack gap={1}>
627
- <Text type="body" weight="bold">
628
- Adding devices from people you trust
479
+ <Text type="body">
480
+ Adding devices for your trusted coven
629
481
  </Text>
630
482
  <Text type="body" color="secondary">
631
- When you approve a request, you grant someone
632
- full access to your account. They&apos;ll be
633
- 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
634
486
  on your behalf.
635
487
  </Text>
636
488
  </VStack>
@@ -653,7 +505,8 @@ export default function SettingsDialog() {
653
505
  isExpanded={expandedRow === 'language'}
654
506
  onEdit={() => handleEdit('language')}
655
507
  onCancel={handleCancel}
656
- onSave={handleSave}>
508
+ onSave={handleSave}
509
+ href={SELF_HASH}>
657
510
  <Selector
658
511
  label="Language"
659
512
  isLabelHidden
@@ -672,7 +525,8 @@ export default function SettingsDialog() {
672
525
  isExpanded={expandedRow === 'currency'}
673
526
  onEdit={() => handleEdit('currency')}
674
527
  onCancel={handleCancel}
675
- onSave={handleSave}>
528
+ onSave={handleSave}
529
+ href={SELF_HASH}>
676
530
  <Selector
677
531
  label="Currency"
678
532
  isLabelHidden
@@ -691,7 +545,8 @@ export default function SettingsDialog() {
691
545
  isExpanded={expandedRow === 'timezone'}
692
546
  onEdit={() => handleEdit('timezone')}
693
547
  onCancel={handleCancel}
694
- onSave={handleSave}>
548
+ onSave={handleSave}
549
+ href={SELF_HASH}>
695
550
  <Selector
696
551
  label="Time zone"
697
552
  isLabelHidden
@@ -711,7 +566,7 @@ export default function SettingsDialog() {
711
566
  <Heading level={3}>Notifications</Heading>
712
567
  <Switch
713
568
  label="Email notifications"
714
- description="Booking updates, reminders, and policy changes."
569
+ description="Booking updates, reminders, and coven decrees."
715
570
  value={emailNotif}
716
571
  onChange={setEmailNotif}
717
572
  labelPosition="start"
@@ -720,7 +575,7 @@ export default function SettingsDialog() {
720
575
  <Divider />
721
576
  <Switch
722
577
  label="Push notifications"
723
- description="Time-sensitive alerts on this device."
578
+ description="Time-sensitive alerts, delivered by raven."
724
579
  value={pushNotif}
725
580
  onChange={setPushNotif}
726
581
  labelPosition="start"
@@ -737,14 +592,16 @@ export default function SettingsDialog() {
737
592
  <Heading level={3}>Payments</Heading>
738
593
  <Divider />
739
594
  <InfoRowItem
740
- label="Payout method"
595
+ label="Payout crypt"
741
596
  value="Visa ending in 4821"
742
597
  action=""
598
+ href={SELF_HASH}
743
599
  />
744
600
  <InfoRowItem
745
- label="Billing history"
746
- value="No invoices yet"
601
+ label="Past payouts"
602
+ value="No tributes yet"
747
603
  action=""
604
+ href={SELF_HASH}
748
605
  />
749
606
  </VStack>
750
607
  </VStack>
@@ -756,14 +613,16 @@ export default function SettingsDialog() {
756
613
  <Heading level={3}>Taxes</Heading>
757
614
  <Divider />
758
615
  <InfoRowItem
759
- label="Tax profile"
616
+ label="Tax scrolls"
760
617
  value="Not submitted"
761
618
  action=""
619
+ href={SELF_HASH}
762
620
  />
763
621
  <InfoRowItem
764
- label="Tax documents"
765
- value="Available after your first payout"
622
+ label="Past scrolls"
623
+ value="Available after your first tribute"
766
624
  action=""
625
+ href={SELF_HASH}
767
626
  />
768
627
  </VStack>
769
628
  </VStack>
@@ -774,8 +633,8 @@ export default function SettingsDialog() {
774
633
  <VStack gap={4}>
775
634
  <Heading level={3}>Travel for work</Heading>
776
635
  <Switch
777
- label="Show work-trip options"
778
- 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."
779
638
  value={workTravel}
780
639
  onChange={setWorkTravel}
781
640
  labelPosition="start"
@@ -802,7 +661,7 @@ export default function SettingsDialog() {
802
661
  <Text type="body" weight="semibold">
803
662
  Blocked people
804
663
  </Text>
805
- <Link>View</Link>
664
+ <Link href={SELF_HASH}>View</Link>
806
665
  </HStack>
807
666
  <Divider />
808
667
  </VStack>
@@ -810,8 +669,8 @@ export default function SettingsDialog() {
810
669
  <VStack gap={4}>
811
670
  <Heading level={3}>Listings</Heading>
812
671
  <Switch
813
- label="Include my listing(s) in search engines"
814
- 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."
815
674
  value={searchEngines}
816
675
  onChange={setSearchEngines}
817
676
  labelPosition="start"
@@ -822,13 +681,13 @@ export default function SettingsDialog() {
822
681
 
823
682
  <VStack gap={4}>
824
683
  <Heading level={3}>Reviews</Heading>
825
- <Text type="supporting" color="secondary">
684
+ <Text type="body" color="secondary">
826
685
  Choose what&apos;s shared when you write a review.{' '}
827
- <Link type="supporting">Learn more</Link>
686
+ <Link href={SELF_HASH}>Learn more</Link>
828
687
  </Text>
829
688
  <VStack gap={4}>
830
689
  <Switch
831
- label="Show my home city and country"
690
+ label="Show my home haunt and country"
832
691
  description="Ex: City and country"
833
692
  value={showCity}
834
693
  onChange={setShowCity}
@@ -836,8 +695,8 @@ export default function SettingsDialog() {
836
695
  labelSpacing="spread"
837
696
  />
838
697
  <Switch
839
- label="Show my trip type"
840
- description="Ex: Stayed with kids or pets"
698
+ label="Show my journey type"
699
+ description="Ex: Rested with kin or familiars"
841
700
  value={showTripType}
842
701
  onChange={setShowTripType}
843
702
  labelPosition="start"
@@ -852,8 +711,8 @@ export default function SettingsDialog() {
852
711
  labelSpacing="spread"
853
712
  />
854
713
  <Switch
855
- label="Show my booked services"
856
- description="Ex: Gourmet brunch or tasting menu"
714
+ label="Show my booked revels"
715
+ description="Ex: Midnight feasts and tasting rituals"
857
716
  value={showServices}
858
717
  onChange={setShowServices}
859
718
  labelPosition="start"
@@ -868,7 +727,7 @@ export default function SettingsDialog() {
868
727
  <Card>
869
728
  <HStack hAlign="between" vAlign="center">
870
729
  <Text type="body">Request my personal data</Text>
871
- <Link>Request</Link>
730
+ <Link href={SELF_HASH}>Request</Link>
872
731
  </HStack>
873
732
  </Card>
874
733
  <Switch
@@ -882,7 +741,7 @@ export default function SettingsDialog() {
882
741
  <Card>
883
742
  <HStack hAlign="between" vAlign="center">
884
743
  <Text type="body">Delete my account</Text>
885
- <Link>Delete</Link>
744
+ <Link href={SELF_HASH}>Delete</Link>
886
745
  </HStack>
887
746
  </Card>
888
747
  <Card variant="muted">
@@ -891,13 +750,13 @@ export default function SettingsDialog() {
891
750
  <Icon icon={ShieldCheck} />
892
751
  </Center>
893
752
  <VStack gap={1}>
894
- <Text type="body" weight="bold">
753
+ <Text type="body">
895
754
  Committed to privacy
896
755
  </Text>
897
- <Text type="supporting" color="secondary">
756
+ <Text type="body" color="secondary">
898
757
  We&apos;re committed to keeping your data
899
758
  protected. See details in our{' '}
900
- <Link type="supporting">
759
+ <Link href={SELF_HASH}>
901
760
  Privacy Policy
902
761
  </Link>
903
762
  .