Files
xsl-validator/web/index_v5.html
T
2026-03-03 21:20:02 +01:00

1762 lines
59 KiB
HTML

<!DOCTYPE html>
<html lang="de">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>DocuMentor — Elegante XSL-Transformation &amp; PDF-Validierung</title>
<link rel="stylesheet" href="fonts/fonts_v5.css">
<style>
/* ===== RESET & BASE ===== */
*, *::before, *::after { margin: 0; padding: 0; box-sizing: border-box; }
:root {
--navy-deep: #0d1b2a;
--navy-mid: #1b2d45;
--navy-light: #243b56;
--gold: #d4af37;
--gold-light: #e8cc6a;
--gold-dark: #b8962e;
--gold-pale: #f5e6b8;
--cream: #f8f3e6;
--white: #ffffff;
--text-light: #c8d0da;
--font-display: 'Poiret One', cursive;
--font-serif: 'Cormorant Garamond', serif;
--font-body: 'Raleway', sans-serif;
}
html { scroll-behavior: smooth; }
body {
font-family: var(--font-body);
font-weight: 300;
background: var(--navy-deep);
color: var(--text-light);
line-height: 1.7;
overflow-x: hidden;
}
/* ===== SHIMMER ANIMATION ===== */
@keyframes shimmer {
0% { background-position: -200% center; }
100% { background-position: 200% center; }
}
@keyframes fadeInUp {
from { opacity: 0; transform: translateY(40px); }
to { opacity: 1; transform: translateY(0); }
}
@keyframes fanReveal {
from { transform: scaleY(0); opacity: 0; }
to { transform: scaleY(1); opacity: 1; }
}
@keyframes pulse-gold {
0%, 100% { opacity: 0.6; }
50% { opacity: 1; }
}
@keyframes rotateIn {
from { transform: rotate(-90deg) scale(0); opacity: 0; }
to { transform: rotate(0deg) scale(1); opacity: 1; }
}
.shimmer-text {
background: linear-gradient(
110deg,
var(--gold-dark) 0%,
var(--gold) 20%,
var(--gold-light) 40%,
var(--gold-pale) 50%,
var(--gold-light) 60%,
var(--gold) 80%,
var(--gold-dark) 100%
);
background-size: 200% auto;
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
background-clip: text;
animation: shimmer 4s linear infinite;
}
.shimmer-border {
background: linear-gradient(
90deg,
var(--gold-dark),
var(--gold),
var(--gold-light),
var(--gold-pale),
var(--gold-light),
var(--gold),
var(--gold-dark)
);
background-size: 200% auto;
animation: shimmer 5s linear infinite;
}
/* ===== GEOMETRIC DECORATIONS ===== */
.geo-line {
height: 1px;
background: linear-gradient(90deg, transparent, var(--gold), transparent);
margin: 2rem auto;
max-width: 600px;
}
.geo-line-short {
height: 1px;
width: 80px;
background: var(--gold);
margin: 1rem auto;
}
.geo-diamond {
width: 12px;
height: 12px;
background: var(--gold);
transform: rotate(45deg);
margin: 0 auto;
}
.geo-diamond-group {
display: flex;
align-items: center;
justify-content: center;
gap: 1.5rem;
margin: 2rem 0;
}
.geo-diamond-group::before,
.geo-diamond-group::after {
content: '';
height: 1px;
width: 80px;
background: linear-gradient(90deg, transparent, var(--gold));
}
.geo-diamond-group::after {
background: linear-gradient(90deg, var(--gold), transparent);
}
/* Sunburst / Fan motif */
.sunburst {
position: relative;
width: 120px;
height: 60px;
margin: 0 auto 2rem;
overflow: hidden;
}
.sunburst::before {
content: '';
position: absolute;
bottom: 0;
left: 50%;
width: 200px;
height: 200px;
transform: translateX(-50%);
background: repeating-conic-gradient(
var(--gold) 0deg 2deg,
transparent 2deg 12deg
);
opacity: 0.3;
border-radius: 50%;
}
.fan-decoration {
position: relative;
width: 200px;
height: 100px;
margin: 0 auto;
overflow: hidden;
}
.fan-decoration::before {
content: '';
position: absolute;
bottom: -100px;
left: 50%;
transform: translateX(-50%);
width: 200px;
height: 200px;
border-radius: 50%;
background: repeating-conic-gradient(
from 180deg,
rgba(212, 175, 55, 0.15) 0deg 3deg,
transparent 3deg 10deg
);
}
/* Corner ornaments */
.corner-ornament {
position: absolute;
width: 60px;
height: 60px;
}
.corner-ornament::before,
.corner-ornament::after {
content: '';
position: absolute;
background: var(--gold);
}
.corner-ornament::before {
width: 100%;
height: 1px;
top: 0;
}
.corner-ornament::after {
width: 1px;
height: 100%;
left: 0;
}
.corner-ornament.top-left { top: 0; left: 0; }
.corner-ornament.top-right { top: 0; right: 0; transform: scaleX(-1); }
.corner-ornament.bottom-left { bottom: 0; left: 0; transform: scaleY(-1); }
.corner-ornament.bottom-right { bottom: 0; right: 0; transform: scale(-1); }
/* ===== NAVIGATION ===== */
nav {
position: fixed;
top: 0;
left: 0;
width: 100%;
z-index: 1000;
background: rgba(13, 27, 42, 0.92);
backdrop-filter: blur(12px);
border-bottom: 1px solid rgba(212, 175, 55, 0.2);
transition: all 0.3s ease;
}
nav.scrolled {
background: rgba(13, 27, 42, 0.98);
border-bottom-color: var(--gold);
}
.nav-inner {
max-width: 1200px;
margin: 0 auto;
padding: 1rem 2rem;
display: flex;
align-items: center;
justify-content: space-between;
}
.nav-logo {
font-family: var(--font-display);
font-size: 1.5rem;
color: var(--gold);
text-decoration: none;
letter-spacing: 4px;
text-transform: uppercase;
}
.nav-links {
display: flex;
gap: 2rem;
list-style: none;
}
.nav-links a {
color: var(--text-light);
text-decoration: none;
font-size: 0.85rem;
font-weight: 400;
letter-spacing: 2px;
text-transform: uppercase;
transition: color 0.3s;
position: relative;
}
.nav-links a::after {
content: '';
position: absolute;
bottom: -4px;
left: 0;
width: 0;
height: 1px;
background: var(--gold);
transition: width 0.3s;
}
.nav-links a:hover { color: var(--gold); }
.nav-links a:hover::after { width: 100%; }
.nav-toggle {
display: none;
flex-direction: column;
gap: 5px;
cursor: pointer;
background: none;
border: none;
padding: 4px;
}
.nav-toggle span {
width: 24px;
height: 1px;
background: var(--gold);
transition: all 0.3s;
}
/* ===== HERO ===== */
.hero {
min-height: 100vh;
display: flex;
align-items: center;
justify-content: center;
position: relative;
overflow: hidden;
background:
radial-gradient(ellipse at 50% 30%, rgba(212, 175, 55, 0.06) 0%, transparent 60%),
radial-gradient(ellipse at 50% 80%, rgba(27, 45, 69, 0.5) 0%, transparent 50%),
var(--navy-deep);
}
/* Background geometric pattern */
.hero::before {
content: '';
position: absolute;
inset: 0;
background-image:
repeating-linear-gradient(
0deg,
transparent,
transparent 80px,
rgba(212, 175, 55, 0.03) 80px,
rgba(212, 175, 55, 0.03) 81px
),
repeating-linear-gradient(
90deg,
transparent,
transparent 80px,
rgba(212, 175, 55, 0.03) 80px,
rgba(212, 175, 55, 0.03) 81px
);
pointer-events: none;
}
.hero-frame {
position: relative;
padding: 4rem 5rem;
text-align: center;
max-width: 900px;
}
/* Art Deco ornamental frame */
.hero-frame::before {
content: '';
position: absolute;
inset: 0;
border: 1px solid rgba(212, 175, 55, 0.3);
pointer-events: none;
}
.hero-frame::after {
content: '';
position: absolute;
inset: 8px;
border: 1px solid rgba(212, 175, 55, 0.15);
pointer-events: none;
}
.hero-fan {
position: absolute;
top: -80px;
left: 50%;
transform: translateX(-50%);
width: 300px;
height: 160px;
overflow: hidden;
opacity: 0.25;
}
.hero-fan::before {
content: '';
position: absolute;
bottom: -160px;
left: 50%;
transform: translateX(-50%);
width: 320px;
height: 320px;
border-radius: 50%;
background: repeating-conic-gradient(
from 180deg,
var(--gold) 0deg 1.5deg,
transparent 1.5deg 8deg
);
}
.hero-subtitle-top {
font-family: var(--font-body);
font-size: 0.85rem;
font-weight: 400;
letter-spacing: 8px;
text-transform: uppercase;
color: var(--gold);
margin-bottom: 1.5rem;
opacity: 0;
animation: fadeInUp 1s ease 0.3s forwards;
}
.hero-title {
font-family: var(--font-display);
font-size: clamp(3rem, 7vw, 6rem);
letter-spacing: 12px;
text-transform: uppercase;
line-height: 1.1;
margin-bottom: 0.5rem;
opacity: 0;
animation: fadeInUp 1s ease 0.5s forwards;
}
.hero-tagline {
font-family: var(--font-serif);
font-size: clamp(1.1rem, 2.5vw, 1.5rem);
font-weight: 300;
font-style: italic;
color: var(--gold-pale);
margin-top: 1rem;
margin-bottom: 2rem;
opacity: 0;
animation: fadeInUp 1s ease 0.7s forwards;
}
.hero-deco-line {
display: flex;
align-items: center;
justify-content: center;
gap: 1rem;
margin: 1.5rem 0;
opacity: 0;
animation: fadeInUp 1s ease 0.9s forwards;
}
.hero-deco-line span {
height: 1px;
width: 100px;
background: linear-gradient(90deg, transparent, var(--gold));
}
.hero-deco-line span:last-child {
background: linear-gradient(90deg, var(--gold), transparent);
}
.hero-deco-line .diamond-sm {
width: 8px;
height: 8px;
background: var(--gold);
transform: rotate(45deg);
flex-shrink: 0;
}
.hero-description {
font-size: 0.95rem;
color: var(--text-light);
max-width: 560px;
margin: 0 auto 2rem;
opacity: 0;
animation: fadeInUp 1s ease 1.1s forwards;
}
.hero-cta {
display: inline-block;
font-family: var(--font-body);
font-size: 0.85rem;
font-weight: 500;
letter-spacing: 4px;
text-transform: uppercase;
color: var(--navy-deep);
background: linear-gradient(135deg, var(--gold), var(--gold-light));
padding: 1rem 3rem;
text-decoration: none;
border: none;
cursor: pointer;
transition: all 0.4s ease;
position: relative;
opacity: 0;
animation: fadeInUp 1s ease 1.3s forwards;
}
.hero-cta:hover {
background: linear-gradient(135deg, var(--gold-light), var(--gold-pale));
transform: translateY(-2px);
box-shadow: 0 8px 30px rgba(212, 175, 55, 0.3);
}
.hero-cta::before,
.hero-cta::after {
content: '';
position: absolute;
width: 12px;
height: 12px;
border: 1px solid var(--gold);
transition: all 0.4s ease;
}
.hero-cta::before {
top: -6px;
left: -6px;
border-right: none;
border-bottom: none;
}
.hero-cta::after {
bottom: -6px;
right: -6px;
border-left: none;
border-top: none;
}
.hero-cta:hover::before { top: -8px; left: -8px; }
.hero-cta:hover::after { bottom: -8px; right: -8px; }
/* Scroll indicator */
.scroll-indicator {
position: absolute;
bottom: 2rem;
left: 50%;
transform: translateX(-50%);
display: flex;
flex-direction: column;
align-items: center;
gap: 0.5rem;
opacity: 0;
animation: fadeInUp 1s ease 1.6s forwards;
}
.scroll-indicator span {
font-size: 0.7rem;
letter-spacing: 3px;
text-transform: uppercase;
color: rgba(212, 175, 55, 0.5);
}
.scroll-indicator .scroll-line {
width: 1px;
height: 40px;
background: linear-gradient(to bottom, var(--gold), transparent);
animation: pulse-gold 2s ease infinite;
}
/* ===== SECTION COMMON ===== */
section {
padding: 6rem 2rem;
position: relative;
}
.section-container {
max-width: 1200px;
margin: 0 auto;
}
.section-header {
text-align: center;
margin-bottom: 4rem;
}
.section-label {
font-family: var(--font-body);
font-size: 0.75rem;
font-weight: 500;
letter-spacing: 6px;
text-transform: uppercase;
color: var(--gold);
margin-bottom: 1rem;
}
.section-title {
font-family: var(--font-display);
font-size: clamp(2rem, 4vw, 3rem);
letter-spacing: 6px;
text-transform: uppercase;
color: var(--cream);
margin-bottom: 0.5rem;
}
/* ===== FEATURES ===== */
.features {
background:
radial-gradient(ellipse at 20% 50%, rgba(27, 45, 69, 0.4) 0%, transparent 50%),
radial-gradient(ellipse at 80% 50%, rgba(27, 45, 69, 0.4) 0%, transparent 50%),
var(--navy-deep);
}
.features-grid {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 2rem;
}
.feature-card {
position: relative;
padding: 2.5rem 2rem;
background: rgba(27, 45, 69, 0.3);
border: 1px solid rgba(212, 175, 55, 0.15);
text-align: center;
transition: all 0.4s ease;
overflow: hidden;
}
.feature-card::before {
content: '';
position: absolute;
top: 0;
left: 50%;
transform: translateX(-50%);
width: 60%;
height: 2px;
background: linear-gradient(90deg, transparent, var(--gold), transparent);
opacity: 0;
transition: opacity 0.4s ease;
}
.feature-card:hover {
background: rgba(27, 45, 69, 0.5);
border-color: rgba(212, 175, 55, 0.4);
transform: translateY(-4px);
}
.feature-card:hover::before { opacity: 1; }
.feature-icon {
width: 64px;
height: 64px;
margin: 0 auto 1.5rem;
position: relative;
display: flex;
align-items: center;
justify-content: center;
}
.feature-icon svg {
width: 36px;
height: 36px;
stroke: var(--gold);
stroke-width: 1.5;
fill: none;
}
.feature-icon::before {
content: '';
position: absolute;
inset: 0;
border: 1px solid rgba(212, 175, 55, 0.3);
transform: rotate(45deg);
transition: all 0.4s ease;
}
.feature-card:hover .feature-icon::before {
border-color: var(--gold);
transform: rotate(45deg) scale(1.1);
}
.feature-card h3 {
font-family: var(--font-serif);
font-size: 1.3rem;
font-weight: 600;
color: var(--cream);
margin-bottom: 0.75rem;
letter-spacing: 1px;
}
.feature-card p {
font-size: 0.9rem;
line-height: 1.6;
color: var(--text-light);
}
/* ===== WORKFLOW ===== */
.workflow {
background:
linear-gradient(180deg, var(--navy-deep) 0%, var(--navy-mid) 50%, var(--navy-deep) 100%);
}
.workflow-steps {
display: flex;
align-items: flex-start;
justify-content: center;
gap: 0;
position: relative;
}
.workflow-step {
flex: 1;
max-width: 260px;
text-align: center;
position: relative;
padding: 0 1rem;
}
.workflow-step:not(:last-child)::after {
content: '';
position: absolute;
top: 32px;
right: -20px;
width: 40px;
height: 1px;
background: var(--gold);
}
.workflow-step:not(:last-child)::before {
content: '';
position: absolute;
top: 28px;
right: -16px;
width: 8px;
height: 8px;
border-top: 1px solid var(--gold);
border-right: 1px solid var(--gold);
transform: rotate(45deg);
}
.step-number {
width: 64px;
height: 64px;
margin: 0 auto 1.5rem;
display: flex;
align-items: center;
justify-content: center;
position: relative;
}
.step-number::before {
content: '';
position: absolute;
inset: 0;
border: 1px solid var(--gold);
transform: rotate(45deg);
}
.step-number span {
font-family: var(--font-display);
font-size: 1.5rem;
color: var(--gold);
}
.workflow-step h3 {
font-family: var(--font-serif);
font-size: 1.2rem;
font-weight: 600;
color: var(--cream);
margin-bottom: 0.75rem;
}
.workflow-step p {
font-size: 0.85rem;
color: var(--text-light);
line-height: 1.6;
}
/* ===== SCREENSHOT / DEMO ===== */
.demo {
background: var(--navy-deep);
overflow: hidden;
}
.demo-mockup {
max-width: 900px;
margin: 0 auto;
position: relative;
}
.mockup-frame {
background: var(--navy-mid);
border: 1px solid rgba(212, 175, 55, 0.3);
border-radius: 4px;
overflow: hidden;
box-shadow:
0 20px 60px rgba(0, 0, 0, 0.4),
0 0 80px rgba(212, 175, 55, 0.05);
}
.mockup-titlebar {
background: rgba(13, 27, 42, 0.9);
padding: 0.75rem 1rem;
display: flex;
align-items: center;
gap: 0.5rem;
border-bottom: 1px solid rgba(212, 175, 55, 0.15);
}
.mockup-dot {
width: 10px;
height: 10px;
border-radius: 50%;
border: 1px solid rgba(212, 175, 55, 0.4);
}
.mockup-dot:nth-child(1) { background: rgba(212, 175, 55, 0.3); }
.mockup-dot:nth-child(2) { background: rgba(212, 175, 55, 0.2); }
.mockup-dot:nth-child(3) { background: rgba(212, 175, 55, 0.1); }
.mockup-title-text {
flex: 1;
text-align: center;
font-size: 0.75rem;
letter-spacing: 2px;
color: var(--gold);
font-family: var(--font-body);
}
.mockup-body {
padding: 1.5rem;
display: grid;
grid-template-columns: 250px 1fr;
gap: 1rem;
min-height: 400px;
}
.mockup-sidebar {
background: rgba(13, 27, 42, 0.6);
border: 1px solid rgba(212, 175, 55, 0.1);
border-radius: 2px;
padding: 1rem;
}
.mockup-sidebar-title {
font-family: var(--font-serif);
font-size: 0.8rem;
color: var(--gold);
letter-spacing: 2px;
text-transform: uppercase;
margin-bottom: 1rem;
padding-bottom: 0.5rem;
border-bottom: 1px solid rgba(212, 175, 55, 0.15);
}
.mockup-tree-item {
padding: 0.3rem 0;
padding-left: 0;
font-size: 0.78rem;
color: var(--text-light);
display: flex;
align-items: center;
gap: 0.4rem;
}
.mockup-tree-item.indent-1 { padding-left: 1rem; }
.mockup-tree-item.indent-2 { padding-left: 2rem; }
.mockup-tree-icon {
width: 6px;
height: 6px;
border: 1px solid var(--gold);
transform: rotate(45deg);
flex-shrink: 0;
}
.mockup-tree-icon.filled { background: var(--gold); }
.mockup-content {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 0.75rem;
}
.mockup-panel {
background: rgba(13, 27, 42, 0.6);
border: 1px solid rgba(212, 175, 55, 0.1);
border-radius: 2px;
display: flex;
flex-direction: column;
}
.mockup-panel-header {
padding: 0.5rem 0.75rem;
font-size: 0.7rem;
letter-spacing: 1px;
text-transform: uppercase;
color: var(--gold);
border-bottom: 1px solid rgba(212, 175, 55, 0.1);
text-align: center;
}
.mockup-panel-body {
flex: 1;
padding: 1rem;
display: flex;
align-items: center;
justify-content: center;
}
.mockup-pdf-placeholder {
width: 80%;
height: 80%;
min-height: 200px;
border: 1px dashed rgba(212, 175, 55, 0.2);
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
gap: 0.5rem;
}
.mockup-pdf-placeholder svg {
width: 32px;
height: 32px;
stroke: rgba(212, 175, 55, 0.3);
stroke-width: 1;
fill: none;
}
.mockup-pdf-placeholder span {
font-size: 0.65rem;
color: rgba(212, 175, 55, 0.3);
letter-spacing: 1px;
}
.mockup-panel.diff .mockup-pdf-placeholder {
border-color: rgba(212, 175, 55, 0.3);
background: rgba(212, 175, 55, 0.02);
}
/* Decorative frame around mockup */
.demo-mockup::before,
.demo-mockup::after {
content: '';
position: absolute;
width: 40px;
height: 40px;
border: 1px solid rgba(212, 175, 55, 0.2);
}
.demo-mockup::before {
top: -12px;
left: -12px;
border-right: none;
border-bottom: none;
}
.demo-mockup::after {
bottom: -12px;
right: -12px;
border-left: none;
border-top: none;
}
/* ===== TECH STACK ===== */
.tech-stack {
background:
radial-gradient(ellipse at 50% 0%, rgba(212, 175, 55, 0.04) 0%, transparent 50%),
linear-gradient(180deg, var(--navy-deep) 0%, var(--navy-mid) 50%, var(--navy-deep) 100%);
}
.tech-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(160px, 1fr));
gap: 1.5rem;
max-width: 800px;
margin: 0 auto;
}
.tech-item {
text-align: center;
padding: 2rem 1rem;
background: rgba(13, 27, 42, 0.5);
border: 1px solid rgba(212, 175, 55, 0.1);
transition: all 0.3s ease;
position: relative;
}
.tech-item::before {
content: '';
position: absolute;
top: 0;
left: 0;
right: 0;
height: 2px;
background: linear-gradient(90deg, transparent, var(--gold), transparent);
transform: scaleX(0);
transition: transform 0.4s ease;
}
.tech-item:hover {
border-color: rgba(212, 175, 55, 0.3);
transform: translateY(-2px);
}
.tech-item:hover::before {
transform: scaleX(1);
}
.tech-item h4 {
font-family: var(--font-serif);
font-size: 1.1rem;
font-weight: 600;
color: var(--gold);
margin-bottom: 0.4rem;
}
.tech-item p {
font-size: 0.78rem;
color: var(--text-light);
}
/* ===== DOWNLOAD / GETTING STARTED ===== */
.download {
background: var(--navy-deep);
position: relative;
}
.download-content {
max-width: 700px;
margin: 0 auto;
text-align: center;
}
.install-card {
background: rgba(27, 45, 69, 0.3);
border: 1px solid rgba(212, 175, 55, 0.25);
padding: 3rem;
position: relative;
margin-top: 2rem;
}
.install-card .corner-ornament { width: 30px; height: 30px; }
.install-steps {
text-align: left;
margin-bottom: 2rem;
}
.install-step {
display: flex;
align-items: flex-start;
gap: 1rem;
margin-bottom: 1.5rem;
}
.install-step-num {
font-family: var(--font-display);
font-size: 1.2rem;
color: var(--gold);
min-width: 24px;
}
.install-step-text {
font-size: 0.9rem;
color: var(--text-light);
}
.install-step-text strong {
color: var(--cream);
font-weight: 500;
}
.code-block {
background: rgba(13, 27, 42, 0.8);
border: 1px solid rgba(212, 175, 55, 0.15);
border-left: 3px solid var(--gold);
padding: 1rem 1.5rem;
font-family: 'Courier New', monospace;
font-size: 0.85rem;
color: var(--gold-light);
overflow-x: auto;
margin: 1rem 0;
position: relative;
}
.code-block .comment {
color: rgba(200, 208, 218, 0.4);
}
.copy-btn {
position: absolute;
top: 0.5rem;
right: 0.5rem;
background: rgba(212, 175, 55, 0.15);
border: 1px solid rgba(212, 175, 55, 0.3);
color: var(--gold);
font-size: 0.7rem;
letter-spacing: 1px;
text-transform: uppercase;
padding: 0.3rem 0.6rem;
cursor: pointer;
font-family: var(--font-body);
transition: all 0.3s;
}
.copy-btn:hover {
background: rgba(212, 175, 55, 0.3);
}
.download-link {
display: inline-block;
font-family: var(--font-body);
font-size: 0.85rem;
font-weight: 500;
letter-spacing: 4px;
text-transform: uppercase;
color: var(--navy-deep);
background: linear-gradient(135deg, var(--gold), var(--gold-light));
padding: 1rem 3rem;
text-decoration: none;
transition: all 0.4s ease;
margin-top: 1rem;
}
.download-link:hover {
background: linear-gradient(135deg, var(--gold-light), var(--gold-pale));
transform: translateY(-2px);
box-shadow: 0 8px 30px rgba(212, 175, 55, 0.3);
}
/* ===== FOOTER ===== */
footer {
background: rgba(13, 27, 42, 0.95);
border-top: 1px solid rgba(212, 175, 55, 0.15);
padding: 3rem 2rem;
text-align: center;
position: relative;
}
footer::before {
content: '';
position: absolute;
top: 0;
left: 50%;
transform: translateX(-50%);
width: 200px;
height: 1px;
background: linear-gradient(90deg, transparent, var(--gold), transparent);
}
.footer-logo {
font-family: var(--font-display);
font-size: 1.8rem;
letter-spacing: 6px;
text-transform: uppercase;
color: var(--gold);
margin-bottom: 1rem;
}
.footer-tagline {
font-family: var(--font-serif);
font-style: italic;
font-size: 0.95rem;
color: var(--text-light);
margin-bottom: 2rem;
}
.footer-links {
display: flex;
justify-content: center;
gap: 2rem;
margin-bottom: 2rem;
flex-wrap: wrap;
}
.footer-links a {
color: var(--text-light);
text-decoration: none;
font-size: 0.8rem;
letter-spacing: 2px;
text-transform: uppercase;
transition: color 0.3s;
}
.footer-links a:hover { color: var(--gold); }
.footer-bottom {
font-size: 0.75rem;
color: rgba(200, 208, 218, 0.4);
letter-spacing: 1px;
}
.footer-deco {
display: flex;
align-items: center;
justify-content: center;
gap: 1rem;
margin: 1.5rem 0;
}
.footer-deco span {
height: 1px;
width: 60px;
background: linear-gradient(90deg, transparent, rgba(212, 175, 55, 0.3));
}
.footer-deco span:last-child {
background: linear-gradient(90deg, rgba(212, 175, 55, 0.3), transparent);
}
.footer-deco .diamond-xs {
width: 6px;
height: 6px;
background: var(--gold);
transform: rotate(45deg);
opacity: 0.5;
}
/* ===== SCROLL REVEAL ===== */
.reveal {
opacity: 0;
transform: translateY(30px);
transition: all 0.8s ease;
}
.reveal.visible {
opacity: 1;
transform: translateY(0);
}
.reveal-delay-1 { transition-delay: 0.1s; }
.reveal-delay-2 { transition-delay: 0.2s; }
.reveal-delay-3 { transition-delay: 0.3s; }
.reveal-delay-4 { transition-delay: 0.4s; }
.reveal-delay-5 { transition-delay: 0.5s; }
.reveal-delay-6 { transition-delay: 0.6s; }
/* ===== RESPONSIVE ===== */
@media (max-width: 1024px) {
.features-grid { grid-template-columns: repeat(2, 1fr); }
.mockup-body { grid-template-columns: 1fr; }
.mockup-sidebar { display: none; }
}
@media (max-width: 768px) {
.nav-links { display: none; }
.nav-links.open {
display: flex;
flex-direction: column;
position: absolute;
top: 100%;
left: 0;
right: 0;
background: rgba(13, 27, 42, 0.98);
padding: 1.5rem 2rem;
border-bottom: 1px solid rgba(212, 175, 55, 0.2);
gap: 1rem;
}
.nav-toggle { display: flex; }
.hero-frame { padding: 3rem 2rem; }
.features-grid { grid-template-columns: 1fr; max-width: 400px; margin: 0 auto; }
.workflow-steps {
flex-direction: column;
align-items: center;
gap: 2rem;
}
.workflow-step:not(:last-child)::after,
.workflow-step:not(:last-child)::before { display: none; }
.mockup-content { grid-template-columns: 1fr; }
.tech-grid { grid-template-columns: repeat(2, 1fr); }
.install-card { padding: 2rem 1.5rem; }
}
@media (max-width: 480px) {
section { padding: 4rem 1rem; }
.tech-grid { grid-template-columns: 1fr 1fr; gap: 1rem; }
}
</style>
</head>
<body>
<!-- ===== NAVIGATION ===== -->
<nav id="navbar">
<div class="nav-inner">
<a href="#hero" class="nav-logo">DocuMentor</a>
<ul class="nav-links" id="navLinks">
<li><a href="#features">Features</a></li>
<li><a href="#workflow">Workflow</a></li>
<li><a href="#demo">Vorschau</a></li>
<li><a href="#tech">Technologie</a></li>
<li><a href="#download">Download</a></li>
</ul>
<button class="nav-toggle" id="navToggle" aria-label="Navigation umschalten">
<span></span><span></span><span></span>
</button>
</div>
</nav>
<!-- ===== HERO ===== -->
<section class="hero" id="hero">
<div class="hero-fan"></div>
<div class="hero-frame">
<div class="corner-ornament top-left"></div>
<div class="corner-ornament top-right"></div>
<div class="corner-ornament bottom-left"></div>
<div class="corner-ornament bottom-right"></div>
<p class="hero-subtitle-top">Pr&auml;zision trifft Eleganz</p>
<h1 class="hero-title shimmer-text">DocuMentor</h1>
<p class="hero-tagline">XSL-Transformation &amp; PDF-Validierung &mdash; meisterhaft orchestriert</p>
<div class="hero-deco-line">
<span></span>
<div class="diamond-sm"></div>
<span></span>
</div>
<p class="hero-description">
Die Desktop-Anwendung f&uuml;r Entwickler, die XSL-Transformationen verwalten,
PDF-Dokumente generieren und &Auml;nderungen visuell vergleichen m&uuml;ssen &mdash;
mit der Pr&auml;zision, die amtliche Dokumente erfordern.
</p>
<a href="#download" class="hero-cta">Jetzt entdecken</a>
</div>
<div class="scroll-indicator">
<span>Scrollen</span>
<div class="scroll-line"></div>
</div>
</section>
<!-- ===== FEATURES ===== -->
<section class="features" id="features">
<div class="section-container">
<div class="section-header reveal">
<p class="section-label">Leistungsmerkmale</p>
<h2 class="section-title">Features</h2>
<div class="geo-diamond-group">
<div class="geo-diamond"></div>
</div>
<div class="fan-decoration"></div>
</div>
<div class="features-grid">
<!-- Feature 1: Baumstruktur -->
<div class="feature-card reveal reveal-delay-1">
<div class="feature-icon">
<svg viewBox="0 0 24 24">
<path d="M12 2L12 8M12 8L7 13M12 8L17 13M7 13L7 18M17 13L17 18M4 18L10 18M14 18L20 18"/>
</svg>
</div>
<h3>Hierarchische Baumstruktur</h3>
<p>Organisieren Sie Ihre XSL-Dateien, XML-Quellen und XSLT-Parameter in einer &uuml;bersichtlichen, verschachtelten Baumansicht.</p>
</div>
<!-- Feature 2: PDF-Diff -->
<div class="feature-card reveal reveal-delay-2">
<div class="feature-icon">
<svg viewBox="0 0 24 24">
<rect x="2" y="3" width="7" height="10" rx="1"/>
<rect x="15" y="3" width="7" height="10" rx="1"/>
<rect x="8.5" y="7" width="7" height="10" rx="1" stroke-dasharray="2 1"/>
<path d="M8 19L16 19M12 17L12 21"/>
</svg>
</div>
<h3>Visueller PDF-Vergleich</h3>
<p>Drei-Panel-Ansicht mit Referenz, Diff und neuer Version. Alpha-Blending und Zoom f&uuml;r pixelgenaue Inspektion.</p>
</div>
<!-- Feature 3: Hash-Tracking -->
<div class="feature-card reveal reveal-delay-3">
<div class="feature-icon">
<svg viewBox="0 0 24 24">
<path d="M4 8L8 4M8 4L12 8M8 4L8 16M20 16L16 20M16 20L12 16M16 20L16 8"/>
<circle cx="4" cy="12" r="2"/>
<circle cx="20" cy="12" r="2"/>
</svg>
</div>
<h3>Hash-basierte &Auml;nderungsverfolgung</h3>
<p>Automatische blake2b-Pr&uuml;fsummen f&uuml;r jede XML-Datei erkennen &Auml;nderungen zuverl&auml;ssig und effizient.</p>
</div>
<!-- Feature 4: Async -->
<div class="feature-card reveal reveal-delay-4">
<div class="feature-icon">
<svg viewBox="0 0 24 24">
<circle cx="12" cy="12" r="9"/>
<path d="M12 7L12 12L16 14"/>
<path d="M3 12A9 9 0 0 1 12 3" stroke-dasharray="3 2"/>
</svg>
</div>
<h3>Asynchrone Verarbeitung</h3>
<p>Hintergrund-Threads f&uuml;r Hash-Berechnungen und Datenbankabfragen halten die Benutzeroberfl&auml;che stets reaktionsf&auml;hig.</p>
</div>
<!-- Feature 5: PostgreSQL -->
<div class="feature-card reveal reveal-delay-5">
<div class="feature-icon">
<svg viewBox="0 0 24 24">
<ellipse cx="12" cy="6" rx="8" ry="3"/>
<path d="M4 6L4 12C4 13.66 7.58 15 12 15C16.42 15 20 13.66 20 12L20 6"/>
<path d="M4 12L4 18C4 19.66 7.58 21 12 21C16.42 21 20 19.66 20 18L20 12"/>
</svg>
</div>
<h3>PostgreSQL-Integration</h3>
<p>Direkte Datenbankanbindung mit SSL-Unterst&uuml;tzung f&uuml;r dynamische XML-Datenquellen &uuml;ber Polars und ConnectorX.</p>
</div>
<!-- Feature 6: Toolchain -->
<div class="feature-card reveal reveal-delay-6">
<div class="feature-icon">
<svg viewBox="0 0 24 24">
<path d="M14.7 6.3a1 1 0 0 0 0 1.4l1.6 1.6a1 1 0 0 0 1.4 0l3.77-3.77a6 6 0 0 1-7.94 7.94l-6.91 6.91a2.12 2.12 0 0 1-3-3l6.91-6.91a6 6 0 0 1 7.94-7.94l-3.76 3.76z"/>
</svg>
</div>
<h3>Toolchain-Konfiguration</h3>
<p>Flexible Verwaltung von Java VMs, Saxon, Apache FOP und diff-pdf &mdash; alles zentral konfigurierbar.</p>
</div>
</div>
</div>
</section>
<!-- ===== WORKFLOW ===== -->
<section class="workflow" id="workflow">
<div class="section-container">
<div class="section-header reveal">
<p class="section-label">Der Prozess</p>
<h2 class="section-title">Workflow</h2>
<div class="geo-diamond-group">
<div class="geo-diamond"></div>
</div>
</div>
<div class="workflow-steps">
<div class="workflow-step reveal reveal-delay-1">
<div class="step-number"><span>I</span></div>
<h3>XSL bearbeiten</h3>
<p>F&uuml;hren Sie die ben&ouml;tigten &Auml;nderungen an Ihren XSL-Stylesheets durch &mdash; DocuMentor erkennt die Auswirkungen.</p>
</div>
<div class="workflow-step reveal reveal-delay-2">
<div class="step-number"><span>II</span></div>
<h3>Transformation starten</h3>
<p>Starten Sie die Transformation per Knopfdruck. Saxon und Apache FOP erzeugen die neuen PDF-Dokumente.</p>
</div>
<div class="workflow-step reveal reveal-delay-3">
<div class="step-number"><span>III</span></div>
<h3>PDF-Diff begutachten</h3>
<p>Vergleichen Sie Referenz- und neue Version visuell in der Drei-Panel-Ansicht mit diff-pdf-Unterst&uuml;tzung.</p>
</div>
<div class="workflow-step reveal reveal-delay-4">
<div class="step-number"><span>IV</span></div>
<h3>Ergebnis verifizieren</h3>
<p>Pr&uuml;fen Sie, ob nur die gew&uuml;nschten Dokumente ge&auml;ndert wurden und die &Auml;nderungen korrekt sind.</p>
</div>
</div>
</div>
</section>
<!-- ===== DEMO / SCREENSHOT ===== -->
<section class="demo" id="demo">
<div class="section-container">
<div class="section-header reveal">
<p class="section-label">Anwendungsvorschau</p>
<h2 class="section-title">Die Oberfl&auml;che</h2>
<div class="geo-diamond-group">
<div class="geo-diamond"></div>
</div>
</div>
<div class="demo-mockup reveal">
<div class="mockup-frame">
<div class="mockup-titlebar">
<div class="mockup-dot"></div>
<div class="mockup-dot"></div>
<div class="mockup-dot"></div>
<span class="mockup-title-text">DocuMentor &mdash; Pr&uuml;fungsverwaltung</span>
</div>
<div class="mockup-body">
<div class="mockup-sidebar">
<div class="mockup-sidebar-title">Projektbaum</div>
<div class="mockup-tree-item">
<div class="mockup-tree-icon filled"></div>
Urkunden
</div>
<div class="mockup-tree-item indent-1">
<div class="mockup-tree-icon"></div>
bachelor_urkunde.xsl
</div>
<div class="mockup-tree-item indent-2">
<div class="mockup-tree-icon filled"></div>
student_001.xml
</div>
<div class="mockup-tree-item indent-2">
<div class="mockup-tree-icon filled"></div>
student_002.xml
</div>
<div class="mockup-tree-item indent-1">
<div class="mockup-tree-icon"></div>
master_urkunde.xsl
</div>
<div class="mockup-tree-item indent-2">
<div class="mockup-tree-icon filled"></div>
student_003.xml
</div>
<div class="mockup-tree-item">
<div class="mockup-tree-icon filled"></div>
Zeugnisse
</div>
<div class="mockup-tree-item indent-1">
<div class="mockup-tree-icon"></div>
zeugnis_ba.xsl
</div>
<div class="mockup-tree-item indent-2">
<div class="mockup-tree-icon filled"></div>
pruefling_001.xml
</div>
<div class="mockup-tree-item">
<div class="mockup-tree-icon filled"></div>
Bescheide
</div>
<div class="mockup-tree-item indent-1">
<div class="mockup-tree-icon"></div>
bescheid_vorlage.xsl
</div>
</div>
<div class="mockup-content">
<div class="mockup-panel">
<div class="mockup-panel-header">Referenz</div>
<div class="mockup-panel-body">
<div class="mockup-pdf-placeholder">
<svg viewBox="0 0 24 24"><path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"/><polyline points="14 2 14 8 20 8"/><line x1="8" y1="13" x2="16" y2="13"/><line x1="8" y1="17" x2="14" y2="17"/></svg>
<span>PDF</span>
</div>
</div>
</div>
<div class="mockup-panel diff">
<div class="mockup-panel-header">Diff</div>
<div class="mockup-panel-body">
<div class="mockup-pdf-placeholder">
<svg viewBox="0 0 24 24"><path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"/><polyline points="14 2 14 8 20 8"/><line x1="8" y1="13" x2="16" y2="13" stroke-dasharray="2 2"/><line x1="8" y1="17" x2="14" y2="17" stroke-dasharray="2 2"/></svg>
<span>Unterschiede</span>
</div>
</div>
</div>
<div class="mockup-panel">
<div class="mockup-panel-header">Neu</div>
<div class="mockup-panel-body">
<div class="mockup-pdf-placeholder">
<svg viewBox="0 0 24 24"><path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"/><polyline points="14 2 14 8 20 8"/><line x1="8" y1="13" x2="16" y2="13"/><line x1="8" y1="17" x2="16" y2="17"/></svg>
<span>PDF</span>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</section>
<!-- ===== TECH STACK ===== -->
<section class="tech-stack" id="tech">
<div class="section-container">
<div class="section-header reveal">
<p class="section-label">Unter der Haube</p>
<h2 class="section-title">Technologie-Stack</h2>
<div class="geo-diamond-group">
<div class="geo-diamond"></div>
</div>
</div>
<div class="tech-grid">
<div class="tech-item reveal reveal-delay-1">
<h4>Python</h4>
<p>Kernsprache</p>
</div>
<div class="tech-item reveal reveal-delay-2">
<h4>PySide6</h4>
<p>Qt-basierte GUI</p>
</div>
<div class="tech-item reveal reveal-delay-3">
<h4>Saxon</h4>
<p>XSLT-Prozessor</p>
</div>
<div class="tech-item reveal reveal-delay-4">
<h4>Apache FOP</h4>
<p>PDF-Erzeugung</p>
</div>
<div class="tech-item reveal reveal-delay-5">
<h4>diff-pdf</h4>
<p>PDF-Vergleich</p>
</div>
<div class="tech-item reveal reveal-delay-1">
<h4>PostgreSQL</h4>
<p>Datenbank</p>
</div>
<div class="tech-item reveal reveal-delay-2">
<h4>Polars</h4>
<p>DataFrames</p>
</div>
<div class="tech-item reveal reveal-delay-3">
<h4>Pydantic</h4>
<p>Konfiguration</p>
</div>
</div>
</div>
</section>
<!-- ===== DOWNLOAD ===== -->
<section class="download" id="download">
<div class="section-container">
<div class="section-header reveal">
<p class="section-label">Loslegen</p>
<h2 class="section-title">Installation</h2>
<div class="geo-diamond-group">
<div class="geo-diamond"></div>
</div>
</div>
<div class="download-content reveal">
<div class="install-card">
<div class="corner-ornament top-left"></div>
<div class="corner-ornament top-right"></div>
<div class="corner-ornament bottom-left"></div>
<div class="corner-ornament bottom-right"></div>
<div class="install-steps">
<div class="install-step">
<span class="install-step-num">1.</span>
<div class="install-step-text">
<strong>Repository klonen</strong>
<div class="code-block">
<button class="copy-btn" onclick="copyCode(this)">Kopieren</button>
git clone https://github.com/your-org/xsl-validator.git<br>
cd xsl-validator
</div>
</div>
</div>
<div class="install-step">
<span class="install-step-num">2.</span>
<div class="install-step-text">
<strong>Abh&auml;ngigkeiten installieren</strong>
<div class="code-block">
<button class="copy-btn" onclick="copyCode(this)">Kopieren</button>
uv sync
</div>
</div>
</div>
<div class="install-step">
<span class="install-step-num">3.</span>
<div class="install-step-text">
<strong>Anwendung starten</strong>
<div class="code-block">
<button class="copy-btn" onclick="copyCode(this)">Kopieren</button>
uv run python src/main.py
</div>
</div>
</div>
</div>
<div class="geo-line"></div>
<p style="font-size: 0.85rem; color: var(--text-light); margin-bottom: 1.5rem;">
Voraussetzungen: Python 3.13+, Java Runtime (f&uuml;r Saxon), Apache FOP, diff-pdf
</p>
<a href="https://github.com/your-org/xsl-validator" class="download-link">
Zum Repository
</a>
</div>
</div>
</div>
</section>
<!-- ===== FOOTER ===== -->
<footer>
<div class="sunburst"></div>
<div class="footer-logo">DocuMentor</div>
<p class="footer-tagline">Pr&auml;zision in jeder Transformation</p>
<div class="footer-deco">
<span></span>
<div class="diamond-xs"></div>
<span></span>
</div>
<div class="footer-links">
<a href="#features">Features</a>
<a href="#workflow">Workflow</a>
<a href="#demo">Vorschau</a>
<a href="#tech">Technologie</a>
<a href="#download">Download</a>
</div>
<div class="footer-deco">
<span></span>
<div class="diamond-xs"></div>
<span></span>
</div>
<p class="footer-bottom">&copy; 2026 DocuMentor &mdash; Elegante XSL-Transformation &amp; PDF-Validierung</p>
</footer>
<!-- ===== JAVASCRIPT ===== -->
<script>
// Navigation scroll effect
const navbar = document.getElementById('navbar');
window.addEventListener('scroll', () => {
navbar.classList.toggle('scrolled', window.scrollY > 50);
});
// Mobile navigation toggle
const navToggle = document.getElementById('navToggle');
const navLinks = document.getElementById('navLinks');
navToggle.addEventListener('click', () => {
navLinks.classList.toggle('open');
});
// Close mobile nav on link click
navLinks.querySelectorAll('a').forEach(link => {
link.addEventListener('click', () => {
navLinks.classList.remove('open');
});
});
// Scroll reveal with IntersectionObserver
const revealElements = document.querySelectorAll('.reveal');
const revealObserver = new IntersectionObserver((entries) => {
entries.forEach(entry => {
if (entry.isIntersecting) {
entry.target.classList.add('visible');
revealObserver.unobserve(entry.target);
}
});
}, {
threshold: 0.15,
rootMargin: '0px 0px -50px 0px'
});
revealElements.forEach(el => revealObserver.observe(el));
// Copy code to clipboard
function copyCode(btn) {
const codeBlock = btn.parentElement;
const text = codeBlock.textContent
.replace('Kopieren', '')
.trim();
navigator.clipboard.writeText(text).then(() => {
const original = btn.textContent;
btn.textContent = 'Kopiert!';
setTimeout(() => { btn.textContent = original; }, 2000);
});
}
// Smooth scroll for anchor links
document.querySelectorAll('a[href^="#"]').forEach(anchor => {
anchor.addEventListener('click', function (e) {
e.preventDefault();
const target = document.querySelector(this.getAttribute('href'));
if (target) {
const offset = navbar.offsetHeight + 20;
const top = target.getBoundingClientRect().top + window.pageYOffset - offset;
window.scrollTo({ top, behavior: 'smooth' });
}
});
});
</script>
</body>
</html>