Adds a new standalone /deepdive page with its own platform.css/platform.js, wires it into the dot-nav as an external entry, and updates the dot-nav docblock to reflect the new seven-entry layout. Also drops in BUSINESS.md and reference material under architecture boxes/ and examples/. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
268 lines
14 KiB
Markdown
268 lines
14 KiB
Markdown
# Handoff: Fenja architecture diagram
|
||
|
||
## Overview
|
||
|
||
A **right-side architecture diagram** for a section of the Fenja AI website. The left side of the section will hold explanatory prose (the developer adds this in their codebase). The right side is this stacked, three-layer diagram showing the Fenja system at a glance: **Foundation → Tools → Agents**.
|
||
|
||
The diagram is the visual anchor of the section. As the user reads down the left column, each paragraph cues the next layer of the diagram to enter — creating a guided "build" of the architecture in concert with the prose.
|
||
|
||
---
|
||
|
||
## About the design files
|
||
|
||
The files in `reference/` are a **design reference** — a working HTML/React prototype that shows the intended look, layout, and entry animation. They are **not production code to copy verbatim**.
|
||
|
||
- `reference/preview.html` — open this in a browser to see the diagram rendered.
|
||
- `reference/approach-fenja.jsx` — the React component (inline JSX, transpiled by Babel in the prototype). Use it as a structural and styling reference.
|
||
- `reference/colors_and_type.css` — Fenja design tokens (CSS variables) and base type styles. Use these tokens — do not invent new ones.
|
||
- `reference/fonts/` — Manrope (sans) and Newsreader (serif) self-hosted TTFs. The diagram **requires both families** — Newsreader for italic descriptors, Manrope for everything else.
|
||
|
||
Recreate the design in your existing environment (Next.js, React, Vue, Astro, whatever the Fenja site uses), wired up to the site's real design tokens and motion primitives.
|
||
|
||
## Fidelity
|
||
|
||
**High-fidelity.** Colors, typography, spacing, and corner radii are final. Recreate pixel-perfectly using the established Fenja design tokens.
|
||
|
||
---
|
||
|
||
## What this diagram is
|
||
|
||
A vertically stacked diagram with three layers, top to bottom:
|
||
|
||
```
|
||
┌──────────────────────────────────────────────────────────┐
|
||
│ FOUNDATION Sovereign by design │
|
||
│ ┌──────────────────────┐ ┌──────────────────────────┐ │
|
||
│ │ Language model │ │ Knowledge (taller) │ │
|
||
│ │ italic descriptor │ │ italic descriptor │ │
|
||
│ │ mono · tag │ │ mono · tag │ │
|
||
│ │ │ │ italic descriptor │ │
|
||
│ │ │ │ mono · tag │ │
|
||
│ └──────────────────────┘ └──────────────────────────┘ │
|
||
└──────────────────────────────────────────────────────────┘
|
||
┌──────────────────────────────────────────────────────────┐
|
||
│ TOOLS How Fenja acts │
|
||
│ ┌────┐ ┌────┐ ┌────┐ ┌────┐ │
|
||
│ │ 4 boxes, equal width and height │
|
||
│ └────┘ └────┘ └────┘ └────┘ │
|
||
└──────────────────────────────────────────────────────────┘
|
||
┌──────────────────────────────────────────────────────────┐
|
||
│ AGENTS How Fenja scales │
|
||
│ ┌────┐ ┌────┐ ┌────┐ ┌────┐ │
|
||
│ │ 4 boxes, equal width and height │
|
||
│ └────┘ └────┘ └────┘ └────┘ │
|
||
└──────────────────────────────────────────────────────────┘
|
||
```
|
||
|
||
### Critical asymmetries
|
||
|
||
- **Foundation has 2 boxes** (narrower row) — the irreducible base.
|
||
- **Tools and Agents each have 4 boxes** (full row) — they extend the base.
|
||
- Within Foundation, the **Knowledge box is intentionally taller** than Language model (5 content rows vs 2). Do not equalize them. The asymmetry is the point.
|
||
- Within Tools and Agents, all 4 boxes are **equal height** (stretch). Do not let content drift the heights.
|
||
|
||
### No connecting lines
|
||
|
||
The first pass has **no lines between layers**. Stacking + vertical order communicates "lower layers depend on what's above." If that's unclear after live testing with copy, a second pass can add subtle connectors.
|
||
|
||
---
|
||
|
||
## Layer content (exact)
|
||
|
||
Use this content verbatim. Do not paraphrase.
|
||
|
||
### Layer 1 — Foundation
|
||
|
||
- Eyebrow (top-left of layer): `Foundation` (rendered uppercase via `text-transform: uppercase`)
|
||
- Descriptor (top-right of layer, serif italic): `Sovereign by design`
|
||
|
||
**Box 1 — Language model**
|
||
- Bold name: `Language model`
|
||
- Italic role: `State-of-the-art, open-source`
|
||
- Mono tag: `On-prem`
|
||
|
||
**Box 2 — Knowledge** (taller — 5 content rows, no min-height equalization)
|
||
- Bold name: `Knowledge`
|
||
- Italic: `Organizational memory at every level`
|
||
- Mono: `Organizational · Departmental · Personal`
|
||
- Italic: `Facts, context, and how things get done`
|
||
- Mono: `Wiki · Routines · Working memory`
|
||
|
||
### Layer 2 — Tools
|
||
|
||
- Eyebrow: `Tools`
|
||
- Descriptor: `How Fenja acts`
|
||
|
||
| Bold name | Italic role | Mono tag |
|
||
|---|---|---|
|
||
| Document retrieval | Find and cite | RAG |
|
||
| Structured data | Query and extract | NL → SQL |
|
||
| System actions | Read and write | APIs · integrations |
|
||
| Custom tools | Your specific work | Defined by you |
|
||
|
||
### Layer 3 — Agents
|
||
|
||
- Eyebrow: `Agents`
|
||
- Descriptor: `How Fenja scales`
|
||
|
||
| Bold name | Italic role | Mono tag |
|
||
|---|---|---|
|
||
| Supervisor | Plan and dispatch | Orchestration |
|
||
| Specialists | Focused expertise | Subagents |
|
||
| Skills | Reusable capability | Portable across specialists |
|
||
| Workflows | Composed by you | Governed end-to-end |
|
||
|
||
---
|
||
|
||
## Layout & sizing
|
||
|
||
The diagram is meant to occupy the right column of a two-column section (roughly 50% of the viewport width on desktop, ~600–760px wide). It is fully fluid — it scales to its container.
|
||
|
||
| Element | Spec |
|
||
|---|---|
|
||
| Outer container | `padding: 56px 56px 64px` on the standalone prototype. In the site, drop the outer padding and let the section's own grid drive margins. |
|
||
| Layer (group) | `background: var(--surface-container)` · `border-radius: 20px` · `padding: 24px 24px 28px` |
|
||
| Layer-to-layer gap | `20px` (vertical flex gap) |
|
||
| Layer header | flex row, baseline-aligned, eyebrow left + italic descriptor right, `margin-bottom: 18px` |
|
||
| Eyebrow label | Manrope · 11px · weight 600 · `letter-spacing: 0.14em` · uppercase · `color: var(--on-surface-variant)` |
|
||
| Italic descriptor | Newsreader italic · 14px · `color: var(--on-surface-muted)` |
|
||
| Card grid | `display: grid` · `gap: 14px` · 2 cols (Foundation) or 4 cols (Tools, Agents) |
|
||
| Card grid alignment | **Foundation: `align-items: start`** (preserves Knowledge's taller height) · **Tools & Agents: `align-items: stretch`** (equal heights within row) |
|
||
| Card | `background: var(--surface-container-lowest)` · `border-radius: 12px` · `padding: 18px 20px` · column flex · `gap: 6px` · `min-height: 76px` · `box-shadow: 0 1px 0 rgba(56,56,49,0.04), 0 8px 20px -16px rgba(56,56,49,0.18)` |
|
||
| Card name | Manrope · 15px · weight 600 · `letter-spacing: -0.005em` · `color: var(--on-surface)` |
|
||
| Italic row | Newsreader italic · 13px · `line-height: 1.35` · `color: var(--on-surface-variant)` |
|
||
| Mono row | Mono stack · 10.5px · `letter-spacing: 0.04em` · `line-height: 1.4` · `color: var(--on-surface-muted)` |
|
||
|
||
**No borders anywhere.** Containment is expressed entirely through the tonal step from `--surface-container` (group) to `--surface-container-lowest` (card). The card's tiny ambient shadow is the only depth cue.
|
||
|
||
---
|
||
|
||
## Design tokens (use existing Fenja tokens; do not invent)
|
||
|
||
These come from `colors_and_type.css`. Map to whatever variable system the codebase uses.
|
||
|
||
```
|
||
--surface #faf6ee /* page canvas */
|
||
--surface-container #efeadc /* group / layer background */
|
||
--surface-container-lowest #fffcf7 /* card background */
|
||
--on-surface #383831 /* card name, primary text */
|
||
--on-surface-variant #5f5e5e /* italic role, eyebrow */
|
||
--on-surface-muted #8a887f /* mono tag, descriptor */
|
||
|
||
--font-sans Manrope, Inter, system-ui (weights 400, 500, 600 used)
|
||
--font-serif Newsreader, Source Serif Pro, Georgia (italic, 400)
|
||
--font-mono JetBrains Mono, IBM Plex Mono, ui-monospace
|
||
|
||
--radius-md 12px (cards)
|
||
--radius-lg 20px (groups)
|
||
```
|
||
|
||
---
|
||
|
||
## Entry animation
|
||
|
||
The user requested: **"each element jumps in together with text I'll add in Claude Code."**
|
||
|
||
### Intent
|
||
|
||
As the section scrolls into view, the diagram builds layer-by-layer in step with the prose on the left. Each paragraph the reader passes "summons" the corresponding layer.
|
||
|
||
### Mechanism (recommended)
|
||
|
||
Use whatever scroll-trigger primitive the site already uses (Framer Motion `whileInView`, GSAP ScrollTrigger, IntersectionObserver, etc.). Do not introduce a new motion library just for this.
|
||
|
||
### Animation values — match Fenja system motion
|
||
|
||
The Fenja design system has **one easing** and **page entrances are fade + 4px translate-up, never scale**. Use those.
|
||
|
||
```
|
||
duration: 240ms (use --duration-med)
|
||
easing: cubic-bezier(0.2, 0.0, 0, 1) (use --ease-standard)
|
||
from: opacity: 0; transform: translateY(8px)
|
||
to: opacity: 1; transform: translateY(0)
|
||
```
|
||
|
||
Note the design system says 4px translate-up, but for cards inside a build sequence 8px reads better. Stay within 4–10px.
|
||
|
||
### Choreography
|
||
|
||
Three trigger points, each tied to a paragraph on the left:
|
||
|
||
| Trigger | Reveals | Stagger |
|
||
|---|---|---|
|
||
| Paragraph 1 in view | Foundation layer (group + 2 cards) | Layer fades, then cards stagger 60ms each |
|
||
| Paragraph 2 in view | Tools layer (group + 4 cards) | Same — group, then cards 60ms apart |
|
||
| Paragraph 3 in view | Agents layer (group + 4 cards) | Same |
|
||
|
||
Within a single layer, the **group container** (with eyebrow + descriptor) appears first, then its cards stagger in left-to-right.
|
||
|
||
### Reduced motion
|
||
|
||
Honor `prefers-reduced-motion: reduce` — fade in over 120ms, no translate.
|
||
|
||
### What to wire on the developer side
|
||
|
||
The component should expose a controllable visibility state per layer, e.g.:
|
||
|
||
```tsx
|
||
<FenjaArchitecture
|
||
visibleLayers={{ foundation: true, tools: paragraph2InView, agents: paragraph3InView }}
|
||
/>
|
||
```
|
||
|
||
…or accept three IntersectionObserver refs (one per paragraph) and drive its own visibility internally. Either is fine — pick whichever suits the codebase's conventions.
|
||
|
||
---
|
||
|
||
## Behavior when the section is statically rendered (no JS)
|
||
|
||
If the page renders without JS (SSR, RSS preview, screenshot tool, print), all three layers must be visible. Animation is a progressive enhancement — the static state is the final state, and the animation should ramp from that final state's opposite, not block on JS to render content. (Translation: render at full opacity by default and let the animation library set initial opacity:0 only when it's ready.)
|
||
|
||
---
|
||
|
||
## State
|
||
|
||
No app state. Pure presentational component. All content is static; nothing is fetched.
|
||
|
||
If the prose paragraphs and the diagram need to coordinate, expose a single `currentLayer: 'foundation' | 'tools' | 'agents' | null` prop or use shared IntersectionObserver hooks — implementer's choice.
|
||
|
||
---
|
||
|
||
## Assets
|
||
|
||
None. The diagram is text-on-paper — no icons, no images, no SVG illustrations.
|
||
|
||
---
|
||
|
||
## Files in this bundle
|
||
|
||
```
|
||
design_handoff_architecture_diagram/
|
||
├── README.md ← you are here
|
||
└── reference/
|
||
├── preview.html ← open this to see the diagram render
|
||
├── approach-fenja.jsx ← the React reference component
|
||
├── colors_and_type.css ← Fenja design tokens (variables + base styles)
|
||
└── fonts/ ← Manrope + Newsreader TTFs (self-hosted)
|
||
```
|
||
|
||
---
|
||
|
||
## Implementation checklist
|
||
|
||
- [ ] Component scaffolded in the codebase's preferred framework (React, Vue, etc.)
|
||
- [ ] All three layers render with the exact copy above
|
||
- [ ] Foundation: Knowledge box visibly taller than Language model (do not equalize)
|
||
- [ ] Tools: 4 cards flush-equal in height (`align-items: stretch`)
|
||
- [ ] Agents: 4 cards flush-equal in height (`align-items: stretch`)
|
||
- [ ] Eyebrow + italic descriptor in the header of every layer
|
||
- [ ] Mono tags use the site's monospace stack (do not substitute regular text)
|
||
- [ ] Bullet separator `·` (interpunct U+00B7) used in mono tags — not `•` or `-`
|
||
- [ ] No borders anywhere (containment = tonal step only)
|
||
- [ ] No connecting lines between layers
|
||
- [ ] No icons inside boxes
|
||
- [ ] Entry animation: fade + 8px translate-up, 240ms, `cubic-bezier(0.2, 0, 0, 1)`
|
||
- [ ] Per-layer trigger tied to corresponding left-column paragraph entering viewport
|
||
- [ ] Cards within a layer stagger 60ms left-to-right
|
||
- [ ] `prefers-reduced-motion: reduce` honored
|
||
- [ ] Static render is fully visible without JS
|