Skip to content
Draft
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
67 changes: 67 additions & 0 deletions apps/web/AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,70 @@ infisical export \
--projectId=87dad7b5-72a6-4791-9228-b3b86b169db1 \
--path="/web"
```

## Design System

All visual tokens live in `src/styles.css` inside the `@theme` block. Never use hardcoded hex values in components — always reference a token.

### Color tokens

| Token | Value | Use for |
|---|---|---|
| `--color-page` | `#F2F3F4` | Page/canvas background (`bg-page`) |
| `--color-surface` | `#ffffff` | Card, panel, modal backgrounds (`bg-surface`) |
| `--color-surface-subtle` | `#fafaf9` | Muted surface variants (`bg-surface-subtle`) |
| `--color-fg` | `#1c1917` | Primary text (`text-fg`) |
| `--color-fg-muted` | `#57534e` | Secondary/body text (`text-fg-muted`) |
| `--color-fg-subtle` | `#a8a29e` | Placeholder, disabled, icons (`text-fg-subtle`) |
| `--color-border` | `#CBC8BD` | Default borders, dividers (`border-border`) |
| `--color-border-subtle` | `#f5f5f5` | Hairline/structural borders (`border-border-subtle`) |
| `--color-brand` | `#78716c` | Brand accent — use sparingly (`bg-brand`, `text-brand`) |
| `--color-brand-dark` | `#57534e` | CTA button gradient end, emphasis (`bg-brand-dark`) |

### Shadow tokens

| Token | Use for |
|---|---|
| `--shadow-ring` | 1px outline border effect — prefer over `border` when stacking borders |
| `--shadow-ring-subtle` | Same, using the subtle border color |

The `.border-shadow` utility class applies `--shadow-ring` as a convenience.

### Typography

- **Display / logo**: `font-serif` (Fraunces) — headings, logo wordmark, editorial emphasis
- **Body / UI text**: `font-sans` (Geist) — all body copy, labels, nav links
- **Code / buttons**: `font-mono` (Geist Mono) — code, button labels, monospaced UI

### CTA button pattern

Primary CTA always uses the warm gradient:

```tsx
"bg-linear-to-t from-brand-dark to-brand rounded-full text-white"
```

Secondary / ghost uses surface + border:

```tsx
"bg-surface border border-border rounded-lg text-fg-muted"
```

## Component structure

Target folder layout. New components must go in the right folder — do not add to the flat root of `components/`.

```
src/components/
layout/ # Header, Footer, Sidebar, SidebarNavigation
ui/ # Primitive brand components: Button, Badge, Card shells
sections/ # Page-level marketing sections (LogoCloud, CtaCard, GithubStars…)
mdx/ # MDX renderer components
notepad/ # Notepad feature
transcription/ # Transcription feature
admin/ # Admin tooling
```

Existing flat-root files are being migrated incrementally. When touching a file, move it to the right folder as part of that PR.

For full brand reference, see `BRAND.md`.
180 changes: 180 additions & 0 deletions apps/web/BRAND.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,180 @@
# Char Brand

This document is the single source of truth for Char's visual identity on the web. All tokens referenced here are defined in `src/styles.css` and available as Tailwind utilities.

---

## Color

The palette is warm neutral — rooted in stone and off-white. One moment of warmth (the brand gradient on CTAs). Everything else recedes.

### Palette

| Role | Token | Hex | Tailwind class |
|---|---|---|---|
| Page background | `--color-page` | `#F2F3F4` | `bg-page` |
| Surface | `--color-surface` | `#ffffff` | `bg-surface` |
| Surface muted | `--color-surface-subtle` | `#fafaf9` | `bg-surface-subtle` |
| Primary text | `--color-fg` | `#1c1917` | `text-fg` |
| Secondary text | `--color-fg-muted` | `#57534e` | `text-fg-muted` |
| Placeholder / disabled | `--color-fg-subtle` | `#a8a29e` | `text-fg-subtle` |
| Default border | `--color-border` | `#CBC8BD` | `border-border` |
| Hairline border | `--color-border-subtle` | `#f5f5f5` | `border-border-subtle` |
| Brand accent | `--color-brand` | `#78716c` | `bg-brand` / `text-brand` |
| Brand dark | `--color-brand-dark` | `#57534e` | `bg-brand-dark` |

### Usage rules

