md-bridge design thinking · v0.1
design doc

Same logic.
More bridges.

A design-thinking base for the next round of md-bridge features — built on the editorial system that already ships, ready to be sliced into community-friendly GitHub issues.

00 · Read me first

Five rules every new feature must respect.

These are not opinions — they're what makes md-bridge md-bridge. Any contribution that breaks one is a different product, not a feature.

1 · Deterministic

Same input, same output, every run. No AI in the conversion pipeline — pure heuristics. Features can help the user choose, but the conversion itself stays reproducible.

2 · Local-first

No external API calls during conversion. Temp files removed before the response goes out. Anything new that needs the network has to be opt-in and explicit.

3 · No persistence

No accounts, no database, no telemetry. User state lives in localStorage or the URL — that's the only memory we're allowed.

4 · Heuristic-first

Every new format pair (DOCX, EPUB, RTF) follows the same vendored-skill pattern under packages/. The route layer stays thin.

5 · Editorial UI

Fraunces + IBM Plex. Cream + ink + a single red accent. No purple gradients, no Inter, no glassy cards. Hierarchy over decoration.

→ Use this doc as a base

Every section below pairs a hi-fi mock (cream/red, same components, same logic) with a ready-to-paste GitHub Issue. Hit Copy issue and open it on the repo.

01 · Foundations

What md-bridge already gives us to build on.

The design system lives in apps/web/src/styles/tokens.css (49 lines, 14 variables). Every mock below reuses these exact tokens — no new font, no new color.

Color tokens · 9 ramps

bg#f7f3ec
bg-elev#fdfaf3
ink#1a1a1a
ink-soft#555
rule#d8d2c5
accent#c8362f
accent-soft#f1d8d5
ok#2e7d4a

Type stack · 3 families

--font-display Fraunces — editorial serif
--font-body IBM Plex Sans — humanist sans
--font-mono JetBrains Mono — mono
xs sm md lg xl

modular scale · ratio 1.25

Existing components · reuse don't recreate

  • <DropZone />drag, click, folder walk, MIME validation
  • <Button />primary · ghost · icon · loading
  • <Card />surface · outline
  • <ConvertButton />state machine: idle / loading / ok / error
  • <MarkdownPreview />react-markdown with in-app theme
  • <DiagnosticPanel />fonts, sizes, tagged-PDF, OCR hint
  • <BatchPanel />queue, per-row status, per-row download
  • <Toast />3s auto-hide, accent border-left
  • <Spinner />thin SVG, accent color
  • <LanguageSwitcher />EN / PT / ES, localStorage

Pages today

  • /Hero + two cards
  • /convert/pdf-to-mdDropZone · Diagnostic · BatchPanel · MarkdownPreview
  • /convert/md-to-pdfDropZone · paste textarea · BatchPanel · PDF iframe
  • /aboutnarrative, limits, links

API surface

  • POST /api/pdf-to-mdmultipart · options json
  • POST /api/md-to-pdfmultipart · returns application/pdf
  • POST /api/inspect-pdfdiagnostics for the panel
  • GET /api/healthstatus + version
02 · Roadmap

Eight features. Eight issues. One coherent system.

Ordered by the user's explicit ask first (theme picker, custom CSS, future formats, languages), then by what unlocks the rest. Each card below carries a type, a scope, and a complexity hint so contributors can self-select.

Feature 01

CSS theme picker for Markdown → PDF

user ask MD→PDF good first issue

A gallery sits under the dropzone. Six bundled stylesheets — Default Editorial, Academic, Technical, Minimal, Corporate, Brief. One click = the next render uses that theme.

localhost:5173 / convert / md-to-pdf
md-bridge

Markdown to PDF

Upload a .md or paste text. Pick a theme for the PDF.

Drop Markdown files or a folder or click to pick files
// PDF theme Academic
Default Editorial

A paragraph with body copy in a humanist sans, justified text.

Subheading
  • item one
  • item two
Defaulteditorial
Academic

Abstract. A paragraph with body copy set in a transitional serif.

1. Introduction

Body paragraph two.

Academicserif
TECHNICAL

// monospace body for code-heavy docs

## Section

- item one

- item two

Technicalmono
Minimal

Quiet body type, generous whitespace, no rules.

SUBHEAD

A second paragraph follows.

Minimalsans
Corporate

A paragraph with a slightly more formal body style.

Subheading

Body paragraph two.

Corporatenavy
Brief

A paragraph set in an italic display face for short docs.

Subheading

Body paragraph two.

Briefitalic
Convert with Academic Browse all 12 →

Sample heading

A paragraph with bold and italic text. The right side is the live HTML preview — PDF render uses the selected theme's CSS at @page level.

Subheading

  • item one
  • item two
Feature 02

Theme library — deep picker with code preview

MD→PDF curated help wanted

