From 13bd7e15224058604bf775e844f92b5a8a0bbff7 Mon Sep 17 00:00:00 2001 From: MiTHRAL Date: Wed, 22 Apr 2026 02:29:25 -0400 Subject: [PATCH] docs: add sanctum-web layout redesign implementation plan --- .../2026-04-22-sanctum-web-layout-redesign.md | 386 ++++++++++++++++++ 1 file changed, 386 insertions(+) create mode 100644 docs/superpowers/plans/2026-04-22-sanctum-web-layout-redesign.md diff --git a/docs/superpowers/plans/2026-04-22-sanctum-web-layout-redesign.md b/docs/superpowers/plans/2026-04-22-sanctum-web-layout-redesign.md new file mode 100644 index 0000000..3445552 --- /dev/null +++ b/docs/superpowers/plans/2026-04-22-sanctum-web-layout-redesign.md @@ -0,0 +1,386 @@ +# sanctum-web Layout Redesign Implementation Plan + +> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking. + +**Goal:** Fork stoatchat/for-web into sanctum-web, fix the root layout so the message area fills the screen properly, and deploy it to mithraic.space/app via Forgejo CI. + +**Architecture:** The root layout lives in two files — `Interface.tsx` (the grid shell) and `Sidebar.tsx` (server list + channel list). Both use Panda CSS (`styled-system/jsx`). We replace the loose flex layout with an explicit CSS Grid, add `min-width: 0` guards on grid children, and wire up a Forgejo Actions pipeline that builds and rsyncs to the VPS on every push to main. + +**Tech Stack:** Solid.js, Vite, TypeScript, Panda CSS (`styled-system/jsx`), pnpm monorepo, Forgejo Actions, rsync + +--- + +## File Map + +| Action | Path | Purpose | +|---|---|---| +| Clone | `git.mithraic.cloud/ad3laid3/sanctum-web` | The fork (already created) | +| Modify | `packages/client/src/Interface.tsx` | Root grid shell — Layout + Content styled components | +| Modify | `packages/client/src/interface/Sidebar.tsx` | Server list + channel list sizing | +| Create | `.forgejo/workflows/deploy.yml` | CI: build + rsync to VPS on push to main | +| Create | `packages/client/.env` | API URLs pointing at mithraic.space services | + +--- + +## Task 1: Clone the fork and add upstream remote + +**Files:** +- Working directory: wherever you keep projects locally + +- [ ] **Step 1: Clone the fork** + +```bash +git clone https://git.mithraic.cloud/ad3laid3/sanctum-web +cd sanctum-web +``` + +- [ ] **Step 2: Add the upstream so you can pull fixes from stoatchat later** + +```bash +git remote add upstream https://github.com/stoatchat/for-web +git fetch upstream +``` + +- [ ] **Step 3: Install dependencies** + +```bash +pnpm install +``` + +- [ ] **Step 4: Confirm dev server starts** + +```bash +cd packages/client +pnpm dev +``` + +Expected: Vite dev server starts, browser opens the app (will show login screen since no backend is configured yet — that's fine). + +- [ ] **Step 5: Commit the baseline (upstream content as-is)** + +```bash +cd ../.. +git add . +git commit -m "chore: initial fork from stoatchat/for-web" +git push origin main +``` + +--- + +## Task 2: Configure environment for mithraic.space + +**Files:** +- Create: `packages/client/.env` + +- [ ] **Step 1: Create the env file** + +```bash +cat > packages/client/.env << 'EOF' +VITE_API_URL=https://mithraic.space/api +VITE_WS_URL=wss://mithraic.space/ws +VITE_MEDIA_URL=https://mithraic.space/media +VITE_PROXY_URL=https://mithraic.space/proxy +EOF +``` + +- [ ] **Step 2: Confirm build succeeds with these env vars** + +```bash +cd packages/client +pnpm build +``` + +Expected: `dist/` folder is created with no errors. + +- [ ] **Step 3: Commit** + +```bash +cd ../.. +git add packages/client/.env +git commit -m "chore: configure env for mithraic.space" +git push origin main +``` + +--- + +## Task 3: Fix the root layout in Interface.tsx + +**Files:** +- Modify: `packages/client/src/Interface.tsx` + +The current `Layout` uses `display: flex` with no explicit column widths, and `Content` uses `width: 100%` which doesn't fill remaining space properly in a flex context. The fix: switch Layout to CSS Grid with `auto 1fr` columns, and replace `width: 100%` on Content with `minWidth: 0` so it respects the grid. + +- [ ] **Step 1: Open `packages/client/src/Interface.tsx` and find the two styled components at the bottom of the file** + +They look like this: +```typescript +const Layout = styled("div", { + base: { + display: "flex", + height: "100%", + minWidth: 0, + }, + // ... +}); + +const Content = styled("div", { + base: { + background: "var(--md-sys-color-surface-container-low)", + display: "flex", + width: "100%", + minWidth: 0, + }, + // ... +}); +``` + +- [ ] **Step 2: Replace `Layout` base styles — switch from flex to grid** + +Change the `Layout` styled component's `base` to: +```typescript +const Layout = styled("div", { + base: { + display: "grid", + gridTemplateColumns: "auto 1fr", + height: "100%", + overflow: "hidden", + }, + variants: { + disconnected: { + true: { + color: "var(--md-sys-color-on-primary-container)", + background: "var(--md-sys-color-primary-container)", + }, + false: { + color: "var(--md-sys-color-outline)", + background: "var(--md-sys-color-surface-container-high)", + }, + }, + }, +}); +``` + +- [ ] **Step 3: Replace `Content` base styles — remove width:100%, add minWidth:0** + +```typescript +const Content = styled("div", { + base: { + background: "var(--md-sys-color-surface-container-low)", + display: "flex", + minWidth: 0, + overflow: "hidden", + }, + variants: { + sidebar: { + false: { + borderTopLeftRadius: "var(--borderRadius-lg)", + borderBottomLeftRadius: "var(--borderRadius-lg)", + overflow: "hidden", + }, + }, + }, +}); +``` + +- [ ] **Step 4: Start the dev server and verify the message area now fills the screen** + +```bash +cd packages/client && pnpm dev +``` + +Expected: The message area takes up the majority of the window. Sidebar stays on the left without overflowing. + +- [ ] **Step 5: Commit** + +```bash +cd ../.. +git add packages/client/src/Interface.tsx +git commit -m "fix: switch root layout to CSS Grid, message area fills remaining space" +git push origin main +``` + +--- + +## Task 4: Fix Sidebar panel widths + +**Files:** +- Modify: `packages/client/src/interface/Sidebar.tsx` + +The Sidebar wraps both the server icon list and the channel list in a single `display: flex` div. We need to give each child an explicit width so they never squeeze or overflow. + +- [ ] **Step 1: Open `packages/client/src/interface/Sidebar.tsx` and find the root return statement** + +It looks like: +```typescript +return ( +
+ + + }> + + + +
+); +``` + +- [ ] **Step 2: Wrap ServerList in a fixed-width container (65px) and the channel sidebar in a 240px container** + +```typescript +return ( +
+
+ channel.unread)} + user={user()!} + selectedServer={() => params.server} + onCreateOrJoinServer={() => + openModal({ type: "create_or_join_server", client: client() }) + } + menuGenerator={props.menuGenerator} + /> +
+ +
+ }> + + + + +
+
+
+); +``` + +- [ ] **Step 3: Check in dev server — server icon column should be narrow (65px), channel list should be 240px, message area fills the rest** + +Expected: Three visually distinct columns. The message area is clearly the widest. + +- [ ] **Step 4: Commit** + +```bash +git add packages/client/src/interface/Sidebar.tsx +git commit -m "fix: explicit 65px server list and 240px channel sidebar widths" +git push origin main +``` + +--- + +## Task 5: Set up Forgejo CI — build and deploy + +**Files:** +- Create: `.forgejo/workflows/deploy.yml` + +This workflow runs on every push to `main`, builds the client, and rsyncs the output to the VPS directory that Caddy serves at `mithraic.space/app`. + +- [ ] **Step 1: Add an SSH deploy key to Forgejo** + +On the VPS, generate a deploy key (if one doesn't exist): +```bash +ssh-keygen -t ed25519 -C "sanctum-web-deploy" -f ~/.ssh/sanctum_web_deploy -N "" +cat ~/.ssh/sanctum_web_deploy.pub >> ~/.ssh/authorized_keys +cat ~/.ssh/sanctum_web_deploy # copy this — it's the private key for the secret +``` + +In Forgejo → `sanctum-web` repo → Settings → Secrets, add: +- `DEPLOY_KEY` = the private key content from above +- `DEPLOY_HOST` = your VPS IP or hostname +- `DEPLOY_USER` = the SSH user on the VPS (e.g. `root` or `deploy`) +- `DEPLOY_PATH` = the path Caddy serves for mithraic.space/app (e.g. `/var/www/sanctum-web`) + +- [ ] **Step 2: Create the workflow file** + +```bash +mkdir -p .forgejo/workflows +``` + +Create `.forgejo/workflows/deploy.yml`: +```yaml +name: Build & Deploy + +on: + push: + branches: [main] + +jobs: + deploy: + runs-on: docker + steps: + - uses: actions/checkout@v4 + + - uses: actions/setup-node@v4 + with: + node-version: '20' + + - name: Install pnpm + run: npm install -g pnpm@10 + + - name: Install dependencies + run: pnpm install + + - name: Build + run: pnpm --filter client build + + - name: Deploy to VPS + env: + DEPLOY_KEY: ${{ secrets.DEPLOY_KEY }} + DEPLOY_HOST: ${{ secrets.DEPLOY_HOST }} + DEPLOY_USER: ${{ secrets.DEPLOY_USER }} + DEPLOY_PATH: ${{ secrets.DEPLOY_PATH }} + run: | + mkdir -p ~/.ssh + echo "$DEPLOY_KEY" > ~/.ssh/deploy_key + chmod 600 ~/.ssh/deploy_key + ssh-keyscan -H "$DEPLOY_HOST" >> ~/.ssh/known_hosts + rsync -avz --delete \ + -e "ssh -i ~/.ssh/deploy_key" \ + packages/client/dist/ \ + "$DEPLOY_USER@$DEPLOY_HOST:$DEPLOY_PATH/" +``` + +- [ ] **Step 3: Commit and push — watch the Actions tab on Forgejo** + +```bash +git add .forgejo/workflows/deploy.yml +git commit -m "ci: build and deploy to VPS on push to main" +git push origin main +``` + +Expected: Forgejo Actions picks up the workflow, builds successfully, and rsyncs `dist/` to the VPS. Visit `mithraic.space/app` — the new layout should be live. + +--- + +## Task 6: Verify the live deployment + +- [ ] **Step 1: Open `mithraic.space/app` in a browser** + +Check: +- Server icon column is narrow on the left +- Channel list is a fixed-width column next to it +- Message area fills the remaining screen width +- No horizontal overflow or clipped panels + +- [ ] **Step 2: Open Sanctum desktop app** + +Since it loads `mithraic.space/app`, it should automatically show the new layout. Verify the same proportions hold in the desktop window. + +- [ ] **Step 3: Test on a narrow browser window (900px wide)** + +Expected: The layout still shows the message area without horizontal scrollbar. If the member list appears (in a text channel), it can collapse or overlap at this width — that's acceptable for v1. + +- [ ] **Step 4: Tag the first release** + +```bash +git tag v1.0.0 +git push origin v1.0.0 +```