diff --git a/frontend/src/app.css b/frontend/src/app.css
index ab83190..bea00ec 100644
--- a/frontend/src/app.css
+++ b/frontend/src/app.css
@@ -1425,6 +1425,29 @@ button.capture-shell__nav-item {
.admin-catalog-section {
padding: 14px;
}
+
+ .exercises-page-toolbar-tabs,
+ .skills-page__tabs-scroll {
+ margin-left: calc(-1 * max(12px, env(safe-area-inset-left, 0px)));
+ margin-right: calc(-1 * max(12px, env(safe-area-inset-right, 0px)));
+ padding-left: max(12px, env(safe-area-inset-left, 0px));
+ padding-right: max(12px, env(safe-area-inset-right, 0px));
+ padding-bottom: 4px;
+ overflow-x: auto;
+ -webkit-overflow-scrolling: touch;
+ scrollbar-width: none;
+ }
+
+ .exercises-page-toolbar-tabs::-webkit-scrollbar,
+ .skills-page__tabs-scroll::-webkit-scrollbar {
+ display: none;
+ }
+
+ .exercises-page-mode-switch,
+ .skills-page-mode-switch {
+ width: max(100%, min(20rem, 100vw - 24px));
+ max-width: none;
+ }
}
/* Trainingsplanung: kompakte Segmente (Gruppe / Verein) */
@@ -2302,6 +2325,427 @@ button.capture-shell__nav-item {
overscroll-behavior: contain;
}
+.skills-page-modal.admin-modal-sheet {
+ max-width: min(600px, 100vw - 32px);
+}
+
+/* Admin Hierarchie: Detail-Panel */
+.detail-panel__title {
+ margin-top: 0;
+}
+.detail-panel__actions {
+ display: flex;
+ flex-wrap: wrap;
+ gap: 8px;
+ margin-top: 20px;
+}
+.detail-panel__context {
+ padding: 12px;
+ margin-bottom: 20px;
+ border-radius: 8px;
+ background: var(--surface2);
+ color: var(--text2);
+}
+.detail-panel__unknown {
+ padding: 20px;
+ color: var(--text3);
+}
+
+/* Seite Fähigkeiten & Methoden */
+.skills-page__loading {
+ padding: 2rem;
+ text-align: center;
+}
+.skills-page__tabs-scroll {
+ margin-bottom: 1.5rem;
+}
+.skills-page__intro-row {
+ display: flex;
+ flex-wrap: wrap;
+ justify-content: space-between;
+ align-items: flex-start;
+ gap: 12px;
+ margin-bottom: 1rem;
+}
+.skills-page__intro-row p {
+ margin: 0;
+ flex: 1 1 12rem;
+ color: var(--text2);
+}
+.skills-page__empty {
+ margin: 0;
+ text-align: center;
+ color: var(--text2);
+}
+.skills-page__category {
+ margin-bottom: 2rem;
+}
+.skills-page__category-title {
+ margin: 0 0 1rem;
+ text-transform: capitalize;
+}
+.skills-page__card-grid {
+ display: grid;
+ grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
+ gap: 1rem;
+}
+.skills-page__card-grid--methods {
+ grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
+}
+.skills-page-card {
+ display: flex;
+ flex-direction: column;
+ height: 100%;
+}
+.skills-page-card__head {
+ display: flex;
+ justify-content: space-between;
+ align-items: flex-start;
+ gap: 8px;
+ margin-bottom: 0.5rem;
+}
+.skills-page-card__meta-block {
+ margin-bottom: 0.5rem;
+}
+.skills-page-card__title {
+ margin: 0;
+ font-size: 1rem;
+}
+.skills-page-card__title--method {
+ margin: 0 0 0.25rem;
+}
+.skills-page-card__abbr {
+ color: var(--text2);
+ font-size: 0.875rem;
+ margin-left: 0.5rem;
+ font-weight: 400;
+}
+.skills-page-card__badge {
+ flex-shrink: 0;
+ font-size: 0.875rem;
+ padding: 0.25rem 0.5rem;
+ border-radius: 4px;
+ background: var(--accent);
+ color: #fff;
+}
+.skills-page-card__meta-row {
+ display: flex;
+ flex-wrap: wrap;
+ gap: 0.5rem;
+}
+.skills-page-card__chip {
+ font-size: 0.75rem;
+ padding: 0.25rem 0.5rem;
+ border-radius: 4px;
+ background: var(--surface2);
+ color: var(--text2);
+}
+.skills-page-card__desc {
+ margin: 0 0 1rem;
+ color: var(--text2);
+ font-size: 0.875rem;
+}
+.skills-page-card__actions {
+ display: flex;
+ gap: 0.5rem;
+ margin-top: auto;
+}
+.skills-page-card__grow {
+ flex: 1;
+}
+.skills-page-modal__footer {
+ display: flex;
+ flex-wrap: wrap;
+ gap: 0.5rem;
+ margin-top: 1.5rem;
+}
+.skills-page-modal__submit {
+ flex: 1;
+}
+
+/* Übungsliste: Kopf, Modus-Segmente, Hinweise */
+.exercises-page__header {
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ margin-bottom: 12px;
+ flex-wrap: wrap;
+ gap: 8px;
+}
+.exercises-page__title {
+ margin: 0;
+}
+.exercises-page-toolbar-tabs {
+ margin-bottom: 14px;
+}
+.exercises-page-mode-switch,
+.skills-page-mode-switch {
+ width: 100%;
+ max-width: min(100%, 28rem);
+}
+.exercise-search-hint {
+ font-size: 12px;
+ color: var(--text3);
+ margin-top: 10px;
+ margin-bottom: 0;
+ line-height: 1.45;
+}
+.exercise-search-hint .btn {
+ margin-left: 6px;
+ vertical-align: middle;
+}
+.exercise-search-bar {
+ margin-bottom: 12px;
+}
+.exercise-search-bar__primary {
+ margin-bottom: 10px;
+}
+.exercise-bulk-toolbar {
+ margin-bottom: 12px;
+ display: flex;
+ flex-wrap: wrap;
+ align-items: center;
+ gap: 10px;
+}
+.exercise-bulk-toolbar__meta {
+ font-size: 12px;
+ color: var(--text3);
+ line-height: 1.4;
+ flex: 1 1 200px;
+}
+.exercises-list-grid {
+ display: grid;
+ grid-template-columns: repeat(auto-fill, minmax(min(100%, 280px), 1fr));
+ gap: 12px;
+}
+.exercise-card-layout {
+ display: flex;
+ gap: 10px;
+ align-items: flex-start;
+}
+.exercise-card-layout__check {
+ margin-top: 4px;
+ flex-shrink: 0;
+ accent-color: var(--accent);
+}
+.exercise-card-body-flex {
+ flex: 1;
+ min-width: 0;
+}
+.exercise-card-title {
+ margin: 0 0 8px;
+ font-size: 1.05rem;
+ line-height: 1.3;
+ font-weight: 700;
+}
+.exercise-card-title a {
+ color: inherit;
+ text-decoration: none;
+}
+.exercise-card-title a:hover {
+ color: var(--accent-dark);
+}
+@media (prefers-color-scheme: dark) {
+ .exercise-card-title a:hover {
+ color: var(--accent);
+ }
+}
+.exercise-card-tags {
+ display: flex;
+ gap: 6px;
+ flex-wrap: wrap;
+ margin-bottom: 8px;
+}
+.exercise-card-summary {
+ color: var(--text2);
+ font-size: 13px;
+ line-height: 1.4;
+ margin: 0;
+}
+.exercises-meta-line {
+ font-size: 13px;
+ color: var(--text2);
+ margin: 0 0 10px;
+}
+.exercises-meta-line--muted {
+ color: var(--text3);
+ margin-bottom: 8px;
+}
+.exercises-load-more {
+ text-align: center;
+ margin-top: 16px;
+}
+.exercises-empty-text {
+ margin: 0;
+ color: var(--text2);
+ text-align: center;
+}
+
+/* Admin Hierarchie-Baum (Fokusbereich) */
+.focus-tree-root {
+ margin-bottom: 12px;
+}
+.focus-tree-header {
+ display: flex;
+ align-items: stretch;
+ gap: 2px;
+ padding: 4px 4px 4px 6px;
+ border-radius: 10px;
+ border: 1px solid transparent;
+ background: transparent;
+ transition: background 0.12s, border-color 0.12s;
+}
+.focus-tree-header:hover {
+ background: var(--surface2);
+ border-color: var(--border);
+}
+.focus-tree-header--selected {
+ background: var(--accent);
+ border-color: var(--accent);
+}
+.focus-tree-header--selected:hover {
+ background: color-mix(in srgb, var(--accent) 94%, #000);
+ border-color: var(--accent);
+}
+.focus-tree-toggle {
+ flex-shrink: 0;
+ display: inline-flex;
+ align-items: center;
+ justify-content: center;
+ width: 32px;
+ min-height: 36px;
+ margin: 0;
+ padding: 0;
+ border: none;
+ border-radius: 8px;
+ background: transparent;
+ color: var(--text2);
+ cursor: pointer;
+ align-self: center;
+ -webkit-tap-highlight-color: transparent;
+}
+.focus-tree-toggle:hover {
+ background: rgba(0, 0, 0, 0.05);
+}
+.focus-tree-header--selected .focus-tree-toggle {
+ color: #fff;
+}
+.focus-tree-header--selected .focus-tree-toggle:hover {
+ background: rgba(255, 255, 255, 0.12);
+}
+.focus-tree-header__label {
+ flex: 1;
+ min-width: 0;
+ display: flex;
+ align-items: center;
+ gap: 6px;
+ padding: 6px 8px 6px 2px;
+ margin: 0;
+ border: none;
+ background: transparent;
+ color: inherit;
+ font: inherit;
+ font-weight: 600;
+ text-align: left;
+ cursor: pointer;
+ border-radius: 8px;
+ -webkit-tap-highlight-color: transparent;
+}
+.focus-tree-emoji {
+ flex-shrink: 0;
+ line-height: 1;
+}
+.focus-tree-children {
+ margin-top: 8px;
+ margin-left: 8px;
+ padding-left: 12px;
+ border-left: 2px solid var(--border);
+}
+.focus-tree-group {
+ margin-bottom: 12px;
+}
+.focus-tree-group:last-child {
+ margin-bottom: 0;
+}
+.focus-tree-group__head {
+ font-size: 11px;
+ font-weight: 700;
+ letter-spacing: 0.04em;
+ color: var(--text3);
+ margin-bottom: 6px;
+ text-transform: uppercase;
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ gap: 8px;
+}
+.focus-tree-add-btn {
+ flex-shrink: 0;
+}
+.focus-tree-item {
+ padding: 8px 12px;
+ margin-bottom: 4px;
+ border-radius: 8px;
+ cursor: pointer;
+ background: var(--surface2);
+ color: var(--text1);
+ font-size: 14px;
+ border: 1px solid var(--border);
+ line-height: 1.35;
+ transition: background 0.12s, border-color 0.12s, color 0.12s;
+}
+.focus-tree-item:last-child {
+ margin-bottom: 0;
+}
+.focus-tree-item:hover {
+ border-color: var(--accent);
+}
+.focus-tree-item--selected {
+ background: var(--accent);
+ color: #fff;
+ border-color: var(--accent);
+}
+.focus-tree-item--selected:hover {
+ border-color: var(--accent);
+}
+.focus-tree-item__abbr {
+ margin-left: 8px;
+ font-size: 12px;
+ opacity: 0.85;
+}
+.focus-tree-item__meta {
+ font-size: 11px;
+ margin-top: 4px;
+ line-height: 1.35;
+ opacity: 0.88;
+}
+.focus-tree-item--selected .focus-tree-item__abbr,
+.focus-tree-item--selected .focus-tree-item__meta {
+ opacity: 0.95;
+ color: #fff;
+}
+
+@media (max-width: 1023px) {
+ .exercise-filter-chips-row {
+ flex-wrap: nowrap;
+ overflow-x: auto;
+ padding-bottom: 4px;
+ margin-left: -2px;
+ margin-right: -2px;
+ padding-left: 2px;
+ padding-right: 2px;
+ -webkit-overflow-scrolling: touch;
+ scrollbar-width: none;
+ }
+ .exercise-filter-chips-row::-webkit-scrollbar {
+ display: none;
+ }
+ .focus-tree-children {
+ margin-left: 4px;
+ padding-left: 8px;
+ }
+}
+
.exercise-filter-modal.admin-modal-sheet {
max-width: min(920px, calc(100dvw - 16px));
}
diff --git a/frontend/src/components/admin/DetailPanel.jsx b/frontend/src/components/admin/DetailPanel.jsx
index 4de3552..d4726be 100644
--- a/frontend/src/components/admin/DetailPanel.jsx
+++ b/frontend/src/components/admin/DetailPanel.jsx
@@ -20,7 +20,7 @@ function DetailPanel({ item, onUpdate, focusAreas }) {
return
Lade Kataloge…
++ Lade Kataloge… +
++
Trefferliste aktualisiert sich kurz nach Eingabe. Titel der aktuellen Liste erscheinen als Vorschläge (Pfeil im Feld). Fachliche Filter über „Filter“ – zwischen Feldern UND, Auswahl mehrerer Werte je Feld mit ODER. {exercises.length > 0 ? ( <> {' '} -
X-Active-Club-Id
).
@@ -736,7 +725,7 @@ function ExercisesListPage() {
+
Zwischen den Bereichen gilt UND. Innerhalb eines Feldes werden mehrere Einträge mit{' '} ODER verknüpft.
@@ -900,12 +889,12 @@ function ExercisesListPage() {+
Es werden {selectedIds.size} Übung(en) aus der aktuellen Auswahl bearbeitet. Pro Durchlauf höchstens {BULK_MAX_IDS}. Ohne Berechtigung bleiben Einzelübungen unverändert (siehe Hinweis nach dem Speichern).
-+
Unter „Zuordnung ersetzen“: die gewählte Liste ersetzt die bisherige Zuordnung bei allen betroffenen Übungen vollständig (leere Auswahl = alle Zuordnungen dieser Kategorie entfernen). Die erste Auswahl gilt als Primärzuordnung. @@ -1066,7 +1055,7 @@ function ExercisesListPage() {
Lade Übungen…
++ Lade Übungen… +
- Keine Übungen gefunden. -
+Keine Übungen gefunden.
Aktualisiere Treffer…
+Aktualisiere Treffer…
) : null} -+
{exercises.length} angezeigt {hasMore ? ' · es gibt weitere Einträge' : ''}
-+
{exercise.summary.length > 160
? `${exercise.summary.slice(0, 160)}…`
: exercise.summary}
@@ -1154,12 +1134,7 @@ function ExercisesListPage() {
Laden...
+
Fähigkeiten sind Kompetenzen, die in Übungen trainiert werden.
{isAdmin && ( @@ -188,60 +186,46 @@ function SkillsPage() { {Object.keys(skillsByCategory).length === 0 ? (+
Keine Fähigkeiten gefunden
+
{skill.description}
)} {isAdmin && ( -+
Trainingsmethoden sind didaktische Ansätze für die Trainingsgestaltung.
{isAdmin && ( @@ -273,52 +257,36 @@ function SkillsPage() { {Object.keys(methodsByCategory).length === 0 ? (+
Keine Trainingsmethoden gefunden
+
{method.description}
)} {isAdmin && ( -