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
package/BRAND.md CHANGED
@@ -8,30 +8,40 @@ Source of truth is `astryx-theme.ts`. Do not add hexes; `bun run audit` enforces
8
8
  | Role | Hex | Use |
9
9
  |---|---|---|
10
10
  | Background | #282A36 | page bg |
11
- | Current line | #6272A4 | line highlight, subtle borders (doubles as comment) |
11
+ | Current line | #6272A4 | line highlight, subtle borders (doubles as comment)[^current-line] |
12
12
  | Selection | #44475A | selected rows, quiet surfaces |
13
13
  | Background Light | #343746 | cards, surfaces |
14
14
  | Background Lighter | #424450 | popovers, floating elements |
15
- | Background Dark | #21222C | shadows |
15
+ | Background Dark | #21222C | shadows, on-fill text |
16
+ | Darker | #191A21 | shadow washes only (never a surface: `--shadow-*` alpha blends) |
16
17
  | Foreground | #F8F8F2 | primary text on dark |
17
- | Comment | #6272A4 | disabled / muted text |
18
+ | Comment | #6272A4 | subtle borders, empty cells, disabled text[^comment] |
18
19
  | Cyan | #8BE9FD | info, secondary links |
19
20
  | Green | #50FA7B | positive, success |
20
- | Orange | #FFB86C | warning, attention |
21
+ | Orange | #FFB86C | attention, constants (never warning) |
21
22
  | Pink | #FF79C6 | flair, accent |
22
23
  | Purple | #BD93F9 | primary, links and titles unvisited |
23
24
  | Red | #FF5555 | negative, error |
24
- | Yellow | #F1FA8C | tags, chips |
25
+ | Yellow | #F1FA8C | tags, chips, warning states |
26
+ | Inverted error | #FFD5CC | pale surface for the inverted error Toast (not a spec hex) |
27
+
28
+ [^comment]: Comment sits **between** the two WCAG floors on the scene backdrop `#21222C`: 3.36:1 clears 1.4.11's **graphical** floor and fails the **text** floor, and any `fillOpacity` below 0.9 is worse (0.85 → 2.81). So Comment is correct on an empty cell or a subtle grid line and **never** on a `<text fill>`. Scene text uses `--color-text-paragraph` (7.59:1). Do not "improve" an empty cell to `--color-separator`: its ceiling on `#21222C` is 1.73:1 at full opacity and 1.32:1 at 0.55, and a grid whose empty cells have vanished is not a grid.
29
+
30
+ [^current-line]: Upstream pins both Current Line and Comment to #6272A4. This kit follows suit for line affordances, including scrollbar thumbs in `tokens.css`. Do not "correct" one of them to #44475A.
25
31
 
26
32
  ## Semantic map (glimpse)
27
33
 
28
34
  - Purple links/titles unvisited. Visited falls back to text-base, hover goes primary + underline. Users learn purple means tappable title.
29
- - Green positive and success. Red negative and error. Yellow tags and chips. Cyan info and secondary links. Pink flair. Orange warning.
30
- - Subdue #4C5067 for metadata and separators. Not a Dracula hex; derived from glimpse ramp for text-on-dark hierarchy.
35
+ - Green positive and success. Red negative and error. Yellow tags, chips, and warning states (`--color-warning` ships Yellow; Orange never carries warning). Cyan info and secondary links. Pink flair. Orange attention and constants.
36
+ - Subdue #4C5067 for separators and hairline chrome, never text (1.8:1 on the page background, 1.5:1 on cards). Not a Dracula hex; derived from the glimpse ramp for chrome hierarchy.
37
+
38
+ ## Borders
39
+
40
+ `--color-border` is Comment `#6272A4`. `--color-border-emphasized` is **`#9AA1BC`**, repinned from Comment: core tone-bumps that token to ≥3:1 for form-control boundaries, but `pin()` returns a literal so that guarantee is inert here, and the old value cleared *no* surface tier at 3:1 while the new one clears all four (5.56 / 4.60 / 3.77 / 3.57). `DropdownMenuRadioItem` reads it on a popover, so the popover tier is a real consumer. Known shortfall: the inverted surface at 2.40, which has no live consumer — recorded, not certified.
31
41
 
32
42
  ## Charts
33
43
 
34
- Categorical series use nearest Dracula hues: blue goes comment, orange orange, purple purple,
44
+ A chart mark takes a `--color-data-*` **role token**, never a `--dracula-*` primitive, and the types enforce it — widening `ChartLegendEntry.color` and `DataBarSegment.color` from `string` to template-literal unions caught ten real violations at compile time, including eight demo bars painting `--color-success` on a data mark. Categorical series use nearest Dracula hues: blue goes comment, orange orange, purple purple (compat token only — purple means tappable, never encode data; the ban is a **module rule** enforced by `chart-hues.ts`, not token absence),
35
45
  green green, pink pink, cyan cyan, red red. Teal uses ANSI bright cyan #A4FFFF and indigo
36
46
  ANSI bright blue #D6ACFF; brown has no spectral match and reuses orange. Sequential ramps cover 9 families (purple, pink, red,
37
47
  orange, yellow, teal, blue, shamrock, gray) with 5 lightness steps each (28/44/60/74/88),
@@ -39,8 +49,8 @@ constant hue and saturation per family.
39
49
 
40
50
  ## Code highlighting
41
51
 
