saccoai-client-portal
This skill takes the output of saccoai-design-variations and turns it into a branded review experience for clients. Instead of sharing raw Vercel preview URLs, the client gets a polished portal with variation summaries, screenshots, direct preview links, and a feedback form.
Default output is a single self-contained HTML file the agent can open in the browser and the user can email or share directly. Enterprise mode scaffolds a lightweight Next.js app with auth, real-time feedback storage, and email notifications — deployed to Vercel as a separate project.
Inputs
| Input | Required | Default | Description |
|---|---|---|---|
| Variations path | No | .saccoai/variations/ |
Path to variations output from saccoai-design-variations |
| Mode | No | static |
static (single HTML file) or deployed (Next.js app on Vercel) |
| Client name | No | from project | Display name shown in the portal header |
| Branding | No | saccoai defaults | Logo URL and accent color hex for the portal |
Execution Model
Single-agent sequential. All four phases run in order. No parallelism is needed — the portal is generated from already-available variation data, and feedback collection is a user-triggered step after the client has reviewed.
Preconditions
Before starting, check:
- Variations output exists: Check for
.saccoai/variations/comparison.md. If missing, abort with: "No variations found at.saccoai/variations/comparison.md. Run saccoai-design-variations first to generate design alternatives." - At least one variation present: Parse comparison.md for variation entries. If only the baseline (variation 0 / main) is listed, abort with: "No variations found beyond the baseline. Generate at least one design variation before creating a review portal."
Phase 1: Read Variations
Collect all the data the portal needs before generating any HTML.
-
Parse comparison metadata: Read
.saccoai/variations/comparison.md. Extract for each variation:- Variation number and label
- Branch name
- Preview URL (if present)
- Visual anchor
- Signature element
- Key difference summary
-
Read design briefs: For each variation directory under
.saccoai/variations/variation-{N}-{label-slug}/, readdesign-brief.md. Extract:- Emotional territory
- Typography (display font + body font)
- Color strategy (primary, accent, background hex values)
- Motion plan
- Signature element description
-
Collect screenshots: Check
.saccoai/variations/variation-{N}-{label-slug}/for any screenshot files (.png,.jpg,.webp). Also check for ascreenshot.pngat the variation root. If screenshot files exist, use them. If no screenshots exist and preview URLs are available, use agent-browser to take a fresh screenshot of each preview URL:- Navigate to the preview URL
- Take a full-page screenshot at 1280×800 viewport
- Save to
.saccoai/variations/variation-{N}-{label-slug}/screenshot.png - If no preview URL and no screenshot, note the gap — the portal card will show a placeholder.
-
Resolve portal config: Determine the final values for:
client_name: from user input → fall back to the project directory name → fall back to "Your Project"logo_url: from user input → fall back tohttps://saccoai.com/logo.svgaccent_color: from user input → fall back to#E8411B(saccoai red)portal_mode: from user input → defaultstatic
Phase 2: Generate Portal
Static Mode (default)
Generate a single self-contained HTML file at .saccoai/variations/review-portal.html. All CSS and JavaScript must be embedded inline — no external dependencies. The file must work when opened directly from the filesystem (no server required) and must be functional when emailed as an attachment.
Structure
Header
- Client name in large type
- saccoai logo (or custom logo if provided) in the top-right corner
- Accent color applied to the logo area or header bar
- Subtitle: "Design Review — please share your feedback"
Variation Cards Grid One card per variation (not including the current/main baseline unless explicitly requested). Each card contains:
- Screenshot (or a styled placeholder with the variation label if no screenshot is available)
- Variation label and visual anchor (e.g., "Editorial Warmth — typography-led")
- Key difference sentence (1 line from comparison.md)
- Typography preview: display font name + body font name
- Color swatches: three small circles showing primary, accent, and background hex values
- Signature element description (1 sentence)
- "Preview live" button — opens the Vercel preview URL in a new tab (if URL available; hidden if not)
- Feedback textarea: "Your notes on this direction (optional)"
- "Choose this direction" radio button
Side-by-Side Toggle A toggle control above the cards grid:
- "Single view" (default): cards laid out in a grid
- "Compare two": select any two variation cards and view them side by side at full width
Submit Bar (sticky bottom)
- "Submit review" button — active only when at least one "Choose this direction" radio is selected
- On click: collect all feedback textarea values + chosen variation → serialize to JSON → trigger a browser download of
feedback.json - JSON structure:
{
"submitted_at": "{ISO timestamp}",
"client_name": "{client_name}",
"chosen_variation": "{variation label and number}",
"feedback": {
"variation-1-{slug}": "{textarea content or null}",
"variation-2-{slug}": "{textarea content or null}"
}
}
Responsive Design
The portal must be fully functional on mobile (clients may review on their phone):
- Cards stack to a single column below 768px
- Side-by-side compare is hidden on mobile (toggle shows a notice: "Compare view is available on desktop")
- Touch targets for radio buttons and the submit button must be at least 44×44px
- Font sizes must remain legible at 375px viewport width
Visual Style
Use saccoai's default style unless overridden by the branding inputs:
- Background:
#FAFAF8(warm off-white) - Text:
#1A1A1A - Accent color: from portal config (default
#E8411B) - Font: system-ui stack (no external font loads — the portal must work without internet access)
- Card border:
1px solid #E5E5E5withborder-radius: 12px - Subtle box shadow on cards:
0 2px 8px rgba(0,0,0,0.06) - The accent color is applied to: selected card border highlight, "Choose this direction" radio fill, "Submit review" button background
Save to: .saccoai/variations/review-portal.html
Deployed Mode
Scaffold a lightweight Next.js app for enterprise review workflows with multiple reviewers.
Scaffold Structure
{client-slug}-review/
├── app/
│ ├── layout.tsx # Portal branding + auth wrapper
│ ├── page.tsx # Main review page (variation cards + feedback form)
│ ├── api/
│ │ ├── feedback/route.ts # POST: save feedback to Upstash Redis
│ │ └── submit/route.ts # POST: mark a direction as chosen, trigger notifications
│ └── auth/
│ └── page.tsx # Password entry page (simple shared secret)
├── components/
│ ├── variation-card.tsx # Individual variation card
│ ├── compare-toggle.tsx # Side-by-side comparison control
│ └── submit-bar.tsx # Sticky bottom submit bar
├── lib/
│ ├── redis.ts # Upstash Redis client
│ └── email.ts # Resend email client
├── public/
│ └── screenshots/ # Copied from .saccoai/variations/
├── .env.local # REDIS_URL, RESEND_API_KEY, PORTAL_PASSWORD (with placeholder values)
└── package.json
Auth
Simple shared-secret auth: a password input page at /auth. On correct password, set a cookie portal-auth=1 (24-hour expiry). Middleware blocks all routes except /auth until the cookie is present. The password is set via the PORTAL_PASSWORD environment variable.
No user accounts. Multiple reviewers share the same password. Each reviewer identifies themselves by entering their name in a "Your name" field on the main review page before submitting feedback.
Real-Time Feedback Storage
Use Upstash Redis (provisioned via Vercel Marketplace):
- Each feedback submission is stored as a hash:
feedback:{variation-slug}:{reviewer-name}→{notes, chosen: true/false, submitted_at} - The "chosen" state for the whole portal is stored as a key:
portal:chosen→{variation-slug, chosen_by, chosen_at} - When a reviewer submits, all previously submitted feedback from other reviewers is shown as a read-only summary below the form
Email Notifications
Use Resend:
- When any reviewer submits feedback: send a notification email to saccoai (configurable
NOTIFY_EMAILenv var) - When a decision-maker clicks "Choose this direction" and submits: send a "Direction chosen" email to
NOTIFY_EMAILwith the chosen variation details and all reviewer feedback
Deployment
- Install Upstash Redis via Vercel Marketplace:
vercel marketplace add upstash-redis - Set environment variables:
PORTAL_PASSWORD,RESEND_API_KEY,NOTIFY_EMAIL - Deploy:
vercel deploy --name {client-slug}-review - The project deploys to
{client-slug}-review.vercel.app(or the assigned Vercel URL)
Phase 3: Present
Static Mode
Open the generated HTML file in the default browser:
open .saccoai/variations/review-portal.html
Then tell the user:
"The review portal is ready at
.saccoai/variations/review-portal.html. Send this file to your client — they can open it in any browser without needing an internet connection. When they've made their choice, they'll download afeedback.jsonfile. Bring that file back here and I'll process the feedback."
If the user wants a shareable link instead of a file attachment, suggest: "You can also upload review-portal.html to any static host (e.g., Vercel, Netlify Drop, GitHub Pages) to get a URL."
Deployed Mode
After deployment completes, collect the deployment URL from vercel deploy output. Then tell the user:
"The review portal is live at: {deployment-url}
Send this link to your client. The password is set in
PORTAL_PASSWORD— share it with your reviewers.When the client has made their choice, come back and I'll fetch the feedback from the database and process it."
Also print the portal password if it was auto-generated, so the user can share it.
Phase 4: Collect Feedback
This phase is user-triggered. It runs after the client has submitted their review. The user initiates it by saying something like "the client submitted their feedback" or "process the feedback.json".
Static Mode
Ask the user for the path to the feedback.json file the client downloaded:
"Please provide the path to the
feedback.jsonfile the client downloaded (e.g.,~/Downloads/feedback.json)."
Read the file. Parse:
chosen_variation: the variation the client selectedfeedback: any per-variation notes the client left
Output a summary:
"The client chose: {variation label} ({visual anchor}).
Their notes:
- Variation 1 ({label}): {notes or 'No notes'}
- Variation 2 ({label}): {notes or 'No notes'} ...
Ready to finalize? I'll run saccoai-design-variations Phase 6 cleanup to merge this variation into main and remove the others."
If the user confirms, invoke saccoai-design-variations Phase 6 with the chosen variation.
Deployed Mode
Fetch the stored feedback from Upstash Redis:
- Read the
REDIS_URLfrom the portal project's.env.local(or ask the user) - Query
portal:chosento get the chosen variation - Query
feedback:*to get all reviewer feedback - Parse and present the same summary as static mode
Then offer to run saccoai-design-variations Phase 6 cleanup.
Passing to Phase 6
When invoking saccoai-design-variations Phase 6, pass:
- The chosen variation number and label
- The client's feedback notes (stored to
.saccoai/variations/client-feedback.jsonfor the record)
saccoai-design-variations Phase 6 handles the git merge, branch cleanup, and design brief promotion.
Composition
saccoai-design-variations (Phase 5) ──→ saccoai-client-portal ──→ saccoai-design-variations (Phase 6 cleanup)
This skill sits between variation presentation and cleanup. It replaces the manual "share these Vercel URLs and wait for an email" workflow with a structured review experience.
- Upstream: saccoai-design-variations. This skill reads
.saccoai/variations/output. It should be run immediately after saccoai-design-variations Phase 5 completes. - Downstream: saccoai-design-variations Phase 6. Once client feedback is collected (Phase 4 of this skill), it triggers Phase 6 cleanup to merge the chosen variation and remove the others.
Also composes with the broader rebuild pipeline:
saccoai-website-rebuild
└──→ saccoai-design-variations (Phases 1-5: generate + deploy N branches)
└──→ saccoai-client-portal (Phases 1-4: portal + client review)
└──→ saccoai-design-variations (Phase 6: merge chosen, cleanup)
└──→ production deploy
Standalone Usage
Invoke this skill directly when:
- saccoai-design-variations has already run and you want to present the variations to the client
- A client needs a more polished review experience than raw Vercel preview URLs
- Multiple stakeholders need to review variations simultaneously (use
--mode deployed) - The user says "create a review portal", "send variations to the client", or "let the client choose"
When invoked standalone, ask for: the variations path (default .saccoai/variations/), the mode (default static), the client name, and any branding overrides. Then run all four phases.
Edge Cases
- No preview URLs: If preview URLs are missing from comparison.md (e.g., Vercel integration was skipped in saccoai-design-variations), take fresh screenshots using agent-browser. If agent-browser is unavailable, the portal cards will show a styled placeholder — note this to the user and advise running saccoai-design-variations Phase 4 first.
- No screenshots and no preview URLs: Generate the portal without images. Cards show the variation label and design brief details only. Note the gap in the Phase 3 "Present" message.
- Single variation only: The portal still works with one variation. The comparison toggle is hidden since there's nothing to compare.
- Deployed mode — Vercel not linked: Abort with instructions: "Run
vercel linkin the portal directory, then re-run Phase 2 deployed mode." - Deployed mode — Upstash Redis not provisioned: Prompt the user to run
vercel marketplace add upstash-redisand provide theREDIS_URL, then retry. - feedback.json already exists in
.saccoai/variations/: A previous review was already completed. Ask the user: "Afeedback.jsonalready exists — was this portal already reviewed? Do you want to re-run the portal or process the existing feedback?" - Client opens portal offline (static mode): The portal is fully self-contained. The only feature that requires internet is the "Preview live" button (which opens Vercel preview URLs). All other features work offline.
Output
.saccoai/variations/
├── review-portal.html # Static mode output
└── client-feedback.json # Saved after Phase 4 completes (both modes)
# Deployed mode also produces:
{client-slug}-review/ # Next.js app scaffold (in cwd or parent directory)
More from saccoai/agent-skills
website-analysis
Crawl any website in a single pass to produce both a complete structural map and full content extraction. Discovers all pages, routes, navigation, multilingual variants, and issues while simultaneously extracting all text, images, metadata, and assets. Use before any migration, redesign, or audit.
16nextjs-fullstack
Opinionated Next.js fullstack patterns — App Router, Tailwind CSS v4, shadcn/ui, Better Auth, Drizzle ORM, Server Actions, and Vercel deployment. Use when scaffolding a new project or enforcing consistent architecture across client projects.
13seo-migration
SEO preservation during website migrations — redirect mapping, canonical URLs, sitemap generation, structured data, meta tags, and Search Console verification. Use when rebuilding a site to ensure zero SEO loss from URL changes, content moves, or domain switches.
9project-handoff
Generate complete client handoff documentation — deployment guide, environment setup, CMS instructions, maintenance checklist, architecture overview, and operational runbook. Use when delivering a finished project to a client or their team.
8client-proposal
Generate a professional project proposal from a website audit. Analyzes the prospect's current site, identifies issues, and produces a structured proposal with scope, deliverables, tech recommendations, and phased timeline. Use as a sales tool or for scoping client engagements.
6web-audit
Comprehensive website quality audit — Lighthouse scores, accessibility (axe-core), cross-browser testing, performance budgets, and mobile responsiveness. Generates actionable reports with pass/fail per page. Use to audit any live website or as a QA gate before deployment.
6