Changelog
All notable changes to CommonPlace are documented here.
Changes are logged as they happen during development. At the end of each month, entries are archived to maintain readability.
[2026-02-11] - Ambient Background Video (NF-15-v2 + Supplement)
Type: Feature
Scope: AmbientBackground component, ThemeContext, AppearanceSettings, App layout
Summary: Added an optional ambient looping background video behind the main application UI at very low opacity (6-8%). Reinforces CommonPlace's calm, contemplative identity. Default is OFF per invariant #18 (Defaults Are Moral Decisions). Users enable it via a simple toggle in Appearance settings. 13 ambient scenes (ocean, rain, aurora, fog, bokeh, etc.) are randomly shuffled on each visit and cycle with a smooth crossfade.
Key behaviors:
- 13 ambient backgrounds with per-video
playbackRate(0.35 for regular speed, 0.5 for slightly slowed, 0.7 for very slow source clips) — all feel roughly the same dreamy pace - Random shuffle on mount — a different scene each visit, cycling through the full playlist with 4-second crossfade transitions after every 3 loops
- 6% opacity (8% in dark mode) with
blur(25px),saturate(0.3)— reads as ambient texture, not content - Source clips processed as boomerang loops (forward + reverse) for seamless looping
- Mobile: shows static image instead of video (battery preservation)
prefers-reduced-motion: shows static image instead of video (accessibility)- Component is
aria-hidden="true"withpointer-events: none— purely decorative - Settings UI is a simple on/off toggle (no video picker — the randomness is the feature)
- Preference persists to Supabase
profilestable (ambient_enabledboolean only) - 3-second ease-out fade-in on load
- No analytics or tracking of playback state
Ambient Backgrounds: glittery-bokeh, rain-puddle, water-caustics-large, dust-particles, water-caustics, rain-window, rain-river, aurora, ocean-close, mountain-fog, ocean-waves, tree-shadows, ocean-sunset
Files Created:
src/components/AmbientBackground.jsx— Component with 13 backgrounds, per-video playback rates, Fisher-Yates shuffle, crossfade cyclingsrc/components/AmbientBackground.css— Opacity, blur, fade-in, crossfade transition animationssrc/__tests__/AmbientBackground.test.jsx— 10 tests (8 original + 2 random cycling)public/ambient/— 39 video/image assets (13 backgrounds x 3 files: .webm, .mp4, -still.jpg)public/ambient/README.md— Asset sourcing guidelinesscripts/process-ambient-videos.sh— FFmpeg pipeline: boomerang loop, 720p downscale, VP9/H.264 export, still frame extractionsupabase/migrations/20260210_ambient_background.sql—ambient_enabled,ambient_selectioncolumns on profiles
Files Modified:
src/context/ThemeContext.jsx— Added ambient enabled state, Supabase persistence, localStorage sync (selection state removed — no longer needed)src/components/settings/AppearanceSettings.jsx— Simple toggle for ambient background (replaced video picker)src/App.jsx— Mounted AmbientBackgroundFromTheme before contentsrc/index.css— Ambient-related styles
Migration Required: Run supabase/migrations/20260210_ambient_background.sql in Supabase SQL Editor.
[2026-02-10] - SHIPWRIGHT Alignment (SW-01 through SW-14)
Type: Infrastructure / Documentation
Scope: Project-wide infrastructure, scripts, documentation, meta tags
Summary: Implemented the full SHIPWRIGHT alignment specification — 14 prompts establishing project infrastructure, quality gates, documentation structure, and deployment assets.
Files Created
CLAUDE.md— Replaced with SHIPWRIGHT-format master context file (93 lines, under 150 limit)PROJECT_INVARIANTS.md— All 20 invariants in operational format with violation examples, tests, quick reference table, and feature matrixARCHITECTURE_DECISIONS.md— 6 ADRs covering stack, intent-first posts, RLS, slow-feed, HomeRoom, mutual friendshipsIMPLEMENTATION_STATUS.md— Current feature status, bug tracker, SHIPWRIGHT status, deferred items, key metricsscripts/check-security.sh— Security scan (SQL injection, eval, hardcoded secrets, localStorage, .select('*'))scripts/generate-snapshot.sh— Codebase snapshot generator for context transferscripts/new-feature.sh— Feature scaffold generator (creates spec + prompt templates)scripts/bootstrap.sh— Health check verifying all SHIPWRIGHT infrastructure.cursorrules/.windsurfrules— IDE code generation rules with CommonPlace anti-patternspublic/robots.txt— Disallows crawling of authenticated user content routespublic/sitemap.xml— Public pages only (landing, /why, /privacy)public/og-image-needed.txt— OG image specs (1200x630, #2d4a2d background)docs/archive/README.md— Archive documentationdocs/session-notes/.gitkeep— Session notes directorydocs/audits/bug-tracker-2026-02-06.md— Bug tracker migrated to docs/
Files Modified
index.html— Added Open Graph tags, Twitter Card tags, theme-color meta.gitignore— Added session notes and snapshot exclusions
Directories Created
docs/specs/,docs/prompts/,docs/reports/,docs/audits/,docs/session-notes/,docs/archive/superseded/,docs/archive/exploration/
Existing Scripts Preserved
scripts/check-invariants.sh— Already existed with more comprehensive checks than SHIPWRIGHT specscripts/pre-session.sh— Already existed with more comprehensive checksscripts/post-session.sh— Already existed with more comprehensive checks
[2026-02-09] - Fix Admin Report Functions
Type: Bug Fix
Scope: Admin / Database
Summary:
Consolidated conflicting admin report function migrations. Two migrations (20260202 and 20260207) had incompatible implementations — the newer one used a weaker profiles.is_admin check instead of the proper admin_roles permission system, omitted audit logging, and was missing the admin_dismiss_report function entirely. Created a single consolidated migration (20260209_admin_report_functions.sql) with all 3 functions (admin_resolve_report, admin_dismiss_report, admin_escalate_report) using admin_has_permission() checks and log_admin_action() audit trail. Deleted the conflicting 20260207_admin_report_functions.sql.
Files Modified:
supabase/migrations/20260209_admin_report_functions.sql— New consolidated migrationsupabase/migrations/20260207_admin_report_functions.sql— Deleted (conflicting)
Migration Required: Run 20260209_admin_report_functions.sql in Supabase SQL Editor.
[2026-02-09] - Fix Mobile Header Overflow
Type: Bug Fix
Scope: Mobile header
Summary:
Fixed mobile header buttons compressing below 44px touch targets on small screens. Added flex-shrink: 0 to prevent button compression, overflow: hidden as a safety net, and a @media (max-width: 359px) rule to tighten padding/gaps on ultra-small screens. Account tabs overflow was already handled (horizontal scroll + fade indicators).
Files Modified:
src/index.css— Mobile header CSS fixes
[2026-02-09] - Site-Wide Theme System & Customizer Layout
Type: Feature, Refactor
Scope: ThemeContext, CSS themes, Account Settings, Customizer layout, Header
Summary: Added a user-facing theme system with 4 themes (Default, Neon Line Art, Forest, Spooky Circus) and an Appearance section in Account Settings. Themes persist to Supabase for cross-device sync. Also moved the style customizer pages to render below the header instead of taking over the full screen.
Part 1: Theme System
- CSS selector unification: Migrated all
body.light/body.darkselectors to:root.light/:root.darkacrossindex.css,Toast.css,ErrorMessage.css,NotificationsPanel.css. Updated theme light-mode selectors from[data-theme="light"]to:root.theme-*.light. - CSS variable bridge: Added bridge in
theme-experimental-base.cssthat maps theme variables (--accent-primary,--bg-secondary, etc.) to app variables (--primary,--bg-card, etc.). Scopedborder-radius: 0 !importantto layout elements only (no longer applies to avatars, toggles, etc.). - ThemeContext expanded: Now manages both color mode (
light/dark/system) and site theme (default/neon/forest/circus). Applies classes to<html>, syncs to localStorage and Supabase (debounced). Backward-compatible — existingtheme/toggleThemeAPI preserved. - AppearanceSettings component: New settings panel with color mode toggle (System/Light/Dark) and 2x2 theme picker grid with color swatches.
- Account.jsx: Added Appearance collapsible section between Profile and Experience.
- Dev ThemeSwitcher updated: Now uses
useTheme()from ThemeContext instead of standaloneuseThemeSwitcherhook.
Part 2: Customizer Below Header
- Route moved:
/room/stylemoved from full-screen route group to standard routes (with header). - Customizer.jsx: Mobile layout changed from
position: fixed; inset: 0toposition: relative; height: calc(100dvh - var(--header-height, 64px)). Desktop layout changed fromheight: 100vhto same calc-based height. - Navigation.jsx (BottomSheet): Changed from
position: fixedtoposition: absolute, height units fromvhto%, drag calculation uses parent height. - Header.jsx: Added ResizeObserver that sets
--header-heightCSS variable on<html>. - HomeroomStyleSettings.jsx: Loading/error states use
calc(100dvh - var(--header-height, 64px))instead of100vh, removed hardcoded background colors.
Migration Required
Run supabase/migrations/20260209_theme_preference.sql in Supabase SQL Editor to add site_theme and color_mode columns to profiles table.
Files Created:
src/components/settings/AppearanceSettings.jsxsupabase/migrations/20260209_theme_preference.sql
Files Modified:
src/context/ThemeContext.jsx— Expanded to manage mode + theme + Supabase syncsrc/index.css— CSS selector migration + appearance settings stylessrc/components/ui/Toast.css—body.dark→:root.darksrc/components/ui/ErrorMessage.css—body.dark→:root.darksrc/components/notifications/NotificationsPanel.css—body.dark→:root.darksrc/styles/themes/theme-experimental-base.css— Variable bridge + scoped border-radiussrc/styles/themes/theme-neon.css— Light mode selector fixsrc/styles/themes/theme-forest.css— Light mode selector fixsrc/styles/themes/theme-circus.css— Light mode selector fixsrc/components/Account.jsx— Added Appearance sectionsrc/components/Header.jsx— Added--header-heightResizeObserversrc/components/dev/ThemeSwitcher.jsx— Uses ThemeContext nowsrc/hooks/useThemeSwitcher.js— Deprecatedsrc/App.jsx— Moved/room/styleto standard routessrc/components/customizer/src/components/Customizer.jsx— In-flow layoutsrc/components/customizer/src/components/Navigation.jsx— Absolute positioningsrc/pages/HomeroomStyleSettings.jsx— Header-aware layout
[2026-02-08] - AI Style Customizer: Server-Side API Proxy
Type: Enhancement
Scope: AI customizer, Netlify Functions, infrastructure
Summary: Moved AI-powered style customization from direct browser-to-Anthropic API calls (requiring each user to enter their own API key) to a server-side proxy via Netlify Functions. Users no longer see an API key input — the AI chat is immediately available.
- Netlify Function
ai-style: Proxies requests toapi.anthropic.com/v1/messageswith the site owner'sANTHROPIC_API_KEY(set as Netlify environment variable). Includes per-IP rate limiting (10 requests/minute), message count cap (20), and input validation. - AIChat.jsx updated: Removed
apiKeystate, localStorage persistence, and API key input UI. Now calls/.netlify/functions/ai-styleinstead of the Anthropic API directly. - netlify.toml: Added
[functions]directory configuration.
Setup required: Set ANTHROPIC_API_KEY in Netlify dashboard → Site settings → Environment variables.
Files Created:
netlify/functions/ai-style.js
Files Modified:
src/components/customizer/src/components/AIChat.jsx— Removed API key UI, switched to proxy endpointnetlify.toml— Added functions directory
[2026-02-08] - Style System Error Handling & Validation
Type: Reliability
Scope: StyleContext, Post, HomeRoom, HomeroomStyleSettings
Summary: Added error boundaries, token validation, loading states, and corrupted data handling across the style system to prevent bad/corrupted style tokens from crashing the app:
- StyleErrorBoundary: New component that catches rendering errors from token-based styling and silently falls back to default (unstyled) rendering. Wraps token-styled Post rendering and HomeRoomModule rendering.
- Token validation:
validateTokens()checks HSL values are in range (hue 0-360, saturation/lightness 0-100) and rejects non-object/array values.safeTokens()wrapper returnsnullfor invalid data soDEFAULT_TOKENSfill in. - Corrupted data handling:
computeStyle()wrapped in try/catch — returns DEFAULT_STYLE on failure instead of crashing. BothStyleProvideranduseStyleForvalidate tokens before computing. - Loading states:
StyleProvidernow exposesstyleLoadedandfetchError.useHomeroomStyleexposesloadingflag.HomeroomStyleSettingsshows a loading screen while style loads and an error screen with retry button on fetch failure.
Files Created:
src/components/StyleErrorBoundary.jsx
Files Modified:
src/contexts/StyleContext.jsx— AddedvalidateTokens,safeTokens, try/catch incomputeStyle,styleLoaded/fetchErrorstatesrc/hooks/useHomeroomStyle.js— ExposedloadingandfetchErrorfrom contextsrc/pages/HomeroomStyleSettings.jsx— Added loading/error early returnssrc/components/Post.jsx— Wrapped token-styled wrapper withStyleErrorBoundarysrc/components/HomeRoom.jsx— Wrapped token-styled module card withStyleErrorBoundary, deduplicated default rendering
[2026-02-08] - Style Computation Performance Optimization
Type: Performance
Scope: StyleContext, Post, HomeRoom
Summary:
Added LRU cache for computeStyle() and optimized useStyleFor() for feed rendering performance:
- LRU style cache: Module-level
Map(capped at 100 entries) in StyleContext caches computed style results keyed byJSON.stringify(tokens). Identical token sets (common when posts share styles) return cached results instead of recomputing colors, clip-paths, shadows, patterns, and fonts. - Stable cache key in
useStyleFor: Uses auseRef-based JSON key comparison so that distinct object references with identical token values don't triggeruseMemorecomputation. This is critical for feed rendering whereusePostStyleForcreates new object references per render. React.memoon Post: Custom comparison checkspost.id,content,edited_at,post_style,isSaved,session.user.id, andauthorIntentStyles— prevents re-renders when sibling posts update.React.memoon HomeRoomModule: Prevents re-renders when sibling modules' collapse/state changes.
Files Modified:
src/contexts/StyleContext.jsx— Added LRU cache, optimizeduseStyleForwith stable key refsrc/components/Post.jsx— Wrapped export withmemoand custom comparisonsrc/components/HomeRoom.jsx— WrappedHomeRoomModulewithmemo
[2026-02-08] - CSS Custom Properties Export (StyleVarsInjector)
Type: Feature
Scope: StyleContext, CSS
Summary:
Added StyleVarsInjector inside StyleProvider that automatically exports the current user's computed style tokens as CSS custom properties on document.documentElement. All properties use the --cp- prefix (CommonPlace) to avoid collision with existing CSS variables.
Available properties:
- Colors:
--cp-primary,--cp-secondary,--cp-tertiary,--cp-background,--cp-surface,--cp-text,--cp-text-muted,--cp-text-surface,--cp-text-surface-muted,--cp-border,--cp-glow - Sizing:
--cp-corner-radius,--cp-border-width,--cp-panel-padding,--cp-element-gap - Typography:
--cp-font-family,--cp-heading-weight,--cp-body-size - Effects:
--cp-shadow,--cp-transition
Properties are cleaned up on unmount (e.g. logout). Any CSS rule can reference these without importing hooks.
Files Modified:
src/contexts/StyleContext.jsx— AddedStyleVarsInjectorcomponent, rendered insideStyleProvider
[2026-02-08] - Render Styled Modules with Per-Module Tokens
Type: Feature
Scope: HomeRoom, module rendering
Summary:
Updated HomeRoomModule to render with per-module style tokens using useModuleStyle and useStyleFor. Each module computes its effective style (from its own tokens + inheritance from Homeroom), then applies clip-path border wrapper, glass/backdrop-blur, custom colors, fonts, and heading styles. Falls back to room-level tokenStyle when no per-module style exists, and to default CSS rendering when neither is available.
Replaced the StyledCard wrapper approach with direct inline styles using the clip-path border wrapper technique, supporting glass blur and per-module font family.
Files Modified:
src/components/HomeRoom.jsx— AddeduseModuleStyleimport, rewroteHomeRoomModulerendering with per-module style priority, removed unusedStyledCardimport
[2026-02-08] - ModuleCustomizer Integration in ModuleManager
Type: Feature
Scope: ModuleManager, style system
Summary: Integrated the ModuleCustomizer into the ModuleManager page for per-module style customization. Each enabled module now has a paintbrush button to open a full-screen style editor, and an inheritance mode selector to control how module tokens merge with the parent Homeroom style.
- Extracted
ModuleItemchild component so each module row can calluseModuleStyleindependently - Added
ModuleStyleEditorwrapper that rendersModuleCustomizerfull-screen - Per-module inheritance selector (Match Room, Room Colors, Room Shapes, Custom)
- Style button with visual indicator when module has custom tokens
- CSS for
.module-style-btn,.inherit-select
Files Modified:
src/components/ModuleManager.jsx— Added ModuleCustomizer overlay, ModuleItem/ModuleStyleEditor components, inheritance controlssrc/index.css— Added module style button and inherit select styles
Files Created:
docs/docs/components/ModuleManager.md
[2026-02-08] - useModuleStyle Hook
Type: Feature
Scope: Hooks, style system, modules
Summary:
Created useModuleStyle hook for managing style tokens on individual Homeroom modules. Supports four inheritance modes (full, colors, shapes, none) that control how module tokens merge with the parent Homeroom style. effectiveStyle returns the computed merged tokens, and saveStyle persists both tokens and inheritance mode to the home_room_modules table.
Requires a migration to add style_tokens (JSONB) and inherit_style (TEXT) columns to home_room_modules.
Files Created:
src/hooks/useModuleStyle.js
[2026-02-08] - Render Token-Styled Posts in Feed
Type: Feature
Scope: Post rendering, feed display
Summary:
Updated the Post component to apply token-based visual styles when posts have style_tokens in their post_style JSONB. Posts created with the Advanced Composer's PostCustomizer now render with custom colors, clip-path shapes, shadows, fonts, corner accents, and glow effects. Posts without tokens render unchanged.
- Uses
usePostStyleFor(post)to extract tokens,useStyleFor(tokens)to compute derived values - Clip-path border wrapper technique for non-rounded corner shapes (hexagon, diamond, etc.)
- Corner accent decorations (decorative corner lines) when enabled
- IntentBadge accepts optional
tokenAccentColorprop for token-styled posts PostCornerAccentshelper component for decorative corner elements
Files Modified:
src/components/Post.jsx— Token style computation, conditional wrapper rendering, corner accentssrc/components/post-parts/IntentBadge.jsx— AddedtokenAccentColorprop supportsrc/index.css— Added.post-token-wrapperand.post-has-tokensstyles
[2026-02-08] - PostCustomizer in Advanced Composer
Type: Feature
Scope: Advanced Composer, style system
Summary: Integrated the token-based PostCustomizer into the Advanced Composer. Users can now open a full-screen style customizer from the "Customize Style" panel to apply advanced visual tokens (colors, patterns, shapes, typography, effects) to individual posts.
- Added
usePostStyle()hook call for token-based style management alongside the existing simple style system - Full-screen PostCustomizer overlay accessible via "Advanced Style" button in the style panel footer
- Token style indicator with remove button when advanced style is active
- Token data stored as
style_tokensinside the existingpost_styleJSONB column - Draft saves (both auto and manual) include token style data
- Posts rendered via
usePostStyleFor()can extract tokens from the JSONB for rendering
Files Modified:
src/components/AdvancedComposer.jsx— Added PostCustomizer integration, token style state, submission mergingsrc/index.css— Added styles for.advanced-style-btn,.token-style-indicator,.token-style-badge,.token-style-clear-btn
[2026-02-08] - usePostStyle Hook
Type: Feature
Scope: Hooks, style system
Summary:
Created usePostStyle hook for managing post-specific style tokens during composition in the Advanced Composer. Provides matchHomeroom to copy the user's Homeroom style onto a post, clearStyle to remove customization, and setPostStyle for direct token updates (e.g., from a customizer). Also exports usePostStyleFor(post) to extract style_tokens from existing posts for rendering.
Files Created:
src/hooks/usePostStyle.js
[2026-02-08] - Apply Token-Based Styles to HomeRoom UI
Type: Feature
Scope: HomeRoom, styled components
Summary:
Created shared styled components (StyledCard, StyledAvatar, StyledButton, StyledDivider) that render using the Homeroom token system. Updated HomeRoom.jsx to apply token-based styling when the room owner has a custom homeroom_style:
- Container: Background color, pattern SVG, font family from tokens
- Avatar: Custom shape (hexagon, diamond, star, etc.) via clip-path, border width, glow effect
- Module cards: Surface color, clip-path corners, border, shadow, corner accents, heading ornaments
- Headings: Custom weight, transform, letter-spacing, glow, ornament prefix
- Dividers: Gradient, glow, ornament, solid, dashed styles
- Footer/muted text: Uses token muted color
All styling is opt-in — rooms without homeroom_style render with the existing CSS-variable system unchanged. Uses useStyleFor(roomOwner.homeroom_style) so visitors see the room owner's style, not their own.
Also added a "Style Room" button (paintbrush icon) in the owner's header actions linking to /room/style.
Files Created:
src/components/homeroom-styled/StyledCard.jsxsrc/components/homeroom-styled/StyledAvatar.jsxsrc/components/homeroom-styled/StyledButton.jsxsrc/components/homeroom-styled/StyledDivider.jsxsrc/components/homeroom-styled/index.js
Files Changed:
src/components/HomeRoom.jsx— ImportsuseStyleFor, styled components; applies token-based styles to container, avatar, headings, modules, footersrc/index.css— Added@keyframes btnShineanimation
[2026-02-08] - Homeroom Style Settings Page
Type: Feature
Scope: Pages, routing, customizer integration
Summary:
Created HomeroomStyleSettings page that renders the full HomeroomCustomizer with the user's saved style tokens. On save, writes tokens via useHomeroomStyle().saveStyle() and navigates to the user's HomeRoom. On cancel, navigates back. Shows a loading overlay while saving and an error toast on failure. Route added at /room/style as a full-screen flow (no header) since the customizer takes over the entire viewport.
Files Created:
src/pages/HomeroomStyleSettings.jsx
Files Changed:
src/App.jsx— Added import and/room/styleroute (full-screen, no header)
[2026-02-08] - useHomeroomStyle Hook
Type: Feature
Scope: Hooks, style system
Summary:
Created useHomeroomStyle hook for reading and writing Homeroom style tokens. Reads the current saved style from StyleContext and writes updates directly to profiles.homeroom_style, then triggers a context refresh so all useStyle() consumers update immediately. Also enhanced StyleContext to expose refreshStyle callback and profileStyle (raw tokens) for this hook's use.
Exports:
useHomeroomStyle()— Returns{ style, saveStyle, clearStyle, saving, error, hasCustomStyle }
Files Created:
src/hooks/useHomeroomStyle.js
Files Changed:
src/contexts/StyleContext.jsx— AddedrefreshStylecallback,fetchVersioncounter, exposedprofileStylein context value
[2026-02-08] - StyleContext Provider
Type: Feature
Scope: Style system, contexts
Summary:
Created a StyleContext that provides computed style values (colors, clip paths, shadows, patterns, fonts) derived from the customizer token system. The context fetches the current user's homeroom_style from their profile and computes derived values using the customizer utilities. Falls back to DEFAULT_TOKENS when no custom style is set.
Exports:
StyleProvider— Wraps authenticated routes, fetches user style from profile, acceptsoverrideTokensprop for previewinguseStyle()— Returns computed style values for the current user (safe to call outside provider — returns defaults)useStyleFor(tokens)— Computes style for another user's tokens (for viewing others' HomeRooms/posts)
Files Created:
src/contexts/StyleContext.jsx
Files Changed:
src/App.jsx— Wrapped authenticated routes with<StyleProvider>
[2026-02-08] - Accessibility: Modal Focus Traps and Form Labels
Type: Accessibility
Scope: All modal components, form inputs
Summary: Added keyboard focus traps, escape key handling, and ARIA attributes to 13 modal components that were missing them. Also audited and fixed form label associations across the app for screen reader compatibility.
Modal Accessibility (13 modals fixed):
- Added
useFocusTraphook to: CreateCircleModal, ReportModal, StepBackModal, EditMessageModal, AddRelationshipModal, CreateDynamicCircleModal, AvatarLibraryModal, NewConversationModal, InviteFriendModal, HowItWorksModal, SteppedAwayModal, AuditDetailModal, ReportDetailModal, UserActionModal - Added
useEscapeKeyhook where missing: CreateCircleModal, ReportModal, StepBackModal, NewConversationModal, InviteFriendModal, AuditDetailModal, ReportDetailModal, UserActionModal - Added
role="dialog",aria-modal="true", andaria-labelledbyto overlays/containers missing them - Added
aria-label="Close"to close buttons that lacked it (AvatarLibraryModal, AuditDetailModal, ReportDetailModal, UserActionModal)
Form Label Fixes:
- FriendSearchInput: Added
aria-labelto search input - SavePopover: Added
aria-labelto shelf name input, note input, shelf dropdown trigger, and create shelf button; addedaria-expandedto dropdown trigger - Post.jsx: Added
aria-labelto edit textarea, saved note input, save/delete note buttons - PostDetail.jsx: Added
aria-labelto edit textarea, reply input, response input, and sort select - InviteFriendModal: Added
aria-labelto search input - CreatePost.jsx: Added
aria-labelto expand-to-full-editor button
Files Changed:
src/components/circles/CreateCircleModal.jsxsrc/components/report/ReportModal.jsxsrc/components/friends/StepBackModal.jsxsrc/components/messaging/EditMessageModal.jsxsrc/components/relationships/AddRelationshipModal.jsxsrc/components/circles/CreateDynamicCircleModal.jsxsrc/components/AvatarLibraryModal.jsxsrc/components/messaging/NewConversationModal.jsxsrc/components/circles/InviteFriendModal.jsxsrc/components/HowItWorks/HowItWorksModal.jsxsrc/components/messaging/SteppedAwayModal.jsxsrc/components/admin/AuditDetailModal.jsxsrc/components/admin/ReportDetailModal.jsxsrc/components/admin/UserActionModal.jsxsrc/components/friends/FriendSearchInput.jsxsrc/components/post-parts/SavePopover.jsxsrc/components/Post.jsxsrc/components/PostDetail.jsxsrc/components/CreatePost.jsx
[2026-02-08] - Spec 23: QA Fixes (BF-07 through BF-15, QC-04 through QC-09)
Type: Bug Fix / Quality
Scope: CSS, Account settings, Feed, Messaging, Circles, Saved Posts, Accessibility
Summary: Completed all remaining items from Spec 23 (QA Fixes). 12 items required code changes, 4 were already implemented, and 1 was determined to be iOS Safari behavior (not a code bug).
Bug Fixes (BF-07 through BF-15):
- BF-07: Voice playback toggle — Fixed label wrapping, double circle knob, and layout shift caused by conflicting generic
.toggle-labeland.toggle-switchCSS selectors. Changed from conditional render to CSS class-based collapse withmax-heighttransition. - BF-08: Previous Posts label wrapping — Same
.toggle-labeloverride pattern applied to.previous-toggle. - BF-09: My Connections module width — Added
max-width: 100%; overflow: hidden; box-sizing: border-boxto.friends-module. - BF-10: Gear icon dark mode — Added
color: var(--text-secondary)to.shelf-manage-btn. - BF-11: Messaging compose text color — Added
color: var(--text-primary)to.message-input-form input. - BF-12: Avatar buttons layout — Changed
.avatar-upload-actionsfrom vertical column to horizontal wrap layout with mobile touch targets. - BF-13: Unsave from Saved Posts — Wired
onUnsaveprop through Post to PostActions withBookmarkMinusicon button. - BF-14: Skip-to-content link — Improved positioning (
top: -100px), added border, transition, and theme-aware colors. - BF-15: MeBook dialog centering — Replaced
transform: translate(-50%, -50%)centering (which conflicts with Framer Motion animations) withmargin: autocentering approach.
Quality Checks (QC-04 through QC-09):
- QC-04: Feed friends-only filter —
canViewPostnow requiresfriendIds.includes(post.user_id)for all non-self, non-circle posts. Public posts from strangers no longer appear. - QC-06: Resume button icon — Replaced "Resume" text with
<Play>icon in both ConversationView and SteppedAwayPrompt. - QC-07: Circle member profiles clickable — Avatar and name now link to
/room/:username. Added message button (MessageSquare icon) for non-self, non-blocked members. - QC-08: Account settings cleanup — Restructured into 3 collapsible sections: "Profile & Identity" (default open), "Experience", "Privacy & Data".
- QC-09: Mobile frame/overlay — Investigated; determined to be iOS Safari in-app browser behavior, not a code issue.
Already Implemented (verified, no changes needed):
- QC-01 (intent labels), QC-02 (avatar/name links), QC-03 (saved posts inline), QC-05 (message status grouping)
Files Changed:
src/index.css— 10+ CSS fixes across multiple selectorssrc/components/Account.jsx— Voice toggle, collapsible settings sectionssrc/components/Post.jsx— AddedonUnsavepropsrc/components/post-parts/PostActions.jsx— Added unsave buttonsrc/components/SavedPage.jsx— WiredonUnsaveto Postsrc/components/Feed.jsx— Friends-onlycanViewPostfiltersrc/components/messaging/ConversationView.jsx— Play icon for resumesrc/components/messaging/SteppedAwayPrompt.jsx— Play icon for resumesrc/components/circles/CircleDetail.jsx— Clickable members, message buttons
Documentation Updated:
docs/docs/components/PostActions.md— AddedonUnsaveprop, unsave button behaviordocs/docs/components/Post.md— AddedonUnsavepropdocs/docs/components/SavedPage.md— Updated unsave behaviordocs/docs/components/Feed.md— Added friends-only filtering behaviordocs/docs/components/ConversationView.md— Updated resume button descriptiondocs/docs/features/messaging.md— Updated SteppedAwayPrompt descriptiondocs/docs/features/circles.md— Added CircleDetail with clickable membersdocs/docs/features/saved-shelves.md— Added unsave from Saved page
[2026-02-08] - Browser Extension Build Scripts
Type: Tooling
Scope: Browser extension (extension/)
Summary:
Added build.sh and watch.sh scripts for the "Clip to CommonPlace" browser extension. These were referenced in package.json but didn't exist yet.
Features:
build.sh— Packages extension into distributable zips for Chrome and/or Firefoxbuild.sh firefox— Automatically patches manifest for Firefox MV3 compatibility (background scripts instead of service_worker, gecko addon ID)build.sh all— Builds both Chrome and Firefox zipswatch.sh— Polls for file changes and auto-rebuilds on save- Cross-platform zip: tries
zip, then PowerShellCompress-Archive, then7z
Files Created:
extension/build.shextension/watch.sh
Documentation Updated:
docs/docs/features/browser-extension.md— New feature doc for the browser extension
[2026-02-08] - Conflict Safety: Step-Back Schema
Type: Enhancement
Scope: Database schema, RLS policies, conflict safety
Summary:
Added the database columns required for the "step back" feature — a private, temporary break from seeing a friend's posts without blocking them. The frontend hook (useSteppedBack.js) was already fully implemented; this migration adds the missing stepped_back_by, stepped_back_at, stepped_back_until, and stepped_back_reason columns to the friendships table. Also updated the posts SELECT RLS policy to filter out posts from stepped-back friends.
Files Changed:
supabase/migrations/20260208_stepped_back_schema.sql— Adds 4 columns to friendships, index, updated posts SELECT policy
Documentation Updated:
docs/docs/database/tables/friendships.md— Added stepped_back columns, Step-Back Feature section
[2026-02-08] - Fix Drawing Draft Save Failures
Type: Bug Fix
Scope: AdvancedComposer, draft system
Summary: Fixed drawing drafts failing to save when storage upload fails. Previously, if the drawing image upload to Supabase Storage failed, the system would attempt to save the raw base64 data URL directly to the database, which would fail due to column size limits. Now the system detects upload failures and shows a clear error message instead of silently failing or crashing.
Files Changed:
src/components/AdvancedComposer.jsx— Return{ uploadFailed: true }sentinel instead of raw base64 on upload failure; all 3 draft save paths (auto-save, manual save, panel save) now check for this and skip/report gracefully
[2026-02-08] - Feed: Add builds_on_post relation + Fix "Click to load" copy
Type: Bug Fix
Scope: Feed queries, ExternalContentCard
Summary:
Added the missing builds_on_post:builds_on_post_id(...) relation to all 4 post queries in Feed.jsx, so posts that build on other posts now include the parent post data (author, content, images). Also changed "Click to load" to "Tap to load" in ExternalContentCard for mobile-first language.
Files Changed:
src/components/Feed.jsx— Addedbuilds_on_postrelation tofetchNewPosts,fetchPreviousPosts,refetchOwnPost, andhandleRealtimePostqueriessrc/components/clips/ExternalContentCard.jsx— Changed "Click to load" to "Tap to load"
[2026-02-08] - Beta: Unlock Circle Features for New Accounts
Type: Enhancement
Scope: Rate limiting, account tiers
Summary: Removed the 7-day waiting period for circle creation and circle invitations during the beta testing phase. New accounts can now use circle features immediately.
Files Changed:
supabase/migrations/20260208_beta_unlock_circles.sql— Updatesget_tier_rate_limit()to allow circle actions for new accountssrc/hooks/useAccountTier.js— Frontend tier restrictions updated to match
[2026-02-08] - Invite Modal UX Improvements
Type: Enhancement
Scope: Circle invitation flow
Summary: Redesigned the circle invite modal for better usability. Invite buttons are now compact icon-only circles that flip to a red revoke (X) button after sending, with optimistic UI updates and visible error feedback.
Changes:
- Invite button is now a compact circular icon button (was a full-width text button)
- After inviting, button changes to red X to revoke the invite
- Revoking deletes the pending invite from
circle_members - Optimistic UI: button state changes immediately, reverts on failure
- Error messages displayed in a banner instead of silent console logging
- Invited friends persist in the list (stored in ref) even after backend refetch
- Display names shown properly (falls back to username if no display name)
onCancelInviteprop added to InviteFriendModal, wired from CircleDetail
Files Changed:
src/components/circles/InviteFriendModal.jsx— Rewritten with optimistic invite/revoke flowsrc/components/circles/CircleDetail.jsx— PassesonCancelInvitehandler to modalsrc/index.css— Circular button styles, revoke variant, error banner
[2026-02-08] - Fix 4 P0 Bugs (Database Migrations)
Type: Bug Fix
Scope: Database schema, RLS policies, RPC functions
Summary: Fixed four app-breaking P0 bugs, all caused by missing database objects. No frontend changes needed — the frontend code was already correct but the database lacked the required functions, policies, and columns.
Migrations Created:
20260208_sharing_allowed_column.sql— Addssharing_allowed,content_note, and other missing sharing columns to posts table20260208_create_circle_rpc.sql— Createscreate_circle()RPC function and addscircle_typecolumn to circles20260208_post_delete_policy.sql— Adds DELETE and INSERT RLS policies for posts table20260208_post_visibility_rls.sql— Replaces posts SELECT policy with audience-aware version (public/friends/circles)
Bugs Fixed:
- P0: Circle creation now works —
create_circle()RPC creates circle + admin member atomically - P0: Post deletion now works — DELETE RLS policy allows authors and admins to delete
- P0: Feed visibility fixed — SELECT policy now enforces audience-based access (friends-only, circle-only)
- P0:
sharing_allowedcolumn added to posts table (was referenced by frontend but missing from DB)
Documentation Updated:
database/tables/posts.md— Removed sharing_allowed warning, updated RLS policies, added new columnsdatabase/tables/circles.md— Addedcircle_typecolumn,create_circle()RPC documentation
[2026-02-07] - Documentation Accuracy Audit and Fixes
Type: Documentation
Scope: Full documentation site accuracy verification
Summary: Exhaustive audit of all 124 documentation files against actual source code. Fixed critical inaccuracies including fabricated database schemas, wrong invariants, incorrect function signatures, and missing columns. All docs now verified against real code.
Critical Fixes:
philosophy/invariants.md— Replaced entirely with correct 20 invariants from CLAUDE.mddatabase/tables/home_room_settings.md— Rewritten from actual migration (was ~85% fabricated)database/tables/home_room_modules.md— Rewritten from actual migration (was ~85% fabricated)database/tables/circles.md— Fixed column names, FK references, RLS policiesdatabase/tables/posts.md— Fixed audience values,can_view_post()param orderdatabase/tables/messages.md— Added 4 missing columns, fixed FK targetsdatabase/tables/profiles.md— Fixed defaults, updated RLS to block-aware versiongetting-started/key-concepts.md— Replaced wrong intent names with actual 6 intentsdatabase/security.md— Fixed SQL examples, admin model referencesarchitecture/file-structure.md— Added missing directories, fixed nonexistent filesgetting-started/project-structure.md— Updated to match actual directory layouthooks/useFriendship.md— Full rewrite from 2-line stub to complete API docshooks/index.md— Rewritten to list all 42 hooks (was listing only 16 with wrong names)hooks/useAdminUsers.md— Added auto-fetch clarificationcomponents/index.md— Rewritten to list all 26 documented components (was listing only 14)components/Post.md— FixedauthorIntentStylesprop description and access pattern ([post.intent], not[post.user_id][intentCssKey])components/AdvancedComposer.md— Fixed navigation state fields (added 6 missing, removed incorrectvoiceData), corrected auto-save storage to IndexedDBcomponents/Feed.md— Fixed default feed mode from "slow" to "normal" (1-hour refresh)
[2026-02-07] - DOC-4: Comprehensive Feature, Component, Hook, and Database Documentation
Type: Documentation
Scope: Full project documentation
Summary: Created comprehensive documentation for all existing CommonPlace features, components, hooks, and database tables. This covers the entire implemented codebase with accurate details sourced from actual code.
Documentation Created:
- 12 feature docs: Intent System, Feed, Posts, Friends, Circles, HomeRoom, MeBook, Voice Narration, Advanced Composer, Saved/Shelves, Messaging, Authentication
- 19 new component docs: SavedPage, Header, Auth, Avatar, Profile, ErrorBoundary, PostDetail, PrivacyCurtain, IntentStylesSettings, AudienceSelector, PostHeader, PostContent, PostActions, PostImages, IntentBadge, SavePopover, Lightbox, ConversationView, NewConversationModal (5 existed from prior session)
- 41 hook docs: All custom hooks in src/hooks/ documented with signatures, parameters, return values, and usage examples
- 44 database table docs: All tables documented with schemas, columns, RLS policies, and relationships
[2026-02-07] - Documentation System Initialized
Type: Documentation
Scope: Project Infrastructure
Summary: Initialized the CommonPlace documentation system using Docusaurus. This provides comprehensive, searchable documentation for all aspects of the project.
Files Changed:
docs/*— New documentation site
Documentation Updated:
- Initial documentation structure created
- Introduction page
- Quick start guide
- Architecture overview placeholder