2026-03-03 20:47:56 +01:00
<!DOCTYPE html>
< html lang = "de" >
< head >
< meta charset = "UTF-8" >
< meta name = "viewport" content = "width=device-width, initial-scale=1.0" >
< title > DocuMentor — XSL-Transformationen unter Kontrolle</ title >
2026-03-03 21:19:54 +01:00
< link rel = "stylesheet" href = "fonts/fonts_v2.css" >
2026-03-03 20:47:56 +01:00
< style >
*, * :: before , * :: after {
margin : 0 ;
padding : 0 ;
box-sizing : border-box ;
}
: root {
--black : #000000 ;
--white : #ffffff ;
--off-white : #f0f0f0 ;
--neon-red : #ff0033 ;
--neon-red-dim : #cc0029 ;
--gray-dark : #1a1a1a ;
--gray-mid : #333333 ;
--gray-light : #888888 ;
--border-thick : 4 px ;
--border-thin : 2 px ;
--font-mono : 'Space Mono' , 'Courier New' , monospace ;
}
html {
scroll-behavior : auto ;
}
body {
font-family : var ( -- font - mono );
background : var ( -- white );
color : var ( -- black );
line-height : 1.6 ;
overflow-x : hidden ;
}
/* ========== BRUTALIST RESETS ========== */
:: selection {
background : var ( -- neon - red );
color : var ( -- white );
}
a {
color : var ( -- neon - red );
text-decoration : none ;
border-bottom : var ( -- border - thin ) solid var ( -- neon - red );
}
a : hover {
background : var ( -- neon - red );
color : var ( -- white );
}
/* ========== GRID OVERLAY ========== */
body :: before {
content : '' ;
position : fixed ;
top : 0 ;
left : 0 ;
width : 100 % ;
height : 100 % ;
background-image :
linear-gradient ( 90 deg , rgba ( 0 , 0 , 0 , 0.03 ) 1 px , transparent 1 px ),
linear-gradient ( 0 deg , rgba ( 0 , 0 , 0 , 0.03 ) 1 px , transparent 1 px );
background-size : 60 px 60 px ;
pointer-events : none ;
z-index : 0 ;
}
/* ========== NAVIGATION ========== */
nav {
position : fixed ;
top : 0 ;
left : 0 ;
width : 100 % ;
z-index : 1000 ;
background : var ( -- black );
color : var ( -- white );
border-bottom : var ( -- border - thick ) solid var ( -- neon - red );
padding : 0 ;
}
nav . nav-inner {
display : flex ;
align-items : stretch ;
justify-content : space-between ;
max-width : 1400 px ;
margin : 0 auto ;
}
nav . nav-brand {
font-weight : 700 ;
font-size : 1.1 rem ;
text-transform : uppercase ;
letter-spacing : 3 px ;
padding : 14 px 24 px ;
border-right : var ( -- border - thin ) solid var ( -- gray - mid );
color : var ( -- white );
border-bottom : none ;
display : flex ;
align-items : center ;
gap : 8 px ;
}
nav . nav-brand span {
color : var ( -- neon - red );
}
nav . nav-links {
display : flex ;
list-style : none ;
align-items : stretch ;
}
nav . nav-links li {
border-left : var ( -- border - thin ) solid var ( -- gray - mid );
}
nav . nav-links a {
display : flex ;
align-items : center ;
padding : 14 px 20 px ;
color : var ( -- white );
text-transform : uppercase ;
font-size : 0.7 rem ;
letter-spacing : 2 px ;
border-bottom : none ;
transition : none ;
}
nav . nav-links a : hover {
background : var ( -- neon - red );
color : var ( -- white );
}
/* ========== HERO ========== */
. hero {
position : relative ;
min-height : 100 vh ;
display : flex ;
flex-direction : column ;
justify-content : center ;
padding : 120 px 40 px 80 px ;
background : var ( -- black );
color : var ( -- white );
border-bottom : var ( -- border - thick ) solid var ( -- neon - red );
overflow : hidden ;
}
. hero :: before {
content : 'XSL→PDF XSL→PDF XSL→PDF XSL→PDF XSL→PDF XSL→PDF XSL→PDF XSL→PDF XSL→PDF XSL→PDF XSL→PDF XSL→PDF XSL→PDF XSL→PDF XSL→PDF XSL→PDF XSL→PDF XSL→PDF XSL→PDF XSL→PDF' ;
position : absolute ;
top : 0 ;
left : 0 ;
width : 200 % ;
height : 100 % ;
font-size : 1.2 rem ;
color : rgba ( 255 , 255 , 255 , 0.03 );
word-break : break-all ;
line-height : 2 ;
letter-spacing : 8 px ;
pointer-events : none ;
z-index : 0 ;
}
. hero-content {
position : relative ;
z-index : 1 ;
max-width : 1400 px ;
margin : 0 auto ;
width : 100 % ;
}
. hero-label {
display : inline-block ;
font-size : 0.7 rem ;
text-transform : uppercase ;
letter-spacing : 4 px ;
border : var ( -- border - thin ) solid var ( -- neon - red );
padding : 6 px 16 px ;
margin-bottom : 40 px ;
color : var ( -- neon - red );
}
. hero h1 {
font-family : var ( -- font - mono );
font-size : clamp ( 3 rem , 10 vw , 8 rem );
font-weight : 700 ;
text-transform : uppercase ;
line-height : 0.95 ;
letter-spacing : -3 px ;
margin-bottom : 40 px ;
}
. hero h1 . red {
color : var ( -- neon - red );
display : block ;
}
. hero-tagline {
font-size : 1.1 rem ;
max-width : 700 px ;
line-height : 1.8 ;
color : var ( -- gray - light );
border-left : var ( -- border - thick ) solid var ( -- neon - red );
padding-left : 24 px ;
margin-bottom : 50 px ;
}
. hero-stats {
display : flex ;
gap : 0 ;
border : var ( -- border - thick ) solid var ( -- white );
width : fit-content ;
}
. hero-stat {
padding : 20 px 32 px ;
border-right : var ( -- border - thin ) solid var ( -- gray - mid );
text-align : center ;
}
. hero-stat : last-child {
border-right : none ;
}
. hero-stat . number {
font-size : 2 rem ;
font-weight : 700 ;
color : var ( -- neon - red );
display : block ;
}
. hero-stat . label {
font-size : 0.6 rem ;
text-transform : uppercase ;
letter-spacing : 2 px ;
color : var ( -- gray - light );
}
/* ========== SECTION BASE ========== */
section {
position : relative ;
z-index : 1 ;
padding : 100 px 40 px ;
}
. section-inner {
max-width : 1400 px ;
margin : 0 auto ;
}
. section-header {
margin-bottom : 60 px ;
}
. section-number {
font-size : 0.7 rem ;
text-transform : uppercase ;
letter-spacing : 4 px ;
color : var ( -- neon - red );
margin-bottom : 12 px ;
display : block ;
}
. section-title {
font-size : clamp ( 2 rem , 5 vw , 3.5 rem );
font-weight : 700 ;
text-transform : uppercase ;
letter-spacing : -1 px ;
line-height : 1.1 ;
}
. section-title . muted {
color : var ( -- gray - light );
}
. section-divider {
width : 100 % ;
height : var ( -- border - thick );
background : var ( -- black );
margin-top : 20 px ;
}
/* ========== FEATURES ========== */
. features {
background : var ( -- white );
border-bottom : var ( -- border - thick ) solid var ( -- black );
}
. features-grid {
display : grid ;
grid-template-columns : repeat ( 3 , 1 fr );
border : var ( -- border - thick ) solid var ( -- black );
}
. feature-card {
padding : 40 px 32 px ;
border-right : var ( -- border - thin ) solid var ( -- black );
border-bottom : var ( -- border - thin ) solid var ( -- black );
position : relative ;
transition : none ;
}
. feature-card : nth-child ( 3n ) {
border-right : none ;
}
. feature-card : nth-child ( n + 4 ) {
border-bottom : none ;
}
. feature-card : hover {
background : var ( -- black );
color : var ( -- white );
}
. feature-card : hover . feature-icon {
color : var ( -- neon - red );
}
. feature-card : hover . feature-num {
color : var ( -- neon - red );
}
. feature-icon {
font-size : 2.5 rem ;
margin-bottom : 16 px ;
display : block ;
filter : grayscale ( 0 );
}
. feature-num {
font-size : 0.65 rem ;
text-transform : uppercase ;
letter-spacing : 3 px ;
color : var ( -- gray - light );
margin-bottom : 12 px ;
display : block ;
}
. feature-card h3 {
font-size : 1.1 rem ;
text-transform : uppercase ;
letter-spacing : 1 px ;
margin-bottom : 12 px ;
font-weight : 700 ;
}
. feature-card p {
font-size : 0.8 rem ;
line-height : 1.7 ;
color : var ( -- gray - light );
}
. feature-card : hover p {
color : var ( -- gray - light );
}
/* ========== WORKFLOW ========== */
. workflow {
background : var ( -- black );
color : var ( -- white );
border-bottom : var ( -- border - thick ) solid var ( -- neon - red );
}
. workflow . section-title {
color : var ( -- white );
}
. workflow . section-divider {
background : var ( -- white );
}
. workflow-steps {
display : grid ;
grid-template-columns : repeat ( 4 , 1 fr );
gap : 0 ;
border : var ( -- border - thick ) solid var ( -- white );
}
. workflow-step {
padding : 40 px 28 px ;
border-right : var ( -- border - thin ) solid var ( -- gray - mid );
position : relative ;
}
. workflow-step : last-child {
border-right : none ;
}
. step-num {
font-size : 4 rem ;
font-weight : 700 ;
color : var ( -- neon - red );
line-height : 1 ;
margin-bottom : 20 px ;
display : block ;
}
. workflow-step h3 {
font-size : 1 rem ;
text-transform : uppercase ;
letter-spacing : 1 px ;
margin-bottom : 12 px ;
font-weight : 700 ;
}
. workflow-step p {
font-size : 0.78 rem ;
line-height : 1.7 ;
color : var ( -- gray - light );
}
. workflow-step . arrow {
position : absolute ;
right : -14 px ;
top : 50 % ;
transform : translateY ( -50 % );
font-size : 1.5 rem ;
color : var ( -- neon - red );
z-index : 2 ;
}
/* ========== DEMO / SCREENSHOT ========== */
. demo {
background : var ( -- off - white );
border-bottom : var ( -- border - thick ) solid var ( -- black );
}
. demo-mockup {
border : var ( -- border - thick ) solid var ( -- black );
background : var ( -- white );
position : relative ;
}
. demo-titlebar {
background : var ( -- black );
color : var ( -- white );
padding : 10 px 20 px ;
display : flex ;
align-items : center ;
justify-content : space-between ;
font-size : 0.75 rem ;
text-transform : uppercase ;
letter-spacing : 2 px ;
}
. demo-dots {
display : flex ;
gap : 8 px ;
}
. demo-dot {
width : 12 px ;
height : 12 px ;
border : var ( -- border - thin ) solid var ( -- white );
}
. demo-dot . red {
background : var ( -- neon - red );
border-color : var ( -- neon - red );
}
. demo-body {
display : grid ;
grid-template-columns : 260 px 1 fr ;
min-height : 500 px ;
}
. demo-sidebar {
border-right : var ( -- border - thick ) solid var ( -- black );
padding : 20 px ;
font-size : 0.72 rem ;
background : var ( -- off - white );
}
. demo-tree-item {
padding : 6 px 0 ;
padding-left : 0 ;
border-bottom : 1 px solid #ddd ;
}
. demo-tree-item . indent-1 { padding-left : 16 px ; }
. demo-tree-item . indent-2 { padding-left : 32 px ; }
. demo-tree-item . indent-3 { padding-left : 48 px ; }
. demo-tree-item . icon {
margin-right : 6 px ;
}
. demo-tree-item . active {
background : var ( -- neon - red );
color : var ( -- white );
padding : 6 px 8 px ;
margin : 0 -20 px ;
padding-left : 52 px ;
}
. demo-main {
display : grid ;
grid-template-columns : repeat ( 3 , 1 fr );
}
. demo-panel {
border-right : var ( -- border - thin ) solid var ( -- black );
position : relative ;
display : flex ;
flex-direction : column ;
}
. demo-panel : last-child {
border-right : none ;
}
. demo-panel-header {
padding : 10 px 16 px ;
font-size : 0.65 rem ;
text-transform : uppercase ;
letter-spacing : 2 px ;
border-bottom : var ( -- border - thin ) solid var ( -- black );
background : var ( -- off - white );
font-weight : 700 ;
}
. demo-panel-body {
flex : 1 ;
display : flex ;
align-items : center ;
justify-content : center ;
padding : 30 px ;
position : relative ;
min-height : 400 px ;
}
. demo-pdf-placeholder {
width : 100 % ;
height : 100 % ;
position : absolute ;
top : 0 ;
left : 0 ;
display : flex ;
flex-direction : column ;
align-items : center ;
justify-content : center ;
font-size : 0.7 rem ;
color : var ( -- gray - light );
text-transform : uppercase ;
letter-spacing : 2 px ;
}
. demo-pdf-placeholder . pdf-icon {
font-size : 3 rem ;
margin-bottom : 12 px ;
opacity : 0.4 ;
}
. demo-panel . diff . demo-panel-header {
background : var ( -- neon - red );
color : var ( -- white );
}
. demo-panel . diff . demo-pdf-placeholder {
background : repeating-linear-gradient (
45 deg ,
transparent ,
transparent 10 px ,
rgba ( 255 , 0 , 51 , 0.04 ) 10 px ,
rgba ( 255 , 0 , 51 , 0.04 ) 20 px
);
}
. demo-statusbar {
background : var ( -- black );
color : var ( -- gray - light );
padding : 8 px 20 px ;
font-size : 0.65 rem ;
display : flex ;
justify-content : space-between ;
text-transform : uppercase ;
letter-spacing : 1 px ;
}
. demo-statusbar . status-ok {
color : #00ff66 ;
}
/* ========== TECH STACK ========== */
. tech {
background : var ( -- white );
border-bottom : var ( -- border - thick ) solid var ( -- black );
}
. tech-grid {
display : grid ;
grid-template-columns : repeat ( 4 , 1 fr );
border : var ( -- border - thick ) solid var ( -- black );
}
. tech-item {
padding : 32 px 24 px ;
border-right : var ( -- border - thin ) solid var ( -- black );
border-bottom : var ( -- border - thin ) solid var ( -- black );
text-align : center ;
}
. tech-item : nth-child ( 4n ) {
border-right : none ;
}
. tech-item : nth-child ( n + 5 ) {
border-bottom : none ;
}
. tech-item : hover {
background : var ( -- black );
color : var ( -- white );
}
. tech-item . tech-icon {
font-size : 2 rem ;
margin-bottom : 10 px ;
display : block ;
}
. tech-item h4 {
font-size : 0.85 rem ;
text-transform : uppercase ;
letter-spacing : 2 px ;
font-weight : 700 ;
margin-bottom : 6 px ;
}
. tech-item p {
font-size : 0.68 rem ;
color : var ( -- gray - light );
letter-spacing : 1 px ;
}
. tech-item : hover p {
color : var ( -- gray - light );
}
/* ========== DOWNLOAD ========== */
. download {
background : var ( -- black );
color : var ( -- white );
border-bottom : var ( -- border - thick ) solid var ( -- neon - red );
}
. download . section-title {
color : var ( -- white );
}
. download . section-divider {
background : var ( -- white );
}
. download-content {
display : grid ;
grid-template-columns : 1 fr 1 fr ;
gap : 0 ;
border : var ( -- border - thick ) solid var ( -- white );
}
. download-info {
padding : 48 px 40 px ;
border-right : var ( -- border - thick ) solid var ( -- white );
}
. download-info h3 {
font-size : 1.2 rem ;
text-transform : uppercase ;
letter-spacing : 1 px ;
margin-bottom : 20 px ;
font-weight : 700 ;
}
. download-info p {
font-size : 0.82 rem ;
line-height : 1.8 ;
color : var ( -- gray - light );
margin-bottom : 24 px ;
}
. download-info ul {
list-style : none ;
margin-bottom : 32 px ;
}
. download-info ul li {
padding : 8 px 0 ;
font-size : 0.78 rem ;
border-bottom : 1 px solid var ( -- gray - mid );
display : flex ;
align-items : center ;
gap : 10 px ;
}
. download-info ul li . check {
color : var ( -- neon - red );
font-weight : 700 ;
}
. download-code {
padding : 48 px 40 px ;
display : flex ;
flex-direction : column ;
justify-content : center ;
}
. code-block {
background : var ( -- gray - dark );
border : var ( -- border - thin ) solid var ( -- gray - mid );
padding : 0 ;
margin-bottom : 20 px ;
}
. code-block-header {
padding : 10 px 16 px ;
font-size : 0.6 rem ;
text-transform : uppercase ;
letter-spacing : 2 px ;
color : var ( -- gray - light );
border-bottom : var ( -- border - thin ) solid var ( -- gray - mid );
}
. code-block pre {
padding : 20 px ;
font-family : var ( -- font - mono );
font-size : 0.82 rem ;
line-height : 1.8 ;
overflow-x : auto ;
color : var ( -- off - white );
}
. code-block pre . comment {
color : var ( -- gray - light );
}
. code-block pre . cmd {
color : var ( -- neon - red );
}
. btn-brutal {
display : inline-block ;
padding : 16 px 32 px ;
background : var ( -- neon - red );
color : var ( -- white );
font-family : var ( -- font - mono );
font-size : 0.8 rem ;
font-weight : 700 ;
text-transform : uppercase ;
letter-spacing : 3 px ;
border : var ( -- border - thick ) solid var ( -- white );
cursor : pointer ;
border-bottom : var ( -- border - thick ) solid var ( -- white );
text-align : center ;
}
. btn-brutal : hover {
background : var ( -- white );
color : var ( -- black );
}
/* ========== FOOTER ========== */
footer {
background : var ( -- black );
color : var ( -- white );
padding : 0 ;
}
. footer-inner {
max-width : 1400 px ;
margin : 0 auto ;
display : grid ;
grid-template-columns : 1 fr 1 fr 1 fr ;
border-top : var ( -- border - thick ) solid var ( -- neon - red );
}
. footer-col {
padding : 40 px 32 px ;
border-right : var ( -- border - thin ) solid var ( -- gray - mid );
}
. footer-col : last-child {
border-right : none ;
}
. footer-col h4 {
font-size : 0.75 rem ;
text-transform : uppercase ;
letter-spacing : 3 px ;
margin-bottom : 20 px ;
color : var ( -- neon - red );
font-weight : 700 ;
}
. footer-col p ,
. footer-col li {
font-size : 0.72 rem ;
line-height : 2 ;
color : var ( -- gray - light );
}
. footer-col ul {
list-style : none ;
}
. footer-col a {
color : var ( -- gray - light );
border-bottom : 1 px solid var ( -- gray - mid );
}
. footer-col a : hover {
color : var ( -- white );
background : var ( -- neon - red );
}
. footer-bottom {
border-top : var ( -- border - thin ) solid var ( -- gray - mid );
padding : 20 px 40 px ;
font-size : 0.65 rem ;
text-transform : uppercase ;
letter-spacing : 2 px ;
color : var ( -- gray - light );
display : flex ;
justify-content : space-between ;
max-width : 1400 px ;
margin : 0 auto ;
}
/* ========== MARQUEE ========== */
. marquee-bar {
background : var ( -- neon - red );
color : var ( -- white );
padding : 10 px 0 ;
overflow : hidden ;
white-space : nowrap ;
font-size : 0.7 rem ;
text-transform : uppercase ;
letter-spacing : 4 px ;
font-weight : 700 ;
border-bottom : var ( -- border - thick ) solid var ( -- black );
}
. marquee-content {
display : inline-block ;
animation : marquee 20 s linear infinite ;
}
@ keyframes marquee {
0 % { transform : translateX ( 0 ); }
100 % { transform : translateX ( -50 % ); }
}
/* ========== GLITCH EFFECT ========== */
. glitch {
position : relative ;
}
. glitch : hover :: before ,
. glitch : hover :: after {
content : attr ( data - text );
position : absolute ;
top : 0 ;
left : 0 ;
width : 100 % ;
height : 100 % ;
}
. glitch : hover :: before {
color : var ( -- neon - red );
z-index : -1 ;
animation : glitch-1 0.3 s steps ( 2 ) infinite ;
}
. glitch : hover :: after {
color : cyan ;
z-index : -2 ;
animation : glitch-2 0.3 s steps ( 2 ) infinite ;
}
@ keyframes glitch-1 {
0 % { clip-path : inset ( 20 % 0 60 % 0 ); transform : translate ( -3 px , 0 ); }
50 % { clip-path : inset ( 50 % 0 20 % 0 ); transform : translate ( 3 px , 0 ); }
100 % { clip-path : inset ( 10 % 0 70 % 0 ); transform : translate ( -2 px , 0 ); }
}
@ keyframes glitch-2 {
0 % { clip-path : inset ( 60 % 0 10 % 0 ); transform : translate ( 3 px , 0 ); }
50 % { clip-path : inset ( 20 % 0 50 % 0 ); transform : translate ( -3 px , 0 ); }
100 % { clip-path : inset ( 70 % 0 5 % 0 ); transform : translate ( 2 px , 0 ); }
}
/* ========== RESPONSIVE ========== */
@ media ( max-width : 1024px ) {
. features-grid {
grid-template-columns : repeat ( 2 , 1 fr );
}
. feature-card : nth-child ( 3n ) {
border-right : var ( -- border - thin ) solid var ( -- black );
}
. feature-card : nth-child ( 2n ) {
border-right : none ;
}
. feature-card : nth-child ( n + 4 ) {
border-bottom : var ( -- border - thin ) solid var ( -- black );
}
. feature-card : nth-child ( n + 5 ) {
border-bottom : none ;
}
. workflow-steps {
grid-template-columns : repeat ( 2 , 1 fr );
}
. workflow-step : nth-child ( 2 ) . arrow {
display : none ;
}
. workflow-step {
border-bottom : var ( -- border - thin ) solid var ( -- gray - mid );
}
. tech-grid {
grid-template-columns : repeat ( 2 , 1 fr );
}
. download-content {
grid-template-columns : 1 fr ;
}
. download-info {
border-right : none ;
border-bottom : var ( -- border - thick ) solid var ( -- white );
}
. demo-body {
grid-template-columns : 1 fr ;
}
. demo-sidebar {
border-right : none ;
border-bottom : var ( -- border - thick ) solid var ( -- black );
}
. demo-main {
grid-template-columns : 1 fr ;
}
. demo-panel {
border-right : none ;
border-bottom : var ( -- border - thin ) solid var ( -- black );
}
. demo-panel-body {
min-height : 200 px ;
}
}
@ media ( max-width : 768px ) {
section {
padding : 60 px 20 px ;
}
. hero {
padding : 100 px 20 px 60 px ;
}
nav . nav-links {
display : none ;
}
. features-grid {
grid-template-columns : 1 fr ;
}
. feature-card {
border-right : none !important ;
border-bottom : var ( -- border - thin ) solid var ( -- black ) !important ;
}
. feature-card : last-child {
border-bottom : none !important ;
}
. workflow-steps {
grid-template-columns : 1 fr ;
}
. workflow-step {
border-right : none ;
}
. workflow-step . arrow {
display : none ;
}
. tech-grid {
grid-template-columns : 1 fr ;
}
. tech-item {
border-right : none !important ;
}
. footer-inner {
grid-template-columns : 1 fr ;
}
. footer-col {
border-right : none ;
border-bottom : var ( -- border - thin ) solid var ( -- gray - mid );
}
. hero-stats {
flex-direction : column ;
}
. hero-stat {
border-right : none ;
border-bottom : var ( -- border - thin ) solid var ( -- gray - mid );
}
. hero-stat : last-child {
border-bottom : none ;
}
}
/* ========== BLINK CURSOR ========== */
. cursor {
display : inline-block ;
width : 3 px ;
height : 1 em ;
background : var ( -- neon - red );
margin-left : 4 px ;
vertical-align : text - bottom ;
animation : blink 0.7 s step-end infinite ;
}
@ keyframes blink {
0 %, 100 % { opacity : 1 ; }
50 % { opacity : 0 ; }
}
/* ========== SCROLL REVEAL ========== */
. reveal {
opacity : 0 ;
transform : translateY ( 30 px );
}
. reveal . visible {
opacity : 1 ;
transform : translateY ( 0 );
transition : opacity 0.1 s step-end , transform 0.1 s step-end ;
}
</ style >
</ head >
< body >
<!-- NAVIGATION -->
< nav >
< div class = "nav-inner" >
< a href = "#hero" class = "nav-brand" >< span > ■ </ span > DocuMentor</ a >
< ul class = "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 = "#tech" > Tech-Stack</ a ></ li >
< li >< a href = "#download" > Download</ a ></ li >
</ ul >
</ div >
</ nav >
<!-- HERO -->
< section class = "hero" id = "hero" >
< div class = "hero-content" >
< span class = "hero-label" > Desktop-Anwendung // PySide6 // Open Source</ span >
< h1 >
< span class = "glitch" data-text = "DOCU" > DOCU</ span >< span class = "red glitch" data-text = "MENTOR" > MENTOR</ span >
</ h1 >
< p class = "hero-tagline" >
XSL-Transformationen unter Kontrolle. Validieren. Vergleichen. Verifizieren.
Die Toolchain für Entwickler, die PDF-Dokumente aus XSL/XML erzeugen
und Änderungen lückenlos nachverfolgen muessen.< span class = "cursor" ></ span >
</ p >
< div class = "hero-stats" >
< div class = "hero-stat" >
< span class = "number" > 100+</ span >
< span class = "label" > XSL-Dateien</ span >
</ div >
< div class = "hero-stat" >
< span class = "number" > 3</ span >
< span class = "label" > PDF-Panels</ span >
</ div >
< div class = "hero-stat" >
< span class = "number" > BLAKE2B</ span >
< span class = "label" > Hash-Tracking</ span >
</ div >
< div class = "hero-stat" >
< span class = "number" > ∞ </ span >
< span class = "label" > Transformationen</ span >
</ div >
</ div >
</ div >
</ section >
<!-- MARQUEE -->
< div class = "marquee-bar" >
< div class = "marquee-content" >
SAXON • APACHE FOP • DIFF-PDF • POSTGRESQL • PYSIDE6 • BLAKE2B • XSL • XML • PDF •
SAXON • APACHE FOP • DIFF-PDF • POSTGRESQL • PYSIDE6 • BLAKE2B • XSL • XML • PDF •
SAXON • APACHE FOP • DIFF-PDF • POSTGRESQL • PYSIDE6 • BLAKE2B • XSL • XML • PDF •
SAXON • APACHE FOP • DIFF-PDF • POSTGRESQL • PYSIDE6 • BLAKE2B • XSL • XML • PDF •
</ div >
</ div >
<!-- FEATURES -->
< section class = "features" id = "features" >
< div class = "section-inner" >
< div class = "section-header reveal" >
< span class = "section-number" > 01 // Features</ span >
< h2 class = "section-title" > Was DocuMentor < span class = "muted" > leistet</ span ></ h2 >
< div class = "section-divider" ></ div >
</ div >
< div class = "features-grid reveal" >
< div class = "feature-card" >
< span class = "feature-icon" > ☰ </ span >
< span class = "feature-num" > Feature 01</ span >
< h3 > Baumstruktur</ h3 >
< p > Hierarchische Organisation von XSL-Transformationen. TreeNode, XslFile und XmlFile bilden eine übersichtliche Projektstruktur. Import- und Include-Abhängigkeiten auf einen Blick.</ p >
</ div >
< div class = "feature-card" >
< span class = "feature-icon" > ▦ </ span >
< span class = "feature-num" > Feature 02</ span >
< h3 > PDF-Diff</ h3 >
< p > Drei-Panel-Ansicht: Referenz, Diff und Neu. Visueller Vergleich mit Alpha-Blending. Änderungen in PDF-Dokumenten sofort erkennen — Pixel für Pixel.</ p >
</ div >
< div class = "feature-card" >
< span class = "feature-icon" > #_</ span >
< span class = "feature-num" > Feature 03</ span >
< h3 > Hash-Tracking</ h3 >
< p > BLAKE2B-Hashing zur Änderungsverfolgung von XML-Dateien. Automatische Berechnung beim Laden. 64-Zeichen-Hexdigest in project.yaml persistiert.</ p >
</ div >
< div class = "feature-card" >
< span class = "feature-icon" > ⇄ </ span >
< span class = "feature-num" > Feature 04</ span >
< h3 > Async-Verarbeitung</ h3 >
< p > Hintergrund-Threads für Hash-Berechnungen und Datenbank-Abfragen. Die UI bleibt reaktionsfähig — auch bei 100+ Dateien. Abbrechen-Dialog inklusive.</ p >
</ div >
< div class = "feature-card" >
< span class = "feature-icon" > ⎓ </ span >
< span class = "feature-num" > Feature 05</ span >
< h3 > PostgreSQL</ h3 >
< p > Datenbankintegration mit Polars und ConnectorX. SSL-Unterstützung. SQL-Abfragen direkt aus der Anwendung. Ergebnisse als DataFrames.</ p >
</ div >
< div class = "feature-card" >
< span class = "feature-icon" > ⚙ </ span >
< span class = "feature-num" > Feature 06</ span >
< h3 > Toolchain-Konfig</ h3 >
< p > Zentrale Verwaltung: Java VM, Saxon JAR, Apache FOP, diff-pdf. ID-basierte Referenzierung. Projekte koennen verschiedene Tool-Versionen verwenden.</ p >
</ div >
</ div >
</ div >
</ section >
<!-- WORKFLOW -->
< section class = "workflow" id = "workflow" >
< div class = "section-inner" >
< div class = "section-header reveal" >
< span class = "section-number" > 02 // Workflow</ span >
< h2 class = "section-title" > Vier Schritte < span style = "color:var(--neon-red);" > zum Ergebnis</ span ></ h2 >
< div class = "section-divider" ></ div >
</ div >
< div class = "workflow-steps reveal" >
< div class = "workflow-step" >
< span class = "step-num" > 01</ span >
< h3 > XSL bearbeiten</ h3 >
< p > Änderungen an den XSL-Dateien durchführen. Import- und Include-Verknüpfungen beachten — eine Änderung kann viele Dokumente betreffen.</ p >
< span class = "arrow" > ▶ </ span >
</ div >
< div class = "workflow-step" >
< span class = "step-num" > 02</ span >
< h3 > Transformation starten</ h3 >
< p > Saxon führt die XSLT-Transformation durch. Apache FOP erzeugt die PDF-Ausgabe. Alles konfigurierbar über die Toolchain.</ p >
< span class = "arrow" > ▶ </ span >
</ div >
< div class = "workflow-step" >
< span class = "step-num" > 03</ span >
< h3 > PDF-Diff begutachten</ h3 >
< p > Die Drei-Panel-Ansicht zeigt Referenz, Differenz und neues Dokument. diff-pdf markiert alle Änderungen visuell.</ p >
< span class = "arrow" > ▶ </ span >
</ div >
< div class = "workflow-step" >
< span class = "step-num" > 04</ span >
< h3 > Ergebnis verifizieren</ h3 >
< p > Wurden die richtigen PDFs geändert? Entsprechen die Änderungen den Erwartungen? Bei Bedarf: zurück zu Schritt 1.</ p >
</ div >
</ div >
</ div >
</ section >
<!-- DEMO / SCREENSHOT -->
< section class = "demo" id = "demo" >
< div class = "section-inner" >
< div class = "section-header reveal" >
< span class = "section-number" > 03 // Oberfläche</ span >
< h2 class = "section-title" > Die Anwendung < span class = "muted" > im Einsatz</ span ></ h2 >
< div class = "section-divider" ></ div >
</ div >
< div class = "demo-mockup reveal" >
< div class = "demo-titlebar" >
< div class = "demo-dots" >
< div class = "demo-dot red" ></ div >
< div class = "demo-dot" ></ div >
< div class = "demo-dot" ></ div >
</ div >
< span > DocuMentor v1.0 — Projekt: Pruefungsdokumente</ span >
< span style = "color:var(--gray-light);" > ■ PySide6</ span >
</ div >
< div class = "demo-body" >
< div class = "demo-sidebar" >
< div class = "demo-tree-item" >< span class = "icon" > ▼ </ span > < strong > Urkunden</ strong ></ div >
< div class = "demo-tree-item indent-1" >< span class = "icon" > ▼ </ span > bachelor_urkunde.xsl</ div >
< div class = "demo-tree-item indent-2" >< span class = "icon" > ● </ span > student_01.xml</ div >
< div class = "demo-tree-item indent-2 active" >< span class = "icon" > ● </ span > student_02.xml</ div >
< div class = "demo-tree-item indent-2" >< span class = "icon" > ● </ span > student_03.xml</ div >
< div class = "demo-tree-item indent-1" >< span class = "icon" > ▶ </ span > master_urkunde.xsl</ div >
< div class = "demo-tree-item" >< span class = "icon" > ▼ </ span > < strong > Zeugnisse</ strong ></ div >
< div class = "demo-tree-item indent-1" >< span class = "icon" > ▶ </ span > zeugnis_ba.xsl</ div >
< div class = "demo-tree-item indent-1" >< span class = "icon" > ▶ </ span > zeugnis_ma.xsl</ div >
< div class = "demo-tree-item" >< span class = "icon" > ▶ </ span > < strong > Bescheide</ strong ></ div >
</ div >
< div class = "demo-main" >
< div class = "demo-panel" >
< div class = "demo-panel-header" > Referenz-PDF</ div >
< div class = "demo-panel-body" >
< div class = "demo-pdf-placeholder" >
< span class = "pdf-icon" > ◼ </ span >
Referenz
</ div >
</ div >
</ div >
< div class = "demo-panel diff" >
< div class = "demo-panel-header" > ■ Diff-Ansicht</ div >
< div class = "demo-panel-body" >
< div class = "demo-pdf-placeholder" >
< span class = "pdf-icon" > ◼ </ span >
Differenz
</ div >
</ div >
</ div >
< div class = "demo-panel" >
< div class = "demo-panel-header" > Neues PDF</ div >
< div class = "demo-panel-body" >
< div class = "demo-pdf-placeholder" >
< span class = "pdf-icon" > ◼ </ span >
Neu generiert
</ div >
</ div >
</ div >
</ div >
</ div >
< div class = "demo-statusbar" >
< span > student_02.xml — BLAKE2B: < span style = "color:var(--neon-red);" > a3f7c9...</ span ></ span >
< span class = "status-ok" > ■ Transformation abgeschlossen</ span >
</ div >
</ div >
</ div >
</ section >
<!-- TECH STACK -->
< section class = "tech" id = "tech" >
< div class = "section-inner" >
< div class = "section-header reveal" >
< span class = "section-number" > 04 // Tech-Stack</ span >
< h2 class = "section-title" > Gebaut mit < span class = "muted" > roher Kraft</ span ></ h2 >
< div class = "section-divider" ></ div >
</ div >
< div class = "tech-grid reveal" >
< div class = "tech-item" >
< span class = "tech-icon" > ◆ </ span >
< h4 > Python</ h4 >
< p > Kern-Sprache</ p >
</ div >
< div class = "tech-item" >
< span class = "tech-icon" > ▣ </ span >
< h4 > PySide6</ h4 >
< p > Qt-GUI-Framework</ p >
</ div >
< div class = "tech-item" >
< span class = "tech-icon" > ♦ </ span >
< h4 > Saxon</ h4 >
< p > XSLT-Prozessor</ p >
</ div >
< div class = "tech-item" >
< span class = "tech-icon" > ▮ </ span >
< h4 > Apache FOP</ h4 >
< p > PDF-Erzeugung</ p >
</ div >
< div class = "tech-item" >
< span class = "tech-icon" > ▬ </ span >
< h4 > diff-pdf</ h4 >
< p > PDF-Vergleich</ p >
</ div >
< div class = "tech-item" >
< span class = "tech-icon" > ⎓ </ span >
< h4 > PostgreSQL</ h4 >
< p > Datenbank</ p >
</ div >
< div class = "tech-item" >
< span class = "tech-icon" > ☷ </ span >
< h4 > Polars</ h4 >
< p > DataFrames</ p >
</ div >
< div class = "tech-item" >
< span class = "tech-icon" > ⚙ </ span >
< h4 > Pydantic</ h4 >
< p > Konfiguration</ p >
</ div >
</ div >
</ div >
</ section >
<!-- DOWNLOAD -->
< section class = "download" id = "download" >
< div class = "section-inner" >
< div class = "section-header reveal" >
< span class = "section-number" > 05 // Loslegen</ span >
< h2 class = "section-title" > Jetzt < span style = "color:var(--neon-red);" > installieren</ span ></ h2 >
< div class = "section-divider" ></ div >
</ div >
< div class = "download-content reveal" >
< div class = "download-info" >
< h3 > Voraussetzungen</ h3 >
< p > DocuMentor läuft auf Linux, Windows und macOS. Die Konfiguration wird plattformspezifisch gespeichert.</ p >
< ul >
< li >< span class = "check" > [x]</ span > Python 3.13+</ li >
< li >< span class = "check" > [x]</ span > Java VM (für Saxon)</ li >
< li >< span class = "check" > [x]</ span > Saxon HE/PE/EE JAR</ li >
< li >< span class = "check" > [x]</ span > Apache FOP</ li >
< li >< span class = "check" > [x]</ span > diff-pdf</ li >
< li >< span class = "check" > [x]</ span > PostgreSQL (optional)</ li >
</ ul >
< a href = "#" class = "btn-brutal" > Dokumentation</ a >
</ div >
< div class = "download-code" >
< div class = "code-block" >
< div class = "code-block-header" > Terminal</ div >
< pre >< span class = "comment" > # Repository klonen</ span >
< span class = "cmd" > $</ span > git clone https://github.com/user/xsl-validator.git
< span class = "cmd" > $</ span > cd xsl-validator
< span class = "comment" > # Abhängigkeiten installieren</ span >
< span class = "cmd" > $</ span > uv sync
< span class = "comment" > # Anwendung starten</ span >
< span class = "cmd" > $</ span > uv run python src/main.py</ pre >
</ div >
< div class = "code-block" >
< div class = "code-block-header" > Linting</ div >
< pre >< span class = "cmd" > $</ span > uv run ruff check
< span class = "cmd" > $</ span > uv run ruff format</ pre >
</ div >
</ div >
</ div >
</ div >
</ section >
<!-- FOOTER -->
< footer >
< div class = "footer-inner" >
< div class = "footer-col" >
< h4 > DocuMentor</ h4 >
< p > Desktop-Anwendung zur Verwaltung und Validierung von XSL-Transformationen. Entwickelt für die kontinuierliche Weiterentwicklung von PDF-Dokumenten in Flexnow.</ p >
</ div >
< div class = "footer-col" >
< h4 > Links</ h4 >
< ul >
< li >< a href = "#features" > Features</ a ></ li >
< li >< a href = "#workflow" > Workflow</ a ></ li >
< li >< a href = "#demo" > Oberfläche</ a ></ li >
< li >< a href = "#tech" > Tech-Stack</ a ></ li >
< li >< a href = "#download" > Download</ a ></ li >
</ ul >
</ div >
< div class = "footer-col" >
< h4 > Tech</ h4 >
< ul >
< li > PySide6 / Qt</ li >
< li > Saxon XSLT</ li >
< li > Apache FOP</ li >
< li > diff-pdf</ li >
< li > PostgreSQL / Polars</ li >
</ ul >
</ div >
</ div >
< div class = "footer-bottom" >
< span > © 2026 DocuMentor</ span >
< span > Gebaut mit roher Kraft.</ span >
</ div >
</ footer >
< script >
// Brutalist scroll reveal — abrupt, no easing
document . addEventListener ( 'DOMContentLoaded' , () => {
const reveals = document . querySelectorAll ( '.reveal' );
const observer = new IntersectionObserver (( entries ) => {
entries . forEach ( entry => {
if ( entry . isIntersecting ) {
entry . target . classList . add ( 'visible' );
observer . unobserve ( entry . target );
}
});
}, {
threshold : 0.15
});
reveals . forEach ( el => observer . observe ( el ));
});
// Nav active state
document . addEventListener ( 'scroll' , () => {
const sections = document . querySelectorAll ( 'section[id]' );
const links = document . querySelectorAll ( '.nav-links a' );
let current = '' ;
sections . forEach ( section => {
const top = section . offsetTop - 80 ;
if ( window . scrollY >= top ) {
current = section . getAttribute ( 'id' );
}
});
links . forEach ( link => {
link . style . background = '' ;
link . style . color = '' ;
if ( link . getAttribute ( 'href' ) === '#' + current ) {
link . style . background = 'var(--neon-red)' ;
link . style . color = 'var(--white)' ;
}
});
});
</ script >
</ body >
</ html >