- Never introduce a color outside this palette without updating the token set first.
- `color-brand` and `color-brand-dark` are the only "warm accent" moments. Use them exclusively for primary CTAs and interactive focus states.
- Tailwind's `neutral-*` and `stone-*` scales are available as fallback but semantic tokens above take precedence for any brand-facing UI.

---

## Typography

Three typefaces, each with a distinct role. Do not mix roles.

| Face | Font | Variable | Role |
|---|---|---|---|
| Serif | Fraunces | `--font-serif` | Wordmark, editorial pull-quotes |
| Sans | Geist | `--font-sans` | All body copy, UI labels, navigation |
| Mono | Geist Mono | `--font-mono` | Button labels, display headings, code, technical UI |

### Type scale principles

- **Heading hierarchy**: h1/h2 use `font-mono` by default (per base styles). Serif is used selectively for editorial or brand moments, not for all headings.
- **Weight contrast**: Pair heavy display weight (`font-semibold` / `font-bold`) with light body weight (`font-normal`). Never use two heavy weights adjacently.
- **Letter spacing**: Tight (`tracking-tight`) on large display type. Open (`tracking-wider`) on all-caps labels and category tags.
- **Minimum readable size**: 14px for body, 12px only for all-caps labels or metadata.

---

## Borders & Shadows

| Token | Value | Class | Use |
|---|---|---|---|
| `--shadow-ring` | `0 0 0 1px #CBC8BD` | `.border-shadow` | Default card/panel outline |
| `--shadow-ring-subtle` | `0 0 0 1px #f5f5f5` | — | Hairline structural outlines |

**Prefer `shadow-ring` over CSS `border`** when an element already has box-shadow — avoids double-border stacking issues.

Border radius conventions:
- `rounded-xs` — tight UI elements (chips, small badges)
- `rounded-md` — cards, inputs, dropdowns
- `rounded-lg` — modals, large cards
- `rounded-full` — pill buttons, avatars, tags

---

## Spacing

The layout uses a base-4 spacing rhythm. Key structural values:

| Purpose | Value |
|---|---|
| Header height | `69px` / `h-17.25` |
| Content max-width | `max-w-6xl` |
| Wide breakpoint | `72rem` (`laptop`) |
| Section vertical padding | `py-12` (mobile) / `py-16` (desktop) |
| Card internal padding | `p-4` (compact) / `p-8` (feature) |

---

## Components

### Primary CTA button

The main action. Warm gradient, pill shape, scales on hover.

```tsx
<button className="flex h-9 items-center rounded-full bg-linear-to-t from-brand-dark to-brand px-4 text-sm text-white shadow-md transition-all hover:scale-[102%] hover:shadow-lg active:scale-[98%]">
Download for free
</button>
```

### Secondary / ghost button

Outline style, no fill. Used for secondary actions.

```tsx
<button className="flex h-9 items-center rounded-lg border border-border bg-surface px-4 text-sm text-fg-muted transition-colors hover:bg-surface-subtle">
Get started
</button>
```

### Nav link

Text-only, dotted underline on hover.

```tsx
<a className="text-sm text-fg-muted decoration-dotted transition-colors hover:text-fg hover:underline">
Link
</a>
```

### Section label (category tag)

All-caps mono, wide tracking, muted.

```tsx
<span className="font-mono text-xs font-semibold tracking-wider text-fg-subtle uppercase">
Features
</span>
```

### Card

No heavy shadow. Border ring or hairline border, surface background.

```tsx
<div className="rounded-md border border-border bg-surface p-4">
</div>
```

Or with `shadow-ring` instead of `border`:

```tsx
<div className="border-shadow rounded-md bg-surface p-4">
</div>
```

---

## Logo

- **Wordmark**: "Char" in `font-serif` (Fraunces), `text-2xl`, `font-semibold`.
- **Do not** render the wordmark in `font-sans` or `font-mono`.
- **Scale animation** on hover: `hover:scale-105 transition-transform` is the only permitted motion on the logo.

---

## Motion

- Scale micro-interactions: `hover:scale-[102%] active:scale-[98%]` — used on all interactive cards and CTA buttons.
- Opacity transitions: `transition-opacity duration-200` — used for fade in/out on dynamic text.
- Page-level slide-in: `animate-in slide-in-from-top duration-300` — used for mobile menu only.
- No bounce, no spring, no decorative keyframes on brand UI.

---

## Component folder structure

