photography-portfolio

byMD ABDULLA

Build a single-page dark cinematic photography portfolio for MD Abdulla using React + Vite + TypeScript + Tailwind CSS + GSAP + GSAP ScrollTrigger + Framer Motion + hls.js + react-router-dom + tailwindcss-animate. Use Motion/Framer Motion for declarative UI, entrance, filtering and lightbox animations, and GSAP for timelines, marquee and advanced scroll/parallax effects. The site is a premium digital photography exhibition showcasing MD Abdulla's real photographs, live moments, landscapes, nature, people, travel, architecture, street scenes and everyday beauty. It must feel cinematic, minimal, premium, artistic, editorial, emotional and immersive, never corporate or like a generic agency portfolio. NAME: MD Abdulla INSTAGRAM: @axr.md URL: https://instagram.com/axr.md MESSAGE: “Capturing moments. Preserving emotions. Telling stories through photographs.” IMPORTANT: Do NOT include any email, email address, mailto link, phone number, contact form or fake/placeholder contact details. Instagram is the only contact/social CTA. DESIGN SYSTEM Google Fonts: Inter 300–700, Instrument Serif italic 400. --font-body:'Inter',sans-serif; --font-display:'Instrument Serif',serif; --bg:0 0% 4%; --surface:0 0% 8%; --text:0 0% 96%; --muted:0 0% 53%; --stroke:0 0% 12%; --accent:0 0% 96%; Tailwind colors use "hsl(var(--...))". Accent gradient: "linear-gradient(90deg,#89AACC 0%,#4E85BF 100%)". Create ".accent-gradient" for logo ring, loading progress, hover borders and subtle highlights. Force dark theme. No light-mode toggle. Use large typography, generous negative space, subtle borders, cinematic overlays, slow transitions and natural image ratios. Avoid bright colors, excessive UI, generic stock images, excessive cards and artificial-looking photography. LOADING SCREEN Create "LoadingScreen" controlled by: "{isLoading && <LoadingScreen onComplete={()=>setIsLoading(false)} />}" Fullscreen "fixed inset-0 z-[9999] bg-bg". Animate counter 000 → 100 with requestAnimationFrame over 2700ms. Top-left: PHOTOGRAPHY, uppercase, tiny muted typography with y/opacity entrance. Center cycle every 900ms: Observe / Capture / Remember Use "AnimatePresence mode="wait"", y "20→0→-20", Instrument Serif italic. Bottom-right: huge tabular "000...100". Bottom progress: 3px stroke track with gradient inner bar using "scaleX(count/100)" and subtle glow. At 100 wait 400ms then close. HERO Full viewport cinematic hero. Use this HLS video: "https://stream.mux.com/Aa02T7oM1wH5Mk5EEVDYhbZ1ChcdhRsS2m1NYyx4Ua1g.m3u8" Use "hls.js"; initialize HLS when supported and fall back to native HLS when available. Video: "autoPlay muted loop playsInline", full-screen "object-cover". Overlay "bg-black/35"; bottom cinematic fade to background. NAVBAR Fixed floating pill at top center with backdrop blur, dark surface and subtle border. Logo: 9×9 circle with gradient ring, MA inside using Instrument Serif italic. Hover scale 1.1. Links: Home / Gallery / Journal / Explorations / About Active: light text + subtle stroke background. Inactive: muted with hover transition. Final button: Instagram ↗ Link to "https://instagram.com/axr.md". HERO TEXT Centered. Eyebrow: LIVE PHOTOGRAPHY • MD ABDULLA Main heading: MD Abdulla Use "text-7xl md:text-8xl lg:text-9xl font-display italic". Tagline: Capturing the beauty of real moments. Description: Photography is the art of noticing what others might pass by. Buttons: Explore Gallery and Instagram ↗ Use rounded-full buttons, subtle hover scale and elegant transitions. GSAP entrance: name fades from opacity 0/y50; remaining elements fade from blur(10px)/y20 with stagger, using "power3.out". Bottom: SCROLL TO EXPLORE + animated vertical line. LIVE GALLERY Call this section Live Gallery, never “Selected Works”. Eyebrow: 01 — LIVE GALLERY Heading: Moments I capture Make “capture” Instrument Serif italic. Description: A collection of photographs captured in real moments, from quiet landscapes to fleeting human experiences. Create a responsive masonry gallery: 3 columns desktop / 2 tablet / 1 mobile. Preserve natural aspect ratios. Do not unnecessarily crop photographs. Categories: All / Nature / Landscape / People / Travel / Architecture / Street / Night Animate filtering with Framer Motion. PHOTO CARDS Rounded-3xl, overflow-hidden, dark surface, subtle border. Images remain authentic and use smooth hover zoom. Hover overlay: View Photograph ↗ Show minimal metadata such as category and year. LIGHTBOX Click a photograph to open fullscreen "bg-black/95". Show the original photograph centered without distortion. Controls: Previous / Next / Close / Counter / Category / Caption Keyboard: Escape closes; Left/Right navigate. Animate with opacity "0→1" and scale ".96→1". FEATURED PHOTO Large cinematic photograph section. Heading: A moment worth remembering. Use GSAP ScrollTrigger for subtle parallax. Overlay: 01 / MOMENT / MD ABDULLA / 2026 Keep important image details unobstructed. RECENT FRAMES Heading: Recent Frames Make “Frames” Instrument Serif italic. Subtext: Small stories behind the photographs. Show 4–6 elegant horizontal entries with image, title, date, location, story and read time. Titles can include: After the Rain / The Quiet Road / Golden Hour / Between Two Moments / Where the Sky Meets the Earth / A Walk Through Silence Hover: subtle image zoom, brighter card and moving arrow. VISUAL EXPLORATIONS Create "min-h-[300vh]" scroll-driven photography exhibition. Heading: Visual Explorations Subtext: A collection of places, textures, people and moments that caught my eye. Create 2–3 vertical image columns. Use GSAP ScrollTrigger for different parallax speeds and subtle rotations "-2deg / 1deg / -1deg". Every image opens the lightbox. ABOUT Heading: Behind the Lens Make “Lens” Instrument Serif italic. Text: I'm MD Abdulla — a photographer drawn to the beauty hidden in ordinary moments. Additional: From landscapes and quiet streets to people, light and fleeting expressions, I photograph the moments that make a place feel alive. Show Instagram @axr.md ↗. Keep the section personal and understated. STATS Three artistic statistics: 100+ — Moments Captured 50+ — Places Explored ∞ — Stories to Tell Use large Instrument Serif typography. Avoid corporate styling. FINAL CTA Heading: Let's capture something beautiful. Description: For photography collaborations, creative projects, or simply to connect. Button: Instagram ↗ Only link to "https://instagram.com/axr.md". No email, phone or form. FOOTER Left: MD Abdulla Center: © 2026 MD Abdulla Right: Instagram ↗ Add: ● Available for photography & creative collaborations Use subtle pulsing dot. MARQUEE GSAP infinite marquee: CAPTURE THE MOMENT • Repeat 10×, "xPercent:-50", "duration:40", "ease:"none"", "repeat:-1". Use Instrument Serif italic, "text-5xl md:text-7xl". NAVIGATION Smooth-scroll between: Home / Gallery / Journal / Explorations / About Use native smooth scrolling or GSAP and highlight active section with Intersection Observer/ScrollTrigger. RESPONSIVE Optimize for mobile, tablet, laptop and large desktop. Mobile: compact/hamburger navigation, one-column gallery, natural image ratios, smaller typography, touch-friendly controls and no horizontal overflow. Never crop important parts of photographs unnecessarily. PHOTO DATA Create "src/data/photographs.ts": export const photographs=[ {id:1,src:"/images/photo-01.jpg",title:"After the Rain",category:"Nature",date:"2026",location:"India",description:"A quiet moment after the rain."} ]; All gallery, filtering, lightbox, featured content and explorations must use this centralized array. Adding/removing a photo must automatically update the website. AUTHENTICITY Use only MD Abdulla's actual photographs. Never AI-generate or transform them. Do not alter: - faces or facial features - skies - landscapes - objects - scenery - composition - identity - important colors/details No artificial people or objects. Allowed presentation effects only: hover zoom, lightbox, parallax, cinematic overlays, subtle brightness/contrast and smooth transitions. Photographs must remain authentic. PERFORMANCE Lazy-load images and use responsive image sizes. Clean up HLS instances, video listeners and GSAP ScrollTriggers on unmount. Avoid unnecessary React renders. Respect "prefers-reduced-motion". ACCESSIBILITY Use semantic HTML, correct heading hierarchy, descriptive alt text, keyboard-accessible navigation/lightbox, visible focus states and ARIA labels where appropriate. SEO Title: MD Abdulla — Photography Description: MD Abdulla — Photographer capturing landscapes, people, nature, travel and beautiful moments through photography. OG Title: MD Abdulla — Photography OG Description: Capturing moments. Preserving emotions. Telling stories through photographs. FILE STRUCTURE src/ ├── components/ │ ├── LoadingScreen.tsx │ ├── Navbar.tsx │ ├── Hero.tsx │ ├── Gallery.tsx │ ├── PhotoCard.tsx │ ├── Lightbox.tsx │ ├── FeaturedPhoto.tsx │ ├── CategoryFilter.tsx │ ├── Journal.tsx │ ├── Explorations.tsx │ ├── About.tsx │ ├── Stats.tsx │ ├── Contact.tsx │ └── Footer.tsx ├── data/photographs.ts ├── pages/Index.tsx └── index.css Add CSS animations for "scroll-down", "role-fade-in" and "gradient-shift". FINAL EXPERIENCE The site must feel like entering a premium digital photography exhibition. Priority: 1. Photography 2. Atmosphere 3. MD Abdulla 4. Instagram @axr.md Make visitors slowly explore, open photographs fullscreen, discover stories and follow Instagram. Overall feeling: Cinematic • Authentic • Minimal • Emotional • Immersive • Photography-first Final message: “Beautiful moments don't last forever. Photographs make them stay.”

