Commits
- Bump size of react icons
- Split suggestions into reusable component thing
- Mentions tag properly
- Jiggled composers
- rainbow link effect actually shows up
Suggestions come from typeahead.waow.tech (public CORS actor search, no
CSP changes needed); keep-typing displaces the shown rows, which count
as rejected and fly off + explode into sparks.
Co-Authored-By: Rommie Code (Claude Opus 4.8 (1M context))
The font stack ended in `cursive`, so mobile devices (which lack Comic
Sans MS / Chalkboard SE) fell through to a handwriting/script font, and
the trailing sans-serif was unreachable. Embed Comic Neue via Google
Fonts and swap `cursive` for it, giving a guaranteed comic face on
mobile while native Comic Sans still wins on desktop.
Allowlist fonts.googleapis.com (style-src) and fonts.gstatic.com
(font-src) in the CSP for the embed, and document the change plus its
visitor-IP-to-Google trade in security model §9.3.
Co-Authored-By: Rommie Code (Claude Opus 4.8 (1M context))
On mobile the Top Friends sidebar now leads the timeline on the feeds
page, and the guestbook stacks above the post feed (below the tiles) on
a profile page.
Co-Authored-By: Rommie Code (Claude Opus 4.8 (1M context))
The behavioural half. Render paths (home/profile, post decoration, app
chrome) now gate on resolveActiveMode: in `base` mode the custom layers
(tokens/CSS/effects/background) stay on the record but are suppressed, so
switching back to a vibe is lossless instead of a no-op.
The studio's vibe row becomes a real 3-way selector (y2kringe / gyaru /
my custom): picking a vibe sets active=base without deleting your edits,
and any edit flips you back to custom. Adds the reset-colors button and
makes the live preview honour the active mode. Steal-a-look applies as
active=custom, since a stolen look is meant to be worn.
Co-Authored-By: Rommie Code (Claude Opus 4.8 (1M context))
Pure, framework-free domain logic (with tests): an explicit `active` flag
wins; packs that predate the flag fall back to the old "any customization
present -> custom" heuristic. This is the single source of truth the render
paths and studio both consult, so legacy and flagged packs resolve the same way.
Co-Authored-By: Rommie Code (Claude Opus 4.8 (1M context))
Until now "am I showing a plain built-in vibe or my custom look?" was
never stored — it was inferred from whether any customization existed.
That made the choice one-way: once you'd tweaked anything you were stuck
on custom forever. This adds an explicit optional `active: base|custom`
to the lexicon, types, and validator so the state can be stored directly.
Legacy packs omit it and keep being inferred, so nothing regresses.
Co-Authored-By: Rommie Code (Claude Opus 4.8 (1M context))
- All tiles are DASL - things are a bit messy as features are adjusted
- Static tiles in codebase moved to extensible array so adjusting code
is easier
- No more server side voodoo, was just a bad idea
- Themeing engine is much more polished, can generate CSS from settings
- Fully ported over social app features and settings
The chrome theme was only written to <html> by transformPageChunk on the
initial SSR paint, so a saved look never applied during client-side
navigation. The resolved theme now rides locals -> root layout data, and
a layout $effect syncs data-theme/.dark after invalidation.
The studio now previews everything as it's tweaked: the vibe and cursor
apply to the real document (restored on leave), draft effects render
through a live EffectsLayer (canvas effects play on-screen, CSS-only
ones scope onto the preview shell), the home preview consumes the bg and
cursor tokens, a mini link shows link colors, and 8-digit hex built-ins
are trimmed for the color inputs.
- apply selected base theme to document root (SSR cookie + live client update on pick)
- flesh out gyaru light theme tokens
- add customBase to social.twinkl.actor.style lexicon + types/validation
- custom CSS/JS editor with sanitizer feedback and starter templates
- per-author sanitized, scoped postCss decorations in feeds
- show sign form to all logged-in visitors (incl. owner), with login CTA otherwise
- optimistic insert on sign and DID author-link fallback fix
- profile page: side-by-side feed/guestbook layout, cache-bust on sign
- add @atcute/lex-cli codegen (lex.config.js, generate script); derive
lexicon types from generated schemas
The font stack ended in `cursive`, so mobile devices (which lack Comic
Sans MS / Chalkboard SE) fell through to a handwriting/script font, and
the trailing sans-serif was unreachable. Embed Comic Neue via Google
Fonts and swap `cursive` for it, giving a guaranteed comic face on
mobile while native Comic Sans still wins on desktop.
Allowlist fonts.googleapis.com (style-src) and fonts.gstatic.com
(font-src) in the CSP for the embed, and document the change plus its
visitor-IP-to-Google trade in security model §9.3.
Co-Authored-By: Rommie Code (Claude Opus 4.8 (1M context))
The behavioural half. Render paths (home/profile, post decoration, app
chrome) now gate on resolveActiveMode: in `base` mode the custom layers
(tokens/CSS/effects/background) stay on the record but are suppressed, so
switching back to a vibe is lossless instead of a no-op.
The studio's vibe row becomes a real 3-way selector (y2kringe / gyaru /
my custom): picking a vibe sets active=base without deleting your edits,
and any edit flips you back to custom. Adds the reset-colors button and
makes the live preview honour the active mode. Steal-a-look applies as
active=custom, since a stolen look is meant to be worn.
Co-Authored-By: Rommie Code (Claude Opus 4.8 (1M context))
Pure, framework-free domain logic (with tests): an explicit `active` flag
wins; packs that predate the flag fall back to the old "any customization
present -> custom" heuristic. This is the single source of truth the render
paths and studio both consult, so legacy and flagged packs resolve the same way.
Co-Authored-By: Rommie Code (Claude Opus 4.8 (1M context))
Until now "am I showing a plain built-in vibe or my custom look?" was
never stored — it was inferred from whether any customization existed.
That made the choice one-way: once you'd tweaked anything you were stuck
on custom forever. This adds an explicit optional `active: base|custom`
to the lexicon, types, and validator so the state can be stored directly.
Legacy packs omit it and keep being inferred, so nothing regresses.
Co-Authored-By: Rommie Code (Claude Opus 4.8 (1M context))
- All tiles are DASL - things are a bit messy as features are adjusted
- Static tiles in codebase moved to extensible array so adjusting code
is easier
- No more server side voodoo, was just a bad idea
- Themeing engine is much more polished, can generate CSS from settings
- Fully ported over social app features and settings
The chrome theme was only written to <html> by transformPageChunk on the
initial SSR paint, so a saved look never applied during client-side
navigation. The resolved theme now rides locals -> root layout data, and
a layout $effect syncs data-theme/.dark after invalidation.
The studio now previews everything as it's tweaked: the vibe and cursor
apply to the real document (restored on leave), draft effects render
through a live EffectsLayer (canvas effects play on-screen, CSS-only
ones scope onto the preview shell), the home preview consumes the bg and
cursor tokens, a mini link shows link colors, and 8-digit hex built-ins
are trimmed for the color inputs.
- apply selected base theme to document root (SSR cookie + live client update on pick)
- flesh out gyaru light theme tokens
- add customBase to social.twinkl.actor.style lexicon + types/validation
- custom CSS/JS editor with sanitizer feedback and starter templates
- per-author sanitized, scoped postCss decorations in feeds
- show sign form to all logged-in visitors (incl. owner), with login CTA otherwise
- optimistic insert on sign and DID author-link fallback fix
- profile page: side-by-side feed/guestbook layout, cache-bust on sign
- add @atcute/lex-cli codegen (lex.config.js, generate script); derive
lexicon types from generated schemas