Spaces:
Sleeping
Sleeping
Commit History
-
Terms: governing law Western Australia
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>ae663c7 -
Require Terms/Privacy acceptance at signup; record per-version acceptance; fill legal details
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>8078a7f -
Add feedback endpoint, beta inactivity + fair-use cap, privacy/terms pages
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>45814ba -
Web: beta invite-code field, ?invite= link, Beta tester label
Tier-choice screen (onboarding + Settings recall) gets a "Have an invite code?" field, shown only while /beta/status reports the beta open with spots left. ?invite=XXXX links are stashed in localStorage across signup and pre-fill the field, or auto-redeem once an existing user reaches chat (?invite, not ?code, to avoid Supabase's PKCE auth param). /profile/ entitlement now returns beta + beta_access_until so the badge/Settings say "Beta tester" and Stripe-only portal/cancel buttons are hidden for them. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>e59ba56
-
Remove redundant Active character section from web Settings
The top banner already shows and switches the active character. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>467ebdd
-
Add philosophy threads & stories card to chat features drill-down
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>aae4fa7
-
Add preset avatar picker to the web profile bubble wizard
Ports the mobile feature (same 18 PNGs -- 12 human variations plus 6 animals, drawn programmatically, no image-gen API, no per-user cost) into the avatar expansion card. New "...or choose an avatar" horizontal row below the existing "Change your avatar" button; clicking a preset fetches the bundled PNG as a blob and uploads it through the exact same POST /profile/avatar endpoint a picked photo already uses (refactored the existing file-input handler into a shared uploadAvatarBlob() to avoid duplicating that logic). Assets served from the existing /avatars static mount (static/avatars/presets/). Label is translated in all 6 supported languages, matching the existing avatar_upload_btn pattern. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>1982a24
-
Port cross-character knock UI to web (was silently missing)
Backend already computed a cross_character_knock offer on every reply, and the Settings toggle/tour card already existed, but the web chat JS never read the field — the interjection was dropped on the floor. Mobile (KnockWidget/KnockReplyChoice) already had the full interactive flow. Adds a collapsed badge that expands into a Hear it / Not now / Never again card, wired to POST /chat/cross_character_accept, then a second prompt to pick who to keep replying to when the guest isn't the active character — mirroring mobile's flow and field names exactly. Pending knock/choice state is cleared at the top of sendToChat() so a new message auto-declines a stale offer, same as mobile. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>916f33e -
Darken the user chat-bubble text/border color for readability
.user-bub's text sat right at #1f6fbf against its translucent-white background -- low contrast. Reused the already-defined-but-unused --user-bg custom property (#1e3a5f, notably darker) instead of picking a new value from scratch. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>2083c39 -
Rename features-tour "Continue" button to "Close"
The tour is recallable any time via the topbar "?" icon, where "Continue" never made sense (nothing pending to continue to) -- "Close" reads correctly in both the onboarding and recall contexts. Same button/behavior/ styling, text-only change. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>e5772fe -
Rename "Compare plans" to "Manage subscription", vary its heading by context
The recall screen (opened from Settings) was reusing the onboarding screen's "Choose how you'd like to begin" / "You can always change this later in Settings" copy verbatim, which doesn't make sense once you're already in Settings changing it. Onboarding entry keeps its original heading; the Settings-triggered recall now shows "Subscriptions" / "Choose the subscription that fits you best." Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>ef35898 -
Add double-tap mic voice toggle and Settings voice test button
- Double-tapping the mic button toggles "speak replies aloud" (voiceOn) without needing to open Settings -- single tap still records as before. A shared setVoiceOn() keeps the Settings switch and the mic button's visual state in sync regardless of which one changed it, with a temporary "Loud response"/"Silent" label shown above the mic button. Single-vs-double-click needed explicit disambiguation (a short timer on the first click) since both fire as individual 'click' events in a double-click sequence -- naive dual listeners would have briefly started/stopped recording on every double-tap too. - Settings: a "Test voice" button plays the last assistant message with whichever voice is currently selected, so a voice can be previewed without waiting for a new reply. Clicking again while it plays stops it early, per request. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>7935406 -
Increase kill_timeout to 60s; darken/less-transparent user message bubble
- fly.toml: kill_timeout was left at Fly's 5s default, which isn't enough time for a slow in-flight chat turn (complex-dialogue pipeline calls can take well over that) to finish gracefully before being force-killed if autostop decides to stop the machine mid-request -- this happened for real (traced via live logs: SIGINT/SIGTERM 5s apart while a chat/send request was still mid-pipeline, machine exited abruptly, proxy timed out, user saw a broken reply). Bumped to 60s. Free -- only affects shutdown grace period, not whether the machine runs continuously. Also refreshed a stale comment referencing the retired trigger_proactive wake-poll pattern. - static/index.html: .user-bub background opacity 0.16 -> 0.30 (less transparent) and blue changed from the bright neon accent (#3ea6ff) to a darker, more muted blue (#1f6fbf) for both border and text, per feedback. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>d86bbce -
Add voice recording (STT) to the web chat input
- routes_stt.py: /stt now requires a valid Supabase JWT, matching every other route (/chat/send, /tts) -- it previously had no auth check at all, so anyone who found the URL could call it unauthenticated. - static/index.html: new mic button on the chat input row. Tap to record, tap again to stop -- records via MediaRecorder, uploads to /stt, fills the message box with the transcription (not auto-sent, matching mobile's simple tap path, not its hold-to-arm hands-free loop mode). Red pulsing state while recording; a toast on permission denial or network error. The existing speaker on/off toggle + voice picker (already wired to /tts) are untouched. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>d0ab148 -
Fix library expansion sizing, make library header green
- The library bubble expansion's transform:scale() on the parent magnifies everything painted inside it, but absolute units (font-size in rem, border-width in px) don't auto-compensate for that the way percentages do (only the avatar, sized in %, came out correct by accident). Every font-size/border-width inside the expanded bubble is now pre-divided by the 2.381 expand factor so the final rendered size is the intended one: Philosophy/Story borders now match every other bubble's true 2px border, and the character's own name is now deliberately smaller than a normal bubble's name (0.7x), not accidentally 2.381x bigger. - Library screen header: the back arrow and breadcrumb text are now neon green (#1bfdc5), matching the app's accent color. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>413a64a -
Move settings icon next to tier badge; fix clipped library expansion
- Topbar: settings gear now sits directly next to the tier badge (e.g. "Free plan [gear]"), before Library/Profile, so it reads as one unit. - Library bubble expansion: replaced the vertical stack of avatar+name-then-two-sub-circles (which clipped against the circular boundary) with a proper "3 equal circles packed inside 1 circle" triangle layout -- character avatar+name at top, Philosophy bottom-left, Story bottom-right, each with margin from the edge. Expansion factor is now a fixed constant (2.381) rather than a per-bubble formula, derived so each of the 3 inner circles ends up exactly the same size as a normal unexpanded bubble (not just visually close) -- all built characters already share one common size, so this is exact, not approximate. The character's own name reuses the same CSS as every other bubble's name, not a separate/smaller override. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>d0e11ba -
Fix double language-selection bounce, wrong tier-card highlight, hidden Cielo library button
- Supabase's onAuthStateChange listener could fire more than once per page load and re-ran the "no profile name yet -> language screen" redirect every time, even after the user had already moved on to the profile bubble screen and hadn't saved a name yet -- bouncing them back to language selection mid-onboarding. Now only auto-routes once per sign-in (_hasRoutedAfterSignIn, reset on sign-out). - The neon-green .featured border was hardcoded onto the Full-access tier card in HTML; renderTierChoiceCards() only ever updated badge/button text, never moved the highlight to whichever card actually matches the current tier after a tier change. Now toggled dynamically per card. - The Library topbar icon was hidden whenever Cielo was the active character (she has no philosophy threads/stories of her own). Now always visible -- Cielo isn't in INTRO_ROSTER, so tapping it safely opens the plain character roster with nothing pre-expanded. Co-Authored-By: Claude Sonnet 5 <nore…e469d58 -
Merge Library roster and character picker into one in-place view
Tapping a character bubble no longer navigates to a separate full-screen Philosophy/Story picker -- instead that bubble grows in place (CSS scale on the inner .pbub circle, which the physics loop never touches) to reveal the two options nested inside it, while every other bubble keeps floating around it untouched. Tapping a different character swaps the expansion; tapping empty background or the same bubble again collapses it. The topic list (level 2) is unchanged, still its own full view. Also: tier-choice close button is now neon green (#1bfdc5) by default, not just on hover. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>ca1929c -
Fix compare-plans screen: visible close button, no auth-listener bounce
- Give the tier-choice recall screen's close button an actual visual affordance (circular dark chip, higher-contrast color) instead of a bare dim character floating on the background image, which was easy to miss. - Stop the Supabase auth-state listener from unconditionally forcing openChatOrProfile() when the compare-plans screen is what's currently showing. This fires when the page is restored via the browser's Back button after visiting Stripe (checkout/portal) without completing anything -- previously it would show the compare-plans screen for a moment then yank the user into chat regardless. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>f45e5c6 -
Fix Settings getting stuck showing only the API-keys section
closePanel() only cleared the .byok-focus spotlight class when it had been set via the onboarding BYOK path (gated on _byokOnboardingActive). The new compare-plans screen's "Add/Manage my key" button sets the same class via a different path that never sets that flag, so the class was never removed -- Settings stayed locked to just the API-keys section on every future open. Now cleared unconditionally on any settings-panel close. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>a8452de -
Add recallable tier-comparison screen to the web app
Settings' Subscription section now opens a "Compare plans" screen instead of a single upgrade/manage button. Reuses the existing onboarding tier-choice screen/markup rather than duplicating it — same screen now serves both purposes, distinguished by a mode flag. Cards show the current tier, and each card's action branches accordingly (paid -> manage subscription, byok -> switch to free deactivates the key toggle, add/manage key routes to Settings' existing API-keys form). Mirrors the equivalent mobile-app screen built earlier. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>f5d64fa
-
Prevent repeat free trials, auto-return from billing portal, drop trial countdown
- stripe_billing.py: before granting a 7-day trial, check whether this Stripe customer has ever had one before (Stripe itself doesn't dedupe this on trial_period_days) -- a returning customer who canceled before being charged is charged immediately on their next checkout instead of getting another free week. Fails open on a Stripe API error. - routes_billing.py: /billing/portal now accepts the same platform/ redirect_to convention as /billing/checkout, so the mobile app's "Manage subscription" flow can auto-return the same way; /billing/mobile-return gained a neutral "done" case for that path. - Web: tier badge is now plain text on transparent background (no pill), and the trial day-countdown/end-date is gone from both the topbar badge and the Settings panel's subscription status -- both now just read "Subscribed" during the trial too, so nothing in-app prompts an early cancellation. - db_entitlements.py: fixed a stale docstring claiming the webhook handler wasn…98eb097 -
Make feature-card titles neon green on the tour/drill-down screens
Matches the accent already used for the heading and buttons on "What you can do here" and "More about the conversation" -- descriptions stay the existing muted-gray for contrast. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>b0729db -
Fix mobile Stripe return flow, restyle tier cards, streamline BYOK onboarding
- routes_billing.py: /billing/checkout accepts platform/redirect_to from the mobile app and points Stripe's success/cancel URLs at a new dedicated /billing/mobile-return page instead of the raw (unauthenticated, in an in-app browser tab) web SPA. Web's own checkout flow is unaffected. - Tier-choice cards: neon accent text in the main card body (buttons keep white text), reordered Full access -> BYOK -> Free, updated Full access copy. - "Add my API key" now opens Settings directly, focused on just the API-keys section (via a new byok-focus CSS state), instead of routing through the features tour first; closing it continues into the tour. Regular Settings access is unaffected. - Cielo's one-time welcome message now always mentions the help ("?") button in the top bar, in all supported languages. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>81e5750
-
Deterministic Library-tap dispatch + near-duplicate message detection
Tapping a curated philosophy-thread/character-story item in the Library sent canned text as if typed, forcing the classifier to re-guess which thread/chapter it was -- confirmed to guess wrong live. The client now sends an explicit library_kind/library_id instead, resolved via a new util_library_tap.py mapping table (Camus only so far) straight into the existing dispatch branches, skipping the classifier call entirely. Also adds near-duplicate-message detection: compares the current message against the user's last message to this same character and injects an instruction so the character acknowledges a repeat naturally instead of answering as if hearing it fresh. Both features reuse the existing ContextVar prompt-injection pattern (first_contact_instruction). Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>e29b1d6 -
Lighten features-tour copy, add a chat drill-down sub-screen
All 6 top-level cards get a one-line description instead of a paragraph. Tapping "Talk to any philosopher" now opens a new #chat-features-screen (3 info cards: the roster, cross-character knocking, and reading a character's live emotional state via their avatar ring/label) with a "Start chatting" button at the bottom and a back link to the main tour -- same multi-level drill-down idiom the Library screen already uses. Corrected one inaccuracy in the proposed copy before shipping: the actual roster is 6 characters today, not 25 (that's the long-term roadmap number). Verified the "read the mood" claim against the real setTopbarEmotion() code before writing copy around it. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>f0d3f08
-
Revert: Paid skips the features tour, straight to Stripe again
Showing the tour AFTER checkout instead of before would need persisting state across a full round-trip through Stripe's hosted page and touching the auth-restore flow to avoid a race with it deciding chat-vs-wizard on return -- too much for this one edge case. Back to Paid going straight to checkout with no detour; removed the now-orphaned #features-continue-error box. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>b9811b0 -
Show the features tour at first login for all 3 tiers, not just Free/BYOK
Paid previously skipped the tour and redirected straight to Stripe checkout; now it routes through the same _pendingTierAction handoff as the other two, so all first-time users see the tour regardless of which tier they pick. Added #features-continue-error since the checkout call now runs from the tour's Continue button instead of the tier-choice screen directly. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>3d9c63d -
Enlarge the Cielo logo and drop the neon ring on login/language/tier/feature screens
#auth-screen/#reset-screen .logo: 92px -> 112px #lang-screen .logo: 80px -> 100px #tier-choice-screen .logo: 72px -> 88px #features-screen .logo: 64px -> 80px All five also lose their border + box-shadow neon-green ring, per feedback. Left the profile-wizard header icon (#profile-cielo-av) untouched -- not one of the screens named this time. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>8d0e1ac -
Trim features tour to 6 uniform cards in a 3x2 grid
Merged cross-character knocking into the "talk to any philosopher" card's description instead of keeping it separate, and switched #feature-cards from flex-wrap with mixed card widths to a plain 3-column CSS grid so every card is exactly the same size, per feedback. Removed the now- orphaned feature-knock-btn handler. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>3be06fe -
Add a "Features tour" screen after tier choice, recallable from chat
New #features-screen: 7 cards (Cielo, chat with any philosopher, your profile, Photos & Memories, Library, "What Would They Say?", cross- character knocking) laid out 3+2+2 per row. Each card's button navigates straight into that feature and closes the tour, reusing existing functions/click handlers -- no new navigation logic. Chained after the tier-choice screen for the Free and BYOK paths via a _pendingTierAction handoff (the tour's Continue button runs whatever action was queued, or defaults to opening chat if nothing's pending -- the recall case). Paid deliberately skips it and still redirects straight to Stripe, since a checkout redirect is the wrong place to add a detour. Also recallable any time via a new "?" topbar icon. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>0826631 -
Zoom in on cielo_icon.png -- halve the margin around the circle logo
Detected the actual teal ring's bounding box (color-matched, not just brightness, to avoid the soft purple glow skewing the center) and cropped symmetrically around it so the black margin between the circle and the image edge is about half of what it was. Same file is used everywhere (favicon, screen logos, in-chat avatar), so this benefits every usage at once with no HTML/CSS changes needed. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>36dcf38 -
Fix cielo_icon.png -- was an unrelated abstract graphic, not the real logo
Same filename existed in this repo's static/avatars/ but held a generic green atom-swirl image with no relation to the actual Cielo brand mark. Overwritten with the real logo (crescent moon + circle) copied from socrates-mobile/assets/cielo_icon.png, the correct source. No HTML/JS changes needed -- every reference already points at this same filename. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>09c6a99 -
Standardize on cielo_icon.png for every Cielo icon/avatar in the app
Replaces moon_stars.png/cielo_avatar.png/cielo_moon_stamp.png across the favicon, intro/auth/language/tier-choice screen logos, the profile-wizard header icon, and Cielo's actual in-chat avatar (CHARS array). Deliberately left the satire share-card watermark (cielo_moon_stamp.png, drawn via ctx.drawImage in satireRenderCard) untouched -- it's the only place in the file where an image's actual alpha transparency matters (drawn directly onto a canvas over a user's photo); every other spot changed here is a plain <img> circularly cropped by CSS border-radius, which doesn't depend on the source PNG having transparency at all. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>20dda89 -
Fix signup/reset success message being wiped before it's ever shown
_setAuthMode() clears #auth-success's text as its first action (so switching modes doesn't leak a stale message) -- but both the signup and forgot-password success paths set the message THEN called _setAuthMode('signin') to flip back to the sign-in screen, immediately erasing the message they'd just set. Users saw a blank success line and no indication to check their email. Reordered both to call _setAuthMode() first, then set the message. Also added a check-your-spam-folder hint per user report. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>25ef452 -
Raise free-tier satire limit to 5/day, make paid tier unlimited
Direct consequence of the real measured cost ($0.002/call, cheapest feature in the app) -- the old 1/day free and 10/day paid caps weren't buying real cost protection. paid tier now has no entry in _DAILY_LIMITS at all (absent = unlimited, existing behavior, no new logic needed). Updated all copy that mentioned the old numbers: the tier-choice screen's free/paid cards and the Settings status text. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>90a3d3c -
Rewrite tier-card copy as bullet points, fix cost claims, drop redundant button
Verified the proposed tier-page copy against tier_gate.py before shipping it: free tier's "Free photo uploads" implied unlimited (actually 1/day), and paid tier's "Free photo uploads" contradicted its own "10 comments a day" line in the same card. Fixed both to state the real numbers, and reworded "photo uploads" to "photo/news comments" to avoid confusion with the unrelated, always-free Photos & Memories (life-events) feature. Converted all three cards to bullet lists for readability. Removed "Decide later" as a separate button -- confirmed it was functionally identical to "Continue with Free" (both just open chat on the free plan), so it was redundant, not a real third choice; also removed its now-orphaned click handler (would have thrown on page load otherwise). Swapped the tier-choice screen's logo to cielo_avatar.png, matching the earlier profile-wizard icon fix. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>a9421a6 -
Bubble-wizard polish: cleaner Cielo icon, readable greeting, name-first pulse
- #profile-cielo-av now uses cielo_avatar.png (moon centered on a black background) instead of moon_stars.png, whose moon sits in a busy corner crowded by dozens of neon stars -- crops poorly at 52px. - #profile-greeting was muted gray italic text over a 55%-opacity header; bumped header opacity to .8, dropped italic, brightened to var(--text) at .95rem/500 weight so the message is actually legible. - Bubble pulse order (which bubble highlights first, driven by array order in PROFILE_BUBBLES via updatePriorityBubble()) now goes name first, avatar second, matching what was asked. Since BUBBLE_TRANSLATIONS.it/.es/.fr/.de/.pt are looked up by array index against PROFILE_BUBBLES (not by id), the same two-entry swap had to be applied to all 5 language arrays too, or non-English users would see the wrong bubble's label/hint after the reorder. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>6cdf642 -
Show trial days-remaining in Settings, matching the topbar badge
renderSubscriptionStatus() said "Free trial active" with no countdown while the topbar badge already showed "Trial - Nd left" -- inconsistent if a user checked both. Now shows "Free trial active -- N day(s) left (ends <date>). Full access, no charge yet." using the same day-count formula as the badge. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>62d1575 -
Add first-login tier-choice screen and a persistent tier badge (Epic 6)
New #tier-choice-screen shown exactly once, right after a brand-new account finishes the profile wizard (reuses the existing isFirstTime signal -- no new DB column needed): three cards for Free / bring-your- own-key / paid-with-7-day-trial, styled to match the existing dark theme + cyan accent. Each option reuses already-built plumbing (openChat, the Settings panel, startCheckout) rather than anything new on the backend. Deliberately does NOT repeat this screen every login -- agreed instead on a small persistent-but-non-blocking topbar badge (#tier-badge) showing "Free plan" / "Your API key" / "Subscribed" / "Trial - Nd left", tappable to open Settings, refreshed on every chat entry and BYOK key change. Consistent with the anti-nagging design already established for the soft-paywall popup earlier in this project. Generalized startCheckout() to accept a target error-box id so both the Settings panel and the new screen can use it; caught and fixed a bug this introduced (an existing add…6b63b71
-
Add Stripe subscription billing (Epic 5): Checkout, Customer Portal, webhook
Web-only paid tier ($25 AUD/month, 7-day trial): stripe_billing.py wraps the Stripe SDK, routes_billing.py exposes /billing/checkout, /billing/portal, /billing/webhook. get_user_tier() now also treats subscription_status 'trialing' as paid (Stripe uses 'trialing' for the whole trial period, not 'active'). Settings panel on web gets an Upgrade/Manage-subscription section. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>4053b7a
-
strengthen free-tier upsell copy to name what upgrading unlocks
Replace vague "this touched on something deeper" wording with copy that names the free tier's limitation (simple replies) and what upgrading actually unlocks (deeper/complex philosophical discussion, or philosophy threads and character stories), to better motivate conversion. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>dda1d43 -
fic web page for free tier limits fix
ff9acc1 -
fic web page for free tier limits fix
aeebaf1
-
update the free tier message after selecting the story
5b33416
-
Relabel satire topic hint as "context"
1bba299
-
Fix share-card domain to ask-cielo.com
6c0087f -
Add character swap, tone dial, and scope the news scrim fix correctly
- /satire/news accepts a cached headline/article_context so swapping characters on the same story skips OCR and search entirely. - Web panel: setup form hides once a result renders, replaced by a "try another character" avatar row that regenerates in place. - Add a closed-vocabulary tone dial (natural/sarcastic/pessimistic/ optimistic/punitive/happy/sweet) across all three generators, framed as a delivery lens that never overrides the character's actual views. - Scope the darker legibility scrim to news screenshots only (personal photos keep the original lighter fade — they don't have a competing headline at the bottom of the frame). - Swap Cielo's character avatar from the full sky/stars/moon graphic to the app's moon-only icon; the same graphic used for onboarding/ auth branding is untouched.b84b6d5
-
Add optional topic hint to the photo/news satire tool
Lets the user steer the character's reaction toward a specific angle (e.g. "old friends" on a beach photo) instead of a generic take on what's shown. Threaded through generate_photo_satire/generate_news_satire as an extra steering line ahead of the usual satire instructions, and exposed as a 'topic_hint' form field on /satire/photo and /satire/news.26d9808 -
Add a "From chat" tab: turn recent messages into a shareable post
New POST /satire/chat takes the character's last 2-3 replies and writes a standalone social-media post (unlike the photo/news takes, this one must supply its own concrete grounding since there's no photo or headline for the reader) plus a mood label from a fixed 8-word vocabulary. The web panel gains a third tab that pulls recent history from the existing /chat/history endpoint, defaults to the currently active chat character, and renders a mood-driven gradient background with bigger, longer, vertically-centred text in place of the photo, reusing the same stamp/branding/share framework.ad0d375