Initial commit: ToolCTRL Landing Page

Statische Landing Page mit Lead-Formular, Impressum und
Datenschutzerklärung, ausgeliefert von einem abhängigkeitsfreien
Node-Server mit lokaler Lead-Erfassung.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
ToolCTRLandClaude Opus 4.7 committed 2026-05-22 16:43:28 +02:00
commit 143748dc0d
33 files changed
+2180

No files matched your search

+9
View File
@@ -0,0 +1,9 @@
# Lead-Daten — enthalten personenbezogene Daten, gehören nicht ins Repo
leads/
# OS / Editor
.DS_Store
# Node
node_modules/
*.log
+44
View File
@@ -0,0 +1,44 @@
# ToolCTRL — Landing Page
Eine-Seiten-Website im Visitenkarten-Stil für den Messeauftritt: Landing Page
plus Lead-Formular zur Kontaktsammlung. Monochrom (weiß / schwarz), an die
ToolCTRL Brand Identity angelehnt, ohne externe Abhängigkeiten.
## Starten
```bash
node server.js
```
Der Server sucht automatisch einen freien Port (zuerst `4317`) und gibt die
URL aus, z. B. `http://127.0.0.1:4317`. Stoppen mit `Strg + C`.
Voraussetzung: Node.js (getestet mit v26). Keine Installation, keine `npm`-Pakete.
## Aufbau
```
public/ statische Website (HTML, CSS, JS, Assets)
index.html Landing Page + Kontaktformular
styles.css Designsystem
script.js Formular-Logik & Mobile-Navigation
assets/ Logos, Emblem, Favicon, Icon-Set
server.js abhängigkeitsfreier Node-HTTP-Server + Lead-Endpunkt
leads/ gesammelte Anfragen (wird automatisch angelegt)
leads.csv Anfragen als CSV — direkt in Excel öffenbar
leads.ndjson dieselben Anfragen als JSON pro Zeile
```
## Leads
Jede abgesendete Anfrage landet sofort lokal auf der Platte — in `leads.csv`
**und** `leads.ndjson`. So geht auf der Messe keine Anfrage verloren, auch
ohne Internet. Ein Honeypot-Feld fängt einfache Spam-Bots ab.
Endpunkt: `POST /api/lead` (JSON). Pflichtfelder: `name`, `email`, `nachricht`.
## Hinweis für die Messe
Für den QR-Code am Stand sollte der Rechner mit dem Server im selben WLAN
erreichbar sein. Soll die Seite öffentlich laufen, hinter einen Reverse-Proxy
mit HTTPS setzen oder bei einem Hoster bereitstellen — `tool-ctrl.de`.
Binary file not shown.

After

Width:  |  Height:  |  Size: 262 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 292 KiB

