13 KiB
Familienarchiv — Design Styleguide
This document defines the visual language for the Familienarchiv frontend. All UI work should follow these conventions to stay consistent with the De Gruyter Brill corporate identity.
Brand Identity
The design is based on the De Gruyter Brill brand identity (unveiled at Frankfurt Book Fair 2024). Key characteristics:
- Clean white backgrounds, high contrast
- Strong typographic hierarchy (uppercase labels, serif body text)
- Academic publisher aesthetic: authoritative, clear, uncluttered
Colors
Defined in src/routes/layout.css as @theme variables. All generate Tailwind utilities automatically (bg-*, text-*, border-*).
| Token | Hex | Usage |
|---|---|---|
brand-navy |
#012851 |
Primary text, headings, buttons, active states — Prussian Blue |
brand-mint |
#A1DCD8 |
Accent color, icon tints, hover underlines — Aqua Island |
brand-purple |
#B4B9FF |
Logo, nav active state highlight, top accent strip — Melrose |
brand-sand |
#F0EFE9 |
Subtle card backgrounds, borders, hover backgrounds — paper tone |
brand-white |
#FFFFFF |
Page background, card surfaces |
brand-dark |
#0D0D0D |
Near-black text when maximum contrast is needed |
Color usage rules
- Never use raw hex values in components — always use token utilities.
- Page and card backgrounds are white. Use
bg-brand-sandonly for subtle inset areas (e.g.bg-brand-sand/30). brand-navyis the workhorse: headings, body text, borders, primary buttons.brand-mintis an accent only — never use it as primary text color on white (contrast too low).brand-purpleis reserved for the logo and the single top accent strip in the header.
Typography
Fonts
| Role | Font | Tailwind | Notes |
|---|---|---|---|
| Body / Serif | Tinos (Times substitute) | font-serif |
Loaded from Google Fonts. Used for document titles, names, body copy, dates. Matches DGB's use of Times. |
| UI / Sans | Montserrat (Gotham substitute) | font-sans |
Loaded from Google Fonts. Used for labels, navigation, buttons, metadata, form elements. Matches DGB's use of Gotham. |
Type scale and usage
| Element | Classes | Example |
|---|---|---|
| Page title | font-serif text-3xl text-brand-navy |
<h1> |
| Card section heading | font-sans text-xs font-bold uppercase tracking-widest text-gray-400 |
Section labels |
| Document / item title | font-serif text-xl font-medium text-brand-navy |
List items |
| Metadata / label | font-sans text-xs font-bold uppercase tracking-widest text-gray-500 |
Field labels |
| Body text | font-serif text-sm text-brand-navy |
Descriptions, summaries |
| Navigation | font-sans text-xs font-bold uppercase tracking-widest |
Nav links |
Rules
- Labels are always uppercase + tracked:
text-xs font-bold uppercase tracking-widest - Headings use
font-sans(Montserrat), set in CSS globally. - Content (document titles, person names, summaries) uses
font-serif(Tinos). - Never use
font-seriffor UI chrome (buttons, labels, nav).
Icons
Library
686 SVG icons in frontend/static/degruyter-icons/. Two families:
- Simple — single-color, action-oriented. Use for all UI icons. Available in 4 sizes.
- Complex — multi-color illustrative icons. Use sparingly for empty states or section headers.
Simple icon sizes
| Size | Pixels | Path segment | Use |
|---|---|---|---|
| XS | 12px | X-Small-12px |
Inline text hints, badges |
| SM | 16px | Small-16px |
Compact UI, table cells |
| MD | 24px | Medium-24px |
Standard UI icon — default choice |
| LG | 32px | Large-32px |
Feature headers, empty states |
URL pattern
/degruyter-icons/Simple/{Size}/SVG/{Category}/{Name}-{Size-Code}.svg
Size codes: XS, SM, MD, LG
Usage as <img> (recommended for static icons)
SVG fills are hardcoded to #000000. Use CSS to tint/size them:
<!-- Standard icon -->
<img src="/degruyter-icons/Simple/Medium-24px/SVG/Action/Edit-Content-MD.svg"
alt="" aria-hidden="true" class="w-6 h-6" />
<!-- Muted/secondary icon -->
<img src="/degruyter-icons/Simple/Medium-24px/SVG/Action/Edit-Content-MD.svg"
alt="" aria-hidden="true" class="w-6 h-6 opacity-40" />
<!-- Colored via CSS filter (navy tint) -->
<img src="/degruyter-icons/Simple/Medium-24px/SVG/Action/Edit-Content-MD.svg"
alt="" aria-hidden="true"
class="w-6 h-6"
style="filter: invert(11%) sepia(58%) saturate(1200%) hue-rotate(192deg) brightness(95%) contrast(101%)" />
Note: Always include
alt=""andaria-hidden="true"for decorative icons. For meaningful icons (no visible label next to them), use a descriptivealttext instead.
Key icons for this app
| Use case | Icon path |
|---|---|
| Edit / Bearbeiten | Action/Edit-Content-MD.svg |
| Search / Suche | Action/Mag-Glass-MD.svg |
| New document | Action/Add/Add-General-MD.svg |
| Download | Action/Download-MD.svg |
| Upload | Action/Upload-MD.svg |
| Filter | Action/Filter/Filter-Outline-MD.svg |
| Calendar / date | Action/Calendar/Calendar-Add-MD.svg |
| Location | Action/Location-MD.svg |
| Person / account | Action/Account-MD.svg |
| Chat / conversation | Action/Chat-MD.svg |
| Tag / bookmark | Action/Bookmark/Bookmark-Outline-MD.svg |
| Close / dismiss | Action/Close-MD.svg |
| Back / left arrow | Action/Arrow/Arrow-Left-MD.svg |
| Settings / admin | Action/Settings-MD.svg |
| Document / PDF | Action/PDF-Document-MD.svg |
Action/Mail-MD.svg |
|
| Delete | Action/Remove/Remove-General-MD.svg |
| Info | Action/Info/Block/Info-Block-Border-MD.svg |
Spacing
Based on Tailwind's 4pt grid. Prefer multiples of 4 for all spacing.
| Scale | Value | Use |
|---|---|---|
p-1 / gap-1 |
4px | Tight inline spacing |
p-2 |
8px | Small padding (badges, chips) |
p-3 |
12px | Compact buttons |
p-4 |
16px | Default section padding |
p-6 |
24px | Card inner padding (default) |
p-8 |
32px | Large card padding |
p-10 |
40px | Page vertical padding |
gap-6 |
24px | Grid/list gaps |
mb-6 |
24px | Standard spacing between sections |
mb-10 |
40px | Large spacing between card sections |
Layout
Page wrapper
All content pages use:
<div class="max-w-7xl mx-auto py-8 px-4 sm:px-6 lg:px-8">
Narrower pages (forms, detail views):
<div class="max-w-4xl mx-auto py-10 px-4">
Header
The global sticky header in +layout.svelte:
- Height: 68px (4px purple accent strip + 64px nav bar)
- Background:
bg-white - Bottom border:
border-b border-gray-100 - Z-index:
z-50
Full-screen views
Document detail (/documents/[id]) uses a full-viewport split layout:
<div class="h-screen flex flex-col bg-white">
<!-- top bar -->
<!-- content: sidebar + preview -->
</div>
Components
Card
Standard content card:
<div class="bg-white shadow-sm border border-brand-sand rounded-sm p-6">
<h2 class="text-xs font-bold uppercase tracking-widest text-gray-400 mb-5">
Section Title
</h2>
<!-- content -->
</div>
Card with colored accent bar (person/document detail):
<div class="bg-white shadow-sm border border-brand-sand rounded-sm overflow-hidden">
<div class="h-2 bg-brand-navy w-full"></div>
<div class="p-8 md:p-10">
<!-- content -->
</div>
</div>
Buttons
Primary button:
<button class="bg-brand-navy text-white px-5 py-2 text-xs font-bold uppercase tracking-widest font-sans hover:bg-brand-navy/90 transition-colors">
Speichern
</button>
Secondary / outline button:
<button class="border border-gray-300 text-gray-600 px-5 py-2 text-xs font-bold uppercase tracking-widest font-sans hover:bg-gray-50 transition-colors rounded-sm">
Abbrechen
</button>
Ghost / text button (inline actions):
<button class="text-brand-navy/60 hover:text-brand-navy text-sm font-medium font-sans transition-colors">
Aktion
</button>
Destructive button:
<button class="border border-red-300 text-red-600 px-4 py-2 text-xs font-bold uppercase tracking-widest font-sans hover:bg-red-50 transition-colors rounded-sm">
Löschen
</button>
Button with DGB icon:
<button class="inline-flex items-center gap-2 bg-brand-navy text-white px-4 py-2 text-xs font-bold uppercase tracking-widest font-sans hover:bg-brand-navy/90 transition-colors">
<img src="/degruyter-icons/Simple/Small-16px/SVG/Action/Edit-Content-SM.svg"
alt="" aria-hidden="true" class="w-4 h-4 invert" />
Bearbeiten
</button>
Use
class="invert"on icons inside dark (navy) buttons to make the black SVG white.
Form inputs
Label + input pair:
<div>
<label for="field" class="block text-xs font-bold uppercase tracking-widest text-gray-500 mb-1.5 font-sans">
Feldname *
</label>
<input
id="field" name="field" type="text"
class="block w-full border border-gray-300 py-2.5 px-3 text-sm font-serif text-brand-navy placeholder-gray-400 focus:border-brand-navy focus:ring-1 focus:ring-brand-navy focus:outline-none"
/>
</div>
Search input:
<div class="relative">
<input type="text" placeholder="Suchen..."
class="block w-full border border-gray-300 py-2.5 pr-10 pl-3 font-sans text-sm text-brand-navy placeholder-gray-400 focus:border-brand-navy focus:ring-1 focus:ring-brand-navy focus:outline-none" />
<div class="pointer-events-none absolute inset-y-0 right-0 flex items-center pr-3">
<img src="/degruyter-icons/Simple/Medium-24px/SVG/Action/Mag-Glass-MD.svg"
alt="" aria-hidden="true" class="w-4 h-4 opacity-40" />
</div>
</div>
Status badges
<!-- Mint (uploaded/active) -->
<span class="inline-flex items-center rounded-full border border-brand-mint/50 bg-brand-mint/20 text-brand-navy px-2.5 py-0.5 text-[10px] font-bold tracking-wide uppercase font-sans">
UPLOADED
</span>
<!-- Yellow (placeholder/pending) -->
<span class="inline-flex items-center rounded-full border border-yellow-200 bg-yellow-50 text-yellow-700 px-2.5 py-0.5 text-[10px] font-bold tracking-wide uppercase font-sans">
PLACEHOLDER
</span>
Tag chips
<button class="inline-flex items-center rounded bg-brand-sand/30 px-2 py-1 text-[10px] font-bold tracking-widest text-brand-navy uppercase font-sans transition-colors hover:bg-brand-navy hover:text-white">
Schlagwort
</button>
Back link
<a href="/persons" class="inline-flex items-center text-xs font-bold uppercase tracking-widest text-gray-500 hover:text-brand-navy transition-colors group mb-4 font-sans">
<img src="/degruyter-icons/Simple/Medium-24px/SVG/Action/Arrow/Arrow-Left-MD.svg"
alt="" aria-hidden="true"
class="w-4 h-4 mr-2 opacity-40 group-hover:opacity-100 transition-opacity" />
Zurück zur Übersicht
</a>
Subtle "new item" link
<a href="/documents/new" class="inline-flex items-center gap-1 text-sm font-medium text-brand-navy/60 hover:text-brand-navy transition-colors font-sans">
<img src="/degruyter-icons/Simple/Medium-24px/SVG/Action/Add/Add-General-MD.svg"
alt="" aria-hidden="true" class="w-4 h-4 opacity-60" />
Neues Dokument
</a>
Empty state
<div class="p-16 text-center">
<div class="mx-auto mb-4 w-16 h-16 flex items-center justify-center">
<img src="/degruyter-icons/Simple/Large-32px/SVG/Action/Mag-Glass-LG.svg"
alt="" aria-hidden="true" class="w-10 h-10 opacity-20" />
</div>
<h3 class="font-serif text-lg font-medium text-brand-navy">Keine Dokumente gefunden</h3>
<p class="mt-1 font-sans text-sm text-gray-500">Versuchen Sie, die Filter anzupassen.</p>
</div>
Nav active state
Current page nav link:
class="text-brand-navy bg-brand-purple/15 rounded"
Inactive nav link:
class="text-gray-500 hover:text-brand-navy hover:bg-brand-sand/60 rounded"
Both share the base: inline-flex items-center px-3 py-1.5 text-xs font-bold uppercase tracking-widest font-sans transition-colors
Save bar (long forms)
Sticky full-bleed (document edit):
<div class="sticky bottom-0 z-10 -mx-4 px-6 py-4 bg-white border-t border-brand-sand shadow-[0_-2px_8px_rgba(0,0,0,0.06)] flex items-center justify-between">
<a href="..." class="text-xs font-bold uppercase tracking-widest text-gray-500 hover:text-brand-navy font-sans transition-colors">
Abbrechen
</a>
<button type="submit" class="bg-brand-navy text-white px-6 py-2.5 text-xs font-bold uppercase tracking-widest font-sans hover:bg-brand-navy/90 transition-colors">
Speichern
</button>
</div>
Card-style (short forms):
<div class="mt-4 flex items-center justify-between rounded-sm border border-brand-sand bg-white px-6 py-4 shadow-sm">
Do / Don't
| Do | Don't |
|---|---|
Use font-sans for all UI labels, buttons, nav |
Use font-serif for buttons or labels |
Use uppercase tracking-widest for labels |
Use sentence case for field labels |
Use brand-navy for primary actions |
Use brand-mint as primary action color |
Use opacity-* to create icon tints |
Change icon fill color inline |
Use invert class on icons inside bg-brand-navy buttons |
Use colored icon files for button icons |
Use rounded-sm for cards and buttons (subtle) |
Use rounded-full for non-pill elements |
Use shadow-sm for card elevation |
Use large shadows |
Keep borders border-gray-100 or border-brand-sand |
Use dark borders |