Saer on Lunary, a production codebase.
Lunary is the founder’s own app, in production on the web and iOS. Saer scanned its 4,262 files locally on 22 October 2026, with saer 0.1.5. Every number, colour and file path on this page is copied from that scan.
Summary
- Colour tokens reconstructed
- 167
- Hard-coded colours equal to a token, and their uses
- 22 / 436
- Near-matches, kept apart
- 78
- Components, and names defined twice
- 1,668 / 15
- Uses of
<Button>that restyle it - 164 of 538
- Failing contrast pairs, default context
- 48
$ saer scan
SAER
Colour system reconstructed.
167 canonical colour entities
Found
22 exact drift finding(s)
78 experimental near-match(es)
13 dead declaration(s)
# typography and foundations trimmed here
Components
1668 component(s), 100% of use sites resolved
15 exact-name duplicate(s), 0 experimental near-duplicate(s)
20 variant finding(s), 19 component(s) overridden at use sites
Accessibility (static checks, not a conformance claim)
48 failing colour pair(s) (111 more only in another colour context), 2781 passing, 7863 unknown
2 focus style finding(s)
1 tap target(s) below 24px, 31 below 44px
(73.6s)Colour: the system as declared, and where the code went around it.
167 colour tokens, every var() chain followed to a value (632 of 633 references resolved; the rest is reported as unresolved, not guessed).
From observations to questions
- 28,798observations of colour in the code: raw values and token classes
- 115findings: 22 exact, 93 inferred and labelled as such
- 14questions only a person can answer, asked once each
Every token, by hue
A green bar under a swatch: a raw hex somewhere in the code is identical to it. Hollow: declared, never used. Families are a browsing lens computed from hue, not a finding.
Showing 167 of 167 tokens. Select a swatch, or use the arrow keys, to inspect it.
color-primary
CSS custom property, declared in src/app/globals.css
- Default
- #8458d8
- Light
- #8458d8
- Dark
- #8458d8
- Uses through a class
- 0
- Raw hex uses
- 104
- Exact drift
- 72
Bypassed by an identical raw value
#8458d8 written 72 times. Files (Saer’s sample):
- src/app/admin/bip/BipTriggerButtons.tsx
- src/app/api/forecast/yearly/calendar/route.ts
- src/app/api/newsletter/daily-horoscope/opt-in/route.ts
- src/app/birth-chart/transits/TransitReadingView.tsx
- src/app/birth-chart/transits/TransitTeaserView.tsx
All 167 tokens as a table
| Token | Default | Light | Dark | Class uses | Exact drift | Note |
|---|---|---|---|---|---|---|
| chart-shadow | #000000 | #ffffff | #000000 | 0 | 67 | |
| color-bg-deep | #050505 | #050505 | #050505 | 0 | 10 | |
| lunary-bg-deep | #050505 | #050505 | #050505 | 0 | 10 | |
| chart-backdrop-edge | #08060f | #ffffff | #08060f | 0 | 67 | |
| color-bg | #0a0a0a | #0a0a0a | #0a0a0a | 0 | 62 | |
| lunary-bg | #0a0a0a | #0a0a0a | #0a0a0a | 0 | 62 | |
| page-bg | #0a0a0a | not set | #0a0a0a | 0 | 62 | |
| surface-base | #0a0a0a | #faf9ff | #0a0a0a | 531 | 62 | |
| lunary-success-950 | #0c120e | #0c120e | #0c120e | 1 | 0 | |
| tint-success | #0c120e | #e7efe9 | #0c120e | 13 | 0 | |
| lunary-success-900 | #19251c | #19251c | #19251c | 2 | 0 | |
| tint-success-mid | #19251c | #ceded3 | #19251c | 16 | 0 | |
| lunary-success-200 | #ceded3 | #ceded3 | #ceded3 | 5 | 0 | |
| lunary-error-100 | #f6e0e0 | #f6e0e0 | #f6e0e0 | 1 | 0 | |
| lunary-success-100 | #e7efe9 | #e7efe9 | #e7efe9 | 1 | 0 | |
| lunary-secondary-50 | #f2f2fd | #f2f2fd | #f2f2fd | 0 | 0 | Never used |
| lunary-accent-50 | #f8f0ff | #f8f0ff | #f8f0ff | 1 | 0 | |
| lunary-rose-50 | #fdf1f5 | #fdf1f5 | #fdf1f5 | 0 | 0 | Never used |
| lunary-primary-50 | #f6f3fc | #f6f3fc | #f6f3fc | 2 | 0 | |
| lunary-error-50 | #fcf3f3 | #fcf3f3 | #fcf3f3 | 0 | 0 | Never used |
| lunary-highlight-50 | #fbf2fd | #fbf2fd | #fbf2fd | 0 | 0 | Never used |
| lunary-success-50 | #f6f9f7 | #f6f9f7 | #f6f9f7 | 1 | 0 | |
| chart-star | #fff8e7 | #7e58be | #fff8e7 | 0 | 2 | |
| chart-text | #ffffff | #2c1f44 | #ffffff | 0 | 67 | |
| color-text | #ffffff | #ffffff | #ffffff | 0 | 67 | |
| content-primary | #ffffff | #1a0f2e | #ffffff | 3,388 | 68 | |
| lunary-text | #ffffff | #ffffff | #ffffff | 0 | 67 | |
| lunary-rose-950 | #1b030b | #1b030b | #1b030b | 0 | 0 | Never used |
| tint-rose | #1b030b | #fadbe5 | #1b030b | 3 | 0 | |
| lunary-rose-400 | #e84a7d | #e84a7d | #e84a7d | 22 | 0 | |
| color-rose | #ee789e | #ee789e | #ee789e | 0 | 24 | |
| lunary-rose | #ee789e | #ee789e | #ee789e | 134 | 24 | |
| lunary-rose-300 | #f089aa | #f089aa | #f089aa | 58 | 0 | |
| lunary-rose-900 | #360716 | #360716 | #360716 | 1 | 0 | |
| tint-rose-mid | #360716 | #f6b7cb | #360716 | 29 | 0 | |
| lunary-rose-800 | #5b0b25 | #5b0b25 | #5b0b25 | 5 | 0 | |
| tint-rose-edge | #5b0b25 | #f6b7cb | #5b0b25 | 4 | 0 | |
| lunary-rose-700 | #881137 | #881137 | #881137 | 25 | 0 | |
| lunary-rose-600 | #b5174a | #b5174a | #b5174a | 9 | 0 | |
| lunary-rose-500 | #e21d5c | #e21d5c | #e21d5c | 11 | 0 | |
| lunary-error-950 | #180707 | #180707 | #180707 | 0 | 0 | Never used |
| tint-error | #180707 | #f6e0e0 | #180707 | 12 | 0 | |
| lunary-error-900 | #2f0e0e | #2f0e0e | #2f0e0e | 2 | 0 | |
| tint-error-mid | #2f0e0e | #ecc0c0 | #2f0e0e | 18 | 0 | |
| lunary-error-800 | #4f1717 | #4f1717 | #4f1717 | 9 | 0 | |
| tint-error-edge | #4f1717 | #ecc0c0 | #4f1717 | 6 | 0 | |
| lunary-error-700 | #762323 | #762323 | #762323 | 50 | 0 | |
| lunary-error-600 | #9d2f2f | #9d2f2f | #9d2f2f | 8 | 0 | |
| lunary-error-500 | #c53a3a | #c53a3a | #c53a3a | 8 | 0 | |
| color-error | #d06060 | #d06060 | #d06060 | 0 | 14 | |
| lunary-error | #d06060 | #d06060 | #d06060 | 95 | 14 | |
| lunary-error-400 | #d06262 | #d06262 | #d06262 | 10 | 0 | |
| chart-aspect-square | #f87171 | #be4848 | #f87171 | 0 | 11 | |
| chart-retrograde | #f87171 | #be4848 | #f87171 | 0 | 11 | |
| chart-fire | #ff7b74 | #c65c5c | #ff7b74 | 0 | 0 | |
| content-error | #e19999 | #c53a3a | #e19999 | 84 | 0 | |
| lunary-error-300 | #e19999 | #e19999 | #e19999 | 47 | 0 | |
| lunary-error-200 | #ecc0c0 | #ecc0c0 | #ecc0c0 | 10 | 0 | |
| tint-warning | #451a03 | #fef3c7 | #451a03 | 23 | 0 | |
| tint-warning-mid | #78350f | #fde68a | #78350f | 46 | 2 | |
| tint-warning-edge | #92400e | #fde68a | #92400e | 4 | 3 | |
| chart-aspect-opposition | #ffd6a3 | #aa7842 | #ffd6a3 | 0 | 6 | |
| content-warning | #fcd34d | #92400e | #fcd34d | 91 | 16 | |
| chart-earth | #88b070 | #537b59 | #88b070 | 0 | 0 | |
| lunary-success-800 | #293d2f | #293d2f | #293d2f | 14 | 0 | |
| tint-success-edge | #293d2f | #ceded3 | #293d2f | 12 | 0 | |
| lunary-success-700 | #3e5b47 | #3e5b47 | #3e5b47 | 46 | 0 | |
| lunary-success-600 | #527a5f | #527a5f | #527a5f | 20 | 0 | |
| lunary-success-500 | #679876 | #679876 | #679876 | 7 | 0 | |
| color-success | #6b9b7a | #6b9b7a | #6b9b7a | 0 | 18 | |
| lunary-success | #6b9b7a | #6b9b7a | #6b9b7a | 278 | 18 | |
| lunary-success-400 | #85ad92 | #85ad92 | #85ad92 | 27 | 0 | |
| content-success | #b0cab8 | #3e5b47 | #b0cab8 | 83 | 0 | |
| lunary-success-300 | #b0cab8 | #b0cab8 | #b0cab8 | 54 | 0 | |
| chart-aspect-trine | #7bffb8 | #438b65 | #7bffb8 | 0 | 8 | |
| chart-air | #86c0eb | #4a8bbc | #86c0eb | 0 | 0 | |
| chart-aspect-sextile | #94d1ff | #4c82b2 | #94d1ff | 0 | 5 | |
| lunary-secondary-600 | #1e1eae | #1e1eae | #1e1eae | 16 | 0 | |
| lunary-secondary-500 | #2626d9 | #2626d9 | #2626d9 | 2 | 0 | |
| lunary-secondary-950 | #05051a | #05051a | #05051a | 3 | 0 | |
| tint-secondary | #05051a | #dcdcf9 | #05051a | 10 | 0 | |
| lunary-secondary-900 | #090934 | #090934 | #090934 | 11 | 0 | |
| tint-secondary-mid | #090934 | #babaf3 | #090934 | 24 | 0 | |
| lunary-secondary-800 | #0f0f57 | #0f0f57 | #0f0f57 | 32 | 0 | |
| tint-secondary-edge | #0f0f57 | #babaf3 | #0f0f57 | 15 | 0 | |
| lunary-secondary-700 | #171782 | #171782 | #171782 | 40 | 0 | |
| lunary-secondary-400 | #5151e1 | #5151e1 | #5151e1 | 34 | 0 | |
| color-secondary | #7b7be8 | #7b7be8 | #7b7be8 | 0 | 38 | |
| lunary-secondary | #7b7be8 | #7b7be8 | #7b7be8 | 108 | 38 | |
| chart-backdrop-mid | #15102d | #f2ecfa | #15102d | 0 | 0 | |
| layer-raised | #291353 | #ffffff | #291353 | 48 | 67 | |
| lunary-primary-800 | #291353 | #291353 | #291353 | 66 | 0 | |
| stroke-subtle | #291353 | #d4c4eb | #291353 | 2,173 | 0 | |
| surface-overlay | #291353 | #e7def7 | #291353 | 208 | 9 | |
| tint-primary-edge | #291353 | #cebdf0 | #291353 | 29 | 0 | |
| chart-backdrop-center | #2e1a5e | #faf7ff | #2e1a5e | 0 | 0 | |
| chat-user-border | #3e1d7c | #b094e6 | #3e1d7c | 0 | 0 | |
| layer-high | #3e1d7c | #e7def7 | #3e1d7c | 88 | 9 | |
| lunary-primary-700 | #3e1d7c | #3e1d7c | #3e1d7c | 378 | 0 | |
| stroke-default | #3e1d7c | #b094e6 | #3e1d7c | 761 | 0 | |
| lunary-primary-600 | #5227a5 | #5227a5 | #5227a5 | 441 | 0 | |
| lunary-primary-500 | #6730cf | #6730cf | #6730cf | 194 | 4 | |
| stroke-strong | #6730cf | #8458d8 | #6730cf | 108 | 76 | |
| chart-angular | #8e8eeb | #6860be | #8e8eeb | 0 | 0 | |
| content-brand-secondary | #8e8eeb | #1e1eae | #8e8eeb | 162 | 0 | |
| lunary-secondary-300 | #8e8eeb | #8e8eeb | #8e8eeb | 39 | 0 | |
| lunary-secondary-200 | #babaf3 | #babaf3 | #babaf3 | 0 | 0 | Never used |
| lunary-secondary-100 | #dcdcf9 | #dcdcf9 | #dcdcf9 | 0 | 0 | Never used |
| chart-surface-soft | #0c0619 | #faf7ff | #0c0619 | 0 | 0 | |
| layer-deep | #0c0619 | #f6f3fc | #0c0619 | 257 | 0 | |
| lunary-primary-950 | #0c0619 | #0c0619 | #0c0619 | 7 | 0 | |
| surface-elevated | #0c0619 | #f6f3fc | #0c0619 | 2,236 | 0 | |
| tint-primary | #0c0619 | #e7def7 | #0c0619 | 9 | 9 | |
| chart-surface | #190c32 | #ffffff | #190c32 | 0 | 67 | |
| chat-user-bg | #190c32 | #e7def7 | #190c32 | 0 | 9 | |
| layer-base | #190c32 | #faf9ff | #190c32 | 808 | 0 | |
| lunary-primary-900 | #190c32 | #190c32 | #190c32 | 15 | 0 | |
| surface-card | #190c32 | #ffffff | #190c32 | 678 | 67 | |
| tint-primary-mid | #190c32 | #cebdf0 | #190c32 | 18 | 0 | |
| lunary-accent-900 | #23003d | #23003d | #23003d | 8 | 0 | |
| tint-accent-mid | #23003d | #dcadff | #23003d | 24 | 0 | |
| lunary-accent-800 | #3a0066 | #3a0066 | #3a0066 | 11 | 0 | |
| tint-accent-edge | #3a0066 | #dcadff | #3a0066 | 5 | 0 | |
| chart-stroke-subtle | #3e2a67 | #e2d8f1 | #3e2a67 | 0 | 0 | |
| lunary-accent-700 | #570099 | #570099 | #570099 | 67 | 0 | |
| lunary-accent-600 | #7400cc | #7400cc | #7400cc | 15 | 0 | |
| chart-stroke | #6748a6 | #c5b5e0 | #6748a6 | 0 | 0 | |
| lunary-accent-500 | #9100ff | #9100ff | #9100ff | 12 | 0 | |
| color-primary | #8458d8 | #8458d8 | #8458d8 | 0 | 72 | |
| lunary-primary | #8458d8 | #8458d8 | #8458d8 | 464 | 72 | |
| lunary-primary-400 | #855ad8 | #855ad8 | #855ad8 | 1,136 | 0 | |
| lunary-accent-400 | #a733ff | #a733ff | #a733ff | 65 | 0 | |
| content-muted | #9a73e0 | #6730cf | #9a73e0 | 4,407 | 4 | |
| chart-text-muted | #b094e6 | #705d91 | #b094e6 | 0 | 0 | |
| content-brand | #b094e6 | #5227a5 | #b094e6 | 1,081 | 0 | |
| lunary-primary-300 | #b094e6 | #b094e6 | #b094e6 | 64 | 0 | |
| content-secondary | #cebdf0 | #3e1d7c | #cebdf0 | 2,618 | 0 | |
| lunary-primary-200 | #cebdf0 | #cebdf0 | #cebdf0 | 7 | 0 | |
| lunary-primary-100 | #e7def7 | #e7def7 | #e7def7 | 3 | 9 | |
| lunary-accent-950 | #11001f | #11001f | #11001f | 1 | 0 | |
| tint-accent | #11001f | #edd6ff | #11001f | 15 | 0 | |
| lunary-highlight-600 | #921cb0 | #921cb0 | #921cb0 | 4 | 0 | |
| chart-water | #b886da | #8658b0 | #b886da | 0 | 0 | |
| lunary-accent-300 | #c67aff | #c67aff | #c67aff | 21 | 0 | |
| chart-aspect-conjunction | #c77dff | #8958ca | #c77dff | 0 | 45 | |
| chart-selected | #c77dff | #7400cc | #c77dff | 0 | 45 | |
| color-accent | #c77dff | #c77dff | #c77dff | 0 | 45 | |
| content-brand-accent | #c77dff | #7400cc | #c77dff | 422 | 45 | |
| lunary-accent | #c77dff | #c77dff | #c77dff | 445 | 45 | |
| lunary-accent-200 | #dcadff | #dcadff | #dcadff | 0 | 0 | Never used |
| lunary-accent-100 | #edd6ff | #edd6ff | #edd6ff | 0 | 0 | Never used |
| lunary-highlight-950 | #16041a | #16041a | #16041a | 1 | 0 | |
| tint-highlight | #16041a | #f3dcf9 | #16041a | 4 | 0 | |
| lunary-highlight-900 | #2c0835 | #2c0835 | #2c0835 | 2 | 0 | |
| tint-highlight-mid | #2c0835 | #e8b9f4 | #2c0835 | 29 | 0 | |
| lunary-highlight-800 | #490e58 | #490e58 | #490e58 | 4 | 0 | |
| tint-highlight-edge | #490e58 | #e8b9f4 | #490e58 | 2 | 0 | |
| lunary-highlight-700 | #6e1584 | #6e1584 | #6e1584 | 5 | 0 | |
| lunary-highlight-500 | #b723dc | #b723dc | #b723dc | 2 | 0 | |
| lunary-highlight-400 | #c54fe3 | #c54fe3 | #c54fe3 | 4 | 0 | |
| color-highlight | #d070e8 | #d070e8 | #d070e8 | 0 | 22 | |
| lunary-highlight | #d070e8 | #d070e8 | #d070e8 | 39 | 22 | |
| lunary-highlight-300 | #d98ded | #d98ded | #d98ded | 2 | 0 | |
| lunary-highlight-200 | #e8b9f4 | #e8b9f4 | #e8b9f4 | 0 | 0 | Never used |
| lunary-highlight-100 | #f3dcf9 | #f3dcf9 | #f3dcf9 | 0 | 0 | Never used |
| lunary-rose-200 | #f6b7cb | #f6b7cb | #f6b7cb | 7 | 0 | |
| lunary-rose-100 | #fadbe5 | #fadbe5 | #fadbe5 | 0 | 0 | Never used |
Exact drift: 22 colours, 436 uses
Each segment is a literal colour from the code, sized by uses, identical to a declared token. Select one to see the tokens and files.
#8458d8
Exact drift · deterministic
- Written
- 72 times
- Share of all exact drift
- 16.5%
Identical to
color-primary · lunary-primary · stroke-strong
Files (Saer’s sample, up to five)
- src/app/admin/bip/BipTriggerButtons.tsx
- src/app/api/forecast/yearly/calendar/route.ts
- src/app/api/newsletter/daily-horoscope/opt-in/route.ts
- src/app/birth-chart/transits/TransitReadingView.tsx
- src/app/birth-chart/transits/TransitTeaserView.tsx
All 22 exact drift findings as a table
| Raw value | Identical token | Uses | First file |
|---|---|---|---|
#8458d8 | color-primary, lunary-primary, stroke-strong | 72 | src/app/admin/bip/BipTriggerButtons.tsx |
#ffffff | chart-backdrop-edge, chart-shadow, chart-surface, chart-text, color-text, content-primary, layer-raised, lunary-text, surface-card | 67 | src/app/api/admin/reactivate-users/route.ts |
#0a0a0a | color-bg, lunary-bg, page-bg, surface-base | 62 | src/app/admin/bip/page.tsx |
#c77dff | chart-aspect-conjunction, chart-selected, color-accent, content-brand-accent, lunary-accent | 45 | src/app/(authenticated)/app/group-sky/page.tsx |
#7b7be8 | color-secondary, lunary-secondary | 38 | src/app/api/forecast/yearly/calendar/route.ts |
#ee789e | color-rose, lunary-rose | 24 | src/app/api/forecast/yearly/calendar/route.ts |
#d070e8 | color-highlight, lunary-highlight | 22 | src/app/api/forecast/yearly/calendar/route.ts |
#6b9b7a | color-success, lunary-success | 18 | src/app/api/forecast/yearly/calendar/route.ts |
#d06060 | color-error, lunary-error | 14 | src/app/api/forecast/yearly/calendar/route.ts |
#fcd34d | content-warning | 14 | src/app/birth-chart/chart-wheel-og.tsx |
#f87171 | chart-aspect-square, chart-retrograde | 11 | src/app/(authenticated)/app/time-machine/page.tsx |
#050505 | color-bg-deep, lunary-bg-deep | 10 | src/app/admin/transit-blog/page.tsx |
#e7def7 | chat-user-bg, layer-high, lunary-primary-100, surface-overlay, tint-primary | 9 | src/app/birth-chart/transits/TransitReadingView.tsx |
#7bffb8 | chart-aspect-trine | 8 | src/app/(authenticated)/app/group-sky/page.tsx |
#ffd6a3 | chart-aspect-opposition | 6 | src/app/(authenticated)/app/group-sky/page.tsx |
#94d1ff | chart-aspect-sextile | 5 | src/app/(authenticated)/app/group-sky/page.tsx |
#6730cf | content-muted, lunary-primary-500, stroke-strong | 4 | src/app/birth-chart/transits/TransitReadingView.tsx |
#92400e | content-warning, tint-warning-edge | 2 | src/app/grimoire/candle-magic/page.tsx |
#fff8e7 | chart-star | 2 | src/components/states/CosmicErrorBoundary.tsx |
#1a0f2e | content-primary | 1 | src/components/charts/chartTheme.ts |
#78350f | tint-warning-mid | 1 | src/app/grimoire/candle-magic/colors/page.tsx |
#fde68a | tint-warning-edge, tint-warning-mid | 1 | src/app/birth-chart/chart-wheel-svg.tsx |
Near-matches, kept apart
78 raw colours sit perceptually close to a token. Saer shows the distance and leaves the decision to you: close is not the same as equal.
- #080b12 → color-bgΔOKLab 0.017 · 17 uses
- #2c2140 → chart-textΔOKLab 0.011 · 9 uses
- #0a0a0f → color-bgΔOKLab 0.011 · 9 uses
- #feffff → chart-backdrop-edgeΔOKLab 0.001 · 8 uses
- #e7d7fb → lunary-accent-100ΔOKLab 0.011 · 8 uses
- #2f2448 → chart-textΔOKLab 0.017 · 6 uses
- #ff6b6b → chart-aspect-squareΔOKLab 0.015 · 5 uses
- #7f1d1d → lunary-error-700ΔOKLab 0.019 · 5 uses
- #2d2548 → chart-textΔOKLab 0.018 · 4 uses
- #1a1030 → content-primaryΔOKLab 0.005 · 3 uses
- #09090b → color-bgΔOKLab 0.006 · 3 uses
- #f8fafc → layer-baseΔOKLab 0.006 · 3 uses
12 of 78 near-matches. Inferred, never mixed with exact drift: a person decides.
All 78 near-matches as a table
| Raw value | Nearest token | ΔOKLab | Uses | First file |
|---|---|---|---|---|
#080b12 | color-bg, lunary-bg (#0a0a0a) | 0.017 | 17 | src/app/birth-chart/transits/TransitsCaptureClient.tsx |
#2c2140 | chart-text (#2c1f44) | 0.011 | 9 | src/constants/seo/thematic-palette-config.ts |
#0a0a0f | color-bg, lunary-bg (#0a0a0a) | 0.011 | 9 | src/app/admin/bip/BipTriggerButtons.tsx |
#feffff | chart-backdrop-edge, chart-shadow (#ffffff) | 0.001 | 8 | src/components/OnboardingFlow.tsx |
#e7d7fb | lunary-accent-100, tint-accent (#edd6ff) | 0.011 | 8 | src/app/grimoire/wheel-of-the-year/page.tsx |
#2f2448 | chart-text (#2c1f44) | 0.017 | 6 | src/constants/seo/thematic-palette-config.ts |
#ff6b6b | chart-aspect-square, chart-retrograde (#f87171) | 0.015 | 5 | src/app/api/tiktok/callback/route.ts |
#7f1d1d | lunary-error-700 (#762323) | 0.019 | 5 | src/app/grimoire/guides/learn-birth-chart/ChartReadingExampleInteractive.tsx |
#2d2548 | chart-text (#2c1f44) | 0.018 | 4 | src/constants/seo/thematic-palette-config.ts |
#1a1030 | content-primary (#1a0f2e) | 0.005 | 3 | src/lib/instagram/design-system.ts |
#09090b | color-bg, lunary-bg (#0a0a0a) | 0.006 | 3 | src/app/grimoire/guides/learn-birth-chart/ChartReadingExampleInteractive.tsx |
#f8fafc | layer-base, surface-base (#faf9ff) | 0.006 | 3 | src/app/grimoire/guides/learn-birth-chart/ChartReadingExampleInteractive.tsx |
#1a0a2e | chart-surface, chat-user-bg (#190c32) | 0.009 | 3 | src/lib/instagram/design-system.ts |
#111111 | lunary-success-950, tint-success (#0c120e) | 0.013 | 3 | src/lib/instagram/caption-content.ts |
#e6edf3 | lunary-success-100, tint-success (#e7efe9) | 0.016 | 3 | src/components/ui/CodeBlock.tsx |
#1f3a30 | lunary-success-800, tint-success-edge (#293d2f) | 0.018 | 3 | src/constants/seo/thematic-palette-config.ts |
#431407 | tint-warning (#451a03) | 0.018 | 3 | src/app/grimoire/guides/learn-birth-chart/ChartReadingExampleInteractive.tsx |
#2e5a48 | content-success, lunary-success-700 (#3e5b47) | 0.019 | 3 | src/constants/seo/thematic-palette-config.ts |
#f4f4ff | layer-deep, lunary-primary-50 (#f6f3fc) | 0.004 | 2 | src/app/api/cosmic-report/generate/route.ts |
#9b75e3 | content-muted (#9a73e0) | 0.006 | 2 | src/lib/pdf/styles.ts |
#081210 | lunary-success-950, tint-success (#0c120e) | 0.007 | 2 | src/lib/instagram/design-system.ts |
#f5f5f5 | lunary-error-50 (#fcf3f3) | 0.010 | 2 | src/app/grimoire/candle-magic/page.tsx |
#0b0b0f | color-bg, lunary-bg (#0a0a0a) | 0.011 | 2 | src/app/admin/gpt-bridge/page.tsx |
#1a1028 | content-primary (#1a0f2e) | 0.013 | 2 | src/lib/pdf/styles.ts |
#e9e3ff | chat-user-bg, layer-high (#e7def7) | 0.015 | 2 | src/components/gifts/SubscriptionGiftCard.tsx |
#121212 | lunary-success-950, tint-success (#0c120e) | 0.015 | 2 | src/lib/pdf/styles.ts |
#ffe08a | tint-warning-edge, tint-warning-mid (#fde68a) | 0.015 | 2 | src/app/(authenticated)/app/group-sky/page.tsx |
#c084fc | chart-aspect-conjunction, chart-selected (#c77dff) | 0.019 | 2 | src/components/SaveToCollection.tsx |
#7c2d12 | tint-warning-mid (#78350f) | 0.019 | 2 | src/lib/moon/identities.ts |
#6d28d9 | content-muted, lunary-primary-500 (#6730cf) | 0.020 | 2 | src/app/api/admin/reactivate-users/route.ts |
#ff7b72 | chart-fire (#ff7b74) | 0.003 | 1 | src/components/ui/CodeBlock.tsx |
#f7efff | lunary-accent-50 (#f8f0ff) | 0.003 | 1 | src/app/grimoire/wheel-of-the-year/page.tsx |
#fff0f5 | lunary-rose-50 (#fdf1f5) | 0.004 | 1 | src/lib/instagram/design-system.ts |
#f5f0ff | lunary-accent-50 (#f8f0ff) | 0.004 | 1 | src/lib/instagram/design-system.ts |
#14102a | chart-backdrop-mid (#15102d) | 0.006 | 1 | src/lib/instagram/design-system.ts |
#f7fafc | lunary-success-50 (#f6f9f7) | 0.007 | 1 | src/app/api/blog/weekly/route.ts |
#f9fafb | layer-base, surface-base (#faf9ff) | 0.007 | 1 | utils/og/symbols.ts |
#f0f0ff | lunary-secondary-50 (#f2f2fd) | 0.007 | 1 | src/lib/instagram/ig-utils.tsx |
#08070d | chart-backdrop-edge (#08060f) | 0.008 | 1 | src/lib/quiz/cosmic-vibe.ts |
#fed7aa | chart-aspect-opposition (#ffd6a3) | 0.008 | 1 | src/app/grimoire/guides/learn-birth-chart/ChartReadingExampleInteractive.tsx |
#fff8ed | chart-star (#fff8e7) | 0.008 | 1 | src/app/grimoire/wheel-of-the-year/page.tsx |
#fffbe6 | chart-star (#fff8e7) | 0.008 | 1 | src/components/charts/MoonPhase.tsx |
#1b0f2a | content-primary (#1a0f2e) | 0.008 | 1 | src/lib/quiz/cosmic-vibe.ts |
#8fae6e | chart-earth (#88b070) | 0.009 | 1 | src/lib/pdf/templates/CosmicReportTemplate.tsx |
#f3d4ff | lunary-accent-100, tint-accent (#edd6ff) | 0.009 | 1 | src/app/share/birth-chart/ShareBirthChartLayout.tsx |
#7a1f1f | lunary-error-700 (#762323) | 0.010 | 1 | src/lib/quiz/cosmic-vibe.ts |
#07110d | lunary-success-950, tint-success (#0c120e) | 0.010 | 1 | src/app/share/birth-chart/ShareBirthChartLayout.tsx |
#fffdf7 | chart-backdrop-edge, chart-shadow (#ffffff) | 0.010 | 1 | src/lib/instagram/design-system.ts |
#0a0613 | chart-backdrop-edge (#08060f) | 0.010 | 1 | src/lib/pdf/templates/CosmicReportTemplate.tsx |
#f3f4f6 | layer-deep, lunary-primary-50 (#f6f3fc) | 0.010 | 1 | src/app/admin/crystal-gallery/page.tsx |
#a23030 | lunary-error-600 (#9d2f2f) | 0.011 | 1 | src/app/share/birth-chart/ShareBirthChartLayout.tsx |
#fff8f0 | chart-star (#fff8e7) | 0.012 | 1 | src/lib/instagram/design-system.ts |
#2a1010 | lunary-error-900, tint-error-mid (#2f0e0e) | 0.012 | 1 | src/lib/instagram/design-system.ts |
#eeeeee | lunary-success-100, tint-success (#e7efe9) | 0.013 | 1 | scripts/send-reset-emails.js |
#1a0a0a | lunary-error-950, tint-error (#180707) | 0.013 | 1 | src/lib/instagram/design-system.ts |
#d4dfff | lunary-secondary-100, tint-secondary (#dcdcf9) | 0.013 | 1 | src/app/share/birth-chart/ShareBirthChartLayout.tsx |
#6b5b95 | chart-text-muted (#705d91) | 0.013 | 1 | src/lib/quiz/cosmic-vibe.ts |
#07081a | chart-surface-soft, layer-deep (#0c0619) | 0.013 | 1 | src/app/share/birth-chart/ShareBirthChartLayout.tsx |
#1f3f2f | lunary-success-800, tint-success-edge (#293d2f) | 0.013 | 1 | src/lib/quiz/cosmic-vibe.ts |
#eefcff | lunary-success-50 (#f6f9f7) | 0.013 | 1 | src/app/grimoire/wheel-of-the-year/page.tsx |
#0d0d0d | color-bg, lunary-bg (#0a0a0a) | 0.014 | 1 | utils/og/symbols.ts |
#e8ecff | chart-backdrop-mid (#f2ecfa) | 0.014 | 1 | src/components/charts/chartTheme.ts |
#121208 | lunary-success-950, tint-success (#0c120e) | 0.015 | 1 | src/lib/instagram/design-system.ts |
#120808 | lunary-error-950, tint-error (#180707) | 0.015 | 1 | src/lib/instagram/design-system.ts |
#b8b8e8 | lunary-secondary-200, tint-secondary-edge (#babaf3) | 0.016 | 1 | src/lib/instagram/ig-utils.tsx |
#120f08 | lunary-success-950, tint-success (#0c120e) | 0.016 | 1 | src/lib/instagram/design-system.ts |
#1a0612 | lunary-rose-950, tint-rose (#1b030b) | 0.016 | 1 | src/lib/quiz/cosmic-vibe.ts |
#0a0b12 | color-bg, lunary-bg (#0a0a0a) | 0.017 | 1 | src/app/share/birth-chart/ShareBirthChartLayout.tsx |
#1c0a28 | content-primary (#1a0f2e) | 0.018 | 1 | src/lib/instagram/design-system.ts |
#0f0a1a | chart-surface-soft, layer-deep (#0c0619) | 0.018 | 1 | utils/og/symbols.ts |
#2a0a0a | lunary-error-900, tint-error-mid (#2f0e0e) | 0.018 | 1 | src/lib/quiz/cosmic-vibe.ts |
#12060a | lunary-error-950, tint-error (#180707) | 0.019 | 1 | src/app/share/birth-chart/ShareBirthChartLayout.tsx |
#2d1f4e | chart-text (#2c1f44) | 0.019 | 1 | utils/og/symbols.ts |
#100820 | chart-surface-soft, layer-deep (#0c0619) | 0.019 | 1 | src/lib/instagram/design-system.ts |
#ddd6fe | lunary-secondary-100, tint-secondary (#dcdcf9) | 0.019 | 1 | src/app/grimoire/guides/learn-birth-chart/ChartReadingExampleInteractive.tsx |
#0a1418 | lunary-success-950, tint-success (#0c120e) | 0.019 | 1 | src/lib/instagram/design-system.ts |
#e8e8ff | chart-backdrop-mid (#f2ecfa) | 0.020 | 1 | src/lib/instagram/ig-utils.tsx |
#d25656 | color-error, lunary-error (#d06060) | 0.020 | 1 | src/components/charts/chartTheme.ts |
Typography: the scale you really use.
24 font sizes in use across 18,547 observations. Values off the declared scale are lavender, because off-scale is an inference.
14px
On the declared scale
- Uses
- 3,909
- Through token classes
- 3,907
- As raw values
- 2
- Through variables
- 0
Classes
text-sm
Foundations: the scales hiding in the styles.
| Foundation | Observations | Exact drift (uses) | Off the scale, inferred |
|---|---|---|---|
| Spacing and sizing | 34,665 | 23 (58) | 39 |
| Border radius | 5,101 | 4 (7) | 8 |
| Shadows and elevation | 245 | 0 (0) | 43 |
| Z-index | 175 | 0 (0) | 11 |
| Breakpoints | 2,496 | 2 (9) | 3 |
| Border widths | 3,714 | 1 (1) | 0 |
| Opacity | 373 | 5 (6) | 0 |
| Motion | 396 | 1 (1) | 2 |
Components: what exists, what is duplicated, what gets restyled.
1,668 components, every one of 10,774 JSX use sites resolved to its definition. 100 unused, 20 variant findings, 19 components restyled at their call sites.
<Button>: 164 of 538 uses restyle it
<Button> across 194 files. Filled: the call site overrides a property the component already sets.What the call sites override
Most frequent overriding classes: rounded-full (41), text-xs (21), border-stroke-default (18), text-content-muted (16), hover:bg-surface-card (15), gap-1.5 (12).
Defined in src/components/ui/button.tsx.
15 component names defined more than once
| Name | Defined in | Uses |
|---|---|---|
| <BirthChart> | src/app/grimoire/components/BirthChart.tsx | 2 |
| src/components/BirthChart.tsx | 7 | |
| <Breadcrumbs> | src/components/comparison/Breadcrumbs.tsx | 1 |
| src/components/grimoire/Breadcrumbs.tsx | 29 | |
| <DailyCosmicOverview> | src/components/growth/DailyCosmicOverview.tsx | 0 |
| src/components/profile/DailyCosmicOverview.tsx | 1 | |
| <EmptyState> | src/components/growth/EmptyStates.tsx | 0 |
| src/components/states/EmptyState.tsx | 1 | |
| <GrimoireLayout> | src/app/grimoire/GrimoireLayout.tsx | 2 |
| src/app/grimoire/GrimoireLayoutClient.tsx | 1 | |
| <GuideNudge> | src/components/GuideNudge.tsx | 3 |
| src/components/growth/GuideNudge.tsx | 0 | |
| <InsightCard> | src/components/InsightCard.tsx | 1 |
| src/components/admin/InsightCard.tsx | 1 | |
| <LuckyElements> | src/app/(authenticated)/horoscope/components/LuckyElements.tsx | 0 |
| src/components/LuckyElements.tsx | 0 | |
| <PremiumPathway> | src/components/PremiumPathway.tsx | 3 |
| src/components/growth/PremiumPathway.tsx | 0 | |
| <ReflectionBox> | src/components/growth/ReflectionBox.tsx | 0 |
| src/components/horoscope/ReflectionBox.tsx | 0 | |
| <StreakBanner> | src/components/StreakBanner.tsx | 5 |
| src/components/growth/StreakBanner.tsx | 0 | |
| <TarotReflectionPrompts> | src/components/growth/TarotReflectionPrompts.tsx | 0 |
| src/components/tarot/TarotReflectionPrompts.tsx | 1 | |
| <TarotRitualForPatterns> | src/components/growth/TarotRitualForPatterns.tsx | 0 |
| src/components/tarot/TarotRitualForPatterns.tsx | 1 | |
| <TarotSeasonReading> | src/components/growth/TarotSeasonReading.tsx | 0 |
| src/components/tarot/TarotSeasonReading.tsx | 1 | |
| <TourProvider> | src/components/feature-tour/tour-provider.tsx | 0 |
| src/context/TourContext.tsx | 2 |
Accessibility: static checks, with the evidence.
Contrast is judged for the text and background pairs written together in the source, in every colour context. Static checks only: not a statement of WCAG conformance.
- Failing contrast pairs, default context
- 48
- More that fail only in another context
- 111
- Passing pairs
- 2,781
- Pairs Saer could not judge, and says so
- 7,863
- Focus styles removed with no replacement
- 2
- Files animating with no reduced-motion fallback
- 28
Then the agent asks before it builds.
A real exchange with saer mcp on Lunary, captured on 22 October 2026: a recommendation for a task, then a check of the agent’s draft. Trimmed for display, never reworded. No model is involved in the answers.
Agent calls saer_recommend
task: “add a confirm-delete dialog for removing a saved birth chart”
Saer answers
deterministic: task words + explicit synonym and needs tables, matched on component, hook and function names (and their family and library folder), use across files, declared variant values and folders; ranked by match class, canonical standing, then uses. No model is involved.
Agent calls saer_check on its draft
export function DeleteChart() {
return (
<div style={{ color: "#8458d8", borderRadius: "7px", padding: "16px" }}>
<button className="outline-none" style={{ width: 20, height: 20 }}>×</button>
</div>
);
}Saer answers: verdict DRIFT, 6 findings
- line 3
- line 3
- line 3
- line 4
- line 4
- line 4
Square: exact, deterministic. Circle: inferred, with the nearest steps. Checked as proposed code at this path (a virtual file; the repository is not changed).
See what Saer finds in your codebase.
The private beta is the full audit and saer mcp, for macOS on Apple Silicon. Everyone in the beta gets Pro free while it runs.