| name | brand-knowvah |
| description | Apply the Knowvah "Warm Studio" visual identity (CSS tokens, ThemeContext, sidebar layout, App.tsx skeleton) to a new React/Vite project on a *.knowvah.com subdomain. |
| user-invocable | true |
| allowed-tools | Read, Write, Edit, Bash, Glob, Grep |
brand-knowvah
Apply the Knowvah "Warm Studio" visual identity and app shell to a new
*.knowvah.com React/Vite project. Covers CSS theme tokens, ThemeContext,
sidebar layout, and the App.tsx provider/routing skeleton.
Run this skill after the project scaffold exists (Vite + React + TypeScript +
Tailwind CSS v4 + React Router + i18next). Run auth-setup first if you want
the sidebar's user profile section wired to a real session.
Step 0 — Resume check
Before doing anything else, check whether .brand-knowvah-progress.md exists
in the working directory.
If it exists:
- Read it.
- If
collected_inputs: true is present, extract the stored inputs — do not
re-ask any question whose answer is already recorded.
- Find the first step checkbox that is still
[ ] (unchecked).
- Print:
Resuming from [step name].
- Skip Steps 1–2 entirely and jump directly to the first unchecked step.
If it does not exist: continue to Step 1 as normal.
Step 1 — Gather inputs
Ask these before doing any work:
- App subtitle — what goes after the dash in the title tag?
E.g. "Live Polling", "Audience Insights". Used in
index.html.
- Subdomain — which
*.knowvah.com subdomain will this deploy to?
(Informational only — used in the summary.)
- Has
auth-setup been run? — determines whether ThemeContext and
Sidebar can reference useAuth(). Yes/No.
- Has
compliance-setup been run? — determines whether index.html
needs the Termly embed and whether AnalyticsProvider needs the consent
gate. Yes/No.
- Has
analytics-setup been run? — determines whether App.tsx wraps
routes with <AnalyticsProvider> and includes PageViewTracker. Yes/No.
- What are this app's main nav items? — list the page names and their
routes. Used to populate
NAV_ITEMS in Sidebar and routes in
constants/routes.ts.
- Does this app have a credits model? — show/hide the credits badge in
the sidebar. Yes/No.
- Does this app have an admin role? — show/hide the admin nav section.
Yes/No.
- Termly site UUID (if compliance-setup was run) — the
data-website-uuid value for the Termly embed script.
After all questions are answered, write .brand-knowvah-progress.md in the
working directory before doing any further work:
# Brand-Knowvah Progress
collected_inputs: true
## Inputs
<record each collected input as a key: value line>
## Steps
- [ ] install-dependencies
- [ ] copy-index-css
- [ ] write-index-html
- [ ] write-storage-ts
- [ ] write-routes-ts
- [ ] write-theme-context
- [ ] write-topbar
- [ ] write-layout
- [ ] write-sidebar
- [ ] copy-logo
- [ ] write-app-tsx
- [ ] wire-main-tsx
- [ ] configure-tailwind
- [ ] add-i18n-keys
- [ ] verify
Step 2 — Install dependencies
Check ui/package.json. Install any missing packages:
npm install react-router-dom @heroicons/react
npm install react-i18next i18next
npm install posthog-js
On success, mark - [x] install-dependencies in .brand-knowvah-progress.md.
Step 3 — Copy and adapt index.css
Copy ui/index.css from ui/index.css (the template). No changes needed —
the full Warm Studio token set is self-contained.
If ui/src/index.css already exists, replace it entirely.
The font is JetBrains Mono, loaded from Google Fonts in index.html. Do not
add a font-family declaration to the CSS — Tailwind's base reset handles
font inheritance from body.
On success, mark - [x] copy-index-css in .brand-knowvah-progress.md.
Step 4 — Write ui/index.html
Copy from ui/index.html. Adapt:
- Replace
"Knowvah – App Name" with "Knowvah – <subtitle from step 1>".
- If compliance-setup was run: replace
XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX
with the Termly UUID from step 1 Q9.
- If compliance-setup was NOT run: remove the entire
<script> block
containing the Termly embed.
On success, mark - [x] write-index-html in .brand-knowvah-progress.md.
Step 5 — Write src/constants/storage.ts
Copy from ui/constants_storage.ts. Adapt:
- Update the
LANG value prefix to match this app's name if different from
knowvah. E.g. 'myapp_lang'.
On success, mark - [x] write-storage-ts in .brand-knowvah-progress.md.
Step 6 — Write src/constants/routes.ts
Copy from ui/constants_routes.ts. Replace the placeholder routes with this
app's actual page structure (from step 1 Q6):
On success, mark - [x] write-routes-ts in .brand-knowvah-progress.md.
Step 7 — Write src/contexts/ThemeContext.tsx
Copy from ui/ThemeContext.tsx.
On success, mark - [x] write-theme-context in .brand-knowvah-progress.md.
Step 8 — Write src/components/TopBar.tsx
Copy from ui/TopBar.tsx. No changes needed.
On success, mark - [x] write-topbar in .brand-knowvah-progress.md.
Step 9 — Write src/components/Layout.tsx
Copy from ui/Layout.tsx. Adapt:
- If compliance-setup was NOT run: remove
CANNY_FEEDBACK_URL and the
conditional feedback link in the footer.
- Update i18n namespace references if 'auth' and 'common' are named
differently in this project.
On success, mark - [x] write-layout in .brand-knowvah-progress.md.
Step 10 — Write src/components/Sidebar.tsx
Copy from ui/Sidebar.tsx. Adapt:
- NAV_ITEMS: replace with the items from step 1 Q6. Import the matching
Heroicons.
- Credits badge: if step 1 Q7 = No, remove the
{user && !collapsed && ...}
credits badge block.
- Admin section: if step 1 Q8 = No, remove the
{user?.is_admin && ...}
block entirely.
- Brand name: update the text
Knowvah after the logo <img> to match
this app's display name (or keep "Knowvah" if that's the brand).
- If auth-setup was NOT run: the
user object shape may differ. Update
type casts on user.credits_available, user.is_admin, user.profile_url
to match the actual user type.
On success, mark - [x] write-sidebar in .brand-knowvah-progress.md.
Step 11 — Copy the Knowvah logo
Copy knowvah_logo.svg from this skill's template directory to
ui/public/knowvah_logo.svg in the new project.
On success, mark - [x] copy-logo in .brand-knowvah-progress.md.
Step 12 — Write src/App.tsx
Copy from ui/App.tsx. Adapt:
- Lazy imports: replace the placeholder page imports with this app's
actual pages. Remove policy page imports if compliance-setup was not run.
- AnalyticsProvider: if analytics-setup was NOT run, remove the import
and the
<AnalyticsProvider> wrapper. Replace useAnalytics() with a
no-op shim or remove the identify call from RequireAuth.
- CannyFeedback: if compliance-setup was NOT run, remove the import and
the
{AppID && <CannyFeedback ...>} block.
- Consent gate: if compliance-setup was NOT run, remove the
consent_required check inside RequireAuth.
- Routes: wire up the pages from step 1 Q6. Public routes go outside the
<RequireAuth><Layout /></RequireAuth> wrapper; authenticated routes go
inside it.
- Admin routes: if step 1 Q8 = No, remove admin route entries.
On success, mark - [x] write-app-tsx in .brand-knowvah-progress.md.
Step 13 — Wire CSS into main.tsx
Ensure ui/src/main.tsx imports the CSS:
import './index.css';
Wrap the app with <BrowserRouter> if not already:
import { BrowserRouter } from 'react-router-dom';
import App from './App';
ReactDOM.createRoot(document.getElementById('root')!).render(
<React.StrictMode>
<BrowserRouter>
<App />
</BrowserRouter>
</React.StrictMode>,
);
On success, mark - [x] wire-main-tsx in .brand-knowvah-progress.md.
Step 14 — Configure Tailwind
Ensure tailwind.config.ts (or vite.config.ts Tailwind plugin) includes
the ui/src/** glob. No custom theme extension is needed — the design system
runs entirely through CSS custom properties referenced as bg-[var(--bg)] etc.
On success, mark - [x] configure-tailwind in .brand-knowvah-progress.md.
Step 15 — Add i18n keys
If i18n-setup was run, add the sidebar and footer translation keys to the
common and auth namespaces:
locales/en/common.json — add under existing keys:
{
"sidebar": {
"expand": "Expand sidebar",
"collapse": "Collapse sidebar"
},
"nav": {
"dashboard": "Dashboard",
"settings": "Settings",
"signOut": "Sign out",
"adminSection": "Admin",
"adminDashboard": "Dashboard"
},
"credits": {
"remaining": "{{count}} credits remaining"
}
}
locales/en/auth.json — add under existing keys:
{
"login": {
"footer": {
"privacy": "Privacy",
"terms": "Terms",
"cookies": "Cookies",
"feedback": "Feedback"
}
}
}
Run npm run i18n:translate (if the translate script exists) to populate the
other 17 locales.
On success, mark - [x] add-i18n-keys in .brand-knowvah-progress.md.
Step 16 — Verify
Failure policy: if npx tsc --noEmit fails, stop immediately and report the
full error output. Do not continue. The user must resolve type errors and
re-run (Step 0 will resume from this step).
- Run
npx tsc --noEmit — fix any type errors before proceeding.
- Run
npm run dev — the app should load with the warm cream background and
dark charcoal sidebar.
- Toggle OS dark mode — theme should switch immediately.
- Collapse/expand the sidebar — state should persist across page refresh.
- Resize to mobile — sidebar should be hidden, hamburger button visible.
- Click the hamburger — drawer should slide in with overlay.
On success, mark - [x] verify in .brand-knowvah-progress.md.
Summary output
## knowvah-brand complete
App: <subtitle> at <subdomain>.knowvah.com
Files written:
ui/index.html — JetBrains Mono, favicon, <Termly: yes/no>
ui/src/index.css — Warm Studio tokens (4 theme combinations)
ui/src/constants/storage.ts
ui/src/constants/routes.ts — <N> routes
ui/src/contexts/ThemeContext.tsx — OS-aware, auth-gated custom prefs
ui/src/components/TopBar.tsx — mobile-only hamburger header
ui/src/components/Layout.tsx — sidebar + main + footer shell
ui/src/components/Sidebar.tsx — collapsible, <N> nav items
ui/src/App.tsx — AuthProvider → ThemeProvider → ...
ui/public/knowvah_logo.svg — copied from knowvah-audience-insights
Nav items configured: <list>
Credits badge: <yes/no>
Admin section: <yes/no>
Compliance (Termly + Canny): <yes/no>
Analytics (PostHog): <yes/no>
Remaining manual steps:
- Set VITE_CANNY_APP_ID in your hosting env (if compliance-setup was run)
- Set VITE_CANNY_FEEDBACK_URL in your hosting env (if compliance-setup was run)
- Deploy to <subdomain>.knowvah.com