Skip to main content

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" with pointer-events: none — purely decorative
  • Settings UI is a simple on/off toggle (no video picker — the randomness is the feature)
  • Preference persists to Supabase profiles table (ambient_enabled boolean 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 cycling
  • src/components/AmbientBackground.css — Opacity, blur, fade-in, crossfade transition animations
  • src/__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 guidelines
  • scripts/process-ambient-videos.sh — FFmpeg pipeline: boomerang loop, 720p downscale, VP9/H.264 export, still frame extraction
  • supabase/migrations/20260210_ambient_background.sqlambient_enabled, ambient_selection columns 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 content
  • src/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 matrix
  • ARCHITECTURE_DECISIONS.md — 6 ADRs covering stack, intent-first posts, RLS, slow-feed, HomeRoom, mutual friendships
  • IMPLEMENTATION_STATUS.md — Current feature status, bug tracker, SHIPWRIGHT status, deferred items, key metrics
  • scripts/check-security.sh — Security scan (SQL injection, eval, hardcoded secrets, localStorage, .select('*'))
  • scripts/generate-snapshot.sh — Codebase snapshot generator for context transfer
  • scripts/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-patterns
  • public/robots.txt — Disallows crawling of authenticated user content routes
  • public/sitemap.xml — Public pages only (landing, /why, /privacy)
  • public/og-image-needed.txt — OG image specs (1200x630, #2d4a2d background)
  • docs/archive/README.md — Archive documentation
  • docs/session-notes/.gitkeep — Session notes directory
  • docs/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 spec
  • scripts/pre-session.sh — Already existed with more comprehensive checks
  • scripts/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 migration
  • supabase/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.dark selectors to :root.light/:root.dark across index.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.css that maps theme variables (--accent-primary, --bg-secondary, etc.) to app variables (--primary, --bg-card, etc.). Scoped border-radius: 0 !important to 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 — existing theme/toggleTheme API 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 standalone useThemeSwitcher hook.

Part 2: Customizer Below Header

  • Route moved: /room/style moved from full-screen route group to standard routes (with header).
  • Customizer.jsx: Mobile layout changed from position: fixed; inset: 0 to position: relative; height: calc(100dvh - var(--header-height, 64px)). Desktop layout changed from height: 100vh to same calc-based height.
  • Navigation.jsx (BottomSheet): Changed from position: fixed to position: absolute, height units from vh to %, drag calculation uses parent height.
  • Header.jsx: Added ResizeObserver that sets --header-height CSS variable on <html>.
  • HomeroomStyleSettings.jsx: Loading/error states use calc(100dvh - var(--header-height, 64px)) instead of 100vh, 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.jsx
  • supabase/migrations/20260209_theme_preference.sql

Files Modified:

  • src/context/ThemeContext.jsx — Expanded to manage mode + theme + Supabase sync
  • src/index.css — CSS selector migration + appearance settings styles
  • src/components/ui/Toast.cssbody.dark:root.dark
  • src/components/ui/ErrorMessage.cssbody.dark:root.dark
  • src/components/notifications/NotificationsPanel.cssbody.dark:root.dark
  • src/styles/themes/theme-experimental-base.css — Variable bridge + scoped border-radius
  • src/styles/themes/theme-neon.css — Light mode selector fix
  • src/styles/themes/theme-forest.css — Light mode selector fix
  • src/styles/themes/theme-circus.css — Light mode selector fix
  • src/components/Account.jsx — Added Appearance section
  • src/components/Header.jsx — Added --header-height ResizeObserver
  • src/components/dev/ThemeSwitcher.jsx — Uses ThemeContext now
  • src/hooks/useThemeSwitcher.js — Deprecated
  • src/App.jsx — Moved /room/style to standard routes
  • src/components/customizer/src/components/Customizer.jsx — In-flow layout
  • src/components/customizer/src/components/Navigation.jsx — Absolute positioning
  • src/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 to api.anthropic.com/v1/messages with the site owner's ANTHROPIC_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 apiKey state, localStorage persistence, and API key input UI. Now calls /.netlify/functions/ai-style instead 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 endpoint
  • netlify.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 returns null for invalid data so DEFAULT_TOKENS fill in.
  • Corrupted data handling: computeStyle() wrapped in try/catch — returns DEFAULT_STYLE on failure instead of crashing. Both StyleProvider and useStyleFor validate tokens before computing.
  • Loading states: StyleProvider now exposes styleLoaded and fetchError. useHomeroomStyle exposes loading flag. HomeroomStyleSettings shows 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 — Added validateTokens, safeTokens, try/catch in computeStyle, styleLoaded/fetchError state
  • src/hooks/useHomeroomStyle.js — Exposed loading and fetchError from context
  • src/pages/HomeroomStyleSettings.jsx — Added loading/error early returns
  • src/components/Post.jsx — Wrapped token-styled wrapper with StyleErrorBoundary
  • src/components/HomeRoom.jsx — Wrapped token-styled module card with StyleErrorBoundary, 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 by JSON.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 a useRef-based JSON key comparison so that distinct object references with identical token values don't trigger useMemo recomputation. This is critical for feed rendering where usePostStyleFor creates new object references per render.
  • React.memo on Post: Custom comparison checks post.id, content, edited_at, post_style, isSaved, session.user.id, and authorIntentStyles — prevents re-renders when sibling posts update.
  • React.memo on HomeRoomModule: Prevents re-renders when sibling modules' collapse/state changes.

Files Modified:

  • src/contexts/StyleContext.jsx — Added LRU cache, optimized useStyleFor with stable key ref
  • src/components/Post.jsx — Wrapped export with memo and custom comparison
  • src/components/HomeRoom.jsx — Wrapped HomeRoomModule with memo

[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 — Added StyleVarsInjector component, rendered inside StyleProvider

[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 — Added useModuleStyle import, rewrote HomeRoomModule rendering with per-module style priority, removed unused StyledCard import

[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 ModuleItem child component so each module row can call useModuleStyle independently
  • Added ModuleStyleEditor wrapper that renders ModuleCustomizer full-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 controls
  • src/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 tokenAccentColor prop for token-styled posts
  • PostCornerAccents helper component for decorative corner elements

Files Modified:

  • src/components/Post.jsx — Token style computation, conditional wrapper rendering, corner accents
  • src/components/post-parts/IntentBadge.jsx — Added tokenAccentColor prop support
  • src/index.css — Added .post-token-wrapper and .post-has-tokens styles

[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_tokens inside the existing post_style JSONB 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 merging
  • src/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.jsx
  • src/components/homeroom-styled/StyledAvatar.jsx
  • src/components/homeroom-styled/StyledButton.jsx
  • src/components/homeroom-styled/StyledDivider.jsx
  • src/components/homeroom-styled/index.js

Files Changed:

  • src/components/HomeRoom.jsx — Imports useStyleFor, styled components; applies token-based styles to container, avatar, headings, modules, footer
  • src/index.css — Added @keyframes btnShine animation

[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/style route (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 — Added refreshStyle callback, fetchVersion counter, exposed profileStyle in 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, accepts overrideTokens prop for previewing
  • useStyle() — 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 useFocusTrap hook to: CreateCircleModal, ReportModal, StepBackModal, EditMessageModal, AddRelationshipModal, CreateDynamicCircleModal, AvatarLibraryModal, NewConversationModal, InviteFriendModal, HowItWorksModal, SteppedAwayModal, AuditDetailModal, ReportDetailModal, UserActionModal
  • Added useEscapeKey hook where missing: CreateCircleModal, ReportModal, StepBackModal, NewConversationModal, InviteFriendModal, AuditDetailModal, ReportDetailModal, UserActionModal
  • Added role="dialog", aria-modal="true", and aria-labelledby to overlays/containers missing them
  • Added aria-label="Close" to close buttons that lacked it (AvatarLibraryModal, AuditDetailModal, ReportDetailModal, UserActionModal)

Form Label Fixes:

  • FriendSearchInput: Added aria-label to search input
  • SavePopover: Added aria-label to shelf name input, note input, shelf dropdown trigger, and create shelf button; added aria-expanded to dropdown trigger
  • Post.jsx: Added aria-label to edit textarea, saved note input, save/delete note buttons
  • PostDetail.jsx: Added aria-label to edit textarea, reply input, response input, and sort select
  • InviteFriendModal: Added aria-label to search input
  • CreatePost.jsx: Added aria-label to expand-to-full-editor button

Files Changed:

  • src/components/circles/CreateCircleModal.jsx
  • src/components/report/ReportModal.jsx
  • src/components/friends/StepBackModal.jsx
  • src/components/messaging/EditMessageModal.jsx
  • src/components/relationships/AddRelationshipModal.jsx
  • src/components/circles/CreateDynamicCircleModal.jsx
  • src/components/AvatarLibraryModal.jsx
  • src/components/messaging/NewConversationModal.jsx
  • src/components/circles/InviteFriendModal.jsx
  • src/components/HowItWorks/HowItWorksModal.jsx
  • src/components/messaging/SteppedAwayModal.jsx
  • src/components/admin/AuditDetailModal.jsx
  • src/components/admin/ReportDetailModal.jsx
  • src/components/admin/UserActionModal.jsx
  • src/components/friends/FriendSearchInput.jsx
  • src/components/post-parts/SavePopover.jsx
  • src/components/Post.jsx
  • src/components/PostDetail.jsx
  • src/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-label and .toggle-switch CSS selectors. Changed from conditional render to CSS class-based collapse with max-height transition.
  • BF-08: Previous Posts label wrapping — Same .toggle-label override pattern applied to .previous-toggle.
  • BF-09: My Connections module width — Added max-width: 100%; overflow: hidden; box-sizing: border-box to .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-actions from vertical column to horizontal wrap layout with mobile touch targets.
  • BF-13: Unsave from Saved Posts — Wired onUnsave prop through Post to PostActions with BookmarkMinus icon 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) with margin: auto centering approach.

Quality Checks (QC-04 through QC-09):

  • QC-04: Feed friends-only filter — canViewPost now requires friendIds.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 selectors
  • src/components/Account.jsx — Voice toggle, collapsible settings sections
  • src/components/Post.jsx — Added onUnsave prop
  • src/components/post-parts/PostActions.jsx — Added unsave button
  • src/components/SavedPage.jsx — Wired onUnsave to Post
  • src/components/Feed.jsx — Friends-only canViewPost filter
  • src/components/messaging/ConversationView.jsx — Play icon for resume
  • src/components/messaging/SteppedAwayPrompt.jsx — Play icon for resume
  • src/components/circles/CircleDetail.jsx — Clickable members, message buttons

Documentation Updated:

  • docs/docs/components/PostActions.md — Added onUnsave prop, unsave button behavior
  • docs/docs/components/Post.md — Added onUnsave prop
  • docs/docs/components/SavedPage.md — Updated unsave behavior
  • docs/docs/components/Feed.md — Added friends-only filtering behavior
  • docs/docs/components/ConversationView.md — Updated resume button description
  • docs/docs/features/messaging.md — Updated SteppedAwayPrompt description
  • docs/docs/features/circles.md — Added CircleDetail with clickable members
  • docs/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 Firefox
  • build.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 zips
  • watch.sh — Polls for file changes and auto-rebuilds on save
  • Cross-platform zip: tries zip, then PowerShell Compress-Archive, then 7z

Files Created:

  • extension/build.sh
  • extension/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 — Added builds_on_post relation to fetchNewPosts, fetchPreviousPosts, refetchOwnPost, and handleRealtimePost queries
  • src/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 — Updates get_tier_rate_limit() to allow circle actions for new accounts
  • src/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)
  • onCancelInvite prop added to InviteFriendModal, wired from CircleDetail

Files Changed:

  • src/components/circles/InviteFriendModal.jsx — Rewritten with optimistic invite/revoke flow
  • src/components/circles/CircleDetail.jsx — Passes onCancelInvite handler to modal
  • src/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 — Adds sharing_allowed, content_note, and other missing sharing columns to posts table
  • 20260208_create_circle_rpc.sql — Creates create_circle() RPC function and adds circle_type column to circles
  • 20260208_post_delete_policy.sql — Adds DELETE and INSERT RLS policies for posts table
  • 20260208_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_allowed column 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 columns
  • database/tables/circles.md — Added circle_type column, 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.md
  • database/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 policies
  • database/tables/posts.md — Fixed audience values, can_view_post() param order
  • database/tables/messages.md — Added 4 missing columns, fixed FK targets
  • database/tables/profiles.md — Fixed defaults, updated RLS to block-aware version
  • getting-started/key-concepts.md — Replaced wrong intent names with actual 6 intents
  • database/security.md — Fixed SQL examples, admin model references
  • architecture/file-structure.md — Added missing directories, fixed nonexistent files
  • getting-started/project-structure.md — Updated to match actual directory layout
  • hooks/useFriendship.md — Full rewrite from 2-line stub to complete API docs
  • hooks/index.md — Rewritten to list all 42 hooks (was listing only 16 with wrong names)
  • hooks/useAdminUsers.md — Added auto-fetch clarification
  • components/index.md — Rewritten to list all 26 documented components (was listing only 14)
  • components/Post.md — Fixed authorIntentStyles prop description and access pattern ([post.intent], not [post.user_id][intentCssKey])
  • components/AdvancedComposer.md — Fixed navigation state fields (added 6 missing, removed incorrect voiceData), corrected auto-save storage to IndexedDB
  • components/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