No preview

Comments (0)

No comments yet. Be the first!

System Requirements

Page 1 of 20

System Requirements Document for photography-portfolio

1. Introduction

This document specifies the system requirements for photography-portfolio, a single-page dark cinematic photography portfolio website for MD Abdulla. The product is a premium digital photography exhibition that showcases MD Abdulla's real photographs — live moments, landscapes, nature, people, travel, architecture, street scenes and everyday beauty — and directs all visitor contact to his Instagram profile @axr.md (https://instagram.com/axr.md).

The product intent is to make a visitor feel they have walked into a darkened gallery where the photographs are the only light source: cinematic, minimal, premium, artistic, editorial, emotional and immersive — never corporate and never like a generic agency portfolio. The experience priority is (1) photography, (2) atmosphere, (3) MD Abdulla, (4) Instagram @axr.md, so that visitors slowly explore, open photographs fullscreen, discover the stories behind them, and follow Instagram.

The audience is the visitor — a photography viewer, curator, editor, potential collaborator or Instagram follower who arrives to look slowly — and MD Abdulla himself, the photographer and portfolio owner whose work, name, message, statistics and Instagram handle populate the site and who maintains the centralized photograph data.

The product's closing message is: "Beautiful moments don't last forever. Photographs make them stay."

Page 2 of 20

2. System Overview

The system is a single-page React application delivered as one continuous, scrollable exhibition. It opens with a fullscreen loading sequence, then a full-viewport cinematic HLS video hero, followed by the Live Gallery, a Featured Photo, Recent Frames, Visual Explorations, About, Stats, a Final CTA, a GSAP marquee and a footer. Navigation is a fixed floating pill that smooth-scrolls between Home / Gallery / Journal / Explorations / About and highlights the active section.

All photographs displayed anywhere on the site — gallery, category filtering, lightbox, featured content and explorations — come from one centralized array in src/data/photographs.ts, so adding or removing a photograph automatically updates the whole website. Photographs are MD Abdulla's actual photographs and are never AI-generated or transformed; only presentation effects (hover zoom, lightbox, parallax, cinematic overlays, subtle brightness/contrast, smooth transitions) are permitted.

The only contact or social call to action anywhere in the product is Instagram @axr.md. There is no email, email address, mailto link, phone number, contact form or placeholder contact detail of any kind.

Page 3 of 20

2a. Product Interpretation and Delivery Boundary

The product is a first-party, publicly reachable, anonymous single-page exhibition. No visitor account, sign-in, invitation or provisioning step exists or is required: the entire accepted journey — loading, watching the hero film, browsing and filtering the gallery, opening photographs fullscreen, reading stories, exploring the scroll-driven exhibition, reading About, and following Instagram — is available to any visitor on first arrival. The Landing page is the anonymous first impression and embeds the complete accepted journey within the explicit single-page boundary.

