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

1210 lines
39 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 - XSL-Transformations-Toolkit</title>
<link rel="stylesheet" href="fonts/fonts_v3.css">
<style>
*, *::before, *::after {
margin: 0;
padding: 0;
box-sizing: border-box;
}
:root {
--green: #00ff41;
--green-dim: #00cc33;
--green-dark: #009922;
--green-glow: #00ff4180;
--green-faint: #00ff4115;
--green-subtle: #00ff410a;
--bg: #0a0a0a;
--bg-light: #0f0f0f;
--bg-card: #111111;
--border: #00ff4130;
}
html {
scroll-behavior: smooth;
}
body {
font-family: 'VT323', monospace;
background: var(--bg);
color: var(--green);
font-size: 18px;
line-height: 1.6;
overflow-x: hidden;
position: relative;
}
/* CRT Scan Lines Overlay */
body::before {
content: '';
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
pointer-events: none;
z-index: 9999;
background: repeating-linear-gradient(
0deg,
transparent,
transparent 2px,
rgba(0, 0, 0, 0.15) 2px,
rgba(0, 0, 0, 0.15) 4px
);
}
/* CRT Flicker */
body::after {
content: '';
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
pointer-events: none;
z-index: 9998;
background: radial-gradient(ellipse at center, transparent 60%, rgba(0,0,0,0.4) 100%);
animation: flicker 0.08s infinite alternate;
}
@keyframes flicker {
0% { opacity: 0.97; }
100% { opacity: 1; }
}
/* Matrix Rain Canvas */
#matrix-canvas {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
z-index: -1;
opacity: 0.06;
}
/* Typing cursor blink */
@keyframes blink-caret {
0%, 50% { border-color: var(--green); }
51%, 100% { border-color: transparent; }
}
@keyframes blink {
0%, 50% { opacity: 1; }
51%, 100% { opacity: 0; }
}
@keyframes glow-pulse {
0%, 100% { text-shadow: 0 0 10px var(--green-glow), 0 0 20px var(--green-glow); }
50% { text-shadow: 0 0 20px var(--green-glow), 0 0 40px var(--green-glow), 0 0 60px var(--green-glow); }
}
@keyframes scanline-move {
0% { top: -10%; }
100% { top: 110%; }
}
@keyframes type-in {
from { width: 0; }
to { width: 100%; }
}
@keyframes fade-in-up {
from { opacity: 0; transform: translateY(30px); }
to { opacity: 1; transform: translateY(0); }
}
.cursor-blink {
display: inline-block;
width: 12px;
height: 1.1em;
background: var(--green);
animation: blink 1s step-end infinite;
vertical-align: text-bottom;
margin-left: 2px;
}
/* Moving scanline */
.scanline-bar {
position: fixed;
width: 100%;
height: 6px;
background: linear-gradient(180deg, transparent, var(--green-faint), transparent);
z-index: 9997;
pointer-events: none;
animation: scanline-move 8s linear infinite;
}
/* Navigation */
nav {
position: fixed;
top: 0;
left: 0;
right: 0;
z-index: 1000;
background: rgba(10, 10, 10, 0.95);
border-bottom: 1px solid var(--border);
padding: 12px 0;
backdrop-filter: blur(5px);
}
nav .nav-inner {
max-width: 1100px;
margin: 0 auto;
padding: 0 24px;
display: flex;
justify-content: space-between;
align-items: center;
}
nav .logo {
font-size: 22px;
color: var(--green);
text-shadow: 0 0 10px var(--green-glow);
letter-spacing: 2px;
}
nav .logo span {
color: var(--green-dark);
}
nav ul {
list-style: none;
display: flex;
gap: 24px;
}
nav ul li a {
color: var(--green-dim);
text-decoration: none;
font-family: 'Share Tech Mono', monospace;
font-size: 14px;
letter-spacing: 1px;
transition: color 0.3s, text-shadow 0.3s;
text-transform: uppercase;
}
nav ul li a:hover {
color: var(--green);
text-shadow: 0 0 10px var(--green-glow);
}
.hamburger {
display: none;
flex-direction: column;
gap: 5px;
cursor: pointer;
background: none;
border: none;
padding: 4px;
}
.hamburger span {
display: block;
width: 24px;
height: 2px;
background: var(--green);
}
/* Sections */
section {
max-width: 1100px;
margin: 0 auto;
padding: 100px 24px;
}
.section-label {
font-family: 'Share Tech Mono', monospace;
font-size: 13px;
color: var(--green-dark);
letter-spacing: 3px;
text-transform: uppercase;
margin-bottom: 8px;
}
.section-title {
font-size: 36px;
color: var(--green);
text-shadow: 0 0 15px var(--green-glow);
margin-bottom: 40px;
line-height: 1.3;
}
.section-title::before {
content: '> ';
color: var(--green-dark);
}
/* ======================== */
/* HERO */
/* ======================== */
#hero {
min-height: 100vh;
display: flex;
flex-direction: column;
justify-content: center;
padding-top: 80px;
position: relative;
}
.boot-sequence {
margin-bottom: 40px;
}
.boot-line {
font-family: 'Share Tech Mono', monospace;
font-size: 14px;
color: var(--green-dark);
opacity: 0;
transform: translateY(10px);
margin-bottom: 4px;
letter-spacing: 1px;
}
.boot-line.visible {
opacity: 1;
transform: translateY(0);
transition: opacity 0.3s, transform 0.3s;
}
.boot-line.ok::after {
content: ' [OK]';
color: var(--green);
}
.boot-line.loading::after {
content: ' ...';
animation: blink 1s step-end infinite;
}
.hero-title {
font-size: clamp(48px, 8vw, 90px);
line-height: 1.1;
color: var(--green);
text-shadow: 0 0 30px var(--green-glow), 0 0 60px rgba(0,255,65,0.3);
margin-bottom: 16px;
animation: glow-pulse 4s ease-in-out infinite;
letter-spacing: 4px;
}
.hero-tagline {
font-size: 24px;
color: var(--green-dim);
margin-bottom: 32px;
max-width: 700px;
}
.hero-tagline .typed-text {
border-right: 2px solid var(--green);
animation: blink-caret 1s step-end infinite;
padding-right: 4px;
}
.hero-prompt {
font-family: 'Share Tech Mono', monospace;
font-size: 15px;
color: var(--green-dark);
margin-top: 48px;
}
.hero-prompt a {
color: var(--green);
text-decoration: none;
border-bottom: 1px dashed var(--green-dark);
transition: text-shadow 0.3s;
}
.hero-prompt a:hover {
text-shadow: 0 0 10px var(--green-glow);
}
/* ======================== */
/* FEATURES */
/* ======================== */
.features-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(320px, 1fr));
gap: 24px;
}
.feature-card {
background: var(--bg-card);
border: 1px solid var(--border);
padding: 28px 24px;
position: relative;
overflow: hidden;
transition: border-color 0.3s, box-shadow 0.3s;
}
.feature-card:hover {
border-color: var(--green-dim);
box-shadow: 0 0 30px var(--green-subtle), inset 0 0 30px var(--green-subtle);
}
.feature-card::before {
content: '';
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 2px;
background: linear-gradient(90deg, transparent, var(--green-dark), transparent);
opacity: 0;
transition: opacity 0.3s;
}
.feature-card:hover::before {
opacity: 1;
}
.feature-icon {
font-size: 28px;
margin-bottom: 12px;
display: block;
color: var(--green);
text-shadow: 0 0 10px var(--green-glow);
font-family: 'Share Tech Mono', monospace;
}
.feature-card h3 {
font-size: 22px;
margin-bottom: 10px;
color: var(--green);
}
.feature-card h3::before {
content: '$ ';
color: var(--green-dark);
font-size: 18px;
}
.feature-card p {
color: var(--green-dim);
font-size: 16px;
line-height: 1.5;
}
/* ======================== */
/* WORKFLOW */
/* ======================== */
.workflow-steps {
display: grid;
gap: 0;
position: relative;
}
.workflow-step {
display: grid;
grid-template-columns: 60px 1fr;
gap: 20px;
padding: 28px 0;
border-bottom: 1px solid var(--border);
position: relative;
opacity: 0;
transform: translateX(-20px);
transition: opacity 0.5s, transform 0.5s;
}
.workflow-step.visible {
opacity: 1;
transform: translateX(0);
}
.workflow-step:last-child {
border-bottom: none;
}
.step-number {
width: 50px;
height: 50px;
border: 2px solid var(--green-dark);
display: flex;
align-items: center;
justify-content: center;
font-size: 24px;
color: var(--green);
text-shadow: 0 0 10px var(--green-glow);
position: relative;
flex-shrink: 0;
}
.step-number::before {
content: '';
position: absolute;
top: -2px;
left: -2px;
right: -2px;
bottom: -2px;
border: 1px solid var(--green-faint);
}
.step-content h3 {
font-size: 22px;
color: var(--green);
margin-bottom: 6px;
}
.step-content p {
color: var(--green-dim);
font-size: 16px;
}
.step-content .cmd {
font-family: 'Share Tech Mono', monospace;
font-size: 13px;
color: var(--green-dark);
margin-top: 8px;
background: var(--bg);
display: inline-block;
padding: 4px 10px;
border: 1px solid var(--border);
}
/* ======================== */
/* DEMO / TERMINAL OUTPUT */
/* ======================== */
.terminal-window {
background: var(--bg);
border: 1px solid var(--border);
overflow: hidden;
max-width: 900px;
margin: 0 auto;
}
.terminal-header {
background: var(--bg-light);
padding: 10px 16px;
display: flex;
align-items: center;
gap: 8px;
border-bottom: 1px solid var(--border);
}
.terminal-dot {
width: 10px;
height: 10px;
border-radius: 50%;
border: 1px solid var(--green-dark);
}
.terminal-dot.r { background: #ff5f5680; border-color: #ff5f56; }
.terminal-dot.y { background: #ffbd2e80; border-color: #ffbd2e; }
.terminal-dot.g { background: #27c93f80; border-color: #27c93f; }
.terminal-title {
font-family: 'Share Tech Mono', monospace;
font-size: 12px;
color: var(--green-dark);
margin-left: 12px;
letter-spacing: 1px;
}
.terminal-body {
padding: 20px 24px;
font-family: 'Share Tech Mono', monospace;
font-size: 14px;
line-height: 1.8;
min-height: 300px;
overflow-x: auto;
}
.terminal-body .prompt {
color: var(--green);
}
.terminal-body .cmd-text {
color: var(--green);
}
.terminal-body .output {
color: var(--green-dim);
}
.terminal-body .success {
color: var(--green);
}
.terminal-body .warning {
color: #ffbd2e;
}
.terminal-body .info {
color: var(--green-dark);
}
.terminal-body .highlight {
color: var(--green);
text-shadow: 0 0 8px var(--green-glow);
}
.terminal-line {
margin-bottom: 2px;
white-space: pre;
}
/* ======================== */
/* TECH STACK */
/* ======================== */
.tech-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
gap: 16px;
}
.tech-item {
background: var(--bg-card);
border: 1px solid var(--border);
padding: 20px;
text-align: center;
transition: border-color 0.3s, transform 0.2s;
}
.tech-item:hover {
border-color: var(--green-dim);
transform: translateY(-2px);
}
.tech-item .tech-name {
font-size: 20px;
color: var(--green);
margin-bottom: 6px;
text-shadow: 0 0 8px var(--green-glow);
}
.tech-item .tech-desc {
font-family: 'Share Tech Mono', monospace;
font-size: 12px;
color: var(--green-dark);
letter-spacing: 1px;
text-transform: uppercase;
}
.tech-item .tech-icon {
font-size: 32px;
margin-bottom: 10px;
display: block;
}
/* ======================== */
/* DOWNLOAD / INSTALL */
/* ======================== */
#download {
text-align: center;
}
.install-block {
background: var(--bg-card);
border: 1px solid var(--border);
padding: 32px;
max-width: 700px;
margin: 0 auto 32px;
text-align: left;
position: relative;
}
.install-block .install-label {
font-family: 'Share Tech Mono', monospace;
font-size: 12px;
color: var(--green-dark);
letter-spacing: 2px;
text-transform: uppercase;
margin-bottom: 16px;
}
.install-cmd {
font-family: 'Share Tech Mono', monospace;
font-size: 16px;
color: var(--green);
background: var(--bg);
padding: 16px 20px;
border: 1px solid var(--border);
display: flex;
align-items: center;
justify-content: space-between;
gap: 12px;
cursor: pointer;
transition: border-color 0.3s;
margin-bottom: 12px;
flex-wrap: wrap;
}
.install-cmd:hover {
border-color: var(--green-dim);
}
.install-cmd .cmd-prefix {
color: var(--green-dark);
user-select: none;
}
.install-cmd .copy-hint {
font-size: 11px;
color: var(--green-dark);
letter-spacing: 1px;
user-select: none;
}
.install-note {
font-family: 'Share Tech Mono', monospace;
font-size: 13px;
color: var(--green-dark);
margin-top: 12px;
}
.requirements-list {
text-align: left;
max-width: 700px;
margin: 32px auto 0;
font-family: 'Share Tech Mono', monospace;
font-size: 14px;
color: var(--green-dim);
}
.requirements-list li {
list-style: none;
padding: 6px 0;
border-bottom: 1px solid var(--border);
}
.requirements-list li::before {
content: '[+] ';
color: var(--green-dark);
}
/* ======================== */
/* FOOTER */
/* ======================== */
footer {
border-top: 1px solid var(--border);
padding: 40px 24px;
text-align: center;
}
footer .footer-inner {
max-width: 1100px;
margin: 0 auto;
}
.footer-ascii {
font-family: 'Share Tech Mono', monospace;
font-size: 11px;
color: var(--green-dark);
margin-bottom: 20px;
line-height: 1.3;
white-space: pre;
overflow-x: auto;
}
.footer-links {
display: flex;
justify-content: center;
gap: 24px;
margin-bottom: 16px;
flex-wrap: wrap;
}
.footer-links a {
font-family: 'Share Tech Mono', monospace;
font-size: 13px;
color: var(--green-dark);
text-decoration: none;
letter-spacing: 1px;
transition: color 0.3s;
}
.footer-links a:hover {
color: var(--green);
}
.footer-copy {
font-family: 'Share Tech Mono', monospace;
font-size: 12px;
color: #333;
letter-spacing: 1px;
}
/* Scroll animations */
.reveal {
opacity: 0;
transform: translateY(30px);
transition: opacity 0.6s ease, transform 0.6s ease;
}
.reveal.visible {
opacity: 1;
transform: translateY(0);
}
/* Responsive */
@media (max-width: 768px) {
nav ul {
display: none;
position: absolute;
top: 100%;
left: 0;
right: 0;
background: rgba(10, 10, 10, 0.98);
flex-direction: column;
padding: 16px 24px;
border-bottom: 1px solid var(--border);
gap: 16px;
}
nav ul.open {
display: flex;
}
.hamburger {
display: flex;
}
.hero-title {
letter-spacing: 2px;
}
.features-grid {
grid-template-columns: 1fr;
}
.workflow-step {
grid-template-columns: 50px 1fr;
gap: 14px;
}
.tech-grid {
grid-template-columns: repeat(2, 1fr);
}
section {
padding: 60px 16px;
}
.terminal-body {
font-size: 12px;
padding: 14px 16px;
}
.footer-ascii {
font-size: 8px;
}
}
@media (max-width: 480px) {
.tech-grid {
grid-template-columns: 1fr;
}
}
</style>
</head>
<body>
<canvas id="matrix-canvas"></canvas>
<div class="scanline-bar"></div>
<!-- Navigation -->
<nav>
<div class="nav-inner">
<div class="logo"><span>[</span>DocuMentor<span>]</span></div>
<button class="hamburger" id="hamburger" aria-label="Menu">
<span></span><span></span><span></span>
</button>
<ul id="nav-links">
<li><a href="#features">Features</a></li>
<li><a href="#workflow">Workflow</a></li>
<li><a href="#demo">Demo</a></li>
<li><a href="#techstack">Tech-Stack</a></li>
<li><a href="#download">Download</a></li>
</ul>
</div>
</nav>
<!-- HERO -->
<section id="hero">
<div class="boot-sequence" id="boot-sequence">
<div class="boot-line ok">BIOS POST abgeschlossen</div>
<div class="boot-line ok">PySide6 Runtime v6.8 geladen</div>
<div class="boot-line ok">Saxon HE 12.5 initialisiert</div>
<div class="boot-line ok">Apache FOP 2.10 bereit</div>
<div class="boot-line ok">PostgreSQL-Verbindung hergestellt</div>
<div class="boot-line ok">XSL-Abhängigkeitsgraph aufgebaut</div>
<div class="boot-line ok">blake2b Hash-Engine aktiv</div>
<div class="boot-line">System bereit. Starte DocuMentor...</div>
</div>
<h1 class="hero-title">DocuMentor</h1>
<p class="hero-tagline">
<span class="typed-text" id="tagline"></span>
</p>
<p class="hero-prompt">
<span style="color:var(--green-dark)">user@documentor:~$</span>
<a href="#features">./erkunde_features.sh</a>
<span class="cursor-blink"></span>
</p>
</section>
<!-- FEATURES -->
<section id="features">
<div class="section-label">// KERNFUNKTIONEN</div>
<h2 class="section-title">Feature-Matrix</h2>
<div class="features-grid">
<div class="feature-card reveal">
<span class="feature-icon">[/\]</span>
<h3>Baumstruktur</h3>
<p>Hierarchische Organisation von XSL-Transformationen mit TreeNode-Architektur. Verwalte komplexe Abhängigkeitsketten über eine intuitive Baumansicht mit Drag-and-Drop.</p>
</div>
<div class="feature-card reveal">
<span class="feature-icon">[&lt;&gt;]</span>
<h3>PDF-Diff</h3>
<p>Visueller Drei-Panel-Vergleich: Referenz, Differenz und Neu. Alpha-Blending Overlay mit Zoom- und Pan-Funktionalitaet zum pixelgenauen Abgleich von PDF-Änderungen.</p>
</div>
<div class="feature-card reveal">
<span class="feature-icon">[##]</span>
<h3>Hash-Tracking</h3>
<p>Automatische blake2b-Hashsummen für alle XML-Dateien. Änderungen werden zuverlässig erkannt und im project.yaml persistent gespeichert.</p>
</div>
<div class="feature-card reveal">
<span class="feature-icon">[~~]</span>
<h3>Async-Verarbeitung</h3>
<p>Nicht-blockierende Hintergrund-Threads für Hash-Berechnung und Datenbankabfragen. Die GUI bleibt stets responsiv - mit Abbrechen-Dialog und Timeout-Steuerung.</p>
</div>
<div class="feature-card reveal">
<span class="feature-icon">[db]</span>
<h3>PostgreSQL</h3>
<p>Native Datenbankintegration mit ConnectorX und Polars DataFrames. SSL-Modus-Unterstützung und asynchrone Verbindungstests inklusive.</p>
</div>
<div class="feature-card reveal">
<span class="feature-icon">[=>]</span>
<h3>Toolchain-Konfiguration</h3>
<p>Flexible Verwaltung von Java VM, Saxon, Apache FOP und diff-pdf. ID-basierte Referenzierung ermöglicht projektübergreifende Konfigurationsprofile.</p>
</div>
</div>
</section>
<!-- WORKFLOW -->
<section id="workflow">
<div class="section-label">// ARBEITSABLAUF</div>
<h2 class="section-title">Workflow-Pipeline</h2>
<div class="workflow-steps">
<div class="workflow-step reveal">
<div class="step-number">01</div>
<div class="step-content">
<h3>XSL-Dateien bearbeiten</h3>
<p>Führe die benötigten Änderungen an den XSL-Stylesheets durch. DocuMentor Überwacht den Abhängigkeitsgraphen von über 100 verknüpften Dateien via xsl:import und xsl:include.</p>
<span class="cmd">vim vorlage_urkunde.xsl</span>
</div>
</div>
<div class="workflow-step reveal">
<div class="step-number">02</div>
<div class="step-content">
<h3>Transformation starten</h3>
<p>Starte die Saxon-Transformation direkt aus dem DocuMentor. Die gesamte Toolchain - von XSLT über FOP bis zur PDF-Generierung - wird automatisch orchestriert.</p>
<span class="cmd">saxon -> fop -> pdf-output/</span>
</div>
</div>
<div class="workflow-step reveal">
<div class="step-number">03</div>
<div class="step-content">
<h3>PDF-Diff begutachten</h3>
<p>Vergleiche die neu generierte PDF mit der Referenzversion im Drei-Panel-Viewer. Visuelles Alpha-Blending hebt jede Änderung hervor - Schrift, Layout, Positionen.</p>
<span class="cmd">diff-pdf --view referenz.pdf neu.pdf</span>
</div>
</div>
<div class="workflow-step reveal">
<div class="step-number">04</div>
<div class="step-content">
<h3>Ergebnis verifizieren</h3>
<p>Prüfe: Wurden nur die beabsichtigten PDF-Dateien geändert? Stimmt die Änderung mit der Erwartung überein? Bei Bedarf: zurück zu Schritt 1.</p>
<span class="cmd">status: VERIFIED | RETRY</span>
</div>
</div>
</div>
</section>
<!-- DEMO -->
<section id="demo">
<div class="section-label">// LIVE-AUSGABE</div>
<h2 class="section-title">Terminal-Vorschau</h2>
<div class="terminal-window reveal">
<div class="terminal-header">
<div class="terminal-dot r"></div>
<div class="terminal-dot y"></div>
<div class="terminal-dot g"></div>
<span class="terminal-title">documentor@workstation:~/projekte/flexnow</span>
</div>
<div class="terminal-body" id="terminal-output">
<div class="terminal-line"><span class="prompt">user@documentor:~$</span> <span class="cmd-text">documentor --projekt flexnow_urkunden</span></div>
<div class="terminal-line"><span class="info">[INFO]</span> <span class="output">Lade project.yaml ...</span></div>
<div class="terminal-line"><span class="info">[INFO]</span> <span class="output">Projektverzeichnis: /srv/flexnow/xsl-vorlagen</span></div>
<div class="terminal-line"><span class="info">[INFO]</span> <span class="output">Gefundene XSL-Dateien: 147</span></div>
<div class="terminal-line"><span class="info">[INFO]</span> <span class="output">Abhängigkeitsgraph: 23 Import-Ketten aufgeloest</span></div>
<div class="terminal-line"><span class="info">[INFO]</span> <span class="output">Hash-Berechnung gestartet (blake2b, async) ...</span></div>
<div class="terminal-line">&nbsp;</div>
<div class="terminal-line"><span class="success">[HASH]</span> <span class="output">urkunde_basis.xml blake2b:a4f8e2..OK</span></div>
<div class="terminal-line"><span class="success">[HASH]</span> <span class="output">zeugnis_master.xml blake2b:7c3d91..OK</span></div>
<div class="terminal-line"><span class="warning">[HASH]</span> <span class="output">bescheid_v3.xml blake2b:GEÄNDERT</span></div>
<div class="terminal-line"><span class="success">[HASH]</span> <span class="output">notenblatt.xml blake2b:f1b8a0..OK</span></div>
<div class="terminal-line">&nbsp;</div>
<div class="terminal-line"><span class="info">[XSLT]</span> <span class="output">Saxon HE 12.5 - Transformation läuft ...</span></div>
<div class="terminal-line"><span class="info">[FOP ]</span> <span class="output">Apache FOP 2.10 - PDF-Generierung ...</span></div>
<div class="terminal-line"><span class="success">[DONE]</span> <span class="highlight">4 PDFs generiert in 3.2s</span></div>
<div class="terminal-line">&nbsp;</div>
<div class="terminal-line"><span class="info">[DIFF]</span> <span class="output">Vergleiche Referenz <-> Neu ...</span></div>
<div class="terminal-line"><span class="success">[DIFF]</span> <span class="output">urkunde_basis.pdf IDENTISCH</span></div>
<div class="terminal-line"><span class="success">[DIFF]</span> <span class="output">zeugnis_master.pdf IDENTISCH</span></div>
<div class="terminal-line"><span class="warning">[DIFF]</span> <span class="highlight">bescheid_v3.pdf 2 Seiten geändert</span></div>
<div class="terminal-line"><span class="success">[DIFF]</span> <span class="output">notenblatt.pdf IDENTISCH</span></div>
<div class="terminal-line">&nbsp;</div>
<div class="terminal-line"><span class="prompt">user@documentor:~$</span> <span class="cursor-blink"></span></div>
</div>
</div>
</section>
<!-- TECH STACK -->
<section id="techstack">
<div class="section-label">// TECHNOLOGIE</div>
<h2 class="section-title">Tech-Stack</h2>
<div class="tech-grid">
<div class="tech-item reveal">
<span class="tech-icon">Py</span>
<div class="tech-name">Python</div>
<div class="tech-desc">Laufzeitumgebung</div>
</div>
<div class="tech-item reveal">
<span class="tech-icon">Qt</span>
<div class="tech-name">PySide6</div>
<div class="tech-desc">GUI-Framework</div>
</div>
<div class="tech-item reveal">
<span class="tech-icon">Sx</span>
<div class="tech-name">Saxon</div>
<div class="tech-desc">XSLT-Prozessor</div>
</div>
<div class="tech-item reveal">
<span class="tech-icon">Fp</span>
<div class="tech-name">Apache FOP</div>
<div class="tech-desc">PDF-Generierung</div>
</div>
<div class="tech-item reveal">
<span class="tech-icon">Df</span>
<div class="tech-name">diff-pdf</div>
<div class="tech-desc">PDF-Vergleich</div>
</div>
<div class="tech-item reveal">
<span class="tech-icon">Pg</span>
<div class="tech-name">PostgreSQL</div>
<div class="tech-desc">Datenbank</div>
</div>
<div class="tech-item reveal">
<span class="tech-icon">Pl</span>
<div class="tech-name">Polars</div>
<div class="tech-desc">DataFrames</div>
</div>
<div class="tech-item reveal">
<span class="tech-icon">Pd</span>
<div class="tech-name">Pydantic</div>
<div class="tech-desc">Konfiguration</div>
</div>
</div>
</section>
<!-- DOWNLOAD -->
<section id="download">
<div class="section-label">// INSTALLATION</div>
<h2 class="section-title">Erste Schritte</h2>
<div class="install-block">
<div class="install-label">Repository klonen</div>
<div class="install-cmd" onclick="copyCmd(this, 'git clone https://github.com/your-org/documentor.git')">
<div><span class="cmd-prefix">$ </span>git clone https://github.com/your-org/documentor.git</div>
<span class="copy-hint">[KLICK ZUM KOPIEREN]</span>
</div>
<div class="install-label" style="margin-top:20px">Abhängigkeiten installieren</div>
<div class="install-cmd" onclick="copyCmd(this, 'cd documentor && uv sync')">
<div><span class="cmd-prefix">$ </span>cd documentor && uv sync</div>
<span class="copy-hint">[KLICK ZUM KOPIEREN]</span>
</div>
<div class="install-label" style="margin-top:20px">Anwendung starten</div>
<div class="install-cmd" onclick="copyCmd(this, 'uv run python src/main.py')">
<div><span class="cmd-prefix">$ </span>uv run python src/main.py</div>
<span class="copy-hint">[KLICK ZUM KOPIEREN]</span>
</div>
<p class="install-note">// Verwendet den uv-Paketmanager für schnelle, reproduzierbare Builds</p>
</div>
<ul class="requirements-list">
<li>Python 3.13 oder höher</li>
<li>Java Runtime für Saxon</li>
<li>Apache FOP 2.x</li>
<li>diff-pdf (optional, für PDF-Vergleich)</li>
<li>PostgreSQL-Server (optional, für Datenbankintegration)</li>
<li>uv-Paketmanager</li>
</ul>
</section>
<!-- FOOTER -->
<footer>
<div class="footer-inner">
<div class="footer-ascii">
____ __ __ _
| _ \ ___ ___ _ | \/ | ___ _ __ | |_ ___ _ __
| | | |/ _ \ / __| | | | |\/| |/ _ \ '_ \| __/ _ \| '__|
| |_| | (_) | (__| |_| | | | | __/ | | | || (_) | |
|____/ \___/ \___|\__,_|_| |_|\___|_| |_|\__\___/|_|
</div>
<div class="footer-links">
<a href="#hero">// NACH OBEN</a>
<a href="https://github.com/your-org/documentor" target="_blank">// GITHUB</a>
<a href="#features">// FEATURES</a>
<a href="#download">// DOWNLOAD</a>
</div>
<p class="footer-copy">&copy; 2026 DocuMentor | XSL-Transformations-Toolkit | Gebaut mit PySide6</p>
</div>
</footer>
<script>
// ============================
// Matrix Rain
// ============================
const canvas = document.getElementById('matrix-canvas');
const ctx = canvas.getContext('2d');
function resizeCanvas() {
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
}
resizeCanvas();
window.addEventListener('resize', resizeCanvas);
const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789<>/={}[];:\'\"!@#$%^&*()_+-~`|\\'.split('');
const fontSize = 14;
let columns = Math.floor(canvas.width / fontSize);
let drops = Array(columns).fill(1);
function drawMatrix() {
ctx.fillStyle = 'rgba(10, 10, 10, 0.05)';
ctx.fillRect(0, 0, canvas.width, canvas.height);
ctx.fillStyle = '#00ff41';
ctx.font = fontSize + 'px "Share Tech Mono", monospace';
for (let i = 0; i < drops.length; i++) {
const text = chars[Math.floor(Math.random() * chars.length)];
ctx.fillText(text, i * fontSize, drops[i] * fontSize);
if (drops[i] * fontSize > canvas.height && Math.random() > 0.975) {
drops[i] = 0;
}
drops[i]++;
}
}
setInterval(drawMatrix, 50);
window.addEventListener('resize', () => {
columns = Math.floor(canvas.width / fontSize);
drops = Array(columns).fill(1);
});
// ============================
// Boot Sequence Animation
// ============================
const bootLines = document.querySelectorAll('.boot-line');
bootLines.forEach((line, i) => {
setTimeout(() => {
line.classList.add('visible');
}, 300 + i * 250);
});
// ============================
// Tagline Typing Effect
// ============================
const tagline = 'XSL-Transformationen validieren. PDF-Änderungen visualisieren. Qualität sichern.';
const taglineEl = document.getElementById('tagline');
let charIndex = 0;
function typeTagline() {
if (charIndex < tagline.length) {
taglineEl.textContent = tagline.substring(0, charIndex + 1);
charIndex++;
setTimeout(typeTagline, 35);
}
}
// Start typing after boot sequence
setTimeout(typeTagline, 300 + bootLines.length * 250 + 500);
// ============================
// Scroll Reveal
// ============================
const revealElements = document.querySelectorAll('.reveal, .workflow-step');
const revealObserver = new IntersectionObserver((entries) => {
entries.forEach(entry => {
if (entry.isIntersecting) {
entry.target.classList.add('visible');
}
});
}, {
threshold: 0.15,
rootMargin: '0px 0px -50px 0px'
});
revealElements.forEach(el => revealObserver.observe(el));
// ============================
// Mobile Nav Toggle
// ============================
document.getElementById('hamburger').addEventListener('click', () => {
document.getElementById('nav-links').classList.toggle('open');
});
// Close nav on link click (mobile)
document.querySelectorAll('#nav-links a').forEach(link => {
link.addEventListener('click', () => {
document.getElementById('nav-links').classList.remove('open');
});
});
// ============================
// Copy Command to Clipboard
// ============================
function copyCmd(el, text) {
navigator.clipboard.writeText(text).then(() => {
const hint = el.querySelector('.copy-hint');
const original = hint.textContent;
hint.textContent = '[KOPIERT!]';
hint.style.color = 'var(--green)';
setTimeout(() => {
hint.textContent = original;
hint.style.color = '';
}, 2000);
});
}
</script>
</body>
</html>