Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .github/workflows/deploy-staging.yml
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,7 @@ jobs:
DB_DATABASE=cipherbox_staging
JWT_SECRET=${{ secrets.STAGING_JWT_SECRET }}
WEB_APP_URL=${{ vars.STAGING_WEB_APP_URL }}
CORS_ALLOWED_ORIGINS=${{ vars.CORS_ALLOWED_ORIGINS }}
IPFS_PROVIDER=local
IPFS_LOCAL_API_URL=http://ipfs:5001
IPFS_LOCAL_GATEWAY_URL=http://ipfs:8080
Expand Down
9 changes: 5 additions & 4 deletions .planning/STATE.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ See: .planning/PROJECT.md (updated 2026-02-11)
Phase: 12 (first of 7 M2 phases: 11-17)
Plan: Not yet planned
Status: Ready to plan
Last activity: 2026-02-11 -- Completed quick task 009: Fix footer GitHub link
Last activity: 2026-02-11 -- Completed quick task 010: Matrix effect visibility

Progress: [##########..........] 50% (M1 complete, M2 0/7 phases)

Expand Down Expand Up @@ -67,9 +67,10 @@ Recent decisions affecting current work:

### Quick Tasks Completed

| # | Description | Date | Commit | Directory |
| --- | ---------------------- | ---------- | ------- | ----------------------------------------------------------------- |
| 009 | Fix footer GitHub link | 2026-02-11 | c13036d | [009-fix-footer-github-link](./quick/009-fix-footer-github-link/) |
| # | Description | Date | Commit | Directory |
| --- | ------------------------ | ---------- | ------- | --------------------------------------------------------------------- |
| 009 | Fix footer GitHub link | 2026-02-11 | c13036d | [009-fix-footer-github-link](./quick/009-fix-footer-github-link/) |
| 010 | Matrix effect visibility | 2026-02-11 | 74d27b5 | [010-matrix-effect-visibility](./quick/010-matrix-effect-visibility/) |

### Research Flags

Expand Down
235 changes: 235 additions & 0 deletions .planning/quick/010-matrix-effect-visibility/010-PLAN.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,235 @@
---
phase: quick-010
plan: 01
type: execute
wave: 1
depends_on: []
files_modified:
- apps/web/src/components/MatrixBackground.tsx
- apps/web/src/styles/layout.css
- apps/web/src/styles/modal.css
- apps/web/src/components/ui/Modal.tsx
autonomous: true

must_haves:
truths:
- 'Matrix rain effect is visibly bleeding through header, sidebar, and footer backgrounds (NOT main content area)'
- 'Modal backdrop shows matrix rain effect behind the modal container'
- 'Text in header, sidebar, and footer remains readable against the semi-transparent backgrounds'
- 'Modal content remains readable with matrix backdrop'
artifacts:
- path: 'apps/web/src/components/MatrixBackground.tsx'
provides: 'Reusable matrix background with configurable opacity and className'
contains: 'opacity'
- path: 'apps/web/src/styles/layout.css'
provides: 'Reduced background opacities for app shell chrome'
contains: 'rgb(0 0 0'
- path: 'apps/web/src/styles/modal.css'
provides: 'Matrix-compatible modal backdrop styling'
contains: 'rgb(0 0 0'
- path: 'apps/web/src/components/ui/Modal.tsx'
provides: 'Modal with embedded MatrixBackground on backdrop'
contains: 'MatrixBackground'
key_links:
- from: 'apps/web/src/components/ui/Modal.tsx'
to: 'apps/web/src/components/MatrixBackground.tsx'
via: 'import and render inside backdrop div'
pattern: 'import.*MatrixBackground'
---

<objective>
Make the matrix rain canvas effect visually bleed through app shell chrome elements (header, sidebar, footer — NOT the main content area) and add it as a backdrop effect on modal overlays.

Purpose: The matrix rain is currently barely visible because app shell backgrounds are too opaque (0.85) and the canvas opacity is too low (0.25). This change creates a more immersive terminal/cyberpunk aesthetic while keeping the main content area fully readable.

Output: Updated MatrixBackground component with props, reduced layout opacities (except main), and matrix-enhanced modal backdrop.
</objective>

<execution_context>
@./.claude/get-shit-done/workflows/execute-plan.md
@./.claude/get-shit-done/templates/summary.md
</execution_context>

<context>
@apps/web/src/components/MatrixBackground.tsx
@apps/web/src/styles/layout.css
@apps/web/src/styles/modal.css
@apps/web/src/components/ui/Modal.tsx
@apps/web/src/components/layout/AppShell.tsx
@apps/web/CLAUDE.md (CSS conventions: use modern `rgb(0 0 0 / 50%)` notation, never legacy `rgba()`)
</context>

<tasks>

<task type="auto">
<name>Task 1: Add props to MatrixBackground and reduce layout opacities</name>
<files>
apps/web/src/components/MatrixBackground.tsx
apps/web/src/styles/layout.css
</files>
<action>
**MatrixBackground.tsx** -- Add optional props for reuse in different contexts:

1. Add props interface:

```tsx
interface MatrixBackgroundProps {
/** Canvas opacity. Default 0.4 */
opacity?: number;
/** Additional CSS class name */
className?: string;
}
```

2. Update function signature: `export function MatrixBackground({ opacity = 0.4, className }: MatrixBackgroundProps)`

3. Replace the inline `style` object on the canvas element with a CSS class approach. Keep `pointerEvents: 'none'` inline (it's behavioral). Move positioning/sizing to CSS:

```tsx
<canvas
ref={canvasRef}
className={`matrix-canvas${className ? ` ${className}` : ''}`}
aria-hidden="true"
style={{
opacity,
pointerEvents: 'none',
}}
/>
```

4. Add CSS at the top of the file via a small style block, OR better: add to layout.css since that's where the app shell styles live. Add these rules to the TOP of layout.css (before App Shell Grid Container section):

```css
/* ==========================================================================
Matrix Background Canvas
========================================================================== */

.matrix-canvas {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
z-index: -1;
}
```

**layout.css** -- Reduce background opacities so the matrix bleeds through. Use modern CSS color notation (`rgb(0 0 0 / XX%)` not `rgba()`):

- `.app-header` line 33: `background-color: rgba(0, 0, 0, 0.85)` --> `background-color: rgb(0 0 0 / 70%)`
- `.app-sidebar` line 72: `background-color: rgba(0, 0, 0, 0.85)` --> `background-color: rgb(0 0 0 / 70%)`
- `.app-main` line 153: **DO NOT CHANGE** -- keep at current opacity so main content area remains fully opaque with no matrix bleed-through
- `.app-footer` line 168: `background-color: rgba(0, 0, 0, 0.85)` --> `background-color: rgb(0 0 0 / 70%)`

Also fix the one remaining legacy rgba in layout.css while we are here -- the `.modal-container` box-shadow line is in modal.css, not here, so just the four above.

NOTE: The default opacity on MatrixBackground changes from 0.25 to 0.4. Both AppShell.tsx and Login.tsx use `<MatrixBackground />` with no props, so they will both get the new default. This is intentional -- the login page also benefits from a more visible matrix effect.
</action>
<verify>

1. `cd /Users/michael/Code/cipher-box && pnpm --filter web build` compiles without errors
2. Visual check: header, sidebar, footer, and main area show green matrix rain bleeding through their semi-transparent backgrounds
</verify>
<done>

- MatrixBackground accepts optional `opacity` and `className` props
- Default opacity is 0.4 (up from 0.25)
- Canvas positioning uses `.matrix-canvas` CSS class instead of inline styles
- All four layout element backgrounds reduced to 60-70% opacity using modern `rgb()` notation
- Matrix rain visibly shows through all app shell chrome elements
</done>
</task>

<task type="auto">
<name>Task 2: Add matrix effect to modal backdrop</name>
<files>
apps/web/src/components/ui/Modal.tsx
apps/web/src/styles/modal.css
</files>
<action>
**Modal.tsx** -- Add a MatrixBackground instance inside the modal backdrop:

1. Add import: `import { MatrixBackground } from '../MatrixBackground';`

2. Inside the `<Portal>`, render a MatrixBackground inside the backdrop div, BEFORE the modal-container div:

```tsx
<div
className={`modal-backdrop${className ? ` ${className}` : ''}`}
onClick={handleBackdropClick}
>
<MatrixBackground opacity={0.15} className="matrix-canvas--modal" />
<div
ref={modalRef}
className="modal-container"
...
>
```

The low opacity (0.15) keeps it subtle so modal content stays readable. The `className` prop adds `.matrix-canvas--modal` for modal-specific positioning.

**modal.css** -- Update backdrop and add modal matrix positioning:

1. Change `.modal-backdrop` background from `rgba(0, 0, 0, 0.8)` to `rgb(0 0 0 / 70%)` -- slightly more transparent to let matrix show. Keep `backdrop-filter: blur(4px)`.

2. Add `.matrix-canvas--modal` override class (add after the Modal Backdrop section):

```css
.matrix-canvas--modal {
position: absolute;
z-index: 0;
}
```

This overrides the `position: fixed` and `z-index: -1` from `.matrix-canvas` so the canvas sits inside the backdrop's stacking context rather than behind the entire page.

3. Add `position: relative` and `overflow: hidden` to `.modal-backdrop` so the absolute-positioned matrix canvas is contained within it. The backdrop already has `position: fixed` and `inset: 0` so adding `overflow: hidden` is safe.

4. Ensure `.modal-container` has `z-index: 1` (or `position: relative; z-index: 1`) so the modal content sits above the matrix canvas in the backdrop. Currently `.modal-container` has `position: relative` already -- just add `z-index: 1` to it.

5. Fix the legacy `rgba()` in `.modal-container` box-shadow while here:
`box-shadow: 0 25px 50px -12px rgba(0, 0, 0, 0.5), var(--glow-green)` --> `box-shadow: 0 25px 50px -12px rgb(0 0 0 / 50%), var(--glow-green)`

IMPORTANT: The MatrixBackground component creates a new canvas with its own animation loop. Since modals are not always open, this is fine -- the canvas only renders when the modal is open (Modal returns null when `open` is false). The animation loop starts on mount and cleans up on unmount via the existing useEffect cleanup.
</action>
<verify>

1. `cd /Users/michael/Code/cipher-box && pnpm --filter web build` compiles without errors
2. Open any modal (e.g., upload modal, settings) -- backdrop shows subtle green matrix rain behind the modal container
3. Close modal -- no console errors, no lingering animation frames
4. Modal content text remains fully readable
</verify>
<done>

- Modal backdrop renders a dedicated MatrixBackground instance at 0.15 opacity
- Matrix canvas is contained within the backdrop via absolute positioning
- Modal container sits above the matrix canvas via z-index
- Backdrop opacity reduced from 0.8 to 0.7 to let matrix show
- All legacy rgba() calls in modal.css converted to modern rgb() notation
- Matrix canvas cleans up properly when modal closes (existing useEffect cleanup)
</done>
</task>

</tasks>

<verification>
1. `pnpm --filter web build` -- no TypeScript or build errors
2. Visual: App shell shows matrix rain bleeding through header, sidebar, main area, and footer
3. Visual: Opening a modal shows subtle matrix rain on the backdrop overlay
4. Visual: All text remains readable in header, sidebar, footer, main area, and modal content
5. No console errors or warnings related to MatrixBackground or Modal
6. Login page still shows matrix background (now at 0.4 opacity instead of 0.25)
</verification>

<success_criteria>

- Matrix rain visually bleeds through all app shell chrome (header, sidebar, footer, main)
- Modal backdrops display a subtle matrix rain effect
- All text across the application remains readable
- No build errors, no runtime errors
- All CSS uses modern `rgb(0 0 0 / XX%)` notation (no legacy `rgba()`)
</success_criteria>
Comment thread
FSM1 marked this conversation as resolved.

<output>
After completion, create `.planning/quick/010-matrix-effect-visibility/010-SUMMARY.md`
</output>
57 changes: 57 additions & 0 deletions .planning/quick/010-matrix-effect-visibility/010-SUMMARY.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
# Quick Task 010: Matrix Effect Visibility

## Summary

Made the matrix rain background effect visible through the app shell chrome (header, sidebar, footer) and added a dedicated matrix animation to modal backdrop overlays. The app-level animation pauses when a modal is open so only one canvas runs at a time (no performance cost).

## Changes

### MatrixBackground.tsx

- Added `opacity`, `className`, and `paused` props
- Default opacity increased from 0.25 to 0.5
- Animation frame rate increased from ~30fps to ~60fps
- Moved positioning styles from inline to `.matrix-canvas` CSS class
- Pause support: animation loop skips draw calls when `paused=true`

### useModalOpen.ts (new)

- Lightweight global open-modal counter using `useSyncExternalStore`
- `incrementModalCount()` / `decrementModalCount()` called by Modal on mount/unmount
- `useAnyModalOpen()` hook returns true when any modal is open

### AppShell.tsx

- Passes `paused={anyModalOpen}` to MatrixBackground
- App-level animation freezes when modal opens, resumes when it closes

### Modal.tsx

- Renders a dedicated `MatrixBackground` (opacity 0.35) inside the modal backdrop
- Calls `incrementModalCount` on mount, `decrementModalCount` on unmount
- Only one canvas animates at a time

### layout.css

- Added `.matrix-canvas` CSS class (position: fixed, z-index: -1)
- Removed solid `background-color` from `.app-shell` (was blocking the canvas)
- Reduced header/sidebar/footer backgrounds to `rgb(0 0 0 / 50%)`
- Main content area set to `rgb(0 0 0 / 90%)` (stays opaque)
- Converted all `rgba()` to modern `rgb()` notation

### modal.css

- Added `.matrix-canvas--modal` class for absolute positioning inside backdrop
- Reduced backdrop opacity to 40% for more visible matrix effect
- Removed `backdrop-filter: blur` (was obscuring the matrix)
- Added `z-index: 1` to `.modal-container` for proper stacking
- Converted legacy `rgba()` to modern `rgb()` notation

## Verified

- Build compiles without errors
- Matrix rain visible through header, sidebar, and footer
- Main content area remains opaque and readable
- Modal overlay shows dedicated matrix animation
- App-level canvas pauses when modal opens (single canvas performance)
- No console errors on modal open/close
5 changes: 4 additions & 1 deletion apps/api/.env.example
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,10 @@ JWT_SECRET=
# Pinata (IPFS pinning service)
PINATA_JWT=

# CORS - allowed origins for web app (comma-separated for multiple)
# CORS - allowed origins (comma-separated, supports wildcards with *)
# Example: https://app.cipherbox.cc,https://cipher-box-pr-*.onrender.com
# Falls back to WEB_APP_URL if not set
CORS_ALLOWED_ORIGINS=http://localhost:5173
WEB_APP_URL=http://localhost:5173

# IPFS Provider: 'pinata' (default) or 'local' (Kubo node)
Expand Down
24 changes: 21 additions & 3 deletions apps/api/src/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,28 @@ async function bootstrap() {
);

app.use(cookieParser());

// CORS_ALLOWED_ORIGINS supports wildcards (e.g. https://cipher-box-pr-*.onrender.com)
// Falls back to WEB_APP_URL for backwards compatibility
const rawOrigins = process.env.CORS_ALLOWED_ORIGINS || process.env.WEB_APP_URL;
const originEntries = rawOrigins
? rawOrigins.split(',').map((s) => s.trim())
: ['http://localhost:5173', 'http://localhost:4173'];
const exactOrigins = originEntries.filter((o) => !o.includes('*'));
const wildcardPatterns = originEntries
.filter((o) => o.includes('*'))
.map((o) => new RegExp(`^${o.replace(/[.+?^${}()|[\]\\]/g, '\\$&').replace(/\*/g, '.*')}$`));

app.enableCors({
origin: process.env.WEB_APP_URL
? process.env.WEB_APP_URL.split(',')
: ['http://localhost:5173', 'http://localhost:4173'],
origin: (
origin: string | undefined,
callback: (err: Error | null, allow?: boolean) => void
) => {
if (!origin) return callback(null, true);
if (exactOrigins.includes(origin)) return callback(null, true);
if (wildcardPatterns.some((re) => re.test(origin))) return callback(null, true);
callback(new Error(`Origin ${origin} not allowed by CORS`));
},
credentials: true,
});

Expand Down
2 changes: 1 addition & 1 deletion apps/web/.env.example
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# Web3Auth
VITE_WEB3AUTH_CLIENT_ID=your-web3auth-client-id
VITE_WEB3AUTH_CLIENT_ID=BKBrLnxLHHqsis7NVyUhYoFB3RehqEziJRIWfKWFweEycHWaBduqQYZtgpEuKon4M2engmUgiax6k2xcNCbzP7s

# API endpoint
VITE_API_URL=http://localhost:3000
11 changes: 11 additions & 0 deletions apps/web/src/App.css
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,17 @@
overflow: hidden;
}

.login-panel {
position: relative;
z-index: 1;
display: flex;
flex-direction: column;
align-items: center;
padding: var(--spacing-xl) 48px;
background-color: rgb(0 0 0 / 60%);
border: 1px solid rgb(0 208 132 / 10%);
}

/* Logo: > CIPHERBOX with terminal prompt */
.login-container h1 {
font-family: var(--font-family-mono);
Expand Down
Loading
Loading