+55
View File
@@ -0,0 +1,55 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg id="Layer_1" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 713.32 678.61">
<defs>
<style>
.cls-1 {
fill: url(#linear-gradient-5);
}
.cls-2 {
fill: url(#linear-gradient-6);
}
.cls-3 {
fill: url(#linear-gradient-4);
}
.cls-4 {
fill: url(#linear-gradient-3);
}
.cls-5 {
fill: url(#linear-gradient-2);
}
.cls-6 {
fill: url(#linear-gradient);
}
</style>
<linearGradient id="linear-gradient" x1="658.96" y1="31.96" x2="297.7" y2="458.6" gradientUnits="userSpaceOnUse">
<stop offset="0" stop-color="#000"/>
<stop offset="1" stop-color="#333"/>
</linearGradient>
<linearGradient id="linear-gradient-2" x1="1684.3" y1="1142.75" x2="2206.09" y2="1553.51" gradientTransform="translate(-1833.74 -1108.96) rotate(5.06) skewX(14.25)" gradientUnits="userSpaceOnUse">
<stop offset="0" stop-color="#b2b2b2"/>
<stop offset=".78" stop-color="#fff"/>
</linearGradient>
<linearGradient id="linear-gradient-3" x1="1719.13" y1="1098.51" x2="2240.91" y2="1509.28" xlink:href="#linear-gradient-2"/>
<linearGradient id="linear-gradient-4" x1="1764.82" y1="1040.47" x2="2286.6" y2="1451.24" xlink:href="#linear-gradient-2"/>
<linearGradient id="linear-gradient-5" x1="1806.27" y1="987.82" x2="2328.05" y2="1398.59" xlink:href="#linear-gradient-2"/>
<linearGradient id="linear-gradient-6" x1="345.03" y1="-10.15" x2="1014.55" y2="516.91" gradientTransform="matrix(1,0,0,1,0,0)" xlink:href="#linear-gradient-2"/>
</defs>
<g>
<path d="M688.7,572.09l-160,98.95c-9.14,5.73-19.99,8.35-30.77,7.37l-380.68-34.36c-22.48-2.01-40.76-19.01-44.35-41.31L.64,159.31c-3.17-19.56,5.6-39.12,22.3-49.72L189.46,8.08c-13.95,9.75,23.77,31.55,26.88,49.95l91.3,361.13c6.21,36.68,36.37,64.58,73.42,67.93l278.64,42.9c8.65.79,21.87,45.68,28.94,42.03l.06.06Z"/>
<path class="cls-6" d="M688.64,572.03c-7.07,3.66-15.23,5.36-23.88,4.57l-349-31.5c-37.04-3.35-67.21-31.26-73.42-67.93L170.39,53.35c-3.11-18.4,5.12-35.52,19.07-45.27l1.95-1.16c7.98-5.06,17.61-7.62,27.91-6.76l358.56,30.34c29.49,2.5,53.56,24.62,58.61,53.8l76.16,440.39c3.53,20.29-7.19,38.99-24.01,47.34Z"/>
</g>
<g>
<g>
<path class="cls-5" d="M300.22,343.93l-15.01,4.26,15.73,96.05c4.23,25.83,21.88,42.59,47.21,44.83l20.42,1.81-2.48-15.14-20.42-1.81c-15.81-1.4-26.04-11.44-28.79-28.28l-8.24-50.34,44.93,3.97-2.45-14.94-44.93-3.97-5.97-36.43Z"/>
<path class="cls-4" d="M421.96,387.97c-31.88-2.82-51.26,18.1-46.08,49.73,5.18,31.64,32.08,56.65,63.97,59.47,31.88,2.82,51.26-18.1,46.08-49.73-5.18-31.64-32.08-56.65-63.97-59.47ZM437.36,482.03c-22.9-2.03-41.54-19.67-45.35-42.9-3.8-23.23,9.53-38.04,32.43-36.02,22.9,2.03,41.54,19.66,45.35,42.9,3.8,23.23-9.53,38.04-32.42,36.02Z"/>
<path class="cls-3" d="M541.37,398.53c-31.88-2.82-51.26,18.1-46.08,49.73,5.18,31.64,32.08,56.65,63.97,59.47,31.88,2.82,51.26-18.1,46.08-49.73-5.18-31.64-32.08-56.65-63.97-59.47ZM556.77,492.59c-22.9-2.03-41.54-19.67-45.35-42.9-3.8-23.23,9.53-38.04,32.43-36.02,22.9,2.03,41.54,19.66,45.35,42.9,3.8,23.23-9.53,38.04-32.42,36.02Z"/>
<polygon class="cls-1" points="607.67 368.41 631.1 511.46 647.04 512.87 622.68 364.15 607.67 368.41"/>
</g>
<path class="cls-2" d="M582.39,164.07l18.3,1.62-56.29-75.12c-3.15-4.2-7.93-6.86-13.16-7.33h0c-7.61-.67-14.86,3.41-18.22,10.27l-30.3,61.75,19.2,1.7,27.57-56.2c.99-2.01,3.75-2.27,5.1-.48l47.81,63.79Z"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 3.5 KiB

+59
View File
@@ -0,0 +1,59 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg id="Layer_1" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 713.32 678.61">
<defs>
<style>
.cls-1 {
fill: url(#linear-gradient-5);
}
.cls-2 {
fill: url(#linear-gradient-6);
}
.cls-3 {
fill: url(#linear-gradient-4);
}
.cls-4 {
fill: url(#linear-gradient-3);
}
.cls-5 {
fill: url(#linear-gradient-2);
}
.cls-6 {
fill: url(#linear-gradient);
}
.cls-7 {
fill: #ededed;
}
</style>
<linearGradient id="linear-gradient" x1="658.96" y1="31.96" x2="297.7" y2="458.6" gradientUnits="userSpaceOnUse">
<stop offset="0" stop-color="#b2b2b2"/>
<stop offset=".78" stop-color="#fff"/>
</linearGradient>
<linearGradient id="linear-gradient-2" x1="1779.23" y1="571.47" x2="2301.02" y2="982.24" gradientTransform="translate(-1833.74 -537.68) rotate(5.06) skewX(14.25)" gradientUnits="userSpaceOnUse">
<stop offset="0" stop-color="#000"/>
<stop offset="1" stop-color="#333"/>
</linearGradient>
<linearGradient id="linear-gradient-3" x1="1814.06" y1="527.24" x2="2335.84" y2="938" xlink:href="#linear-gradient-2"/>
<linearGradient id="linear-gradient-4" x1="1859.75" y1="469.2" x2="2381.53" y2="879.96" xlink:href="#linear-gradient-2"/>
<linearGradient id="linear-gradient-5" x1="1901.2" y1="416.55" x2="2422.98" y2="827.31" xlink:href="#linear-gradient-2"/>
<linearGradient id="linear-gradient-6" x1="345.03" y1="-10.15" x2="1014.55" y2="516.91" gradientTransform="matrix(1,0,0,1,0,0)" xlink:href="#linear-gradient-2"/>
</defs>
<g>
<path class="cls-7" d="M688.7,572.09l-160,98.95c-9.14,5.73-19.99,8.35-30.77,7.37l-380.68-34.36c-22.48-2.01-40.76-19.01-44.35-41.31L.64,159.31c-3.17-19.56,5.6-39.12,22.3-49.72L189.46,8.08c-13.95,9.75,23.77,31.55,26.88,49.95l91.3,361.13c6.21,36.68,36.37,64.58,73.42,67.93l278.64,42.9c8.65.79,21.87,45.68,28.94,42.03l.06.06Z"/>
<path class="cls-6" d="M688.64,572.03c-7.07,3.66-15.23,5.36-23.88,4.57l-349-31.5c-37.04-3.35-67.21-31.26-73.42-67.93L170.39,53.35c-3.11-18.4,5.12-35.52,19.07-45.27l1.95-1.16c7.98-5.06,17.61-7.62,27.91-6.76l358.56,30.34c29.49,2.5,53.56,24.62,58.61,53.8l76.16,440.39c3.53,20.29-7.19,38.99-24.01,47.34Z"/>
</g>
<g>
<g>
<path class="cls-5" d="M300.22,343.93l-15.01,4.26,15.73,96.05c4.23,25.83,21.88,42.59,47.21,44.83l20.42,1.81-2.48-15.14-20.42-1.81c-15.81-1.4-26.04-11.44-28.79-28.28l-8.24-50.34,44.93,3.97-2.45-14.94-44.93-3.97-5.97-36.43Z"/>
<path class="cls-4" d="M421.96,387.97c-31.88-2.82-51.26,18.1-46.08,49.73,5.18,31.64,32.08,56.65,63.97,59.47,31.88,2.82,51.26-18.1,46.08-49.73-5.18-31.64-32.08-56.65-63.97-59.47ZM437.36,482.03c-22.9-2.03-41.54-19.67-45.35-42.9-3.8-23.23,9.53-38.04,32.43-36.02,22.9,2.03,41.54,19.66,45.35,42.9,3.8,23.23-9.53,38.04-32.42,36.02Z"/>
<path class="cls-3" d="M541.37,398.53c-31.88-2.82-51.26,18.1-46.08,49.73,5.18,31.64,32.08,56.65,63.97,59.47,31.88,2.82,51.26-18.1,46.08-49.73-5.18-31.64-32.08-56.65-63.97-59.47ZM556.77,492.59c-22.9-2.03-41.54-19.67-45.35-42.9-3.8-23.23,9.53-38.04,32.43-36.02,22.9,2.03,41.54,19.66,45.35,42.9,3.8,23.23-9.53,38.04-32.42,36.02Z"/>
<polygon class="cls-1" points="607.67 368.41 631.1 511.46 647.04 512.87 622.68 364.15 607.67 368.41"/>
</g>
<path class="cls-2" d="M582.39,164.07l18.3,1.62-56.29-75.12c-3.15-4.2-7.93-6.86-13.16-7.33h0c-7.61-.67-14.86,3.41-18.22,10.27l-30.3,61.75,19.2,1.7,27.57-56.2c.99-2.01,3.75-2.27,5.1-.48l47.81,63.79Z"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 3.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.
+3
View File
@@ -0,0 +1,3 @@
<svg width="95" height="95" viewBox="0 0 95 95" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M78.9246 27.6238C78.9246 21.0854 73.6242 15.7851 67.0859 15.7851H27.6235C21.0852 15.7851 15.7848 21.0854 15.7848 27.6238V67.0861C15.7848 73.6245 21.0852 78.9248 27.6235 78.9248H67.0859C73.6242 78.9248 78.9246 73.6245 78.9246 67.0861V27.6238ZM27.6235 63.1399V43.4087C27.6235 41.2293 29.3903 39.4625 31.5698 39.4625C33.7492 39.4625 35.516 41.2293 35.516 43.4087V63.1399C35.516 65.3193 33.7492 67.0861 31.5698 67.0861C29.3903 67.0861 27.6235 65.3193 27.6235 63.1399ZM43.4085 63.1399V31.57C43.4085 29.3906 45.1752 27.6238 47.3547 27.6238C49.5341 27.6238 51.3009 29.3906 51.3009 31.57V63.1399C51.3009 65.3193 49.5341 67.0861 47.3547 67.0861C45.1752 67.0861 43.4085 65.3193 43.4085 63.1399ZM59.1934 63.1399V43.4087C59.1934 41.2293 60.9602 39.4625 63.1396 39.4625C65.3191 39.4625 67.0859 41.2293 67.0859 43.4087V63.1399C67.0859 65.3193 65.3191 67.0861 63.1396 67.0861C60.9602 67.0861 59.1934 65.3193 59.1934 63.1399ZM86.8171 67.0861C86.8171 77.9834 77.9831 86.8173 67.0859 86.8173H27.6235C16.7263 86.8173 7.89233 77.9834 7.89233 67.0861V27.6238C7.89233 16.7265 16.7263 7.89258 27.6235 7.89258H67.0859C77.9831 7.89258 86.8171 16.7265 86.8171 27.6238V67.0861Z" fill="black"/>
</svg>

After

Width:  |  Height:  |  Size: 1.2 KiB

+6
View File
@@ -0,0 +1,6 @@
<svg width="95" height="95" viewBox="0 0 95 95" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M19.7313 7.89258C13.1929 7.89258 7.89258 13.1929 7.89258 19.7313V31.57C7.89258 38.1083 13.1929 43.4087 19.7313 43.4087H31.57C38.1083 43.4087 43.4087 38.1083 43.4087 31.57V19.7313C43.4087 13.1929 38.1083 7.89258 31.57 7.89258H19.7313ZM15.7851 19.7313C15.7851 17.5518 17.5518 15.7851 19.7313 15.7851H31.57C33.7494 15.7851 35.5162 17.5518 35.5162 19.7313V31.57C35.5162 33.7494 33.7494 35.5162 31.57 35.5162H19.7313C17.5518 35.5162 15.7851 33.7494 15.7851 31.57V19.7313Z" fill="black"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M63.1399 7.89258C56.6016 7.89258 51.3012 13.1929 51.3012 19.7313V31.57C51.3012 38.1083 56.6015 43.4087 63.1399 43.4087H74.9786C81.5169 43.4087 86.8173 38.1083 86.8173 31.57V19.7313C86.8173 13.1929 81.5169 7.89258 74.9786 7.89258H63.1399ZM59.1937 19.7313C59.1937 17.5518 60.9604 15.7851 63.1399 15.7851H74.9786C77.158 15.7851 78.9248 17.5518 78.9248 19.7313V31.57C78.9248 33.7494 77.158 35.5162 74.9786 35.5162H63.1399C60.9604 35.5162 59.1937 33.7494 59.1937 31.57V19.7313Z" fill="black"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M7.89258 63.1399C7.89258 56.6015 13.1929 51.3012 19.7313 51.3012H31.57C38.1083 51.3012 43.4087 56.6016 43.4087 63.1399V74.9786C43.4087 81.5169 38.1083 86.8173 31.57 86.8173H19.7313C13.1929 86.8173 7.89258 81.5169 7.89258 74.9786V63.1399ZM19.7313 59.1937C17.5518 59.1937 15.7851 60.9604 15.7851 63.1399V74.9786C15.7851 77.158 17.5518 78.9248 19.7313 78.9248H31.57C33.7494 78.9248 35.5162 77.158 35.5162 74.9786V63.1399C35.5162 60.9604 33.7494 59.1937 31.57 59.1937H19.7313Z" fill="black"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M63.1399 51.3012C56.6016 51.3012 51.3012 56.6015 51.3012 63.1399V74.9786C51.3012 81.5169 56.6015 86.8173 63.1399 86.8173H74.9786C81.5169 86.8173 86.8173 81.5169 86.8173 74.9786V63.1399C86.8173 56.6016 81.5169 51.3012 74.9786 51.3012H63.1399ZM59.1937 63.1399C59.1937 60.9604 60.9604 59.1937 63.1399 59.1937H74.9786C77.158 59.1937 78.9248 60.9604 78.9248 63.1399V74.9786C78.9248 77.158 77.158 78.9248 74.9786 78.9248H63.1399C60.9604 78.9248 59.1937 77.158 59.1937 74.9786V63.1399Z" fill="black"/>
</svg>

After

Width:  |  Height:  |  Size: 2.2 KiB

+6
View File
@@ -0,0 +1,6 @@
<svg width="95" height="95" viewBox="0 0 95 95" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M43.4088 11.8903C43.4019 9.71082 45.1632 7.9385 47.3426 7.93166C49.5221 7.92482 51.2944 9.68606 51.3012 11.8655L43.4088 11.8903Z" fill="black"/>
<path d="M56.4934 40.6289L51.4075 45.7469L51.3012 11.8655L43.4088 11.8903L43.5151 45.7716L38.3971 40.6857C36.8512 39.1494 34.3525 39.1572 32.8162 40.7031C31.28 42.249 31.2878 44.7476 32.8337 46.2839L32.8437 46.2938L32.8476 46.2976L47.5087 60.8671L62.0375 46.2468L62.0595 46.2247L62.0626 46.2215L62.0656 46.2185L62.0889 46.1951L62.0917 46.1922L56.4934 40.6289Z" fill="black"/>
<path d="M62.0917 46.1922C63.628 44.6463 63.6202 42.1476 62.0743 40.6113C60.5284 39.0751 58.0297 39.083 56.4934 40.6289L62.0917 46.1922Z" fill="black"/>
<path d="M15.7851 47.3569C15.7851 42.998 19.3186 39.4644 23.6775 39.4644C25.857 39.4644 27.6238 37.6976 27.6238 35.5182C27.6238 33.3387 25.857 31.5719 23.6775 31.5719C14.9597 31.5719 7.89258 38.6391 7.89258 47.3569V71.0343C7.89258 79.7521 14.9597 86.8192 23.6775 86.8192H67.0861C77.9834 86.8192 86.8173 77.9853 86.8173 67.0881V47.3569C86.8173 38.6391 79.7501 31.5719 71.0324 31.5719C68.8529 31.5719 67.0861 33.3387 67.0861 35.5182C67.0861 37.6976 68.8529 39.4644 71.0324 39.4644C75.3913 39.4644 78.9248 42.998 78.9248 47.3569V67.0881C78.9248 73.6264 73.6245 78.9268 67.0861 78.9268H23.6775C19.3186 78.9268 15.7851 75.3932 15.7851 71.0343V47.3569Z" fill="black"/>
</svg>

After

Width:  |  Height:  |  Size: 1.4 KiB

+4
View File
@@ -0,0 +1,4 @@
<svg width="95" height="95" viewBox="0 0 95 95" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M30.089 32.4338C28.3871 31.0723 25.9038 31.3483 24.5423 33.0501C23.1808 34.752 23.4567 37.2353 25.1586 38.5968L42.4246 52.4096C45.307 54.7156 49.4029 54.7156 52.2853 52.4096L69.5513 38.5968C71.2532 37.2353 71.5291 34.752 70.1676 33.0501C68.8061 31.3483 66.3228 31.0723 64.6209 32.4338L47.3549 46.2466L30.089 32.4338Z" fill="black"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M27.6238 11.8379C16.7265 11.8379 7.89258 20.6718 7.89258 31.5691V63.139C7.89258 74.0362 16.7265 82.8701 27.6238 82.8701H67.0861C77.9834 82.8701 86.8173 74.0362 86.8173 63.139V31.5691C86.8173 20.6718 77.9834 11.8379 67.0861 11.8379H27.6238ZM15.7851 31.5691C15.7851 25.0307 21.0854 19.7304 27.6238 19.7304H67.0861C73.6245 19.7304 78.9248 25.0307 78.9248 31.5691V63.139C78.9248 69.6773 73.6245 74.9777 67.0861 74.9777H27.6238C21.0854 74.9777 15.7851 69.6773 15.7851 63.139V31.5691Z" fill="black"/>
</svg>

After

Width:  |  Height:  |  Size: 989 B

+4
View File
@@ -0,0 +1,4 @@
<svg width="95" height="95" viewBox="0 0 95 95" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M70.3696 37.7052C71.5785 35.8918 71.0885 33.4417 69.2751 32.2328C67.4617 31.0238 65.0116 31.5138 63.8027 33.3273L52.8501 49.756L39.6712 40.8602C37.1776 39.1771 33.7775 39.991 32.3165 42.6209L24.1741 57.2772C23.1157 59.1824 23.8021 61.5848 25.7073 62.6433C27.6125 63.7017 30.015 63.0153 31.0734 61.1101L37.7526 49.0875L50.7373 57.8521C53.0952 59.4437 56.2979 58.8127 57.8759 56.4457L70.3696 37.7052Z" fill="black"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M27.6238 7.89258C16.7265 7.89258 7.89258 16.7265 7.89258 27.6238V67.0861C7.89258 77.9834 16.7265 86.8173 27.6238 86.8173H67.0861C77.9834 86.8173 86.8173 77.9834 86.8173 67.0861V27.6238C86.8173 16.7265 77.9834 7.89258 67.0861 7.89258H27.6238ZM15.7851 27.6238C15.7851 21.0854 21.0854 15.7851 27.6238 15.7851H67.0861C73.6245 15.7851 78.9248 21.0854 78.9248 27.6238V67.0861C78.9248 73.6245 73.6245 78.9248 67.0861 78.9248H27.6238C21.0854 78.9248 15.7851 73.6245 15.7851 67.0861V27.6238Z" fill="black"/>
</svg>

After

Width:  |  Height:  |  Size: 1.0 KiB

+4
View File
@@ -0,0 +1,4 @@
<svg width="95" height="95" viewBox="0 0 95 95" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M51.3013 55.2474C51.3013 53.068 49.5345 51.3012 47.355 51.3012C45.1756 51.3012 43.4088 53.068 43.4088 55.2474V63.1399C43.4088 65.3193 45.1756 67.0861 47.355 67.0861C49.5345 67.0861 51.3013 65.3193 51.3013 63.1399V55.2474Z" fill="black"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M27.6239 32.045C20.9788 33.6701 15.7852 39.3038 15.7852 46.4443V68.3004C15.7852 78.8184 24.9225 86.8173 35.5163 86.8173H59.1938C69.7876 86.8173 78.9249 78.8184 78.9249 68.3004V46.4443C78.9249 39.3038 73.7313 33.6701 67.0862 32.045V27.6238C67.0862 16.7265 58.2523 7.89258 47.355 7.89258C36.4578 7.89258 27.6239 16.7265 27.6239 27.6238V32.045ZM59.1938 27.6238V31.57H35.5163V27.6238C35.5163 26.2401 35.7537 24.9118 36.19 23.6775C37.8152 19.0794 42.2004 15.7851 47.355 15.7851C52.5097 15.7851 56.8949 19.0794 58.5201 23.6775C58.9564 24.9118 59.1938 26.2401 59.1938 27.6238ZM23.6776 46.4443C23.6776 42.8798 26.9079 39.4625 31.5701 39.4625H63.14C67.8022 39.4625 71.0325 42.8798 71.0325 46.4443V68.3004C71.0325 73.8766 66.0355 78.9248 59.1938 78.9248H35.5163C28.6746 78.9248 23.6776 73.8766 23.6776 68.3004V46.4443Z" fill="black"/>
</svg>

After

Width:  |  Height:  |  Size: 1.2 KiB

+3
View File
@@ -0,0 +1,3 @@
<svg width="95" height="95" viewBox="0 0 95 95" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M36.8382 18.655V20.7314C26.2236 25.0841 18.8077 39.381 19.0768 51.7714L19.0767 58.6535C13.6429 65.6392 13.9626 76.0548 27.5193 76.0548H36.8382C36.8382 78.9092 37.9505 81.6467 39.9305 83.6651C41.9105 85.6834 44.596 86.8173 47.3961 86.8173C50.1962 86.8173 52.8817 85.6834 54.8617 83.6651C56.8417 81.6467 57.954 78.9092 57.954 76.0548H67.2985C80.8294 76.0548 81.0256 65.6174 75.5924 58.6317L75.7435 51.7812C76.0171 39.3761 68.5868 25.0663 57.954 20.7198V18.655C57.954 15.8007 56.8417 13.0632 54.8617 11.0448C52.8817 9.02648 50.1962 7.89258 47.3961 7.89258C44.596 7.89258 41.9105 9.02648 39.9305 11.0448C37.9505 13.0632 36.8382 15.8007 36.8382 18.655ZM50.9154 18.655C50.9154 18.7279 50.9132 18.8005 50.9089 18.8728C49.7628 18.7291 48.5951 18.655 47.4102 18.655C46.2157 18.655 45.0387 18.7303 43.8835 18.8764C43.8791 18.8029 43.8768 18.7291 43.8768 18.655C43.8768 17.7036 44.2476 16.7911 44.9076 16.1183C45.5676 15.4455 46.4627 15.0676 47.3961 15.0676C48.3295 15.0676 49.2246 15.4455 49.8846 16.1183C50.5446 16.7911 50.9154 17.7036 50.9154 18.655ZM43.8768 76.0548C43.8768 77.0063 44.2476 77.9188 44.9076 78.5916C45.5676 79.2644 46.4627 79.6423 47.3961 79.6423C48.3295 79.6423 49.2246 79.2644 49.8846 78.5916C50.5446 77.9188 50.9154 77.0063 50.9154 76.0548H43.8768ZM67.2985 68.8799C70.3052 68.8799 71.9273 65.2848 69.9705 62.9577C69.0197 61.827 68.5133 60.3887 68.5459 58.9117L68.7067 51.62C68.9753 39.4394 59.3623 25.83 47.4102 25.83C35.461 25.83 25.8492 39.4349 26.1137 51.6126L26.2722 58.9129C26.3043 60.3895 25.7978 61.8273 24.8473 62.9577C22.8905 65.2848 24.5126 68.8799 27.5193 68.8799H67.2985Z" fill="black"/>
</svg>

After

Width:  |  Height:  |  Size: 1.7 KiB

+4
View File
@@ -0,0 +1,4 @@
<svg width="95" height="95" viewBox="0 0 95 95" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M38.6017 11.6428C43.2978 6.48625 51.4132 6.48626 56.1093 11.6428L59.0111 14.8298C59.8022 15.6985 60.9397 16.1699 62.1134 16.1151L66.418 15.9147C73.3849 15.5891 79.1219 21.3261 78.7963 28.2929L78.5959 32.5975C78.541 33.7712 79.0124 34.9087 79.8811 35.6998L83.0681 38.6017C88.2247 43.2978 88.2247 51.4132 83.0681 56.1093L79.8811 59.0111C79.0124 59.8022 78.541 60.9397 78.5959 62.1134L78.7963 66.418C79.1219 73.3849 73.3849 79.1219 66.418 78.7963L62.1134 78.5959C60.9397 78.541 59.8022 79.0124 59.0111 79.8811L56.1093 83.0681C51.4132 88.2247 43.2978 88.2247 38.6017 83.0681L35.6998 79.8811C34.9087 79.0124 33.7712 78.541 32.5975 78.5959L28.2929 78.7963C21.3261 79.1219 15.5891 73.3849 15.9147 66.418L16.1151 62.1134C16.1699 60.9397 15.6985 59.8022 14.8298 59.0111L11.6428 56.1093C6.48625 51.4132 6.48626 43.2978 11.6428 38.6017L14.8298 35.6998C15.6985 34.9087 16.1699 33.7712 16.1151 32.5975L15.9147 28.2929C15.5891 21.326 21.3261 15.5891 28.2929 15.9147L32.5975 16.1151C33.7712 16.1699 34.9087 15.6985 35.6998 14.8298L38.6017 11.6428ZM50.2728 16.9571C48.7075 15.2389 46.0035 15.2389 44.4382 16.9571L41.5363 20.1442C39.1629 22.7502 35.7505 24.1644 32.2295 23.9998L27.9249 23.7975C25.6026 23.689 23.689 25.6026 23.7975 27.9249L23.9998 32.2295C24.1644 35.7505 22.7502 39.1629 20.1442 41.5363L16.9571 44.4382C15.2389 46.0035 15.2389 48.7075 16.9571 50.2728L20.1442 53.1746C22.7502 55.548 24.1644 58.9604 23.9998 62.4814L23.7975 66.7861C23.689 69.1083 25.6026 71.022 27.9249 70.9134L32.2295 70.7111C35.7505 70.5465 39.1629 71.9607 41.5363 74.5668L44.4382 77.7538C46.0035 79.4721 48.7075 79.4721 50.2728 77.7538L53.1746 74.5668C55.548 71.9607 58.9604 70.5465 62.4814 70.7111L66.7861 70.9134C69.1083 71.022 71.022 69.1083 70.9134 66.7861L70.7111 62.4814C70.5465 58.9604 71.9607 55.548 74.5668 53.1746L77.7538 50.2728C79.4721 48.7075 79.4721 46.0035 77.7538 44.4382L74.5668 41.5363C71.9607 39.1629 70.5465 35.7505 70.7111 32.2295L70.9134 27.9249C71.022 25.6026 69.1083 23.689 66.7861 23.7975L62.4814 23.9998C58.9604 24.1644 55.548 22.7502 53.1746 20.1442L50.2728 16.9571Z" fill="black"/>
<path d="M55.2477 47.3553C55.2477 42.9964 51.7142 39.4628 47.3553 39.4628C42.9964 39.4628 39.4628 42.9964 39.4628 47.3553C39.4628 51.7142 42.9964 55.2477 47.3553 55.2477C51.7142 55.2477 55.2477 51.7142 55.2477 47.3553ZM63.1402 47.3553C63.1402 56.073 56.073 63.1402 47.3553 63.1402C38.6375 63.1402 31.5703 56.073 31.5703 47.3553C31.5703 38.6375 38.6375 31.5703 47.3553 31.5703C56.073 31.5703 63.1402 38.6375 63.1402 47.3553Z" fill="black"/>
</svg>

After

Width:  |  Height:  |  Size: 2.6 KiB

+3
View File
@@ -0,0 +1,3 @@
<svg width="95" height="95" viewBox="0 0 95 95" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M65.4688 7.89746C72.9321 8.08631 78.9246 14.1953 78.9248 21.7041C78.9248 29.3322 72.7404 35.5166 65.1123 35.5166C61.5526 35.5165 58.3083 34.1688 55.8594 31.957L35.0664 45.8193C35.3597 46.9395 35.5166 48.115 35.5166 49.3271C35.5166 50.5396 35.3599 51.7155 35.0664 52.8359L53.6836 65.248C56.1685 61.5938 60.3601 59.1935 65.1123 59.1934L65.4688 59.1982C72.9321 59.3871 78.9246 65.496 78.9248 73.0049C78.9248 80.6329 72.7404 86.8174 65.1123 86.8174C57.6035 86.8172 51.4945 80.8247 51.3057 73.3613L51.3018 73.1455L30.957 59.582C28.508 61.7932 25.2632 63.1396 21.7041 63.1396C14.1953 63.1394 8.08631 57.147 7.89746 49.6836L7.89258 49.3271L7.89746 48.9707C8.08674 41.5077 14.1955 35.5158 21.7041 35.5156L22.0605 35.5205C25.4797 35.607 28.59 36.9363 30.957 39.0732L51.751 25.2109C51.4867 24.2012 51.3331 23.1465 51.3057 22.0605L51.3008 21.7041L51.3057 21.3477C51.4949 13.8847 57.6037 7.8928 65.1123 7.89258L65.4688 7.89746ZM65.1123 67.0859C61.8435 67.0862 59.1936 69.736 59.1934 73.0049C59.1934 76.1717 61.6802 78.7582 64.8076 78.917L65.1123 78.9248C68.2794 78.9248 70.866 76.4373 71.0244 73.3096L71.0322 73.0049C71.032 69.7359 68.3813 67.0859 65.1123 67.0859ZM21.7041 43.4082C18.4353 43.4084 15.7854 46.0583 15.7852 49.3271C15.7852 52.494 18.272 55.0805 21.3994 55.2393L21.7041 55.2471C24.8712 55.2471 27.4578 52.7596 27.6162 49.6318L27.624 49.3271C27.6238 46.0582 24.9731 43.4082 21.7041 43.4082ZM65.1123 15.7852C61.8435 15.7854 59.1936 18.4353 59.1934 21.7041C59.1934 24.8709 61.6802 27.4574 64.8076 27.6162L65.1123 27.624C68.2794 27.624 70.866 25.1366 71.0244 22.0088L71.0322 21.7041C71.032 18.4351 68.3813 15.7852 65.1123 15.7852Z" fill="black"/>
</svg>

After

Width:  |  Height:  |  Size: 1.7 KiB

+6
View File
@@ -0,0 +1,6 @@
<svg width="95" height="95" viewBox="0 0 95 95" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M27.6238 27.6238C25.4443 27.6238 23.6775 29.3906 23.6775 31.57C23.6775 33.7494 25.4443 35.5162 27.6238 35.5162H51.3012C53.4806 35.5162 55.2474 33.7494 55.2474 31.57C55.2474 29.3906 53.4806 27.6238 51.3012 27.6238H27.6238Z" fill="black"/>
<path d="M23.6775 47.3549C23.6775 45.1755 25.4443 43.4087 27.6238 43.4087H51.3012C53.4806 43.4087 55.2474 45.1755 55.2474 47.3549C55.2474 49.5344 53.4806 51.3012 51.3012 51.3012H27.6238C25.4443 51.3012 23.6775 49.5344 23.6775 47.3549Z" fill="black"/>
<path d="M27.6238 59.1937C25.4443 59.1937 23.6775 60.9604 23.6775 63.1399C23.6775 65.3193 25.4443 67.0861 27.6238 67.0861H51.3012C53.4806 67.0861 55.2474 65.3193 55.2474 63.1399C55.2474 60.9604 53.4806 59.1937 51.3012 59.1937H27.6238Z" fill="black"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M22.1977 11.8388H27.7567C30.4261 9.35801 34.1244 7.89258 37.9825 7.89258H72.5121C79.9628 7.89258 86.8172 13.3578 86.8172 21.0467V57.8782C86.8172 65.5672 79.9628 71.0324 72.5121 71.0324H70.7956C69.576 77.7292 63.7858 82.8711 56.7273 82.8711H22.1977C14.2388 82.8711 7.89258 76.334 7.89258 68.4015V26.3083C7.89258 18.3759 14.2388 11.8388 22.1977 11.8388ZM72.5121 63.1399H71.0324V26.3083C71.0324 22.1816 69.3148 18.4325 66.5462 15.7851H72.5121C76.5035 15.7851 78.9247 18.5649 78.9247 21.0467V57.8782C78.9247 60.3601 76.5035 63.1399 72.5121 63.1399ZM22.1977 19.7313C18.7144 19.7313 15.7851 22.6171 15.7851 26.3083V68.4015C15.7851 72.0928 18.7144 74.9786 22.1977 74.9786H56.7273C60.2105 74.9786 63.1399 72.0928 63.1399 68.4015V26.3083C63.1399 22.6171 60.2105 19.7313 56.7273 19.7313H22.1977Z" fill="black"/>
</svg>

After

Width:  |  Height:  |  Size: 1.7 KiB

+4
View File
@@ -0,0 +1,4 @@
<svg width="95" height="95" viewBox="0 0 95 95" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M43.4082 31.5712C43.4082 29.3918 45.175 27.625 47.3544 27.625C49.5339 27.625 51.3007 29.3918 51.3007 31.5712V45.7222L61.9833 56.4048L62.255 56.7034C63.5193 58.2534 63.4281 60.5402 61.9833 61.985C60.5384 63.4299 58.2517 63.5211 56.7017 62.2567L56.403 61.985L43.4082 48.9902V31.5712Z" fill="black"/>
<path d="M78.9248 47.3549C78.9248 29.9194 64.7905 15.7851 47.3549 15.7851C29.9194 15.7851 15.7851 29.9194 15.7851 47.3549C15.7851 64.7905 29.9194 78.9248 47.3549 78.9248C64.7905 78.9248 78.9248 64.7905 78.9248 47.3549ZM86.8173 47.3549C86.8173 69.1494 69.1494 86.8173 47.3549 86.8173C25.5605 86.8173 7.89258 69.1494 7.89258 47.3549C7.89258 25.5605 25.5605 7.89258 47.3549 7.89258C69.1494 7.89258 86.8173 25.5605 86.8173 47.3549Z" fill="black"/>
</svg>

After

Width:  |  Height:  |  Size: 854 B

+6
View File
@@ -0,0 +1,6 @@
<svg width="95" height="95" viewBox="0 0 95 95" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M51.4369 55.2698C51.4438 57.4492 49.6825 59.2215 47.5031 59.2284C45.3237 59.2352 43.5513 57.474 43.5445 55.2945L51.4369 55.2698Z" fill="black"/>
<path d="M38.3523 26.5311L43.4382 21.4131L43.5445 55.2945L51.4369 55.2698L51.3307 21.3884L56.4486 26.4743C57.9946 28.0106 60.4932 28.0028 62.0295 26.4569C63.5658 24.911 63.5579 22.4124 62.012 20.8761L47.3371 6.29297L32.754 20.9678L38.3523 26.5311Z" fill="black"/>
<path d="M32.754 20.9678C31.2177 22.5137 31.2255 25.0124 32.7714 26.5487C34.3173 28.085 36.816 28.077 38.3523 26.5311L32.754 20.9678Z" fill="black"/>
<path d="M15.7851 47.3529C15.7851 42.994 19.3186 39.4604 23.6775 39.4604C25.857 39.4604 27.6238 37.6936 27.6238 35.5142C27.6238 33.3347 25.857 31.5679 23.6775 31.5679C14.9597 31.5679 7.89258 38.6351 7.89258 47.3529V71.0303C7.89258 79.7481 14.9597 86.8152 23.6775 86.8152H67.0861C77.9834 86.8152 86.8173 77.9813 86.8173 67.084V47.3529C86.8173 38.6351 79.7501 31.5679 71.0324 31.5679C68.8529 31.5679 67.0861 33.3347 67.0861 35.5142C67.0861 37.6936 68.8529 39.4604 71.0324 39.4604C75.3913 39.4604 78.9248 42.994 78.9248 47.3529V67.084C78.9248 73.6224 73.6245 78.9228 67.0861 78.9228H23.6775C19.3186 78.9228 15.7851 75.3892 15.7851 71.0303V47.3529Z" fill="black"/>
</svg>

After

Width:  |  Height:  |  Size: 1.3 KiB

+4
View File
@@ -0,0 +1,4 @@
<svg width="95" height="95" viewBox="0 0 95 95" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M47.355 23.6775C38.6372 23.6775 31.5701 30.7447 31.5701 39.4625C31.5701 48.1803 38.6372 55.2474 47.355 55.2474C56.0728 55.2474 63.14 48.1803 63.14 39.4625C63.14 30.7447 56.0728 23.6775 47.355 23.6775ZM39.4625 39.4625C39.4625 35.1036 42.9961 31.57 47.355 31.57C51.7139 31.57 55.2475 35.1036 55.2475 39.4625C55.2475 43.8214 51.7139 47.3549 47.355 47.3549C42.9961 47.3549 39.4625 43.8214 39.4625 39.4625Z" fill="black"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M76.2734 74.2067C69.0673 81.9639 58.7779 86.8173 47.3549 86.8173C25.5605 86.8173 7.89258 69.1494 7.89258 47.3549C7.89258 25.5605 25.5605 7.89258 47.3549 7.89258C69.1494 7.89258 86.8173 25.5605 86.8173 47.3549C86.8173 57.4715 83.0105 66.6989 76.7513 73.6829C76.7836 73.8116 76.8152 73.9411 76.846 74.0714L76.2734 74.2067ZM15.7851 47.3549C15.7851 29.9194 29.9194 15.7851 47.3549 15.7851C64.7905 15.7851 78.9248 29.9194 78.9248 47.3549C78.9248 54.2655 76.7045 60.6574 72.9382 65.8562C72.9215 65.8364 72.9048 65.8167 72.888 65.797C70.9916 63.5712 68.6631 62.096 66.1143 61.1279C61.2483 59.2796 55.24 59.1937 49.3281 59.1937H45.3819C39.5245 59.1937 33.885 59.2638 29.4177 61.1946C26.5281 62.4436 24.3032 64.3622 22.6418 67.0017C18.3497 61.61 15.7851 54.782 15.7851 47.3549ZM28.5351 72.7044C33.7904 76.6124 40.3026 78.9248 47.3549 78.9248C54.9963 78.9248 62.0036 76.21 67.4649 71.6922C67.2757 71.4078 67.0802 71.1501 66.8804 70.9155C65.9819 69.861 64.8323 69.0836 63.3119 68.5061C60.0396 67.2632 55.5453 67.0861 49.3281 67.0861H45.3819C39.1103 67.0861 35.2337 67.279 32.5491 68.4393C30.9816 69.1169 29.6054 70.2304 28.5351 72.7044Z" fill="black"/>
</svg>

After

Width:  |  Height:  |  Size: 1.7 KiB

+4
View File
@@ -0,0 +1,4 @@
<svg width="95" height="95" viewBox="0 0 95 95" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M47.3549 35.5154C40.8166 35.5154 35.5162 40.8158 35.5162 47.3541C35.5162 53.8925 40.8166 59.1928 47.3549 59.1928C53.8933 59.1928 59.1937 53.8925 59.1937 47.3541C59.1937 40.8158 53.8933 35.5154 47.3549 35.5154ZM43.4087 47.3541C43.4087 45.1747 45.1755 43.4079 47.3549 43.4079C49.5344 43.4079 51.3012 45.1747 51.3012 47.3541C51.3012 49.5336 49.5344 51.3004 47.3549 51.3004C45.1755 51.3004 43.4087 49.5336 43.4087 47.3541Z" fill="black"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M86.1463 44.5157C77.1176 28.2222 62.3989 19.7305 47.3549 19.7305C32.311 19.7305 17.5923 28.2222 8.56356 44.5157C7.68093 46.1086 7.67007 48.0727 8.52513 49.6729C17.4102 66.3012 32.2125 74.9778 47.3549 74.9778C62.4974 74.9778 77.2996 66.3012 86.1848 49.6729C87.0398 48.0727 87.0289 46.1086 86.1463 44.5157ZM47.3549 67.0853C35.7568 67.0853 23.8374 60.6624 16.1471 47.1516C23.9483 33.9217 35.805 27.6229 47.3549 27.6229C58.9048 27.6229 70.7616 33.9217 78.5628 47.1516C70.8725 60.6624 58.9531 67.0853 47.3549 67.0853Z" fill="black"/>
</svg>

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 102 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 95 KiB

+67
View File
@@ -0,0 +1,67 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg id="Layer_1" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 880.71 224.61">
<defs>
<style>
.cls-1 {
fill: url(#linear-gradient-5);
}
.cls-2 {
fill: url(#linear-gradient-6);
}
.cls-3 {
fill: url(#linear-gradient-4);
}
.cls-4 {
fill: url(#linear-gradient-3);
}
.cls-5 {
fill: url(#linear-gradient-2);
}
.cls-6 {
fill: url(#linear-gradient);
}
</style>
<linearGradient id="linear-gradient" x1="862.72" y1="10.58" x2="743.14" y2="151.79" gradientUnits="userSpaceOnUse">
<stop offset="0" stop-color="#000"/>
<stop offset="1" stop-color="#333"/>
</linearGradient>
<linearGradient id="linear-gradient-2" x1="2323.63" y1="1011.62" x2="2496.34" y2="1147.58" gradientTransform="translate(-1833.74 -1165.98) rotate(5.06) skewX(14.25)" gradientUnits="userSpaceOnUse">
<stop offset="0" stop-color="#b2b2b2"/>
<stop offset=".78" stop-color="#fff"/>
</linearGradient>
<linearGradient id="linear-gradient-3" x1="2335.16" y1="996.98" x2="2507.87" y2="1132.94" xlink:href="#linear-gradient-2"/>
<linearGradient id="linear-gradient-4" x1="2350.28" y1="977.77" x2="2522.99" y2="1113.73" xlink:href="#linear-gradient-2"/>
<linearGradient id="linear-gradient-5" x1="2364" y1="960.34" x2="2536.71" y2="1096.3" xlink:href="#linear-gradient-2"/>
<linearGradient id="linear-gradient-6" x1="758.81" y1="-3.36" x2="980.41" y2="171.09" gradientTransform="matrix(1,0,0,1,0,0)" xlink:href="#linear-gradient-2"/>
</defs>
<g>
<g>
<path d="M872.56,189.36l-52.96,32.75c-3.02,1.9-6.62,2.76-10.18,2.44l-126-11.37c-7.44-.67-13.49-6.29-14.68-13.67l-23.92-146.77c-1.05-6.47,1.86-12.95,7.38-16.46l55.12-33.6c-4.62,3.23,7.87,10.44,8.9,16.53l30.22,119.53c2.06,12.14,12.04,21.38,24.3,22.49l92.23,14.2c2.86.26,7.24,15.12,9.58,13.91l.02.02Z"/>
<path class="cls-6" d="M872.54,189.34c-2.34,1.21-5.04,1.77-7.91,1.51l-115.51-10.43c-12.26-1.11-22.24-10.35-24.3-22.49l-23.82-140.28c-1.03-6.09,1.69-11.76,6.31-14.98l.64-.38c2.64-1.67,5.83-2.52,9.24-2.24l118.68,10.04c9.76.83,17.73,8.15,19.4,17.81l25.21,145.76c1.17,6.72-2.38,12.91-7.95,15.67Z"/>
</g>
<g>
<g>
<path class="cls-5" d="M743.98,113.84l-4.97,1.41,5.21,31.79c1.4,8.55,7.24,14.1,15.63,14.84l6.76.6-.82-5.01-6.76-.6c-5.23-.46-8.62-3.79-9.53-9.36l-2.73-16.66,14.87,1.32-.81-4.94-14.87-1.32-1.97-12.06Z"/>
<path class="cls-4" d="M784.27,128.41c-10.55-.93-16.97,5.99-15.25,16.46,1.71,10.47,10.62,18.75,21.17,19.68,10.55.93,16.97-5.99,15.25-16.46-1.71-10.47-10.62-18.75-21.17-19.68ZM789.37,159.55c-7.58-.67-13.75-6.51-15.01-14.2-1.26-7.69,3.15-12.59,10.73-11.92,7.58.67,13.75,6.51,15.01,14.2,1.26,7.69-3.15,12.59-10.73,11.92Z"/>
<path class="cls-3" d="M823.79,131.91c-10.55-.93-16.97,5.99-15.25,16.46,1.71,10.47,10.62,18.75,21.17,19.68,10.55.93,16.97-5.99,15.25-16.46-1.71-10.47-10.62-18.75-21.17-19.68ZM828.89,163.04c-7.58-.67-13.75-6.51-15.01-14.2-1.26-7.69,3.15-12.59,10.73-11.92,7.58.67,13.75,6.51,15.01,14.2,1.26,7.69-3.15,12.59-10.73,11.92Z"/>
<polygon class="cls-1" points="845.74 121.94 853.49 169.29 858.77 169.75 850.71 120.53 845.74 121.94"/>
</g>
<path class="cls-2" d="M837.37,54.31l6.06.54-18.63-24.87c-1.04-1.39-2.63-2.27-4.36-2.43h0c-2.52-.22-4.92,1.13-6.03,3.4l-10.03,20.44,6.36.56,9.13-18.6c.33-.67,1.24-.75,1.69-.16l15.82,21.11Z"/>
</g>
</g>
<g>
<path d="M40.05,168.37c-4.3,2.14-10,3.92-14.3,3.92-12.86,0-15.73-8.03-15.73-19.64v-51.8h29.48v-9.1H10.02v-26.42l-9.51,2.09c-.29.07-.51.34-.51.63v9.22h.07v49.8h-.07v25.6c0,18.4,6.61,28.95,25.19,28.95,6.08,0,12.33-1.8,18.22-4.65l-3.4-8.57.03-.02Z"/>
<path d="M94.52,89.96c-26.99,0-45.57,19.47-45.57,45.91s18.58,45.89,45.57,45.89,45.57-19.47,45.57-45.89-18.77-45.91-45.57-45.91ZM94.52,172.12c-20.91,0-35.38-15.72-35.38-36.25s14.47-36.27,35.38-36.27,35.38,15.72,35.38,36.27-14.66,36.25-35.38,36.25Z"/>
<path d="M197.39,89.96c-26.97,0-45.57,19.47-45.57,45.91s18.58,45.89,45.57,45.89,45.57-19.47,45.57-45.89-18.75-45.91-45.57-45.91ZM197.39,172.12c-20.91,0-35.38-15.72-35.38-36.25s14.47-36.27,35.38-36.27,35.4,15.72,35.4,36.27-14.66,36.25-35.4,36.25Z"/>
<path d="M259.33,57.7v122.28h10.19V54.95l-9.68,2.12c-.29.07-.49.34-.49.63h-.02Z"/>
<path d="M439.9,162.7c-8.85,0-13.3-5.4-13.3-15.03v-44.14h27.38v-18.3h-27.38l-.03-27.17-20.82,4.57c-.32.07-.54.36-.54.68v84.37c0,22.73,11.57,34.11,31.22,34.11,7.9,0,14.06-1.36,21.4-4.64l-5.98-17.35c-3.65,1.73-8.1,2.9-11.96,2.9h.02Z"/>
<path d="M516.47,82.49c-9.83,0-17.48,1.27-26.17,6.35-13.35,7.79-20.33,22.31-20.33,37.51v54.08h21.59v-46.44c0-18.69,9.83-30.07,25.25-30.07,5.79,0,10.6,1.55,16,5.21l9.63-17.54c-1.41-1.27-3.02-2.43-4.79-3.43-5.45-3.11-14.21-5.67-21.2-5.67h.02Z"/>
<path d="M552.06,50.13c-.32.07-.54.36-.54.68v129.6h21.59V45.51l-21.06,4.62h.02Z"/>
<path d="M303.47,132.12c0-29.44,20.4-49.65,50.63-49.65,13.86,0,25.8,4.8,35.99,14.62l-13.09,14.04c-5.78-5.77-14.05-9.05-22.52-9.05-17.32,0-29.45,12.31-29.45,30.02s11.94,30.02,29.45,30.02c9.24,0,17.71-3.46,23.49-9.81l13.28,14.43c-10.58,10.2-22.33,15.01-36.96,15.01-30.79,0-50.82-19.63-50.82-49.65v.02Z"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 5.2 KiB

+75
View File
@@ -0,0 +1,75 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg id="Layer_1" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 880.71 224.61">
<defs>
<style>
.cls-1 {
fill: url(#linear-gradient-5);
}
.cls-2 {
fill: url(#linear-gradient-6);
}
.cls-3 {
fill: url(#linear-gradient-4);
}
.cls-4 {
fill: url(#linear-gradient-3);
}
.cls-5 {
fill: url(#linear-gradient-2);
}
.cls-6 {
fill: url(#linear-gradient);
}
.cls-7 {
fill: #fff;
}
.cls-8 {
fill: #ededed;
}
</style>
<linearGradient id="linear-gradient" x1="862.72" y1="10.58" x2="743.14" y2="151.79" gradientUnits="userSpaceOnUse">
<stop offset="0" stop-color="#b2b2b2"/>
<stop offset=".78" stop-color="#fff"/>
</linearGradient>
<linearGradient id="linear-gradient-2" x1="2416.49" y1="452.81" x2="2589.2" y2="588.77" gradientTransform="translate(-1833.74 -607.17) rotate(5.06) skewX(14.25)" gradientUnits="userSpaceOnUse">
<stop offset="0" stop-color="#000"/>
<stop offset="1" stop-color="#333"/>
</linearGradient>
<linearGradient id="linear-gradient-3" x1="2428.02" y1="438.17" x2="2600.73" y2="574.13" xlink:href="#linear-gradient-2"/>
<linearGradient id="linear-gradient-4" x1="2443.14" y1="418.96" x2="2615.85" y2="554.92" xlink:href="#linear-gradient-2"/>
<linearGradient id="linear-gradient-5" x1="2456.86" y1="401.53" x2="2629.57" y2="537.49" xlink:href="#linear-gradient-2"/>
<linearGradient id="linear-gradient-6" x1="758.81" y1="-3.36" x2="980.41" y2="171.09" gradientTransform="matrix(1,0,0,1,0,0)" xlink:href="#linear-gradient-2"/>
</defs>
<g>
<g>
<path class="cls-8" d="M872.56,189.36l-52.96,32.75c-3.02,1.9-6.62,2.76-10.18,2.44l-126-11.37c-7.44-.67-13.49-6.29-14.68-13.67l-23.92-146.77c-1.05-6.47,1.86-12.95,7.38-16.46l55.12-33.6c-4.62,3.23,7.87,10.44,8.9,16.53l30.22,119.53c2.06,12.14,12.04,21.38,24.3,22.49l92.23,14.2c2.86.26,7.24,15.12,9.58,13.91l.02.02Z"/>
<path class="cls-6" d="M872.54,189.34c-2.34,1.21-5.04,1.77-7.91,1.51l-115.51-10.43c-12.26-1.11-22.24-10.35-24.3-22.49l-23.82-140.28c-1.03-6.09,1.69-11.76,6.31-14.98l.64-.38c2.64-1.67,5.83-2.52,9.24-2.24l118.68,10.04c9.76.83,17.73,8.15,19.4,17.81l25.21,145.76c1.17,6.72-2.38,12.91-7.95,15.67Z"/>
</g>
<g>
<g>
<path class="cls-5" d="M743.98,113.84l-4.97,1.41,5.21,31.79c1.4,8.55,7.24,14.1,15.63,14.84l6.76.6-.82-5.01-6.76-.6c-5.23-.46-8.62-3.79-9.53-9.36l-2.73-16.66,14.87,1.32-.81-4.94-14.87-1.32-1.97-12.06Z"/>
<path class="cls-4" d="M784.27,128.41c-10.55-.93-16.97,5.99-15.25,16.46,1.71,10.47,10.62,18.75,21.17,19.68,10.55.93,16.97-5.99,15.25-16.46-1.71-10.47-10.62-18.75-21.17-19.68ZM789.37,159.55c-7.58-.67-13.75-6.51-15.01-14.2-1.26-7.69,3.15-12.59,10.73-11.92,7.58.67,13.75,6.51,15.01,14.2,1.26,7.69-3.15,12.59-10.73,11.92Z"/>
<path class="cls-3" d="M823.79,131.91c-10.55-.93-16.97,5.99-15.25,16.46,1.71,10.47,10.62,18.75,21.17,19.68,10.55.93,16.97-5.99,15.25-16.46-1.71-10.47-10.62-18.75-21.17-19.68ZM828.89,163.04c-7.58-.67-13.75-6.51-15.01-14.2-1.26-7.69,3.15-12.59,10.73-11.92,7.58.67,13.75,6.51,15.01,14.2,1.26,7.69-3.15,12.59-10.73,11.92Z"/>
<polygon class="cls-1" points="845.74 121.94 853.49 169.29 858.77 169.75 850.71 120.53 845.74 121.94"/>
</g>
<path class="cls-2" d="M837.37,54.31l6.06.54-18.63-24.87c-1.04-1.39-2.63-2.27-4.36-2.43h0c-2.52-.22-4.92,1.13-6.03,3.4l-10.03,20.44,6.36.56,9.13-18.6c.33-.67,1.24-.75,1.69-.16l15.82,21.11Z"/>
</g>
</g>
<g>
<path class="cls-7" d="M40.05,168.37c-4.3,2.14-10,3.92-14.3,3.92-12.86,0-15.73-8.03-15.73-19.64v-51.8h29.48v-9.1H10.02v-26.42l-9.51,2.09c-.29.07-.51.34-.51.63v9.22h.07v49.8h-.07v25.6c0,18.4,6.61,28.95,25.19,28.95,6.08,0,12.33-1.8,18.22-4.65l-3.4-8.57.03-.02Z"/>
<path class="cls-7" d="M94.52,89.96c-26.99,0-45.57,19.47-45.57,45.91s18.58,45.89,45.57,45.89,45.57-19.47,45.57-45.89-18.77-45.91-45.57-45.91ZM94.52,172.12c-20.91,0-35.38-15.72-35.38-36.25s14.47-36.27,35.38-36.27,35.38,15.72,35.38,36.27-14.66,36.25-35.38,36.25Z"/>
<path class="cls-7" d="M197.39,89.96c-26.97,0-45.57,19.47-45.57,45.91s18.58,45.89,45.57,45.89,45.57-19.47,45.57-45.89-18.75-45.91-45.57-45.91ZM197.39,172.12c-20.91,0-35.38-15.72-35.38-36.25s14.47-36.27,35.38-36.27,35.4,15.72,35.4,36.27-14.66,36.25-35.4,36.25Z"/>
<path class="cls-7" d="M259.33,57.7v122.28h10.19V54.95l-9.68,2.12c-.29.07-.49.34-.49.63h-.02Z"/>
<path class="cls-7" d="M439.9,162.7c-8.85,0-13.3-5.4-13.3-15.03v-44.14h27.38v-18.3h-27.38l-.03-27.17-20.82,4.57c-.32.07-.54.36-.54.68v84.37c0,22.73,11.57,34.11,31.22,34.11,7.9,0,14.06-1.36,21.4-4.64l-5.98-17.35c-3.65,1.73-8.1,2.9-11.96,2.9h.02Z"/>
<path class="cls-7" d="M516.47,82.49c-9.83,0-17.48,1.27-26.17,6.35-13.35,7.79-20.33,22.31-20.33,37.51v54.08h21.59v-46.44c0-18.69,9.83-30.07,25.25-30.07,5.79,0,10.6,1.55,16,5.21l9.63-17.54c-1.41-1.27-3.02-2.43-4.79-3.43-5.45-3.11-14.21-5.67-21.2-5.67h.02Z"/>
<path class="cls-7" d="M552.06,50.13c-.32.07-.54.36-.54.68v129.6h21.59V45.51l-21.06,4.62h.02Z"/>
<path class="cls-7" d="M303.47,132.12c0-29.44,20.4-49.65,50.63-49.65,13.86,0,25.8,4.8,35.99,14.62l-13.09,14.04c-5.78-5.77-14.05-9.05-22.52-9.05-17.32,0-29.45,12.31-29.45,30.02s11.94,30.02,29.45,30.02c9.24,0,17.71-3.46,23.49-9.81l13.28,14.43c-10.58,10.2-22.33,15.01-36.96,15.01-30.79,0-50.82-19.63-50.82-49.65v.02Z"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 5.4 KiB

+163
View File
@@ -0,0 +1,163 @@
<!DOCTYPE html>
<html lang="de">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>Datenschutzerklärung — ToolCTRL</title>
<meta name="description" content="Datenschutzerklärung von ToolCTRL — Informationen zur Verarbeitung personenbezogener Daten auf dieser Website." />
<meta name="robots" content="noindex" />
<link rel="icon" type="image/png" href="/assets/favicon.png" />
<link rel="stylesheet" href="/styles.css" />
</head>
<body>
<header class="site-header">
<div class="wrap header-inner">
<a class="brand" href="/" aria-label="ToolCTRL Startseite">
<img src="/assets/logo-black.svg" alt="ToolCTRL" class="brand-logo" />
</a>
<a class="legal-back" href="/">Zurück zur Startseite</a>
</div>
</header>
<main class="legal-main">
<h1>Datenschutzerklärung</h1>
<p class="legal-intro">
Der Schutz Ihrer personenbezogenen Daten ist uns wichtig. Diese Erklärung
informiert Sie darüber, welche Daten beim Besuch dieser Website verarbeitet
werden und welche Rechte Ihnen zustehen.
</p>
<p class="legal-updated">Stand: Mai 2026</p>
<h2>1. Verantwortlicher</h2>
<p>
Verantwortlich für die Datenverarbeitung auf dieser Website ist:
</p>
<p>
R&amp;D² UG (haftungsbeschränkt)<br />
Orbinstraße 1<br />
76646 Bruchsal<br />
E-Mail: <a href="mailto:admin@tool-ctrl.de">admin@tool-ctrl.de</a>
</p>
<p>Die vollständigen Anbieterangaben finden Sie im <a href="/impressum.html">Impressum</a>.</p>
<h2>2. Hosting und Server-Logfiles</h2>
<p>
Diese Website wird bei einem externen Dienstleister gehostet:
<span class="legal-tbd">[ Hosting-Anbieter — vom Betreiber zu ergänzen ]</span>.
Beim Aufruf der Website verarbeitet dieser automatisch technische
Informationen, die Ihr Browser übermittelt (sogenannte Server-Logfiles):
</p>
<ul>
<li>IP-Adresse des anfragenden Geräts</li>
<li>Datum und Uhrzeit des Zugriffs</li>
<li>aufgerufene Seite beziehungsweise Datei</li>
<li>übertragene Datenmenge</li>
<li>verwendeter Browsertyp und Betriebssystem</li>
</ul>
<p>
Diese Daten dienen ausschließlich der technischen Auslieferung der Website,
der Systemsicherheit und der Fehleranalyse. Rechtsgrundlage ist unser
berechtigtes Interesse an einem sicheren und stabilen Betrieb
(Art. 6 Abs. 1 lit. f DSGVO). Eine Zusammenführung dieser Daten mit anderen
Datenquellen findet nicht statt.
</p>
<h2>3. Kontaktformular</h2>
<p>
Wenn Sie uns über das Kontaktformular eine Anfrage senden, verarbeiten wir
die von Ihnen eingegebenen Daten:
</p>
<ul>
<li>Name <strong>(Pflichtangabe)</strong></li>
<li>E-Mail-Adresse <strong>(Pflichtangabe)</strong></li>
<li>Ihre Nachricht <strong>(Pflichtangabe)</strong></li>
<li>Firma (freiwillig)</li>
<li>Telefonnummer (freiwillig)</li>
</ul>
<p>
Diese Daten verwenden wir ausschließlich, um Ihre Anfrage zu bearbeiten und
mit Ihnen Kontakt aufzunehmen. Rechtsgrundlage ist Art. 6 Abs. 1 lit. b
DSGVO (Durchführung vorvertraglicher Maßnahmen) sowie unser berechtigtes
Interesse an der Beantwortung Ihrer Anfrage (Art. 6 Abs. 1 lit. f DSGVO).
Soweit Sie mit dem Absenden ausdrücklich einwilligen, ist zusätzlich
Art. 6 Abs. 1 lit. a DSGVO Rechtsgrundlage. Eine erteilte Einwilligung
können Sie jederzeit mit Wirkung für die Zukunft widerrufen.
</p>
<p>
Die Angabe der Pflichtfelder ist erforderlich, um Ihre Anfrage bearbeiten
zu können; die übrigen Angaben sind freiwillig.
</p>
<h2>4. Speicherdauer</h2>
<p>
Wir speichern personenbezogene Daten nur so lange, wie es für die genannten
Zwecke erforderlich ist. Daten aus Kontaktanfragen löschen wir, sobald Ihre
Anfrage abschließend bearbeitet ist und keine gesetzlichen
Aufbewahrungspflichten entgegenstehen. Server-Logfiles werden nach kurzer
Zeit automatisch gelöscht.
</p>
<h2>5. Keine Cookies, kein Tracking</h2>
<p>
Diese Website verwendet <strong>keine Cookies</strong>, kein Tracking und
keine Analyse- oder Marketing-Dienste. Es werden keine Profile über Ihr
Verhalten erstellt. Verwendete Schriftarten werden lokal von unserem eigenen
Server geladen; eine Verbindung zu Servern Dritter (etwa Google Fonts)
besteht dabei nicht.
</p>
<h2>6. SSL-/TLS-Verschlüsselung</h2>
<p>
Diese Website nutzt aus Sicherheitsgründen eine Verschlüsselung (SSL/TLS).
Eine verschlüsselte Verbindung erkennen Sie am „https://" in der Adresszeile
Ihres Browsers.
</p>
<h2>7. Ihre Rechte</h2>
<p>
Hinsichtlich Ihrer personenbezogenen Daten stehen Ihnen folgende Rechte zu:
</p>
<ul>
<li>Auskunft über die zu Ihnen gespeicherten Daten (Art. 15 DSGVO)</li>
<li>Berichtigung unrichtiger Daten (Art. 16 DSGVO)</li>
<li>Löschung Ihrer Daten (Art. 17 DSGVO)</li>
<li>Einschränkung der Verarbeitung (Art. 18 DSGVO)</li>
<li>Datenübertragbarkeit (Art. 20 DSGVO)</li>
<li>Widerspruch gegen die Verarbeitung (Art. 21 DSGVO)</li>
<li>Widerruf einer erteilten Einwilligung (Art. 7 Abs. 3 DSGVO)</li>
</ul>
<p>
Zur Ausübung Ihrer Rechte genügt eine formlose Nachricht an
<a href="mailto:admin@tool-ctrl.de">admin@tool-ctrl.de</a>.
</p>
<h2>8. Beschwerderecht bei der Aufsichtsbehörde</h2>
<p>
Sie haben das Recht, sich bei einer Datenschutz-Aufsichtsbehörde über die
Verarbeitung Ihrer personenbezogenen Daten zu beschweren (Art. 77 DSGVO).
Zuständig ist in der Regel die Aufsichtsbehörde Ihres üblichen
Aufenthaltsorts oder die des Verantwortlichen.
</p>
<h2>9. Aktualität dieser Erklärung</h2>
<p>
Diese Datenschutzerklärung hat den Stand Mai 2026. Durch die
Weiterentwicklung der Website oder geänderte gesetzliche Vorgaben kann eine
Anpassung erforderlich werden.
</p>
</main>
<footer class="legal-footer">
<div class="wrap legal-footer-inner">
<span>© 2026 ToolCTRL</span>
<span>
<a href="/">Startseite</a> ·
<a href="/impressum.html">Impressum</a> ·
<a href="/datenschutz.html">Datenschutz</a>
</span>
</div>
</footer>
</body>
</html>
+104
View File
@@ -0,0 +1,104 @@
<!DOCTYPE html>
<html lang="de">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>Impressum — ToolCTRL</title>
<meta name="description" content="Impressum und Anbieterkennzeichnung von ToolCTRL." />
<meta name="robots" content="noindex" />
<link rel="icon" type="image/png" href="/assets/favicon.png" />
<link rel="stylesheet" href="/styles.css" />
</head>
<body>
<header class="site-header">
<div class="wrap header-inner">
<a class="brand" href="/" aria-label="ToolCTRL Startseite">
<img src="/assets/logo-black.svg" alt="ToolCTRL" class="brand-logo" />
</a>
<a class="legal-back" href="/">Zurück zur Startseite</a>
</div>
</header>
<main class="legal-main">
<h1>Impressum</h1>
<p class="legal-updated">Angaben gemäß § 5 DDG (Digitale-Dienste-Gesetz)</p>
<h2>Anbieter</h2>
<p>
R&amp;D² UG (haftungsbeschränkt)<br />
Orbinstraße 1<br />
76646 Bruchsal<br />
Deutschland
</p>
<h2>Vertreten durch</h2>
<p>
<span class="legal-tbd">[ Name der vertretungsberechtigten Person(en) — bei Gesellschaften ]</span>
</p>
<h2>Kontakt</h2>
<p>
Telefon: <span class="legal-tbd">[ Telefonnummer ]</span><br />
E-Mail: <a href="mailto:admin@tool-ctrl.de">admin@tool-ctrl.de</a><br />
Web: <a href="https://tool-ctrl.de">tool-ctrl.de</a>
</p>
<h2>Registereintrag</h2>
<p>
<span class="legal-tbd">[ Registergericht — falls vorhanden, sonst entfällt dieser Abschnitt ]</span><br />
<span class="legal-tbd">[ Registernummer (z. B. HRB …) ]</span>
</p>
<h2>Umsatzsteuer-Identifikationsnummer</h2>
<p>
Umsatzsteuer-Identifikationsnummer gemäß § 27a Umsatzsteuergesetz:<br />
<span class="legal-tbd">[ USt-IdNr. — falls vorhanden, sonst entfällt dieser Abschnitt ]</span>
</p>
<h2>Verantwortlich für den Inhalt nach § 18 Abs. 2 MStV</h2>
<p>
<span class="legal-tbd">[ Name der verantwortlichen Person ]</span><br />
Orbinstraße 1<br />
76646 Bruchsal
</p>
<h2>Haftung für Inhalte</h2>
<p>
Die Inhalte dieser Website wurden mit größtmöglicher Sorgfalt erstellt.
Für die Richtigkeit, Vollständigkeit und Aktualität der Inhalte können wir
jedoch keine Gewähr übernehmen. Als Diensteanbieter sind wir gemäß den
allgemeinen Gesetzen für eigene Inhalte auf diesen Seiten verantwortlich.
</p>
<h2>Haftung für Links</h2>
<p>
Diese Website enthält Links zu externen Websites Dritter, auf deren Inhalte
wir keinen Einfluss haben. Für die Inhalte der verlinkten Seiten ist stets
der jeweilige Anbieter oder Betreiber verantwortlich. Eine permanente
inhaltliche Kontrolle der verlinkten Seiten ist ohne konkrete Anhaltspunkte
einer Rechtsverletzung nicht zumutbar.
</p>
<h2>Urheberrecht</h2>
<p>
Die auf dieser Website veröffentlichten Inhalte unterliegen dem deutschen
Urheberrecht. Beiträge Dritter sind als solche gekennzeichnet. Jede
Vervielfältigung, Bearbeitung oder Verbreitung außerhalb der Grenzen des
Urheberrechts bedarf der vorherigen schriftlichen Zustimmung.
</p>
</main>
<footer class="legal-footer">
<div class="wrap legal-footer-inner">
<span>© 2026 ToolCTRL</span>
<span>
<a href="/">Startseite</a> ·
<a href="/impressum.html">Impressum</a> ·
<a href="/datenschutz.html">Datenschutz</a>
</span>
</div>
</footer>
</body>
</html>
+380
View File
@@ -0,0 +1,380 @@
<!DOCTYPE html>
<html lang="de">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>ToolCTRL — from vision to version</title>
<meta name="description" content="ToolCTRL entwickelt Automatisierungen, interne Tools und individuelle Software — schnell umgesetzt, zuverlässig im Betrieb." />
<link rel="icon" type="image/png" href="/assets/favicon.png" />
<link rel="preconnect" href="https://fonts.googleapis.com" />
<link rel="stylesheet" href="/styles.css" />
</head>
<body>
<!-- ============ HEADER ============ -->
<header class="site-header" id="top">
<div class="wrap header-inner">
<a class="brand" href="#top" aria-label="ToolCTRL Startseite">
<img src="/assets/logo-black.svg" alt="ToolCTRL" class="brand-logo" />
</a>
<nav class="nav" aria-label="Hauptnavigation">
<a href="#leistungen">Leistungen</a>
<a href="#vorgehen">Vorgehen</a>
<a href="#arbeit">Organisation</a>
<a class="btn btn-solid btn-sm" href="#kontakt">Kontakt aufnehmen</a>
</nav>
<button class="nav-toggle" aria-label="Menü" aria-expanded="false">
<span></span><span></span>
</button>
</div>
<div class="mobile-nav" hidden>
<a href="#leistungen">Leistungen</a>
<a href="#vorgehen">Vorgehen</a>
<a href="#arbeit">Organisation</a>
<a class="btn btn-solid" href="#kontakt">Kontakt aufnehmen</a>
</div>
</header>
<main>
<!-- ============ HERO ============ -->
<section class="hero">
<div class="wrap hero-grid">
<div class="hero-copy">
<h1 class="hero-title">
Software und Automatisierung,<br />
die einfach&nbsp;läuft.
</h1>
<p class="hero-lead">
ToolCTRL plant, baut und betreibt individuelle Software — von der
Prozessautomatisierung über interne Tools bis zur Integration
bestehender Systeme. Schnell umgesetzt, sauber konstruiert,
zuverlässig im&nbsp;Betrieb.
</p>
<div class="hero-actions">
<a class="btn btn-solid" href="#kontakt">Projekt besprechen</a>
<a class="btn btn-ghost" href="#leistungen">Leistungen ansehen</a>
</div>
</div>
<!-- Automatisierung trifft Kontrolle — generisch, kein reales Produkt -->
<div class="hero-visual" aria-hidden="true">
<div class="visual-frame">
<div class="visual-label">
<span class="dot"></span> Workflow · ctrl
</div>
<svg class="node-graph" viewBox="0 0 540 400" role="presentation">
<defs>
<pattern id="grid" width="26" height="26" patternUnits="userSpaceOnUse">
<path d="M26 0H0V26" fill="none" stroke="#ECECEC" stroke-width="1" />
</pattern>
<linearGradient id="capface" x1="0" y1="0" x2="0" y2="1">
<stop offset="0" stop-color="#2A2A2A" />
<stop offset="1" stop-color="#101010" />
</linearGradient>
</defs>
<rect width="540" height="400" fill="url(#grid)" />
<!-- Leitungen -->
<g fill="none" stroke="#1A1A1A" stroke-width="1.6">
<path d="M116 78 C 165 78, 152 182, 200 182" />
<path d="M116 202 C 158 202, 168 202, 200 202" />
<path d="M116 326 C 165 326, 152 224, 200 224" />
<path d="M340 192 C 388 192, 378 118, 424 118" />
<path d="M340 214 C 388 214, 378 292, 424 292" />
</g>
<g fill="#1A1A1A">
<circle cx="116" cy="78" r="3" /><circle cx="116" cy="202" r="3" />
<circle cx="116" cy="326" r="3" /><circle cx="424" cy="118" r="3" />
<circle cx="424" cy="292" r="3" />
</g>
<!-- Eingangs-Knoten -->
<g class="gnode">
<rect x="24" y="56" width="92" height="44" />
<text x="70" y="83" text-anchor="middle">Daten</text>
</g>
<g class="gnode">
<rect x="24" y="180" width="92" height="44" />
<text x="70" y="207" text-anchor="middle">Auslöser</text>
</g>
<g class="gnode">
<rect x="24" y="304" width="92" height="44" />
<text x="70" y="331" text-anchor="middle">System</text>
</g>
<!-- Ausgangs-Knoten -->
<g class="gnode">
<rect x="424" y="96" width="92" height="44" />
<text x="470" y="123" text-anchor="middle">Aktion</text>
</g>
<g class="gnode">
<rect x="424" y="270" width="92" height="44" />
<text x="470" y="297" text-anchor="middle">Report</text>
</g>
<!-- zentraler CTRL-Keycap -->
<rect x="200" y="166" width="140" height="102" rx="14" fill="#000000" />
<rect x="200" y="152" width="140" height="102" rx="14"
fill="url(#capface)" stroke="#000000" stroke-width="1.6" />
<rect x="209" y="159" width="122" height="3" rx="1.5"
fill="#FFFFFF" opacity="0.12" />
<path d="M311 175 l8 -9 l8 9" fill="none" stroke="#727272"
stroke-width="2.4" stroke-linecap="round" stroke-linejoin="round" />
<text x="270" y="218" text-anchor="middle" class="cap-legend">ctrl</text>
<g fill="#000000">
<circle cx="200" cy="182" r="3" /><circle cx="200" cy="202" r="3" />
<circle cx="200" cy="224" r="3" /><circle cx="340" cy="192" r="3" />
<circle cx="340" cy="214" r="3" />
</g>
</svg>
</div>
<div class="visual-meta">
<span>Automatisiert</span>
<span>Kontrolliert</span>
<span>Wartbar</span>
</div>
</div>
</div>
</section>
<!-- ============ LEISTUNGEN ============ -->
<section class="section" id="leistungen">
<div class="wrap">
<div class="section-head">
<span class="eyebrow">Leistungen</span>
<h2 class="section-title">Die digitale Infrastruktur Ihres Betriebs.</h2>
<p class="section-intro">
Wir arbeiten dort, wo Tabellen, manuelle Schritte und getrennte
Systeme zu viel Zeit kosten. Daraus bauen wir eine tragfähige
Infrastruktur: Software, Automatisierung und Schnittstellen,
zugeschnitten auf Ihren Ablauf, nicht umgekehrt.
</p>
</div>
<div class="cards">
<article class="card">
<span class="icon-key"><img src="/assets/icons/graph.svg" alt="" class="card-icon" /></span>
<h3>Prozessautomatisierung</h3>
<p>Wiederkehrende Abläufe werden zu verlässlichen Workflows, die
ohne manuelles Zutun ausgelöst, verarbeitet und dokumentiert
werden.</p>
</article>
<article class="card">
<span class="icon-key"><img src="/assets/icons/settings.svg" alt="" class="card-icon" /></span>
<h3>Individuelle Software</h3>
<p>Anwendungen, die exakt zu Ihrem Geschäft passen. Schlank
gebaut, klar bedienbar und auf Dauer wartbar.</p>
</article>
<article class="card">
<span class="icon-key"><img src="/assets/icons/chart.svg" alt="" class="card-icon" /></span>
<h3>Dashboards &amp; Datenflüsse</h3>
<p>Verstreute Daten an einem Ort: aktuell, übersichtlich und
als Grundlage für schnelle Entscheidungen.</p>
</article>
<article class="card">
<span class="icon-key"><img src="/assets/icons/share.svg" alt="" class="card-icon" /></span>
<h3>Schnittstellen &amp; Integrationen</h3>
<p>Bestehende Tools, APIs und Systeme greifen ineinander, statt
nebeneinander zu laufen.</p>
</article>
<article class="card">
<span class="icon-key"><img src="/assets/icons/columns.svg" alt="" class="card-icon" /></span>
<h3>Interne Tools</h3>
<p>Werkzeuge für das eigene Team, die verstreute Tabellenlösungen
ablösen und mit Ihren Abläufen mitwachsen.</p>
</article>
<article class="card">
<span class="icon-key"><img src="/assets/icons/time.svg" alt="" class="card-icon" /></span>
<h3>Betrieb &amp; Weiterentwicklung</h3>
<p>Nach dem Launch ist nicht Schluss: Wartung, Anpassung und
Ausbau aus einer Hand.</p>
</article>
</div>
</div>
</section>
<!-- ============ VORGEHEN ============ -->
<section class="section section-alt" id="vorgehen">
<div class="wrap">
<div class="section-head">
<span class="eyebrow">Vorgehen</span>
<h2 class="section-title">In vier klaren Schritten.</h2>
<p class="section-intro">
Kein Wasserfall, kein Blindflug. Ein Ablauf, der Ergebnisse früh
sichtbar macht und Sie an jeder Stelle einbezieht.
</p>
</div>
<ol class="steps">
<li class="step">
<span class="step-num">01</span>
<h3>Analyse</h3>
<p>Wir sehen uns Ihren Ablauf an und legen offen, wo Zeit, Daten
und Klarheit verloren gehen.</p>
</li>
<li class="step">
<span class="step-num">02</span>
<h3>Konzept</h3>
<p>Ein konkreter Lösungsvorschlag mit Aufwand, Umfang und
erwartetem Nutzen, transparent kalkuliert.</p>
</li>
<li class="step">
<span class="step-num">03</span>
<h3>Umsetzung</h3>
<p>Wir bauen in kurzen Zyklen. Sie sehen früh ein funktionierendes
Ergebnis statt nur Folien.</p>
</li>
<li class="step">
<span class="step-num">04</span>
<h3>Betrieb</h3>
<p>Übergabe, Einweisung und laufende Pflege, damit die Lösung
dauerhaft trägt.</p>
</li>
</ol>
</div>
</section>
<!-- ============ ARBEITSWEISE / KANBAN VISUAL ============ -->
<section class="section" id="arbeit">
<div class="wrap arbeit-grid">
<div class="arbeit-copy">
<span class="eyebrow">Organisation</span>
<h2 class="section-title">Struktur, die in der Software steckt.</h2>
<p class="section-intro">
Ob Lead-Verarbeitung, Vertriebspipeline oder Projektboard: Wir
bauen die Software, in der Aufgaben, Status und Fortschritt
sichtbar werden und Abläufe automatisch weiterlaufen.
</p>
<ul class="checklist">
<li>Lead- und Vertriebspipelines</li>
<li>Aufgaben- und Projektboards</li>
<li>Workflow-Automatisierung und Status-Tracking</li>
</ul>
</div>
<!-- Kanban-Andeutung: bewusst unscharf, kein reales Produkt -->
<div class="kanban-wrap" aria-hidden="true">
<div class="kanban">
<div class="kb-col">
<div class="kb-head">Backlog</div>
<div class="kb-card"><span class="kb-line w70"></span><span class="kb-line w40"></span></div>
<div class="kb-card"><span class="kb-line w55"></span><span class="kb-line w60"></span></div>
<div class="kb-card"><span class="kb-line w80"></span><span class="kb-line w35"></span></div>
</div>
<div class="kb-col">
<div class="kb-head">In Arbeit</div>
<div class="kb-card kb-active"><span class="kb-line w65"></span><span class="kb-line w50"></span></div>
<div class="kb-card"><span class="kb-line w75"></span><span class="kb-line w45"></span></div>
</div>
<div class="kb-col">
<div class="kb-head">Review</div>
<div class="kb-card"><span class="kb-line w60"></span><span class="kb-line w55"></span></div>
</div>
<div class="kb-col">
<div class="kb-head">Live</div>
<div class="kb-card kb-done"><span class="kb-line w70"></span><span class="kb-line w40"></span></div>
<div class="kb-card kb-done"><span class="kb-line w50"></span><span class="kb-line w65"></span></div>
</div>
</div>
<div class="kanban-fade"></div>
</div>
</div>
</section>
<!-- ============ KONTAKT ============ -->
<section class="section section-dark" id="kontakt">
<div class="wrap kontakt-grid">
<div class="kontakt-copy">
<span class="eyebrow eyebrow-light">Kontakt</span>
<h2 class="section-title">Sprechen wir über Ihr Vorhaben.</h2>
<p class="section-intro">
Beschreiben Sie kurz, woran es hakt. Wir melden uns mit einer
ehrlichen Einschätzung. Unverbindlich und ohne Verkaufsdruck.
</p>
<dl class="contact-list">
<div>
<dt>E-Mail</dt>
<dd><a href="mailto:admin@tool-ctrl.de">admin@tool-ctrl.de</a></dd>
</div>
<div>
<dt>LinkedIn</dt>
<dd><a href="https://www.linkedin.com/company/toolctrl/" target="_blank" rel="noopener">linkedin.com/company/toolctrl</a></dd>
</div>
</dl>
</div>
<form class="lead-form" id="lead-form" novalidate>
<div class="form-row">
<label for="f-name">Name <span>*</span></label>
<input id="f-name" name="name" type="text" autocomplete="name" required />
</div>
<div class="form-row">
<label for="f-firma">Firma</label>
<input id="f-firma" name="firma" type="text" autocomplete="organization" />
</div>
<div class="form-grid">
<div class="form-row">
<label for="f-email">E-Mail <span>*</span></label>
<input id="f-email" name="email" type="email" autocomplete="email" required />
</div>
<div class="form-row">
<label for="f-telefon">Telefon</label>
<input id="f-telefon" name="telefon" type="tel" autocomplete="tel" />
</div>
</div>
<div class="form-row">
<label for="f-nachricht">Worum geht es? <span>*</span></label>
<textarea id="f-nachricht" name="nachricht" rows="4" required
placeholder="Kurz Ihr Anliegen — wir kümmern uns um die Details."></textarea>
</div>
<!-- Honeypot gegen Spam -->
<div class="hp" aria-hidden="true">
<label for="f-website">Website</label>
<input id="f-website" name="website" type="text" tabindex="-1" autocomplete="off" />
</div>
<div class="form-foot">
<button type="submit" class="btn btn-solid">Anfrage senden</button>
<p class="form-note">Mit dem Absenden stimmen Sie der Bearbeitung
Ihrer Angaben gemäß der
<a href="/datenschutz.html">Datenschutzerklärung</a> zu.</p>
</div>
<p class="form-status" id="form-status" role="status" hidden></p>
</form>
</div>
</section>
</main>
<!-- ============ FOOTER ============ -->
<footer class="site-footer">
<div class="wrap footer-inner">
<div class="footer-brand">
<img src="/assets/logo-white.svg" alt="ToolCTRL" class="footer-logo" />
<p>from vision to version.</p>
</div>
<div class="footer-cols">
<div class="footer-col">
<span class="footer-h">Navigation</span>
<a href="#leistungen">Leistungen</a>
<a href="#vorgehen">Vorgehen</a>
<a href="#arbeit">Organisation</a>
<a href="#kontakt">Kontakt</a>
</div>
<div class="footer-col">
<span class="footer-h">Kontakt</span>
<a href="mailto:admin@tool-ctrl.de">admin@tool-ctrl.de</a>
<a href="https://tool-ctrl.de">tool-ctrl.de</a>
<a href="https://www.linkedin.com/company/toolctrl/" target="_blank" rel="noopener">LinkedIn</a>
</div>
</div>
</div>
<div class="wrap footer-base">
<span>© <span id="year">2026</span> ToolCTRL</span>
<span><a href="/impressum.html">Impressum</a> · <a href="/datenschutz.html">Datenschutz</a></span>
</div>
</footer>
<script src="/script.js"></script>
</body>
</html>
+127
View File
@@ -0,0 +1,127 @@
/* ToolCTRL — Landing Page Interaktion */
(function () {
"use strict";
/* ---- Jahr im Footer ---- */
var yearEl = document.getElementById("year");
if (yearEl) yearEl.textContent = String(new Date().getFullYear());
/* ---- Mobile-Navigation ---- */
var toggle = document.querySelector(".nav-toggle");
var mobileNav = document.querySelector(".mobile-nav");
if (toggle && mobileNav) {
toggle.addEventListener("click", function () {
var open = mobileNav.hasAttribute("hidden");
if (open) {
mobileNav.removeAttribute("hidden");
toggle.setAttribute("aria-expanded", "true");
} else {
mobileNav.setAttribute("hidden", "");
toggle.setAttribute("aria-expanded", "false");
}
});
mobileNav.querySelectorAll("a").forEach(function (a) {
a.addEventListener("click", function () {
mobileNav.setAttribute("hidden", "");
toggle.setAttribute("aria-expanded", "false");
});
});
}
/* ---- Lead-Formular ---- */
var form = document.getElementById("lead-form");
var status = document.getElementById("form-status");
if (!form) return;
function setStatus(msg, kind) {
if (!status) return;
status.textContent = msg;
status.className = "form-status " + (kind || "");
status.hidden = false;
}
function fieldRow(input) {
return input.closest(".form-row");
}
function validate() {
var ok = true;
["f-name", "f-email", "f-nachricht"].forEach(function (id) {
var el = document.getElementById(id);
var row = fieldRow(el);
var valid = el.value.trim() !== "";
if (id === "f-email" && valid) {
valid = /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(el.value.trim());
}
if (row) row.classList.toggle("invalid", !valid);
if (!valid) ok = false;
});
return ok;
}
form.addEventListener("submit", function (e) {
e.preventDefault();
if (!validate()) {
setStatus("Bitte füllen Sie die markierten Pflichtfelder aus.", "err");
return;
}
var btn = form.querySelector("button[type=submit]");
var payload = {
name: form.name.value.trim(),
firma: form.firma.value.trim(),
email: form.email.value.trim(),
telefon: form.telefon.value.trim(),
nachricht: form.nachricht.value.trim(),
website: form.website.value.trim(), // Honeypot
quelle: "Messe — Landing Page"
};
if (btn) { btn.disabled = true; btn.textContent = "Wird gesendet …"; }
setStatus("Anfrage wird übermittelt …", "");
fetch("/api/lead", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify(payload)
})
.then(function (res) {
return res.json().then(function (data) {
return { ok: res.ok, data: data };
});
})
.then(function (r) {
if (r.ok) {
form.reset();
setStatus(
"Vielen Dank — Ihre Anfrage ist bei uns eingegangen. Wir melden uns zeitnah.",
"ok"
);
} else {
setStatus(
(r.data && r.data.error) ||
"Es ist ein Fehler aufgetreten. Bitte versuchen Sie es erneut.",
"err"
);
}
})
.catch(function () {
setStatus(
"Verbindung fehlgeschlagen. Bitte schreiben Sie uns direkt an admin@tool-ctrl.de.",
"err"
);
})
.finally(function () {
if (btn) { btn.disabled = false; btn.textContent = "Anfrage senden"; }
});
});
/* Markierung beim Tippen entfernen */
form.querySelectorAll("input, textarea").forEach(function (el) {
el.addEventListener("input", function () {
var row = fieldRow(el);
if (row) row.classList.remove("invalid");
});
});
})();
+818
View File
@@ -0,0 +1,818 @@
/* ============================================================
ToolCTRL — Landing Page
Monochrom · Weiß / Schwarz · scharfe Kanten · Haarlinien
============================================================ */
/* ---------- Hausschrift: Schibsted Grotesk (lokal gehostet) ---------- */
@font-face {
font-family: "Schibsted Grotesk";
font-style: normal;
font-weight: 400 800;
font-display: swap;
src: url(/assets/fonts/schibsted-grotesk-latin.woff2) format("woff2");
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6,
U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122,
U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
font-family: "Schibsted Grotesk";
font-style: normal;
font-weight: 400 800;
font-display: swap;
src: url(/assets/fonts/schibsted-grotesk-latin-ext.woff2) format("woff2");
unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7,
U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F,
U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F,
U+A720-A7FF;
}
:root {
--black: #0A0A0A;
--ink: #141414;
--gray-1:#5C5C5C;
--gray-2:#8C8C8C;
--line: #E2E2E2;
--line-strong:#0A0A0A;
--paper: #FFFFFF;
--paper-2:#F6F6F4;
--wrap: 1200px;
--grotesk: "Schibsted Grotesk", "Helvetica Neue", Arial, sans-serif;
}
* { box-sizing: border-box; margin: 0; padding: 0; }
html { scroll-behavior: smooth; }
body {
font-family: var(--grotesk);
color: var(--ink);
background: var(--paper);
line-height: 1.55;
-webkit-font-smoothing: antialiased;
text-rendering: optimizeLegibility;
}
img { display: block; max-width: 100%; }
a { color: inherit; text-decoration: none; }
.wrap {
width: 100%;
max-width: var(--wrap);
margin: 0 auto;
padding: 0 32px;
}
/* ---------- Eyebrow — als Mini-Keycap ---------- */
.eyebrow {
display: inline-block;
font-size: 10px;
letter-spacing: .16em;
text-transform: uppercase;
font-weight: 700;
color: var(--paper);
background: #1C1C1C;
padding: 7px 13px 8px;
border-radius: 4px;
box-shadow: 0 3px 0 0 #000000, inset 0 1.5px 0 0 rgba(255,255,255,.16);
}
.eyebrow-light {
color: var(--black);
background: var(--paper);
box-shadow: 0 3px 0 0 #B5B5B5, inset 0 1.5px 0 0 rgba(255,255,255,.9);
}
/* ---------- Buttons — als physische Tastenkappen ---------- */
.btn {
display: inline-flex;
align-items: center;
justify-content: center;
font-size: 14px;
font-weight: 600;
letter-spacing: .01em;
padding: 15px 28px;
border: 1.5px solid var(--black);
border-radius: 7px;
position: relative;
cursor: pointer;
white-space: nowrap;
transition: transform .09s ease, box-shadow .09s ease,
background .15s ease, color .15s ease;
}
/* Tastendruck — Kappe fährt auf die Grundfläche herunter */
.btn:active { transform: translateY(8px); }
/* schwarze Tastenkappe */
.btn-solid {
background: linear-gradient(180deg, #3C3C3C 0%, #1A1A1A 52%, #0C0C0C 100%);
color: var(--paper);
box-shadow:
0 8px 0 0 #000000,
0 17px 18px -7px rgba(0,0,0,.55),
inset 0 2px 0 0 rgba(255,255,255,.24),
inset 0 -10px 13px -11px rgba(0,0,0,.95);
}
.btn-solid:hover {
background: linear-gradient(180deg, #484848 0%, #232323 52%, #121212 100%);
}
.btn-solid:active {
box-shadow:
0 0 0 0 #000000,
0 5px 8px -3px rgba(0,0,0,.5),
inset 0 2px 0 0 rgba(255,255,255,.16),
inset 0 -8px 11px -11px rgba(0,0,0,.9);
}
/* weiße Tastenkappe */
.btn-ghost {
background: linear-gradient(180deg, #FFFFFF 0%, #F1F1EF 58%, #E5E5E2 100%);
color: var(--black);
box-shadow:
0 8px 0 0 #0A0A0A,
0 17px 18px -8px rgba(0,0,0,.34),
inset 0 2px 0 0 rgba(255,255,255,.95),
inset 0 -9px 11px -11px rgba(0,0,0,.42);
}
.btn-ghost:hover {
background: linear-gradient(180deg, #FFFFFF 0%, #EAEAE7 58%, #DBDBD8 100%);
}
.btn-ghost:active {
box-shadow:
0 0 0 0 #0A0A0A,
0 5px 7px -3px rgba(0,0,0,.3),
inset 0 2px 0 0 rgba(255,255,255,.9),
inset 0 -7px 10px -11px rgba(0,0,0,.38);
}
/* helle Tastenkappe (auf dunklem Grund) */
.btn-light {
background: linear-gradient(180deg, #FFFFFF 0%, #EAEAEA 100%);
color: var(--black);
border-color: #FFFFFF;
box-shadow:
0 8px 0 0 #6E6E6E,
0 17px 18px -8px rgba(0,0,0,.45),
inset 0 2px 0 0 rgba(255,255,255,.95);
}
.btn-light:hover {
background: linear-gradient(180deg, #FFFFFF 0%, #DCDCDC 100%);
}
.btn-light:active {
box-shadow:
0 0 0 0 #6E6E6E,
0 5px 7px -3px rgba(0,0,0,.4),
inset 0 2px 0 0 rgba(255,255,255,.9);
}
/* kompakte Variante (Header) — flachere Tiefe, passt in die Leiste */
.btn-sm { padding: 11px 20px; font-size: 13px; }
.btn-sm.btn-solid {
box-shadow:
0 5px 0 0 #000000,
0 9px 10px -6px rgba(0,0,0,.5),
inset 0 2px 0 0 rgba(255,255,255,.22),
inset 0 -7px 10px -11px rgba(0,0,0,.9);
}
.btn-sm.btn-solid:active {
box-shadow:
0 0 0 0 #000000,
0 3px 5px -2px rgba(0,0,0,.45),
inset 0 2px 0 0 rgba(255,255,255,.16);
}
.btn-sm:active { transform: translateY(5px); }
/* ============================================================
HEADER
============================================================ */
.site-header {
position: sticky;
top: 0;
z-index: 50;
background: rgba(255,255,255,.94);
backdrop-filter: blur(8px);
border-bottom: 1px solid var(--line);
}
.header-inner {
display: flex;
align-items: center;
justify-content: space-between;
height: 74px;
}
.brand-logo { height: 26px; width: auto; }
.nav {
display: flex;
align-items: center;
gap: 34px;
}
.nav > a:not(.btn) {
font-size: 14px;
font-weight: 500;
color: var(--ink);
padding-bottom: 2px;
border-bottom: 1.5px solid transparent;
}
.nav > a:not(.btn):hover { border-bottom-color: var(--black); }
.nav-toggle {
display: none;
flex-direction: column;
gap: 5px;
background: none;
border: 1.5px solid var(--black);
padding: 11px 10px;
cursor: pointer;
}
.nav-toggle span {
width: 20px; height: 1.5px;
background: var(--black);
display: block;
}
.mobile-nav {
/* Standardmäßig nie sichtbar — wird nur im Mobil-Breakpoint
per JS (hidden-Attribut entfernen) eingeblendet. */
display: none;
flex-direction: column;
gap: 4px;
padding: 16px 32px 24px;
border-bottom: 1px solid var(--line);
background: var(--paper);
}
.mobile-nav a:not(.btn) {
padding: 12px 0;
font-size: 16px;
font-weight: 500;
border-bottom: 1px solid var(--line);
}
.mobile-nav .btn { margin-top: 12px; }
/* ============================================================
HERO
============================================================ */
.hero {
border-bottom: 1px solid var(--line);
}
.hero-grid {
display: grid;
grid-template-columns: 1.05fr .95fr;
gap: 64px;
align-items: center;
padding: 96px 32px 104px;
}
.hero-title {
font-size: clamp(36px, 4.6vw, 62px);
line-height: 1.05;
letter-spacing: -.022em;
font-weight: 700;
margin: 0 0 24px;
}
.hero-lead {
font-size: 17px;
color: var(--gray-1);
max-width: 33em;
margin-bottom: 32px;
}
.hero-actions {
display: flex;
gap: 14px;
flex-wrap: wrap;
}
.hero-tag {
margin-top: 34px;
padding-top: 22px;
border-top: 1px solid var(--line);
font-size: 13px;
letter-spacing: .04em;
color: var(--gray-2);
font-weight: 500;
}
/* ---------- Hero visual: node graph ---------- */
.visual-frame {
border: 1.5px solid var(--black);
background: var(--paper);
position: relative;
}
.visual-label {
display: flex;
align-items: center;
gap: 8px;
font-size: 11px;
letter-spacing: .14em;
text-transform: uppercase;
font-weight: 600;
padding: 12px 16px;
border-bottom: 1px solid var(--line);
}
.visual-label .dot {
width: 7px; height: 7px;
background: var(--black);
border-radius: 50%;
}
.node-graph { display: block; width: 100%; height: auto; }
.gnode rect {
fill: var(--paper);
stroke: var(--black);
stroke-width: 1.5;
}
.gnode text {
font-family: var(--grotesk);
font-size: 13px;
font-weight: 600;
fill: var(--black);
}
.cap-legend {
font-family: var(--grotesk);
font-size: 31px;
font-weight: 700;
letter-spacing: .01em;
fill: var(--paper);
}
.visual-meta {
display: flex;
gap: 8px;
margin-top: 14px;
flex-wrap: wrap;
}
.visual-meta span {
font-size: 11px;
letter-spacing: .08em;
text-transform: uppercase;
font-weight: 600;
color: var(--gray-1);
border: 1px solid var(--line);
padding: 6px 10px;
}
/* ============================================================
SECTIONS (generic)
============================================================ */
.section { padding: 100px 0; }
.section-alt { background: var(--paper-2); }
.section-head { max-width: 620px; margin-bottom: 56px; }
.section-title {
font-size: clamp(28px, 3.2vw, 42px);
line-height: 1.12;
letter-spacing: -.02em;
font-weight: 700;
margin: 18px 0 16px;
}
.section-intro {
font-size: 16px;
color: var(--gray-1);
}
/* ---------- Capability cards ---------- */
.cards {
display: grid;
grid-template-columns: repeat(3, 1fr);
border-top: 1px solid var(--line-strong);
border-left: 1px solid var(--line-strong);
}
.card {
border-right: 1px solid var(--line-strong);
border-bottom: 1px solid var(--line-strong);
padding: 36px 32px 40px;
background: var(--paper);
transition: background .15s ease;
}
.card:hover { background: var(--paper-2); }
/* Icon sitzt auf einem weißen 3D-Keycap */
.icon-key {
display: inline-flex;
align-items: center;
justify-content: center;
width: 56px;
height: 56px;
margin-bottom: 28px;
background: var(--paper);
border: 1.6px solid var(--black);
border-radius: 8px;
box-shadow: 0 5px 0 0 var(--black);
}
.card-icon {
width: 27px;
height: 27px;
}
.card h3 {
font-size: 19px;
font-weight: 700;
letter-spacing: -.01em;
margin-bottom: 10px;
}
.card p {
font-size: 15px;
color: var(--gray-1);
}
/* ---------- Steps ---------- */
.steps {
display: grid;
grid-template-columns: repeat(4, 1fr);
list-style: none;
gap: 0;
border-top: 1px solid var(--line-strong);
}
.step {
padding: 34px 26px 38px;
border-right: 1px solid var(--line);
}
.step:last-child { border-right: none; }
.step-num {
display: block;
font-size: 13px;
font-weight: 700;
letter-spacing: .12em;
color: var(--gray-2);
margin-bottom: 26px;
}
.step h3 {
font-size: 20px;
font-weight: 700;
margin-bottom: 10px;
}
.step p {
font-size: 15px;
color: var(--gray-1);
}
/* ============================================================
ARBEITSWEISE + KANBAN
============================================================ */
.arbeit-grid {
display: grid;
grid-template-columns: .9fr 1.1fr;
gap: 64px;
align-items: center;
}
.checklist {
list-style: none;
margin-top: 28px;
}
.checklist li {
font-size: 15px;
padding: 14px 0 14px 28px;
border-top: 1px solid var(--line);
position: relative;
color: var(--ink);
}
.checklist li:last-child { border-bottom: 1px solid var(--line); }
.checklist li::before {
content: "";
position: absolute;
left: 0;
top: 0;
bottom: 0;
margin-block: auto;
width: 12px;
height: 1.5px;
background: var(--black);
}
/* Kanban — bewusst unscharf, nur angedeutet */
.kanban-wrap {
position: relative;
border: 1.5px solid var(--black);
background: var(--paper);
overflow: hidden;
padding: 22px;
}
.kanban {
display: grid;
grid-template-columns: repeat(4, 1fr);
gap: 14px;
filter: blur(3.5px);
opacity: .7;
user-select: none;
}
.kb-col { display: flex; flex-direction: column; gap: 12px; }
.kb-head {
font-size: 12px;
font-weight: 700;
letter-spacing: .06em;
text-transform: uppercase;
color: var(--gray-1);
padding-bottom: 8px;
border-bottom: 1.5px solid var(--black);
}
.kb-card {
border: 1px solid var(--black);
background: var(--paper);
padding: 14px 12px;
display: flex;
flex-direction: column;
gap: 8px;
min-height: 64px;
}
.kb-card.kb-active { background: var(--black); }
.kb-card.kb-active .kb-line { background: #6E6E6E; }
.kb-card.kb-done { border-style: dashed; }
.kb-line {
height: 8px;
background: #DADADA;
display: block;
}
.kb-line.w35 { width: 35%; } .kb-line.w40 { width: 40%; }
.kb-line.w45 { width: 45%; } .kb-line.w50 { width: 50%; }
.kb-line.w55 { width: 55%; } .kb-line.w60 { width: 60%; }
.kb-line.w65 { width: 65%; } .kb-line.w70 { width: 70%; }
.kb-line.w75 { width: 75%; } .kb-line.w80 { width: 80%; }
.kanban-fade {
position: absolute;
inset: 0;
background:
linear-gradient(180deg, rgba(255,255,255,0) 55%, rgba(255,255,255,.92) 100%),
radial-gradient(120% 80% at 50% 40%, rgba(255,255,255,0) 50%, rgba(255,255,255,.6) 100%);
pointer-events: none;
}
/* ============================================================
KONTAKT
============================================================ */
.section-dark {
background: var(--black);
color: var(--paper);
}
.kontakt-grid {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 72px;
align-items: start;
}
.section-dark .section-intro { color: #A6A6A6; }
.contact-list {
margin-top: 34px;
border-top: 1px solid #2B2B2B;
}
.contact-list > div {
display: grid;
grid-template-columns: 90px 1fr;
gap: 16px;
padding: 16px 0;
border-bottom: 1px solid #2B2B2B;
}
.contact-list dt {
font-size: 11px;
letter-spacing: .14em;
text-transform: uppercase;
font-weight: 600;
color: var(--gray-2);
padding-top: 2px;
}
.contact-list dd { font-size: 15px; }
.contact-list a:hover { text-decoration: underline; }
/* ---------- Form ---------- */
.lead-form {
background: var(--paper-2);
color: var(--ink);
padding: 36px 34px;
border-radius: 14px;
}
.form-row { margin-bottom: 20px; }
.form-grid {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 18px;
}
.form-row label {
display: block;
font-size: 12px;
font-weight: 700;
letter-spacing: .08em;
text-transform: uppercase;
color: var(--ink);
margin-bottom: 8px;
}
.form-row label span { color: var(--gray-2); }
.form-row input,
.form-row textarea {
width: 100%;
font-family: var(--grotesk);
font-size: 15px;
color: var(--ink);
background: var(--paper);
border: 1.5px solid var(--line);
border-radius: 7px;
padding: 12px 14px;
transition: border-color .15s ease;
}
.form-row input:focus,
.form-row textarea:focus {
outline: none;
border-color: var(--black);
}
.form-row textarea { resize: vertical; }
.form-row.invalid input,
.form-row.invalid textarea { border-color: #C0392B; }
.hp { position: absolute; left: -9999px; width: 1px; height: 1px; overflow: hidden; }
.form-foot {
display: flex;
align-items: center;
gap: 18px;
margin-top: 6px;
}
.form-foot .btn { flex: none; }
.form-note {
font-size: 12px;
color: var(--gray-2);
line-height: 1.45;
}
.form-note a {
color: var(--ink);
text-decoration: underline;
text-underline-offset: 2px;
}
.form-status {
margin-top: 18px;
font-size: 14px;
font-weight: 600;
padding: 12px 14px;
border: 1.5px solid var(--black);
border-radius: 7px;
}
.form-status.ok { background: var(--black); color: var(--paper); }
.form-status.err { border-color: #C0392B; color: #C0392B; }
/* ============================================================
FOOTER
============================================================ */
.site-footer {
background: var(--black);
color: var(--paper);
padding-top: 64px;
}
.footer-inner {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 48px;
padding-bottom: 56px;
}
.footer-logo { height: 24px; width: auto; margin-bottom: 16px; }
.footer-brand p {
font-size: 13px;
color: var(--gray-2);
letter-spacing: .03em;
}
.footer-cols {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 32px;
}
.footer-col { display: flex; flex-direction: column; gap: 12px; }
.footer-h {
font-size: 11px;
letter-spacing: .14em;
text-transform: uppercase;
font-weight: 700;
color: var(--gray-2);
margin-bottom: 4px;
}
.footer-col a {
font-size: 14px;
color: #D4D4D4;
}
.footer-col a:hover { color: var(--paper); }
.footer-base {
display: flex;
justify-content: space-between;
padding-top: 22px;
padding-bottom: 28px;
border-top: 1px solid #262626;
font-size: 12px;
color: var(--gray-2);
}
.footer-base a:hover { color: var(--paper); }
/* ============================================================
RESPONSIVE
============================================================ */
@media (max-width: 960px) {
.nav { display: none; }
.nav-toggle { display: flex; }
/* Mobil-Menü nur sichtbar, wenn JS das hidden-Attribut entfernt */
.mobile-nav:not([hidden]) { display: flex; }
.hero-grid { grid-template-columns: 1fr; gap: 48px; padding: 60px 32px 72px; }
.cards { grid-template-columns: 1fr 1fr; }
.steps { grid-template-columns: 1fr 1fr; }
.step:nth-child(2) { border-right: none; }
.step:nth-child(1), .step:nth-child(2) { border-bottom: 1px solid var(--line); }
.arbeit-grid { grid-template-columns: 1fr; gap: 44px; }
.kontakt-grid { grid-template-columns: 1fr; gap: 44px; }
.footer-inner { grid-template-columns: 1fr; gap: 36px; }
}
@media (max-width: 620px) {
.wrap { padding: 0 20px; }
.mobile-nav { padding: 16px 20px 24px; }
.section { padding: 64px 0; }
.section-head { margin-bottom: 36px; }
.hero-actions .btn { flex: 1 1 auto; }
.cards { grid-template-columns: 1fr; }
.card { border-right: 1px solid var(--line-strong); }
.steps { grid-template-columns: 1fr; }
.step { border-right: none; border-bottom: 1px solid var(--line); }
.step:last-child { border-bottom: none; }
.form-grid { grid-template-columns: 1fr; gap: 0; }
.form-foot { flex-direction: column; align-items: stretch; gap: 14px; }
.form-foot .btn { width: 100%; }
.lead-form { padding: 26px 22px; }
.footer-cols { grid-template-columns: 1fr; }
.footer-base { flex-direction: column; gap: 8px; }
}
@media (prefers-reduced-motion: reduce) {
html { scroll-behavior: auto; }
}
/* ============================================================
RECHTLICHE SEITEN (Impressum / Datenschutz)
============================================================ */
.legal-back {
font-size: 14px;
font-weight: 500;
color: var(--ink);
padding-bottom: 2px;
border-bottom: 1.5px solid transparent;
}
.legal-back:hover { border-bottom-color: var(--black); }
.legal-main {
max-width: 780px;
margin: 0 auto;
padding: 64px clamp(20px, 5vw, 32px) 88px;
}
.legal-main h1 {
font-size: clamp(30px, 4vw, 44px);
line-height: 1.1;
letter-spacing: -.02em;
font-weight: 700;
margin-bottom: 14px;
}
.legal-intro {
font-size: 16px;
color: var(--gray-1);
margin-bottom: 10px;
}
.legal-updated {
font-size: 13px;
color: var(--gray-2);
padding-bottom: 28px;
margin-bottom: 8px;
border-bottom: 1px solid var(--line);
}
.legal-main h2 {
font-size: 19px;
font-weight: 700;
letter-spacing: -.01em;
margin: 38px 0 12px;
}
.legal-main p {
font-size: 15px;
line-height: 1.7;
color: var(--gray-1);
margin-bottom: 12px;
}
.legal-main ul {
margin: 0 0 12px;
padding-left: 20px;
}
.legal-main li {
font-size: 15px;
line-height: 1.7;
color: var(--gray-1);
margin-bottom: 5px;
}
.legal-main a {
color: var(--ink);
text-decoration: underline;
text-underline-offset: 2px;
}
.legal-main strong { color: var(--ink); font-weight: 700; }
/* Platzhalter — vor dem Live-Gang zu ersetzen */
.legal-tbd {
background: var(--paper-2);
border: 1px dashed var(--black);
padding: 1px 7px;
font-weight: 600;
color: var(--ink);
}
.legal-footer {
background: var(--black);
color: var(--gray-2);
padding: 26px 0;
}
.legal-footer-inner {
display: flex;
justify-content: space-between;
gap: 12px 24px;
font-size: 13px;
flex-wrap: wrap;
}
.legal-footer a { color: #D4D4D4; }
.legal-footer a:hover { color: var(--paper); }
+218
View File
@@ -0,0 +1,218 @@
/* ============================================================
ToolCTRL — Landing Page Server
Abhängigkeitsfrei (nur Node-Standardbibliothek).
Liefert /public und nimmt Leads unter POST /api/lead entgegen.
============================================================ */
"use strict";
const http = require("http");
const fs = require("fs");
const path = require("path");
const ROOT = __dirname;
const PUBLIC_DIR = path.join(ROOT, "public");
const LEADS_DIR = path.join(ROOT, "leads");
const LEADS_JSON = path.join(LEADS_DIR, "leads.ndjson");
const LEADS_CSV = path.join(LEADS_DIR, "leads.csv");
/* Bevorzugte Ports — der erste freie wird genutzt. */
const PORT_CANDIDATES = [4317, 4318, 4417, 5317, 8317, 0];
const HOST = "127.0.0.1";
const MIME = {
".html": "text/html; charset=utf-8",
".css": "text/css; charset=utf-8",
".js": "text/javascript; charset=utf-8",
".svg": "image/svg+xml",
".png": "image/png",
".jpg": "image/jpeg",
".jpeg": "image/jpeg",
".ico": "image/x-icon",
".json": "application/json; charset=utf-8",
".woff2": "font/woff2"
};
/* ---------- Lead-Speicher vorbereiten ---------- */
function ensureLeadStore() {
if (!fs.existsSync(LEADS_DIR)) fs.mkdirSync(LEADS_DIR, { recursive: true });
if (!fs.existsSync(LEADS_CSV)) {
fs.writeFileSync(
LEADS_CSV,
"zeitpunkt,name,firma,email,telefon,nachricht,quelle\n",
"utf8"
);
}
}
function csvCell(value) {
const s = String(value == null ? "" : value);
return '"' + s.replace(/"/g, '""').replace(/\r?\n/g, " ") + '"';
}
function saveLead(lead) {
ensureLeadStore();
fs.appendFileSync(LEADS_JSON, JSON.stringify(lead) + "\n", "utf8");
const row = [
lead.zeitpunkt,
lead.name,
lead.firma,
lead.email,
lead.telefon,
lead.nachricht,
lead.quelle
]
.map(csvCell)
.join(",");
fs.appendFileSync(LEADS_CSV, row + "\n", "utf8");
}
/* ---------- Statische Dateien ---------- */
function serveStatic(req, res) {
let urlPath = decodeURIComponent(req.url.split("?")[0]);
if (urlPath === "/") urlPath = "/index.html";
/* Path-Traversal verhindern */
const filePath = path.normalize(path.join(PUBLIC_DIR, urlPath));
if (!filePath.startsWith(PUBLIC_DIR)) {
res.writeHead(403).end("Forbidden");
return;
}
fs.stat(filePath, (err, stat) => {
if (err || !stat.isFile()) {
res.writeHead(404, { "Content-Type": "text/html; charset=utf-8" });
res.end("<h1>404</h1><p>Seite nicht gefunden.</p>");
return;
}
const ext = path.extname(filePath).toLowerCase();
res.writeHead(200, {
"Content-Type": MIME[ext] || "application/octet-stream",
"Cache-Control": "no-cache"
});
fs.createReadStream(filePath).pipe(res);
});
}
/* ---------- Lead-Endpunkt ---------- */
function handleLead(req, res) {
let body = "";
let tooLarge = false;
req.on("data", (chunk) => {
body += chunk;
if (body.length > 64 * 1024) {
tooLarge = true;
req.destroy();
}
});
req.on("end", () => {
if (tooLarge) return sendJSON(res, 413, { error: "Anfrage zu groß." });
let data;
try {
data = JSON.parse(body || "{}");
} catch (e) {
return sendJSON(res, 400, { error: "Ungültiges Format." });
}
/* Honeypot — befülltes Feld = Bot. Still mit OK quittieren. */
if (data.website && String(data.website).trim() !== "") {
return sendJSON(res, 200, { ok: true });
}
const name = String(data.name || "").trim();
const email = String(data.email || "").trim();
const nachricht = String(data.nachricht || "").trim();
if (!name || !email || !nachricht) {
return sendJSON(res, 400, {
error: "Bitte Name, E-Mail und Nachricht angeben."
});
}
if (!/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email)) {
return sendJSON(res, 400, { error: "Bitte eine gültige E-Mail angeben." });
}
const lead = {
zeitpunkt: new Date().toISOString(),
name: name.slice(0, 200),
firma: String(data.firma || "").trim().slice(0, 200),
email: email.slice(0, 200),
telefon: String(data.telefon || "").trim().slice(0, 80),
nachricht: nachricht.slice(0, 4000),
quelle: String(data.quelle || "Landing Page").slice(0, 120)
};
try {
saveLead(lead);
} catch (e) {
console.error("[lead] Speichern fehlgeschlagen:", e.message);
return sendJSON(res, 500, {
error: "Speichern fehlgeschlagen. Bitte später erneut versuchen."
});
}
console.log(
"[lead] " + lead.zeitpunkt + " — " + lead.name +
(lead.firma ? " (" + lead.firma + ")" : "") + " <" + lead.email + ">"
);
sendJSON(res, 200, { ok: true });
});
}
function sendJSON(res, code, obj) {
res.writeHead(code, { "Content-Type": "application/json; charset=utf-8" });
res.end(JSON.stringify(obj));
}
/* ---------- Router ---------- */
const server = http.createServer((req, res) => {
const route = req.url.split("?")[0];
if (route === "/api/lead") {
if (req.method !== "POST") {
return sendJSON(res, 405, { error: "Methode nicht erlaubt." });
}
return handleLead(req, res);
}
if (req.method !== "GET" && req.method !== "HEAD") {
res.writeHead(405).end("Method Not Allowed");
return;
}
serveStatic(req, res);
});
/* ---------- Freien Port suchen und starten ---------- */
function listen(candidates) {
if (candidates.length === 0) {
console.error("Kein freier Port gefunden.");
process.exit(1);
}
const port = candidates[0];
server.once("error", (err) => {
if (err.code === "EADDRINUSE") {
console.log("Port " + port + " belegt — versuche nächsten …");
listen(candidates.slice(1));
} else {
console.error("Serverfehler:", err.message);
process.exit(1);
}
});
server.listen(port, HOST, () => {
const actual = server.address().port;
ensureLeadStore();
console.log("");
console.log(" ToolCTRL — Landing Page läuft");
console.log(" ----------------------------------------");
console.log(" URL: http://" + HOST + ":" + actual);
console.log(" Leads: " + LEADS_CSV);
console.log(" " + LEADS_JSON);
console.log(" Stop: Strg + C");
console.log("");
});
}
listen(PORT_CANDIDATES);