--- version: alpha name: fernweg-books-design description: "A dark wood-brown canvas (#1c1410) with warm cream ink (#f2e9db), a gold-leaf amber (#c9a24a) for the staff pick's own spine and primary action, and a muted wine (#c17777) for the ribbon bookmark and attention states. Crimson Pro carries every heading at weight 600; Lato carries the surrounding prose. The system reads as an actual small shop's site, specific about titles, never a big-box retailer's bestseller carousel." --- ## Brand Positioning Fernweg Books is for readers who want a recommendation from someone who actually read the book, not an algorithm's "customers also bought" row. It exists because most bookstore sites borrow big-retailer chrome (a bestseller carousel, star ratings, "customers also bought") that has nothing to do with a shop small enough to hand-sell four titles a week. Fernweg's bet: the one piece of drama on the page should be the shelf itself opening, spines fanning out like a hand of cards, a ribbon bookmark dropping into the one book the staff actually chose. Every visual decision below serves that one bet. If a component doesn't help someone find a book or reach the shop, or doesn't come from a real bookstore interaction (staff-pick table, order status, newsletter form), it doesn't belong in this system. colors: accent: "#c9a24a" accent-alt: "#c17777" ink: "#f2e9db" ink-muted: "#ab9a86" canvas: "#1c1410" surface: "#251c16" surface-raised: "#2f241c" border: "#3d2f24" focus-ring: "#c9a24a" ## Logo / Wordmark System The mark is a rounded-square card containing a single closed book with a ribbon bookmark hanging from its top edge, literally a 1:1 miniature of the staff pick's spine on the homepage shelf, ribbon included. ```svg ``` - **Lockup**: mark, then a `0.5rem` gap, then the wordmark "Fernweg" in Crimson Pro/600, mark always left of the wordmark, never stacked or reversed. - **Minimum size**: mark not smaller than `16px` square, below that the ribbon and book outline 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 remove the ribbon, an unmarked book is a different, generic brand. Don't animate the mark itself, the fan-and-drop motion belongs to the homepage's shelf, not the nav. Don't rotate or stretch it. ## Color System ### Roles | Role | Token | Value | Used for | |---|---|---|---| | Canvas | `--bg` | `#1c1410` | Page background | | Surface | `--panel` | `#251c16` | Panels, nav, table header | | Surface raised | `--surface-raised` | `#2f241c` | Row hover, input focus bg | | Border | `--border` | `#3d2f24` | Panel edges, dividers, table rules | | Ink | `--ink` | `#f2e9db` | Primary text | | Ink muted | `--dim` | `#ab9a86` | Secondary text, helper text, order-in status | | Staff pick / primary | `--accent` | `#c9a24a` | This week's pick spine, primary button fill, in-stock status, focus ring | | Ribbon / attention | `--accent-alt` | `#c17777` | Ribbon bookmark, backordered copy | There is deliberately no alarm red. A backordered title is ordinary shop reality, not a failure, so it's communicated in the same muted wine the ribbon uses, a specific sentence naming the new timeline. ### Contrast (computed from the hex values above via WCAG relative luminance) | Pairing | Ratio | Passes | |---|---|---| | `--ink` text on `--bg` | ~15.1:1 | AAA | | `--dim` text on `--bg` | ~6.7:1 | AA (body text) | | `--accent` text on `--bg` (in-stock status, links) | ~7.6:1 | AAA | | `--accent-alt` text on `--bg` (backorder copy) | ~5.3:1 | AA (body text) | | Dark label on `--accent` fill (primary button) | ~7.6:1 | AAA | | `--ink` on `--panel` | ~13.9:1 | AAA | | `--ink` on `--surface-raised` | ~12.6:1 | AAA | The rule this table exists to enforce: `--accent-alt` started as a brighter rose that only cleared large-text contrast and was darkened specifically so the backorder message itself, not just a badge, could carry the color directly at body size. typography: display: fontFamily: Crimson Pro fontWeight: 600 body: fontFamily: Lato fontWeight: 400 ## Type Scale | Token | Size | Weight | Family | Line-height | Letter-spacing | Used for | |---|---|---|---|---|---|---| | `--text-display` | `clamp(2.5rem, 6vw, 4.25rem)` | 600 | Crimson Pro | 1.1 | 0 | Hero H1 only | | `--text-h2` | `1.7rem` (homepage) / `1.45rem` (second page) | 600 | Crimson Pro | 1.2 | 0 | Section headings | | `--text-spine` | `0.8rem` | 600 | Crimson Pro | 1.2 | 0 | Vertical text on a book spine | | `--text-body` | `1rem` | 400 | Lato | 1.6 | 0 | Paragraph copy | | `--text-small` | `0.85rem` | 400 | Lato | 1.5 | 0.01em | Footer, nav utility links, helper text, table cells | Rule for Crimson Pro vs. Lato: the serif is reserved for the hero headline, section headings, and spine labels, moments meant to feel like actual book typography. Everything else, nav, buttons, form labels, table cells (title/author/reason), is Lato, chosen for staying warm and legible when a table cell needs to hold a full sentence like "handsold more than anything else this year." ## 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: 8px` for panels, inputs, and table containers. `--radius-pill: 999px` for buttons and the ready-for-pickup badge. Book spines round only at the top corners (`3px 3px 0 0`), matching how a real spine meets a shelf. ## Iconography No icon library. The only non-text glyphs are the logo mark, the shelf/spine/ribbon illustration, and one Unicode glyph, `✓` (ready for pickup), set at the same weight as the text beside it. Stock status is communicated with a plain-language phrase ("In stock", "Order in") paired with color, never a stock 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 fans five book spines open from a flat stack into a spread hand, each one rotating into place with a short stagger and a slight overshoot (`back.out`), the ribbon bookmark then dropping into the staff pick's spine once the fan finishes. The whole sequence plays once per view (`toggleActions: play none none reverse`), 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 every spine already fanned and the ribbon already dropped, no animation. ### Never-list (written before the impeccable-pass rebuild) 1. No full-viewport centered hero holding the fanning shelf a forced screen-height away, the shelf sits directly beneath the headline in the same first fold. 2. No two-button CTA row floating free of the shelf. ## Voice & Tone literary, warm, specific about titles and authors, no bestseller hype. In practice: - **Button label**: "Visit the store", not "Shop Our Bestselling Collection" - **Error message**: "Backordered. The publisher pushed this title to next month.", not "Sorry, temporarily unavailable!" - **Empty state**: "Nothing on order right now.", not "No results, try browsing our catalog!" - **Success status**: "Ready for pickup, Orbital", not "Your book has arrived! 📚" ## Accessibility Baseline - Focus ring: `2px solid var(--accent)`, `2px` offset, applied via `:focus-visible` on every interactive element (links, buttons, inputs), never removed without a visible replacement. - Reduced motion: the shelf fan-out and ribbon drop both check `prefers-reduced-motion: reduce` and render fully resolved with no animation when it's set. - Minimum tap target: `44px` in the smallest dimension for every button and form control on touch viewports. - Color is never the only signal: stock status pairs color with a specific phrase, the backorder state pairs wine with a full sentence naming the new timeline, not a bare icon. ## 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. Right: a Shelf 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 ("Visit the store", "Subscribe"). - **Secondary**: transparent fill, `1px solid --border`, `--ink` label. "See new date" and similar secondary actions. - **Ghost**: text-only, `--dim` label, `--ink` on hover. Tertiary actions like "see this week's pick." All variants define `:hover` (brightness/border shift), `:active` (`transform: scale(0.98)`), `:disabled` (`opacity: .4`, `pointer-events: none`), and `:focus-visible` (accent outline). ### Shelf illustration Five book-spine rectangles that rotate open from a flat stack, one (the staff pick) taller and gold, with a wine-colored ribbon dropping from its top edge. Purely illustrative, not interactive, exists to make "shelved by someone who read it" visually literal. ### Table Header row in `--panel`/`--dim` labels, body rows in `--bg`, one `--border` rule between rows, row hover to `--surface-raised`. The "why we picked it" column always carries a specific, personal reason, never a generic tag like "bestseller." ### Forms Label above input, `--text-small`/`--dim`. Input: `--panel` background, `1px solid --border`, `--radius`, `--ink` text, `--dim` placeholder. On `:focus`, border becomes `--accent` and background lifts to `--surface-raised`. On error, border becomes `--accent-alt` 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 title, 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: shop name/tagline on the left, real page links on the right (Shelf, back to gallery). No invented legal text. ## Do's and Don'ts ### Do - Let the shelf fan-out and ribbon drop be the only scroll-staggered elements on the page. - Reserve `--accent` for the staff-pick meaning and `--accent-alt` for the ribbon/attention meaning, keep that split consistent everywhere. - Give every recommendation a specific, personal reason, never a generic "bestseller" or star rating. - Use a dark label on any `--accent`-filled surface. - Name real titles and authors everywhere, never placeholder "Book Title" copy. ### Don't - Don't add a star-rating system, a bestseller carousel, or "customers also bought" rows, this is a small shop's own curated picks, not an algorithmic storefront. - Don't introduce red for backorders or delays, route those to `--accent-alt` with specific copy instead. - Don't replay the shelf fan-out on every scroll pass, reveal once per view. - 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, shelf), still no real cart or checkout flow, no responsive breakpoint table beyond a single-column mobile collapse, no authenticated customer account (the newsletter and order flows are not wired to anything real, this is a concept demo).