AI strategy and build consultancy. From opportunity mapping to scale-ready engines.
A dual-mode marketing site for an AI consultancy that pivots between Strategy (business/ROI language) and Build (engineering/architecture language) — with a generative SVG iris, tiered service cards, a streaming AI chat widget powered by Hugging Face, and a grain texture overlay.
npm run dev
# → http://localhost:3000| Feature | Description |
|---|---|
| Dual Mode System | Toggle between Strategy (warm gold/cream) and Build (dark mint/carbon) themes. Every component reacts to mode state. |
| Generative Iris SVG | Procedurally drawn gold filaments that rotate clockwise/counter-clockwise. Colors and glow shift with the active mode. |
| Tier Cards | Three service tiers (Lens → Blueprint → Build) with conditional rendering: business deliverables in Strategy mode, code snippets in Build mode. |
| Streaming AI Chat | Edge-runtime API route that streams responses from Hugging Face Inference API via Server-Sent Events. Context-aware system prompt switches with the mode. |
| Grain Texture Overlay | SVG noise filter applied globally at 4% opacity for a premium tactile feel. |
| Responsive Typography | clamp()-based fluid type scale using DM Serif Display, Syne, and JetBrains Mono. |
- Framework: Next.js 14 (App Router, Edge Runtime)
- Language: TypeScript
- Styling: Tailwind CSS
- Fonts: DM Serif Display · Syne · JetBrains Mono (Google Fonts)
- AI Inference: @huggingface/inference + Hugging Face Serverless API
- Runtime: Node 18+ / Edge
iris-ai/
├── app/
│ ├── api/chat/route.ts # Edge streaming endpoint for HF Inference API
│ ├── globals.css # Tailwind directives + iris keyframes
│ ├── layout.tsx # Root layout with ModeProvider + GrainOverlay
│ └── page.tsx # Landing page composition
├── components/
│ ├── chat/ChatWidget.tsx # Floating AI chat panel (SSE streaming)
│ ├── iris/IrisCanvas.tsx # Procedural SVG eye animation
│ ├── nav/Navbar.tsx # Fixed top nav with mode-aware theming
│ ├── sections/ # Hero, Tiers, Stack, CTA, Footer
│ └── ui/ # ModeToggle, GrainOverlay
├── hooks/useMode.tsx # React context for strategy/build state
├── lib/
│ ├── ai.ts # HF client, prompt builder, IRIS_SYSTEM_PROMPT
│ └── constants.ts # TIERS + STACK_ITEMS data
├── types/index.ts # Mode, Tier, Message, StackItem types
└── .env.local.example # Env template
- Node.js 18+
- A Hugging Face account + Access Token
# 1. Clone / unzip
cd iris-ai
# 2. Install dependencies
npm install
# 3. Set environment variables
cp .env.local.example .env.local
# Edit .env.local → add your HF_API_TOKEN
# 4. Start the dev server
npm run dev| Variable | Required | Description |
|---|---|---|
HF_API_TOKEN |
Yes | Hugging Face read token from Settings → Tokens |
The entire app is wrapped in a ModeProvider (hooks/useMode.tsx). Toggling the mode updates a single 'strategy' | 'build' state, and every component reads isStrategy to switch colors, copy, and even rendered content.
IrisCanvas.tsx uses raw DOM manipulation to generate 48 outer and 32 inner SVG <line> elements with randomized lengths, angles, and opacity. Two CSS keyframe animations spin the groups independently.
app/api/chat/route.ts runs on the Edge Runtime. It formats the conversation history into a Mistral-7B-Instruct prompt template, sends it to the Hugging Face Inference API via textGenerationStream, and pipes each token delta into a ReadableStream.
The client (ChatWidget.tsx) accumulates chunks in real time using getReader() + TextDecoder.
Because open-source models don't have a native "chat completions" endpoint like Claude, lib/ai.ts manually builds the prompt using the Mistral instruct template:
<s>[INST] System prompt + first user message [/INST] Assistant response</s>
[INST] Next user message [/INST] Assistant response</s>
[INST] Current user message [/INST]
The model then generates tokens after the final [/INST] tag.
Edit lib/ai.ts:
export const HF_MODEL = 'meta-llama/Meta-Llama-3-8B-Instruct'
// or
export const HF_MODEL = 'HuggingFaceH4/zephyr-7b-beta'
⚠️ If you change models, you must update thebuildPrompt()function to match that model's chat template (e.g., Llama-3 uses<|start_header_id|>tags, Zephyr uses a different format).
Edit lib/constants.ts and append to the TIERS array. Both deliverable/aha (Strategy) and codeSnippet (Build) render automatically.
The palette is hardcoded via Tailwind arbitrary values (e.g., bg-[#FAF8F4], text-[#4AE3A0]). Search-and-replace across component files to re-theme.
- Cold-start latency: The Hugging Face Serverless Inference API (free tier) queues requests if the model hasn't been used recently. The first request may return a 503 with "Model is currently loading". The API route catches this and returns a friendly message. For production, use a Dedicated Endpoint or upgrade to PRO for always-warm models.
- Rate limits: Free tier has request limits. If you hit them, the chat will error out.
- No contact form: The CTA uses a
mailto:link. A real form would need an additional API route. - Stack items vs. deps: Framer Motion and Spline Runtime are listed in the UI stack grid but are not installed in
package.json. Add them only if you implement actual animations beyond the CSS keyframes. - Missing production files: No
error.tsx,sitemap.ts, orrobots.tsyet.
Proprietary — IRIS_AI
Built with precision × scale.