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
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,10 @@ apps/backend/.env
!apps/frontend/.env.example
!apps/backend/.env.example

# Vercel CLI project-link metadata (apps/marketing, #382) -- not secret, but
# machine-local and not meant to be committed.
apps/marketing/.vercel

# ==========================================
# Local-only strategy / roadmap docs (never commit)
# The Market-Fit Roadmap is the single source of truth for product direction,
Expand Down
72 changes: 72 additions & 0 deletions apps/marketing/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
# PARTHA marketing site

A free, static marketing site for PARTHA (#382). It reuses the real `apps/frontend` landing page — the same
1728px-wide authored design, the same light/dark theme system, the same FAQ and footer — as its visual basis, ported
in rather than re-invented, with two behavioral differences since this site has no backend or accounts at all:

- The "Log In" nav hotspot and the "See how it works" hero hotspot both open a scripted product simulation instead
(`src/components/DemoModal.tsx`), using canned sample data — there's nothing live to log into or scroll to a
walkthrough of, so both lead to the same demo.
- Every "Analyze a Repository" hotspot has no live backend to analyze against, so it opens fork/clone setup
instructions instead (`src/components/RunItYourselfModal.tsx`), plus a note encouraging people to star the repo.

There is no waitlist or hosted-beta path anywhere on this site: PARTHA is self-hosted only for the foreseeable
future, with no hosted service planned, so there's nothing to wait for.

Deliberately independent of `apps/frontend` — no backend dependency, and nothing here talks to the real Render/Neon
deployment (which is paused, not live — see #375/#377). It builds and runs entirely on its own; shared visual assets
(SVG artwork, theme hook, tokens) are copied in directly rather than imported cross-package, to keep it that way.

## Local development

```bash
cd apps/marketing
npm install
npm run dev
```

Opens at `http://localhost:5173` (or the next free port Vite picks; the repo's `.claude/launch.json` runs it on
`5174` alongside the real frontend dev server on `5173`). The entire page works with zero configuration — there is
no backend call anywhere on the site.

## Verification

```bash
npm run typecheck # tsc -b --noEmit
npm run lint # eslint .
npm run build # tsc -b && vite build -- outputs to dist/
npm run preview # serve the production build locally
```

## Deploying on Vercel

This project is intentionally **not** part of the root npm workspace (`apps/frontend` is) — it has its own
`package.json`/`node_modules`, so Vercel can build it in complete isolation from the rest of the monorepo.

1. In the Vercel dashboard: **Add New → Project**, import the `Second-Origin/PARTHA` GitHub repository.
2. Set the project's **Root Directory** to `apps/marketing`. Vercel auto-detects the Vite framework preset from
there; `vercel.json` in this directory pins the build command and output directory explicitly regardless.
3. No env vars needed to deploy — the page renders and the simulation works with zero configuration.
4. Deploy. Vercel gives you a `*.vercel.app` URL immediately; a custom domain can be attached afterward under
**Settings → Domains**.

## Structure

- `src/App.tsx` — the ported landing page: renders the authored SVG artwork (`src/assets/landing/`), overlays the
invisible nav/hero/footer hotspots on top, and wires the two behavioral differences described above.
- `src/components/DemoModal.tsx`, `RunItYourselfModal.tsx` — the two interactive surfaces reached from those
hotspots.
- `src/hooks/useLandingTheme.ts`, `src/components/ThemeSwitcher.tsx` — verbatim ports of the real frontend's
light/dark/system theme store and toggle.
- `src/data/sampleAnalysis.ts` — the canned data behind the demo simulation, using PARTHA's real finding
categories/severities/output shape.

## What this deliberately does not do

- Does not call the real PARTHA API — the "simulation" is entirely canned data in `src/data/sampleAnalysis.ts`,
clearly labeled in the UI as a scripted sample-repository walkthrough, not a live analysis.
- Does not create or need a PARTHA account, login, or session — the reused landing page's "Log In" hotspot opens the
demo instead of a login flow.
- Does not offer a waitlist or any hosted-beta path — the product is self-hosted only, with no hosted service
planned, so "run it yourself" is the only call to action.
- Does not touch `apps/frontend`, the backend, or `render.yaml` — those stay exactly as they are, paused.
34 changes: 34 additions & 0 deletions apps/marketing/eslint.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import js from '@eslint/js';
import reactHooks from 'eslint-plugin-react-hooks';
import reactRefresh from 'eslint-plugin-react-refresh';
import globals from 'globals';
import tseslint from 'typescript-eslint';

export default tseslint.config(
{
ignores: ['dist', 'node_modules', '.vercel'],
},
js.configs.recommended,
...tseslint.configs.recommended,
{
files: ['**/*.{ts,tsx}'],
languageOptions: {
ecmaVersion: 2020,
globals: globals.browser,
},
plugins: {
'react-hooks': reactHooks,
'react-refresh': reactRefresh,
},
rules: {
...reactHooks.configs.recommended.rules,
'react-refresh/only-export-components': ['warn', { allowConstantExport: true }],
},
},
{
files: ['api/**/*.ts'],
languageOptions: {
globals: globals.node,
},
},
);
38 changes: 38 additions & 0 deletions apps/marketing/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<link rel="icon" type="image/svg+xml" href="/favicon.svg" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta
name="description"
content="PARTHA turns a repository revision into one sealed, queryable model and uses it to explain architecture, dependencies, review findings, insights, and documentation. See a scripted walkthrough, or run it yourself."
/>
<title>PARTHA — Repository Intelligence</title>
<link rel="preconnect" href="https://fonts.googleapis.com" />
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&family=JetBrains+Mono:wght@400;500&display=swap" rel="stylesheet" />
<style>
/* Ported from apps/frontend/index.html (#382): prevents a white flash
behind the landing artwork before React mounts and App's own
scoped .landing-dark class takes over. This whole site is the
landing page, so unlike the real app there's no pathname check. */
html[data-landing-theme-boot='dark'] body {
background: #000;
}
</style>
<script>
(function () {
try {
var stored = window.localStorage.getItem('partha-landing-theme');
var dark = stored === 'dark' || ((stored === 'system' || !stored) && window.matchMedia('(prefers-color-scheme: dark)').matches);
if (dark) document.documentElement.setAttribute('data-landing-theme-boot', 'dark');
} catch (e) {}
})();
</script>
</head>
<body>
<div id="root"></div>
<script type="module" src="/src/main.tsx"></script>
</body>
</html>
Loading
Loading