App als Download hinzugefügt
This commit is contained in:
@@ -12,4 +12,14 @@ public class PlaylistController {
|
|||||||
public String index() {
|
public String index() {
|
||||||
return "index";
|
return "index";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@GetMapping("/impressum")
|
||||||
|
public String impressum() {
|
||||||
|
return "impressum";
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping("/datenschutz")
|
||||||
|
public String datenschutz() {
|
||||||
|
return "datenschutz";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1203,3 +1203,139 @@ body { padding-top: 4rem; }
|
|||||||
width: 100%;
|
width: 100%;
|
||||||
max-width: 260px;
|
max-width: 260px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* ── Footer links ── */
|
||||||
|
.footer-links {
|
||||||
|
display: flex;
|
||||||
|
gap: .6rem;
|
||||||
|
align-items: center;
|
||||||
|
font-size: .82rem;
|
||||||
|
color: var(--text-muted);
|
||||||
|
margin-top: .4rem;
|
||||||
|
}
|
||||||
|
.footer-links a {
|
||||||
|
color: var(--text-muted);
|
||||||
|
transition: color .15s;
|
||||||
|
}
|
||||||
|
.footer-links a:hover { color: var(--teal); }
|
||||||
|
|
||||||
|
/* ── Cookie Banner ── */
|
||||||
|
.cookie-banner {
|
||||||
|
position: fixed;
|
||||||
|
bottom: 0;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
z-index: 800;
|
||||||
|
background: var(--surface-2);
|
||||||
|
border-top: 1px solid var(--border);
|
||||||
|
padding: 1rem 1.5rem;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
gap: 1.25rem;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
box-shadow: 0 -4px 24px rgba(0,0,0,.4);
|
||||||
|
}
|
||||||
|
.cookie-text {
|
||||||
|
font-size: .88rem;
|
||||||
|
color: var(--text-muted);
|
||||||
|
flex: 1;
|
||||||
|
min-width: 200px;
|
||||||
|
}
|
||||||
|
.cookie-text a {
|
||||||
|
color: var(--teal);
|
||||||
|
text-decoration: underline;
|
||||||
|
text-underline-offset: 2px;
|
||||||
|
}
|
||||||
|
.cookie-btn { white-space: nowrap; flex-shrink: 0; }
|
||||||
|
|
||||||
|
/* ── Legal pages ── */
|
||||||
|
.legal-header {
|
||||||
|
padding: 1rem 0;
|
||||||
|
background: var(--bg-2);
|
||||||
|
border-bottom: 1px solid var(--border);
|
||||||
|
}
|
||||||
|
.legal-header .section-inner {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 1.25rem;
|
||||||
|
}
|
||||||
|
.legal-back {
|
||||||
|
display: inline-flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: .35rem;
|
||||||
|
color: var(--text-muted);
|
||||||
|
font-size: .9rem;
|
||||||
|
transition: color .15s;
|
||||||
|
}
|
||||||
|
.legal-back:hover { color: var(--teal); }
|
||||||
|
.legal-logo {
|
||||||
|
height: 32px;
|
||||||
|
width: auto;
|
||||||
|
margin-left: auto;
|
||||||
|
opacity: .75;
|
||||||
|
}
|
||||||
|
.legal-main {
|
||||||
|
padding: 4rem 0 6rem;
|
||||||
|
min-height: calc(100vh - 200px);
|
||||||
|
}
|
||||||
|
.legal-inner h1 {
|
||||||
|
font-size: clamp(1.8rem, 4vw, 2.6rem);
|
||||||
|
font-weight: 900;
|
||||||
|
letter-spacing: -.5px;
|
||||||
|
margin-bottom: 2.5rem;
|
||||||
|
background: var(--grad);
|
||||||
|
-webkit-background-clip: text;
|
||||||
|
-webkit-text-fill-color: transparent;
|
||||||
|
background-clip: text;
|
||||||
|
}
|
||||||
|
.legal-section {
|
||||||
|
margin-bottom: 2.25rem;
|
||||||
|
padding-bottom: 2.25rem;
|
||||||
|
border-bottom: 1px solid var(--border);
|
||||||
|
}
|
||||||
|
.legal-section:last-child {
|
||||||
|
border-bottom: none;
|
||||||
|
padding-bottom: 0;
|
||||||
|
}
|
||||||
|
.legal-section h2 {
|
||||||
|
font-size: 1.05rem;
|
||||||
|
font-weight: 700;
|
||||||
|
color: var(--teal);
|
||||||
|
margin-bottom: .75rem;
|
||||||
|
text-transform: uppercase;
|
||||||
|
letter-spacing: .05em;
|
||||||
|
font-size: .82rem;
|
||||||
|
}
|
||||||
|
.legal-section p {
|
||||||
|
color: var(--text-muted);
|
||||||
|
line-height: 1.8;
|
||||||
|
margin-bottom: .75rem;
|
||||||
|
}
|
||||||
|
.legal-section p:last-child { margin-bottom: 0; }
|
||||||
|
.legal-section ul {
|
||||||
|
list-style: none;
|
||||||
|
margin: .5rem 0 .75rem;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: .5rem;
|
||||||
|
}
|
||||||
|
.legal-section ul li {
|
||||||
|
color: var(--text-muted);
|
||||||
|
padding-left: 1.1rem;
|
||||||
|
position: relative;
|
||||||
|
line-height: 1.7;
|
||||||
|
}
|
||||||
|
.legal-section ul li::before {
|
||||||
|
content: '–';
|
||||||
|
position: absolute;
|
||||||
|
left: 0;
|
||||||
|
color: var(--teal);
|
||||||
|
}
|
||||||
|
.legal-section a {
|
||||||
|
color: var(--teal);
|
||||||
|
text-decoration: underline;
|
||||||
|
text-underline-offset: 2px;
|
||||||
|
transition: color .15s;
|
||||||
|
}
|
||||||
|
.legal-section a:hover { color: var(--teal-h); }
|
||||||
|
|||||||
Binary file not shown.
142
src/main/resources/templates/datenschutz.html
Normal file
142
src/main/resources/templates/datenschutz.html
Normal file
@@ -0,0 +1,142 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="de" xmlns:th="http://www.thymeleaf.org">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<title>Datenschutzerklärung – LibreDeck</title>
|
||||||
|
<link rel="icon" type="image/png" th:href="@{/images/favicon.png}">
|
||||||
|
<link rel="stylesheet" th:href="@{/css/style.css}">
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
|
||||||
|
<header class="legal-header">
|
||||||
|
<div class="section-inner">
|
||||||
|
<a th:href="@{/}" class="legal-back">
|
||||||
|
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"
|
||||||
|
stroke-linecap="round" stroke-linejoin="round" width="18" height="18" aria-hidden="true">
|
||||||
|
<polyline points="15 18 9 12 15 6"/>
|
||||||
|
</svg>
|
||||||
|
Zurück
|
||||||
|
</a>
|
||||||
|
<img th:src="@{/images/logo.png}" alt="LibreDeck" class="legal-logo">
|
||||||
|
</div>
|
||||||
|
</header>
|
||||||
|
|
||||||
|
<main class="legal-main">
|
||||||
|
<div class="section-inner legal-inner">
|
||||||
|
<h1>Datenschutzerklärung</h1>
|
||||||
|
|
||||||
|
<section class="legal-section">
|
||||||
|
<h2>1. Verantwortlicher</h2>
|
||||||
|
<p>
|
||||||
|
Mario Störmer<br>
|
||||||
|
Langheide 14<br>
|
||||||
|
24354 Rieseby<br>
|
||||||
|
E-Mail: <a href="mailto:mario.stoerner@langhei.de">mario.stoerner@langhei.de</a>
|
||||||
|
</p>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section class="legal-section">
|
||||||
|
<h2>2. Grundsätze der Datenverarbeitung</h2>
|
||||||
|
<p>
|
||||||
|
LibreDeck verarbeitet keine personenbezogenen Daten dauerhaft. Es werden keine
|
||||||
|
Nutzerkonten angelegt, keine Registrierung verlangt und keine Daten persistent
|
||||||
|
auf dem Server gespeichert. Alle Verarbeitungsschritte finden ausschließlich
|
||||||
|
im Arbeitsspeicher während einer aktiven Sitzung statt.
|
||||||
|
</p>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section class="legal-section">
|
||||||
|
<h2>3. Zugriffsdaten / Server-Logs</h2>
|
||||||
|
<p>
|
||||||
|
Beim Aufruf der Website werden vom Webserver automatisch allgemeine Zugriffsdaten
|
||||||
|
erfasst (sog. Server-Logs): IP-Adresse, Zeitpunkt des Zugriffs, aufgerufene URL,
|
||||||
|
HTTP-Statuscode, übertragene Datenmenge sowie Referrer und Browser-Kennung.
|
||||||
|
Diese Daten werden ausschließlich zur Sicherstellung des technischen Betriebs
|
||||||
|
verwendet und nach spätestens 7 Tagen gelöscht. Rechtsgrundlage ist
|
||||||
|
Art. 6 Abs. 1 lit. f DSGVO (berechtigtes Interesse am sicheren Betrieb).
|
||||||
|
</p>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section class="legal-section">
|
||||||
|
<h2>4. Cookies und Sitzungsdaten</h2>
|
||||||
|
<p>
|
||||||
|
LibreDeck setzt ausschließlich technisch notwendige Session-Cookies ein
|
||||||
|
(JSESSIONID). Diese dienen dazu, während einer Browsersitzung den
|
||||||
|
Authentifizierungsstatus gegenüber den verbundenen Streaming-Diensten
|
||||||
|
aufrechtzuerhalten. Das Cookie wird beim Schließen des Browsers automatisch
|
||||||
|
gelöscht. Es findet keine Auswertung für Werbe- oder Trackingzwecke statt.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
Rechtsgrundlage: Art. 6 Abs. 1 lit. b DSGVO (Vertragserfüllung, da das Cookie
|
||||||
|
für den Betrieb des Dienstes technisch erforderlich ist).
|
||||||
|
</p>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section class="legal-section">
|
||||||
|
<h2>5. Verbindung mit Streaming-Diensten</h2>
|
||||||
|
<p>
|
||||||
|
Wenn Sie sich über LibreDeck mit einem Streaming-Dienst (Deezer, Spotify, Tidal,
|
||||||
|
Apple Music, YouTube) verbinden, werden Sie zur Anmeldeseite des jeweiligen
|
||||||
|
Anbieters weitergeleitet. LibreDeck erhält anschließend ein zeitlich begrenztes
|
||||||
|
Zugriffstoken, das nur für die Dauer Ihrer Sitzung gespeichert wird. Die
|
||||||
|
eigentliche Authentifizierung und die damit verbundene Datenverarbeitung erfolgt
|
||||||
|
beim jeweiligen Drittanbieter; dessen Datenschutzbestimmungen gelten:
|
||||||
|
</p>
|
||||||
|
<ul>
|
||||||
|
<li>Spotify: <a href="https://www.spotify.com/de/legal/privacy-policy/" target="_blank" rel="noopener">Datenschutzrichtlinie Spotify</a></li>
|
||||||
|
<li>Deezer: <a href="https://www.deezer.com/legal/personal-datas" target="_blank" rel="noopener">Datenschutzrichtlinie Deezer</a></li>
|
||||||
|
<li>Tidal: <a href="https://tidal.com/privacy" target="_blank" rel="noopener">Datenschutzrichtlinie Tidal</a></li>
|
||||||
|
<li>Apple Music: <a href="https://www.apple.com/de/legal/privacy/" target="_blank" rel="noopener">Datenschutzrichtlinie Apple</a></li>
|
||||||
|
<li>YouTube: <a href="https://policies.google.com/privacy" target="_blank" rel="noopener">Datenschutzrichtlinie Google</a></li>
|
||||||
|
</ul>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section class="legal-section">
|
||||||
|
<h2>6. MusicBrainz</h2>
|
||||||
|
<p>
|
||||||
|
Zur Ermittlung von Erscheinungsjahren werden Künstlername und Titel einzelner
|
||||||
|
Tracks an die öffentliche API von MusicBrainz (MetaBrainz Foundation, USA)
|
||||||
|
übermittelt. Es handelt sich dabei um keine personenbezogenen Daten.
|
||||||
|
Weitere Informationen: <a href="https://metabrainz.org/privacy" target="_blank" rel="noopener">MetaBrainz Datenschutzrichtlinie</a>.
|
||||||
|
</p>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section class="legal-section">
|
||||||
|
<h2>7. Ihre Rechte</h2>
|
||||||
|
<p>Nach der DSGVO stehen Ihnen folgende Rechte zu:</p>
|
||||||
|
<ul>
|
||||||
|
<li><strong>Auskunft</strong> (Art. 15 DSGVO): Sie können Auskunft über die zu Ihrer Person gespeicherten Daten verlangen.</li>
|
||||||
|
<li><strong>Berichtigung</strong> (Art. 16 DSGVO): Sie können die Berichtigung unrichtiger Daten verlangen.</li>
|
||||||
|
<li><strong>Löschung</strong> (Art. 17 DSGVO): Sie können die Löschung Ihrer Daten verlangen, soweit keine gesetzliche Aufbewahrungspflicht entgegensteht.</li>
|
||||||
|
<li><strong>Einschränkung</strong> (Art. 18 DSGVO): Sie können die Einschränkung der Verarbeitung Ihrer Daten verlangen.</li>
|
||||||
|
<li><strong>Widerspruch</strong> (Art. 21 DSGVO): Sie können der Verarbeitung Ihrer Daten widersprechen, soweit diese auf Art. 6 Abs. 1 lit. f DSGVO beruht.</li>
|
||||||
|
<li><strong>Beschwerderecht</strong> (Art. 77 DSGVO): Sie haben das Recht, sich bei einer Datenschutzaufsichtsbehörde zu beschweren.</li>
|
||||||
|
</ul>
|
||||||
|
<p>Anfragen richten Sie bitte an: <a href="mailto:mario.stoerner@langhei.de">mario.stoerner@langhei.de</a></p>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section class="legal-section">
|
||||||
|
<h2>8. Änderungen</h2>
|
||||||
|
<p>
|
||||||
|
Wir behalten uns vor, diese Datenschutzerklärung anzupassen, um sie stets den
|
||||||
|
aktuellen rechtlichen Anforderungen oder Änderungen am Dienst anzupassen.
|
||||||
|
</p>
|
||||||
|
</section>
|
||||||
|
</div>
|
||||||
|
</main>
|
||||||
|
|
||||||
|
<footer class="site-footer">
|
||||||
|
<div class="section-inner footer-inner">
|
||||||
|
<img th:src="@{/images/logo.png}" alt="LibreDeck" class="footer-logo-img">
|
||||||
|
<p>Keine Datenspeicherung · Kein Account erforderlich</p>
|
||||||
|
<div class="footer-links">
|
||||||
|
<a th:href="@{/impressum}">Impressum</a>
|
||||||
|
<span aria-hidden="true">·</span>
|
||||||
|
<a th:href="@{/datenschutz}">Datenschutz</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</footer>
|
||||||
|
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
94
src/main/resources/templates/impressum.html
Normal file
94
src/main/resources/templates/impressum.html
Normal file
@@ -0,0 +1,94 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="de" xmlns:th="http://www.thymeleaf.org">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<title>Impressum – LibreDeck</title>
|
||||||
|
<link rel="icon" type="image/png" th:href="@{/images/favicon.png}">
|
||||||
|
<link rel="stylesheet" th:href="@{/css/style.css}">
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
|
||||||
|
<header class="legal-header">
|
||||||
|
<div class="section-inner">
|
||||||
|
<a th:href="@{/}" class="legal-back">
|
||||||
|
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"
|
||||||
|
stroke-linecap="round" stroke-linejoin="round" width="18" height="18" aria-hidden="true">
|
||||||
|
<polyline points="15 18 9 12 15 6"/>
|
||||||
|
</svg>
|
||||||
|
Zurück
|
||||||
|
</a>
|
||||||
|
<img th:src="@{/images/logo.png}" alt="LibreDeck" class="legal-logo">
|
||||||
|
</div>
|
||||||
|
</header>
|
||||||
|
|
||||||
|
<main class="legal-main">
|
||||||
|
<div class="section-inner legal-inner">
|
||||||
|
<h1>Impressum</h1>
|
||||||
|
|
||||||
|
<section class="legal-section">
|
||||||
|
<h2>Angaben gemäß § 5 TMG</h2>
|
||||||
|
<p>
|
||||||
|
Mario Störmer<br>
|
||||||
|
Langheide 14<br>
|
||||||
|
24354 Rieseby
|
||||||
|
</p>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section class="legal-section">
|
||||||
|
<h2>Kontakt</h2>
|
||||||
|
<p>E-Mail: <a href="mailto:mario.stoerner@langhei.de">mario.stoerner@langhei.de</a></p>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section class="legal-section">
|
||||||
|
<h2>EU-Streitbeilegung</h2>
|
||||||
|
<p>
|
||||||
|
Die Europäische Kommission stellt eine Plattform zur Online-Streitbeilegung (OS) bereit:
|
||||||
|
<a href="https://ec.europa.eu/consumers/odr/" target="_blank" rel="noopener">
|
||||||
|
https://ec.europa.eu/consumers/odr/
|
||||||
|
</a>.<br>
|
||||||
|
Unsere E-Mail-Adresse finden Sie oben im Impressum.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
Wir sind nicht bereit oder verpflichtet, an Streitbeilegungsverfahren vor einer
|
||||||
|
Verbraucherschlichtungsstelle teilzunehmen.
|
||||||
|
</p>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section class="legal-section">
|
||||||
|
<h2>Haftung für Inhalte</h2>
|
||||||
|
<p>
|
||||||
|
Als Diensteanbieter sind wir gemäß § 7 Abs. 1 TMG für eigene Inhalte auf diesen Seiten
|
||||||
|
nach den allgemeinen Gesetzen verantwortlich. Nach §§ 8 bis 10 TMG sind wir als
|
||||||
|
Diensteanbieter jedoch nicht verpflichtet, übermittelte oder gespeicherte fremde
|
||||||
|
Informationen zu überwachen oder nach Umständen zu forschen, die auf eine rechtswidrige
|
||||||
|
Tätigkeit hinweisen.
|
||||||
|
</p>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section class="legal-section">
|
||||||
|
<h2>Urheberrecht</h2>
|
||||||
|
<p>
|
||||||
|
Die durch die Seitenbetreiber erstellten Inhalte und Werke auf diesen Seiten unterliegen
|
||||||
|
dem deutschen Urheberrecht. Die Vervielfältigung, Bearbeitung, Verbreitung und jede Art
|
||||||
|
der Verwertung außerhalb der Grenzen des Urheberrechtes bedürfen der schriftlichen
|
||||||
|
Zustimmung des jeweiligen Autors bzw. Erstellers.
|
||||||
|
</p>
|
||||||
|
</section>
|
||||||
|
</div>
|
||||||
|
</main>
|
||||||
|
|
||||||
|
<footer class="site-footer">
|
||||||
|
<div class="section-inner footer-inner">
|
||||||
|
<img th:src="@{/images/logo.png}" alt="LibreDeck" class="footer-logo-img">
|
||||||
|
<p>Keine Datenspeicherung · Kein Account erforderlich</p>
|
||||||
|
<div class="footer-links">
|
||||||
|
<a th:href="@{/impressum}">Impressum</a>
|
||||||
|
<span aria-hidden="true">·</span>
|
||||||
|
<a th:href="@{/datenschutz}">Datenschutz</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</footer>
|
||||||
|
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
@@ -216,6 +216,28 @@
|
|||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
|
<!-- ── Android Download ── -->
|
||||||
|
<section class="download-section" id="androidDownload" style="display:none">
|
||||||
|
<div class="section-inner download-inner">
|
||||||
|
<div class="download-icon" aria-hidden="true">
|
||||||
|
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round">
|
||||||
|
<rect x="5" y="2" width="14" height="20" rx="2"/><line x1="12" y1="18" x2="12" y2="18.01"/>
|
||||||
|
</svg>
|
||||||
|
</div>
|
||||||
|
<div class="download-text">
|
||||||
|
<h2>Android-App</h2>
|
||||||
|
<p>Scanne deine Karten direkt mit der App – öffnet den richtigen Streaming-Dienst per Tap.</p>
|
||||||
|
<a href="/downloads/libredeck.apk" class="btn btn-lg download-btn" download>
|
||||||
|
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" width="18" height="18" aria-hidden="true" style="flex-shrink:0">
|
||||||
|
<path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"/><polyline points="7 10 12 15 17 10"/><line x1="12" y1="15" x2="12" y2="3"/>
|
||||||
|
</svg>
|
||||||
|
APK herunterladen
|
||||||
|
</a>
|
||||||
|
<p class="download-hint">Android · Sideload · Einstellungen → Apps → Unbekannte Quellen erlauben</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
<!-- ── Card detail ── -->
|
<!-- ── Card detail ── -->
|
||||||
<section class="detail-section">
|
<section class="detail-section">
|
||||||
<div class="section-inner detail-inner">
|
<div class="section-inner detail-inner">
|
||||||
@@ -458,36 +480,40 @@
|
|||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
<!-- ── Android Download ── -->
|
|
||||||
<section class="download-section">
|
|
||||||
<div class="section-inner download-inner">
|
|
||||||
<div class="download-icon" aria-hidden="true">
|
|
||||||
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round">
|
|
||||||
<rect x="5" y="2" width="14" height="20" rx="2"/><line x1="12" y1="18" x2="12" y2="18.01"/>
|
|
||||||
</svg>
|
|
||||||
</div>
|
|
||||||
<div class="download-text">
|
|
||||||
<h2>Android-App</h2>
|
|
||||||
<p>Scanne deine Karten direkt mit der App – öffnet den richtigen Streaming-Dienst per Tap.</p>
|
|
||||||
<a href="/downloads/libredeck.apk" class="btn btn-lg download-btn" download>
|
|
||||||
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" width="18" height="18" aria-hidden="true" style="flex-shrink:0">
|
|
||||||
<path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"/><polyline points="7 10 12 15 17 10"/><line x1="12" y1="15" x2="12" y2="3"/>
|
|
||||||
</svg>
|
|
||||||
APK herunterladen
|
|
||||||
</a>
|
|
||||||
<p class="download-hint">Android · Sideload · Einstellungen → Apps → Unbekannte Quellen erlauben</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</section>
|
|
||||||
|
|
||||||
<!-- ── Footer ── -->
|
<!-- ── Footer ── -->
|
||||||
<footer class="site-footer">
|
<footer class="site-footer">
|
||||||
<div class="section-inner footer-inner">
|
<div class="section-inner footer-inner">
|
||||||
<img th:src="@{/images/logo.png}" alt="LibreDeck" class="footer-logo-img">
|
<img th:src="@{/images/logo.png}" alt="LibreDeck" class="footer-logo-img">
|
||||||
<p>Keine Datenspeicherung · Kein Account erforderlich</p>
|
<p>Keine Datenspeicherung · Kein Account erforderlich</p>
|
||||||
|
<div class="footer-links">
|
||||||
|
<a th:href="@{/impressum}">Impressum</a>
|
||||||
|
<span aria-hidden="true">·</span>
|
||||||
|
<a th:href="@{/datenschutz}">Datenschutz</a>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</footer>
|
</footer>
|
||||||
|
|
||||||
|
<!-- ── Cookie Banner ── -->
|
||||||
|
<div id="cookieBanner" class="cookie-banner" role="dialog" aria-label="Cookie-Hinweis" style="display:none">
|
||||||
|
<p class="cookie-text">
|
||||||
|
Diese Website verwendet ausschließlich technisch notwendige Cookies zur Aufrechterhaltung
|
||||||
|
der Sitzung. Es findet kein Tracking statt.
|
||||||
|
<a href="/datenschutz">Datenschutzerklärung</a>
|
||||||
|
</p>
|
||||||
|
<button class="btn btn-sm cookie-btn" onclick="acceptCookies()">Verstanden</button>
|
||||||
|
</div>
|
||||||
|
<script>
|
||||||
|
(function () {
|
||||||
|
if (!localStorage.getItem('cookieConsent')) {
|
||||||
|
document.getElementById('cookieBanner').style.display = 'flex';
|
||||||
|
}
|
||||||
|
})();
|
||||||
|
function acceptCookies() {
|
||||||
|
localStorage.setItem('cookieConsent', '1');
|
||||||
|
document.getElementById('cookieBanner').style.display = 'none';
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
<!-- ── Bulk-check warning dialog ── -->
|
<!-- ── Bulk-check warning dialog ── -->
|
||||||
<div id="bulkCheckDialog" style="display:none" role="dialog" aria-modal="true" aria-labelledby="bulkCheckTitle">
|
<div id="bulkCheckDialog" style="display:none" role="dialog" aria-modal="true" aria-labelledby="bulkCheckTitle">
|
||||||
<div class="dialog-backdrop" onclick="document.getElementById('bulkCheckDialog').style.display='none'"></div>
|
<div class="dialog-backdrop" onclick="document.getElementById('bulkCheckDialog').style.display='none'"></div>
|
||||||
@@ -537,6 +563,11 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
// ── Android download banner ──
|
||||||
|
if (/Android/i.test(navigator.userAgent)) {
|
||||||
|
document.getElementById('androidDownload').style.display = '';
|
||||||
|
}
|
||||||
|
|
||||||
// ── Unified service state ──
|
// ── Unified service state ──
|
||||||
const SERVICES = ['Spotify', 'Tidal', 'Deezer', 'Apple Music', 'YouTube'];
|
const SERVICES = ['Spotify', 'Tidal', 'Deezer', 'Apple Music', 'YouTube'];
|
||||||
const GEN_IDS = ['panelSpotify', 'panelTidal', 'panelDeezer', 'panelApple', 'panelYoutube'];
|
const GEN_IDS = ['panelSpotify', 'panelTidal', 'panelDeezer', 'panelApple', 'panelYoutube'];
|
||||||
|
|||||||
Reference in New Issue
Block a user