Communitygithub.com

ZeroSum-Solutions/mishmash

Single-page landing for the fictional creative design studio **Viktor Oddy**, built with React + TypeScript + Vite + Tailwind CSS and lucide-react icons. The design is minimal white-background throughout, pairing **PP Neue Montreal** (body, Webflow CDN) with **PP Mondwest** (serif accent, served locally from `/PPMondwest-Regular.woff2`). Staggered IntersectionObserver scroll reveals, an infinite image marquee, a parallax testimonial portrait, pricing cards, an auto-scrolling testimonial carousel, a project showcase, and a cursor-trail GIF CTA make up the full interactive experience.

What is mishmash?

mishmash is a Claude Code agent skill that single-page landing for the fictional creative design studio **Viktor Oddy**, built with React + TypeScript + Vite + Tailwind CSS and lucide-react icons. The design is minimal white-background throughout, pairing **PP Neue Montreal** (body, Webflow CDN) with **PP Mondwest** (serif accent, served locally from `/PPMondwest-Regular.woff2`). Staggered IntersectionObserver scroll reveals, an infinite image marquee, a parallax testimonial portrait, pricing cards, an auto-scrolling testimonial carousel, a project showcase, and a cursor-trail GIF CTA make up the full interactive experience.

Works with✓Claude Code~Codex CLI✓Cursor
npx skills add https://github.com/ZeroSum-Solutions/mishmash/tree/HEAD/design-templates/viktor-oddy-landing

Ask in your favorite AI

Open a new chat with this agent skill pre-loaded.

Documentation

Viktor Oddy — Creative Studio Landing Page

Landing page vendored from the MIT-licensed pulkitxm/claude-directory gallery.

Single-page landing for the fictional creative design studio Viktor Oddy, built with React + TypeScript + Vite + Tailwind CSS and lucide-react icons. The design is minimal white-background throughout, pairing PP Neue Montreal (body, Webflow CDN) with PP Mondwest (serif accent, served locally from /PPMondwest-Regular.woff2). Staggered IntersectionObserver scroll reveals, an infinite image marquee, a parallax testimonial portrait, pricing cards, an auto-scrolling testimonial carousel, a project showcase, and a cursor-trail GIF CTA make up the full interactive experience.

Workflow

  1. Clone example.html into the user's workspace as the working file.
  2. Replace placeholder content with the user's real brand name, headlines, body copy, numbers, and imagery. Match existing image dimensions when swapping assets.
  3. Preserve the design system. The palette, type scale, spacing rhythm, and motion in the build spec below are the identity — do not substitute fonts, recolour the palette, or strip decorative elements.
  4. Extend by duplicating sections, never by importing a layout from another template. If a section is missing, design it from scratch in this template's own vocabulary.
  5. Keep motion accessible. Every animation must stay behind prefers-reduced-motion, as the build spec requires.

Output contract

Emit between <artifact> tags:

<artifact identifier="viktor-oddy-landing" type="text/html" title="Viktor Oddy — Creative Studio Landing Page">
<!doctype html>
<html>...</html>
</artifact>

Build spec

The upstream prompt that produced this design, verbatim.

Viktor Oddy — Creative Studio Landing Page

Overview

Build a single-page marketing landing page for a creative design studio called "Viktor Oddy". The page has a white background throughout, uses two custom fonts, and is composed of a centered hero, an infinite image marquee, a parallax testimonial, a pricing grid, an auto-scrolling testimonial carousel, a project showcase, an interactive partner CTA, a footer, a copyright bar, and a fixed floating bottom nav. Scroll-triggered fade-in animations are used throughout.

Tech Stack

  • Framework: React 18 (react ^18.3.1, react-dom ^18.3.1) with TypeScript (typescript ^5.7.3).
  • Build tool: Vite (vite ^5.4.14) with @vitejs/plugin-react (^4.3.4). Build script: tsc -b && vite build.
  • Styling: Tailwind CSS (tailwindcss ^3.4.17) with postcss (^8.5.1) and autoprefixer (^10.4.20).
  • Icons: lucide-react (^0.469.0) — Quote, Star, ChevronLeft, ChevronRight, ArrowUpRight.
  • Fonts: PP Neue Montreal (body, loaded from Webflow CDN) and PP Mondwest (serif accent, loaded from a local /PPMondwest-Regular.woff2 file). The body default font is PP Neue Montreal with system fallbacks (font-sans).
  • Notable techniques: IntersectionObserver-driven scroll reveals, a CSS marquee, a requestAnimationFrame parallax image, an auto-playing infinite carousel with snap-back, and a cursor-trail effect that spawns image thumbnails on mouse move.

Global Setup

index.html

  • lang="en", charset UTF-8, viewport meta.
  • Description meta: Viktor Oddy — the creative studio of Viktor Oddy. Build the next wave, the bold way.
  • Title: Viktor Oddy — Creative Studio.
  • Inline SVG favicon (data URI): a rounded square fill='%23051A24' with a serif "V" in fill='%23F6FCFF'.
  • Preload the font: <link rel="preload" href="/PPMondwest-Regular.woff2" as="font" type="font/woff2" crossorigin />.
  • Root element <div id="root"></div> mounted by /src/main.tsx.

src/main.tsx

Standard React 18 entry. Renders <App /> inside <StrictMode> and imports ./index.css.

import { StrictMode } from 'react';
import { createRoot } from 'react-dom/client';
import App from './App';
import './index.css';

