Initial Pflegezeichen-Finder website

This commit is contained in:
2026-04-20 05:27:54 +00:00
commit 92ae48181a
25 changed files with 6296 additions and 0 deletions
+24
View File
@@ -0,0 +1,24 @@
# build output
dist/
# generated types
.astro/
# dependencies
node_modules/
# logs
npm-debug.log*
yarn-debug.log*
yarn-error.log*
pnpm-debug.log*
# environment variables
.env
.env.production
# macOS-specific files
.DS_Store
# jetbrains setting folder
.idea/
+4
View File
@@ -0,0 +1,4 @@
{
"recommendations": ["astro-build.astro-vscode"],
"unwantedRecommendations": []
}
+11
View File
@@ -0,0 +1,11 @@
{
"version": "0.2.0",
"configurations": [
{
"command": "./node_modules/.bin/astro dev",
"name": "Development server",
"request": "launch",
"type": "node-terminal"
}
]
}
+43
View File
@@ -0,0 +1,43 @@
# Pflegezeichen-Finder
Pflegezeichen-Finder ist eine schlanke Astro-Website für eine einfache SEO-Nische: Waschzeichen verstehen, Stoffe richtig pflegen und schnelle Antworten auf typische Waschfragen finden.
## Warum diese Nische
- klares Nutzerproblem im Alltag
- evergreen Suchanfragen
- viele Long-Tail-Seiten möglich
- sehr gut für Display-Werbung geeignet
## Tech
- Astro
- statische Seiten
- einfache CSS-Struktur
- AdSense-ready Platzhalter über `src/components/AdSlot.astro`
## Wichtige Routen
- `/`
- `/tools/pflegezeichen-finder`
- `/symbole/[slug]`
- `/stoffe/[slug]`
- `/ratgeber/[slug]`
- `/privacy-policy`
- `/legal-notice`
## Entwicklung
```bash
npm install
npm run dev
```
## Build
```bash
npm run build
npm run preview -- --host 0.0.0.0 --port 4477
```
## Google AdSense vorbereiten
Wenn später eine AdSense-Client-ID gesetzt wird, kann das Layout ohne Umbau Anzeigen ausspielen:
```bash
PUBLIC_ADSENSE_CLIENT=ca-pub-xxxxxxxxxxxxxxxx npm run build
```
+6
View File
@@ -0,0 +1,6 @@
// @ts-check
import { defineConfig } from 'astro/config';
export default defineConfig({
site: 'https://pflegezeichen-finder.de',
});
+4736
View File
File diff suppressed because it is too large Load Diff
+17
View File
@@ -0,0 +1,17 @@
{
"name": "pflegezeichen-finder",
"type": "module",
"version": "0.1.0",
"engines": {
"node": ">=22.12.0"
},
"scripts": {
"dev": "astro dev",
"build": "astro build",
"preview": "astro preview",
"astro": "astro"
},
"dependencies": {
"astro": "^6.1.8"
}
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 655 B

+5
View File
@@ -0,0 +1,5 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64" fill="none">
<rect width="64" height="64" rx="16" fill="#111827"/>
<path d="M18 20h28v6H18zM22 30h20v14H22z" fill="#fff"/>
<path d="M32 26c3.3 0 6 2.7 6 6v8H26v-8c0-3.3 2.7-6 6-6z" fill="#60A5FA"/>
</svg>

After

Width:  |  Height:  |  Size: 271 B

+4
View File
@@ -0,0 +1,4 @@
User-agent: *
Allow: /
Sitemap: https://pflegezeichen-finder.de/sitemap-index.xml
+31
View File
@@ -0,0 +1,31 @@
---
interface Props {
slot?: string;
label?: string;
className?: string;
}
const { slot, label = 'Anzeige', className = '' } = Astro.props;
const adsenseClient = import.meta.env.PUBLIC_ADSENSE_CLIENT;
---
<div class={`ad-slot ${className}`.trim()}>
<div class="ad-slot__label">{label}</div>
{
adsenseClient ? (
<ins
class="adsbygoogle"
style="display:block"
data-ad-client={adsenseClient}
data-ad-slot={slot}
data-ad-format="auto"
data-full-width-responsive="true"></ins>
) : (
<div class="ad-slot__placeholder">
Ruhiger Platzhalter für eine spätere Anzeige.
</div>
)
}
</div>
{adsenseClient && <script is:inline>(adsbygoogle = window.adsbygoogle || []).push({});</script>}
+98
View File
@@ -0,0 +1,98 @@
---
import type { SymbolItem } from '../data/content';
interface Props {
symbols: SymbolItem[];
compact?: boolean;
}
const { symbols, compact = false } = Astro.props;
const compactSymbols = compact ? symbols.slice(0, 6) : symbols;
const payload = JSON.stringify(compactSymbols);
---
<section class={`decoder ${compact ? 'decoder--compact' : ''}`} data-symbols={payload}>
<div class="decoder__controls">
<label class="field">
<span>Symbol oder Frage eingeben</span>
<input type="search" placeholder="z. B. Trockner, 30 Grad, Handwäsche" data-search />
</label>
<label class="field">
<span>Kategorie</span>
<select data-category>
<option value="alle">Alle</option>
<option value="Waschen">Waschen</option>
<option value="Bleichen">Bleichen</option>
<option value="Trocknen">Trocknen</option>
<option value="Bügeln">Bügeln</option>
<option value="Reinigung">Reinigung</option>
</select>
</label>
</div>
<div class="decoder__results" data-results>
{compactSymbols.map((symbol) => (
<article class="symbol-card" data-symbol-card>
<div class="symbol-card__top">
<span class="symbol-icon">{symbol.icon}</span>
<span class="symbol-category">{symbol.category}</span>
</div>
<h3>{symbol.name}</h3>
<p>{symbol.short}</p>
<a class="text-link" href={`/symbole/${symbol.slug}`}>Symbol erklären</a>
</article>
))}
</div>
<p class="decoder__empty" data-empty hidden>Keine Treffer. Versuch es mit „Handwäsche“, „Trockner“ oder „Bügeln“.</p>
{compact && (
<div class="decoder__footer">
<a class="button secondary" href="/tools/pflegezeichen-finder">Kompletten Finder öffnen</a>
</div>
)}
</section>
<script is:inline>
const root = document.currentScript?.previousElementSibling;
if (root && root.matches('.decoder')) {
const symbols = JSON.parse(root.getAttribute('data-symbols') || '[]');
const search = root.querySelector('[data-search]');
const category = root.querySelector('[data-category]');
const results = root.querySelector('[data-results]');
const empty = root.querySelector('[data-empty]');
const render = () => {
const query = (search?.value || '').trim().toLowerCase();
const categoryValue = category?.value || 'alle';
const filtered = symbols.filter((symbol) => {
const haystack = [symbol.name, symbol.short, symbol.category, symbol.meaning, ...symbol.doThis, ...symbol.avoidThis]
.join(' ')
.toLowerCase();
const queryMatch = !query || haystack.includes(query);
const categoryMatch = categoryValue === 'alle' || symbol.category === categoryValue;
return queryMatch && categoryMatch;
});
results.innerHTML = filtered
.map(
(symbol) => `
<article class="symbol-card">
<div class="symbol-card__top">
<span class="symbol-icon">${symbol.icon}</span>
<span class="symbol-category">${symbol.category}</span>
</div>
<h3>${symbol.name}</h3>
<p>${symbol.short}</p>
<a class="text-link" href="/symbole/${symbol.slug}">Symbol erklären</a>
</article>`
)
.join('');
empty.hidden = filtered.length > 0;
};
search?.addEventListener('input', render);
category?.addEventListener('change', render);
}
</script>
+364
View File
@@ -0,0 +1,364 @@
export type SymbolItem = {
slug: string;
name: string;
icon: string;
category: 'Waschen' | 'Bleichen' | 'Trocknen' | 'Bügeln' | 'Reinigung';
short: string;
meaning: string;
doThis: string[];
avoidThis: string[];
commonQuestions: { question: string; answer: string }[];
relatedFabrics: string[];
};
export type FabricGuide = {
slug: string;
name: string;
short: string;
washTemp: string;
dryRule: string;
ironing: string;
quickSteps: string[];
mistakes: string[];
};
export type GuideItem = {
slug: string;
title: string;
intent: string;
short: string;
intro: string;
steps: string[];
tips: string[];
};
export const symbols: SymbolItem[] = [
{
slug: 'waschbottich-30-grad',
name: 'Waschen bei 30 °C',
icon: '🛁 30°',
category: 'Waschen',
short: 'Das Kleidungsstück darf im Schon- oder Normalwaschgang bei 30 °C gewaschen werden.',
meaning: '30 Grad sind oft die sichere Standardtemperatur für empfindlichere Alltagskleidung, Prints und Mischgewebe.',
doThis: ['Farben trennen, wenn das Teil neu ist.', 'Mildes Waschmittel benutzen.', 'Nicht zu voll beladen, damit das Teil sauber wird.'],
avoidThis: ['Nicht unnötig auf 40 oder 60 Grad hochgehen.', 'Kein starkes Schleudern bei empfindlichen Stoffen.'],
commonQuestions: [
{ question: 'Reicht 30 Grad für normale Kleidung?', answer: 'Für leicht verschmutzte Alltagskleidung meistens ja. Bei Handtüchern oder Unterwäsche oft eher 40 oder 60 Grad prüfen.' },
{ question: 'Kann ich 30 Grad statt 40 Grad wählen?', answer: 'Oft ja, wenn das Kleidungsstück nicht stark verschmutzt ist. Das schont Farbe und Fasern.' }
],
relatedFabrics: ['baumwolle', 'viskose', 'polyester']
},
{
slug: 'waschbottich-40-grad',
name: 'Waschen bei 40 °C',
icon: '🛁 40°',
category: 'Waschen',
short: 'Das Teil kann bei 40 °C gewaschen werden und verträgt damit etwas mehr Reinigung.',
meaning: '40 Grad sind für viele Shirts, Bettwäsche und robustere Alltagstextilien ein guter Mittelweg.',
doThis: ['Normales Waschmittel verwenden.', 'Vor dem Waschen Taschen leeren und Reißverschlüsse schließen.', 'Helle und dunkle Kleidung weiter trennen.'],
avoidThis: ['Nicht automatisch mit 60 Grad waschen.', 'Empfindliche Drucke nicht auf links vergessen.'],
commonQuestions: [
{ question: 'Ist 40 Grad hygienischer als 30 Grad?', answer: 'Ja, in vielen Fällen schon. Es ist aber keine Desinfektion.' },
{ question: 'Kann Baumwolle meist 40 Grad ab?', answer: 'Viele Baumwollteile ja, das Etikett entscheidet aber.' }
],
relatedFabrics: ['baumwolle', 'leinen', 'polyester']
},
{
slug: 'handwaesche',
name: 'Nur Handwäsche',
icon: '✋🛁',
category: 'Waschen',
short: 'Das Teil sollte nicht in die normale Maschine, sondern von Hand gewaschen werden.',
meaning: 'Handwäsche ist meist für sehr empfindliche Fasern, Formteile oder dekorative Stücke gedacht.',
doThis: ['Lauwarmes Wasser benutzen.', 'Sanft drücken statt stark rubbeln.', 'Das Teil liegend trocknen, wenn es schwer wird.'],
avoidThis: ['Nicht wringen.', 'Nicht im normalen Schleudergang waschen.'],
commonQuestions: [
{ question: 'Geht stattdessen das Handwaschprogramm?', answer: 'Manchmal ja, aber nur wenn das Etikett oder der Hersteller das erlaubt.' },
{ question: 'Wie lange einweichen?', answer: 'Kurz reicht meistens. Zu langes Einweichen kann Farben und Form belasten.' }
],
relatedFabrics: ['wolle', 'seide', 'kaschmir']
},
{
slug: 'nicht-waschen',
name: 'Nicht waschen',
icon: '🛁✕',
category: 'Waschen',
short: 'Das Kleidungsstück gehört nicht in Wasser und sollte anders gereinigt werden.',
meaning: 'Dieses Symbol findest du oft bei Jacken, formstabilen Teilen oder Materialien, die durch Wasser Schaden nehmen.',
doThis: ['Pflegehinweis des Herstellers lesen.', 'Auf Reinigungssymbole daneben achten.', 'Flecken nur punktuell und vorsichtig behandeln.'],
avoidThis: ['Nicht probeweise in die Maschine werfen.', 'Nicht komplett einweichen.'],
commonQuestions: [
{ question: 'Kann ich es trotzdem im Schonwaschgang versuchen?', answer: 'Besser nicht. Das Risiko für Formverlust oder Materialschäden ist hoch.' },
{ question: 'Was mache ich bei Geruch?', answer: 'Oft hilft Lüften oder eine professionelle Reinigung.' }
],
relatedFabrics: ['leder', 'wolle']
},
{
slug: 'bleichen-erlaubt',
name: 'Bleichen erlaubt',
icon: '△',
category: 'Bleichen',
short: 'Das Teil darf gebleicht werden, wenn es nötig ist.',
meaning: 'Das Symbol zeigt, dass der Stoff mit geeigneten Bleichmitteln behandelt werden kann.',
doThis: ['Nur dosiert verwenden.', 'Vorher Farbbeständigkeit prüfen.', 'Sauerstoffbleiche im Zweifel zuerst testen.'],
avoidThis: ['Nicht blind mit Chlor starten.', 'Nicht bei empfindlichen Farben einsetzen.'],
commonQuestions: [
{ question: 'Muss ich überhaupt bleichen?', answer: 'Nein. Es ist nur erlaubt, nicht notwendig.' },
{ question: 'Ist Sauerstoffbleiche oft die sanftere Wahl?', answer: 'Ja, in vielen Haushalten ist sie die alltagstauglichere Variante.' }
],
relatedFabrics: ['baumwolle', 'leinen']
},
{
slug: 'nicht-bleichen',
name: 'Nicht bleichen',
icon: '△✕',
category: 'Bleichen',
short: 'Kein Bleichmittel verwenden.',
meaning: 'Bleichmittel können Farbe, Druck oder Fasern angreifen. Dieses Symbol ist bei farbiger Kleidung sehr häufig.',
doThis: ['Normales Colorwaschmittel nutzen.', 'Bei Flecken lieber gezielt vorbehandeln.', 'Sanfte Sauerstoffprodukte nur verwenden, wenn der Hersteller es erlaubt.'],
avoidThis: ['Keine Chlorbleiche.', 'Keine aggressiven Fleckenmittel ohne Test.'],
commonQuestions: [
{ question: 'Warum ist das so wichtig?', answer: 'Weil Bleichmittel Farben schnell auswaschen oder Material schwächen können.' },
{ question: 'Was hilft stattdessen gegen Flecken?', answer: 'Schnelles Ausspülen und eine passende, milde Vorbehandlung.' }
],
relatedFabrics: ['viskose', 'seide', 'polyester']
},
{
slug: 'trockner-niedrige-temperatur',
name: 'Trockner bei niedriger Temperatur',
icon: '◻︎•',
category: 'Trocknen',
short: 'Das Teil darf in den Trockner, aber eher sanft und nicht zu heiß.',
meaning: 'Niedrige Temperatur schont Fasern, Elastan und Drucke.',
doThis: ['Schonprogramm wählen.', 'Teil früh herausnehmen, wenn es fast trocken ist.', 'Auf links trocknen, wenn ein Druck vorhanden ist.'],
avoidThis: ['Kein heißes Standardprogramm.', 'Nicht zu lange nachtrocknen.'],
commonQuestions: [
{ question: 'Warum lieber niedrige Temperatur?', answer: 'Weil Hitze viele Stoffe schneller altern lässt.' },
{ question: 'Kann das Teil leicht einlaufen?', answer: 'Ja, besonders bei Mischgewebe mit Baumwolle.' }
],
relatedFabrics: ['baumwolle', 'polyester']
},
{
slug: 'nicht-im-trockner',
name: 'Nicht im Trockner trocknen',
icon: '◻︎○✕',
category: 'Trocknen',
short: 'Das Teil sollte lufttrocknen und nicht in den Trockner.',
meaning: 'Hitze oder Bewegung im Trockner könnte Form, Oberfläche oder Elastizität beschädigen.',
doThis: ['An der Luft trocknen.', 'Form nach dem Waschen glattziehen.', 'Bei schweren Teilen liegend trocknen.'],
avoidThis: ['Nicht schnell mit heißer Luft nachtrocknen.', 'Nicht ignorieren, nur weil es eilig ist.'],
commonQuestions: [
{ question: 'Was ist die sichere Alternative?', answer: 'Lufttrocknen auf einem Wäscheständer oder liegend, je nach Stoff.' },
{ question: 'Gilt das auch für Sportkleidung?', answer: 'Sehr oft ja. Viele Funktionsstoffe mögen keine hohe Hitze.' }
],
relatedFabrics: ['wolle', 'viskose', 'elastan']
},
{
slug: 'liegend-trocknen',
name: 'Liegend trocknen',
icon: '▭',
category: 'Trocknen',
short: 'Das Teil sollte flach ausgelegt trocknen.',
meaning: 'So verzieht sich der Stoff weniger und schwere, nasse Fasern hängen nicht aus.',
doThis: ['Auf ein Handtuch legen.', 'In Form ziehen.', 'Nicht in direkter Sonne trocknen, wenn Farbe empfindlich ist.'],
avoidThis: ['Nicht aufhängen, wenn das Teil schwer wird.', 'Nicht auf die Heizung legen.'],
commonQuestions: [
{ question: 'Bei welchen Stoffen ist das wichtig?', answer: 'Vor allem bei Wolle, Strick und manchen feinen Oberteilen.' },
{ question: 'Brauche ich einen speziellen Trocknerost?', answer: 'Nicht zwingend. Ein sauberes Handtuch reicht oft.' }
],
relatedFabrics: ['wolle', 'kaschmir', 'viskose']
},
{
slug: 'buegeln-niedrig',
name: 'Bügeln bei niedriger Temperatur',
icon: '🧺•',
category: 'Bügeln',
short: 'Nur mit niedriger Hitze bügeln.',
meaning: 'Das Symbol ist typisch für empfindliche Fasern und Mischgewebe, die auf starke Hitze reagieren.',
doThis: ['Wenn möglich auf links bügeln.', 'Ein Tuch dazwischen legen.', 'Mit wenig Dampf starten.'],
avoidThis: ['Nicht direkt auf Drucke gehen.', 'Keine hohe Leinen- oder Baumwollstufe wählen.'],
commonQuestions: [
{ question: 'Was ist niedrige Temperatur ungefähr?', answer: 'Oft die erste Stufe oder ein Synthetik-Programm am Bügeleisen.' },
{ question: 'Kann ich stattdessen steamen?', answer: 'Häufig ja, wenn der Stoff darauf gut reagiert.' }
],
relatedFabrics: ['viskose', 'polyester', 'seide']
},
{
slug: 'nicht-buegeln',
name: 'Nicht bügeln',
icon: '🧺✕',
category: 'Bügeln',
short: 'Das Teil sollte nicht gebügelt werden.',
meaning: 'Hitze kann die Oberfläche beschädigen, den Stoff glänzend machen oder Drucke zerstören.',
doThis: ['Nach dem Waschen glatt ausschütteln.', 'Aufhängen oder liegend in Form trocknen.', 'Wenn nötig nur vorsichtig mit Dampf auf Abstand arbeiten.'],
avoidThis: ['Kein direkter Kontakt mit dem Bügeleisen.', 'Nicht mit hoher Restwärme experimentieren.'],
commonQuestions: [
{ question: 'Wie bekomme ich Falten dann raus?', answer: 'Oft hilft Dampfbad im Bad oder ein Steamer mit Abstand.' },
{ question: 'Gilt das auch für Druckshirts?', answer: 'Ja, bei Prints ist Vorsicht besonders wichtig.' }
],
relatedFabrics: ['elastan', 'polyester']
},
{
slug: 'chemische-reinigung',
name: 'Chemische Reinigung möglich',
icon: '◯ P',
category: 'Reinigung',
short: 'Das Teil kann professionell gereinigt werden.',
meaning: 'Dieses Symbol richtet sich vor allem an Reinigungen, zeigt dir aber auch: nicht einfach normal waschen.',
doThis: ['Bei hochwertigen Teilen lieber abgeben.', 'Flecken kurz beschreiben, wenn du das Teil abgibst.', 'Etikett dranlassen.'],
avoidThis: ['Nicht selbst aggressive Mittel probieren.', 'Nicht ohne weitere Prüfung in die Maschine geben.'],
commonQuestions: [
{ question: 'Muss ich immer in die Reinigung?', answer: 'Wenn zusätzlich kein Waschsymbol erlaubt ist, meist ja.' },
{ question: 'Was sage ich in der Reinigung?', answer: 'Material, Fleck und ob das Teil empfindlich ist. Mehr braucht es oft nicht.' }
],
relatedFabrics: ['wolle', 'leder', 'seide']
}
];
export const fabrics: FabricGuide[] = [
{
slug: 'baumwolle',
name: 'Baumwolle',
short: 'Robust, alltagstauglich und in vielen T-Shirts, Bettwäschen und Basics zu finden.',
washTemp: 'Oft 30 bis 40 °C, bei Handtüchern oder Unterwäsche teils mehr.',
dryRule: 'Trockner nur, wenn das Etikett es erlaubt. Sonst lufttrocknen.',
ironing: 'Meist gut bügelbar, oft mittlere bis höhere Temperatur.',
quickSteps: ['Nach Farben sortieren.', 'Bei Prints auf links waschen.', 'Nicht unnötig zu heiß trocknen.'],
mistakes: ['Zu heiß trocknen und dadurch Einlaufen riskieren.', 'Weiße Baumwolle mit stark färbenden Teilen zusammen waschen.']
},
{
slug: 'leinen',
name: 'Leinen',
short: 'Atmungsaktiv, kühl und beliebt im Sommer, aber etwas knitterfreudig.',
washTemp: 'Meist 30 bis 40 °C, je nach Verarbeitung.',
dryRule: 'Lieber lufttrocknen und leicht feucht in Form ziehen.',
ironing: 'Lässt sich oft gut im leicht feuchten Zustand glätten.',
quickSteps: ['Schonend schleudern.', 'Nicht übertrocknen.', 'Falten eher akzeptieren als wegquälen.'],
mistakes: ['Leinen im heißen Trockner hart und steif werden lassen.', 'Zu stark schleudern.']
},
{
slug: 'wolle',
name: 'Wolle',
short: 'Warm, empfindlich und schnell beleidigt, wenn Hitze oder Reibung ins Spiel kommen.',
washTemp: 'Eher kalt oder speziell laut Etikett.',
dryRule: 'Nie heiß trocknen. Meist liegend trocknen.',
ironing: 'Wenn überhaupt, sehr vorsichtig und mit wenig Hitze.',
quickSteps: ['Wollwaschmittel nutzen.', 'Nicht wringen.', 'Liegend auf einem Handtuch trocknen.'],
mistakes: ['Temperaturwechsel zwischen Waschen und Spülen.', 'Normales Waschprogramm mit viel Bewegung.']
},
{
slug: 'seide',
name: 'Seide',
short: 'Glatt, fein und schön, aber empfindlich gegen Reibung, Hitze und aggressive Mittel.',
washTemp: 'Sehr sanft, oft Handwäsche oder Spezialprogramm.',
dryRule: 'An der Luft trocknen, nicht in direkter Sonne.',
ironing: 'Nur sehr niedrig und am besten auf links.',
quickSteps: ['Mildes Spezialwaschmittel wählen.', 'Kurz waschen.', 'Keine starken Fleckenmittel nutzen.'],
mistakes: ['Zu lange einweichen.', 'Mit groben Stoffen zusammen waschen.']
},
{
slug: 'viskose',
name: 'Viskose',
short: 'Fällt schön, ist aber im nassen Zustand oft empfindlicher als gedacht.',
washTemp: 'Meist 30 °C und eher sanft.',
dryRule: 'Lieber lufttrocknen und in Form ziehen.',
ironing: 'Niedrige bis mittlere Hitze, oft auf links.',
quickSteps: ['Schonprogramm nutzen.', 'Nicht stark schleudern.', 'Nass nicht hart ziehen.'],
mistakes: ['Zu viel Reibung in der Trommel.', 'Heiß trocknen.']
},
{
slug: 'polyester',
name: 'Polyester',
short: 'Pflegeleicht, schnell trocknend und in Sport- und Alltagskleidung weit verbreitet.',
washTemp: 'Oft 30 bis 40 °C.',
dryRule: 'Viele Teile lieber nicht heiß trocknen.',
ironing: 'Nur niedrig, wenn überhaupt.',
quickSteps: ['Nicht überdosiert waschen.', 'Sportteile zügig trocknen.', 'Weichspüler bei Funktionskleidung eher vermeiden.'],
mistakes: ['Zu hohe Hitze beim Bügeln.', 'Sportgeruch durch langes Liegenlassen verstärken.']
},
{
slug: 'kaschmir',
name: 'Kaschmir',
short: 'Weich, teuer und deutlich sensibler als normale Wolle.',
washTemp: 'Sehr schonend, eher kalt.',
dryRule: 'Immer liegend trocknen.',
ironing: 'Nur wenn nötig, sehr vorsichtig.',
quickSteps: ['Sehr wenig Bewegung.', 'Kurz waschen.', 'Pilling später sanft entfernen statt hart zu reiben.'],
mistakes: ['Aufhängen im nassen Zustand.', 'Heizungstrocknung.']
},
{
slug: 'elastan',
name: 'Elastan-Mischungen',
short: 'Sorgt für Dehnung, mag aber Hitze meistens gar nicht.',
washTemp: 'Meist 30 °C oder laut Etikett.',
dryRule: 'Kein heißer Trockner.',
ironing: 'Oft gar nicht oder nur sehr niedrig.',
quickSteps: ['Schonend waschen.', 'Nicht überhitzen.', 'Sport- und Passformteile gut ausschütteln und lufttrocknen.'],
mistakes: ['Hohe Trocknerhitze.', 'Direktes Bügeln auf elastischen Bereichen.']
}
];
export const guides: GuideItem[] = [
{
slug: 'weisse-waesche-richtig-waschen',
title: 'Weiße Wäsche richtig waschen',
intent: 'Weiße Kleidung soll sauber bleiben, ohne grau oder gelb zu werden.',
short: 'So bleibt Weiß länger ruhig, sauber und nicht fleckig-grau.',
intro: 'Weiße Wäsche wirkt unkompliziert, wird aber schnell stumpf, wenn Temperatur, Waschmittel oder Sortierung nicht passen.',
steps: ['Weiße Teile separat sammeln.', 'Temperatur am Etikett prüfen.', 'Geeignetes Waschmittel nutzen.', 'Maschine nicht überfüllen.', 'Feucht nicht ewig liegen lassen.'],
tips: ['Neue weiße Teile die ersten Male separat waschen.', 'Bei starken Flecken lieber gezielt vorbehandeln statt alles heißer zu waschen.', 'Sonne kann bei manchen weißen Textilien beim Trocknen helfen.']
},
{
slug: 'schwarze-kleidung-waschen',
title: 'Schwarze Kleidung waschen, ohne dass sie schnell verblasst',
intent: 'Dunkle Kleidung soll ihre Farbe behalten.',
short: 'Weniger Reibung, weniger Hitze, weniger unnötige Waschpower.',
intro: 'Schwarz wirkt schnell stumpf, wenn Kleidung zu heiß, zu voll oder mit ungeeignetem Waschmittel gewaschen wird.',
steps: ['Auf links waschen.', 'Farben getrennt halten.', 'Mildes Waschmittel für Dunkles nutzen.', '30 oder 40 Grad nur wenn nötig.', 'Nicht in praller Sonne trocknen.'],
tips: ['Je seltener unnötig gewaschen wird, desto länger bleibt Schwarz satt.', 'Zu viel Waschmittel hilft der Farbe nicht.', 'Der Trockner kann Farbe und Oberfläche zusätzlich stressen.']
},
{
slug: 'sportkleidung-waschen',
title: 'Sportkleidung waschen, ohne Funktion und Form zu ruinieren',
intent: 'Funktionskleidung soll sauber werden, aber elastisch und atmungsaktiv bleiben.',
short: 'Geruch raus, Material heil.',
intro: 'Sportkleidung ist oft pflegeleicht, reagiert aber empfindlich auf Weichspüler, Hitze und zu langes Liegenlassen.',
steps: ['Nach dem Tragen nicht im Beutel vergessen.', 'Schonend bei niedriger Temperatur waschen.', 'Weichspüler weglassen.', 'Lufttrocknen statt heiß trocknen.', 'Reißverschlüsse schließen.'],
tips: ['Bei starkem Geruch hilft oft schnelles Waschen mehr als höheres Waschen.', 'Funktionsshirts mögen meistens keinen Trockner.', 'Pflegeetikett ist wichtiger als Gewohnheit.']
},
{
slug: 'handtuecher-waschen',
title: 'Handtücher waschen: sauber, frisch und nicht kratzig',
intent: 'Handtücher sollen hygienisch und angenehm bleiben.',
short: 'Die Balance zwischen sauber und weich ist einfacher, als sie wirkt.',
intro: 'Handtücher brauchen oft etwas mehr Reinigung als normale Kleidung, aber auch hier bringt zu viel nicht automatisch bessere Ergebnisse.',
steps: ['Nach Farben sortieren.', 'Etikett prüfen.', 'Nicht mit feinen Teilen mischen.', 'Genug Platz in der Trommel lassen.', 'Gut durchtrocknen lassen.'],
tips: ['Zu viel Waschmittel kann Handtücher stumpf machen.', 'Feuchte Handtücher nie lange zusammenliegen lassen.', 'Trockner nur laut Etikett.']
},
{
slug: 'oelfleck-entfernen',
title: 'Ölfleck aus Kleidung entfernen',
intent: 'Frischer Öl- oder Fettfleck soll ohne dauerhaften Rand verschwinden.',
short: 'Schnelligkeit hilft mehr als Härte.',
intro: 'Bei Öl zählt oft die erste Minute. Je weniger du den Fleck einarbeitest, desto besser.',
steps: ['Überschüssiges Öl vorsichtig abtupfen.', 'Nicht rubbeln.', 'Mild vorbehandeln.', 'Etikett prüfen.', 'Erst trocknen, wenn der Fleck wirklich weg ist.'],
tips: ['Hitze fixiert manche Flecken.', 'Vorbehandlung lieber lokal als die ganze Wäsche härter fahren.', 'Helle Stoffe besonders früh prüfen.']
},
{
slug: 'deoflecken-behandeln',
title: 'Deoflecken und Achselränder behandeln',
intent: 'Rückstände sollen weg, ohne Stoff oder Farbe zu ruinieren.',
short: 'Geduldig und gezielt ist besser als aggressiv.',
intro: 'Deoflecken sind oft eine Mischung aus Produktresten, Schweiß und Waschgewohnheit. Deshalb hilft meist eine ruhige Vorbehandlung.',
steps: ['Fleck anfeuchten.', 'Mild vorbehandeln.', 'Nicht zu stark reiben.', 'Laut Etikett waschen.', 'Vor dem Trocknen prüfen.'],
tips: ['Dunkle Stoffe nicht zu aggressiv behandeln.', 'Rückstände lieber früh angehen.', 'Wechsel zwischen Produkt und Waschmittel kann helfen.']
}
];
export const categoryIntro = {
Waschen: 'Hier geht es um Temperatur, Schonprogramme und die Frage, ob ein Teil überhaupt in Wasser darf.',
Bleichen: 'Diese Symbole regeln, ob Bleichmittel erlaubt sind oder besser komplett wegbleiben.',
Trocknen: 'Trocknersymbole helfen dir dabei, Einlaufen, Verziehen und Materialstress zu vermeiden.',
Bügeln: 'Bügelsymbole zeigen vor allem eins: wie viel Hitze ein Stoff wirklich verträgt.',
Reinigung: 'Reinigungssymbole betreffen meist professionelle Pflege und sind wichtig bei empfindlichen Stücken.'
};
+10
View File
@@ -0,0 +1,10 @@
export const privacyHighlights = [
'Für das reine Lesen der Inhalte ist kein Konto nötig.',
'Später eingebundene Werbeanzeigen können Cookies oder ähnliche Technologien nutzen.',
'Externe Links, etwa zu Herstellerhinweisen oder Suchmaschinen, können eigene Datenschutzregeln haben.',
];
export const adDisclosure = {
title: 'Hinweis zu Werbung',
text: 'Die Website ist so vorbereitet, dass später Google AdSense eingebunden werden kann. Anzeigenplätze sind bewusst als ruhige Platzhalter angelegt, damit sie sich ohne Umbau integrieren lassen.'
};
+23
View File
@@ -0,0 +1,23 @@
export const site = {
name: 'Pflegezeichen-Finder',
domain: 'https://pflegezeichen-finder.de',
language: 'de',
title: 'Pflegezeichen-Finder | Waschzeichen verstehen und Kleidung richtig pflegen',
description:
'Verstehe Waschzeichen in wenigen Sekunden. Finde einfache Erklärungen zu Pflegesymbolen, Stoffen, Flecken und Waschregeln für den Alltag.',
tagline: 'Waschzeichen verstehen, Stoffe richtig pflegen, Kleidung länger tragen.',
heroTitle: 'Verstehe Waschzeichen in wenigen Sekunden.',
heroText:
'Pflegezeichen-Finder erklärt Symbole auf dem Etikett, zeigt dir passende Waschregeln und hilft dir bei typischen Fragen zu Stoffen, Flecken und Trocknung.',
adsenseNote: 'Die Seitenstruktur ist bewusst so gebaut, dass Google AdSense später leicht ergänzt werden kann.',
};
export const company = {
name: 'Pflegezeichen-Finder',
owner: 'Justin Michael Eckenweber',
email: 'hey@unverpackt-finder.de',
phone: '028160031948',
addressLine1: 'Rühlestraße 5',
addressLine2: '45147 Essen',
addressLine3: 'Deutschland',
};
+64
View File
@@ -0,0 +1,64 @@
---
import '../styles/global.css';
import { company, site } from '../data/site';
interface Props {
title?: string;
description?: string;
}
const { title = site.title, description = site.description } = Astro.props;
const canonical = new URL(Astro.url.pathname, site.domain).toString();
const adsenseClient = import.meta.env.PUBLIC_ADSENSE_CLIENT;
---
<html lang={site.language}>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta name="generator" content={Astro.generator} />
<meta name="description" content={description} />
<link rel="canonical" href={canonical} />
<link rel="icon" type="image/svg+xml" href="/favicon.svg" />
<link rel="icon" href="/favicon.ico" />
<meta property="og:type" content="website" />
<meta property="og:site_name" content={site.name} />
<meta property="og:title" content={title} />
<meta property="og:description" content={description} />
<meta property="og:url" content={canonical} />
<meta name="twitter:card" content="summary_large_image" />
<meta name="twitter:title" content={title} />
<meta name="twitter:description" content={description} />
<title>{title}</title>
{adsenseClient && (
<script async src={`https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js?client=${adsenseClient}`} crossorigin="anonymous"></script>
)}
</head>
<body>
<header class="site-header">
<div class="container nav">
<a class="brand" href="/">{site.name}</a>
<nav class="nav-links" aria-label="Hauptnavigation">
<a href="/#finder">Finder</a>
<a href="/#symbole">Symbole</a>
<a href="/#stoffe">Stoffe</a>
<a href="/#ratgeber">Ratgeber</a>
</nav>
</div>
</header>
<slot />
<footer class="footer">
<div class="container footer-inner">
<div class="footer-copy">
<strong>{company.name}</strong> — einfache Hilfe rund um Waschzeichen, Stoffpflege und Wäsche-Alltag.
</div>
<div class="footer-links">
<a href="/">Start</a>
<a href="/tools/pflegezeichen-finder">Finder</a>
<a href="/privacy-policy">Datenschutz</a>
<a href="/legal-notice">Impressum</a>
</div>
</div>
</footer>
</body>
</html>
+143
View File
@@ -0,0 +1,143 @@
---
import BaseLayout from '../layouts/BaseLayout.astro';
import DecoderTool from '../components/DecoderTool.astro';
import AdSlot from '../components/AdSlot.astro';
import { site } from '../data/site';
import { symbols, fabrics, guides } from '../data/content';
---
<BaseLayout>
<main>
<section class="hero">
<div class="container hero-grid">
<div>
<span class="eyebrow">Schnelle Hilfe für echte Alltagsfragen</span>
<h1>{site.heroTitle}</h1>
<p>{site.heroText}</p>
<div class="button-row">
<a class="button primary" href="#finder">Jetzt Symbol suchen</a>
<a class="button secondary" href="#ratgeber">Beliebte Waschfragen</a>
</div>
<div class="stats">
<span><strong>{symbols.length}</strong> häufige Pflegesymbole</span>
<span><strong>{fabrics.length}</strong> Stoff-Guides</span>
<span><strong>{guides.length}</strong> schnelle Ratgeber</span>
</div>
</div>
<div class="simple-panel hero-note">
<h2>Wofür die Seite gebaut ist</h2>
<p>
Pflegeetiketten sind klein, uneinheitlich und im Alltag oft unklar. Die meisten Leute wollen keine lange
Theorie. Sie wollen schnell wissen: Darf das in den Trockner, wie heiß darf ich waschen und was ist bei
empfindlichen Stoffen sicher?
</p>
<p>
Genau darauf ist Pflegezeichen-Finder ausgerichtet: kurze Antworten, gut lesbare Seiten und ein Aufbau, der
sich auch auf dem Handy schnell erfassen lässt.
</p>
</div>
</div>
</section>
<section id="finder" class="section">
<div class="container">
<span class="eyebrow">Pflegezeichen-Finder</span>
<h2>Such dir direkt das passende Symbol oder Thema heraus</h2>
<p class="section-intro">
Gib einen Begriff ein oder filtere nach Kategorie. So kommst du ohne Umweg zur richtigen Erklärung.
</p>
<DecoderTool symbols={symbols} compact={true} />
</div>
</section>
<section class="section section--soft">
<div class="container">
<AdSlot label="Anzeigeplatz" />
</div>
</section>
<section id="symbole" class="section">
<div class="container">
<span class="eyebrow">Beliebte Symbole</span>
<h2>Häufig gesuchte Waschzeichen</h2>
<div class="list-block">
{symbols.slice(0, 8).map((symbol) => (
<article class="list-row">
<div class="list-row__meta">{symbol.category}</div>
<div>
<h3>{symbol.name}</h3>
<p>{symbol.short}</p>
</div>
<div class="list-row__action">
<a class="text-link" href={`/symbole/${symbol.slug}`}>Öffnen</a>
</div>
</article>
))}
</div>
</div>
</section>
<section id="stoffe" class="section">
<div class="container">
<span class="eyebrow">Stoffpflege</span>
<h2>Wenn das Symbol klar ist, kommt der Stoff</h2>
<div class="three-col-grid">
{fabrics.map((fabric) => (
<article class="info-card">
<h3>{fabric.name}</h3>
<p>{fabric.short}</p>
<ul class="simple-list compact-list">
<li><strong>Waschen:</strong> {fabric.washTemp}</li>
<li><strong>Trocknen:</strong> {fabric.dryRule}</li>
</ul>
<a class="text-link" href={`/stoffe/${fabric.slug}`}>Stoff-Guide lesen</a>
</article>
))}
</div>
</div>
</section>
<section id="ratgeber" class="section">
<div class="container">
<span class="eyebrow">Ratgeber</span>
<h2>Kurze Antworten auf typische Waschfragen</h2>
<div class="list-block">
{guides.map((guide) => (
<article class="list-row list-row--guide">
<div class="list-row__meta">Hilfe im Alltag</div>
<div>
<h3>{guide.title}</h3>
<p>{guide.short}</p>
</div>
<div class="list-row__action">
<a class="text-link" href={`/ratgeber/${guide.slug}`}>Lesen</a>
</div>
</article>
))}
</div>
</div>
</section>
<section class="section">
<div class="container two-col">
<div>
<span class="eyebrow">Schnell verstanden</span>
<h2>Was du hier in kurzer Zeit findest</h2>
<p>
Du musst nicht erst raten, ob ein Zeichen streng oder nur vorsichtig gemeint ist. Die Seiten sind so gebaut,
dass du erst die direkte Antwort bekommst und dann, wenn nötig, noch die praktische Einordnung dazu.
</p>
</div>
<div class="simple-panel">
<h2>Typische Fragen, die die Seite löst</h2>
<ul class="simple-list">
<li>Darf dieses Teil in den Trockner?</li>
<li>Wie wasche ich Wolle oder Viskose, ohne sie zu ruinieren?</li>
<li>Welche Temperatur ist für schwarze oder weiße Kleidung sinnvoll?</li>
<li>Was hilft bei Öl- oder Deoflecken, ohne alles härter zu waschen?</li>
</ul>
</div>
</div>
</section>
</main>
</BaseLayout>
+30
View File
@@ -0,0 +1,30 @@
---
import BaseLayout from '../layouts/BaseLayout.astro';
import { company } from '../data/site';
---
<BaseLayout title="Impressum | Pflegezeichen-Finder" description="Impressum von Pflegezeichen-Finder.">
<main class="section legal-page">
<div class="container narrow">
<span class="eyebrow">Rechtliches</span>
<h1>Impressum</h1>
<p>
Angaben gemäß § 5 TMG
</p>
<p>
{company.owner}<br />
{company.addressLine1}<br />
{company.addressLine2}<br />
{company.addressLine3}
</p>
<p>
Kontakt<br />
E-Mail: {company.email}<br />
Telefon: {company.phone}
</p>
<p>
Inhaltlich verantwortlich: {company.owner}
</p>
</div>
</main>
</BaseLayout>
+41
View File
@@ -0,0 +1,41 @@
---
import BaseLayout from '../layouts/BaseLayout.astro';
import { company } from '../data/site';
import { privacyHighlights, adDisclosure } from '../data/legal';
---
<BaseLayout title="Datenschutz | Pflegezeichen-Finder" description="Datenschutzhinweise für Pflegezeichen-Finder.">
<main class="section legal-page">
<div class="container narrow">
<span class="eyebrow">Rechtliches</span>
<h1>Datenschutz</h1>
<p>
Diese Website informiert über Waschzeichen, Stoffpflege und Wäschetipps. Beim bloßen Besuch der Seiten ist kein
Nutzerkonto nötig.
</p>
<section class="content-section">
<h2>Verantwortlich</h2>
<p>
{company.owner}<br />
{company.addressLine1}<br />
{company.addressLine2}<br />
{company.addressLine3}
</p>
<p>E-Mail: {company.email}</p>
</section>
<section class="content-section">
<h2>Grundsätzliches</h2>
<ul class="simple-list">
{privacyHighlights.map((item) => <li>{item}</li>)}
</ul>
</section>
<section class="content-section">
<h2>{adDisclosure.title}</h2>
<p>{adDisclosure.text}</p>
</section>
</div>
</main>
</BaseLayout>
+53
View File
@@ -0,0 +1,53 @@
---
import BaseLayout from '../../layouts/BaseLayout.astro';
import AdSlot from '../../components/AdSlot.astro';
import { guides } from '../../data/content';
export function getStaticPaths() {
return guides.map((guide) => ({ params: { slug: guide.slug }, props: { guide } }));
}
const { guide } = Astro.props;
---
<BaseLayout title={`${guide.title} | Pflegezeichen-Finder`} description={guide.short}>
<main class="section">
<div class="container detail-grid detail-grid--wide">
<article>
<span class="eyebrow">Ratgeber</span>
<h1>{guide.title}</h1>
<p class="lead">{guide.intro}</p>
<section class="content-section">
<h2>Worum es hier geht</h2>
<p>{guide.intent}</p>
</section>
<section class="content-section">
<h2>Praktische Schritte</h2>
<ol class="number-list">
{guide.steps.map((step) => <li>{step}</li>)}
</ol>
</section>
<section class="content-section">
<h2>Nützliche Hinweise</h2>
<ul class="simple-list">
{guide.tips.map((tip) => <li>{tip}</li>)}
</ul>
</section>
</article>
<aside>
<div class="simple-panel sticky-panel">
<h2>Kurz gedacht, damit es schnell hilft</h2>
<p>
Diese Ratgeber sind absichtlich knapp geschrieben. Erst die direkte Hilfe, dann die Einordnung. Genau das
macht solche Seiten im Alltag nützlich.
</p>
</div>
<AdSlot className="ad-slot--stack" />
</aside>
</div>
</main>
</BaseLayout>
+59
View File
@@ -0,0 +1,59 @@
---
import BaseLayout from '../../layouts/BaseLayout.astro';
import AdSlot from '../../components/AdSlot.astro';
import { fabrics, symbols } from '../../data/content';
export function getStaticPaths() {
return fabrics.map((fabric) => ({ params: { slug: fabric.slug }, props: { fabric } }));
}
const { fabric } = Astro.props;
const relatedSymbols = symbols.filter((symbol) => symbol.relatedFabrics.includes(fabric.slug)).slice(0, 5);
---
<BaseLayout title={`${fabric.name} richtig waschen | Pflegezeichen-Finder`} description={fabric.short}>
<main class="section">
<div class="container detail-grid detail-grid--wide">
<article>
<span class="eyebrow">Stoff-Guide</span>
<h1>{fabric.name} richtig pflegen</h1>
<p class="lead">{fabric.short}</p>
<section class="content-section">
<h2>Die schnelle Antwort</h2>
<div class="facts-grid">
<div class="fact-card"><strong>Waschen</strong><p>{fabric.washTemp}</p></div>
<div class="fact-card"><strong>Trocknen</strong><p>{fabric.dryRule}</p></div>
<div class="fact-card"><strong>Bügeln</strong><p>{fabric.ironing}</p></div>
</div>
</section>
<section class="content-section">
<h2>So gehst du am besten vor</h2>
<ol class="number-list">
{fabric.quickSteps.map((step) => <li>{step}</li>)}
</ol>
</section>
<section class="content-section">
<h2>Typische Fehler</h2>
<ul class="simple-list">
{fabric.mistakes.map((mistake) => <li>{mistake}</li>)}
</ul>
</section>
</article>
<aside>
<div class="simple-panel sticky-panel">
<h2>Wichtige Symbole für {fabric.name}</h2>
<ul class="simple-list compact-list">
{relatedSymbols.map((symbol) => (
<li><a class="text-link" href={`/symbole/${symbol.slug}`}>{symbol.name}</a></li>
))}
</ul>
</div>
<AdSlot className="ad-slot--stack" />
</aside>
</div>
</main>
</BaseLayout>
+69
View File
@@ -0,0 +1,69 @@
---
import BaseLayout from '../../layouts/BaseLayout.astro';
import AdSlot from '../../components/AdSlot.astro';
import { symbols, fabrics } from '../../data/content';
export function getStaticPaths() {
return symbols.map((symbol) => ({ params: { slug: symbol.slug }, props: { symbol } }));
}
const { symbol } = Astro.props;
const relatedFabrics = fabrics.filter((fabric) => symbol.relatedFabrics.includes(fabric.slug));
---
<BaseLayout title={`${symbol.name} | Pflegezeichen-Finder`} description={symbol.short}>
<main class="section">
<div class="container detail-grid detail-grid--wide">
<article>
<span class="eyebrow">{symbol.category}</span>
<h1>{symbol.name}</h1>
<p class="lead">{symbol.short}</p>
<div class="symbol-hero-box">
<div class="symbol-icon symbol-icon--large">{symbol.icon}</div>
<div>
<h2>Was dieses Symbol bedeutet</h2>
<p>{symbol.meaning}</p>
</div>
</div>
<section class="content-section">
<h2>Das kannst du damit meist sicher machen</h2>
<ul class="simple-list">
{symbol.doThis.map((item) => <li>{item}</li>)}
</ul>
</section>
<section class="content-section">
<h2>Lieber vermeiden</h2>
<ul class="simple-list">
{symbol.avoidThis.map((item) => <li>{item}</li>)}
</ul>
</section>
<section class="content-section">
<h2>Häufige Fragen</h2>
<div class="faq-list">
{symbol.commonQuestions.map((faq) => (
<article class="faq-item">
<h3>{faq.question}</h3>
<p>{faq.answer}</p>
</article>
))}
</div>
</section>
</article>
<aside>
<div class="simple-panel sticky-panel">
<h2>Passt oft zu diesen Stoffen</h2>
<ul class="simple-list compact-list">
{relatedFabrics.map((fabric) => (
<li><a class="text-link" href={`/stoffe/${fabric.slug}`}>{fabric.name}</a></li>
))}
</ul>
</div>
<AdSlot className="ad-slot--stack" />
</aside>
</div>
</main>
</BaseLayout>
@@ -0,0 +1,29 @@
---
import BaseLayout from '../../layouts/BaseLayout.astro';
import DecoderTool from '../../components/DecoderTool.astro';
import AdSlot from '../../components/AdSlot.astro';
import { symbols } from '../../data/content';
---
<BaseLayout
title="Pflegezeichen-Finder | Waschsymbol suchen und verstehen"
description="Suche nach Waschsymbolen und filtere nach Kategorie. Der Pflegezeichen-Finder erklärt, was auf dem Etikett wirklich gemeint ist.">
<main class="section">
<div class="container page-intro">
<span class="eyebrow">Tool</span>
<h1>Pflegezeichen-Finder</h1>
<p>
Suche nach einem Waschsymbol oder filtere nach Kategorie. Die Ergebnisse sind auf schnelle Orientierung im Alltag
gebaut, nicht auf Fachjargon.
</p>
</div>
<div class="container">
<DecoderTool symbols={symbols} />
</div>
<div class="container section">
<AdSlot label="Anzeigeplatz im Tool" />
</div>
</main>
</BaseLayout>
+427
View File
@@ -0,0 +1,427 @@
body {
margin: 0;
font-family: Inter, ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
color: #1f2937;
background: #ffffff;
}
* {
box-sizing: border-box;
}
a {
color: inherit;
text-decoration: none;
}
img {
max-width: 100%;
}
.container {
width: min(1080px, calc(100% - 32px));
margin: 0 auto;
}
.narrow {
width: min(760px, calc(100% - 32px));
}
.site-header {
background: rgba(255, 255, 255, 0.96);
border-bottom: 1px solid #eceff3;
position: sticky;
top: 0;
z-index: 20;
backdrop-filter: blur(10px);
}
.nav {
min-height: 72px;
display: flex;
align-items: center;
justify-content: space-between;
gap: 16px;
}
.brand {
font-size: 1.08rem;
font-weight: 700;
color: #111827;
}
.nav-links,
.footer-links {
display: flex;
flex-wrap: wrap;
gap: 18px;
color: #4b5563;
font-size: 0.97rem;
}
.nav-links a:hover,
.footer-links a:hover,
.text-link:hover {
color: #111827;
}
.hero {
padding: 88px 0 42px;
}
.hero-grid,
.two-col,
.detail-grid {
display: grid;
grid-template-columns: 1.25fr 0.85fr;
gap: 40px;
}
.detail-grid--wide {
align-items: start;
}
.hero h1,
h1 {
font-size: clamp(2.5rem, 5vw, 4.6rem);
line-height: 0.97;
letter-spacing: -0.05em;
color: #111827;
margin: 0 0 18px;
}
h2,
h3 {
color: #111827;
margin-top: 0;
}
h2 {
font-size: clamp(1.45rem, 3vw, 2rem);
margin-bottom: 12px;
}
h3 {
font-size: 1.08rem;
margin-bottom: 8px;
}
p,
li {
line-height: 1.72;
color: #374151;
font-size: 1.02rem;
}
.lead {
font-size: 1.06rem;
}
.section {
padding: 26px 0 54px;
}
.section--soft {
padding-top: 0;
}
.section-intro {
max-width: 720px;
margin-bottom: 22px;
}
.eyebrow {
display: inline-block;
margin-bottom: 14px;
color: #2563eb;
font-size: 0.92rem;
font-weight: 600;
}
.button-row {
display: flex;
flex-wrap: wrap;
gap: 12px;
margin-top: 22px;
}
.button {
display: inline-flex;
align-items: center;
justify-content: center;
min-height: 46px;
padding: 0 18px;
border-radius: 999px;
font-weight: 600;
border: 1px solid transparent;
}
.button.primary {
background: #111827;
color: white;
}
.button.secondary {
background: #fff;
color: #111827;
border-color: #d1d5db;
}
.simple-panel,
.content-section,
.ad-slot,
.info-card,
.fact-card,
.faq-item,
.symbol-card {
border-top: 1px solid #eceff3;
padding-top: 18px;
}
.info-card,
.symbol-card,
.fact-card {
background: #fbfcfe;
border: 1px solid #edf2f7;
border-radius: 18px;
padding: 18px;
}
.symbol-card {
box-shadow: 0 8px 22px rgba(15, 23, 42, 0.04);
}
.stats {
display: flex;
flex-wrap: wrap;
gap: 18px;
margin-top: 28px;
color: #6b7280;
}
.stats strong {
color: #111827;
}
.list-block {
border-top: 1px solid #eceff3;
}
.list-row {
display: grid;
grid-template-columns: 170px 1fr auto;
gap: 18px;
padding: 22px 0;
border-bottom: 1px solid #eceff3;
align-items: start;
}
.list-row__meta {
color: #2563eb;
font-size: 0.92rem;
font-weight: 600;
padding-top: 4px;
}
.list-row__action {
white-space: nowrap;
}
.text-link {
font-weight: 600;
color: #111827;
}
.three-col-grid {
display: grid;
grid-template-columns: repeat(3, minmax(0, 1fr));
gap: 26px;
}
.compact-list li,
.number-list li,
.simple-list li {
margin-bottom: 10px;
}
.number-list {
padding-left: 20px;
}
.decoder__controls {
display: grid;
grid-template-columns: minmax(0, 1.7fr) minmax(180px, 0.7fr);
gap: 14px;
margin-bottom: 18px;
}
.field {
display: grid;
gap: 8px;
}
.field span {
color: #374151;
font-size: 0.94rem;
font-weight: 600;
}
.field input,
.field select {
min-height: 48px;
border: 1px solid #d1d5db;
border-radius: 14px;
padding: 0 14px;
font: inherit;
color: #111827;
background: #fff;
}
.decoder__results {
display: grid;
grid-template-columns: repeat(3, minmax(0, 1fr));
gap: 22px;
}
.decoder__empty {
margin-top: 18px;
}
.decoder__footer {
margin-top: 20px;
}
.symbol-card__top {
display: flex;
align-items: center;
justify-content: space-between;
gap: 12px;
margin-bottom: 12px;
}
.symbol-icon {
width: 56px;
height: 56px;
border-radius: 16px;
display: inline-grid;
place-items: center;
font-size: 1.5rem;
background: #eff6ff;
color: #1d4ed8;
}
.symbol-icon--large {
width: 88px;
height: 88px;
border-radius: 22px;
font-size: 2.5rem;
}
.symbol-category {
color: #2563eb;
font-size: 0.88rem;
font-weight: 600;
}
.symbol-hero-box {
display: grid;
grid-template-columns: auto 1fr;
gap: 18px;
align-items: start;
padding: 18px 0 2px;
}
.facts-grid {
display: grid;
grid-template-columns: repeat(3, minmax(0, 1fr));
gap: 18px;
}
.fact-card p {
margin-bottom: 0;
}
.faq-list {
display: grid;
gap: 18px;
}
.page-intro {
padding-bottom: 12px;
}
.ad-slot__label {
color: #6b7280;
font-size: 0.82rem;
text-transform: uppercase;
letter-spacing: 0.08em;
margin-bottom: 10px;
}
.ad-slot__placeholder {
min-height: 96px;
background: #f8fafc;
border: 1px dashed #d7dee8;
border-radius: 16px;
display: grid;
place-items: center;
text-align: center;
padding: 20px;
color: #6b7280;
font-size: 0.95rem;
}
.ad-slot--stack {
margin-top: 24px;
}
.sticky-panel {
position: sticky;
top: 92px;
}
.footer {
border-top: 1px solid #eceff3;
background: #fff;
margin-top: 56px;
}
.footer-inner {
padding: 26px 0 38px;
display: flex;
flex-wrap: wrap;
align-items: center;
justify-content: space-between;
gap: 16px;
}
.footer-copy {
color: #6b7280;
font-size: 0.95rem;
}
@media (max-width: 980px) {
.hero-grid,
.two-col,
.detail-grid,
.three-col-grid,
.decoder__results,
.facts-grid,
.list-row {
grid-template-columns: 1fr;
}
.hero {
padding-top: 56px;
}
.sticky-panel {
position: static;
}
}
@media (max-width: 640px) {
.decoder__controls {
grid-template-columns: 1fr;
}
}
+5
View File
@@ -0,0 +1,5 @@
{
"extends": "astro/tsconfigs/strict",
"include": [".astro/types.d.ts", "**/*"],
"exclude": ["dist"]
}