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."
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.
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:
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.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.
The following authoritative content-source facts are preserved exactly as supplied.
Hero HLS video (content source — authoritative):
https://stream.mux.com/Aa02T7oM1wH5Mk5EEVDYhbZ1ChcdhRsS2m1NYyx4Ua1g.m3u8hls.js with native HLS fallback.Instagram destination (content source — authoritative):
@axr.mdhttps://instagram.com/axr.mdIdentity and message content:
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:
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."
The single page of the product: an anonymous, publicly reachable, continuously scrollable exhibition containing every accepted section in order.
Information and state
isLoading controls a fullscreen LoadingScreen overlay rendered as {isLoading && <LoadingScreen onComplete={()=>setIsLoading(false)} />}.Primary actions
Supporting actions
Domain entities
id, src, title, category, date, location, description.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.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
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.
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.
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.
https://instagram.com/axr.md.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.
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.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.
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.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.
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.
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.
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.
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.
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.
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.
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.
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."
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.
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.
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.
src/data/photographs.ts array so that adding or removing a photograph automatically updates the gallery, filtering, lightbox, featured content and explorations.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.
isLoading is true, so LoadingScreen renders fullscreen at fixed inset-0 z-[9999] bg-bg.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.onComplete, setting isLoading to false and revealing the exhibition.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.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.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.https://instagram.com/axr.md, or follows "SCROLL TO EXPLORE" and the animated vertical line downward.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.CategoryFilter.PhotoCard is rounded-3xl, overflow-hidden, on a dark surface with a subtle border, showing minimal metadata such as category and year.bg-black/95, animating with opacity 0→1 and scale .96→1, showing the original photograph centered without distortion.min-h-[300vh] Visual Explorations section, headed "Visual Explorations" with the subtext "A collection of places, textures, people and moments that caught my eye."https://instagram.com/axr.md, where the follow or contact happens under Instagram's ownership.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."}.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):
| Role | Hex | Usage |
|---|---|---|
| Background | #0A0A0A | ~75% of the page ground |
| Surface | #141414 | navbar pill, photo cards, lightbox chrome only |
| Text | #F5F5F5 | display and body |
| Primary | #89AACC | accent gradient start |
| Accent | #4E85BF | accent gradient end |
| Muted | #878787 | eyebrows, metadata, captions, inactive nav |
| Hairline | #1F1F1F | 1px 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.
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.
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
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.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.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.
All technology choices below are explicitly specified by the user and are preserved exactly.
hsl(var(--...)).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.
Assumptions
src/pages/Index.tsx structure. (explicit)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)Constraints
https://instagram.com/axr.md. (explicit)prefers-reduced-motion. (explicit)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.hls.js with a native HLS fallback.xPercent:-50, duration:40, ease:"none", repeat:-1.min-h-[300vh] scroll-driven exhibition of 2–3 vertical image columns at different parallax speeds with rotations −2deg / 1deg / −1deg.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.photographs export in src/data/photographs.ts, the single source consumed by the gallery, filtering, lightbox, featured content and explorations.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.
No completed page designs yet.
Completed design pages will appear here when they are ready to preview.
No comments yet. Be the first!