42
- Custom spec-exact syntax theme (`draculaSyntax` in `astryx-theme.ts`, stricter than the bundled preset):
43
- pink keywords, yellow strings, comment gray comments, orange numbers, green functions, cyan types.
52
+ Syntax theme (`draculaSyntax` in `astryx-theme.ts`, 14 slots per the spec Token Classification):
53
+ pink keywords/operators/tags, yellow strings, comment-gray comments, orange numbers, green functions and attributes, cyan types, purple constants, foreground variables/properties/punctuation, Background canvas. Regexps get no split (core's tokenizer emits no regexp scope); attributes/tags follow the official Dracula editors and the core `dracula` preset, not the Support bucket's Cyan.
44
54
 
45
55
  ## Status surfaces
46
56
 
@@ -49,13 +59,14 @@ Each status scope redefines its muted token to the categorical tint
49
59
  (`--color-background-<hue>`, 10% accent wash) with a semantic accent border.
50
60
  Text on fills is always `#21222C`; spec never uses raw black. Links render accent
51
61
  with underline and resolve to foreground on hover. Focus and interactive edges
52
- use Functional Purple `#815CD6`.
62
+ use accent, not Functional Purple: `--color-functional-*` is pinned for spec parity
63
+ (token compat — never encode status in these) and no shipped component consumes it.
53
64
 
54
65
  ## Interactions
55
66
 
56
67
  Buttons darken on hover; destructive pairs red fill with dark text. Links render accent
57
68
  underlined and resolve to foreground on hover. Focus rings use accent, not Functional
58
- Purple: 5.9 contrast beats 3.5 on dark backgrounds, verified by keyboard screenshot.
69
+ Purple: 5.9 contrast beats 3.0 on dark backgrounds, verified by keyboard screenshot.
59
70
  Inputs take accent and error rings from core; table rows lift on hover. Cards, banners,
60
71
  badges, and progress bars are static.
61
72
 
@@ -65,13 +76,14 @@ Radii flat and crisp (5px elements, 4px inner). Everything below is a core defau
65
76
 
66
77
  - Motion durations: neutral defaults (fast 175ms, medium 410ms).
67
78
  - Spacing/size/ease scales: core defaults. Shadows, radii, and surfaces are Dracula-hued tokens above.
68
- - Zero theme dependencies: icons vendored (Lucide), everything else defined here.
69
- - Derived AA lifts (not spec hexes, same hues): secondary text #9AA1BC, muted text #8288A6, paragraph #B0B3C4, subdue #4C5067.
70
- - Icon glyphs vendored from Lucide in `icons.tsx` (MIT). The theme also sets icon colors (primary, secondary, disabled, accent).
71
- - onDark: generated defaults inherited. Dark-surface content resolves from the same ramp.
72
- - `--color-data-neutral`: default gray reads fine on dark.
79
+ - One runtime dependency: `lucide-react` (icons render from it at runtime, both the theme `draculaIconRegistry` in `icons.tsx` and every template's direct imports — `bun run audit` fails when a registered glyph stops resolving to a real export). Everything else is defined here.
80
+ - Derived AA lifts (not spec hexes, same hues): secondary text #9AA1BC, muted text #8288A6, paragraph #B0B3C4. Subdue #4C5067 is chrome, below every text floor.
81
+ - Icon glyphs from Lucide in `icons.tsx` (MIT). The theme also sets icon colors (primary, secondary, disabled, accent).
82
+ - onDark: `--color-on-dark` is repinned to spec Foreground `#F8F8F2` — the spec has **no pure white**, so a `#FFFFFF` here is off-palette. The pair is **deliberately asymmetric** and should not be "fixed" into symmetry: on-dark = spec Foreground `#F8F8F2`, on-light = spec black `#000000`. `--color-tint-hover` is **`#FFFFFF` and ruled correct — do not repaint.** It looks like a second pure white next to the line above, and it is not: core only ever reads it as a `color-mix` **partner** at 5–20% (`CheckboxInput.tsx:115-138`, `Slider.tsx:252`), never as a paint, and it is core's own dark value (`tokens.stylex.ts:81`, `light-dark(black, white)`). Retinting it to a Dracula grey would silently change every mix core builds and break the only thing it is for. `#FFFFFF` is not on-palette; the *token* is.
83
+ - `--color-data-neutral`: `#8C939B`, **inherited from core** (core declares `light-dark(#8494A3, #8C939B)` in `core/src/theme/domainTokens/dataTokens.ts`) and off-palette — neither a Dracula hex nor on our gray ramp, whose L60 computes to `#8A8EA8`. It stays because it reads fine on dark. The "Stone" label in an earlier line here was never an Astryx brand name: `grep -ril stone node_modules/@astryxdesign/` hits only a separate `@astryxdesign/theme-stone` package, not this value. **Open question, deliberately not answered:** the value is off-palette and we could ship a gray ramp step instead — but it is core's own default, and diverging from core on a data role buys brand purity at the cost of surprising anyone who ports a core chart. That trade is the human's.
84
+ - Tag accents: `--color-tag-<orange|pink|cyan|yellow|green|purple>`. The purple tag was **renamed from `blue`** — it always held `#BD93F9` (spec Purple) and never a blue. Dracula has no blue, so the value was right and the name was the lie. Historical trap for anyone who greps: `blue` is also the name of six *other* tokens that genuinely are Comment (`--color-background-blue`, `-border-`, `-icon-`, `-text-`, `--color-data-categorical-blue`, `--color-data-blue-1..5`), so a repo-wide find/replace on "blue" would silently repoint all six at Purple. A name that contradicts its own value is invisible to every contrast gate, which is why this needed a ruling rather than a threshold.
73
85
  - No color-scale config: HCT generation would fight the pinned hexes. No light mode, ever.
74
86
 
75
87
  ## Dims
76
88
 
77
- Gap 24px, viewport 16px, content 15px vertical / 16px horizontal, widget-gap 24px, tile-row 96px, radius 5px everywhere, JetBrains Mono, type scale base 14 ratio 1.2: h1 24 / h2 20 / h3 17 / h4 14 / body 14 / supporting 12 / h6 10. Outer Card padding 4, nested inset 3. Touch targets 24px floor, 44 where touch matters.
89
+ Gap 24px, viewport 16px, content 15px vertical / 16px horizontal, widget-gap 24px, tile-row 96px, radius 5px everywhere, JetBrains Mono, type scale base 14 ratio 1.2, generated steps 12 / 14 / 17 / 20 / 24. The pinned heading tokens are compat dims, not a strict 1.2 ladder: h1 24 / h2 20 / h3 16 / h4 14 / h5 13 / h6 12, body 14, supporting 12. Astryx `Heading` sizes come from the scale roles instead, so level 3 renders the 17px `lg` step. Outer Card padding 4, nested inset 3. Touch targets 24px floor, 44 where touch matters.
package/README.md CHANGED
@@ -10,13 +10,13 @@ Live showcase: https://yuzu-octopus.github.io/astryx-dracula/
10
10
 
11
11
  ## Features
12
12
 
13
- - 270+ tokens pinned to the official Dracula specification, dark-only
14
- - Spec-exact code syntax theme plus chart series and sequential ramps
15
- - Prebuilt CSS with zero runtime cost, or runtime injection for prototyping
13
+ - Dracula tokens pinned in `astryx-theme.ts` (`grep -c "pin(" astryx-theme.ts` pins) (191 public props in the prebuilt `theme.css`, plus 3 private `--_*-radius` aliases; `tokens.css` is a full plain-CSS mirror, `grep -c "^ --" tokens.css` vars), dark-only. No gate asserts these counts — `bun run theme:check` asserts freshness, `bun run audit` asserts palette purity and contrast.
14
+ - Syntax theme plus chart series and sequential ramps
15
+ - Prebuilt CSS plus runtime theme injection, or runtime injection alone for prototyping
16
16
  - WCAG contrast gates enforced in CI via `bun run audit`
17
- - Vendored JetBrains Mono fonts and Lucide icons, zero theme dependencies
17
+ - JetBrains Mono fonts and Lucide icons, one runtime dependency (`lucide-react`)
18
18
  - Agent skill, `llms.txt`, and copy-paste quickstart for AI-assisted adoption
19
- - 43 themed pages in `templates/`, published as an Astryx integration pack and viewable live at `/astryx-dracula/#/templates`
19
+ - Around 45 themed pages in `templates/`, published as an Astryx integration pack and viewable live at `/astryx-dracula/#/templates`
20
20
 
21
21
  ## Installation
22
22
 
@@ -27,9 +27,12 @@ bun add astryx-dracula
27
27
  ## Usage
28
28
 
29
29
  ```tsx
30
+ import '@astryxdesign/core/reset.css';
31
+ import '@astryxdesign/core/astryx.css';
32
+ import 'astryx-dracula/tokens.css';
33
+ import 'astryx-dracula/theme.css';
30
34
  import { Theme } from '@astryxdesign/core/theme';
31
35
  import { astryxDraculaTheme } from 'astryx-dracula';
32
- import 'astryx-dracula/theme.css';
33
36
 
34
37
  <Theme theme={astryxDraculaTheme} mode="dark">
35
38
  <App />
@@ -39,18 +42,19 @@ import 'astryx-dracula/theme.css';
39
42
  Copy `fonts/` from the package into your served `public/fonts/` directory.
40
43
 
41
44
  > [!NOTE]
42
- > For the plain-CSS path, migrating an existing codebase, and the full token reference, see [USAGE.md](USAGE.md) and [BRAND.md](BRAND.md). AI agents should start with the skill in `.agents/skills/astryx-dracula/SKILL.md`.
45
+ > For the plain-CSS path, migrating an existing codebase, and the full token reference, see [USAGE.md](USAGE.md) and [BRAND.md](BRAND.md). AI agents should start with the skill in `.agents/skills/astryx-dracula/SKILL.md` (agent index: [AGENTS.snippet.md](AGENTS.snippet.md)).
43
46
 
44
47
  ## Project layout
45
48
 
46
49
  ```text
47
50
  astryx-theme.ts defineTheme source, single source of truth
48
51
  theme.css prebuilt output of bun run theme:build
49
- tokens.css plain-CSS :root fallback for any stack
50
- icons.tsx vendored Lucide icon registry
52
+ tokens.css plain-CSS :root mirror for any stack
53
+ icons.tsx Lucide icon registry (runtime `lucide-react` dependency)
51
54
  fonts/ JetBrains Mono woff2 files
52
- templates/ 43 themed pages plus integration specs
53
- scripts/check.ts palette plus contrast gates
55
+ templates/ around 45 themed pages plus integration specs
56
+ shared/ reusable modules templates compose (23 files)
57
+ scripts/check.ts palette, contrast, and packaging gates
54
58
  demo/ showcase source, deployed to GitHub Pages
55
59
  ```
56
60
 
@@ -62,9 +66,10 @@ demo/ showcase source, deployed to GitHub Pages
62
66
  | `bun run theme:build`| Rebuild `theme.css` from the source |
63
67
  | `bun run theme:check`| Fail if committed theme outputs are stale |
64
68
  | `bun run build` | Typecheck plus showcase build |
69
+ | `bunx react-doctor@latest` | Component health scan (currently 100/100) |
65
70
 
66
71
  ## Attribution & License
67
72
 
68
- - **Astryx Design System**: Created by the Astryx team at Meta Platforms, Inc. under the [MIT License](https://github.com/facebook/astryx/blob/main/LICENSE). The 43 template files in `templates/` are derived from Astryx's open source page templates and adapted for the Dracula brand (pure Dracula spec retokening, recharts replaced with zero-dependency inline SVGs, heroicons mapped to Lucide, XLE/XLO structural expression headers, and responsive layout hardening).
73
+ - **Astryx Design System**: Created by the Astryx team at Meta Platforms, Inc. under the [MIT License](https://github.com/facebook/astryx/blob/main/LICENSE). The template files in `templates/` (around 45) are derived from Astryx's open source page templates and adapted for the Dracula brand (pure Dracula spec retokening, recharts replaced with zero-dependency inline SVGs, heroicons mapped to Lucide, XLE/XLO structural expression headers, and responsive layout hardening).
69
74
  - **Dracula Theme**: Color palette and specification by [Zeno Rocha and the Dracula Theme community](https://draculatheme.com).
70
75
  - **Package & Additions**: Released under the [MIT License](LICENSE).
package/USAGE.md CHANGED
@@ -14,7 +14,7 @@ Or clone `https://github.com/yuzu-octopus/astryx-dracula.git` and copy
14
14
 
15
15
  ## Prebuilt (recommended for Astryx apps)
16
16
 
17
- Zero runtime cost. Built with `bun run theme:build` from `astryx-theme.ts`.
17
+ Prebuilt CSS plus runtime theme injection (the CSS carries the paint, the `<Theme>` object carries the tokens). Built with `bun run theme:build` from `astryx-theme.ts`.
18
18
 
19
19
  ```tsx
20
20
  import '@astryxdesign/core/reset.css';
@@ -62,7 +62,7 @@ import '../tokens.css';
62
62
  ```
63
63
 
64
64
  Then use `var(--color-primary)`, `var(--dracula-purple)`, `var(--space-gap)`.
65
- `tokens.css` sets real `:root` values with `color-scheme: dark`, so first paint is correct with no runtime.
65
+ `tokens.css` sets real `:root` values with `color-scheme: dark`, so first paint is correct with no runtime. It is a full plain-CSS mirror of the theme (`grep -c "^ --" tokens.css` `:root` vars, unlayered by design so it beats core layers with zero `!important`); edit the theme, not this file, then re-mirror.
66
66
 
67
67
  ## Migrating an existing site
68
68
 
@@ -73,7 +73,7 @@ Then use `var(--color-primary)`, `var(--dracula-purple)`, `var(--space-gap)`.
73
73
 
74
74
  ## Templates
75
75
 
76
- 43 themed pages ship in `templates/`, each with a `<id>.template.mjs` spec, published
76
+ Around 45 themed pages ship in `templates/`, each with a `<id>.template.mjs` spec, published
77
77
  as an Astryx integration pack (`astryx.integration.mjs`). List this package in your
78
78
  `astryx.config`, then scaffold any of them:
79
79
 
@@ -81,15 +81,17 @@ as an Astryx integration pack (`astryx.integration.mjs`). List this package in y
81
81
  bunx astryx template dashboard --package astryx-dracula
82
82
  ```
83
83
 
84
- View all 43 live at `/astryx-dracula/#/templates` on the showcase. Pack rules: templates
85
- import React plus `@astryxdesign/core` only.
84
+ View them all live at `/astryx-dracula/#/templates` on the showcase (agent index: [AGENTS.snippet.md](AGENTS.snippet.md)). Pack rules: templates
85
+ import `@astryxdesign/core`, `lucide-react`, and the kit's own shared modules (`astryx-dracula/shared/*`: auth-copy, auth-chrome-config, chaptered-doc, chaptered-doc-config, chart-hues, chart-labels, chart-panel-style, gallery-image, login-demo, metric-delta, revenue-chart, scene-castle, scene-hues, scene-tile, settings-data, settings-rows, sparkline, sso-icons), no chart libraries.
86
86
 
87
87
  ## Fonts
88
88
 
89
89
  Copy `fonts/` to your app's served static dir (Vite: `public/fonts/`).
90
90
  `tokens.css` declares the `@font-face` blocks; the theme sets JetBrains Mono
91
- for body, heading, and code roles. Without the files, text falls back to
92
- `monospace` — `bun run audit` fails when they are missing here.
91
+ for body, heading, and code roles. The shipped URLs are base-scoped
92
+ (`/astryx-dracula/fonts/*.woff2`, matching this repo's demo `base`) — apps
93
+ served from `/` remap or self-host the files at that path, otherwise text
94
+ falls back to `monospace`. `bun run audit` fails when the files are missing here. Only the package root `fonts/` ships them: a subpath import resolves nothing, so a fallback after copying means the copy step missed the expected path.
93
95
 
94
96
  ## Consumer Vite config
95
97
 
@@ -97,7 +99,9 @@ No special config needed. This kit follows the glimpse path: prebuilt
97
99
  `@astryxdesign/core` CSS plus `<Theme>` injection. A stock Vite React
98
100
  config works. The only recommended extra is the CSS layer-order snippet so
99
101
  theme overrides beat component base styles (our repo `vite.config.ts` also
100
- sets a demo-only `base` path; do not copy that):
102
+ sets a demo-only `base` path; do not copy that). Tailwind projects keep their
103
+ own setup and add the snippet as a plain `<style>` tag in `index.html` — the
104
+ layer names are the contract, not the Vite plugin:
101
105
 
102
106
  ```ts
103
107
  // vite.config.ts
@@ -113,7 +117,7 @@ export default defineConfig({
113
117
  {
114
118
  tag: 'style',
115
119
  children:
116
- '@layer reset, priority1, priority2, priority3, priority4, priority5, priority6, priority7, priority8, priority9, astryx-theme;',
120
+ '@layer reset, astryx-base, astryx-theme;',
117
121
  injectTo: 'head-prepend',
118
122
  },
119
123
  ];
@@ -132,7 +136,7 @@ README. Not required for this kit.
132
136
 
133
137
  - Unstyled components: entry is missing `reset.css`/`astryx.css` or the import order is wrong.
134
138
  - Monospace fallback: `fonts/` not copied to served `public/fonts/`.
135
- - Wrong colors after a theme edit: rebuild with `bun run theme:build`; `bun run theme:check` confirms staleness.
139
+ - Wrong colors after a theme edit: rebuild with `bun run theme:build`; `bun run theme:check` confirms staleness (it ignores `astryx-dracula.js` by design — that file is a build artifact, not a freshness signal).
136
140
  - Old `:root` `--color-*` overrides winning: delete them.
137
141
 
138
142
  ## Rules
@@ -141,3 +145,18 @@ README. Not required for this kit.
141
145
  - Never override `--color-*` in app `:root`. Brand changes live in `astryx-theme.ts` via `defineTheme`, then `bun run theme:build`.
142
146
  - Tokens for every value: `var(--color-*|--space-*|--radius-*)`. No raw hex or px in components.
143
147
  - Component styling: props first, then theme `components` overrides in `astryx-theme.ts`. No per-app CSS wars.
148
+ - A chart mark takes a `--color-data-*` role token, never a `--dracula-*` primitive. The `chart-hues` / `chart-legend` / `data-bar` types reject anything else at compile time.
149
+ - `--dracula-comment` is legal on a **graphical** mark (3.36:1 clears WCAG 1.4.11) and illegal on **text** (fails 4.5:1). Any `fillOpacity` under 0.9 makes it worse. Text in a scene uses `--color-text-paragraph`.
150
+ - A `Layout height="fill"` needs `style={{height: '100dvh'}}` or it silently degrades to document scroll. `minHeight: '100%'` computes to 0 against an indefinite parent, so it is a no-op.
151
+ - Derive any count a page prints from its data. Hardcoded numerals are how `documentation.tsx` came to say "twenty-eight components" over 31 entries.
152
+ - A `.tsx` exports components only; shared data lives in a sibling `.ts`, so React Fast Refresh works.
153
+
154
+ ## Release checklist
155
+
156
+ Before tagging a release:
157
+
158
+ 1. Pin versions: `@astryxdesign/core` / `@astryxdesign/cli` in `package.json` match the showcase and CI.
159
+ 2. Nothing to refresh by hand: the version badges in `templates/product-tour.tsx` + `templates/centered-hero.tsx` (rendered text *and* XLE header) are gated against `package.json` by `bun run audit`, so bump the version and the audit tells you if you missed one.
160
+ 3. Rebuild and gate: `bun run theme:build`, then `bun run theme:check`, then `bun run audit`, then `bunx react-doctor@latest` (must stay 100/100).
161
+ 4. Counts in the docs are cited with the command that produces them, so there is nothing to refresh by hand. If you find a bare numeral, replace it with its command.
162
+ 5. `npm publish` runs the same four gates itself via `prepublishOnly`, so a tree that fails cannot reach the registry. There is no publish workflow in CI — publishing is deliberately a human step.
package/astryx-dracula.js CHANGED
@@ -55,7 +55,7 @@ export const astryxDraculaTheme = {
55
55
  "--text-large-weight": "var(--font-weight-semibold)",
56
56
  "--text-large-leading": "1.4118",
57
57
  "--text-label-size": "var(--font-size-base)",
58
- "--text-label-weight": "var(--font-weight-medium)",
58
+ "--text-label-weight": "var(--font-weight-semibold)",
59
59
  "--text-label-leading": "1.4286",
60
60
  "--text-code-size": "var(--font-size-base)",
61
61
  "--text-code-weight": "var(--font-weight-normal)",
@@ -92,16 +92,18 @@ export const astryxDraculaTheme = {
92
92
  "--color-syntax-type": "#8BE9FD",
93
93
  "--color-syntax-variable": "#F8F8F2",
94
94
  "--color-syntax-operator": "#FF79C6",
95
- "--color-syntax-constant": "#FFB86C",
95
+ "--color-syntax-constant": "#BD93F9",
96
96
  "--color-syntax-tag": "#FF79C6",
97
- "--color-syntax-attribute": "#F1FA8C",
98
- "--color-syntax-property": "#8BE9FD",
97
+ "--color-syntax-attribute": "#50FA7B",
98
+ "--color-syntax-property": "#F8F8F2",
99
99
  "--color-syntax-punctuation": "#F8F8F2",
100
100
  "--color-syntax-background": "#282A36",
101
101
  "--radius-inner": "4px",
102
102
  "--radius-element": "5px",
103
103
  "--radius-container": "5px",
104
104
  "--radius-page": "5px",
105
+ "--radius-chat": "5px",
106
+ "--font-family-mono": "'JetBrains Mono', monospace",
105
107
  "--font-size-h1": "24px",
106
108
  "--font-size-h2": "20px",
107
109
  "--font-size-h3": "16px",
@@ -112,12 +114,17 @@ export const astryxDraculaTheme = {
112
114
  "--shadow-med": "0 2px 4px #191A210D, 0 4px 12px #191A211A",
113
115
  "--shadow-high": "0 4px 6px #191A211A, 0 12px 24px #191A2126",
114
116
  "--shadow-inset-hover": "inset 0px 0px 0px 2px #6272A430",
117
+ "--shadow-inset-selected": "inset 0px 0px 0px 2px #BD93F930",
115
118
  "--shadow-inset-success": "inset 0px 0px 0px 2px #50FA7B30",
116
119
  "--shadow-inset-warning": "inset 0px 0px 0px 2px #F1FA8C30",
117
120
  "--shadow-inset-error": "inset 0px 0px 0px 2px #FF555530",
118
121
  "--color-neutral": "light-dark(#F8F8F21A, #F8F8F21A)",
119
122
  "--color-background-inverted": "light-dark(#F8F8F2, #F8F8F2)",
120
123
  "--color-background-error-inverted": "light-dark(#FFD5CC, #FFD5CC)",
124
+ "--color-tint-hover": "light-dark(#FFFFFF, #FFFFFF)",
125
+ "--color-on-dark": "light-dark(#F8F8F2, #F8F8F2)",
126
+ "--color-on-light": "light-dark(#000000, #000000)",
127
+ "--color-shadow": "light-dark(#21222C, #21222C)",
121
128
  "--color-accent-muted": "var(--color-background-purple)",
122
129
  "--color-success-muted": "var(--color-background-green)",
123
130
  "--color-warning-muted": "var(--color-background-yellow)",
@@ -139,7 +146,7 @@ export const astryxDraculaTheme = {
139
146
  "--color-overlay-hover": "light-dark(#0000001F, #0000001F)",
140
147
  "--color-overlay-pressed": "light-dark(#00000033, #00000033)",
141
148
  "--color-border": "light-dark(#6272A4, #6272A4)",
142
- "--color-border-emphasized": "light-dark(#6272A4, #6272A4)",
149
+ "--color-border-emphasized": "light-dark(#9AA1BC, #9AA1BC)",
143
150
  "--color-accent": "light-dark(#BD93F9, #BD93F9)",
144
151
  "--color-success": "light-dark(#50FA7B, #50FA7B)",
145
152
  "--color-error": "light-dark(#FF5555, #FF5555)",
@@ -158,6 +165,7 @@ export const astryxDraculaTheme = {
158
165
  "--color-on-warning": "light-dark(#21222C, #21222C)",
159
166
  "--color-on-error": "light-dark(#21222C, #21222C)",
160
167
  "--color-on-info": "light-dark(#21222C, #21222C)",
168
+ "--color-data-neutral": "light-dark(#8C939B, #8C939B)",
161
169
  "--color-track": "light-dark(#6272A4, #6272A4)",
162
170
  "--color-skeleton": "light-dark(#6272A4, #6272A4)",
163
171
  "--color-functional-red": "light-dark(#DE5735, #DE5735)",
@@ -167,13 +175,11 @@ export const astryxDraculaTheme = {
167
175
  "--color-functional-purple": "light-dark(#815CD6, #815CD6)",
168
176
  "--color-data-categorical-blue": "light-dark(#6272A4, #6272A4)",
169
177
  "--color-data-categorical-orange": "light-dark(#FFB86C, #FFB86C)",
170
- "--color-data-categorical-purple": "light-dark(#BD93F9, #BD93F9)",
171
178
  "--color-data-categorical-green": "light-dark(#50FA7B, #50FA7B)",
172
179
  "--color-data-categorical-pink": "light-dark(#FF79C6, #FF79C6)",
173
180
  "--color-data-categorical-cyan": "light-dark(#8BE9FD, #8BE9FD)",
174
181
  "--color-data-categorical-red": "light-dark(#FF5555, #FF5555)",
175
182
  "--color-data-categorical-teal": "light-dark(#A4FFFF, #A4FFFF)",
176
- "--color-data-categorical-brown": "light-dark(#FFB86C, #FFB86C)",
177
183
  "--color-data-categorical-indigo": "light-dark(#D6ACFF, #D6ACFF)",
178
184
  "--color-background-blue": "light-dark(#6272A41A, #6272A41A)",
179
185
  "--color-border-blue": "light-dark(#6272A44D, #6272A44D)",
@@ -240,11 +246,11 @@ export const astryxDraculaTheme = {
240
246
  "--color-data-yellow-3": "light-dark(hsl(64.91 91.67% 60%), hsl(64.91 91.67% 60%))",
241
247
  "--color-data-yellow-2": "light-dark(hsl(64.91 91.67% 74%), hsl(64.91 91.67% 74%))",
242
248
  "--color-data-yellow-1": "light-dark(hsl(64.91 91.67% 88%), hsl(64.91 91.67% 88%))",
243
- "--color-data-teal-5": "light-dark(hsl(190.53 96.61% 28%), hsl(190.53 96.61% 28%))",
244
- "--color-data-teal-4": "light-dark(hsl(190.53 96.61% 44%), hsl(190.53 96.61% 44%))",
245
- "--color-data-teal-3": "light-dark(hsl(190.53 96.61% 60%), hsl(190.53 96.61% 60%))",
246
- "--color-data-teal-2": "light-dark(hsl(190.53 96.61% 74%), hsl(190.53 96.61% 74%))",
247
- "--color-data-teal-1": "light-dark(hsl(190.53 96.61% 88%), hsl(190.53 96.61% 88%))",
249
+ "--color-data-teal-5": "light-dark(hsl(180 100% 28%), hsl(180 100% 28%))",
250
+ "--color-data-teal-4": "light-dark(hsl(180 100% 44%), hsl(180 100% 44%))",
251
+ "--color-data-teal-3": "light-dark(hsl(180 100% 60%), hsl(180 100% 60%))",
252
+ "--color-data-teal-2": "light-dark(hsl(180 100% 74%), hsl(180 100% 74%))",
253
+ "--color-data-teal-1": "light-dark(hsl(180 100% 88%), hsl(180 100% 88%))",
248
254
  "--color-data-blue-5": "light-dark(hsl(225.45 26.61% 28%), hsl(225.45 26.61% 28%))",
249
255
  "--color-data-blue-4": "light-dark(hsl(225.45 26.61% 44%), hsl(225.45 26.61% 44%))",
250
256
  "--color-data-blue-3": "light-dark(hsl(225.45 26.61% 60%), hsl(225.45 26.61% 60%))",
@@ -287,7 +293,7 @@ export const astryxDraculaTheme = {
287
293
  "--color-tag-cyan": "light-dark(#8BE9FD, #8BE9FD)",
288
294
  "--color-tag-yellow": "light-dark(#F1FA8C, #F1FA8C)",
289
295
  "--color-tag-green": "light-dark(#50FA7B, #50FA7B)",
290
- "--color-tag-blue": "light-dark(#BD93F9, #BD93F9)"
296
+ "--color-tag-purple": "light-dark(#BD93F9, #BD93F9)"
291
297
  },
292
298
  icons: draculaIconRegistry,
293
299
  };
@@ -9,11 +9,26 @@
9
9
  // Generated by astryx theme build
10
10
  export {};
11
11
 
12
+ declare module '@astryxdesign/core/StatusDot' {
13
+ interface StatusDotVariantMap {
14
+ 'info': true;
15
+ }
16
+ }
17
+
12
18
  declare module '@astryxdesign/core/ProgressBar' {
13
19
  interface ProgressBarVariantMap {
14
20
  'accent': true;
15
21
  'success': true;
16
22
  'warning': true;
17
23
  'error': true;
24
+ 'neutral': true;
25
+ 'disabled': true;
26
+ }
27
+ }
28
+
29
+ declare module '@astryxdesign/core/Avatar' {
30
+ interface AvatarStatusDotVariantMap {
31
+ 'success': true;
32
+ 'error': true;
18
33
  }
19
34
  }
package/package.json CHANGED
@@ -1,68 +1,110 @@
1
1
  {
2
+ "author": "Yuzu Octopus",
3
+ "bugs": {
4
+ "url": "https://github.com/yuzu-octopus/astryx-dracula/issues"
5
+ },
2
6
  "dependencies": {
3
- "@astryxdesign/core": "^0.3.0",
4
- "@stylexjs/stylex": "^0.19.0",
5
- "lucide-react": "^1.33.0",
6
- "react": "^19.2.8",
7
- "react-dom": "^19.2.8"
7
+ "lucide-react": "^1.45.0"
8
8
  },
9
9
  "description": "Pure Dracula brand theme for Astryx React sites. Dark-only tokens, syntax highlighting, and chart colors with prebuilt CSS.",
10
10
  "devDependencies": {
11
11
  "@astryxdesign/cli": "^0.3.0",
12
- "@types/bun": "^1.4.1",
13
- "@types/node": "^26.4.1",
14
- "@types/react": "^19.2.18",
15
- "@types/react-dom": "^19.2.4",
16
- "@vitejs/plugin-react": "^6.1.0",
12
+ "@types/bun": "^1.4.2",
13
+ "@types/node": "^26.5.1",
14
+ "@types/react": "^19.3.0",
15
+ "@types/react-dom": "^19.3.0",
16
+ "@vitejs/plugin-react": "^6.1.1",
17
17
  "typescript": "^7.0.2",
18
- "vite": "^8.0.0"
18
+ "vite": "^8.3.0"
19
19
  },
20
20
  "exports": {
21
+ "./shared/auth-chrome": "./shared/auth-chrome.tsx",
22
+ "./shared/auth-chrome-config": "./shared/auth-chrome-config.ts",
23
+ "./shared/auth-copy": "./shared/auth-copy.ts",
24
+ "./shared/chaptered-doc": "./shared/chaptered-doc.tsx",
25
+ "./shared/chaptered-doc-config": "./shared/chaptered-doc-config.ts",
26
+ "./shared/chart-hues": "./shared/chart-hues.ts",
27
+ "./shared/chart-labels": "./shared/chart-labels.tsx",
28
+ "./shared/chart-legend": "./shared/chart-legend.tsx",
29
+ "./shared/chart-panel-style": "./shared/chart-panel-style.ts",
30
+ "./shared/data-bar": "./shared/data-bar.tsx",
31
+ "./shared/gallery-image": "./shared/gallery-image.ts",
32
+ "./shared/login-demo": "./shared/login-demo.ts",
33
+ "./shared/metric-delta": "./shared/metric-delta.tsx",
34
+ "./shared/order-desk": "./shared/order-desk.tsx",
35
+ "./shared/revenue-chart": "./shared/revenue-chart.tsx",
36
+ "./shared/scene-castle": "./shared/scene-castle.tsx",
37
+ "./shared/scene-frame": "./shared/scene-frame.tsx",
38
+ "./shared/scene-hues": "./shared/scene-hues.ts",
39
+ "./shared/scene-tile": "./shared/scene-tile.tsx",
40
+ "./shared/settings-data": "./shared/settings-data.ts",
41
+ "./shared/settings-rows": "./shared/settings-rows.tsx",
42
+ "./shared/sparkline": "./shared/sparkline.tsx",
43
+ "./shared/sso-icons": "./shared/sso-icons.tsx",
21
44
  ".": {
22
45
  "default": "./astryx-dracula.js",
23
46
  "types": "./astryx-dracula.d.ts"
24
47
  },
25
- "./built": {
26
- "default": "./astryx-dracula.js",
27
- "types": "./astryx-dracula.d.ts"
28
- },
48
+ "./astryx.integration.mjs": "./astryx.integration.mjs",
29
49
  "./package.json": "./package.json",
50
+ "./templates/*": "./templates/*",
30
51
  "./theme.css": "./theme.css",
31
52
  "./tokens.css": "./tokens.css"
32
53
  },
33
54
  "files": [
34
55
  "BRAND.md",
35
56
  "LICENSE",
57
+ "README.md",
36
58
  "USAGE.md",
37
59
  "astryx-dracula.d.ts",
38
60
  "astryx-dracula.js",
39
61
  "astryx-dracula.variants.d.ts",
40
62
  "fonts/",
41
63
  "icons.tsx",
64
+ "shared/",
42
65
  "theme.css",
43
66
  "tokens.css",
44
67
  "templates/",
45
68
  "astryx.integration.mjs"
46
69
  ],
70
+ "keywords": [
71
+ "astryx",
72
+ "dracula",
73
+ "dracula-theme",
74
+ "theme",
75
+ "design-system",
76
+ "dark-theme",
77
+ "react",
78
+ "tokens"
79
+ ],
47
80
  "license": "MIT",
48
81
  "name": "astryx-dracula",
49
82
  "peerDependencies": {
50
83
  "@astryxdesign/core": "^0.3.0",
84
+ "lucide-react": "^1.45.0",
51
85
  "react": ">=19.0.0",
52
86
  "react-dom": ">=19.0.0"
53
87
  },
88
+ "repository": {
89
+ "type": "git",
90
+ "url": "git+https://github.com/yuzu-octopus/astryx-dracula.git"
91
+ },
54
92
  "scripts": {
55
93
  "audit": "bun scripts/check.ts",
56
94
  "build": "tsc --noEmit && vite build",
57
95
  "dev": "vite",
58
96
  "preview": "vite preview",
59
97
  "theme:build": "bunx astryx theme build astryx-theme.ts -o theme.css",
60
- "theme:check": "bunx astryx theme build astryx-theme.ts -o theme.css --check"
98
+ "theme:check": "bunx astryx theme build astryx-theme.ts -o theme.css --check --json | bun -e 'const r = JSON.parse(await Bun.stdin.text()); if (r.type !== \"theme.build.check\") { console.error(\"theme:check: unexpected CLI response \" + JSON.stringify(r).slice(0, 200)); process.exit(1); } const stale = r.data.stale.filter(s => s.path !== \"astryx-dracula.js\"); for (const s of stale) console.error(\"stale: \" + s.path + \" (\" + s.reason + \")\"); if (stale.length) process.exit(1); const entry = await import(\"./astryx-dracula.js\"); if (!entry.astryxDraculaTheme || !entry.draculaIconRegistry) { console.error(\"astryx-dracula.js is missing its theme or icon registry export\"); process.exit(1); } console.log(\"theme outputs up to date; astryx-dracula.js (hand-maintained) loads and exports\");'",
99
+ "prepublishOnly": "bun run theme:check && bun run audit && tsc --noEmit && bunx react-doctor@latest --score"
61
100
  },
101
+ "sideEffects": [
102
+ "**/*.css"
103
+ ],
62
104
  "trustedDependencies": [
63
105
  "@astryxdesign/core",
64
106
  "@astryxdesign/cli"
65
107
  ],
66
108
  "type": "module",
67
- "version": "0.2.1"
109
+ "version": "0.3.0"
68
110
  }
@@ -0,0 +1,18 @@
1
+ // Auth page chrome, split from the component that renders it, for the same
2
+ // reason as shared/scene-hues.ts: a .tsx exporting non-components breaks React
3
+ // Fast Refresh. Five templates import these, so they are genuinely shared --
4
+ // they were only ever co-located by accident of history.
5
+ import type {CSSProperties} from 'react';
6
+
7
+ // Standalone auth pages paint their own body background (no host shell).
8
+ export const authPageStyle: CSSProperties = {
9
+ minHeight: '100%',
10
+ backgroundColor: 'var(--color-background-body)',
11
+ padding: 'var(--spacing-6)',
12
+ };
13
+ // Cap the column at 400px but let it shrink to fit narrow screens.
14
+ export const authContentStyle: CSSProperties = {width: '100%', maxWidth: 400};
15
+ // WCAG 1.3.5 autocomplete: TextInput forwards unknown props to <input> but its
16
+ // prop type omits input-only attributes, so spread through a widened record.
17
+ export const inputAutoComplete = (value: string) =>
18
+ ({autoComplete: value}) as Record<string, string>;
@@ -0,0 +1,25 @@
1
+ // Shared login chrome: page wash + 400px column + Moon brand row + the
2
+ // autocomplete widen-record TextInput needs (prop type omits input attrs).
3
+ import type {CSSProperties} from 'react';
4
+ import {Moon} from 'lucide-react';
5
+ import {VStack} from '@astryxdesign/core/Layout';
6
+ import {Text} from '@astryxdesign/core/Text';
7
+ import {Icon} from '@astryxdesign/core/Icon';
8
+ import {AUTH_BRAND_NAME} from 'astryx-dracula/shared/auth-copy';
9
+ import {
10
+ authContentStyle,
11
+ authPageStyle,
12
+ inputAutoComplete,
13
+ } from 'astryx-dracula/shared/auth-chrome-config';
14
+
15
+
16
+ export function LoginBrand() {
17
+ return (
18
+ <VStack gap={2} hAlign="center">
19
+ <Icon icon={Moon} size="lg" color="secondary" />
20
+ <Text type="body" weight="semibold" size="lg">
21
+ {AUTH_BRAND_NAME}
22
+ </Text>
23
+ </VStack>
24
+ );
25
+ }
@@ -0,0 +1,22 @@
1
+ // Auth copy shared by the four login templates. Single-sourced so the family
2
+ // line cannot drift again. SSO-specific strings (Work email, Whisper your
3
+ // details, Continue with SSO, provider names) stay per-template in login-sso.
4
+ export const AUTH_HEADING = 'Welcome back to the night';
5
+ export const AUTH_SUBTITLE = 'Sign in to your crypt';
6
+ export const AUTH_PRIMARY_CTA = 'Sign in';
7
+ export const AUTH_SIGNUP_PROMPT = 'New to the castle?';
8
+ export const AUTH_SIGNUP_LINK = 'Sign up';
9
+ export const AUTH_SSO_DIVIDER = 'Or continue with';
10
+ export const AUTH_FORGOT_PASSWORD = 'Forgot password?';
11
+ // Names the problem without apologising, and does not blame one field: a
12
+ // mistyped email used to be reported as a wrong password, because this string
13
+ // was attached to the password input only.
14
+ export const AUTH_ERROR_MESSAGE = 'Email or password is wrong. Try again.';
15
+ export const AUTH_EMAIL_PLACEHOLDER = 'you@castle.dracula';
16
+ // The placeholder is the only visible name on the credential inputs, so it has
17
+ // to actually name the field. "Whisper your password" named nothing.
18
+ export const AUTH_PASSWORD_PLACEHOLDER = 'Your password';
19
+ export const AUTH_BRAND_NAME = 'Castle Dracula';
20
+ export const AUTH_TERMS_PREFIX = 'By clicking continue, you agree to our';
21
+ export const AUTH_TERMS_SERVICE = 'Terms of service';
22
+ export const AUTH_TERMS_PRIVACY = 'Privacy policy';