F1 is the quick gallery on the convert page. F2 is the deep browser — a dedicated /themes route with a curated catalogue of 12+ pre-defined themes, full A4 preview, and the read-only CSS source for transparency. The user picks. They never edit.

localhost:5173 / themes
md-bridge

Theme library

Twelve curated stylesheets for the PDF render. Pick one — we show you exactly what it does.

Filter All 12 Serif 5 Sans 4 Mono 2 Numbered 3 Showing 12 · sorted by name
// catalogue
  • Default Editorial
    serif · A4 · v1
  • Academic
    serif · numbered · selected
  • Technical
    mono · code-friendly
  • Minimal
    sans · quiet
  • Corporate
    serif · navy accent
  • Brief
    italic · short docs
  • Newsroom
    serif · columns
  • Thesis
    serif · double-spaced
  • Whitepaper
    sans · cover page
  • Memo
    sans · letter-size
  • Manuscript
    Courier · industry
  • Notebook
    mono · ruled
// visual preview · Academic A4 · 11pt body · sample.md
A Brief Survey of Markdown to PDF Pipelines
md-bridge documentation team · 20 May 2026
Abstract. We describe the heuristics behind deterministic conversion between PDF and Markdown, with emphasis on stable output across runs.
1. Introduction

A paragraph with bold and italic text. Body copy is set in a transitional serif at 11pt with hanging indents and justified text, in the style of an academic article. Page numbers appear at the bottom centre from page 2 onward.

1.1. Heading detection

Sample paragraph two with longer body text that demonstrates justified line-breaking and hyphenation behaviour configured by this theme’s stylesheet.

  • font size + outline heuristic
  • list recovery
  • table extraction
1 / 12
// source · academic.css read-only · 142 lines
/* academic.css — transitional serif
   numbered headings, justified body */

@page { size: A4; margin: 2.5cm 2cm;
  @bottom-center { content: counter(page)
    " / " counter(pages); }
}

body {
  font-family: "Times New Roman", serif;
  font-size: 11pt;
  line-height: 1.55;
  text-align: justify;
  hyphens: auto;
}

h1 { text-align: center; font-size: 18pt; }
h2 { font-style: italic;
  counter-reset: subsec;
  counter-increment: sec; }
h2::before { content: counter(sec) ". "; }
h3::before { content: counter(sec)
  "." counter(subsec) ". "; }

/* … 124 more lines */
Use Academic Download .css Try sample render
Last updated v0.4.1 · 12 Mar 2026
Author md-bridge core · License MIT
Feature 03

Per-conversion options panel

MD→PDF PDF→MD good first issue

An Options panel folds open above the convert button. Today it holds page-size, margins, TOC, page numbers, header text. Tomorrow it's where every new option lives so the right column doesn't grow forever.

localhost:5173 / convert / md-to-pdf
md-bridge
Drop Markdown files or click to pick
// PDF options 5 set · 0 default
Page size
A4LetterLegal
Margins
TightNormalLoose
Table of contents
Generate from headings
Page numbers
Footer · centred
Header text

Tokens: {{ title }} · {{ author }} · {{ date }} · {{ page }} / {{ pages }}

Include YAML front matter Page break before each H1
Convert all (3) Save as preset → Options apply to this batch
// preview A4 · loose
syllabus · md-bridge
Sample heading

A paragraph with bold and italic text. Headers and footers pick up the live tokens above. TOC will go before the first H1 when enabled.

Subheading
  • item one
  • item two
1 / 1
Feature 04

Format hub — DOCX, EPUB, HTML, RTF

user ask platform help wanted

Two conversion pairs today; six tomorrow. The Home page becomes a matrix — columns are output, rows are input. Filled cells route to /convert/X-to-Y. Empty cells say «wanted — open an issue».

localhost:5173 /
md-bridge

Convert documents locally.

Same deterministic heuristics. More format pairs.

From   ↓   to → PDF Markdown DOCX EPUB HTML RTF
PDF SHIPPED wanted v0.3 in PR #142 wanted
Markdown SHIPPED v0.2 · this issue v0.3 v0.2 wanted
DOCX wanted v0.3 wanted wanted wanted

SHIPPED in PR on roadmap community wanted — clicking opens a GitHub issue template pre-filled with the pair.

2shipped today
3on roadmap
7community wanted
0cloud calls
Feature 05

Language workshop — contribute a locale from the UI

user ask i18n good first issue

A new page at /contribute/i18n lists every locale, shows untranslated keys against the EN reference, and exports a draft dictionaries.ts diff. Translators get a real workflow; maintainers get clean PRs.

localhost:5173 / contribute / i18n
md-bridge

Language workshop

Pick a locale, fill in the missing keys, export the diff. Open the PR with one paste.

