Gå till innehållet

08 – MkDocs Design Guide

How a MkDocs site, its interactive app pages and its app icon look and behave: colours, typography, spacing, components, drawings, printing and the web app (PWA) setup. It is not tied to one product. Use this file as the single reference when you build a new MkDocs site or app that must look and behave the same.

Note for this repository (Receptsamling). This is a copy of design-guide.md from the Workshop repository (mkdocs/docs/design-guide.md), which in turn is a copy of the Load_Cell guide. Here the app icon and the header logo are a plate with fork and knife (overrides/.icons/recept/plate.svg, master docs/assets/icons/icon.svg) instead of the tap glyph. The site language is Swedish (language: sv); everything else is followed as written. The scan page (docs/03-scan.md) uses the app page components of section 6.4: 46 px buttons, 44 px fields, 12 px cards and the glowing edge in dark mode.

Source of truth: every value below was read from the files of the reference site. The file that defines each value is named in the "Source" column or the line under each heading. Where a value is not defined there, it is marked not defined and listed in Open points.


1. Design principles

These follow from how the reference site is built.

Principle How it shows in the code
One brand colour (teal) with one warm accent primary: teal, accent: deep orange in mkdocs.yml; app pages use --accent teal
Light and dark mode everywhere Two palettes in mkdocs.yml; prefers-color-scheme in app.css; [data-md-color-scheme="slate"] in explorer.css
Phone first, large touch targets Buttons min-height: 46px, inputs min-height: 44px, tab buttons ≥ 2.6 rem
Rounded, card based layout border-radius: 12px on cards, figures, frames and tiles
Colour carries meaning, never alone Status (pass / fail / warning) always have a text label or chip as well as a colour
Works offline and installs as an app PWA manifest, service worker, icons (section 9)

2. MkDocs setup (mkdocs.yml)

Setting Value
Theme material (MkDocs Material)
Custom theme folder overrides/
Language en
Logo icon loadcell/load-cell (custom icon in overrides/.icons/loadcell/load-cell.svg)
Favicon assets/icons/icon-192.png
Extra CSS assets/extra.css, assets/explorer.css
Extra JavaScript assets/pwa.js
Hook hooks/pwa.py (fills in the service worker after every build)

Palette

palette:
  - media: "(prefers-color-scheme: light)"
    scheme: default
    primary: teal
    accent: deep orange
    toggle:
      icon: material/weather-night
      name: Switch to dark mode
  - media: "(prefers-color-scheme: dark)"
    scheme: slate
    primary: teal
    accent: deep orange
    toggle:
      icon: material/weather-sunny
      name: Switch to light mode

Theme features

navigation.tabs, navigation.sections, navigation.top, navigation.footer, navigation.indexes, toc.follow, search.suggest, search.highlight, content.tabs.link

Markdown extensions

admonition, attr_list, md_in_html, tables, toc (with permalink: true), pymdownx.details, pymdownx.highlight, pymdownx.inlinehilite, pymdownx.keys, pymdownx.tasklist (custom_checkbox: true), pymdownx.tabbed (alternate_style: true), pymdownx.emoji (Material Twemoji, SVG output), pymdownx.superfences (with a mermaid custom fence).


3. Colours

3.1 Brand colours

Role Light Dark Source
Site primary #00897b (light #4db6ac, dark #00695c) same mkdocs.yml (primary: teal) with own values in docs/assets/extra.css
Site accent #d84315 #ffab76 mkdocs.yml (accent: deep orange) with own values in docs/assets/extra.css
Web app theme colour #00897b – docs/manifest.webmanifest, overrides/main.html, app pages
Web app background colour #ffffff – docs/manifest.webmanifest
App icon background #00897b – docs/assets/icons/icon.svg
App icon glyph #ffffff – docs/assets/icons/icon.svg
App page accent #00897b #26a69a docs/app/app.css
App page theme-color meta #00897b – docs/app/index.html, docs/app/pd.html
Interactive page accent #00897b #4db6ac docs/assets/explorer.css

One brand teal

#00897b is the only teal (decision DS-001). The icon, manifest, site, app pages and interactive pages all use it. The site primary and accent are set with own hex values in docs/assets/extra.css (DS-002), not the theme defaults. Copy that block into every new MkDocs site.

