--- version: alpha name: aperture-studio-design description: "A near-black studio canvas (#0b0b0c) with warm white ink (#f2f0ec), a golden-hour amber (#e8a33d) for the lens and primary action, and a flash cyan (#4fb3c4) for the aperture's center and secondary accents. Bebas Neue carries every heading in condensed uppercase; Manrope carries the surrounding prose. The system reads as an actual working photographer's site, minimal and visual-first, never a stock-photo template." --- ## Brand Positioning Aperture Studio is for clients who want to see how a photographer actually works, not scroll a stock-photo template with placeholder smiling faces. It exists because most photography sites borrow generic portfolio-template chrome (auto-playing image carousels, drop-shadow-heavy cards, stock captions like "capturing your special moments") that has nothing to do with the actual mechanics of taking a photograph. Aperture's bet: the one piece of drama on the page should be the aperture itself, a six-blade iris spinning open exactly the way it does before a real shutter fires. Every visual decision below serves that one bet. If a component doesn't help someone understand a session or book one, or doesn't come from a real studio interaction (session table, booking status, request form), it doesn't belong in this system. colors: accent: "#e8a33d" accent-alt: "#4fb3c4" ink: "#f2f0ec" ink-muted: "#9c9a98" canvas: "#0b0b0c" surface: "#161617" surface-raised: "#1f1f21" border: "#2c2c2f" focus-ring: "#4fb3c4" ## Logo / Wordmark System The mark is a rounded-square card containing a lens ring with a cyan center dot, literally a 1:1 miniature of the aperture illustration at rest, the small opening a real iris leaves even near-closed. ```svg ``` - **Lockup**: mark, then a `0.5rem` gap, then the wordmark "Aperture" in Bebas Neue, uppercase, tracked out, mark always left of the wordmark, never stacked or reversed. - **Minimum size**: mark not smaller than `16px` square, below that the ring and center dot merge. Wordmark not smaller than `0.9rem`. - **Clearspace**: empty margin equal to the mark's own height (22px at default size) on all four sides of the lockup. - **Don't**: recolor the mark for a light background, it only ever renders on `--panel`/`--bg`. Don't add blade lines to the static mark, that detail belongs to the homepage's full iris illustration. Don't animate the mark itself, the spin-open motion belongs to the hero section, not the nav. Don't rotate or stretch it. ## Color System ### Roles | Role | Token | Value | Used for | |---|---|---|---| | Canvas | `--bg` | `#0b0b0c` | Page background | | Surface | `--panel` | `#161617` | Panels, nav, service/session cards, table header | | Surface raised | `--surface-raised` | `#1f1f21` | Iris blade fill, row hover, input focus bg | | Border | `--border` | `#2c2c2f` | Panel edges, dividers, table rules, blade seams | | Ink | `--ink` | `#f2f0ec` | Primary text | | Ink muted | `--dim` | `#9c9a98` | Secondary text, helper text | | Lens / primary | `--accent` | `#e8a33d` | Iris reveal glow, primary button fill, delivered badge, focus color on primary actions | | Center / secondary | `--accent-alt` | `#4fb3c4` | Aperture center dot, reschedule-needed copy, focus ring | There is deliberately no red anywhere. A reschedule from equipment trouble is ordinary studio logistics, not a failure, so it's communicated in the cyan the aperture's own center uses, a specific sentence naming what happened. ### Contrast (computed from the hex values above via WCAG relative luminance) | Pairing | Ratio | Passes | |---|---|---| | `--ink` text on `--bg` | ~17.3:1 | AAA | | `--dim` text on `--bg` | ~7.0:1 | AAA | | `--accent` text on `--bg` (delivered status, links) | ~9.1:1 | AAA | | `--accent-alt` text on `--bg` (reschedule copy) | ~8.0:1 | AAA | | Dark label on `--accent` fill (primary button) | ~9.1:1 | AAA | | `--ink` on `--panel` | ~15.9:1 | AAA | | `--ink` on `--surface-raised` | ~14.5:1 | AAA | The rule this table exists to enforce: a button or badge filled with `--accent` always labels itself in a near-black (`#251a04`), never `--ink`, cream-on-amber at this saturation undershoots the crispness the rest of the system holds to. typography: display: fontFamily: Bebas Neue fontWeight: 400 body: fontFamily: Manrope fontWeight: 400 ## Type Scale | Token | Size | Weight | Family | Line-height | Letter-spacing | Used for | |---|---|---|---|---|---|---| | `--text-display` | `clamp(3rem, 8vw, 5.5rem)` | 400 | Bebas Neue | 1.0 | 0.02em, uppercase | Hero H1 only | | `--text-h2` | `2rem` (homepage) / `1.7rem` (second page) | 400 | Bebas Neue | 1.1 | 0.02em, uppercase | Section headings | | `--text-session-name` | `1.4rem` | 400 | Bebas Neue | 1.1 | 0.02em, uppercase | Session/service card names | | `--text-body` | `1rem` | 400 | Manrope | 1.6 | 0 | Paragraph copy | | `--text-small` | `0.85rem` | 400 | Manrope | 1.5 | 0.01em | Footer, nav utility links, helper text, table cells | Rule for Bebas Neue vs. Manrope: Bebas Neue, always uppercase and condensed, is reserved for the hero headline, section headings, and session names, moments meant to feel like a gallery wall label. Everything else, nav, buttons, form labels, table cells, is Manrope, chosen because Bebas Neue at body size and in sentence case becomes hard to read quickly. ## Spacing Scale Base unit `8px`. Tokens in use: `--space-2: 0.5rem`, `--space-3: 1rem`, `--space-4: 1.5rem`, `--space-6: 2rem`, `--space-8: 3rem`, `--space-12: 4rem`. ## Shape One radius scale: `--radius: 6px` for panels, cards, inputs, and table containers, tight and unfussy. `--radius-pill: 999px` for buttons and the delivered-gallery badge. The aperture illustration is the one intentional circular exception. ## Iconography No icon library. The only non-text glyphs are the logo mark, the aperture-blade illustration, and one Unicode glyph, `✓` (gallery delivered), set at the same weight as the text beside it. Session and booking status is communicated with a plain-language phrase paired with color, never a generic calendar or camera icon. If a future page needs more iconography, the fallback is Phosphor (line style, `1.5` stroke), that decision just hasn't been needed yet. ## Motion Principles Scroll rotates six identical aperture-blade wedges around a shared center, all by the same growing angle, so the overlapping blades fan open like a pinwheel and reveal an amber-tinted circle behind them, exactly the way a real iris diaphragm widens before a shutter fires. Driven entirely by scroll position (`scrub`, not a fixed duration), reversible by scrolling back up. This is the only scripted animation on either page, everything else (buttons, table rows, form inputs) uses only `:hover`/`:active`/`:focus-visible` CSS transitions. The whole system honors `prefers-reduced-motion` by showing the blades in their fully-open position immediately, no rotation. ### Never-list (written before the impeccable-pass rebuild) 1. No small decorative iris icon stacked below a centered headline, the iris is large (up to 380px, was 220px) and shares the first viewport with the copy in a two-column layout. 2. No two-button CTA row floating free of the iris, the primary action sits beside the intro copy that introduces it. ## Voice & Tone minimal, visual-first, short captions, no adjectives about the work. In practice: - **Button label**: "Book a session", not "Capture Your Most Beautiful Moments" - **Error message**: "Reschedule needed. A camera repair pushed Thursday's slots back a day.", not "Oops, a hiccup!" - **Empty state**: "No sessions on the calendar this week.", not "Nothing booked, want to change that?" - **Success status**: "Gallery delivered, 42 frames", not "Your stunning gallery is ready! 📸" ## Accessibility Baseline - Focus ring: `2px solid var(--accent-alt)`, `2px` offset, applied via `:focus-visible` on every interactive element (links, buttons, inputs, select), never removed without a visible replacement. - Reduced motion: the aperture's blade rotation checks `prefers-reduced-motion: reduce` and renders the blades fully open immediately, no scrubbed rotation. - Minimum tap target: `44px` in the smallest dimension for every button and form control on touch viewports. - Color is never the only signal: session and booking status pair color with a specific phrase and, where relevant, a frame count, the reschedule state pairs cyan with a full sentence naming what happened. ## Components ### Navigation Single-line bar, `64px` tall, `--panel` background with a `--border` bottom hairline, sticky to the top. Left: a small "back to gallery" utility link. Center-left: the mark + wordmark lockup, wordmark uppercase. Right: a Book link plus one primary button. Collapses to just the lockup and primary button under `480px`, no hamburger, there are only two destinations. ### Buttons Three variants, one radius (`--radius-pill`), one primary accent: - **Primary**: `--accent` fill, dark label, used once per view for the single real action ("Book a session", "Request a date"). - **Secondary**: transparent fill, `1px solid --border`, `--ink` label. "Pick a new time" and similar secondary actions. - **Ghost**: text-only, `--dim` label, `--ink` on hover. Tertiary actions like "open the lens." All variants define `:hover` (brightness/border shift), `:active` (`transform: scale(0.98)`), `:disabled` (`opacity: .4`, `pointer-events: none`), and `:focus-visible` (cyan outline). ### Aperture illustration An SVG of six identical wedge shapes, each in its own rotated group sharing one center pivot, all rotating by the same scroll-driven angle so the overlapping blades fan open in unison. An amber-tinted circle sits behind them, becoming visible as the gaps widen. Illustrative only, not interactive. ### Session cards A flat panel per session type: a Bebas Neue name and one plain sentence of scope (length, deliverable count). No stock photography, the copy carries the specificity. ### Table Header row in `--panel`/`--dim` labels, body rows in `--bg`, one `--border` rule between rows, row hover to `--surface-raised`. Pricing and length are plain text, no strikethrough anchoring or "starting at" hedging. ### Forms Label above control, `--text-small`/`--dim`. Select/input: `--panel` background, `1px solid --border`, `--radius`, `--ink` text, `--dim` placeholder. On `:focus`, border becomes `--accent-alt` and background lifts to `--surface-raised`. On error, border becomes `--accent` and helper text explains what to fix in plain language. ### Status / feedback states - **Loading**: a skeleton shaped like the real content (bars matching text line-heights), not a spinner. - **Empty**: a plain sentence in `--dim`, no illustration. - **Error**: an inline `--accent-alt` message naming the specific cause, with a concrete next step, never a silent failure. - **Success / status badge**: `--radius-pill`, `1px solid --accent`, `--accent` text on transparent fill, not filled, filled would compete with the primary button's exclusive use of a solid `--accent` fill. ### Footer One row: studio name/tagline on the left, real page links on the right (Book, back to gallery). No invented legal or licensing text. ## Do's and Don'ts ### Do - Let the aperture's blade rotation be the only scroll-scrubbed element on the page. - Reserve `--accent` for the lens/primary-action meaning and `--accent-alt` for the center/secondary meaning, keep that split consistent everywhere. - Keep session copy scoped and specific (length, deliverable count, price), never vague "custom pricing" hedges. - Use a dark label on any `--accent`-filled surface. - Let the aperture illustration and typography carry the visual system, no photography needed to prove the concept. ### Don't - Don't use an auto-playing image carousel or stock portrait photography, the aperture illustration is the whole visual hook on purpose. - Don't write generic captions like "capturing your special moments," name the actual format and deliverable instead. - Don't introduce red for reschedules or delays, route those to `--accent-alt` with specific copy instead. - Don't stack more than one primary button in the same view. - Don't fill a status badge solid, badges stay outlined so the primary button remains the only solid-`--accent`-fill element on screen. ## Known Constraints - Two routes now exist (home, book), still no real portfolio gallery or online proofing tool, no responsive breakpoint table beyond a single-column mobile collapse, no authenticated client login (the booking flow and request form are not wired to anything real, this is a concept demo).