Changelog
Every meaningful shipped change, newest first. Bug fixes live in patchlog.md; security-impacting changes in security.md.
2026-05-01 — Self-hosted log forwarding pipeline
**Added**:
- `lib/logger/redact.ts` / `core.ts` / `client.ts` / `server.ts` / `LoggerInit.tsx` — wraps `console.debug/log/info/warn/error`, batches (50 / 5s, errors flush immediately), redacts secrets/PII, forwards to the new `log-ingest` Supabase edge function. Original `console.*` still fires. Persistent context via `logger.setContext({...})`, one-shot via `logger.with({...}).warn(...)`, runtime-extensible redaction via `logger.addRedactor(fn)`.
- `instrumentation.ts` — installs the server-side console wrap + `uncaughtException` / `unhandledRejection` handlers at Node-runtime boot. Skipped on Edge runtime.
- `app/error.tsx` — App Router route-level error boundary; logs the caught error with `digest`, `route`, and `boundary: 'app/error.tsx'` context.
- `app/global-error.tsx` — root error boundary; logs at `fatal` level.
- `app/layout.tsx` — mounts `<LoggerInit />` once in `<body>` so the browser console wrap installs as early as possible.
**Notes**:
- No third-party log vendor. Logs land in Supabase (`analytics.app_logs`), readable only by admins via existing `admin.is_admin()` helper.
- 30-day retention, monthly compressed CSV backups to private storage bucket.
- Configurable via `NEXT_PUBLIC_LOG_LEVEL` (default `info` in prod) and `NEXT_PUBLIC_LOG_SAMPLE_INFO` (default `0.1` in prod).
---2026-04-27 — Sitewide theme toggle
**Added**: - `components/ThemeToggle.tsx` — sticky pill switch (bottom-right, `position: fixed`, `z-index: 50`) with sun/moon icons; toggles between `prophetic_dark` and `prophetic_light` via the existing `useTheme()` hook. Uses brand tokens only (`surfaceElevated`, `accent`, `textOnAccent`, `glass.border`, `glass.overlay`). Accessible as `role="switch"` with dynamic `aria-label`. - Mounted in `app/providers.tsx` so it renders on every route. Persistence handled by `AuldromThemeProvider` (existing).
2026-04-27 — Theme palette unification (Phase 1)
Adopted the `landing.css` deep-navy + multi-hue palette as the new `prophetic_dark` brand identity sitewide. Derived a cream-white counterpart for `prophetic_light`. Landing page itself untouched in this phase (still scoped-overrides via `landing.css`); rewrite + promotion follow in Phases 2 & 3.
**Changed**:
- `lib/theme/colors.ts`:
- `Brand.violet` `#A855F7` → `#c27bff`; `Brand.bone` `#E8E4E0` → `#eaf0fb`.
- New `Hues` const — 5-stop mode-invariant brand identity (`#7c6bff`, `#c27bff`, `#ff6fb3`, `#ff9c6b`, `#ffd36b`).
- `ThemeBundle` extended with required fields: `hues`, `stroke: { default; bright }`, `accentDeep`, `accentGlow`.
- `prophetic_dark` rewritten to navy palette (bg `#000`, surfaces `#03050a`/`#060912`, ink `#eaf0fb`/`#8a97b4`, multi-hue accent gradient).
- `prophetic_light` rewritten — cream `#f7f2e8` background, `#0a0d18` text, warm-tinted strokes, same multi-hue accent.
- All three `DreamThemes` (lucid/nightmare/recurring) extended with the new required fields (shared `hues`, accent-derived `stroke`/`accentDeep`/`accentGlow`).
- `lib/theme/gradients.ts`:
- `GradientStops.prophetic`: 2-stop → 5-stop (90deg). `nightmare` / `recurring` second stop updated to new violet.
- `app/globals.css`:
- `--brand-violet` / `--brand-bone` / `--gradient-prophetic` updated; new `--hue-1..5` at `:root`.
- `[data-theme='prophetic-dark']` and `[data-theme='prophetic-light']` blocks rewritten with `--accent-deep`, `--accent-glow`, `--stroke`, `--stroke-bright`.
- `@theme inline` extended to expose all new tokens (`--color-accent-deep`, `--color-accent-glow`, `--color-stroke`, `--color-stroke-bright`, `--color-hue-1..5`).
**Notes**:
- `styled.d.ts` needed no change — `DefaultTheme extends ThemeBundle`.
- 41 consumers of `Brand.violet`/`Brand.bone`/`theme.gradients.prophetic` (modals, sigil, loader, marketing home, contact form, button, empty state, etc.) pick up the new identity automatically with zero edits.
- `Glass` left theme-agnostic — out of scope for this phase.
- `app/landing/landing.css` untouched. The toggle's effect is invisible on `/landing` until Phase 2 rewrites the page off scoped overrides.2026-04-27 — Landing CSS migration + shared primitives themified (Phase 2a)
Migrated `app/landing/landing.css` (228 lines) into `app/globals.css` under `.landing-root` scope, with every raw hex/rgba replaced by `var(--*)`. Themified the shared primitive components. The landing page now responds to the sitewide light/dark toggle (except for visual elements depicting the app, which are intentionally literal pending an iPhone product-asset replacement). **Changed**: - `app/globals.css`: - Added landing legacy var aliases inside both `[data-theme]` blocks (`--bg-0..3`, `--ink`, `--ink-dim`, `--ink-faint`, `--accent-grad`, `--nav-bg`) so existing landing components keep working with no rename. - Added light-mode `--glass-*` overrides (inverted from dark whites to dark-on-cream rgbas). - Migrated all landing utility classes (`.display`, `.mono`, `.eyebrow`, `.section-title`, `.section-sub`, `.accent-text`, `.framed`, `.glass`, `.btn`, `.pill`), the `.glow-stars-mid` / `.glow-stars-near` parallax starfield (~30 hardcoded star colors per layer remapped to `--hue-1..5`; literal `#fff` sparkles preserved), and three keyframes (`landing-twinkle`, `landing-blink`, `landing-floatPhone`). - `app/landing/_components/Mark.tsx` — SVG gradient stops now resolve through `var(--hue-1/3/5)` via inline `style.stopColor`. - `app/landing/_components/Nav.tsx` — sticky nav background `→ var(--nav-bg)`. - `app/landing/_components/ConstellationBg.tsx` — nebula stops, constellation strokes, bright-star fills now resolve through `var(--hue-*)` via inline SVG styles. - `app/landing/_components/Hero.tsx` — left-column page chrome themified (Google Play CTA bg → `var(--glass-light)`; play triangle → `var(--hue-4)`; rating stars → `var(--hue-5)`). **Removed**: - `app/landing/landing.css` (deleted). - `import './landing.css'` from `app/landing/layout.tsx`. **Notes**: - `Hero.tsx` phone mockup interior, two floating side cards, and `ImgPlaceholder.tsx` are intentionally left as literal hex per option B — they depict the app and will be replaced with a real iPhone product photo/video asset. - `Board.tsx`, `SectionHeader.tsx`, `ViewAllLink.tsx`, `PageBg.tsx` needed no edits (already consumed only classes / `var()`s). - Phase 2b will sweep the six section components (`Analysis`, `Features`, `Themes`, `Privacy`, `Pricing`, `Download`).
2026-04-27 — Landing sections themified (Phase 2b)
Swept the six landing section components for hardcoded colors. The full landing page now responds to the sitewide light/dark toggle, with the only remaining literals being intentional per option B (visuals depicting the app). **Changed**: - `app/landing/_components/sections/Themes.tsx` — chart series Water/Chased: `#9a88d8` → `var(--hue-1)`, `#e6b36a` → `var(--hue-4)` (4 occurrences across SVG strokes, circle fills, legend swatches). - `app/landing/_components/sections/Pricing.tsx` — "Keep" tier alt CTA: gradient `#e6b36a → #c49050` → `var(--hue-5) → var(--hue-4)`; glow `rgba(230,179,106,0.5)` → `color-mix(in oklch, var(--hue-4) 50%, transparent)`. Kept `color: '#1a1000'` literal — the amber gradient stays amber in both modes, dark-on-amber reads correctly. - `app/landing/_components/sections/Download.tsx` — App Store + Google Play card backgrounds `rgba(0,0,0,0.4)` → `var(--glass-overlay)` (×2); social-icon backgrounds `rgba(255,255,255,0.02)` → `var(--glass-light)`. **Unchanged** (already theme-aware): - `Analysis.tsx`, `Features.tsx`, `Privacy.tsx` — consumed only utility classes + `var()`s pre-existing. **Intentional remaining literals** (option B): - `Hero.tsx` phone mockup + side cards (slated for real iPhone product asset replacement). - `ImgPlaceholder.tsx` decorative purple field. - `Themes.tsx` white-on-image overlay labels (will read on real photos). - `Pricing.tsx#L58` `#1a1000` Keep-tier CTA text (constant amber gradient in both modes).
2026-04-27 — Landing promoted to home; SiteHeader/Footer overwritten (Phase 3)
The home page (`/`) is now the landing-style composition, and `SiteHeader` / `SiteFooter` are landing-styled sitewide. The `/landing` route is retired (404). Marketing's Alpha/Beta/Diary "Early Program" copy is integrated as a new section. The change affects every marketing route — `/alpha`, `/beta`, `/changelog`, `/contact`, `/diary`, `/diary/[slug]`, `/download`, `/features`, `/help`, `/legal`, `/privacy`, `/terms`, `/terms-of-use` all inherit the new chrome. **Changed**: - `components/site/SiteHeader.tsx` — full rewrite. Sticky landing-styled header (Mark + AULDROM wordmark, glassy `var(--nav-bg)` background, `var(--stroke)` border). Desktop nav: Features / Download / Diary / Help / Contact via Next `<Link>`. Gradient-bordered "Get Auldrom" CTA. Mobile hamburger menu retained at ≤768px. - `components/site/SiteFooter.tsx` — full rewrite. 5-column grid (brand col + Product / Programs / Support / Legal), tagline + 4 social icons, bottom copyright/locale row, `SolomonFooter` retained at the bottom. Collapses to 2 cols at ≤1024px. - `app/(marketing)/page.tsx` — content replaced with the landing composition (`PageBg` + `Hero` + Analysis + Features + Themes×2 + Privacy + Pricing×2 + EarlyProgram + Download), wrapped in `<div className="landing-root">`. `SiteHeader` + `SiteFooter` come from `app/(marketing)/layout.tsx`. - `app/landing/_components/sections/Download.tsx` — stripped the baked-in 4-col footer (now lives in `SiteFooter`); also swapped App Store / Google Play card `rgba(0,0,0,0.4)` backgrounds → `var(--glass-overlay)` for consistency. **Added**: - `app/landing/_components/sections/EarlyProgram.tsx` — `EarlyProgramA` Board with Alpha / Beta / Diary cards linking to `/alpha`, `/beta`, `/diary`. Inserted between `PricingB` and `DownloadA`. **Removed**: - `app/landing/page.tsx` (the `/landing` route). - `app/landing/layout.tsx`. - `app/landing/_components/Nav.tsx` (replaced by the new `SiteHeader`). - `app/(marketing)/_components/HomeParts.tsx` (used only by the retired marketing home). **Notes**: - `app/landing/_components/` survives as a shared component library imported by `(marketing)/page.tsx`. It's no longer a route. A future cosmetic rename (e.g. → `components/home/`) is non-blocking. - Mobile/responsive polish on the home sections themselves is still desktop-first; will need a dedicated pass later. ---
2026-04-21 — Initial scaffold
Split the Auldrom website out of the Expo app into this standalone Next.js 15 repo.
**Added**:
- Next.js 15 App Router + TypeScript + Tailwind v4 + ESLint scaffold.
- styled-components 6 with App Router SSR registry (`app/registry.tsx`) and `ThemeProvider` (`app/providers.tsx`).
- Design token port from the Expo app's `constants/Colors.ts` + `Typography.ts` into `lib/theme/`, surfaced as:
- Tailwind v4 `@theme` colors + font families in `app/globals.css`
- CSS custom properties (`--color-*`, `--gradient-*`, `--font-*`) for raw CSS
- A typed `theme` object for styled-components (extended via `styled.d.ts`)
- 21 UI components ported from React Native to TS styled-components: `AuldromSigil`, `Header`, `SolomonFooter`, `SearchBar`, `Tooltip`, `BrandedLoader`, `EmotionPicker`, `DreamCard`, `DraftCard`, `SwipeableDreamCard`, `Button`, `GlassCard`, `LoadingSpinner`, `SkeletonCard`, `EmptyState`, `ErrorState`, `TabBarIcon`, 3 modals (portal-based), and a 28-icon set (native SVG).
- Supabase SSR wiring (`lib/supabase/{client,server,middleware,database.types}.ts` + root `middleware.ts`).
- API layer port (`lib/api/*`, 8 files) — identical function signatures to the Expo originals; supabase singleton replaced with `createBrowserClient` for client-side use.
- Groq LLM client (`lib/llm/groq.ts`) and tier-access utilities (`lib/utils/tierAccess.ts`) ported verbatim minus env var prefix rename.
- Domain types (`types/*`, 5 files) copied verbatim.
- Full Supabase schema source of truth under `supabase/` — 16 migrations plus `config.toml`.
- Prettier config + `eslint-config-prettier` integrated into the flat ESLint config.
- `.env.example` with all `NEXT_PUBLIC_*` variables.
**Known limitations** / follow-ups:
- Licensed brand fonts (Neue Machina, Satoshi, JetBrains Mono) are referenced in the font stack but not bundled. Drop font files into `public/fonts/` and add `@font-face` declarations in `app/globals.css` to pick them up.
- `FullAnalysisModal` uses a stubbed `useFeatureAccessStub` returning free-tier defaults until `lib/hooks/useFeatureAccess` is re-implemented for Next.js.
- `SwipeableDreamCard` animation parity is approximate — Reanimated spring physics replaced with CSS transitions.
- `contexts/AuthContext`, `contexts/DreamContext`, `contexts/TooltipContext`, `lib/storage`, `lib/responsive`, `lib/analytics`, and `lib/hooks/useFeatureAccess` from the Expo app are **not** ported yet — deferred until a page requires them.