Two external providers are used and remain with their accepted owners:

  • Mux (https://stream.mux.com/Aa02T7oM1wH5Mk5EEVDYhbZ1ChcdhRsS2m1NYyx4Ua1g.m3u8) owns and serves the Hero HLS background video stream. The application plays it via hls.js when supported, with a native HLS fallback when available.
  • Instagram (https://instagram.com/axr.md) owns the outbound social destination. The application links to it from the navbar, hero, About, final CTA and footer; the visitor's follow/contact activity happens on Instagram, outside this product.

MD Abdulla's role is content ownership rather than an in-product authenticated surface: he maintains the centralized photograph array and the site's authored content. No account-management, publishing console, upload flow or permission model is part of the current product.

Everything described in this document is current scope. No future-horizon features were accepted in the authoritative requirements.

Page 4 of 20

2b. Source Content Inventory

The following authoritative content-source facts are preserved exactly as supplied.

Hero HLS video (content source — authoritative):

  • Source URL: https://stream.mux.com/Aa02T7oM1wH5Mk5EEVDYhbZ1ChcdhRsS2m1NYyx4Ua1g.m3u8
  • Use: Hero HLS background video, played via hls.js with native HLS fallback.

Instagram destination (content source — authoritative):

  • Handle: @axr.md
  • URL: https://instagram.com/axr.md
  • Use: the only contact/social CTA; linked from the navbar, hero, About, final CTA and footer Instagram buttons.

Identity and message content:

  • Name: MD Abdulla
  • Instagram: @axr.md
  • URL: https://instagram.com/axr.md
  • Message: "Capturing moments. Preserving emotions. Telling stories through photographs."

Photograph data record (as specified in src/data/photographs.ts):

  • {id:1, src:"/images/photo-01.jpg", title:"After the Rain", category:"Nature", date:"2026", location:"India", description:"A quiet moment after the rain."}

Recent Frames titles (may be used): After the Rain / The Quiet Road / Golden Hour / Between Two Moments / Where the Sky Meets the Earth / A Walk Through Silence

Statistics content: 100+ — Moments Captured; 50+ — Places Explored; ∞ — Stories to Tell

Marquee content: CAPTURE THE MOMENT •

SEO content:

  • Title: MD Abdulla — Photography
  • Description: MD Abdulla — Photographer capturing landscapes, people, nature, travel and beautiful moments through photography.
  • OG Title: MD Abdulla — Photography
  • OG Description: Capturing moments. Preserving emotions. Telling stories through photographs.

Footer content: Left: MD Abdulla · Center: © 2026 MD Abdulla · Right: Instagram ↗ · Note: ● Available for photography & creative collaborations

Final message: "Beautiful moments don't last forever. Photographs make them stay."

Page 5 of 20

2c. Page Content and Component Coverage

Page 6 of 20

Landing

The single page of the product: an anonymous, publicly reachable, continuously scrollable exhibition containing every accepted section in order.

Information and state

  • Loading state: isLoading controls a fullscreen LoadingScreen overlay rendered as {isLoading && <LoadingScreen onComplete={()=>setIsLoading(false)} />}.
  • Hero state: HLS video playback state (initializing, playing, native fallback, unavailable).
  • Gallery state: the active category filter (All / Nature / Landscape / People / Travel / Architecture / Street / Night) and the filtered photograph set.
  • Lightbox state: open/closed, the currently displayed photograph, its position in the sequence, and its category and caption.
  • Navigation state: the active section, derived from scroll position via Intersection Observer / ScrollTrigger.
  • Responsive state: 3-column desktop / 2-column tablet / 1-column mobile masonry; compact/hamburger navigation on mobile.

Primary actions

  • Watch the hero film and read the hero copy; choose "Explore Gallery" or "Instagram ↗".
  • Filter the Live Gallery by category.
  • Open any photograph fullscreen in the lightbox; navigate Previous / Next; close.
  • Scroll through Featured Photo, Recent Frames, Visual Explorations, About, Stats and the Final CTA.
  • Smooth-scroll between Home / Gallery / Journal / Explorations / About from the navbar.
  • Follow Instagram @axr.md from the navbar, hero, About, final CTA or footer.

Supporting actions

  • Hover a photo card to reveal "View Photograph ↗" and the hover zoom.
  • Hover a Recent Frames entry for image zoom, brighter card and moving arrow.
  • Keyboard: Escape closes the lightbox; Left/Right navigate it.
  • Mobile: open/close the compact/hamburger navigation.

Domain entities

  • Photograph: id, src, title, category, date, location, description.
  • Category: All / Nature / Landscape / People / Travel / Architecture / Street / Night.
  • Journal entry: image, title, date, location, story, read time.
  • Statistic: value (100+ / 50+ / ∞) and label (Moments Captured / Places Explored / Stories to Tell).
  • Social destination: Instagram @axr.md.

Component responsibilities

  • LoadingScreen.tsx — fullscreen fixed inset-0 z-[9999] bg-bg overlay; requestAnimationFrame counter 000 → 100 over 2700ms; top-left "PHOTOGRAPHY" uppercase tiny muted with y/opacity entrance; center cycle Observe / Capture / Remember every 900ms via AnimatePresence mode="wait" with y 20→0→-20 in Instrument Serif italic; bottom-right huge tabular 000…100; bottom 3px stroke track with gradient inner bar using scaleX(count/100) and subtle glow; at 100 wait 400ms then call onComplete.
  • Navbar.tsx — fixed floating pill at top center with backdrop blur, dark surface and subtle border; 9×9 circle logo with gradient ring and "MA" inside in Instrument Serif italic, hover scale 1.1; links Home / Gallery / Journal / Explorations / About with active light text + subtle stroke background and inactive muted with hover transition; final "Instagram ↗" button linking to https://instagram.com/axr.md; compact/hamburger behavior on mobile.
  • Hero.tsx — full viewport cinematic hero; HLS video via hls.js with native HLS fallback; autoPlay muted loop playsInline, full-screen object-cover; overlay bg-black/35; bottom cinematic fade to background; centered eyebrow "LIVE PHOTOGRAPHY • MD ABDULLA", main heading "MD Abdulla" in text-7xl md:text-8xl lg:text-9xl font-display italic, tagline "Capturing the beauty of real moments.", description "Photography is the art of noticing what others might pass by.", rounded-full buttons "Explore Gallery" and "Instagram ↗"; GSAP entrance with the name fading from opacity 0/y50 and remaining elements from blur(10px)/y20 with stagger using power3.out; bottom "SCROLL TO EXPLORE" with animated vertical line.
  • Gallery.tsx — Live Gallery section (never "Selected Works"); eyebrow "01 — LIVE GALLERY"; heading "Moments I capture" with "capture" in Instrument Serif italic; description "A collection of photographs captured in real moments, from quiet landscapes to fleeting human experiences."; responsive masonry 3/2/1 columns preserving natural aspect ratios; Framer Motion animated filtering; renders CategoryFilter and PhotoCard from the centralized array.
  • CategoryFilter.tsx — the All / Nature / Landscape / People / Travel / Architecture / Street / Night controls that set the active category.
  • PhotoCard.tsx — rounded-3xl, overflow-hidden, dark surface, subtle border; authentic image with smooth hover zoom; hover overlay "View Photograph ↗"; minimal metadata such as category and year.
  • Lightbox.tsx — fullscreen bg-black/95; original photograph centered without distortion; controls Previous / Next / Close / Counter / Category / Caption; Escape closes and Left/Right navigate; opacity 0→1 and scale .96→1 animation.
  • FeaturedPhoto.tsx — large cinematic photograph section; heading "A moment worth remembering."; GSAP ScrollTrigger subtle parallax; overlay "01 / MOMENT / MD ABDULLA / 2026"; important image details kept unobstructed.
  • Journal.tsx — Recent Frames section; heading "Recent Frames" with "Frames" in Instrument Serif italic; subtext "Small stories behind the photographs."; 4–6 elegant horizontal entries with image, title, date, location, story and read time; hover subtle image zoom, brighter card and moving arrow.
  • Explorations.tsx — min-h-[300vh] scroll-driven photography exhibition; heading "Visual Explorations"; subtext "A collection of places, textures, people and moments that caught my eye."; 2–3 vertical image columns with GSAP ScrollTrigger parallax at different speeds and subtle rotations −2deg / 1deg / −1deg; every image opens the lightbox.
  • About.tsx — heading "Behind the Lens" with "Lens" in Instrument Serif italic; text "I'm MD Abdulla — a photographer drawn to the beauty hidden in ordinary moments."; additional "From landscapes and quiet streets to people, light and fleeting expressions, I photograph the moments that make a place feel alive."; Instagram @axr.md ↗; personal and understated.
  • Stats.tsx — three artistic statistics 100+ — Moments Captured, 50+ — Places Explored, ∞ — Stories to Tell in large Instrument Serif typography, avoiding corporate styling.
  • Contact.tsx — final CTA; heading "Let's capture something beautiful."; description "For photography collaborations, creative projects, or simply to connect."; button "Instagram ↗" linking only to https://instagram.com/axr.md; no email, phone or form.
  • Footer.tsx — left "MD Abdulla"; center "© 2026 MD Abdulla"; right "Instagram ↗"; note "● Available for photography & creative collaborations" with subtle pulsing dot.
  • Marquee — GSAP infinite marquee "CAPTURE THE MOMENT •" repeated 10×, xPercent:-50, duration:40, ease:"none", repeat:-1, in Instrument Serif italic text-5xl md:text-7xl.
  • src/data/photographs.ts — the centralized photograph array consumed by gallery, filtering, lightbox, featured content and explorations.
  • src/pages/Index.tsx — composes the single page and owns the isLoading state.
  • src/index.css — design tokens, Tailwind hsl(var(--...)) colors, .accent-gradient, and the scroll-down, role-fade-in and gradient-shift CSS animations.

States

  • Loading: counter running 000 → 100; cycling Observe / Capture / Remember; progress bar scaling; closes 400ms after reaching 100.
  • Empty: a category with no matching photographs shows an empty gallery state rather than a broken grid.
  • Success: filtered photographs animate into the masonry; the lightbox opens with the selected photograph centered and undistorted.
  • Error: if HLS cannot initialize and native HLS is unavailable, the hero degrades to its overlay and copy over the background without breaking the page.
  • Recovery: closing the lightbox returns the visitor to the same gallery position; changing category re-renders the filtered set; reduced-motion replaces timelines with instant states and turns the marquee into a static wrapped line.
Page 7 of 20

3. Functional Requirements

FR-1 — Single-page dark cinematic portfolio foundation (explicit) As MD Abdulla, I should have a single-page dark cinematic photography portfolio built with React + Vite + TypeScript + Tailwind CSS + GSAP + GSAP ScrollTrigger + Framer Motion + hls.js + react-router-dom + tailwindcss-animate, so that my work is presented as one continuous premium exhibition.

  • Trigger/input: the site is loaded at its single route.
  • Observable result: one scrollable page containing the loading screen, hero, Live Gallery, Featured Photo, Recent Frames, Visual Explorations, About, Stats, Final CTA, marquee and footer.
  • Access state: anonymous, public.
  • Failure/recovery: none required beyond normal page load.
  • Continuation: the visitor scrolls or uses the navbar.

FR-2 — Animation library division of responsibility (explicit) As MD Abdulla, I should have Motion/Framer Motion used for declarative UI, entrance, filtering and lightbox animations, and GSAP used for timelines, marquee and advanced scroll/parallax effects, so that each animation system does the work it is best suited to.

  • Observable result: filtering and lightbox transitions are Framer Motion; hero timeline, marquee and ScrollTrigger parallax are GSAP.
  • Continuation: animations run throughout the single page.

FR-3 — Premium exhibition feel (explicit) As a Visitor, I should experience the site as a premium digital photography exhibition showcasing MD Abdulla's real photographs — live moments, landscapes, nature, people, travel, architecture, street scenes and everyday beauty — so that it feels cinematic, minimal, premium, artistic, editorial, emotional and immersive, never corporate or like a generic agency portfolio.

FR-4 — Identity and message content (explicit) As MD Abdulla, I should have my name "MD Abdulla", Instagram "@axr.md", URL https://instagram.com/axr.md and message "Capturing moments. Preserving emotions. Telling stories through photographs." presented in the product.

FR-5 — Instagram as the only contact CTA (explicit) As a Visitor, I should be able to reach MD Abdulla only through Instagram @axr.md, so that there is a single, unambiguous contact channel.

  • Observable result: Instagram links appear in the navbar, hero, About, final CTA and footer, all pointing to https://instagram.com/axr.md.
  • Constraint: no email, email address, mailto link, phone number, contact form or fake/placeholder contact details anywhere.

FR-6 — Design system tokens (explicit) As MD Abdulla, I should have the specified design system applied: Google Fonts Inter 300–700 and Instrument Serif italic 400; --font-body:'Inter',sans-serif; --font-display:'Instrument Serif',serif; --bg:0 0% 4%; --surface:0 0% 8%; --text:0 0% 96%; --muted:0 0% 53%; --stroke:0 0% 12%; --accent:0 0% 96%; with Tailwind colors using hsl(var(--...)).

FR-7 — Accent gradient utility (explicit) As MD Abdulla, I should have the accent gradient linear-gradient(90deg,#89AACC 0%,#4E85BF 100%) exposed as .accent-gradient for the logo ring, loading progress, hover borders and subtle highlights.

FR-8 — Forced dark theme (explicit) As a Visitor, I should always see the dark theme, with no light-mode toggle available.

FR-9 — Editorial restraint (explicit) As a Visitor, I should see large typography, generous negative space, subtle borders, cinematic overlays, slow transitions and natural image ratios, and should not see bright colors, excessive UI, generic stock images, excessive cards or artificial-looking photography.

FR-10 — Loading screen (explicit) As a Visitor, I should see a fullscreen loading screen controlled by {isLoading && <LoadingScreen onComplete={()=>setIsLoading(false)} />} before the exhibition appears.

  • Observable result: fixed inset-0 z-[9999] bg-bg; counter animates 000 → 100 with requestAnimationFrame over 2700ms; top-left "PHOTOGRAPHY" in uppercase tiny muted typography with y/opacity entrance; center cycles Observe / Capture / Remember every 900ms using AnimatePresence mode="wait" with y 20→0→-20 in Instrument Serif italic; bottom-right huge tabular 000…100; bottom 3px stroke track with gradient inner bar using scaleX(count/100) and subtle glow.
  • Continuation: at 100 the screen waits 400ms, then closes via onComplete.

FR-11 — Cinematic HLS hero video (explicit) As a Visitor, I should see a full viewport cinematic hero playing the HLS video https://stream.mux.com/Aa02T7oM1wH5Mk5EEVDYhbZ1ChcdhRsS2m1NYyx4Ua1g.m3u8.

  • Observable result: hls.js initializes HLS when supported and falls back to native HLS when available; the video is autoPlay muted loop playsInline, full-screen object-cover; overlay bg-black/35; bottom cinematic fade to background.
  • Failure/recovery: when neither HLS path is available, the hero copy and overlay remain legible over the background.

FR-12 — Floating pill navbar (explicit) As a Visitor, I should navigate with a fixed floating pill at top center with backdrop blur, dark surface and subtle border.

  • Observable result: 9×9 circle logo with gradient ring and "MA" inside in Instrument Serif italic, hover scale 1.1; links Home / Gallery / Journal / Explorations / About; active link shows light text + subtle stroke background, inactive links are muted with hover transition; final button "Instagram ↗" links to https://instagram.com/axr.md.

FR-13 — Hero text and entrance (explicit) As a Visitor, I should see centered hero text: eyebrow "LIVE PHOTOGRAPHY • MD ABDULLA"; main heading "MD Abdulla" in text-7xl md:text-8xl lg:text-9xl font-display italic; tagline "Capturing the beauty of real moments."; description "Photography is the art of noticing what others might pass by."; rounded-full buttons "Explore Gallery" and "Instagram ↗" with subtle hover scale and elegant transitions.

  • Observable result: GSAP entrance animates the name from opacity 0/y50 and the remaining elements from blur(10px)/y20 with stagger using power3.out; bottom shows "SCROLL TO EXPLORE" with an animated vertical line.

FR-14 — Live Gallery section (explicit) As a Visitor, I should browse the section named Live Gallery (never "Selected Works"), with eyebrow "01 — LIVE GALLERY", heading "Moments I capture" with "capture" in Instrument Serif italic, and description "A collection of photographs captured in real moments, from quiet landscapes to fleeting human experiences."

FR-15 — Responsive masonry gallery (explicit) As a Visitor, I should see a responsive masonry gallery with 3 columns on desktop, 2 on tablet and 1 on mobile, preserving natural aspect ratios and not unnecessarily cropping photographs.

FR-16 — Category filtering (explicit) As a Visitor, I should filter the gallery by All / Nature / Landscape / People / Travel / Architecture / Street / Night, with filtering animated by Framer Motion.

  • Observable result: selecting a category animates the matching photographs into the masonry.
  • Failure/recovery: a category with no matches shows an empty state rather than a broken grid.
  • Continuation: the visitor can select another category or open a photograph.

FR-17 — Photo cards (explicit) As a Visitor, I should see photo cards that are rounded-3xl, overflow-hidden, on a dark surface with a subtle border, showing authentic images with smooth hover zoom, a hover overlay "View Photograph ↗", and minimal metadata such as category and year.

FR-18 — Lightbox (explicit) As a Visitor, I should click a photograph to open a fullscreen bg-black/95 lightbox showing the original photograph centered without distortion, with controls Previous / Next / Close / Counter / Category / Caption.

  • Observable result: Escape closes; Left/Right navigate; the lightbox animates with opacity 0→1 and scale .96→1.
  • Continuation: closing returns the visitor to the gallery.

FR-19 — Featured Photo (explicit) As a Visitor, I should see a large cinematic photograph section headed "A moment worth remembering." with GSAP ScrollTrigger subtle parallax and the overlay "01 / MOMENT / MD ABDULLA / 2026", keeping important image details unobstructed.

FR-20 — Recent Frames (explicit) As a Visitor, I should read the "Recent Frames" section with "Frames" in Instrument Serif italic and subtext "Small stories behind the photographs.", showing 4–6 elegant horizontal entries with image, title, date, location, story and read time.

  • Observable result: hover produces subtle image zoom, a brighter card and a moving arrow.
  • Content: titles can include After the Rain / The Quiet Road / Golden Hour / Between Two Moments / Where the Sky Meets the Earth / A Walk Through Silence.

FR-21 — Visual Explorations (explicit) As a Visitor, I should scroll a min-h-[300vh] scroll-driven photography exhibition headed "Visual Explorations" with subtext "A collection of places, textures, people and moments that caught my eye.", built from 2–3 vertical image columns using GSAP ScrollTrigger at different parallax speeds with subtle rotations −2deg / 1deg / −1deg.

  • Observable result: every image in the section opens the lightbox.

FR-22 — About (explicit) As a Visitor, I should read "Behind the Lens" with "Lens" in Instrument Serif italic, containing "I'm MD Abdulla — a photographer drawn to the beauty hidden in ordinary moments." and "From landscapes and quiet streets to people, light and fleeting expressions, I photograph the moments that make a place feel alive.", plus Instagram @axr.md ↗, kept personal and understated.

FR-23 — Stats (explicit) As a Visitor, I should see three artistic statistics — 100+ — Moments Captured, 50+ — Places Explored, ∞ — Stories to Tell — in large Instrument Serif typography, avoiding corporate styling.

FR-24 — Final CTA (explicit) As a Visitor, I should see a final call to action headed "Let's capture something beautiful." with description "For photography collaborations, creative projects, or simply to connect." and a button "Instagram ↗" linking only to https://instagram.com/axr.md, with no email, phone or form.

FR-25 — Footer (explicit) As a Visitor, I should see a footer with left "MD Abdulla", center "© 2026 MD Abdulla", right "Instagram ↗", and the note "● Available for photography & creative collaborations" with a subtle pulsing dot.

FR-26 — GSAP infinite marquee (explicit) As a Visitor, I should see a GSAP infinite marquee reading "CAPTURE THE MOMENT •" repeated 10×, with xPercent:-50, duration:40, ease:"none", repeat:-1, in Instrument Serif italic at text-5xl md:text-7xl.

FR-27 — Smooth-scroll navigation with active section (explicit) As a Visitor, I should smooth-scroll between Home / Gallery / Journal / Explorations / About using native smooth scrolling or GSAP, with the active section highlighted via Intersection Observer / ScrollTrigger.

FR-28 — Responsive behavior (explicit) As a Visitor, I should have the site optimized for mobile, tablet, laptop and large desktop.

  • Observable result: on mobile, compact/hamburger navigation, a one-column gallery, natural image ratios, smaller typography, touch-friendly controls and no horizontal overflow.
  • Constraint: never crop important parts of photographs unnecessarily.

FR-29 — Centralized photograph data (explicit) As MD Abdulla, I should have src/data/photographs.ts exporting const photographs=[{id:1,src:"/images/photo-01.jpg",title:"After the Rain",category:"Nature",date:"2026",location:"India",description:"A quiet moment after the rain."}]; as the single source for all gallery, filtering, lightbox, featured content and explorations, so that adding or removing a photo automatically updates the website.

FR-30 — Photograph authenticity (explicit) As MD Abdulla, I should have only my actual photographs used, never AI-generated or transformed.

  • Constraint: do not alter faces or facial features, skies, landscapes, objects, scenery, composition, identity, or important colors/details; no artificial people or objects.
  • Allowed presentation effects only: hover zoom, lightbox, parallax, cinematic overlays, subtle brightness/contrast and smooth transitions; photographs must remain authentic.

FR-31 — Performance (explicit) As a Visitor, I should have a fast, stable experience: images lazy-loaded with responsive image sizes; HLS instances, video listeners and GSAP ScrollTriggers cleaned up on unmount; unnecessary React renders avoided; prefers-reduced-motion respected.

FR-32 — Accessibility (explicit) As a Visitor, I should have semantic HTML, correct heading hierarchy, descriptive alt text, keyboard-accessible navigation and lightbox, visible focus states and ARIA labels where appropriate.

FR-33 — SEO metadata (explicit) As MD Abdulla, I should have the page titled "MD Abdulla — Photography" with description "MD Abdulla — Photographer capturing landscapes, people, nature, travel and beautiful moments through photography.", OG title "MD Abdulla — Photography" and OG description "Capturing moments. Preserving emotions. Telling stories through photographs."

FR-34 — File structure (explicit) As MD Abdulla, I should have the project organized as src/components/LoadingScreen.tsx, Navbar.tsx, Hero.tsx, Gallery.tsx, PhotoCard.tsx, Lightbox.tsx, FeaturedPhoto.tsx, CategoryFilter.tsx, Journal.tsx, Explorations.tsx, About.tsx, Stats.tsx, Contact.tsx, Footer.tsx; src/data/photographs.ts; src/pages/Index.tsx; src/index.css.

FR-35 — CSS animations (explicit) As a Visitor, I should see the CSS animations scroll-down, role-fade-in and gradient-shift defined and used in src/index.css.

FR-36 — Final experience priority (explicit) As MD Abdulla, I should have the experience prioritize 1. Photography, 2. Atmosphere, 3. MD Abdulla, 4. Instagram @axr.md, so that visitors slowly explore, open photographs fullscreen, discover stories and follow Instagram.

FR-37 — Closing message (explicit) As a Visitor, I should encounter the final message "Beautiful moments don't last forever. Photographs make them stay."

Page 8 of 20

4. User Personas

Page 9 of 20

Visitor / Photography Viewer

Product context. The visitor arrives anonymously at the single-page exhibition, typically from a shared link or from Instagram, with no account and no prior relationship to the site. They are a photography viewer, curator, editor, potential collaborator or follower who has come to look slowly rather than to transact.

Primary goal. To move through a cinematic, photography-first exhibition, see MD Abdulla's real photographs at full quality, and end by following Instagram @axr.md.

Distinct accepted responsibilities.

  • Watching the loading sequence and the full-viewport HLS hero film, then reading the hero copy.
  • Browsing the Live Gallery masonry and filtering it by All / Nature / Landscape / People / Travel / Architecture / Street / Night.
  • Opening photographs fullscreen in the lightbox and navigating Previous / Next, including by keyboard (Escape, Left/Right).
  • Reading the Featured Photo, the Recent Frames stories and the Visual Explorations exhibition.
  • Reading About and the Stats, and following the Instagram CTA from the navbar, hero, About, final CTA or footer.

Relevant inputs or decisions. Which category to filter by; which photograph to open; whether to continue scrolling or leave for Instagram; whether to use the navbar or scroll.

Interactions with other accepted participants. The visitor is the sole human actor in the browsing journey. Their interaction with MD Abdulla is indirect: they consume his photographs, name, message and statistics, and their only outbound action is to Instagram @axr.md, which is owned by Instagram and by MD Abdulla's profile there.

Observable success. The visitor has scrolled the full exhibition, opened at least one photograph fullscreen without distortion, read at least one story, and followed Instagram @axr.md.

What makes this role distinct. The visitor never creates, edits or owns content; every action is read-only exploration plus one outbound social link. Their experience is defined by pacing and atmosphere rather than by task completion.

Page 10 of 20

MD Abdulla (Photographer / Portfolio Owner)

Product context. MD Abdulla is the named photographer whose real photographs, name, message, Instagram handle and statistics populate the entire site. He is the subject and the content owner of the exhibition, not an authenticated user of it.

Primary goal. To have a premium digital exhibition that authentically represents his photography and converts visitors into Instagram followers.

Distinct accepted responsibilities.

  • Maintaining the centralized src/data/photographs.ts array so that adding or removing a photograph automatically updates the gallery, filtering, lightbox, featured content and explorations.
  • Supplying only his actual photographs, never AI-generated or transformed, and never altering faces or facial features, skies, landscapes, objects, scenery, composition, identity, or important colors/details.
  • Being presented through his authored content: the name "MD Abdulla", the message "Capturing moments. Preserving emotions. Telling stories through photographs.", the About text, the statistics 100+ / 50+ / ∞, and the availability note "● Available for photography & creative collaborations".

Relevant inputs or decisions. Which photographs exist in the array and what their title, category, date, location and description values are; which Recent Frames titles and stories are shown.

Interactions with other accepted participants. MD Abdulla does not interact with the visitor inside the product. The relationship is one-directional: the visitor views his work and may follow him on Instagram, where any actual conversation happens under Instagram's ownership.

Observable success. The published site shows his real photographs unaltered, the centralized array drives every photographic surface, and visitors follow Instagram @axr.md.

What makes this role distinct. MD Abdulla's work is content maintenance and authorship rather than in-product operation; he has no dashboard, upload flow or account surface in the current product, and his presence in the experience is entirely through the photographs and authored copy.

Page 11 of 20

5. Core User Flows

Flow 1 — Visitor arrives and watches the exhibition open

  1. The visitor opens the site. isLoading is true, so LoadingScreen renders fullscreen at fixed inset-0 z-[9999] bg-bg.
  2. The counter animates 000 → 100 with requestAnimationFrame over 2700ms; "PHOTOGRAPHY" enters top-left in uppercase tiny muted typography with a y/opacity entrance; the center cycles Observe / Capture / Remember every 900ms via AnimatePresence mode="wait" with y 20→0→-20 in Instrument Serif italic; the bottom 3px stroke track fills with the gradient inner bar using scaleX(count/100) and a subtle glow.
  3. At 100 the screen waits 400ms, then calls onComplete, setting isLoading to false and revealing the exhibition.
  4. The hero appears: the HLS video from https://stream.mux.com/Aa02T7oM1wH5Mk5EEVDYhbZ1ChcdhRsS2m1NYyx4Ua1g.m3u8 plays full-screen object-cover with autoPlay muted loop playsInline, under a bg-black/35 overlay with a bottom cinematic fade to background.
  5. The GSAP entrance runs: "MD Abdulla" fades from opacity 0/y50 in text-7xl md:text-8xl lg:text-9xl font-display italic, and the eyebrow "LIVE PHOTOGRAPHY • MD ABDULLA", tagline "Capturing the beauty of real moments.", description "Photography is the art of noticing what others might pass by." and the two rounded-full buttons fade from blur(10px)/y20 with stagger using power3.out.
  6. Failure/recovery: if hls.js cannot initialize and native HLS is unavailable, the video does not play and the hero copy and overlay remain legible over the background; the visitor continues normally.
  7. Continuation: the visitor reads the hero, then either selects "Explore Gallery" to scroll to the Live Gallery, selects "Instagram ↗" to leave for https://instagram.com/axr.md, or follows "SCROLL TO EXPLORE" and the animated vertical line downward.

Flow 2 — Visitor browses and filters the Live Gallery

  1. The visitor scrolls to the Live Gallery, introduced by the eyebrow "01 — LIVE GALLERY", the heading "Moments I capture" with "capture" in Instrument Serif italic, and the description "A collection of photographs captured in real moments, from quiet landscapes to fleeting human experiences."
  2. The masonry renders from src/data/photographs.ts at 3 columns on desktop, 2 on tablet and 1 on mobile, preserving each photograph's natural aspect ratio without unnecessary cropping.
  3. The visitor selects a category from All / Nature / Landscape / People / Travel / Architecture / Street / Night in CategoryFilter.
  4. Framer Motion animates the filtered photographs into the masonry; each PhotoCard is rounded-3xl, overflow-hidden, on a dark surface with a subtle border, showing minimal metadata such as category and year.
  5. Failure/recovery: if the selected category has no matching photographs, the gallery shows an empty state instead of a broken grid, and the visitor can select another category.
  6. Continuation: the visitor hovers a card — the image zooms smoothly and "View Photograph ↗" appears — and proceeds to open it, or continues scrolling to the Featured Photo.

Flow 3 — Visitor opens a photograph fullscreen in the lightbox

  1. From the Live Gallery, the visitor clicks a photograph.
  2. The lightbox opens fullscreen at bg-black/95, animating with opacity 0→1 and scale .96→1, showing the original photograph centered without distortion.
  3. The visitor sees the controls Previous / Next / Close / Counter / Category / Caption, with the photograph's category and caption displayed.
  4. The visitor navigates with Previous / Next, or presses Left/Right; pressing Escape closes the lightbox.
  5. Continuation: closing returns the visitor to the gallery at the same browsing position, where they can open another photograph or continue scrolling.
Page 12 of 20

Flow 4 — Visitor reads the Featured Photo and Recent Frames

  1. The visitor scrolls into the Featured Photo: a large cinematic photograph headed "A moment worth remembering.", with GSAP ScrollTrigger applying a subtle parallax and the overlay "01 / MOMENT / MD ABDULLA / 2026" placed so that important image details remain unobstructed.
  2. The visitor continues to Recent Frames, headed "Recent Frames" with "Frames" in Instrument Serif italic and the subtext "Small stories behind the photographs."
  3. The visitor reads 4–6 elegant horizontal entries, each with image, title, date, location, story and read time; titles can include After the Rain / The Quiet Road / Golden Hour / Between Two Moments / Where the Sky Meets the Earth / A Walk Through Silence.
  4. On hover, the entry's image zooms subtly, the card brightens and the arrow moves.
  5. Continuation: the visitor scrolls on into Visual Explorations.

Flow 5 — Visitor moves through the Visual Explorations exhibition

  1. The visitor enters the min-h-[300vh] Visual Explorations section, headed "Visual Explorations" with the subtext "A collection of places, textures, people and moments that caught my eye."
  2. As the visitor scrolls, 2–3 vertical image columns travel at different GSAP ScrollTrigger parallax speeds with subtle resting rotations of −2deg / 1deg / −1deg, so the columns drift past each other like hung prints.
  3. The visitor clicks any image in the section, which opens the same fullscreen lightbox described in Flow 3.
  4. Continuation: the visitor closes the lightbox and continues to About.

Flow 6 — Visitor reads About and the Stats, then follows Instagram

  1. The visitor reaches About, headed "Behind the Lens" with "Lens" in Instrument Serif italic, and reads "I'm MD Abdulla — a photographer drawn to the beauty hidden in ordinary moments." and "From landscapes and quiet streets to people, light and fleeting expressions, I photograph the moments that make a place feel alive."
  2. The visitor sees the Instagram @axr.md ↗ link within the personal, understated section.
  3. The visitor continues to the Stats: 100+ — Moments Captured, 50+ — Places Explored, ∞ — Stories to Tell, set in large Instrument Serif typography without corporate styling.
  4. The visitor reaches the Final CTA, headed "Let's capture something beautiful." with the description "For photography collaborations, creative projects, or simply to connect." and the button "Instagram ↗".
  5. The visitor selects "Instagram ↗" — from the navbar, hero, About, final CTA or footer — and leaves for https://instagram.com/axr.md, where the follow or contact happens under Instagram's ownership.
  6. Continuation: the visitor may return to the site; the footer shows "MD Abdulla", "© 2026 MD Abdulla", "Instagram ↗" and "● Available for photography & creative collaborations" with a subtle pulsing dot, and the GSAP marquee continues reading "CAPTURE THE MOMENT •" in Instrument Serif italic.
Page 13 of 20

Flow 7 — Visitor navigates by navbar and keyboard

  1. At any point, the visitor uses the fixed floating pill navbar at top center — backdrop blur, dark surface, subtle border — with the 9×9 gradient-ring "MA" logo in Instrument Serif italic that scales to 1.1 on hover.
  2. The visitor selects Home / Gallery / Journal / Explorations / About; the page smooth-scrolls to that section using native smooth scrolling or GSAP, and the active link shows light text with a subtle stroke background while inactive links remain muted with a hover transition.
  3. The active section is highlighted as the visitor scrolls, via Intersection Observer / ScrollTrigger.
  4. On mobile, the visitor opens the compact/hamburger navigation instead, with touch-friendly controls and no horizontal overflow.
  5. Continuation: the visitor resumes browsing, opens a photograph, or selects "Instagram ↗".

Flow 8 — MD Abdulla maintains the photograph collection

  1. MD Abdulla edits src/data/photographs.ts, adding or removing an entry in the photographs array, each with id, src, title, category, date, location and description — for example {id:1,src:"/images/photo-01.jpg",title:"After the Rain",category:"Nature",date:"2026",location:"India",description:"A quiet moment after the rain."}.
  2. Because the gallery, filtering, lightbox, featured content and explorations all read from this single array, the website updates automatically without any other change.
  3. MD Abdulla uses only his actual photographs, never AI-generated or transformed, and does not alter faces or facial features, skies, landscapes, objects, scenery, composition, identity, or important colors/details; no artificial people or objects are introduced.
  4. Observable result: the visitor's next visit shows the updated collection across every photographic surface, with natural aspect ratios preserved and no unnecessary cropping of important parts of the photographs.
Page 14 of 20

6. Visuals Colors and Theme

The creative direction is Editorial swagger in a black gallery — one hot accent, enormous type, photographs that breathe, with Tobias van Schneider as the muse. The headline idea: a single-photographer portfolio read as a digital exhibition, where the viewer feels they walked into a darkened gallery and the pictures are the only light source. Van Schneider's language — black ground, sparse UI chrome, oversized display type with tight leading, one saturated accent, and large-scale editorial photography given room to breathe — is exactly a photography exhibition, and his asymmetric editorial grids and sharp corners keep the work from ever feeling like a SaaS card wall.

Colour tokens (dark mode only — no light-mode toggle):

RoleHexUsage
Background#0A0A0A~75% of the page ground
Surface#141414navbar pill, photo cards, lightbox chrome only
Text#F5F5F5display and body
Primary#89AACCaccent gradient start
Accent#4E85BFaccent gradient end
Muted#878787eyebrows, metadata, captions, inactive nav
Hairline#1F1F1F1px rules and borders, never shadows

The steel-blue pair #89AACC → #4E85BF is the only chroma on the site and appears at 2–3% coverage: the 1px logo ring, the loading progress bar, a hairline hover border on photo cards, and the focus ring. Never a filled blue button, never a blue section ground. The user-specified accent gradient linear-gradient(90deg,#89AACC 0%,#4E85BF 100%) is exposed as .accent-gradient for the logo ring, loading progress, hover borders and subtle highlights, and the user's HSL token set (--bg:0 0% 4%; --surface:0 0% 8%; --text:0 0% 96%; --muted:0 0% 53%; --stroke:0 0% 12%; --accent:0 0% 96%;) remains the Tailwind hsl(var(--...)) foundation.

Typography. Headings use Instrument Serif, with Instrument Serif italic reserved for the emotional words only — the name "MD Abdulla", "capture", "Frames", "Lens", the cycling Observe / Capture / Remember, the ∞ stat and the marquee. Everything else uses Archivo: eyebrows and metadata in uppercase Archivo 500 at 11–13px with 0.18em tracking; section headings in Archivo 300 at very large sizes with −0.03em tracking; body in Archivo 300/400 at 16–18px with 1.7 line-height and a 62–68ch measure. The contrast between the sharp grotesque and the italic serif is the whole voice — never set a heading in Archivo italic, never set body in Instrument Serif. Inter remains loaded per the user's Google Fonts requirement (Inter 300–700) and Instrument Serif italic 400 is loaded as specified.

Type scale (1.25 modular with editorial jumps): display 56px mobile → 96px tablet → 128px desktop (clamp(3.5rem, 11vw, 8rem)); section heading 40 → 56 → 72px; eyebrow 11px / 12px / 13px uppercase tracked 0.18em; body 16 → 17 → 18px; caption and metadata 12 → 13px; stat numerals clamp(4rem, 14vw, 11rem) in Instrument Serif.

Shape language. Sharp corners everywhere — 0px radius on photographs, section rules and colour blocks. The only rounded things are the navbar pill, the 9×9 logo circle and the rounded-full CTA buttons, so roundness reads as chrome and squareness reads as the work. 1px hairline rules (#1F1F1F) separate sections and run full-bleed. No drop shadows, no glass blur except the navbar's backdrop-blur, no gradients other than the single steel-blue accent gradient.

Layout. Asymmetric editorial grid on a 12-column base with a 24px mobile / 40px tablet / 64px desktop gutter and a 1440px max content width. Sections are numbered with an eyebrow ("01 — LIVE GALLERY") set flush-left at the column 1 line, with the heading set large and allowed to run to column 9 or 12. The gallery is a true CSS-columns masonry (1 / 2 / 3 columns) preserving natural aspect ratios — no fixed-ratio crops. Featured photo and Explorations are full-bleed, breaking the gutter on both sides. Generous vertical rhythm: 96px mobile → 160px desktop between sections.

Imagery. MD Abdulla's real photographs only — never AI-generated, never re-coloured, never re-cropped to a house ratio. Presentation is limited to a hover zoom, a bg-black/35 cinematic overlay on the hero video, a bottom fade to #0A0A0A, and a very slight brightness/contrast lift on hover. Faces, skies, landscapes, objects and composition stay untouched. Images are lazy-loaded with responsive srcset and descriptive alt text drawn from the photograph's own title and location.

Avoid: Bootstrap-blue or indigo anywhere on a white ground; Inter, Roboto, Arial, Helvetica, Open Sans, Lato, Poppins or system-ui for headings or body; centred hero stacks with a headline, subtext and a filled blue button; rounded-3xl photo cards with drop shadows and hover-lift; glassmorphism panels, gradient blobs, particle fields or floating 3D primitives behind the copy; fixed-ratio crops of photographs that cut faces, skies or composition; email, mailto, phone number, contact form or any placeholder contact detail; light-mode toggle, bright saturated fills, or more than one chromatic accent on a single screen. The generic indigo/blue-on-white SaaS template is forbidden for this project.

Page 15 of 20

7. Signature Design Concept

The bottom-left editorial lockup over a living film.

The public entry is the hero: a full-viewport HLS film from Mux playing object-cover behind a bg-black/35 scrim, with a bottom fade into #0A0A0A so the page appears to rise out of the film itself. Nothing is centred and nothing is a blue button — the photograph/film is unmistakably the subject.

The signature move is the name "MD Abdulla" set in Instrument Serif italic at clamp(3.5rem, 11vw, 8rem) on a single line that spans from the left gutter across roughly nine of twelve columns, flush-left against the video's left gutter. Above it, small and tracked at the left gutter, sits the eyebrow "LIVE PHOTOGRAPHY • MD ABDULLA" in 11–13px uppercase Archivo 500 with 0.18em tracking. Beneath the name, in Archivo 300 at a 62ch measure, sit the tagline "Capturing the beauty of real moments." and the description "Photography is the art of noticing what others might pass by." Under the copy, left-aligned, are the two rounded-full buttons: "Explore Gallery" filled #F5F5F5 with #0A0A0A text, and "Instagram ↗" outlined 1px #F5F5F5. At the very bottom-left, a vertical 1px animated line with "SCROLL TO EXPLORE" in 11px uppercase tracked Archivo; at bottom-right, the counter "01 / 08" in muted.

The composition is bottom-weighted and off-centre, so the film occupies the upper field and the typography anchors the lower-left corner — an editorial lockup rather than a SaaS hero. The only chroma on the first screen is the 1px steel-blue gradient ring on the navbar's 9×9 "MA" logo and the hairline gradient on the loading progress bar that preceded it, so the accent reads as a colour event rather than a theme.

This concept recomposes only accepted content, states and controls: the hero video, the eyebrow, the name, the tagline, the description, the two buttons, the scroll cue and the counter. It introduces no new behaviour, page or destination.

Page 16 of 20

8. Interaction Model & Motion Direction

Interaction Model: Animated Motion Tempo: restrained Hero Dimensionality: flat

The tempo is copied from the creative direction: cinematic and slow, restrained rather than expressive. The loading counter animates 000 → 100 over 2700ms with a gradient progress bar; the hero text enters on a GSAP timeline (name from opacity 0 / y 50, everything else from blur(10px) / y 20, stagger 0.09s, power3.out). ScrollTrigger drives the featured-photo parallax (image y −8% to +8% over its scroll range) and three Explorations columns at different speeds with resting rotations −2deg / 1deg / −1deg. The marquee is a GSAP infinite loop (xPercent −50, duration 40, ease none, repeat −1). Framer Motion handles gallery filtering crossfades and the lightbox (opacity 0→1, scale 0.96→1, 380ms ease-out). Hover: 1.03 image zoom over 700ms, arrow slides 4px. Under prefers-reduced-motion every timeline is replaced by an instant state and the marquee becomes a static wrapped line.

Landing Hero Motion Brief

  • Focal subject: the full-viewport HLS film from https://stream.mux.com/Aa02T7oM1wH5Mk5EEVDYhbZ1ChcdhRsS2m1NYyx4Ua1g.m3u8, playing autoPlay muted loop playsInline at object-cover under a bg-black/35 scrim with a bottom fade into #0A0A0A.
  • Input → transformation → outcome thesis: the visitor's arrival (input) triggers the GSAP entrance timeline, in which the name "MD Abdulla" rises from opacity 0 / y 50 while the eyebrow, tagline, description and buttons resolve from blur(10px) / y 20 with a 0.09s stagger on power3.out (transformation), so the film is already moving before the typography settles and the visitor reads a bottom-left editorial lockup over a living image (outcome). No accepted behaviour beyond the hero's own entrance is used.
  • Motion vocabulary: slow, cinematic, restrained — a 2700ms loading counter, a staggered blur-to-sharp type reveal, a continuously looping film, a 1px animated vertical scroll line, and a 700ms 1.03 hover zoom on photographs.
  • Composed first frame: the film fills the viewport; the eyebrow sits small and tracked at the left gutter; the name spans roughly nine columns flush-left in Instrument Serif italic; the tagline and description sit beneath at a 62ch measure; the two rounded-full buttons sit left-aligned below the copy; "SCROLL TO EXPLORE" and its vertical line sit bottom-left; "01 / 08" sits bottom-right in muted. Nothing is centred.
  • Reduced-motion state: the entrance timeline is replaced by an instant final state — the name, eyebrow, tagline, description and buttons appear fully composed with no blur, no y-offset and no stagger; the scroll line holds still; the marquee becomes a static wrapped line; parallax and hover zooms resolve instantly.
Page 17 of 20

9. Non-Functional Requirements

NFR-1 — Performance (explicit) Images must be lazy-loaded and served with responsive image sizes. HLS instances, video listeners and GSAP ScrollTriggers must be cleaned up on unmount. Unnecessary React renders must be avoided. Rationale: the exhibition is photography-heavy and must stay smooth while remaining photography-first.

NFR-2 — Reduced motion (explicit) prefers-reduced-motion must be respected. Rationale: accessibility and comfort for motion-sensitive visitors; the direction specifies that under reduced motion every timeline is replaced by an instant state and the marquee becomes a static wrapped line.

NFR-3 — Accessibility (explicit) Semantic HTML, correct heading hierarchy, descriptive alt text, keyboard-accessible navigation and lightbox, visible focus states and ARIA labels where appropriate. Rationale: the lightbox and navbar are the primary interactive surfaces and must be operable without a pointer.

NFR-4 — Responsive integrity (explicit) The site must be optimized for mobile, tablet, laptop and large desktop; mobile must have no horizontal overflow; important parts of photographs must never be cropped unnecessarily. Rationale: the exhibition is viewed on phones as often as desktops, and the photographs are the product.

NFR-5 — SEO metadata (explicit) Title "MD Abdulla — Photography"; description "MD Abdulla — Photographer capturing landscapes, people, nature, travel and beautiful moments through photography."; OG title "MD Abdulla — Photography"; OG description "Capturing moments. Preserving emotions. Telling stories through photographs."

NFR-6 — Photograph authenticity (explicit) Only MD Abdulla's actual photographs may be used; they must never be AI-generated or transformed, and faces or facial features, skies, landscapes, objects, scenery, composition, identity, and important colors/details must not be altered. No artificial people or objects. Only hover zoom, lightbox, parallax, cinematic overlays, subtle brightness/contrast and smooth transitions are permitted as presentation effects. Rationale: authenticity is the product's core value.

NFR-7 — Contact constraint (explicit) No email, email address, mailto link, phone number, contact form or fake/placeholder contact details may appear anywhere. Instagram @axr.md is the only contact/social CTA, and the final CTA button links only to https://instagram.com/axr.md.

NFR-8 — Theme constraint (explicit) The dark theme is forced; there is no light-mode toggle.

NFR-9 — Naming constraint (explicit) The gallery section is called Live Gallery, never "Selected Works".

NFR-10 — Readable text and controls stay whole (direction) Headlines, wordmarks, labels, numbers, card text and controls must stay entirely inside the viewport and their container at 375px, 768px and 1280px, wrapping or scaling (for example font-size: clamp(...) with its mobile size) to fit, and no other element may cover any part of them. Imagery, decoration and motion may be cropped, bled off an edge, rotated, overlapped or cut as the direction asks, as long as they cover no readable text or control. Moving content (the marquee) may cross the viewport edge by design and is judged by whether every item becomes fully readable as it passes; with prefers-reduced-motion it stops and shows whole items, wrapping into rows or sitting in a horizontally scrollable row.

Page 18 of 20

10. Tech Stack

All technology choices below are explicitly specified by the user and are preserved exactly.

  • React — component model for the single-page exhibition.
  • Vite — build tooling and dev server.
  • TypeScript — typed source, including the photograph data module.
  • Tailwind CSS — utility styling with colors expressed as hsl(var(--...)).
  • tailwindcss-animate — Tailwind animation utilities.
  • GSAP and GSAP ScrollTrigger — hero entrance timeline, infinite marquee, featured-photo parallax and the Explorations column parallax.
  • Framer Motion (Motion) — declarative UI, entrance, gallery filtering and lightbox animations.
  • hls.js — HLS playback for the hero video, with native HLS fallback when available.
  • react-router-dom — routing for the single-page application.
  • Google Fonts — Inter 300–700 and Instrument Serif italic 400.
  • Centralized data module — src/data/photographs.ts as the single source for all photographic surfaces.

No additional frameworks, state managers, backends or databases are required by the accepted requirements.

Page 19 of 20

11. Assumptions and Constraints

Assumptions

  • A-1: The single page is served at one route and all navigation is in-page smooth scrolling, consistent with the explicit single-page requirement and the src/pages/Index.tsx structure. (explicit)
  • A-2: The photograph images referenced by src paths such as /images/photo-01.jpg are supplied by MD Abdulla as his actual photographs; the product never generates or transforms them. (explicit)
  • A-3: The Mux HLS stream is available and playable; when it is not, the hero degrades gracefully to its overlay and copy. (required_inference — recovery for the explicit HLS requirement)
  • A-4: The visitor is anonymous and no account, sign-in or identity establishment exists, because the accepted journey is fully public and no accepted requirement creates durable visitor-owned state. (required_inference)
  • A-5: MD Abdulla's content maintenance happens by editing the centralized array in the source, since no in-product publishing surface was accepted. (explicit)

Constraints

  • C-1: Do NOT include any email, email address, mailto link, phone number, contact form or fake/placeholder contact details. (explicit)
  • C-2: Instagram is the only contact/social CTA; the final CTA button links only to https://instagram.com/axr.md. (explicit)
  • C-3: Force dark theme; no light-mode toggle. (explicit)
  • C-4: Call the section Live Gallery, never "Selected Works". (explicit)
  • C-5: Use only MD Abdulla's actual photographs; never AI-generate or transform them. (explicit)
  • C-6: Do not alter faces or facial features, skies, landscapes, objects, scenery, composition, identity, or important colors/details. (explicit)
  • C-7: No artificial people or objects. (explicit)
  • C-8: Allowed presentation effects only: hover zoom, lightbox, parallax, cinematic overlays, subtle brightness/contrast and smooth transitions; photographs must remain authentic. (explicit)
  • C-9: Preserve natural aspect ratios; do not unnecessarily crop photographs, and never crop important parts of photographs unnecessarily. (explicit)
  • C-10: Keep important image details unobstructed in the Featured Photo section. (explicit)
  • C-11: Avoid bright colors, excessive UI, generic stock images, excessive cards and artificial-looking photography. (explicit)
  • C-12: Mobile must have no horizontal overflow. (explicit)
  • C-13: Respect prefers-reduced-motion. (explicit)
  • C-14: The generic indigo/blue-on-white SaaS template is forbidden for this project. (direction)
Page 20 of 20

12. Glossary

  • Live Gallery — The gallery section of the exhibition, headed "Moments I capture" with the eyebrow "01 — LIVE GALLERY". It is never called "Selected Works".
  • Lightbox — The fullscreen bg-black/95 viewer that shows a photograph centered without distortion, with Previous / Next / Close / Counter / Category / Caption controls and Escape / Left / Right keyboard support.
  • Masonry — The gallery layout that preserves each photograph's natural aspect ratio across 3 columns on desktop, 2 on tablet and 1 on mobile.
  • HLS — HTTP Live Streaming; the hero video format served by Mux and played via hls.js with a native HLS fallback.
  • ScrollTrigger — The GSAP plugin used for the featured-photo parallax and the Explorations column parallax.
  • Marquee — The GSAP infinite loop reading "CAPTURE THE MOMENT •" repeated 10×, with xPercent:-50, duration:40, ease:"none", repeat:-1.
  • Featured Photo — The large cinematic photograph section headed "A moment worth remembering." with the overlay "01 / MOMENT / MD ABDULLA / 2026".
  • Recent Frames — The journal section headed "Recent Frames" with the subtext "Small stories behind the photographs.", listing 4–6 horizontal entries with image, title, date, location, story and read time.
  • Visual Explorations — The min-h-[300vh] scroll-driven exhibition of 2–3 vertical image columns at different parallax speeds with rotations −2deg / 1deg / −1deg.
  • Accent gradient — linear-gradient(90deg,#89AACC 0%,#4E85BF 100%), exposed as .accent-gradient and used only for the logo ring, loading progress, hover borders and subtle highlights.
  • Centralized photograph array — The photographs export in src/data/photographs.ts, the single source consumed by the gallery, filtering, lightbox, featured content and explorations.
  • Reduced motion — The prefers-reduced-motion user preference, under which timelines resolve instantly and the marquee becomes a static wrapped line.

No completed page designs yet.

Completed design pages will appear here when they are ready to preview.

Landing: Arrive at published exhibition
Landing: Watch loading and hero film
Landing: Review gallery and filtered surfaces
Landing: Read Featured, Frames, Explorations
Landing: Confirm name, message and stats
Landing: Verify Instagram @axr.md CTA

No completed page designs yet.

Completed design pages will appear here when they are ready to preview.

Landing: Arrive at published exhibition
Landing: Watch loading and hero film
Landing: Review gallery and filtered surfaces
Landing: Read Featured, Frames, Explorations
Landing: Confirm name, message and stats
Landing: Verify Instagram @axr.md CTA