Hilfe-Button mit Overlay hinzugefügt - Barrierefreier Tooltip und Modal-Dialog implementiert
This commit is contained in:
31
info.md
Normal file
31
info.md
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
# Was ist Elpatrons Datumsrechner?
|
||||||
|
|
||||||
|
Der Datumsrechner kann verschiedene Datumsberechnungen durchführen:
|
||||||
|
|
||||||
|
- Anzahl der Tage zwischen zwei Daten
|
||||||
|
- Anzahl der Werktage zwischen zwei Daten
|
||||||
|
- Anzeige des Wochentags eines Datums
|
||||||
|
- Datum plus/minus X Tage
|
||||||
|
- Datum plus/minus X Werktage
|
||||||
|
- Datum plus/minus X Wochen/Monate
|
||||||
|
- Kalenderwoche zu Datum
|
||||||
|
- Start-/Enddatum einer Kalenderwoche eines Jahres
|
||||||
|
|
||||||
|
## Online Datumsrechner gibt es bereits in einer Vielzahl, warum also noch einer?
|
||||||
|
|
||||||
|
Aus zwei Gründen:
|
||||||
|
|
||||||
|
- Finde mal einen Datumsrechner, der nicht vollkommen verseucht mit Werbung, Tracking und Cookies ist!
|
||||||
|
- Das hat mich so geärgert, dass ich meinen eigenen programmiert habe.
|
||||||
|
- Genau genommen nicht ich selbst. Diese App wurde zum überwiegenden Teil von KI nach meinen Anweisungen entwickelt ([Vibe Coding}(https://www.wikiwand.com/en/articles/Vibe_coding).)
|
||||||
|
|
||||||
|
## Was du noch wissen solltest
|
||||||
|
|
||||||
|
- Ich habe versucht, die App möglichst barrierefrei zu gestalten, um Menschen mit Einschränkungen die Benutzung zu erleichtern.
|
||||||
|
- Diese App schnüffelt dir nicht hinterher, sammelt keine persönlichen Daten und geht dir auch sonst (hoffentlich!) in keiner Weise auf die Nerven.
|
||||||
|
- Den Quellcode dieser App habe ich auf [Codeberg](https://codeberg.org/elpatron/datecalc) veröffentlicht, du kannst ihn einsehen, verändern oder damit deinen eigenen kleinen Datumsrechner betreiben.
|
||||||
|
- Die App läuft auf meinem kleinen Home-Server und ist derzeit nicht für große Besucherzahlen ausgelegt.
|
||||||
|
- Ich übernehme keine Gewähr für die Funktionalität und die Rechenergebnisse. Die KI, die das programmiert hat, übrigens auch nicht.
|
||||||
|
- Falls du einen Fehler findest oder eine weitere Funktion wünschst, kannst du mir eine Mail schreiben (siehe Mailto Link in der Fußzeile)
|
||||||
|
|
||||||
|
Hab Spaß mit Elpatrons Datumsrechner! Dein M. Busche
|
@@ -51,6 +51,145 @@ body {
|
|||||||
box-shadow: var(--shadow);
|
box-shadow: var(--shadow);
|
||||||
padding: 2.5em 2em 2em 2em;
|
padding: 2.5em 2em 2em 2em;
|
||||||
border: 1px solid var(--border);
|
border: 1px solid var(--border);
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
.help-button-container {
|
||||||
|
position: absolute;
|
||||||
|
top: 2.5em;
|
||||||
|
right: 2em;
|
||||||
|
z-index: 10;
|
||||||
|
}
|
||||||
|
.help-button {
|
||||||
|
width: 2.2em;
|
||||||
|
height: 2.2em;
|
||||||
|
border-radius: 50%;
|
||||||
|
background: rgba(37, 99, 235, 0.1);
|
||||||
|
color: var(--primary);
|
||||||
|
border: 1px solid var(--border);
|
||||||
|
cursor: pointer;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
font-size: 1em;
|
||||||
|
font-weight: 500;
|
||||||
|
transition: all 0.2s;
|
||||||
|
min-width: 44px;
|
||||||
|
min-height: 44px;
|
||||||
|
}
|
||||||
|
.help-button:hover {
|
||||||
|
background: rgba(37, 99, 235, 0.2);
|
||||||
|
border-color: var(--primary);
|
||||||
|
}
|
||||||
|
.help-button:focus {
|
||||||
|
outline: 3px solid #facc15;
|
||||||
|
outline-offset: 2px;
|
||||||
|
box-shadow: 0 0 0 4px #1e293b;
|
||||||
|
}
|
||||||
|
.help-tooltip {
|
||||||
|
position: absolute;
|
||||||
|
top: 100%;
|
||||||
|
left: 50%;
|
||||||
|
transform: translateX(-50%);
|
||||||
|
background: var(--text);
|
||||||
|
color: white;
|
||||||
|
padding: 0.5em 0.8em;
|
||||||
|
border-radius: 6px;
|
||||||
|
font-size: 0.85em;
|
||||||
|
white-space: nowrap;
|
||||||
|
opacity: 0;
|
||||||
|
visibility: hidden;
|
||||||
|
transition: opacity 0.2s, visibility 0.2s;
|
||||||
|
margin-top: 0.5em;
|
||||||
|
z-index: 20;
|
||||||
|
}
|
||||||
|
.help-tooltip::before {
|
||||||
|
content: '';
|
||||||
|
position: absolute;
|
||||||
|
bottom: 100%;
|
||||||
|
left: 50%;
|
||||||
|
transform: translateX(-50%);
|
||||||
|
border: 5px solid transparent;
|
||||||
|
border-bottom-color: var(--text);
|
||||||
|
}
|
||||||
|
.help-button:hover + .help-tooltip,
|
||||||
|
.help-button:focus + .help-tooltip {
|
||||||
|
opacity: 1;
|
||||||
|
visibility: visible;
|
||||||
|
}
|
||||||
|
.modal-overlay {
|
||||||
|
position: fixed;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
background: rgba(0, 0, 0, 0.5);
|
||||||
|
display: none;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
z-index: 1000;
|
||||||
|
}
|
||||||
|
.modal-overlay.active {
|
||||||
|
display: flex;
|
||||||
|
}
|
||||||
|
.modal-content {
|
||||||
|
background: var(--surface);
|
||||||
|
border-radius: 12px;
|
||||||
|
padding: 2em;
|
||||||
|
max-width: 90%;
|
||||||
|
max-height: 90%;
|
||||||
|
overflow-y: auto;
|
||||||
|
position: relative;
|
||||||
|
box-shadow: 0 10px 25px rgba(0, 0, 0, 0.2);
|
||||||
|
margin: 0 auto;
|
||||||
|
left: 50%;
|
||||||
|
transform: translateX(-50%);
|
||||||
|
}
|
||||||
|
.modal-close {
|
||||||
|
position: absolute;
|
||||||
|
top: 1em;
|
||||||
|
right: 1em;
|
||||||
|
background: none;
|
||||||
|
border: none;
|
||||||
|
font-size: 1.5em;
|
||||||
|
cursor: pointer;
|
||||||
|
color: var(--text);
|
||||||
|
padding: 0.5em;
|
||||||
|
border-radius: 50%;
|
||||||
|
transition: background 0.2s;
|
||||||
|
width: 2.5em;
|
||||||
|
height: 2.5em;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
min-width: 44px;
|
||||||
|
min-height: 44px;
|
||||||
|
}
|
||||||
|
.modal-close:hover {
|
||||||
|
background: var(--border);
|
||||||
|
}
|
||||||
|
.modal-close:focus {
|
||||||
|
outline: 3px solid #facc15;
|
||||||
|
outline-offset: 2px;
|
||||||
|
}
|
||||||
|
.modal-content h1 {
|
||||||
|
margin-top: 0;
|
||||||
|
color: var(--primary-dark);
|
||||||
|
}
|
||||||
|
.modal-content h2 {
|
||||||
|
color: var(--primary-dark);
|
||||||
|
margin-top: 1.5em;
|
||||||
|
margin-bottom: 0.5em;
|
||||||
|
}
|
||||||
|
.modal-content p {
|
||||||
|
line-height: 1.6;
|
||||||
|
margin-bottom: 1em;
|
||||||
|
}
|
||||||
|
.modal-content ul {
|
||||||
|
margin-bottom: 1em;
|
||||||
|
padding-left: 1.5em;
|
||||||
|
}
|
||||||
|
.modal-content li {
|
||||||
|
margin-bottom: 0.5em;
|
||||||
}
|
}
|
||||||
h1 {
|
h1 {
|
||||||
text-align: center;
|
text-align: center;
|
||||||
@@ -275,6 +414,25 @@ button:focus, .accordion-header:focus {
|
|||||||
h1 {
|
h1 {
|
||||||
font-size: 1.3em;
|
font-size: 1.3em;
|
||||||
}
|
}
|
||||||
|
.help-button-container {
|
||||||
|
top: 1.5em;
|
||||||
|
right: 1.2em;
|
||||||
|
}
|
||||||
|
.help-button {
|
||||||
|
width: 2em;
|
||||||
|
height: 2em;
|
||||||
|
font-size: 0.9em;
|
||||||
|
min-width: 48px;
|
||||||
|
min-height: 48px;
|
||||||
|
}
|
||||||
|
.help-tooltip {
|
||||||
|
font-size: 0.8em;
|
||||||
|
padding: 0.4em 0.6em;
|
||||||
|
}
|
||||||
|
.modal-content {
|
||||||
|
padding: 1.5em;
|
||||||
|
margin: 1em;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Touch-Target Optimierungen für Footer-Links */
|
/* Touch-Target Optimierungen für Footer-Links */
|
||||||
@@ -335,6 +493,22 @@ footer br + a {
|
|||||||
el.classList.toggle('active', i === idx);
|
el.classList.toggle('active', i === idx);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
function showHelp() {
|
||||||
|
const modal = document.getElementById('helpModal');
|
||||||
|
modal.classList.add('active');
|
||||||
|
document.body.style.overflow = 'hidden';
|
||||||
|
// Fokus auf den Schließen-Button setzen
|
||||||
|
setTimeout(() => {
|
||||||
|
document.querySelector('.modal-close').focus();
|
||||||
|
}, 100);
|
||||||
|
}
|
||||||
|
function hideHelp() {
|
||||||
|
const modal = document.getElementById('helpModal');
|
||||||
|
modal.classList.remove('active');
|
||||||
|
document.body.style.overflow = '';
|
||||||
|
// Fokus zurück auf den Hilfe-Button setzen
|
||||||
|
document.querySelector('.help-button').focus();
|
||||||
|
}
|
||||||
document.addEventListener('DOMContentLoaded', function() {
|
document.addEventListener('DOMContentLoaded', function() {
|
||||||
// Sofortige Aktivierung der ersten Accordion-Sektion um Layout-Shifts zu vermeiden
|
// Sofortige Aktivierung der ersten Accordion-Sektion um Layout-Shifts zu vermeiden
|
||||||
const activeIdx = parseInt("{{ active_idx|default(0) }}");
|
const activeIdx = parseInt("{{ active_idx|default(0) }}");
|
||||||
@@ -368,6 +542,20 @@ footer br + a {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// ESC-Taste zum Schließen des Modals
|
||||||
|
document.addEventListener('keydown', function(e) {
|
||||||
|
if (e.key === 'Escape') {
|
||||||
|
hideHelp();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Klick außerhalb des Modals zum Schließen
|
||||||
|
document.getElementById('helpModal').addEventListener('click', function(e) {
|
||||||
|
if (e.target === this) {
|
||||||
|
hideHelp();
|
||||||
|
}
|
||||||
|
});
|
||||||
});
|
});
|
||||||
if ('serviceWorker' in navigator) {
|
if ('serviceWorker' in navigator) {
|
||||||
window.addEventListener('load', function() {
|
window.addEventListener('load', function() {
|
||||||
@@ -378,6 +566,10 @@ footer br + a {
|
|||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div class="container">
|
<div class="container">
|
||||||
|
<div class="help-button-container">
|
||||||
|
<button type="button" class="help-button" onclick="showHelp()" aria-label="Hilfe anzeigen" title="Hilfe anzeigen" aria-describedby="help-tooltip">?</button>
|
||||||
|
<div id="help-tooltip" class="help-tooltip" role="tooltip">Öffnet ein Hilfefenster mit Informationen über den Datumsrechner</div>
|
||||||
|
</div>
|
||||||
<div style="text-align:center; margin-bottom:1.2em;">
|
<div style="text-align:center; margin-bottom:1.2em;">
|
||||||
<div style="font-size:1.1em; font-style:italic; color:#64748b;">Elpatrons</div>
|
<div style="font-size:1.1em; font-style:italic; color:#64748b;">Elpatrons</div>
|
||||||
<h1 style="margin:0;">Datumsrechner</h1>
|
<h1 style="margin:0;">Datumsrechner</h1>
|
||||||
@@ -540,6 +732,57 @@ footer br + a {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<!-- Help Modal Overlay -->
|
||||||
|
<div id="helpModal" class="modal-overlay" role="dialog" aria-labelledby="help-title" aria-describedby="help-content">
|
||||||
|
<div class="modal-content">
|
||||||
|
<button type="button" class="modal-close" onclick="hideHelp()" aria-label="Hilfe schließen">×</button>
|
||||||
|
<h1 id="help-title">Was ist Elpatrons Datumsrechner?</h1>
|
||||||
|
|
||||||
|
<p>Der Datumsrechner kann verschiedene Datumsberechnungen durchführen:</p>
|
||||||
|
|
||||||
|
<ul>
|
||||||
|
<li>Anzahl der Tage zwischen zwei Daten</li>
|
||||||
|
<li>Anzahl der Werktage zwischen zwei Daten</li>
|
||||||
|
<li>Anzeige des Wochentags eines Datums</li>
|
||||||
|
<li>Datum plus/minus X Tage</li>
|
||||||
|
<li>Datum plus/minus X Werktage</li>
|
||||||
|
<li>Datum plus/minus X Wochen/Monate</li>
|
||||||
|
<li>Kalenderwoche zu Datum</li>
|
||||||
|
<li>Start-/Enddatum einer Kalenderwoche eines Jahres</li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
<h2>Online Datumsrechner gibt es bereits in einer Vielzahl, warum also noch einer?</h2>
|
||||||
|
|
||||||
|
<p>Aus zwei Gründen:</p>
|
||||||
|
|
||||||
|
<ul>
|
||||||
|
<li>Finde mal einen Datumsrechner, der nicht vollkommen verseucht mit Werbung, Tracking und Cookies ist!</li>
|
||||||
|
<li>Das hat mich so geärgert, dass ich meinen eigenen programmiert habe.
|
||||||
|
<ul>
|
||||||
|
<li>Genau genommen nicht ich selbst. Diese App wurde zum überwiegenden Teil von KI nach meinen Anweisungen entwickelt (Vibe Coding).</li>
|
||||||
|
</ul>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
<h2>Was du noch wissen solltest</h2>
|
||||||
|
|
||||||
|
<ul>
|
||||||
|
<li>Ich habe versucht, die App möglichst barrierefrei zu gestalten, um Menschen mit Einschränkungen die Benutzung zu erleichtern.</li>
|
||||||
|
<li>Diese App schnüffelt dir nicht hinterher, sammelt keine persönlichen Daten und geht dir auch sonst (hoffentlich!) in keiner Weise auf die Nerven.</li>
|
||||||
|
<li>Den Quellcode dieser App habe ich auf <a href="https://codeberg.org/elpatron/datecalc" target="_blank">Codeberg</a> veröffentlicht, du kannst ihn einsehen, verändern oder damit deinen eigenen kleinen Datumsrechner betreiben.</li>
|
||||||
|
<li>Die App läuft auf meinem kleinen Home-Server und ist derzeit nicht für große Besucherzahlen ausgelegt.</li>
|
||||||
|
<li>Ich übernehme keine Gewähr für die Funktionalität und die Rechenergebnisse. Die KI, die das programmiert hat, übrigens auch nicht.</li>
|
||||||
|
<li>Falls du einen Fehler findest oder eine weitere Funktion wünschst, kannst du mir eine Mail schreiben (siehe Mailto Link in der Fußzeile)</li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
<p><strong>Hab Spaß mit Elpatrons Datumsrechner! Dein M. Busche</strong></p>
|
||||||
|
</div>
|
||||||
|
<div id="help-content" class="sr-only">
|
||||||
|
Hilfe-Informationen für den Datumsrechner mit Erklärungen zu allen Funktionen
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<footer style="text-align:center; margin-top:2em; color:#64748b; font-size:0.98em; padding-bottom:1.5em;">
|
<footer style="text-align:center; margin-top:2em; color:#64748b; font-size:0.98em; padding-bottom:1.5em;">
|
||||||
Dies ist ein werbe- und trackingfreier <a href="https://codeberg.org/elpatron/datecalc/src/branch/main/README.md" target="_blank" style="color:#2563eb; text-decoration:underline;">Open Source Datumsrechner</a><br>
|
Dies ist ein werbe- und trackingfreier <a href="https://codeberg.org/elpatron/datecalc/src/branch/main/README.md" target="_blank" style="color:#2563eb; text-decoration:underline;">Open Source Datumsrechner</a><br>
|
||||||
<a href="/api-docs" target="_blank" style="color:#2563eb; text-decoration:underline;">REST API Dokumentation (Swagger)</a><br>
|
<a href="/api-docs" target="_blank" style="color:#2563eb; text-decoration:underline;">REST API Dokumentation (Swagger)</a><br>
|
||||||
|
Reference in New Issue
Block a user