diff --git a/workspace/assets/css/aufgaben.css b/workspace/assets/css/aufgaben.css index b767050a..1acee8a7 100644 --- a/workspace/assets/css/aufgaben.css +++ b/workspace/assets/css/aufgaben.css @@ -26,9 +26,27 @@ border-radius: var(--radius); } .neu__zeile { margin-bottom: 14px; } +/* Zwoelf Spalten statt auto-fit: Damit laesst sich sagen, WIE breit ein + Feld sein soll -- ein Titel braucht die ganze Zeile, eine Stufe ein + Drittel. auto-fit gab jedem Feld dieselbe Breite, egal was drin steht. */ .neu__raster { - display: grid; gap: 14px; margin-bottom: 8px; - grid-template-columns: repeat(auto-fit, minmax(170px, 1fr)); + display: grid; gap: 14px 16px; margin-bottom: 8px; + grid-template-columns: repeat(12, 1fr); +} +/* Vorgabe: ein Drittel. Reicht fuer Auswahlfelder und Datumsangaben. */ +.neu__raster > .feld { grid-column: span 4; min-width: 0; } + +/* Diese Klasse stand in drei HTML-Dateien, war aber NIE definiert -- + deshalb quetschte das Raster jedes Feld in dieselbe Breite und lange + Kategorienamen wurden abgeschnitten. */ +.neu__raster > .feld--breit { grid-column: 1 / -1; } +.neu__raster > .feld--halb { grid-column: span 6; } + +@media (max-width: 860px) { + .neu__raster > .feld { grid-column: span 6; } +} +@media (max-width: 560px) { + .neu__raster > .feld, .neu__raster > .feld--halb { grid-column: 1 / -1; } } .neu__knoepfe { display: flex; gap: 10px; align-items: center; margin-top: 12px; } diff --git a/workspace/assets/css/wissen.css b/workspace/assets/css/wissen.css index 6940ebf5..094c2604 100644 --- a/workspace/assets/css/wissen.css +++ b/workspace/assets/css/wissen.css @@ -206,31 +206,94 @@ /* ---------- Formular ---------------------------------------------------------- */ -.haken { display: flex; align-items: center; gap: 9px; font-size: .87rem; cursor: pointer; } -.haken input { width: 17px; height: 17px; accent-color: var(--akzent); cursor: pointer; } +/* ---------- Ablagefläche für die PDF ------------------------------------ + Ein nacktes sah aus wie ein Fremdkörper und der + Knopf wurde vom Browser abgeschnitten ("K..."). Eine eigene Fläche + nimmt auch gezogene Dateien an -- der Weg, den man ohnehin erwartet. */ -.tag-vorschlag { display: flex; gap: 6px; flex-wrap: wrap; margin-top: 8px; } +.pdf-ablage { + display: grid; place-items: center; gap: 5px; + padding: 26px 20px; cursor: pointer; + border: 1px dashed rgba(255, 255, 255, .2); + border-radius: var(--radius); + background: rgba(255, 255, 255, .022); + transition: border-color .18s ease, background .18s ease; +} +.pdf-ablage:hover, .pdf-ablage:focus-visible { + outline: none; + border-color: rgba(63, 189, 245, .55); + background: rgba(63, 189, 245, .06); +} +.pdf-ablage[data-drueber="ja"] { + border-color: var(--akzent); border-style: solid; + background: rgba(63, 189, 245, .1); +} +.pdf-ablage[data-fertig="ja"] { + border-style: solid; border-color: rgba(95, 201, 154, .45); + background: rgba(95, 201, 154, .07); +} +.pdf-ablage__zeichen { + width: 26px; height: 26px; + fill: none; stroke: var(--text-still); stroke-width: 1.6; + stroke-linecap: round; stroke-linejoin: round; +} +.pdf-ablage[data-fertig="ja"] .pdf-ablage__zeichen { stroke: #5fc99a; } +.pdf-ablage__text { margin: 0; font-size: .92rem; color: var(--text-leise); text-align: center; } +.pdf-ablage__text strong { color: var(--akzent); } +.pdf-ablage__klein { margin: 0; font-size: .77rem; color: var(--text-still); } + +/* ---------- Schalter „besonders wichtig“ --------------------------------- + Ein Kästchen von 17 Pixeln ist auf dem Handy kaum zu treffen und sagt + nicht, was passiert. Der Schalter ist groß, zeigt seinen Zustand und + erklärt sich in einer Zeile. */ + +.schalter { + display: flex; align-items: flex-start; gap: 14px; + margin-top: 18px; padding: 14px 16px; cursor: pointer; + border: 1px solid var(--rand); border-radius: var(--radius); + background: rgba(255, 255, 255, .022); + transition: border-color .18s ease, background .18s ease; +} +.schalter:hover { border-color: rgba(255, 255, 255, .2); } +.schalter input { position: absolute; opacity: 0; width: 0; height: 0; } +.schalter__gleis { + flex: none; position: relative; width: 42px; height: 24px; margin-top: 1px; + border-radius: 999px; + background: rgba(255, 255, 255, .1); + border: 1px solid var(--rand); + transition: background .2s ease, border-color .2s ease; +} +.schalter__punkt { + position: absolute; left: 3px; top: 3px; width: 16px; height: 16px; + border-radius: 50%; background: var(--text-still); + transition: transform .2s ease, background .2s ease; +} +.schalter input:checked + .schalter__gleis { + background: rgba(232, 192, 125, .3); + border-color: rgba(232, 192, 125, .6); +} +.schalter input:checked + .schalter__gleis .schalter__punkt { + transform: translateX(18px); background: #e8c07d; +} +.schalter input:focus-visible + .schalter__gleis { + box-shadow: 0 0 0 3px rgba(232, 192, 125, .28); +} +.schalter:has(input:checked) { + border-color: rgba(232, 192, 125, .35); + background: rgba(232, 192, 125, .05); +} +.schalter__text { display: grid; gap: 2px; font-size: .88rem; } +.schalter__text .leise { font-size: .79rem; } + +.tag-vorschlag { display: flex; gap: 5px; flex-wrap: wrap; margin-top: 8px; } .tag-knopf { - padding: 4px 10px; cursor: pointer; + padding: 3px 9px; cursor: pointer; font-size: .73rem; background: transparent; border: 1px dashed var(--rand); border-radius: 999px; - color: var(--text-still); font: inherit; font-size: .74rem; + color: var(--text-still); font-family: inherit; transition: color .16s ease, border-color .16s ease; } .tag-knopf:hover { color: var(--akzent); border-color: rgba(63, 189, 245, .45); border-style: solid; } -#n-datei { - width: 100%; padding: 10px 12px; - background: rgba(255, 255, 255, .04); - border: 1px dashed var(--rand); border-radius: var(--radius-klein); - color: var(--text-leise); font: inherit; font-size: .85rem; cursor: pointer; -} -#n-datei::file-selector-button { - margin-right: 12px; padding: 6px 13px; cursor: pointer; - background: rgba(63, 189, 245, .12); - border: 1px solid rgba(63, 189, 245, .3); border-radius: 8px; - color: var(--akzent); font: inherit; font-size: .8rem; font-weight: 600; -} - .leer-hinweis { display: grid; gap: 12px; justify-items: center; padding: 34px 22px; margin-bottom: 26px; text-align: center; @@ -247,6 +310,7 @@ } @media (prefers-reduced-motion: reduce) { - .kachel, .pdf, .marke-tag, .tag-knopf { transition: none; } + .kachel, .pdf, .marke-tag, .tag-knopf, .pdf-ablage, + .schalter, .schalter__gleis, .schalter__punkt { transition: none; } .kachel:hover { transform: none; } } diff --git a/workspace/assets/js/wissen.js b/workspace/assets/js/wissen.js index 4465430c..503caed0 100644 --- a/workspace/assets/js/wissen.js +++ b/workspace/assets/js/wissen.js @@ -339,7 +339,7 @@ $('neu-block').hidden = true; $('neu-auf').hidden = !aufbau.darf_pflegen; $('neu-form').reset(); - $('n-dateiname').textContent = 'Höchstens 40 MB. Nur echte PDF-Dateien.'; + zeigeDatei(); bearbeite = null; } @@ -374,11 +374,57 @@ $('neu-auf').addEventListener('click', () => formularOeffnen(null)); $('neu-zu').addEventListener('click', formularSchliessen); - $('n-datei').addEventListener('change', () => { + /* ---------- Ablagefläche ---------------------------------------------- */ + + const ablage = $('n-ablage'); + + function zeigeDatei() { const d = $('n-datei').files[0]; - $('n-dateiname').textContent = d - ? `${d.name} · ${groesse(d.size)}` - : 'Höchstens 40 MB. Nur echte PDF-Dateien.'; + const text = $('n-dateiname'); + text.textContent = ''; + if (!d) { + text.append(document.createTextNode('PDF hierher ziehen oder ')); + text.append(el('strong', null, 'auswählen')); + delete ablage.dataset.fertig; + return; + } + text.append(el('strong', null, d.name)); + text.append(document.createTextNode(' · ' + groesse(d.size))); + ablage.dataset.fertig = 'ja'; + /* Ist der Titel noch leer, den Dateinamen als Vorschlag nehmen -- + er ist fast immer schon die halbe Miete. */ + if (!$('n-titel').value.trim()) { + $('n-titel').value = d.name.replace(/\.pdf$/i, '').replace(/[_-]+/g, ' ').trim().slice(0, 140); + } + } + + function nimmDatei(d) { + if (!d) return; + if (!/\.pdf$/i.test(d.name) && d.type !== 'application/pdf') { + $('n-fehler').textContent = 'Das ist keine PDF-Datei.'; + return; + } + const dt = new DataTransfer(); + dt.items.add(d); + $('n-datei').files = dt.files; + $('n-fehler').textContent = ''; + zeigeDatei(); + } + + ablage.addEventListener('click', () => $('n-datei').click()); + ablage.addEventListener('keydown', (e) => { + if (e.key === 'Enter' || e.key === ' ') { e.preventDefault(); $('n-datei').click(); } + }); + $('n-datei').addEventListener('change', zeigeDatei); + for (const art of ['dragenter', 'dragover']) { + ablage.addEventListener(art, (e) => { e.preventDefault(); ablage.dataset.drueber = 'ja'; }); + } + for (const art of ['dragleave', 'drop']) { + ablage.addEventListener(art, () => { delete ablage.dataset.drueber; }); + } + ablage.addEventListener('drop', (e) => { + e.preventDefault(); + nimmDatei(e.dataTransfer?.files?.[0]); }); $('neu-form').addEventListener('submit', async (e) => { diff --git a/workspace/aufgaben.html b/workspace/aufgaben.html index 0921d593..ea1f4cce 100644 --- a/workspace/aufgaben.html +++ b/workspace/aufgaben.html @@ -7,9 +7,9 @@ - - - + + + @@ -134,7 +134,7 @@ - - + + diff --git a/workspace/bereich.html b/workspace/bereich.html index 4d13b036..e84ac3d4 100644 --- a/workspace/bereich.html +++ b/workspace/bereich.html @@ -7,10 +7,10 @@ - - - - + + + + @@ -98,7 +98,7 @@ - - + + diff --git a/workspace/calls.html b/workspace/calls.html index 4e55e111..7622bb7f 100644 --- a/workspace/calls.html +++ b/workspace/calls.html @@ -7,10 +7,10 @@ - - - - + + + + @@ -49,7 +49,7 @@ - - + + diff --git a/workspace/dateien.html b/workspace/dateien.html index 766abea7..241611c1 100644 --- a/workspace/dateien.html +++ b/workspace/dateien.html @@ -7,10 +7,10 @@ - - - - + + + + @@ -88,7 +88,7 @@ - - + + diff --git a/workspace/index.html b/workspace/index.html index ee953414..402eb106 100644 --- a/workspace/index.html +++ b/workspace/index.html @@ -25,7 +25,7 @@ type="image/webp" media="(max-width: 899px)" /> - + @@ -130,6 +130,6 @@

- + diff --git a/workspace/kalender.html b/workspace/kalender.html index 51b915b8..cb87db37 100644 --- a/workspace/kalender.html +++ b/workspace/kalender.html @@ -7,10 +7,10 @@ - - - - + + + + @@ -94,7 +94,7 @@ - - + + diff --git a/workspace/personen.html b/workspace/personen.html index 9981a746..231f5e0a 100644 --- a/workspace/personen.html +++ b/workspace/personen.html @@ -7,10 +7,10 @@ - - - - + + + + @@ -87,7 +87,7 @@ - - + + diff --git a/workspace/profil.html b/workspace/profil.html index 54bea75f..21a4f993 100644 --- a/workspace/profil.html +++ b/workspace/profil.html @@ -7,10 +7,10 @@ - - - - + + + + @@ -127,7 +127,7 @@ - - + + diff --git a/workspace/report.html b/workspace/report.html index 655afc2d..7ca5da71 100644 --- a/workspace/report.html +++ b/workspace/report.html @@ -7,10 +7,10 @@ - - - - + + + + @@ -86,7 +86,7 @@ - - + + diff --git a/workspace/scouting.html b/workspace/scouting.html index a745ade7..d9611ada 100644 --- a/workspace/scouting.html +++ b/workspace/scouting.html @@ -7,10 +7,10 @@ - - - - + + + + @@ -124,7 +124,7 @@ - - + + diff --git a/workspace/start.html b/workspace/start.html index 07e0d387..77fcd6a7 100644 --- a/workspace/start.html +++ b/workspace/start.html @@ -7,8 +7,8 @@ - - + + @@ -56,7 +56,7 @@

- - + + diff --git a/workspace/startcheck.html b/workspace/startcheck.html index 325aaa70..606ee080 100644 --- a/workspace/startcheck.html +++ b/workspace/startcheck.html @@ -7,10 +7,10 @@ - - - - + + + + @@ -65,7 +65,7 @@ - - + + diff --git a/workspace/wissen.html b/workspace/wissen.html index 0d78c7d1..968af94f 100644 --- a/workspace/wissen.html +++ b/workspace/wissen.html @@ -7,10 +7,10 @@ - - - - + + + + @@ -93,6 +93,22 @@