3.2 Dark mode surfaces (decision DS-006)

The dark scheme (slate) is near black with clear white text. Light mode is unchanged. All values are set in the [data-md-color-scheme="slate"] block at the end of docs/assets/extra.css; the page CSS files (viewer.css, lasermark.css) use the same values.

Surface Value Variable
Page background #0b0b0a --md-default-bg-color
Cards, code #141413 --md-code-bg-color, --tv-card, --lm-bg
Text and number fields #2c2c2a (lighter than the card around them) [data-md-color-scheme="slate"] input, select in extra.css
Chips, soft fills #1e1e1c --tv-soft, --lm-soft
Footer #050505 --md-footer-bg-color
Dividers and table rules #2b2b29 --md-default-fg-color--lightest, --tv-sep
Text and numbers #faf9f5 (clear white, no light grey) --md-default-fg-color, --md-typeset-color
Secondary text #c2c0b6 --md-default-fg-color--lighter
Links #4db6ac --md-typeset-a-color

3.3 Glowing edge on cards and boxes (decision DS-007)

In dark mode every card, filter box, form group, preview area and input has a 1 px edge in the header teal #00897b with a glow. The glow is strongest on the line and fades both outwards and inwards, like a lit tube.

Part Rule
Large boxes (--ws-glow) Outer: 0 0 3px at 90 %, 0 0 9px at 45 %, 0 0 20px at 20 %. Inner: inset 0 0 3px at 80 %, inset 0 0 9px at 35 %, inset 0 0 18px at 14 %. Colour rgb(0 137 123)
Buttons, chips, inputs (--ws-glow-soft) Same colour, weaker: 0 0 3px at 70 %, 0 0 8px at 30 %, and the same inside
Not glowing Dividers inside a card, table rows and list separators (--tv-sep, #2b2b29)

3.4 Orange for names, white for values (decision DS-008)

Anything that names a thing is orange; anything that is a value stays white. The orange is the site accent from 3.1 (#d84315 light, #ffab76 dark).

Orange (name) White (value)
Page headings h1 to h4, tool titles such as M2x0.4, card titles on Home Text the user types or selects
Field labels (ID number, Date, filter names), group titles (Card data, Filters) Numbers and text in spec tables (2.5 mm, DIN 338)
Spec table names (Diameter Ø, Brand), card bar titles (Drawing, Specification, 3D model) Option texts (Single card, Batch, Show logo)

The large Workshop title on the green Home banner stays white, because orange has too little contrast on green.


4. Typography

Context Font Size and weight Source
Site (MkDocs Material) Roboto (text), Roboto Mono (code) Theme default sizes mkdocs.yml (theme.font)
App pages system-ui, -apple-system, "Segoe UI", Roboto, Helvetica, Arial, sans-serif 16px/1.45 app.css
SVG text in symbols var(--md-text-font-family, system-ui, sans-serif) 10 px, weight 600 extra.css
Numbers in tables and results font-variant-numeric: tabular-nums – app.css, explorer.css

App page sizes:

Element Size
h2 1.15rem
h3 1rem
Brand name in header 1.1rem, weight 700
Key-number value (.kv b) 1.3rem
Banner 1.1rem, weight 700
Small text, table header .8rem

Interactive page sizes: h2 1.5rem (1.25rem on phones), control label .7rem uppercase with letter-spacing: .06em, tag .6rem uppercase.


5. Layout and spacing

Item Value Source
App page content width max-width: 980px, centred app.css
App page gap between cards 1rem app.css
Card padding 1rem (.85rem under 520 px) app.css
Card border: 1px solid var(--line), border-radius: 12px, background var(--card) app.css
Card grid repeat(auto-fit, minmax(190px, 1fr)), gap .75rem app.css
Key-number tiles repeat(auto-fit, minmax(150px, 1fr)), gap .6rem app.css
Interactive value cards repeat(auto-fit, minmax(300px, 1fr)), gap .9rem explorer.css
Symbol grid repeat(auto-fill, minmax(250px, 1fr)), gap .9rem extra.css
Phone breakpoint (app page) max-width: 520px app.css
Phone breakpoint (site pages) max-width: 44.984em extra.css, explorer.css
Safe areas env(safe-area-inset-top) and env(safe-area-inset-bottom) app.css

5.1 Responsive rules (phone portrait and desktop landscape)

Every page must work on a phone held upright (360–430 px wide) without sideways scrolling, and must use the full screen width on a desktop in landscape. This site implements it in extra.css and tables.js (in overrides/assets/).

Situation Rule
Phone, page margin .5rem (10 px) on each side instead of Material's .8rem; full-bleed blocks (code, tab labels) use the same value as negative margin; table cards run to the content edge with no extra padding
Phone, page width No page element is wider than the screen; images, SVG and video use max-width: 100%; long words, paths and identifiers wrap (overflow-wrap: anywhere)
Phone, tables Each row becomes a card with 12px radius: first cell is the card title (grey fill, bold), every other cell shows its column heading as a small uppercase label above the value. tables.js adds data-label and data-stacked to each table; without JavaScript the table scrolls sideways as a fallback
Phone, code Code blocks wrap (white-space: pre-wrap) instead of scrolling
Phone breakpoint max-width: 44.984em (the Material phone breakpoint), as in section 5
Desktop, from 76.25em .md-grid has no maximum width: header, tabs, navigation, content and table of contents use the whole screen; tables fill the content column
Wide pictures A picture that carries a lot of detail may grow to min(100%, 1200px)
Check Open every page at 360 and 390 px (portrait) and at 1920 px (landscape); document.documentElement.scrollWidth must equal the window width, and no element inside the content may scroll sideways

6. Components

6.1 Site components (MkDocs)

Component How to build it
Landing cards <div class="grid cards" markdown> with a Material icon, bold title, --- rule, text and an arrow link (:octicons-arrow-right-24:)
"At a glance" tiles <div class="grid cards glance" markdown>; value in <strong class="big"> (1.6rem, 1.2rem on phones; two tiles per row on phones)
Figure { .rig }: full width, max-width: 960px, centred, border-radius: 12px
Mermaid diagram Fenced mermaid block; centred, scrolls sideways on phones
Step number in tables First column in bold; does not wrap
Embedded app page .logger-frame: 80vh high, min-height: 560px, 1 px border in --md-default-fg-color--lightest, 12px radius
Symbol card .sym with an SVG and a figcaption (bold title, text, italic i line for the source)
Note flag .flag: boxed bold number, 2px border, 3px radius
Home button in the header Home icon next to the palette toggle and search (overrides/partials/header.html, class .ws-home-btn, 44 px touch target); goes to the start page without opening the menu (DS-009)
Page icon The whole Home card picture (16:10, not cropped) as a rounded icon (docs/assets/home/icon-*.webp, 320 × 200 px) in front of the page title (112 × 70 px, 80 × 50 px on phones) and in the menu (76 × 48 px, teal 1px border). All pictures have the same light background. Side menu and drawer also show the page description from the Home card under the title; the top tabs show a 40 × 25 px icon only. Added by docs/assets/nav-icons.js (DS-011)
Primary action button Solid accent fill with dark text (#00897b light, #4db6ac dark). Used for Download SVG on every page and for Send by email in the laser card generator, so the two main actions look the same (DS-010)

6.2 Admonitions (coloured boxes)

Defined in docs/guides/index.md. Use these meanings consistently.

Type Title Meaning
!!! abstract "In one sentence" Summary at the top of a guide
!!! info "Why?" Reason behind a step
!!! danger "Stop" Do not continue; something is wrong or unsafe
!!! tip "Tip" Practical trick
!!! note "Internal proposal" Our interpretation where the specification is silent; must link to an open-points ID
!!! warning "Open points" Known gaps; link to the open-points list

6.3 Standard guide layout

Every step-by-step guide page uses the same nine sections (from docs/guides/index.md of the reference site):

  1. At a glance
  2. What does it show?
  3. The setup
  4. Values per variant (one tab per variant)
  5. The whole procedure as a flow chart
  6. Step by step (tick-boxes, with "why" and "stop" boxes)
  7. Pass or fail?
  8. Common mistakes
  9. Open points

6.4 App page components (docs/app/app.css)

Component Class Style
Header bar .top Background --accent, text --accent-ink, padding .7rem 1rem plus top safe area
Warning bar .warn-bar --warn-bg / --warn
Tabs .tabs button Sticky; top corners rounded; active tab (aria-current="page") is --accent
Card .card See section 5
Primary button button.btn --accent fill, 10px radius, min-height: 46px, weight 600
Secondary button button.btn.secondary Transparent, --accent text and border
Danger button button.btn.danger Transparent, --fail text and border
Small button button.btn.small min-height: 36px
Input, select, textarea – --bg fill, 1px --line border, 8px radius, min-height: 44px
Focus ring :focus-visible 3px solid var(--accent), offset 1px
Key-number tile .kv > div --accent-soft fill, 10px radius; value bold 1.3rem, label .8rem muted
Note .note 4px left border and soft fill; variants .warn, .bad, .ok
Verdict chip .chip Pill (999px), .8rem bold; variants .PASS, .FAIL, .IN_PROGRESS, .NOT_STARTED, .NOT_REQUIRED (dashed border, no fill)
Verdict banner .banner 12px radius, 1.1rem bold; same variants as chips
Progress bar .progress 8px high, --line track, fill uses currentColor
Picker buttons .pairs button, .seg button 2px border, 10px radius, min-height: 56px; selected (aria-pressed="true") uses --accent border and --accent-soft fill
Checklist .steps 24 px checkbox with accent-color: var(--accent); ticked rows turn muted with strike-through
Toggle (fault flag) .toggles label 2px border; checked state uses --fail border, fill and text
Table table .92rem; header .8rem muted; numbers right-aligned; row states .invalid (warn) and .failed (fail)
Toast #toast Fixed at the bottom centre, --ink fill, 10px radius; .bad variant uses --fail
Photo slot .phslot, .ph 10px radius; thumbnails 56 × 56 px, 8px radius
Chart svg.chart Full width, --bg fill, 8px radius, 11px muted axis text

6.5 Interactive page components (docs/assets/explorer.css)

Component Class Style
Segmented control .ux-seg 1.5px accent border, 10px radius; selected button (.on) is solid accent
Tabs .ux-tabs 2px bottom line; selected tab has a 3px accent underline and soft fill
Key chips .ux-keys li Pill with --ux-soft fill, .8rem
Value card .ux-card 12px radius, 1px line; title .95rem in accent
Source tag .ux-tag spec = accent, int = orange (internal proposal), ref = grey
Player controls .ux-ctl Buttons with 1.5px accent border; play button solid accent, min width 7.5rem
Progress bar .ux-bar2 6px high
"Now" box .ux-now 4px accent left border, soft fill
Step chips ol.ux-steps Done = accent border; current = solid accent
Verdict list .ux-verdicts li ok = accent border and soft fill; bad = red border

7. Drawings and diagrams

Rule Value Source
Line style fill: none, round caps and joins; stroke currentColor extra.css
Stroke widths normal 2, thin 1.2, thick 3.2 (symbols); 2.5 for set-up parts extra.css, explorer.css
Hidden / auxiliary line dashed 5 3; centre line 12 3 2 3 extra.css
Main line var(--md-primary-fg-color), width 5 (7 in wide drawings) extra.css
Main line in interactive set-up --ux-pipe, width 9 explorer.css
Dimension lines and values --ux-orange, 1.6 stroke explorer.css
Limits --ux-red, dashed 5 4 explorer.css
Data series A = accent (solid); B = orange (dashed 6 3); tare = muted (dashed 3 3) explorer.css
Backgrounds Symbol drawings sit on var(--md-code-bg-color); set-up drawings on var(--md-default-bg-color) extra.css, explorer.css
Colours in SVG Always CSS variables so light and dark mode both work –

8. Printing

From app.css: on print the page is white with black text; only the #printArea is shown; headings 16pt / 13pt; tables 9.5pt with 1px #999 borders; chips are black outline only; each run avoids page breaks (break-inside: avoid).


9. App icon and web app (PWA)

9.1 Icon

Item Value
Master file docs/assets/icons/icon.svg (viewBox="0 0 512 512")
Background Rounded square, rx="96", fill #00897b
Glyph Load cell: a load arrow on a column cell with three bore holes and a base plate, white #ffffff, fill-rule="evenodd", transform="translate(96 96) scale(13.3333)" (glyph is 320 × 320 px, centred)
Glyph licence Own drawing for this project, no third-party licence
Same glyph in the site header theme.icon.logo: loadcell/load-cell (same path in overrides/.icons/loadcell/load-cell.svg)

Glyph path (24 × 24 grid), copy as is when you make a new icon in another colour:

M11 1.5h2V6h2.4L12 9.8 8.6 6H11zM9 11h6v1.6H9zM5.5 13h13a1 1 0 0 1 1 1v4a1 1 0 0 1-1 1h-13a1 1 0 0 1-1-1v-4a1 1 0 0 1 1-1zM12 14.4a1.6 1.6 0 1 0 0 3.2 1.6 1.6 0 1 0 0-3.2zM7.6 15.1a.9.9 0 1 0 0 1.8.9.9 0 1 0 0-1.8zM16.4 15.1a.9.9 0 1 0 0 1.8.9.9 0 1 0 0-1.8zM3 19.8h18V22H3z

9.2 Icon files

File Size Format Use
icon.svg any SVG Manifest (purpose: any)
icon-192.png 192 × 192 PNG, RGBA Favicon, manifest, shortcuts
icon-512.png 512 × 512 PNG, RGBA Manifest (purpose: any)
icon-maskable-512.png 512 × 512 PNG, RGB Manifest (purpose: maskable): full-bleed teal square with the white glyph in the centre
apple-touch-icon.png 180 × 180 PNG, RGB iOS home screen

9.3 Manifest (docs/manifest.webmanifest)

Field Value
name Full site name (here: Load Cell)
short_name Short name for the home screen (here: Load Cell)
display standalone
orientation any
theme_color #00897b
background_color #ffffff
start_url, scope, id ./
lang, dir en, ltr
categories productivity, utilities
shortcuts One per app page or key page (here: the user manual and the open items), each with icon-192.png

9.4 Page head for an installable page

From overrides/main.html (site) and docs/app/index.html (app page):

<link rel="manifest" href="manifest.webmanifest">
<meta name="theme-color" content="#00897b">
<link rel="apple-touch-icon" href="assets/icons/apple-touch-icon.png">
<meta name="apple-mobile-web-app-capable" content="yes">
<meta name="mobile-web-app-capable" content="yes">
<meta name="apple-mobile-web-app-title" content="<short name>">
<meta name="apple-mobile-web-app-status-bar-style" content="default">

In overrides/main.html the links use {{ '...' | url }}; the app pages also set <meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover"> and <meta name="color-scheme" content="light dark">.

9.5 Offline behaviour

  • docs/assets/pwa.js registers sw.js from the site root (found from the script's own address).
  • docs/sw.js is network first; the cached copy is used only when offline.
  • hooks/pwa.py writes the list of all built files (skips sw.js, sitemap.xml, sitemap.xml.gz and files over 5 MB) and a content hash into sw.js after every build.

10. Checklist for a new MkDocs site

  1. Copy mkdocs.yml and change only site_name, site_description, repo_name, repo_url and nav.
  2. Keep the theme, palette, features and markdown_extensions blocks unchanged.
  3. Copy docs/assets/extra.css (and explorer.css if interactive pages are needed).
  4. Copy overrides/main.html, overrides/partials/header.html (Home button), hooks/pwa.py, docs/assets/pwa.js, docs/sw.js and docs/manifest.webmanifest; update the names in the manifest and the apple-mobile-web-app-title.
  5. Copy docs/assets/icons/ or generate a new icon from section 9.1 (same size, corner radius, glyph scale and colours).
  6. Copy requirements.txt and .github/workflows/site.yml if the site is built the same way.
  7. Write pages with the layout in 6.3 and the admonition meanings in 6.2.
  8. Check light and dark mode, a 360 px wide phone, and print preview.

Open points

None. Design decisions DS-001 to DS-005 were decided 2026-10-16 and DS-006 to DS-011 on 2026-10-18; all are closed.