createRoot(document.getElementById('root')!).render(
  <StrictMode>
    <App />
  </StrictMode>,
);

src/index.css — fonts and global base

Includes the three @tailwind directives, the @font-face declarations, a base layer, and the keyframe animations.

@tailwind base;
@tailwind components;
@tailwind utilities;

@font-face {
  font-family: 'PP Neue Montreal';
  src: url('https://assets.website-files.com/6009ec8cda7f305645c9d91b/60176f9bb43e36419997ecfe_PPNeueMontreal-Book.otf')
    format('opentype');
  font-weight: 400;
  font-display: swap;
}

@font-face {
  font-family: 'PP Neue Montreal';
  src: url('https://assets.website-files.com/6009ec8cda7f305645c9d91b/60176f9b39c5673e51a86f5a_PPNeueMontreal-Medium.otf')
    format('opentype');
  font-weight: 500;
  font-display: swap;
}

@font-face {
  font-family: 'PP Mondwest';
  src: url('/PPMondwest-Regular.woff2') format('woff2');
  font-weight: 400;
  font-display: swap;
}

@layer base {
  html {
    scroll-behavior: smooth;
  }

  body {
    @apply bg-white font-sans text-[#051A24] antialiased;
  }
}

Configure Tailwind so that font-serif maps to PP Mondwest and font-sans to PP Neue Montreal (with system fallbacks).

Layout (src/App.tsx)

The root <div id="top"> uses min-h-screen bg-white pb-32. Sections render in this order:

  1. Hero
  2. Marquee
  3. TestimonialSection
  4. PricingSection
  5. TestimonialCarousel
  6. ProjectsSection
  7. PartnerSection (receives images={MARQUEE_IMAGES})
  8. Footer
  9. CopyrightBar
  10. BottomNav

Shared constants

  • BOOK_URL = 'https://halaskastudio.com/./book' — used by primary/secondary CTAs throughout.
  • MARQUEE_IMAGES — eight GIF paths (also reused by PartnerSection):
const MARQUEE_IMAGES = [
  '/assets/hero-space-voyage-preview-eECLH3Yc.gif',
  '/assets/hero-portfolio-cosmic-preview-BpvWJ3Nc.gif',
  '/assets/hero-velorah-preview-CJNTtbpd.gif',
  '/assets/hero-asme-preview-B_nGDnTP.gif',
  '/assets/hero-transform-data-preview-Cx5OU29N.gif',
  '/assets/hero-aethera-preview-DknSlcTa.gif',
  '/assets/hero-orbit-web3-preview-BXt4OttD.gif',
  '/assets/hero-nexora-preview-cx5HmUgo.gif',
];

Asset note: These GIFs (and the avatar/parallax images below) are vendored locally under public/assets/. They originate from https://motionsites.ai/assets/... (e.g. https://motionsites.ai/assets/hero-space-voyage-preview-eECLH3Yc.gif), with case-sensitive filenames matching the local paths.

Hero (Hero in src/App.tsx)

Centered, narrow column: <section id="about"> with mx-auto w-full max-w-[440px] px-6 pt-12 md:pt-16. Uses the useInViewAnimation hook for staggered reveals.

  • Logo text: Viktor Oddy in an <h1>, classes mb-4 font-serif text-[32px] font-semibold tracking-tight text-[#051A24] md:text-[40px] lg:text-[44px]. Animation delay 0.1s.
  • Tagline: The creative studio of Viktor Oddy in a <p>, classes mb-2 font-mono text-xs text-[#051A24] md:text-sm. Animation delay 0.2s.
  • Main heading (<h2>): two lines — Build the next wave, / the bold way. — where next wave and bold way. are wrapped in <span className="font-serif">. Classes whitespace-nowrap text-[32px] leading-[1.1] tracking-tight text-[#0D212C] md:text-[40px] lg:text-[44px]. A <br /> separates the lines. Animation delay 0.3s.
  • Description: a flex flex-col gap-6 container with classes mt-5 ... text-sm leading-relaxed text-[#051A24] md:mt-6 md:text-base, three paragraphs. Animation delay 0.4s:
    • Paragraph 1: I spent seven years at Apple crafting products used by over a billion people. I founded Vortex Studio to bring that same level of thinking to innovators shaping what comes next.
    • Paragraph 2: The studio is deliberately small. I guide the creative vision on every project, backed by a veteran design crew that moves fast without cutting corners.
    • Paragraph 3: Projects start at $5,000 per month.
  • Buttons: a flex flex-col gap-3 sm:flex-row md:mt-6 md:gap-4 container, mt-5, animation delay 0.5s:
    • Start a chat — variant="primary", href={BOOK_URL}.
    • View projects — variant="secondary", href="#work".

Infinite Marquee (Marquee in src/App.tsx)

Full-width horizontally scrolling image strip.

  • Wrapper: mb-16 mt-16 w-full overflow-hidden md:mt-20.
  • Track: animate-marquee flex w-max.
  • The eight MARQUEE_IMAGES are duplicated ([...MARQUEE_IMAGES, ...MARQUEE_IMAGES], 16 total). Each <img> has key={i}, alt="", aria-hidden={i >= MARQUEE_IMAGES.length} (the duplicate copy is hidden from assistive tech), and classes mx-3 h-[280px] w-auto rounded-2xl object-cover shadow-lg md:h-[500px].
  • Animation (CSS): translateX(0) to translateX(-50%), 30s linear infinite on desktop, 10s on mobile.

Testimonial / Parallax Section (src/components/TestimonialSection.tsx)

<section> with mx-auto max-w-2xl px-6 py-12 text-center. Uses useInViewAnimation plus a custom useParallax hook.

  • Quote icon: Lucide Quote, classes mx-auto h-6 w-6 text-slate-900, wrapped in a <div> with animation delay 0.1s.
  • Large quote (<blockquote>): ‘I left + <span className="font-serif">Apple</span> + to build the studio I always wanted to work with’ (uses &lsquo; / &rsquo; curly quotes). Classes mt-6 text-[32px] leading-[1.1] tracking-tight text-[#0D212C] md:text-[40px] lg:text-[44px]. Animation delay 0.2s.
  • Author: Viktor Oddy in a <p>, classes mt-6 text-sm italic text-[#273C46]. Animation delay 0.3s.
  • Company logos (as text): a mt-12 flex items-center justify-center gap-8 row, animation delay 0.4s. Each is a <span> with classes text-[24px] font-medium text-slate-900 and an inline width:
    • Apple — 80px
    • IDEO — 83px
    • Polygon — 110px
  • Parallax image: a <div ref={parallaxRef}> with mt-16 and animation delay 0.5s, containing an <img>:
    • src = /assets/hf_20260330_103804_7aa5494f-4d5b-432e-9dc7-20715275f143.webp
    • alt="Chris Halaska", loading="lazy"
    • Classes mx-auto w-full max-w-xs rounded-2xl shadow-lg will-change-transform
    • Inline style={{ transform: \translateY(${offset.toFixed(2)}px)` }}`

Asset note: The parallax image is vendored locally as the .webp above. It originally came from https://images.higgs.ai/?default=1&output=webp&url=https%3A%2F%2Fd8j0ntlcm91z4.cloudfront.net%2Fuser_38xzzbokvigwjottwixh07lwa1p%2Fhf_20260330_103804_7aa5494f-4d5b-432e-9dc7-20715275f143.png&w=1280&q=85.

useParallax hook

const PARALLAX_MAX_OFFSET = 200;
  • Tracks an element with an IntersectionObserver (sets a visible flag) plus passive scroll and resize listeners.
  • On update, computes progress (viewportHeight - rect.top) / (viewportHeight + rect.height) clamped to [0, 1], then next = (clamped - 0.5) * 2 * PARALLAX_MAX_OFFSET, clamped to [-200, 200] px.
  • Updates are scheduled via requestAnimationFrame and only run while the element is visible; the frame and listeners are cleaned up on unmount.

Pricing Section (src/components/PricingSection.tsx)

<section id="services"> with w-full px-6 py-12. Inner wrapper md:flex md:justify-end; the grid is grid grid-cols-1 gap-8 md:max-w-4xl md:grid-cols-2 (right-aligned on desktop). Uses useInViewAnimation. BOOK_URL = 'https://halaskastudio.com/./book'.

Card 1 — Monthly Partnership (dark)

<article> classes: rounded-[40px] bg-[#051A24] pb-10 pl-10 pr-10 pt-3 shadow-[inset_0_2px_16px_0_rgba(246,252,255,0.12)] md:pr-24. Animation delay 0.1s.

  • Title (<h3>): Monthly Partnership — mt-7 text-[22px] font-medium text-[#F6FCFF].
  • Description (<p>): A dedicated creative design team. <br /> You work directly with Viktor. — mt-3 text-sm leading-relaxed text-[#E0EBF0].
  • Price: $5,000 in mt-8 text-2xl text-[#F6FCFF], then Monthly in mt-1 text-sm text-[#E0EBF0].
  • Buttons (mt-8 flex flex-col gap-3 sm:flex-row): Start a chat (variant="primary") and How it works (variant="secondary"), both href={BOOK_URL}.

Card 2 — Custom Project (light)

<article> classes: rounded-[40px] bg-white pb-10 pl-10 pr-10 pt-3 shadow-[0_4px_16px_rgba(0,0,0,0.08)] md:pr-24. Animation delay 0.2s.

  • Title (<h3>): Custom Project — mt-7 text-[22px] font-medium text-[#0D212C].
  • Description (<p>): Fixed scope, fixed timeline. <br /> Same team, same standards. — mt-3 text-sm leading-relaxed text-[#273C46].
  • Price: $5,000 in mt-8 text-2xl text-[#0D212C], then Minimum in mt-1 text-sm text-[#273C46].
  • Button (mt-8 flex): Start a chat (variant="tertiary"), href={BOOK_URL}.

Testimonial Carousel (src/components/TestimonialCarousel.tsx)

<section> with w-full overflow-hidden py-20. Uses useInViewAnimation.

Header row

A flex flex-col gap-8 md:ml-auto md:max-w-4xl md:flex-row md:items-end md:justify-between container (animation delay 0.1s):

  • Title (<h2>): What + <span className="font-serif">builders</span> + say, classes text-[32px] leading-[1.1] tracking-tight text-[#0D212C] md:text-[40px] lg:text-[44px].
  • Right cluster (flex flex-col items-start gap-4 md:items-end):
    • Five Lucide Star icons (h-5 w-5 fill-black text-black) inside a flex wrapper labeled aria-label="5 out of 5 stars", followed by Clutch 5/5 in text-sm text-[#051A24].
    • Prev/next buttons in a flex gap-3: each flex h-12 w-12 items-center justify-center rounded-full border border-[#0D212C]/20 text-[#0D212C] transition-colors hover:bg-[#0D212C]/5, containing Lucide ChevronLeft / ChevronRight (h-5 w-5) with aria-label "Previous testimonial" / "Next testimonial".

Carousel mechanics

const COUNT = TESTIMONIALS.length;
const TRIPLED = [...TESTIMONIALS, ...TESTIMONIALS, ...TESTIMONIALS];
const GAP = 24; // gap-6
const DESKTOP_CARD_WIDTH = 427.5;
const AUTOPLAY_MS = 3000;
  • State: index (starts at COUNT), animate, hovered, cardWidth.
  • Card width updates on resize: window.innerWidth >= 768 ? DESKTOP_CARD_WIDTH : window.innerWidth - 48 (i.e. 427.5px on desktop, full width minus 48px on mobile).
  • Auto-advance every 3000ms via setInterval; pauses while hovered (onMouseEnter / onMouseLeave on the track wrapper).
  • The testimonials are tripled for an infinite-scroll illusion. handleTransitionEnd snaps the index back into the middle copy without animation when it drifts past COUNT * 2 or below COUNT (re-enabling animate after a double requestAnimationFrame).
  • Track container: mt-12 pl-6 (animation delay 0.2s). Inner track: flex gap-6 will-change-transform with inline transform: translateX(-offset px) where offset = index * (cardWidth + GAP), and transition: 'transform 0.8s cubic-bezier(0.4, 0, 0.2, 1)' when animating ('none' otherwise).

Cards

Each <article>: shrink-0 rounded-[32px] bg-white px-6 py-8 shadow-[0_4px_16px_rgba(0,0,0,0.08)] md:rounded-[40px] md:pl-10 md:pr-24, inline width: ${cardWidth}px. Exited cards (i < index) fade and scale down: opacity: 0 and transform: scale(0.9) with transition: opacity 0.8s cubic-bezier(0.4, 0, 0.2, 1), transform 0.8s cubic-bezier(0.4, 0, 0.2, 1).

Card content:

  • QuoteMark SVG — a custom 28x22 (viewBox="0 0 28 22") double-quote glyph filled #0D212C:
<svg width="28" height="22" viewBox="0 0 28 22" fill="none" xmlns="http://www.w3.org/2000/svg" aria-hidden="true">
  <path
    d="M0 22V14.3C0 11.5 0.56 9 1.68 6.8C2.84 4.56 4.72 2.3 7.32 0L11.6 3.1C10 4.62 8.82 6.04 8.06 7.36C7.34 8.68 6.94 10.06 6.86 11.5H12.2V22H0ZM15.8 22V14.3C15.8 11.5 16.36 9 17.48 6.8C18.64 4.56 20.52 2.3 23.12 0L27.4 3.1C25.8 4.62 24.62 6.04 23.86 7.36C23.14 8.68 22.74 10.06 22.66 11.5H28V22H15.8Z"
    fill="#0D212C"
  />
</svg>
  • Quote text (<p>): mt-5 text-base leading-relaxed text-[#0D212C].
  • Author row (mt-7 flex items-center gap-4): circular avatar <img> (h-12 w-12 rounded-full object-cover, loading="lazy", alt={name}), name in text-sm font-semibold text-[#051A24], role/company in text-sm text-[#273C46] prefixed with → (&rarr;): → {role}, {company}.

Testimonials data

NameRoleCompanyAvatar
Marcus AndersonCEOData.storage/assets/pexels-2379004.jpg
alexwuFounderNexgate/assets/pexels-220453.jpg
James MitchellVP ProductLaunchPad/assets/pexels-614810.jpg
Rachel FosterCo-founderNexus Labs/assets/pexels-774909.jpg
David ZhangHead of DesignParadigm Labs/assets/pexels-1222271.jpg

Quotes (verbatim):

  1. With very little guidance team delivered designs that were consistently spot on. They understood our brand from day one, and every iteration landed closer than anything we could have briefed ourselves.
  2. Viktor led the creation of our best fundraising deck to date! Investors kept commenting on the design before we even got to the numbers. Worth every dollar and then some.
  3. Working with Viktor transformed our product vision into an interface our users genuinely love. Every screen feels considered — nothing shipped until it earned its place.
  4. The design quality exceeded our expectations at every single milestone. It felt like having a world-class in-house design team without the overhead of building one.
  5. Incredible work from start to finish. Fast, opinionated in the best way, and relentlessly polished. The crew moves like a team three times its size.

Asset note: Avatars are vendored locally from Pexels (pexels-*.jpg).

Projects Section (src/components/ProjectsSection.tsx)

<section id="work"> with mx-auto max-w-[1200px] px-6 py-12. Inner stack: flex flex-col gap-16 md:gap-20. Each ProjectItem independently triggers a fade-in via its own useInViewAnimation.

Each ProjectItem (animation delay 0.1s):

  • Text block offset left: <div className="ml-20 mb-6 md:ml-28"> with the project name (<h3>, font-serif text-2xl font-semibold text-[#051A24] md:text-3xl) and description (<p>, mt-2 text-sm text-[#051A24]/70 md:text-base).
  • Full-width <img> below: w-full rounded-2xl object-cover shadow-lg, loading="lazy", alt={\${name} — ${description}`}`.

Projects data:

NameDescriptionImage
evrFrom idea to millions raised for a web3 AI product/assets/hero-evr-ventures-preview-DZxeVFEX.gif
Automation MachinesStreamlining industrial automation processes/assets/hero-automation-machines-preview-DlTveRIN.gif
xPortfolioModern portfolio management platform/assets/hero-xportfolio-preview-D4A8maiC.gif

Asset note: Project GIFs are vendored locally; original origin https://motionsites.ai/assets/....

Partner Section (src/components/PartnerSection.tsx)

<section> with w-full px-6 py-12. Receives images: string[] (the MARQUEE_IMAGES). Uses useInViewAnimation.

const SPAWN_INTERVAL_MS = 80;
const TRAIL_LIFETIME_MS = 1000;
const AVATAR = '/assets/pexels-415829.jpg';
  • Container (ref={containerRef}, onMouseMove={handleMouseMove}): relative mx-auto max-w-7xl overflow-hidden rounded-[40px] bg-white py-48 text-center shadow-[0_0_0_0.5px_rgba(0,0,0,0.05),0_4px_30px_rgba(0,0,0,0.06)]. Animation delay 0.1s.
  • Cursor trail: on mousemove, no more often than every 80ms (performance.now() throttle), a TrailItem is spawned at the cursor position (event.clientX/Y minus the container rect) with a random rotation of Math.random() * 20 - 10 (i.e. −10° to +10°), cycling through images. Each trail <img> is animate-trail-fade pointer-events-none absolute z-0 w-36 rounded-lg shadow-lg, positioned via inline left/top, and sets the CSS custom property --trail-rotation. Items are removed after 1000ms via setTimeout; all timeouts are tracked in a Set and cleared on unmount.
  • Foreground (pointer-events-none relative z-10):
    • Heading (<h2>): Partner with us, classes mb-12 font-serif text-[48px] leading-[1.05] text-[#0D212C] md:text-[64px] lg:text-[80px].
    • CTA Button variant="primary", href="https://halaskastudio.com/./book", extra classes pointer-events-auto py-2 pl-2, containing a circular avatar <img src={AVATAR}> (h-10 w-10 rounded-full object-cover, aria-hidden) and the label Start chat with Viktor.

Asset note: The avatar (pexels-415829.jpg) is vendored locally from Pexels.

Footer (src/components/Footer.tsx)

<footer> with mx-auto w-full max-w-[1200px] px-6 py-12, animation delay 0.1s (via useInViewAnimation).

  • Inner flex flex-col justify-between gap-12 md:flex-row.
  • Left: Start a chat (variant="primary", href="https://halaskastudio.com/./book").
  • Right (flex items-start gap-8): Lucide ArrowUpRight (mt-1 h-5 w-5 text-[#051A24]), then two <nav> columns of links (flex flex-col gap-3):
    • Anchor links (aria-label="Site"): Services → #services, Work → #work, About → #about.
    • External links (aria-label="Social", target="_blank", rel="noopener noreferrer"): x.com → https://x.com, LinkedIn → https://www.linkedin.com.
  • All links: text-base text-[#051A24] transition-opacity hover:opacity-70.

Copyright Bar (src/components/CopyrightBar.tsx)

A <div> with mx-auto flex w-full max-w-[1200px] items-center justify-between px-6 py-4 text-sm text-[#051A24]. Left <span>: Vortex Studio Limited. Right <span>: Austin, USA.

Fixed Bottom Nav (src/components/BottomNav.tsx)

A floating pill <nav aria-label="Quick actions"> fixed to the bottom and horizontally centered: fixed bottom-6 left-1/2 z-50 flex -translate-x-1/2 items-center gap-6 rounded-full bg-white px-8 py-2, with a layered shadow:

shadow-[0_0_0_0.5px_rgba(0,0,0,0.05),0_1px_2px_0_rgba(5,26,36,0.1),0_4px_4px_0_rgba(5,26,36,0.09),0_9px_6px_0_rgba(5,26,36,0.05),0_17px_7px_0_rgba(5,26,36,0.01),0_4px_30px_rgba(0,0,0,0.08)]

Contents:

  • A V link (href="#top", aria-label="Back to top") in font-serif text-2xl font-semibold text-[#051A24].
  • A Start a chat button (variant="primary", href="https://halaskastudio.com/./book", extra classes px-5 py-2.5).

Button Component (src/components/Button.tsx)

A reusable anchor-based button. Props extend AnchorHTMLAttributes<HTMLAnchorElement> with variant?: 'primary' | 'secondary' | 'tertiary' (default 'primary') and children.

Base classes:

inline-flex cursor-pointer items-center justify-center gap-2 whitespace-nowrap rounded-full px-7 py-3 text-sm font-medium transition-transform duration-200 ease-out hover:-translate-y-0.5 active:translate-y-0

Variant classes:

  • primary: bg-[#051A24] text-white + PRIMARY_SHADOW
  • secondary: bg-white text-[#051A24] + SECONDARY_SHADOW
  • tertiary: bg-white text-[#051A24] + TERTIARY_SHADOW

Shadow tokens (critical for the design feel):

PRIMARY_SHADOW =
  'shadow-[0_1px_2px_0_rgba(5,26,36,0.1),0_4px_4px_0_rgba(5,26,36,0.09),0_9px_6px_0_rgba(5,26,36,0.05),0_17px_7px_0_rgba(5,26,36,0.01),0_26px_7px_0_rgba(5,26,36,0),inset_0_2px_8px_0_rgba(255,255,255,0.5)]'

SECONDARY_SHADOW =
  'shadow-[0_0_0_0.5px_rgba(0,0,0,0.05),0_4px_30px_rgba(0,0,0,0.08)]'

TERTIARY_SHADOW =
  'shadow-[0_0_0_0.5px_rgba(0,0,0,0.05),0_4px_30px_rgba(0,0,0,0.08),0_1px_2px_0_rgba(5,26,36,0.1),0_4px_4px_0_rgba(5,26,36,0.09),0_9px_6px_0_rgba(5,26,36,0.05)]'

Animations

useInViewAnimation hook (src/hooks/useInViewAnimation.ts)

A generic scroll-trigger hook. It observes a refd element with an IntersectionObserver (threshold: 0.1), flips inView to true once when at least 10% enters the viewport (then disconnects, so it triggers only once), and returns { ref, inView, animationClass } where animationClass is 'animate-fade-in-up' when in view and 'opacity-0' otherwise.

import { useEffect, useRef, useState } from 'react';

export function useInViewAnimation<T extends HTMLElement = HTMLDivElement>() {
  const ref = useRef<T | null>(null);
  const [inView, setInView] = useState(false);

  useEffect(() => {
    const element = ref.current;
    if (!element) return;

    const observer = new IntersectionObserver(
      (entries) => {
        if (entries[0]?.isIntersecting) {
          setInView(true);
          observer.disconnect();
        }
      },
      { threshold: 0.1 },
    );

    observer.observe(element);
    return () => observer.disconnect();
  }, []);

  const animationClass = inView ? 'animate-fade-in-up' : 'opacity-0';

  return { ref, inView, animationClass };
}

Each element within a section uses staggered animationDelay values (0.1s, 0.2s, 0.3s, etc.).

CSS keyframes (in src/index.css)

/* ---- Infinite marquee ---- */
@keyframes marquee {
  0% {
    transform: translateX(0);
  }
  100% {
    transform: translateX(-50%);
  }
}

.animate-marquee {
  animation: marquee 30s linear infinite;
}

@media (max-width: 767px) {
  .animate-marquee {
    animation-duration: 10s;
  }
}

/* ---- Scroll-triggered fade in ---- */
@keyframes fadeInUp {
  0% {
    opacity: 0;
    transform: translateY(30px);
  }
  100% {
    opacity: 1;
    transform: translateY(0);
  }
}

.animate-fade-in-up {
  animation: fadeInUp 0.8s ease-out forwards;
  opacity: 0;
}

/* ---- Cursor trail thumbnails (PartnerSection) ---- */
@keyframes trail-fade {
  0% {
    opacity: 1;
    transform: translate(-50%, -50%) rotate(var(--trail-rotation, 0deg)) scale(1);
  }
  100% {
    opacity: 0;
    transform: translate(-50%, -50%) rotate(var(--trail-rotation, 0deg)) scale(0.6);
  }
}

.animate-trail-fade {
  animation: trail-fade 1000ms ease-out forwards;
}

@media (prefers-reduced-motion: reduce) {
  .animate-marquee,
  .animate-fade-in-up,
  .animate-trail-fade {
    animation-duration: 0.01ms;
    animation-iteration-count: 1;
  }
}

Note: the trail keyframe scales to 0.6 and the .animate-fade-in-up rule keeps opacity: 0 so elements stay hidden until their delayed animation runs. A prefers-reduced-motion: reduce block neutralizes all three animations.

Color Palette

  • Primary dark: #051A24 (also body text)
  • Secondary dark: #0D212C
  • Light text on dark: #F6FCFF, #E0EBF0
  • Muted text: #273C46
  • Background: white throughout

File Structure

  • index.html — favicon, font preload, root mount.
  • src/main.tsx — React entry (StrictMode, imports index.css).
  • src/App.tsx — main layout with Hero, Marquee, and section composition; defines MARQUEE_IMAGES and BOOK_URL.
  • src/components/Button.tsx — reusable button (primary/secondary/tertiary variants).
  • src/components/TestimonialSection.tsx — quote with parallax image (useParallax).
  • src/components/PricingSection.tsx — two pricing cards.
  • src/components/TestimonialCarousel.tsx — auto-scrolling testimonial cards.
  • src/components/ProjectsSection.tsx — project showcase items.
  • src/components/PartnerSection.tsx — interactive mouse-trail CTA section.
  • src/components/Footer.tsx — footer with links.
  • src/components/CopyrightBar.tsx — copyright line.
  • src/components/BottomNav.tsx — fixed floating bottom nav.
  • src/hooks/useInViewAnimation.ts — IntersectionObserver scroll-trigger hook.
  • src/index.css — font faces, marquee animation, fade-in-up animation, cursor-trail animation.
  • public/PPMondwest-Regular.woff2 — local serif accent font.
  • public/assets/ — vendored GIF previews, Pexels avatars, and the parallax .webp.

Source & license

Vendored from MIT-licensed pulkitxm/claude-directory. The upstream MIT licence text ships in this template at LICENSE and must be redistributed alongside any copy of example.html or assets/.

Webfonts and full-resolution imagery are not vendored: local @font-face rules are served from the Google Fonts CDN and referenced images are downscaled. Fetch the upstream folder for the original assets.

Individual skills in this repo

This repo contains 20 individual skills — each has its own dedicated page.

ZeroSum-Solutions/mishmash

Two-section scroll landing for **S.P.D**, a fictional daily-operations automation platform. Section one is a full-bleed black hero: a muted, looping period-painting video plays edge to edge behind a top-left wordmark and tagline, a top-right pill CTA, and a large right-aligned serif headline low in the frame. A cloud-plume image straddles the seam into section two, a saturated red panel holding a centered monogram, an uppercase mission line, a large script signature, two closing lines of copy, and a second looping video with a soft fade into the red. Motion is a staggered load-in fade on the hero, an IntersectionObserver reveal on the red section's content, and a scroll-linked parallax on the cloud plume — all degrading to a static, fully-visible layout under reduced motion.

ZeroSum-Solutions/mishmash

Full-screen, single-viewport (100vh, no scroll) dark hero landing page for **Asme**, a fictional no-code AI app platform. The fullscreen background is an HLS video stream from Mux, playing natively on Safari and via hls.js MediaSource on other browsers. A liquid-glass pill navbar (luminosity-blended glass with a masked `::before` gradient border) floats above an Instrument Serif hero heading and an animated email-capture CTA — "Get early access" expands to a form with a 60 ms/char typewriter placeholder, flips `ArrowRight` to `Check` on submit, and auto-resets after 4 seconds. All elements animate in on load with Motion (Framer Motion).

ZeroSum-Solutions/mishmash

A pixel-spec, dark-themed single-page marketing landing site for **Asme**, a fictional knowledge and insights platform, featuring a signature reusable `.liquid-glass` surface treatment — luminosity-blended translucent fill, 4px backdrop blur, inset top highlight, and a masked `::before` gradient border — applied consistently across the navbar pill, email capture, buttons, cards, and icon chips. The full-viewport hero loops a locally vendored `.mp4` video via a vanilla `requestAnimationFrame` opacity crossfade (fade in on `canplay`, fade out at 0.55s remaining, 100ms gap restart). Four scroll-triggered sections animate in with Framer Motion `useInView`: About, Featured Video, Innovation × Vision (video + two columns sliding from opposite sides), and Services (two glass cards with hover-zoom video). Instrument Serif display type sits against pure black throughout.

ZeroSum-Solutions/mishmash

A premium, dark-cinematic landing page for **Aura**, a fictional AI-native email client, featuring a looping fullscreen background video, a gradient-clip shiny headline, a macOS-style menu bar mockup, a realistic inbox preview, and a custom liquid-glass card treatment. The multi-section layout covers navbar, hero, menu bar, inbox mockup, feature triage, logo cloud, testimonials, pricing, and a final CTA — targeting the AI productivity app and SaaS landing page use case.

ZeroSum-Solutions/mishmash

A modern React landing page for a fictional broadcast-grade live video platform featuring a full-screen adaptive HLS video background, a glassmorphic navigation header, and hero content pinned to the bottom-left corner. Dark cinematic aesthetic with Gloock display serif, Archivo body, JetBrains Mono telemetry labels, and an aurora-green signal accent — ideal as a live streaming platform or video SaaS landing page template.

ZeroSum-Solutions/mishmash

A single-screen marketing landing page for "dot.", a calm-messaging product that links you with one anonymous peer for a single message each day. The hero is a full-screen looping background video of a phone, fronted by an animated Instrument Serif headline and a typewriter effect that types and deletes short messages ("Are you here?", "Yes, I am.", "Speak soon.") positioned to sit on the phone's on-screen display — evoking a quiet, analog rhythm. A floating pill navbar with a glinting "Link up" CTA completes the single-screen composition.

ZeroSum-Solutions/mishmash

A single-page "scrollytelling" landing page called Step Into Wonder: a 4.8-screen pinned scroll sequence where painted curtains part over a glowing crystal-cave portal, the world zooms and the portal irises open toward a sky beyond, then a giant arc of nine pastel destination cards sweeps across the closing scroll like a slow ferris wheel. Serif display headlines (Viaoda Libre) pair with a plain sans body face (Imprima) over a near-black stage, with mouse parallax on every layer and a dignified static fallback under reduced motion.

ZeroSum-Solutions/mishmash

Full landing page for the fictional AI workflow-automation platform **FlowMate** — a fixed left sidebar with a logo mark and section nav, a translucent blurred navbar, a large serif hero headline, a liquid-glass chat-composer card overlaid on a looping ambient video, a six-card feature grid, and an auto-rotating three-up cards carousel, all on an off-white minimalist palette with one indigo-violet chromatic accent.

ZeroSum-Solutions/mishmash

A single-page landing page for GroundAI, an interior-design AI product, built with TanStack Start v1 on file-based routing, React 19, TypeScript, Tailwind CSS v4, framer-motion for all animation, and lucide-react for icons. The page is composed of four stacked sections: a full-bleed autoplaying video hero with spring-animated header, expanding glass nav pill, and word-by-word animated description; a CSS marquee of partner brand wordmarks; a CraftExperiences section with a spring-driven style carousel, a skeleton-morphing chat card, and a staggered adaptable list; and a two-column testimonials block with animated word reveals.

ZeroSum-Solutions/mishmash

Produce a print-grade single-page kami (紙 / 纸) document — warm parchment canvas, ink-blue accent, serif at one weight, no italic, no cool grays. The output reads like a professional white paper or studio one-pager, not an app UI. Multilingual by design (EN · zh-CN · ja). One self-contained HTML file, zero dependencies.

ZeroSum-Solutions/mishmash

A single-page, desktop-only dark hero landing for the fictional studio **Kubric™**, built on **TanStack Start v1 + React 19 + Vite 7 + Tailwind v4** with file-based routing. Features a looping background video with a progressive 8-layer `backdrop-filter` blur at the bottom, an animated SVG logo with arc stroke-dashoffset reveals, a glass nav pill, a character-by-character headline reveal, a vertical right-side section nav, and a white "About us" card. Everything animates in on first load once the background video is ready.

ZeroSum-Solutions/mishmash

Warm, editorial single-page landing for **Velar.**, a fictional luxury real-estate brand. A deep-teal typewriter preloader gives way to a sky-backdrop hero ("Live in Irreplaceable") with a cutout building image that rises from below on load, then a scroll-driven centerpiece: as the user scrolls, that same building drifts upward and scales to 1.45x while pinning toward the bottom of a sticky black statement section with count-up stats. A hover-expand five-tile video gallery slides up over the statement section, and a bronze-gradient "Inquire" close finishes the page. Syne (display) pairs with Inter (body) throughout, on a warm off-white ground with one chromatic bronze accent.

ZeroSum-Solutions/mishmash

A full-screen, cinematic hero landing page for a creative agency called Mainframe, featuring a fixed background video that scrubs forward and backward in response to horizontal mouse movement, an AI-assistant-themed blurred intro label, a typewriter-animated headline, and a row of pill-shaped action buttons with a clipboard copy email link. The design pairs HelveticaNowDisplay-Medium headings with HelveticaNowDisplayW01-Rg body text, both vendored locally for offline use. Built with React 19, TypeScript, Vite, and Tailwind CSS v3.

ZeroSum-Solutions/mishmash

A cinematic, single-section landing hero for mėntality, a fictional mental-health resources product. The page pairs a full-bleed background video that gradient-masks into a soft `#edeef5` base with a glassmorphic, fixed navigation bar, built in React 19 + Vite and animated with Motion (formerly Framer Motion). Notable techniques include `backdrop-blur` glassmorphism, a gradient mask that blends the video top into the base color, `clamp()` fluid headline sizing, an animated SVG hamburger that morphs into an X, an inline blinking "eye/pupil" pill in the headline, and an animated `pl`/`en` language toggle. Styling is Tailwind CSS 4 via the `@tailwindcss/vite` plugin (CSS-first `@theme`, no config file), with Inter and Outfit from Google Fonts.

ZeroSum-Solutions/mishmash

A pure-black (#000) monochrome landing page for Mindloop, a newsletter and content platform, where white typography does the talking — Inter for structure and Instrument Serif italics for accent words. The seven-section page flows through a fixed glass navbar, a full-viewport MP4 hero with email capture, an AI-platform awareness section, a scroll-driven word-by-word opacity reveal, a solution feature grid with a 3:1 video panel, an HLS-streamed CTA section via hls.js (with native Safari fallback), and a minimal footer — with Framer Motion entrances and a liquid-glass CSS border effect throughout.

ZeroSum-Solutions/mishmash

Cinematic single-page landing for the fictional neural-AI platform **SynapseX**. A fixed, full-viewport background video scrubs frame-by-frame as the page scrolls and progressively blurs, sitting behind a scramble-in split-corner hero headline, a 3D-tilted cinematic paragraph reveal, and a frosted-glass horizontal metrics carousel. Pure black-and-white scaffolding is punctuated by one neon-green "synaptic" accent that ties the UI to the glowing footage underneath it.

ZeroSum-Solutions/mishmash

A dark, full-bleed landing page for Neuralyn, a fictional analytics-dashboard SaaS, featuring a full-viewport hero with a scroll-linked parallax dashboard composited over a looping background video and a scroll-driven testimonial where each word lights up as you scroll. The aesthetic is pure-black background, white type, a single italic serif accent word, and a liquid-glass tag pill. Built with React 18 + Vite and TypeScript, styled with Tailwind CSS 3 and shadcn/ui-style primitives, animated via Framer Motion (`useScroll`/`useTransform`) for scroll-linked parallax and the word-by-word color reveal, with fonts self-hosted via Fontsource.

ZeroSum-Solutions/mishmash

A monochrome, editorial landing page for a fictional Natural History Museum paleontology collection, featuring a three-section continuous scroll: a full-viewport hero with a delayed background video reveal and an animated geometric "NHM" SVG logotype (per-polygon slide-up reveal), an "Explore Our World" section with scroll-revealed display heading and action pills, and a dark "Ancient Collection" chapter browser with auto-cycling fossil images and a custom SVG `feTurbulence`/`feDisplacementMap` sand-dissolve transition effect. Built with React 19, Vite 6, Tailwind CSS 4 (CSS-first config), and Motion (Framer Motion), in a strictly monochrome black/white/gray palette — no color accents.

ZeroSum-Solutions/mishmash

A single-page NFT landing site with four full-bleed sections (Hero, About, Collection, CTA) on a dark space theme. The page uses looping muted background videos, a CSS liquid-glass UI effect, a fixed grain texture overlay, and a tight color system (deep navy `#010828`, off-white `#EFF4FF`, neon green `#6FFF00`; Anton headings, Condiment cursive accents, system mono body). Showcases a three-card NFT collection grid with rarity scores and video previews.

ZeroSum-Solutions/mishmash

An integration of the `HeroGeometric` component from Kokonut UI — five blurred, gradient-filled shapes drift behind a gradient-clipped headline on a near-black `#030303` canvas, all driven by Framer Motion. The component is dropped into a proper shadcn/ui project structure and wrapped in a landing experience (floating navbar, CTAs, a live props playground, feature grid, install band) that showcases it above the fold. This animated hero section is an ideal starting point for dark-themed SaaS, design tool, or portfolio landing pages.

Related Skills