Klarbild-Design, neues Logo, Ein-Klick-Einfügen, mobil überarbeitet, Spenden-Knopf

- Design auf Klarbild-Tokens umgestellt: Space Grotesk/Mono, Papier/Karte, Blau, Pills
- Neues Logo und App-Icon: Klemmbrett mit Pfeil (Zwischenablage -> Datei)
- Einfügen-Knopf liest die Zwischenablage direkt (HTML bevorzugt), Fallback-Hinweis
- Mobil: 44px-Ziele, 16px-Eingaben, Safe-Area, Bottom-Sheet, Datei öffnen, Speichern per Teilen-Menü
- Spenden-Knopf (PayPal) in Kopfzeile, Fußzeile und Rechtstexten; Datenschutz um PayPal und Zwischenablage ergänzt
- Service Worker: Seiten network-first (Impressum/Datenschutz froren im Cache ein), Cache v4
- nginx: no-cache für Seiten
- Listen mit einem Leerzeichen nach dem Aufzählungszeichen
This commit is contained in:
till committed 2026-09-16 12:21:06 +02:00
1 parent da781d9991
commit fe9401c38f
22 files changed
+877 -604

No files matched your search

+9 -47
View File
@@ -1,51 +1,13 @@
# clip2md — Design System # clip2md — Design System
Register: **product**. Color strategy: **Restrained** (tinted neutrals + one accent ≤10%). Seit September 2026 Teil der **Klarbild-Familie** (Tokens aus `klarbild-oss/src/styles/tokens.css`).
Theme: **dark**. Scene: Nutzer legt spätabends oder tagsüber am Monitor schnell einen langen
Thread ab; eine ruhige, dunkle, blendfreie Fläche hält den Fokus auf dem Text, nicht auf dem UI.
## Color (OKLCH) - **Farbe:** warmes Papier `#EAEAE3`, Karte `#FBFBF7`, Linie `#D7D6CC`, Tinte `#16150F`, ein kräftiges Blau `#1B3BE0` (OKLCH 45% 0.23 267) für Primäraktion, Fokus, Logo. Dunkelmodus: blau getönte Neutrals, Blau aufgehellt.
- **Schrift:** Space Grotesk (UI, Überschriften), Space Mono (Editor, Dateiname, Mono-Labels in Versalien mit 0.18em Sperrung). Self-hosted, keine Google-Fonts.
- **Form:** Karten mit 4px Radius, Bedienelemente als Pills (999px). Kein Schatten außer 1px-Hauch und Toast/Sheet.
- **Logo:** Klemmbrett mit Pfeil nach unten (Zwischenablage → Datei) in Blau, Wortmarke „clip**2**md" mit blauer 2. App-Icon: cremefarbenes Klemmbrett auf blauem Quadrat.
- **Mobil:** Touch-Ziele ≥44px, Eingaben 16px (kein iOS-Zoom), `env(safe-area-inset-*)`, Einstellungen als Bottom-Sheet, Aktionsleiste als 5er-Raster mit Icon über Label, Speichern über Teilen-Menü.
- **Motion:** ease-out-quint, 120–240ms, nur Opacity/Transform; `prefers-reduced-motion` respektiert.
Neutrals sind zur Marken-Hue (kühles Blau-Grau, ~265) getönt — nie reines `#000`/`#fff`. ## Historie
Vorher: dunkles Theme mit Grün (v1), dann helles Editorial mit Geist und Zinnober/Blau (v2). Beides abgelöst.
| Token | OKLCH | Rolle |
| --- | --- | --- |
| `--bg` | `0.17 0.014 265` | App-Hintergrund (tief) |
| `--surface` | `0.215 0.016 265` | Editor-Fläche |
| `--raised` | `0.255 0.018 265` | Bars, Buttons |
| `--line` | `0.32 0.02 265` | Ruhige Rahmen |
| `--line-strong`| `0.42 0.024 265` | Aktive Rahmen |
| `--text` | `0.95 0.006 265` | Primärtext |
| `--muted` | `0.68 0.012 265` | Sekundärtext, Labels |
| `--faint` | `0.5 0.012 265` | Tertiär, Legende |
| `--accent` | `0.74 0.15 152` | Grün — Primäraktion, Fokus, „konvertiert" |
| `--accent-ink` | `0.22 0.05 152` | Text auf Accent |
| `--danger` | `0.66 0.16 25` | Fehler-Toast, destruktiv |
Accent trägt <10% der Fläche: Save-Button, Fokus-Ring, „konvertiert"-Badge. Sonst Neutrals.
## Typography
- **Sans (UI-Chrome):** Inter / system-ui. Labels, Buttons, Legende.
- **Mono (Daten):** ui-monospace / JetBrains Mono. Editor, Dateiname, Zähler — alles, was „Inhalt" ist.
- Scale mit ≥1.25-Kontrast: 11 (legende) · 12.5 (meta) · 14 (body/editor) · 15 (buttons) · 18 (wordmark).
- Editor-Zeilenhöhe 1.65, `tab-size: 2`, Body-Zeilen bleiben durch die Mono-Fläche natürlich lesbar.
## Elevation & Layout
- Drei Ebenen: `bg` (App) → `surface` (Editor, das Herzstück, bekommt den Raum) → `raised` (Bars/Buttons).
- Keine Cards, keine Schatten außer einem weichen Toast-Drop. Trennung über 1px-Linien und Ton, nicht Boxen.
- Spacing-Rhythmus variiert bewusst: großzügig um den Editor, kompakt in der Toolbar.
- Radius 10–12px, konsistent.
## Motion
- Ease-out-quint (`cubic-bezier(0.22, 1, 0.36, 1)`), 120–240ms. Kein Bounce.
- Nur Opacity/Transform animieren. Toast slidet ein, Button-Press senkt 1px, „konvertiert"-Badge pulst einmal kurz, auto-aktualisierter Dateiname flasht dezent.
- `prefers-reduced-motion`: alle nicht-essenziellen Transitions aus.
## Accessibility
- `:focus-visible` Ring in Accent, überall. Touch-Ziele ≥40px.
- Toasts über `aria-live="polite"`. Editor & Felder korrekt gelabelt.
- Kontrast: Text/`bg` und Accent-Ink/Accent über WCAG AA.
+19 -8
View File
@@ -1,13 +1,15 @@
# clip2md — Paste to Markdown # clip2md — Paste to Markdown
Paste a long Reddit thread, an article, or any formatted web content, and save it as clean Paste a long Reddit thread, an article, or any formatted web content, and save it as clean
Markdown in a single keystroke. Runs entirely in your browser: nothing is uploaded, no account, Markdown in one click. Works on desktop and phone. Runs entirely in your browser: nothing is uploaded, no account,
no tracking, works offline. no tracking, works offline.
**Live demo:** https://clip2md.heidrich-digital.de **Live demo:** https://clip2md.heidrich-digital.de
![clip2md](docs/screenshot-light.png) ![clip2md](docs/screenshot-light.png)
<img src="docs/screenshot-mobile.png" alt="clip2md on a phone" width="280">
## Why ## Why
Copying from the web and getting usable Markdown is usually two or three tools and a lot of Copying from the web and getting usable Markdown is usually two or three tools and a lot of
@@ -19,6 +21,8 @@ Obsidian vault, a wiki, or a repo.
## Features ## Features
- **One-click paste.** The *Paste* button reads the clipboard directly (Async Clipboard API) and
picks the HTML version when there is one. Browsers ask once for permission; `⌘V` always works too.
- **Smart paste.** Formatted HTML (copy from a browser, e.g. Reddit `⌘A` → `⌘C`) is converted to - **Smart paste.** Formatted HTML (copy from a browser, e.g. Reddit `⌘A` → `⌘C`) is converted to
clean Markdown. Plain text stays raw. Same `⌘V` for both, no mode switch. clean Markdown. Plain text stays raw. Same `⌘V` for both, no mode switch.
- **Force raw.** `⌘/Ctrl+Shift+V` pastes the next clip as plain text, skipping conversion. - **Force raw.** `⌘/Ctrl+Shift+V` pastes the next clip as plain text, skipping conversion.
@@ -29,9 +33,11 @@ Obsidian vault, a wiki, or a repo.
knowledge bases like Obsidian. knowledge bases like Obsidian.
- **Conversion options.** Links as plain text, strip images, bullet marker (`-` / `*` / `+`), - **Conversion options.** Links as plain text, strip images, bullet marker (`-` / `*` / `+`),
heading style (ATX `#` / Setext). heading style (ATX `#` / Setext).
- **Drag & drop.** Drop an `.html`, `.md` or `.txt` file to load or convert it. - **Open & drop files.** Pick or drop an `.html`, `.md` or `.txt` file to load or convert it.
- **Mobile-first.** 44 px touch targets, 16 px inputs (no iOS zoom), safe-area aware, settings as a
bottom sheet; *Save* hands the file to the share sheet (Files, Obsidian, mail) on phones.
- **Bilingual.** English and German, switchable in the header. - **Bilingual.** English and German, switchable in the header.
- **Light & dark.** Warm, flat, editorial light theme by default; dark mode one click away. - **Light & dark.** Warm paper, one strong blue, clipboard logo; dark mode one click away.
- **Save / copy / clear**, word + character count and reading time. - **Save / copy / clear**, word + character count and reading time.
- **Installable PWA**, fully offline after first load. - **Installable PWA**, fully offline after first load.
@@ -49,9 +55,10 @@ construction.
## Tech ## Tech
- Single self-contained `index.html` (inline CSS/JS, OKLCH tokens, Geist + Geist Mono). - Single self-contained `index.html` (inline CSS/JS, OKLCH tokens, Space Grotesk + Space Mono).
- Vendored, no CDN: Turndown + GFM plugin, marked, DOMPurify, fonts — all under `vendor/`. - Vendored, no CDN: Turndown + GFM plugin, marked, DOMPurify, fonts — all under `vendor/`.
- Served by `nginx:alpine` (`Dockerfile` + `nginx.conf`) with a service worker for offline use. - Served by `nginx:alpine` (`Dockerfile` + `nginx.conf`) with a service worker for offline use
(network-first for pages, cache-first for static assets).
- No build step, no backend, no database. - No build step, no backend, no database.
## Run locally ## Run locally
@@ -71,16 +78,20 @@ Any static host works — point it at this repo. The reference deployment uses
## Update vendored libraries ## Update vendored libraries
```bash ```bash
npm pack turndown turndown-plugin-gfm marked dompurify geist npm pack turndown turndown-plugin-gfm marked dompurify @fontsource/space-grotesk @fontsource/space-mono
# turndown/dist/turndown.js -> vendor/turndown.js # turndown/dist/turndown.js -> vendor/turndown.js
# turndown-plugin-gfm/dist/turndown-plugin-gfm.js -> vendor/turndown-plugin-gfm.js # turndown-plugin-gfm/dist/turndown-plugin-gfm.js -> vendor/turndown-plugin-gfm.js
# marked/lib/marked.umd.js -> vendor/marked.umd.js # marked/lib/marked.umd.js -> vendor/marked.umd.js
# dompurify/dist/purify.min.js -> vendor/purify.min.js # dompurify/dist/purify.min.js -> vendor/purify.min.js
# geist/dist/fonts/**/*-Variable.woff2 -> vendor/fonts/ # @fontsource/*/files/*-latin-{400,500,700}-normal.woff2 -> vendor/fonts/
``` ```
Bump the `CACHE` constant in `sw.js` whenever an asset changes so clients pick it up. Bump the `CACHE` constant in `sw.js` whenever an asset changes so clients pick it up.
## License ## License
[MIT](LICENSE). Turndown, marked, DOMPurify and Geist are under their respective MIT/OFL licenses. [MIT](LICENSE). Turndown, marked, DOMPurify, Space Grotesk and Space Mono are under their respective MIT/Apache/OFL licenses.
## Support
clip2md is free. If it saves you time: [buy me a coffee via PayPal](https://www.paypal.com/donate/?business=info%40tillheidrich.de&currency_code=EUR&item_name=clip2md).
+47 -16
View File
@@ -2,29 +2,29 @@
<html lang="de"> <html lang="de">
<head> <head>
<meta charset="UTF-8" /> <meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" /> <meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover" />
<meta name="robots" content="noindex" /> <meta name="robots" content="noindex" />
<meta name="theme-color" content="#faf7f2" /> <meta name="theme-color" content="#EAEAE3" />
<title>Datenschutzerklärung — clip2md</title> <title>Datenschutzerklärung — clip2md</title>
<link rel="icon" href="icon.svg" type="image/svg+xml" /> <link rel="icon" href="/icon.svg" type="image/svg+xml" />
<link rel="stylesheet" href="legal.css" /> <link rel="stylesheet" href="/legal.css" />
<script> <script>
try { var t = JSON.parse(localStorage.getItem('clip2md:theme')); if (t === 'dark') document.documentElement.setAttribute('data-theme','dark'); } catch (e) {} try { var th = JSON.parse(localStorage.getItem('clip2md:theme')); if (th === 'dark' || (th === null && matchMedia('(prefers-color-scheme: dark)').matches)) document.documentElement.setAttribute('data-theme','dark'); } catch (e) {}
</script> </script>
</head> </head>
<body> <body>
<header class="legal-head"> <header class="topbar">
<div class="inner"> <a class="brand" href="/"><svg viewBox="0 0 24 24" aria-hidden="true"><g fill="none" stroke="currentColor" stroke-width="1.9" stroke-linecap="round" stroke-linejoin="round"><rect x="5" y="4.5" width="14" height="17" rx="1.5"/><path d="M12 9.5v7.5M8.8 13.8 12 17l3.2-3.2"/></g><rect x="8.6" y="2.4" width="6.8" height="3.8" rx="1" fill="currentColor"/></svg><span>clip<span class="two">2</span>md</span></a>
<a class="back" href="/"><span class="wordmark">clip<b>2</b>md</span></a>
<nav> <nav>
<a href="impressum.html">Impressum</a> <a href="/impressum.html">Impressum</a>
<a href="datenschutz.html" aria-current="page">Datenschutz</a> <a href="/datenschutz.html" aria-current="page">Datenschutz</a>
</nav> </nav>
</div>
</header> </header>
<main class="legal"> <main class="legal">
<span class="mono-label">Rechtliches</span>
<h1>Datenschutzerklärung</h1> <h1>Datenschutzerklärung</h1>
<div class="card">
<p class="intro"> <p class="intro">
Der Text, den Sie auf dieser Seite einfügen, wird ausschließlich in Ihrem Browser Der Text, den Sie auf dieser Seite einfügen, wird ausschließlich in Ihrem Browser
@@ -57,6 +57,13 @@
Zwischenablage erfolgen ebenfalls lokal über die entsprechenden Browser-Schnittstellen. Zwischenablage erfolgen ebenfalls lokal über die entsprechenden Browser-Schnittstellen.
Auch dabei werden keine Daten an uns übermittelt. Auch dabei werden keine Daten an uns übermittelt.
</p> </p>
<p>
Über die Schaltfläche „Einfügen" liest die Seite die Zwischenablage Ihres Geräts aus. Das
geschieht nur, wenn Sie die Schaltfläche betätigen, und je nach Browser erst nach Ihrer
Zustimmung. Der Inhalt wird wie beim Einfügen per Tastatur ausschließlich lokal umgewandelt.
Auf Smartphones übergibt „Speichern" die Datei an das Teilen-Menü Ihres Betriebssystems; wohin
Sie sie von dort weitergeben, entscheiden Sie selbst.
</p>
<h2>3. Lokale Speicherung Ihrer Einstellungen</h2> <h2>3. Lokale Speicherung Ihrer Einstellungen</h2>
<p> <p>
@@ -117,7 +124,7 @@
Einwilligungsabfrage ist deshalb nicht erforderlich. Einwilligungsabfrage ist deshalb nicht erforderlich.
</p> </p>
<p> <p>
Eine Ausnahme betrifft die optionale Vorschau: Enthält der von Ihnen eingefuegte Text Eine Ausnahme betrifft die optionale Vorschau: Enthält der von Ihnen eingefügte Text
Bilder, die auf fremde Server verweisen, lädt Ihr Browser diese Bilder beim Anzeigen der Bilder, die auf fremde Server verweisen, lädt Ihr Browser diese Bilder beim Anzeigen der
Vorschau von dort. Dabei erfährt der jeweilige fremde Server Ihre IP-Adresse. Übertragen Vorschau von dort. Dabei erfährt der jeweilige fremde Server Ihre IP-Adresse. Übertragen
wird dabei nichts von Ihrem Text; die Herkunft wird durch die Einstellung wird dabei nichts von Ihrem Text; die Herkunft wird durch die Einstellung
@@ -125,7 +132,28 @@
vermeiden möchten, lassen Sie die Vorschau ausgeschaltet. vermeiden möchten, lassen Sie die Vorschau ausgeschaltet.
</p> </p>
<h2>8. Ihre Rechte</h2> <h2>8. Spenden über PayPal</h2>
<p>
Auf der Seite finden Sie einen Link „Spenden" bzw. „Buy me a coffee". Es handelt sich um einen
einfachen Link; beim Aufruf von clip2md werden keine Inhalte, Skripte oder Cookies von PayPal
geladen und keine Daten an PayPal übertragen. Erst wenn Sie den Link anklicken, verlassen Sie
diese Seite und werden zu PayPal weitergeleitet.
</p>
<p>
Anbieter ist die PayPal (Europe) S.à r.l. et Cie, S.C.A., 22–24 Boulevard Royal, L-2449
Luxemburg. Für die Verarbeitung auf den Seiten von PayPal ist PayPal selbst verantwortlich; es
gilt dessen Datenschutzerklärung:
<a href="https://www.paypal.com/de/legalhub/privacy-full" rel="noopener nofollow">paypal.com/de/legalhub/privacy-full</a>.
</p>
<p>
Wenn Sie spenden, erhalten wir von PayPal die zur Abwicklung nötigen Angaben: Ihren Namen, Ihre
E-Mail-Adresse, den Betrag, das Datum und gegebenenfalls eine Nachricht, die Sie hinzufügen.
Rechtsgrundlage ist Art. 6 Abs. 1 lit. b DSGVO (Abwicklung der Zuwendung) sowie Art. 6 Abs. 1
lit. c DSGVO in Verbindung mit den steuer- und handelsrechtlichen Aufbewahrungspflichten
(in der Regel zehn Jahre). Eine weitere Nutzung, etwa für Werbung, findet nicht statt.
</p>
<h2>9. Ihre Rechte</h2>
<p> <p>
Sie haben das Recht auf Auskunft (Art. 15 DSGVO), Berichtigung (Art. 16), Löschung Sie haben das Recht auf Auskunft (Art. 15 DSGVO), Berichtigung (Art. 16), Löschung
(Art. 17), Einschränkung der Verarbeitung (Art. 18), Datenübertragbarkeit (Art. 20) sowie (Art. 17), Einschränkung der Verarbeitung (Art. 18), Datenübertragbarkeit (Art. 20) sowie
@@ -133,17 +161,20 @@
(Art. 21). Wenden Sie sich dafür an die oben genannte Adresse. (Art. 21). Wenden Sie sich dafür an die oben genannte Adresse.
</p> </p>
<h2>9. Beschwerderecht</h2> <h2>10. Beschwerderecht</h2>
<p> <p>
Sie können sich bei einer Datenschutz-Aufsichtsbehörde beschweren. Zuständig ist die Sie können sich bei einer Datenschutz-Aufsichtsbehörde beschweren. Zuständig ist die
Landesbeauftragte für den Datenschutz Niedersachsen, Prinzenstraße 5, 30159 Hannover. Landesbeauftragte für den Datenschutz Niedersachsen, Prinzenstraße 5, 30159 Hannover.
</p> </p>
<h2>10. Stand</h2> <h2>11. Stand</h2>
<p>Diese Datenschutzerklärung hat den Stand September 2026.</p> <p>Diese Datenschutzerklärung hat den Stand September 2026.</p>
</div>
<div class="legal-foot"> <div class="legal-foot">
<a href="/">Zurück zum Werkzeug</a> · <a href="impressum.html">Impressum</a> <a href="/">← Zurück zu clip2md</a>
<a href="/impressum.html">Impressum</a>
<a href="https://www.paypal.com/donate/?business=info%40tillheidrich.de&amp;currency_code=EUR&amp;item_name=clip2md" target="_blank" rel="noopener nofollow">Spenden</a>
</div> </div>
</main> </main>
</body> </body>
Binary file not shown.

Before

Width:  |  Height:  |  Size: 101 KiB

After

Width:  |  Height:  |  Size: 54 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 132 KiB

+5 -5
View File
@@ -1,7 +1,7 @@
<svg xmlns="http://www.w3.org/2000/svg" width="512" height="512" viewBox="0 0 512 512" role="img" aria-label="clip2md"> <svg xmlns="http://www.w3.org/2000/svg" width="512" height="512" viewBox="0 0 512 512" role="img" aria-label="clip2md" xmlns:c2pa="http://c2pa.org/manifest"><metadata><c2pa:manifest>AAAWgmp1bWIAAAAeanVtZGMycGEAEQAQgAAAqgA4m3EDYzJwYQAAABZcanVtYgAAAEdqdW1kYzJtYQARABCAAACqADibcQN1cm46YzJwYTo5NjkzMWJiNy1jYTg3LTRjNWEtOGE4Ni0yNjQxYzJjODg3Y2IAAAADl2p1bWIAAAApanVtZGMyYXMAEQAQgAAAqgA4m3EDYzJwYS5hc3NlcnRpb25zAAAAALxqdW1iAAAARGp1bWRjYm9yABEAEIAAAKoAOJtxE2MycGEuaW5ncmVkaWVudC52MwAAAAAYYzJzaEd1ybodD3L6bmfkOq9bA40AAABwY2JvcqNpZGM6Zm9ybWF0bWltYWdlL3N2Zyt4bWxqaW5zdGFuY2VJRHgseG1wOmlpZDpiYmUwY2ZjNi00NGNhLTRkMWItYjRiNi04MmRjY2U1ZWQyYzJscmVsYXRpb25zaGlwaHBhcmVudE9mAAAB4mp1bWIAAABBanVtZGNib3IAEQAQgAAAqgA4m3ETYzJwYS5hY3Rpb25zLnYyAAAAABhjMnNoD8B6kTZGbHgLyzg08rdPaAAAAZljYm9yomdhY3Rpb25zgqJmYWN0aW9ua2MycGEub3BlbmVkanBhcmFtZXRlcnOha2luZ3JlZGllbnRzgaJjdXJseC1zZWxmI2p1bWJmPWMycGEuYXNzZXJ0aW9ucy9jMnBhLmluZ3JlZGllbnQudjNkaGFzaFggefl5EZp24D6m6pO00dQE2grxyV6xfE4gO+musKFljSakZmFjdGlvbngdY29tLmFudGhyb3BpYy5jbGF1ZGUucHJvdmlkZWRqcGFyYW1ldGVyc6F4H2NvbS5hbnRocm9waWMub3JpZ2luLWNvbmZpZGVuY2VndW5rbm93bmtkZXNjcmlwdGlvbnhmQ2xhdWRlIHByb3ZpZGVkIHRoaXMgZmlsZSBhdCB0aGUgcmVxdWVzdCBvZiBhIHVzZXIgYW5kIG1heSBoYXZlIGNyZWF0ZWQgb3IgbW9kaWZpZWQgdGhlIGZpbGUgY29udGVudHMubXNvZnR3YXJlQWdlbnShZG5hbWVmQ2xhdWRlcmFsbEFjdGlvbnNJbmNsdWRlZPUAAADIanVtYgAAAEBqdW1kY2JvcgARABCAAACqADibcRNjMnBhLmhhc2guZGF0YQAAAAAYYzJzaJenzbrkdVtDScW6NB1RE6oAAACAY2JvcqVjYWxnZnNoYTI1NmNwYWRNAAAAAAAAAAAAAAAAAGRoYXNoWCD6NBeqJ7Ht0mHPVl42j6FWIZFbAbXQRXPffHTHE/OE8GRuYW1lbmp1bWJmIG1hbmlmZXN0amV4Y2x1c2lvbnOBomVzdGFydBi2Zmxlbmd0aBkeBAAAAj5qdW1iAAAAJ2p1bWRjMmNsABEAEIAAAKoAOJtxA2MycGEuY2xhaW0udjIAAAACD2Nib3KlY2FsZ2ZzaGEyNTZpc2lnbmF0dXJleE1zZWxmI2p1bWJmPS9jMnBhL3VybjpjMnBhOjk2OTMxYmI3LWNhODctNGM1YS04YTg2LTI2NDFjMmM4ODdjYi9jMnBhLnNpZ25hdHVyZWppbnN0YW5jZUlEeCx4bXA6aWlkOjgyMDQyNDg5LWEwZmQtNDFkMS1iNzJiLWNiN2I3ODQ5ZGM3ZHJjcmVhdGVkX2Fzc2VydGlvbnODomN1cmx4LXNlbGYjanVtYmY9YzJwYS5hc3NlcnRpb25zL2MycGEuaW5ncmVkaWVudC52M2RoYXNoWCB5+XkRmnbgPqbqk7TR1ATaCvHJXrF8TiA76a6woWWNJqJjdXJseCpzZWxmI2p1bWJmPWMycGEuYXNzZXJ0aW9ucy9jMnBhLmFjdGlvbnMudjJkaGFzaFggaNNTgOw83IrurlIppyF4vuc6nRxPx9W196cCasAjeCSiY3VybHgpc2VsZiNqdW1iZj1jMnBhLmFzc2VydGlvbnMvYzJwYS5oYXNoLmRhdGFkaGFzaFggjA55f0u5dgptrQQn9+ArLOZjPV71ZLqDOc0AfCcWtx50Y2xhaW1fZ2VuZXJhdG9yX2luZm+jZG5hbWVvQW50aHJvcGljIEZpbGVzZ3ZlcnNpb25lMS4wLjBrc3BlY1ZlcnNpb25lMi40LjAAABA4anVtYgAAAChqdW1kYzJjcwARABCAAACqADibcQNjMnBhLnNpZ25hdHVyZQAAABAIY2JvctKEWQISogEmGCFZAgowggIGMIIBjaADAgECAhRA5aAK7sI50L64g/oGQgU9Z1UTADAKBggqhkjOPQQDAzBJMRcwFQYDVQQKEw5BbnRocm9waWMsIFBCQzEuMCwGA1UEAxMlQW50aHJvcGljIENvbnRlbnQgQ3JlZGVudGlhbHMgUm9vdCBDQTAeFw0yNjA4MDcxODQzNTZaFw0yODA4MDYxOTQzNTZaMEQxFzAVBgNVBAoTDkFudGhyb3BpYywgUEJDMSkwJwYDVQQDEyBBbnRocm9waWMgQ2xhdWRlIENvbnRlbnQgU2lnbmluZzBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABJh6CmvLUBgFFNU0vUKlOVtE6djd17L5SuwX0LemFisBM3dkd/3cyjxFA3Qo5S46fX0/ihY0VZ7mfb9KF703t5OjWDBWMA4GA1UdDwEB/wQEAwIHgDAVBgNVHSUEDjAMBgorBgEEAYPoXgIBMAwGA1UdEwEB/wQCMAAwHwYDVR0jBBgwFoAUzlHiBIFOZFsj+OPEz5o+nMHXXMIwCgYIKoZIzj0EAwMDZwAwZAIwMXMdFJ4BetLLVY7ORuE9noqbbAZOZn/aArXyTwFAZfKrPzxF2vPoJNf1+UCdg1XGAjBwX1zd9WGqYkqmL5SFqw1QySjr1zJfpJM9+1rdDwSPLMOPOjKuiXjoU/pUUeG9RwmhY3BhZFkNngAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAALine truncated
<g fill="none" stroke="currentColor" stroke-width="44" stroke-linecap="round" stroke-linejoin="round"> <g fill="none" stroke="#000" stroke-width="30" stroke-linecap="round" stroke-linejoin="round">
<path d="M118 352V166l86 94 86-94v186"/> <rect x="146" y="124" width="220" height="284" rx="22"/>
<path d="M384 166v140"/> <path d="M256 214v124M204 288l52 52 52-52"/>
<path d="M338 268l46 52 46-52"/>
</g> </g>
<rect x="198" y="92" width="116" height="64" rx="16" fill="#000"/>
</svg> </svg>

Before

Width:  |  Height:  |  Size: 350 B

After

Width:  |  Height:  |  Size: 8.0 KiB

+6 -6
View File
@@ -1,8 +1,8 @@
<svg xmlns="http://www.w3.org/2000/svg" width="512" height="512" viewBox="0 0 512 512" role="img" aria-label="clip2md"> <svg xmlns="http://www.w3.org/2000/svg" width="512" height="512" viewBox="0 0 512 512" role="img" aria-label="clip2md" xmlns:c2pa="http://c2pa.org/manifest"><metadata><c2pa:manifest>AAAWgmp1bWIAAAAeanVtZGMycGEAEQAQgAAAqgA4m3EDYzJwYQAAABZcanVtYgAAAEdqdW1kYzJtYQARABCAAACqADibcQN1cm46YzJwYTo3NjZmY2E1NS0xNWZhLTRjMjktOWMwMi0yZWQ2YTRlMTE5N2IAAAADl2p1bWIAAAApanVtZGMyYXMAEQAQgAAAqgA4m3EDYzJwYS5hc3NlcnRpb25zAAAAALxqdW1iAAAARGp1bWRjYm9yABEAEIAAAKoAOJtxE2MycGEuaW5ncmVkaWVudC52MwAAAAAYYzJzaIxdjdUDEhE5YIY3eHT5SCoAAABwY2JvcqNpZGM6Zm9ybWF0bWltYWdlL3N2Zyt4bWxqaW5zdGFuY2VJRHgseG1wOmlpZDo1NGNhN2NlYy0wYWE0LTQ5YzMtOGI5Ny00YzUxNDdlMmJjNjJscmVsYXRpb25zaGlwaHBhcmVudE9mAAAB4mp1bWIAAABBanVtZGNib3IAEQAQgAAAqgA4m3ETYzJwYS5hY3Rpb25zLnYyAAAAABhjMnNo9xq2bExTiscFiT0oWzKpFgAAAZljYm9yomdhY3Rpb25zgqJmYWN0aW9ua2MycGEub3BlbmVkanBhcmFtZXRlcnOha2luZ3JlZGllbnRzgaJjdXJseC1zZWxmI2p1bWJmPWMycGEuYXNzZXJ0aW9ucy9jMnBhLmluZ3JlZGllbnQudjNkaGFzaFggsVAEfTnGrUgMMt4oWhSoE9/0KzYLZORmwRH2LXb/+VKkZmFjdGlvbngdY29tLmFudGhyb3BpYy5jbGF1ZGUucHJvdmlkZWRqcGFyYW1ldGVyc6F4H2NvbS5hbnRocm9waWMub3JpZ2luLWNvbmZpZGVuY2VndW5rbm93bmtkZXNjcmlwdGlvbnhmQ2xhdWRlIHByb3ZpZGVkIHRoaXMgZmlsZSBhdCB0aGUgcmVxdWVzdCBvZiBhIHVzZXIgYW5kIG1heSBoYXZlIGNyZWF0ZWQgb3IgbW9kaWZpZWQgdGhlIGZpbGUgY29udGVudHMubXNvZnR3YXJlQWdlbnShZG5hbWVmQ2xhdWRlcmFsbEFjdGlvbnNJbmNsdWRlZPUAAADIanVtYgAAAEBqdW1kY2JvcgARABCAAACqADibcRNjMnBhLmhhc2guZGF0YQAAAAAYYzJzaIs0FFpWK28j1nfpDaf+6ewAAACAY2JvcqVjYWxnZnNoYTI1NmNwYWRNAAAAAAAAAAAAAAAAAGRoYXNoWCC9PsI0VhKdqWl+KMmXDr0D88GymzjDSxOZnAykNujo+mRuYW1lbmp1bWJmIG1hbmlmZXN0amV4Y2x1c2lvbnOBomVzdGFydBi2Zmxlbmd0aBkeBAAAAj5qdW1iAAAAJ2p1bWRjMmNsABEAEIAAAKoAOJtxA2MycGEuY2xhaW0udjIAAAACD2Nib3KlY2FsZ2ZzaGEyNTZpc2lnbmF0dXJleE1zZWxmI2p1bWJmPS9jMnBhL3VybjpjMnBhOjc2NmZjYTU1LTE1ZmEtNGMyOS05YzAyLTJlZDZhNGUxMTk3Yi9jMnBhLnNpZ25hdHVyZWppbnN0YW5jZUlEeCx4bXA6aWlkOjMyYTlhZWM1LWI3NjgtNDM1Zi1hYmQwLWI3YWI0ZjM1ZDliMXJjcmVhdGVkX2Fzc2VydGlvbnODomN1cmx4LXNlbGYjanVtYmY9YzJwYS5hc3NlcnRpb25zL2MycGEuaW5ncmVkaWVudC52M2RoYXNoWCCxUAR9OcatSAwy3ihaFKgT3/QrNgtk5GbBEfYtdv/5UqJjdXJseCpzZWxmI2p1bWJmPWMycGEuYXNzZXJ0aW9ucy9jMnBhLmFjdGlvbnMudjJkaGFzaFggC2jWKBQAXG2Nl28/mppC+AVk5pvIfJUH9IZaGTTCDMaiY3VybHgpc2VsZiNqdW1iZj1jMnBhLmFzc2VydGlvbnMvYzJwYS5oYXNoLmRhdGFkaGFzaFgglSQJIGyHAJjeNhWxWBLoo/KtOZ1TONf6O1V9ENt4vf10Y2xhaW1fZ2VuZXJhdG9yX2luZm+jZG5hbWVvQW50aHJvcGljIEZpbGVzZ3ZlcnNpb25lMS4wLjBrc3BlY1ZlcnNpb25lMi40LjAAABA4anVtYgAAAChqdW1kYzJjcwARABCAAACqADibcQNjMnBhLnNpZ25hdHVyZQAAABAIY2JvctKEWQISogEmGCFZAgowggIGMIIBjaADAgECAhRA5aAK7sI50L64g/oGQgU9Z1UTADAKBggqhkjOPQQDAzBJMRcwFQYDVQQKEw5BbnRocm9waWMsIFBCQzEuMCwGA1UEAxMlQW50aHJvcGljIENvbnRlbnQgQ3JlZGVudGlhbHMgUm9vdCBDQTAeFw0yNjA4MDcxODQzNTZaFw0yODA4MDYxOTQzNTZaMEQxFzAVBgNVBAoTDkFudGhyb3BpYywgUEJDMSkwJwYDVQQDEyBBbnRocm9waWMgQ2xhdWRlIENvbnRlbnQgU2lnbmluZzBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABJh6CmvLUBgFFNU0vUKlOVtE6djd17L5SuwX0LemFisBM3dkd/3cyjxFA3Qo5S46fX0/ihY0VZ7mfb9KF703t5OjWDBWMA4GA1UdDwEB/wQEAwIHgDAVBgNVHSUEDjAMBgorBgEEAYPoXgIBMAwGA1UdEwEB/wQCMAAwHwYDVR0jBBgwFoAUzlHiBIFOZFsj+OPEz5o+nMHXXMIwCgYIKoZIzj0EAwMDZwAwZAIwMXMdFJ4BetLLVY7ORuE9noqbbAZOZn/aArXyTwFAZfKrPzxF2vPoJNf1+UCdg1XGAjBwX1zd9WGqYkqmL5SFqw1QySjr1zJfpJM9+1rdDwSPLMOPOjKuiXjoU/pUUeG9RwmhY3BhZFkNngAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAALine truncated
<rect width="512" height="512" rx="112" fill="#c14a2b"/> <rect width="512" height="512" rx="104" fill="#1B3BE0"/>
<g fill="none" stroke="#fdf6f1" stroke-width="44" stroke-linecap="round" stroke-linejoin="round"> <g fill="none" stroke="#FBFBF7" stroke-width="30" stroke-linecap="round" stroke-linejoin="round">
<path d="M118 352V166l86 94 86-94v186"/> <rect x="146" y="124" width="220" height="284" rx="22"/>
<path d="M384 166v140"/> <path d="M256 214v124M204 288l52 52 52-52"/>
<path d="M338 268l46 52 46-52"/>
</g> </g>
<rect x="198" y="92" width="116" height="64" rx="16" fill="#FBFBF7"/>
</svg> </svg>

Before

Width:  |  Height:  |  Size: 404 B

After

Width:  |  Height:  |  Size: 8.1 KiB

+17 -14
View File
@@ -2,29 +2,29 @@
<html lang="de"> <html lang="de">
<head> <head>
<meta charset="UTF-8" /> <meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" /> <meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover" />
<meta name="robots" content="noindex" /> <meta name="robots" content="noindex" />
<meta name="theme-color" content="#faf7f2" /> <meta name="theme-color" content="#EAEAE3" />
<title>Impressum — clip2md</title> <title>Impressum — clip2md</title>
<link rel="icon" href="icon.svg" type="image/svg+xml" /> <link rel="icon" href="/icon.svg" type="image/svg+xml" />
<link rel="stylesheet" href="legal.css" /> <link rel="stylesheet" href="/legal.css" />
<script> <script>
try { var t = JSON.parse(localStorage.getItem('clip2md:theme')); if (t === 'dark') document.documentElement.setAttribute('data-theme','dark'); } catch (e) {} try { var th = JSON.parse(localStorage.getItem('clip2md:theme')); if (th === 'dark' || (th === null && matchMedia('(prefers-color-scheme: dark)').matches)) document.documentElement.setAttribute('data-theme','dark'); } catch (e) {}
</script> </script>
</head> </head>
<body> <body>
<header class="legal-head"> <header class="topbar">
<div class="inner"> <a class="brand" href="/"><svg viewBox="0 0 24 24" aria-hidden="true"><g fill="none" stroke="currentColor" stroke-width="1.9" stroke-linecap="round" stroke-linejoin="round"><rect x="5" y="4.5" width="14" height="17" rx="1.5"/><path d="M12 9.5v7.5M8.8 13.8 12 17l3.2-3.2"/></g><rect x="8.6" y="2.4" width="6.8" height="3.8" rx="1" fill="currentColor"/></svg><span>clip<span class="two">2</span>md</span></a>
<a class="back" href="/"><span class="wordmark">clip<b>2</b>md</span></a>
<nav> <nav>
<a href="impressum.html" aria-current="page">Impressum</a> <a href="/impressum.html" aria-current="page">Impressum</a>
<a href="datenschutz.html">Datenschutz</a> <a href="/datenschutz.html">Datenschutz</a>
</nav> </nav>
</div>
</header> </header>
<main class="legal"> <main class="legal">
<span class="mono-label">Rechtliches</span>
<h1>Impressum</h1> <h1>Impressum</h1>
<div class="card">
<h2>Angaben gemäß § 5 DDG</h2> <h2>Angaben gemäß § 5 DDG</h2>
<table class="legal-table"> <table class="legal-table">
@@ -65,12 +65,15 @@
<h2>Urheberrecht und Lizenz</h2> <h2>Urheberrecht und Lizenz</h2>
<p> <p>
Der Quellcode von clip2md steht unter der MIT-Lizenz. Die eingebundenen Bibliotheken Der Quellcode von clip2md steht unter der MIT-Lizenz. Die eingebundenen Bibliotheken
(Turndown, Marked, DOMPurify) und die Schriftfamilie Geist stehen unter ihren jeweiligen (Turndown, Marked, DOMPurify, MIT- bzw. Apache-Lizenz) und die Schriftfamilien Space Grotesk und Space Mono stehen unter ihren jeweiligen
freien Lizenzen. Texte und Gestaltung dieser Seite unterliegen dem deutschen Urheberrecht. freien Lizenzen (Schriften: SIL Open Font License). Texte und Gestaltung dieser Seite unterliegen dem deutschen Urheberrecht.
</p> </p>
</div>
<div class="legal-foot"> <div class="legal-foot">
<a href="/">Zurück zum Werkzeug</a> · <a href="datenschutz.html">Datenschutzerklärung</a> <a href="/">← Zurück zu clip2md</a>
<a href="/datenschutz.html">Datenschutzerklärung</a>
<a href="https://www.paypal.com/donate/?business=info%40tillheidrich.de&amp;currency_code=EUR&amp;item_name=clip2md" target="_blank" rel="noopener nofollow">Spenden</a>
</div> </div>
</main> </main>
</body> </body>
+477 -423
View File
File diff suppressed because it is too large. Load diff
+53 -55
View File
@@ -1,66 +1,64 @@
@font-face { font-family: "Geist"; src: url("vendor/fonts/Geist-Variable.woff2") format("woff2"); font-weight: 100 900; font-style: normal; font-display: swap; } @font-face { font-family: "Space Grotesk"; src: url("/vendor/fonts/space-grotesk-latin-400-normal.woff2") format("woff2"); font-weight: 400; font-display: swap; }
@font-face { font-family: "Geist Mono"; src: url("vendor/fonts/GeistMono-Variable.woff2") format("woff2"); font-weight: 100 900; font-style: normal; font-display: swap; } @font-face { font-family: "Space Grotesk"; src: url("/vendor/fonts/space-grotesk-latin-700-normal.woff2") format("woff2"); font-weight: 700; font-display: swap; }
@font-face { font-family: "Space Mono"; src: url("/vendor/fonts/space-mono-latin-400-normal.woff2") format("woff2"); font-weight: 400; font-display: swap; }
:root { :root {
--paper: oklch(98.4% 0.006 80); --paper: oklch(92.8% 0.005 95); --card: oklch(98.4% 0.004 95); --tint: oklch(95.6% 0.005 95);
--surface: oklch(99.6% 0.003 80); --line: oklch(86.8% 0.007 95); --mark: oklch(70% 0.006 95);
--line: oklch(89% 0.008 75); --ink: oklch(21% 0.01 95); --ink-soft: oklch(49% 0.008 95);
--ink: oklch(26% 0.02 55); --accent: oklch(45% 0.23 267); --accent-2: oklch(38% 0.21 267); --accent-bg: oklch(45% 0.23 267 / 0.07); --on-accent: #fff;
--ink-2: oklch(44% 0.018 55); --radius: 4px; --shadow: 0 1px 2px oklch(21% 0.01 95 / 0.05);
--ink-3: oklch(58% 0.014 55); --sans: "Space Grotesk", system-ui, -apple-system, sans-serif;
--accent: oklch(56% 0.168 34); --mono: "Space Mono", ui-monospace, Menlo, monospace;
--accent-hi: oklch(52% 0.18 33);
--r: 10px;
--font: "Geist", ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
--mono: "Geist Mono", ui-monospace, "SF Mono", Menlo, Consolas, monospace;
} }
[data-theme="dark"] { [data-theme="dark"] {
--paper: oklch(19% 0.008 60); --paper: oklch(17.5% 0.01 267); --card: oklch(21% 0.012 267); --tint: oklch(24% 0.014 267);
--surface: oklch(22% 0.01 60); --line: oklch(31% 0.015 267); --mark: oklch(52% 0.012 267);
--line: oklch(30% 0.012 60); --ink: oklch(94% 0.005 95); --ink-soft: oklch(72% 0.01 95);
--ink: oklch(93% 0.006 75); --accent: oklch(70% 0.15 267); --accent-2: oklch(79% 0.12 267); --accent-bg: oklch(70% 0.15 267 / 0.14); --on-accent: oklch(17% 0.03 267);
--ink-2: oklch(72% 0.012 70); --shadow: 0 1px 2px oklch(0% 0 0 / 0.3);
--ink-3: oklch(60% 0.012 65);
--accent: oklch(70% 0.15 40);
--accent-hi: oklch(76% 0.14 42);
} }
*, *::before, *::after { box-sizing: border-box; } *, *::before, *::after { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; } html { -webkit-text-size-adjust: 100%; }
body { body { margin: 0; background: var(--paper); color: var(--ink); font-family: var(--sans); font-size: 16px; line-height: 1.6;
margin: 0; background: var(--paper); color: var(--ink); -webkit-font-smoothing: antialiased; padding-left: env(safe-area-inset-left); padding-right: env(safe-area-inset-right); }
font-family: var(--font); font-size: 1rem; line-height: 1.62;
-webkit-font-smoothing: antialiased;
}
.legal-head { border-bottom: 1px solid var(--line); background: var(--surface); }
.legal-head .inner, main.legal { width: min(100% - 2.5rem, 46rem); margin-inline: auto; }
.legal-head .inner { display: flex; align-items: center; justify-content: space-between; gap: 1rem; padding: 0.9rem 0; }
.legal-head a.back { display: inline-flex; align-items: center; gap: 0.45rem; text-decoration: none; color: var(--ink); font-weight: 500; }
.legal-head .wordmark { font-family: var(--mono); font-size: 1.02rem; letter-spacing: -0.03em; }
.legal-head .wordmark b { color: var(--accent); }
.legal-head nav { display: flex; gap: 1.25rem; font-size: 0.875rem; }
.legal-head nav a { color: var(--ink-3); text-decoration: none; }
.legal-head nav a:hover, .legal-head nav a[aria-current="page"] { color: var(--accent); }
main.legal { padding: 3rem 0 5rem; }
h1 { font-size: clamp(1.9rem, 1.5rem + 1.6vw, 2.5rem); letter-spacing: -0.03em; line-height: 1.12; margin: 0 0 1.5rem; }
h2 { font-size: 1.0625rem; letter-spacing: -0.015em; margin: 2.4rem 0 0.6rem; }
p { margin: 0 0 1em; color: var(--ink-2); }
p.intro { color: var(--ink); }
ul { padding-left: 1.15rem; margin: 0 0 1em; color: var(--ink-2); }
li { margin-bottom: 0.32em; }
a { color: var(--accent); text-underline-offset: 3px; } a { color: var(--accent); text-underline-offset: 3px; }
a:hover { color: var(--accent-hi); } a:hover { color: var(--accent-2); }
:focus-visible { outline: 2px solid var(--accent); outline-offset: 3px; border-radius: 3px; } :focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
code, .mono { font-family: var(--mono); font-size: 0.92em; }
table.legal-table { border-collapse: collapse; margin: 0 0 1em; } .topbar { position: sticky; top: 0; z-index: 10; display: flex; align-items: center; gap: 12px;
table.legal-table th { text-align: left; font-weight: 500; color: var(--ink-3); padding: 0.22rem 1.6rem 0.22rem 0; vertical-align: top; white-space: nowrap; font-size: 0.9375rem; } padding: calc(10px + env(safe-area-inset-top)) 16px 10px; border-bottom: 1px solid var(--line);
table.legal-table td { padding: 0.22rem 0; vertical-align: top; color: var(--ink-2); } background: color-mix(in oklab, var(--card) 88%, transparent); backdrop-filter: blur(8px); -webkit-backdrop-filter: blur(8px); }
.brand { display: inline-flex; align-items: center; gap: 9px; color: var(--ink); text-decoration: none; font-weight: 700; font-size: 1.2rem; letter-spacing: -0.02em; }
.brand:hover { color: var(--ink); }
.brand svg { width: 22px; height: 22px; color: var(--accent); }
.brand .two { color: var(--accent); }
.topbar nav { margin-left: auto; display: flex; gap: 4px; flex-wrap: wrap; }
.topbar nav a { min-height: 40px; display: inline-flex; align-items: center; padding: 0 12px; border-radius: 999px; color: var(--ink-soft); text-decoration: none; font-size: 0.9rem; }
.topbar nav a:hover { color: var(--ink); background: var(--tint); }
.topbar nav a[aria-current="page"] { color: var(--accent); background: var(--accent-bg); font-weight: 700; }
.legal-foot { border-top: 1px solid var(--line); margin-top: 3rem; padding-top: 1.25rem; font-size: 0.875rem; color: var(--ink-3); } main.legal { max-width: 760px; margin: 0 auto; padding: 32px 16px calc(64px + env(safe-area-inset-bottom)); }
.legal-foot a { color: var(--ink-3); } .mono-label { font-family: var(--mono); font-size: 10px; letter-spacing: 0.18em; text-transform: uppercase; color: var(--ink-soft); }
h1 { font-size: clamp(1.9rem, 1.5rem + 1.6vw, 2.5rem); letter-spacing: -0.02em; line-height: 1.12; margin: 6px 0 20px; }
.card { background: var(--card); border: 1px solid var(--line); border-radius: var(--radius); box-shadow: var(--shadow); padding: 8px 24px 20px; }
h2 { font-size: 1.08rem; letter-spacing: -0.01em; margin: 1.8rem 0 0.5rem; }
p { margin: 0 0 1em; color: var(--ink-soft); }
p.intro { color: var(--ink); font-size: 1.05rem; margin-bottom: 20px; }
ul { padding-left: 1.15rem; margin: 0 0 1em; color: var(--ink-soft); }
li { margin-bottom: 0.3em; }
code, .mono { font-family: var(--mono); font-size: 0.88em; }
table.legal-table { border-collapse: collapse; margin: 0 0 1em; width: 100%; }
table.legal-table th { text-align: left; font-weight: 400; color: var(--ink-soft); padding: 0.3rem 1.4rem 0.3rem 0; vertical-align: top; white-space: nowrap; font-family: var(--mono); font-size: 0.78rem; letter-spacing: .04em; }
table.legal-table td { padding: 0.3rem 0; vertical-align: top; overflow-wrap: anywhere; }
.legal-foot { margin-top: 24px; display: flex; gap: 8px 18px; flex-wrap: wrap; font-size: 0.9rem; }
.legal-foot a { color: var(--ink-soft); text-decoration: none; padding: 6px 0; }
.legal-foot a:hover { color: var(--accent); } .legal-foot a:hover { color: var(--accent); }
@media (max-width: 560px) {
@media (prefers-reduced-motion: reduce) { *, *::before, *::after { transition-duration: 0.01ms !important; animation-duration: 0.01ms !important; } } .card { padding: 4px 16px 16px; }
.topbar nav a { padding: 0 10px; font-size: 0.85rem; }
table.legal-table th, table.legal-table td { display: block; padding: 0; }
table.legal-table td { margin-bottom: 10px; }
}
@media (prefers-reduced-motion: reduce) { *, *::before, *::after { transition-duration: .001ms !important; animation-duration: .001ms !important; } }
.card > :first-child { margin-top: 18px; }
+7 -6
View File
@@ -1,13 +1,14 @@
{ {
"name": "clip2md — Paste to Markdown", "name": "clip2md — Paste to Markdown",
"short_name": "clip2md", "short_name": "clip2md",
"description": "Paste rich text or a web page and save it as clean Markdown in one keystroke. Client-side, private, offline-capable.", "description": "Paste rich text or a web page and save it as clean Markdown in one click. Client-side, private, offline-capable.",
"start_url": ".", "start_url": "/",
"scope": ".", "scope": "/",
"display": "standalone", "display": "standalone",
"background_color": "#faf7f2", "background_color": "#EAEAE3",
"theme_color": "#faf7f2", "theme_color": "#EAEAE3",
"icons": [ "icons": [
{ "src": "icon.svg", "sizes": "any", "type": "image/svg+xml", "purpose": "any maskable" } { "src": "/icon.svg", "sizes": "any", "type": "image/svg+xml", "purpose": "any" },
{ "src": "/icon.svg", "sizes": "any", "type": "image/svg+xml", "purpose": "maskable" }
] ]
} }
+3
View File
@@ -38,7 +38,10 @@ server {
add_header Cache-Control "no-cache"; add_header Cache-Control "no-cache";
} }
# Pages and icons revalidate on every load, so a deploy reaches users immediately.
location / { location / {
include /etc/nginx/security-headers.conf;
add_header Cache-Control "no-cache";
try_files $uri $uri.html $uri/ /index.html; try_files $uri $uri.html $uri/ /index.html;
} }
} }
+48 -24
View File
@@ -1,19 +1,25 @@
/* clip2md service worker — offline shell cache. Bump CACHE on any asset change. */ /* clip2md service worker.
var CACHE = 'clip2md-v3'; Pages (navigations, .html): network first, cache only as offline fallback —
so new or changed pages are never frozen for existing users.
Static assets (vendor, fonts, icons): cache first. Bump CACHE on asset changes. */
var CACHE = 'clip2md-v4';
var ASSETS = [ var ASSETS = [
'./', '/',
'./index.html', '/index.html',
'./impressum.html', '/impressum.html',
'./datenschutz.html', '/datenschutz.html',
'./legal.css', '/legal.css',
'./icon.svg', '/icon.svg',
'./manifest.webmanifest', '/manifest.webmanifest',
'./vendor/turndown.js', '/vendor/turndown.js',
'./vendor/turndown-plugin-gfm.js', '/vendor/turndown-plugin-gfm.js',
'./vendor/marked.umd.js', '/vendor/marked.umd.js',
'./vendor/purify.min.js', '/vendor/purify.min.js',
'./vendor/fonts/Geist-Variable.woff2', '/vendor/fonts/space-grotesk-latin-400-normal.woff2',
'./vendor/fonts/GeistMono-Variable.woff2' '/vendor/fonts/space-grotesk-latin-500-normal.woff2',
'/vendor/fonts/space-grotesk-latin-700-normal.woff2',
'/vendor/fonts/space-mono-latin-400-normal.woff2',
'/vendor/fonts/space-mono-latin-700-normal.woff2'
]; ];
self.addEventListener('install', function (e) { self.addEventListener('install', function (e) {
@@ -29,18 +35,36 @@ self.addEventListener('activate', function (e) {
); );
}); });
function isPage(req, url) {
return req.mode === 'navigate' || req.destination === 'document' || /\.html$/.test(url.pathname) || url.pathname === '/';
}
self.addEventListener('fetch', function (e) { self.addEventListener('fetch', function (e) {
if (e.request.method !== 'GET') return; var req = e.request;
if (req.method !== 'GET') return;
var url = new URL(req.url);
if (url.origin !== self.location.origin) return; // external links (PayPal, GitHub) untouched
if (isPage(req, url)) {
e.respondWith( e.respondWith(
caches.match(e.request).then(function (hit) { fetch(req).then(function (res) {
return hit || fetch(e.request).then(function (res) { if (res && res.ok) { var copy = res.clone(); caches.open(CACHE).then(function (c) { c.put(req, copy); }); }
// Runtime-cache same-origin successful responses.
if (res && res.ok && e.request.url.indexOf(self.location.origin) === 0) {
var copy = res.clone();
caches.open(CACHE).then(function (c) { c.put(e.request, copy); });
}
return res; return res;
}).catch(function () { return caches.match('./index.html'); }); }).catch(function () {
return caches.match(req).then(function (hit) {
return hit || caches.match(url.pathname.replace(/\/$/, '/index.html')) || caches.match('/index.html');
});
})
);
return;
}
e.respondWith(
caches.match(req).then(function (hit) {
return hit || fetch(req).then(function (res) {
if (res && res.ok) { var copy = res.clone(); caches.open(CACHE).then(function (c) { c.put(req, copy); }); }
return res;
});
}) })
); );
}); });
Binary file not shown.
Binary file not shown.
+93
View File
@@ -0,0 +1,93 @@
Copyright 2020 The Space Grotesk Project Authors (https://github.com/floriankarsten/space-grotesk)
This Font Software is licensed under the SIL Open Font License, Version 1.1.
This license is copied below, and is also available with a FAQ at:
http://scripts.sil.org/OFL
-----------------------------------------------------------
SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
-----------------------------------------------------------
PREAMBLE
The goals of the Open Font License (OFL) are to stimulate worldwide
development of collaborative font projects, to support the font creation
efforts of academic and linguistic communities, and to provide a free and
open framework in which fonts may be shared and improved in partnership
with others.
The OFL allows the licensed fonts to be used, studied, modified and
redistributed freely as long as they are not sold by themselves. The
fonts, including any derivative works, can be bundled, embedded,
redistributed and/or sold with any software provided that any reserved
names are not used by derivative works. The fonts and derivatives,
however, cannot be released under any other type of license. The
requirement for fonts to remain under this license does not apply
to any document created using the fonts or their derivatives.
DEFINITIONS
"Font Software" refers to the set of files released by the Copyright
Holder(s) under this license and clearly marked as such. This may
include source files, build scripts and documentation.
"Reserved Font Name" refers to any names specified as such after the
copyright statement(s).
"Original Version" refers to the collection of Font Software components as
distributed by the Copyright Holder(s).
"Modified Version" refers to any derivative made by adding to, deleting,
or substituting -- in part or in whole -- any of the components of the
Original Version, by changing formats or by porting the Font Software to a
new environment.
"Author" refers to any designer, engineer, programmer, technical
writer or other person who contributed to the Font Software.
PERMISSION & CONDITIONS
Permission is hereby granted, free of charge, to any person obtaining
a copy of the Font Software, to use, study, copy, merge, embed, modify,
redistribute, and sell modified and unmodified copies of the Font
Software, subject to the following conditions:
1) Neither the Font Software nor any of its individual components,
in Original or Modified Versions, may be sold by itself.
2) Original or Modified Versions of the Font Software may be bundled,
redistributed and/or sold with any software, provided that each copy
contains the above copyright notice and this license. These can be
included either as stand-alone text files, human-readable headers or
in the appropriate machine-readable metadata fields within text or
binary files as long as those fields can be easily viewed by the user.
3) No Modified Version of the Font Software may use the Reserved Font
Name(s) unless explicit written permission is granted by the corresponding
Copyright Holder. This restriction only applies to the primary font name as
presented to the users.
4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
Software shall not be used to promote, endorse or advertise any
Modified Version, except to acknowledge the contribution(s) of the
Copyright Holder(s) and the Author(s) or with their explicit written
permission.
5) The Font Software, modified or unmodified, in part or in whole,
must be distributed entirely under this license, and must not be
distributed under any other license. The requirement for fonts to
remain under this license does not apply to any document created
using the Font Software.
TERMINATION
This license becomes null and void if any of the above conditions are
not met.
DISCLAIMER
THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
OTHER DEALINGS IN THE FONT SOFTWARE.
+93
View File
@@ -0,0 +1,93 @@
Copyright 2016 The Space Mono Project Authors (https://github.com/googlefonts/spacemono) SpaceMono-Italic.ttf: Copyright 2016 The Space Mono Project Authors (https://github.com/googlefonts/spacemono) SpaceMono-Bold.ttf: Copyright 2016 The Space Mono Project Authors (https://github.com/googlefonts/spacemono) SpaceMono-BoldItalic.ttf: Copyright 2016 The Space Mono Project Authors (https://github.com/googlefonts/spacemono)
This Font Software is licensed under the SIL Open Font License, Version 1.1.
This license is copied below, and is also available with a FAQ at:
http://scripts.sil.org/OFL
-----------------------------------------------------------
SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
-----------------------------------------------------------
PREAMBLE
The goals of the Open Font License (OFL) are to stimulate worldwide
development of collaborative font projects, to support the font creation
efforts of academic and linguistic communities, and to provide a free and
open framework in which fonts may be shared and improved in partnership
with others.
The OFL allows the licensed fonts to be used, studied, modified and
redistributed freely as long as they are not sold by themselves. The
fonts, including any derivative works, can be bundled, embedded,
redistributed and/or sold with any software provided that any reserved
names are not used by derivative works. The fonts and derivatives,
however, cannot be released under any other type of license. The
requirement for fonts to remain under this license does not apply
to any document created using the fonts or their derivatives.
DEFINITIONS
"Font Software" refers to the set of files released by the Copyright
Holder(s) under this license and clearly marked as such. This may
include source files, build scripts and documentation.
"Reserved Font Name" refers to any names specified as such after the
copyright statement(s).
"Original Version" refers to the collection of Font Software components as
distributed by the Copyright Holder(s).
"Modified Version" refers to any derivative made by adding to, deleting,
or substituting -- in part or in whole -- any of the components of the
Original Version, by changing formats or by porting the Font Software to a
new environment.
"Author" refers to any designer, engineer, programmer, technical
writer or other person who contributed to the Font Software.
PERMISSION & CONDITIONS
Permission is hereby granted, free of charge, to any person obtaining
a copy of the Font Software, to use, study, copy, merge, embed, modify,
redistribute, and sell modified and unmodified copies of the Font
Software, subject to the following conditions:
1) Neither the Font Software nor any of its individual components,
in Original or Modified Versions, may be sold by itself.
2) Original or Modified Versions of the Font Software may be bundled,
redistributed and/or sold with any software, provided that each copy
contains the above copyright notice and this license. These can be
included either as stand-alone text files, human-readable headers or
in the appropriate machine-readable metadata fields within text or
binary files as long as those fields can be easily viewed by the user.
3) No Modified Version of the Font Software may use the Reserved Font
Name(s) unless explicit written permission is granted by the corresponding
Copyright Holder. This restriction only applies to the primary font name as
presented to the users.
4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
Software shall not be used to promote, endorse or advertise any
Modified Version, except to acknowledge the contribution(s) of the
Copyright Holder(s) and the Author(s) or with their explicit written
permission.
5) The Font Software, modified or unmodified, in part or in whole,
must be distributed entirely under this license, and must not be
distributed under any other license. The requirement for fonts to
remain under this license does not apply to any document created
using the Font Software.
TERMINATION
This license becomes null and void if any of the above conditions are
not met.
DISCLAIMER
THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
OTHER DEALINGS IN THE FONT SOFTWARE.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.