```
src/components/
layout/ # Header, Footer, Sidebar — structural chrome
ui/ # Primitive, stateless brand components (Button, Badge, Card)
sections/ # Composed page sections (LogoCloud, CtaCard, GithubStars)
mdx/ # MDX renderer overrides
notepad/ # Notepad product feature
transcription/ # Transcription product feature
admin/ # Internal admin tooling
```

When creating a new component, ask:
- Is it a stateless visual primitive? → `ui/`
- Is it a full page section? → `sections/`
- Is it structural layout chrome? → `layout/`
- Is it tied to a specific product feature? → that feature's folder
55 changes: 55 additions & 0 deletions apps/web/content-collections.ts
Original file line number Diff line number Diff line change
Expand Up @@ -803,6 +803,60 @@ const jobs = defineCollection({
},
});

const solutions = defineCollection({
name: "solutions",
directory: "content/solutions",
include: "*.mdx",
exclude: "AGENTS.md",
schema: z.object({
label: z.string(),
icon: z.string(),
order: z.number().default(0),
metaTitle: z.string(),
metaDescription: z.string(),
hero: z.object({
badgeText: z.string(),
title: z.string(),
description: z.string(),
primaryCTA: z.object({ label: z.string(), to: z.string() }),
secondaryCTA: z.object({ label: z.string(), to: z.string() }).optional(),
}),
features: z.object({
title: z.string(),
description: z.string(),
items: z.array(
z.object({
icon: z.string(),
title: z.string(),
description: z.string(),
}),
),
}),
useCases: z.object({
title: z.string(),
description: z.string(),
items: z.array(
z.object({
title: z.string(),
description: z.string(),
}),
),
}),
cta: z.object({
title: z.string(),
description: z.string(),
}),
}),
transform: async (document) => {
const slug = document._meta.path.replace(/\.mdx$/, "");

return {
...document,
slug,
};
},
});

export default defineConfig({
collections: [
articles,
Expand All @@ -820,5 +874,6 @@ export default defineConfig({
ossFriends,
jobs,
updates,
solutions,
],
});
55 changes: 55 additions & 0 deletions apps/web/content/solutions/coaching.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
---
label: "For Coaches"
icon: "mdi:heart-pulse"
order: 18
metaTitle: "AI Meeting Notes for Coaches - Char"
metaDescription: "Capture coaching sessions, client progress, and breakthrough moments with AI-powered meeting notes. Focus on your clients with Char."
hero:
badgeText: "For Coaches"
title: "Transform lives with\nAI-powered meeting notes"
description: "Be fully present with your clients while Char captures every insight, tracks progress, and helps you deliver transformational coaching."
primaryCTA:
label: "Download for free"
to: "/download/"
secondaryCTA:
label: "See how it works"
to: "/product/ai-notetaking/"
features:
title: "Built for coaching sessions"
description: "Every feature designed to help you stay present and track client transformation."
items:
- icon: "mdi:account-heart"
title: "Full Presence"
description: "Stop taking notes during sessions. Be fully present and engaged with your clients while AI captures everything."
- icon: "mdi:chart-line"
title: "Progress Tracking"
description: "Track client goals, commitments, and breakthroughs across sessions. See patterns and progress over time."
- icon: "mdi:lightbulb-on"
title: "Insight Capture"
description: "AI identifies key themes, mindset shifts, and breakthrough moments from coaching conversations."
- icon: "mdi:clipboard-check"
title: "Action Items"
description: "Automatically extract commitments, homework, and action items from each session for follow-up."
- icon: "mdi:message-reply-text"
title: "Session Summaries"
description: "Generate session summaries to share with clients. Help them remember key insights and next steps."
- icon: "mdi:shield-lock"
title: "Client Privacy"
description: "Local AI processing ensures sensitive coaching conversations stay completely private and secure."
useCases:
title: "For every coaching conversation"
description: "From life coaching to executive development, Char helps you deliver transformational results."
items:
- title: "Life Coaching"
description: "Capture personal goals, challenges, and transformation journeys. Track client progress toward their vision."
- title: "Executive Coaching"
description: "Document leadership challenges, strategic thinking, and professional development goals. Support high-stakes growth."
- title: "Career Coaching"
description: "Track career goals, skill development, and job search progress. Help clients navigate their career journey."
- title: "Health & Wellness"
description: "Record wellness goals, habit changes, and health milestones. Support clients in sustainable lifestyle changes."
cta:
title: "Ready to amplify your impact?"
description: "Join coaches who are transforming lives with AI-powered meeting notes."
---

Loading