Englishen
128 / 128 · source
Portuguêspt
128 / 128 · complete
Españoles
123 / 128 · 5 missing
Françaisfr · in progress
49 / 128 · 79 missing
+ Start a new locale: Create draft PR template + dictionary stub will be downloaded
// editing · français (fr) · 5 of 79 shown 38% complete
key english (source) français · your draft
home.title Convert PDF and Markdown locally.
pdfToMd.title PDF to Markdown
batch.convertAll Convert all
dropzone.orClickMany or click to pick files
about.title About md-bridge
Export PR-ready diff (.patch) Copy as JSON Draft kept in localStorage · md-bridge:i18n-draft:fr
Feature 06

Conversion presets

UX power user

Once F1–F3 land there are a dozen knobs per conversion. A preset bundles them with a name. The dropzone toolbar gets a chip-style selector. Stored locally — no backend, no account.

localhost:5173 / convert / md-to-pdf
md-bridge

Markdown to PDF

Preset Internal briefs A4 · brief · TOC Acme corporate Letter · acme Lecture notes academic · numbered + Save current as preset 3 saved · max 12
Drop Markdown files preset «Internal briefs» will be applied
// active preset · Internal briefs Edit →
Theme
Brief (italic display)
Page
A4 · normal margins
TOC
Yes — H1+H2
Page numbers
Centred footer
Header
{{ title }} · Internal
Front matter
Hidden
// new preset

Name it. Tag it. It's yours — lives in this browser only.

Save preset Export as JSON
Feature 07

Local conversion history

UX local-only good first issue

Closing the tab today loses the result blob. A modest local history (just names, sizes, settings, and blob URLs while alive) lets users re-download or re-run the same input. No server, no privacy regression.

localhost:5173 / convert / pdf-to-md
md-bridge

PDF to Markdown

Upload a PDF and extract its content as structured Markdown.

Drop PDF files or a folder or click to pick files
// recent · this browser only · 24h 5 of 5 · Clear all
  • ddp-factsheet-en.pdf 2.3 MB · 12 pages · default theme · 4 m ago
    done Re-download .md Re-run
  • cpre_foundationlevel_syllabus_br_v3.2.2.pdf 8.7 MB · 89 pages · default · 22 m ago
    done Re-download .md Re-run
  • scanned-receipt.pdf needs_ocr · 1.1 MB · 31 m ago
    warn Re-download .md Re-run
  • notes.md → PDF 9 KB · academic theme · 2 h ago
    done Re-download .pdf Re-run
  • handbook.pdf 3.4 MB · 56 pages · 20 h ago · result expired
    expired Re-run

History lives in this browser, not on the server. Results are kept as blob URLs while the tab is open. After 24h the entry remains but the result is «expired» — re-run to regenerate.

Selected entry · preview

Click any history row to load its result back into the preview pane on the right.

Blob URLs survive until the tab closes. Nothing here is sent anywhere — clearing browser data clears the history.

Feature 08

Preferences page

settings polish

Once a dozen preferences live in localStorage, they need a home. /preferences is that home — one column, sectioned, no surprises. Every setting links back to the feature it belongs to.

localhost:5173 / preferences
md-bridge

Preferences

Per-browser. Nothing leaves this device.

// defaults

Default language

Falls back if browser locale is unsupported.

ENPTES
Default PDF theme

Applied to every new MD→PDF batch. F1 →

academic ▾
Default page size

A4 outside the US, Letter inside.

A4LetterLegal
Open PDF preview in new tab

Off → inline iframe (current behaviour).

On

// UI

Accent colour

Brand red by default. Choose any HSL.

Reduce motion

Skip fades and transitions. Auto-on if your OS asks.

Off

// privacy

No telemetry. No cookies. No accounts.

Verified at build by scripts/audit-deps.py. View report →

Reset all preferences Export as JSON
03 · Appendix

Issue hygiene — how to file these as a maintainer.

Short checklist to keep this batch of issues tidy as community PRs land. Reuses the existing labels and templates.

1 · One issue per F-number

Paste the markdown card into .github/ISSUE_TEMPLATE/feature_request.md. Title prefix matches the bracket convention already in use (e.g. [feature], [i18n], [platform]).

2 · Link the doc

Every issue body links back to this file under docs/design/Design Thinking.html. That way a contributor can see the mock and the rationale before writing a line of code.

3 · Suggested order

F3 (Options) → F1 (Themes) → F2 (Custom CSS) → F6 (Presets) → F7 (History) → F8 (Prefs) → F4 (Formats) → F5 (i18n).

Front-load the dependency root (Options panel) so everything else has somewhere to attach.

4 · Labels we're reusing

enhancement good first issue help wanted i18n

No new labels invented. Sticking with the GitHub defaults + the i18n one you already use.

Next steps

  1. Save this file at docs/design/Design Thinking.html in the repo (or wherever you keep design docs).
  2. Open 8 issues on vinicq/md-bridge using the «Copy issue» buttons.
  3. Add a short paragraph to CONTRIBUTING.md pointing newcomers at this doc as the «start here» map.
  4. Tag the F1, F4, and F5 issues as «Hacktoberfest»-friendly when next October rolls around.