diff --git a/Makefile b/Makefile
index c08275c..3c707b8 100644
--- a/Makefile
+++ b/Makefile
@@ -190,7 +190,8 @@ HDM_DEPLOY_PATH = /home/tengo/html/hdm
build-index: build/.exists
@echo "Building root index..."
- @echo '
HdM VorlesungenHdM Vorlesungen
Wintersemester 2025/26 · Michael Czechowski
Referenzen

https://librete.ch/hdm/
' > build/index.html
+ @mkdir -p build
+ @./scripts/generate-root-index.sh
# Deploy
define deploy_course
diff --git a/scripts/generate-index.sh b/scripts/generate-index.sh
index 354455a..ceaa889 100755
--- a/scripts/generate-index.sh
+++ b/scripts/generate-index.sh
@@ -42,6 +42,15 @@ TOPIC_MAP["geschichte-grundlagen-html"]="Geschichte, Grundlagen & HTML"
TOPIC_MAP["netzwerke-protokolle-css"]="Netzwerke, Protokolle & CSS"
TOPIC_MAP["interaktivitaet-javascript"]="Interaktivität & JavaScript"
+# Configure which topics should appear disabled per course
+# Two modes: fully disabled (non-clickable card) and buttons-disabled (link remains clickable, buttons are disabled)
+declare -A DISABLED_FULL
+declare -A DISABLED_BUTTONS
+# For course B: chapters 3,4,5 should be fully disabled
+DISABLED_FULL["223015b"]="speichermedien-schnittstellen distribution-apis-zukunft vertiefung-offene-fragen"
+# For course C: chapter 3 should keep link clickable but buttons disabled
+DISABLED_BUTTONS["223015c"]="interaktivitaet-javascript"
+
cat > "$BUILD_DIR/index.html" << HEADER
@@ -61,6 +70,15 @@ cat > "$BUILD_DIR/index.html" << HEADER
line-height: 1.5;
}
header { margin-bottom: 2rem; }
+ .breadcrumb {
+ margin-bottom: 1rem;
+ font-size: 0.85rem;
+ }
+ .breadcrumb a {
+ color: #86868b;
+ text-decoration: none;
+ }
+ .breadcrumb a:hover { text-decoration: underline; }
h1 {
font-size: 1.75rem;
font-weight: 600;
@@ -68,6 +86,12 @@ cat > "$BUILD_DIR/index.html" << HEADER
margin-bottom: 0.5rem;
color: $ACCENT_COLOR;
}
+ .course-heading {
+ font-size: 1.25rem;
+ font-weight: 500;
+ color: #1d1d1f;
+ margin-bottom: 0.25rem;
+ }
.subtitle {
color: #86868b;
font-size: 0.95rem;
@@ -77,7 +101,8 @@ cat > "$BUILD_DIR/index.html" << HEADER
font-size: 0.875rem;
margin-top: 0.25rem;
}
- .kapitel {
+ /* Use the .termine wrapper and add a gap between cards */
+ .termine {
margin-top: 1.5rem;
display: flex;
flex-direction: column;
@@ -93,6 +118,7 @@ cat > "$BUILD_DIR/index.html" << HEADER
grid-template-columns: 1fr auto auto;
align-items: center;
gap: 1rem;
+ padding: 0; /* inner padding handled by kapitel-link */
}
.kapitel-card:hover {
transform: translateY(-2px);
@@ -105,6 +131,8 @@ cat > "$BUILD_DIR/index.html" << HEADER
color: inherit;
grid-column: 1;
}
+ /* Disabled look: dim the entire card and prevent pointer events */
+ .kapitel-card.disabled { opacity: 0.6; pointer-events: none; }
.kapitel-label {
font-size: 0.7rem;
font-weight: 600;
@@ -135,11 +163,11 @@ cat > "$BUILD_DIR/index.html" << HEADER
white-space: nowrap;
position: relative;
z-index: 1;
+ margin-right: 0.5rem;
}
.btn-slides {
background: $ACCENT_COLOR;
color: #fff;
- margin-right: 0.5rem;
}
.btn-slides:hover {
filter: brightness(1.1);
@@ -147,9 +175,9 @@ cat > "$BUILD_DIR/index.html" << HEADER
.btn-pdf {
background: #f5f5f7;
color: #1d1d1f;
- margin-right: 1rem;
}
.btn-pdf:hover { background: #e8e8ed; }
+ .btn-disabled { opacity: 0.6; pointer-events: none; }
/* Make entire card clickable via overlay */
.kapitel-link::after {
content: '';
@@ -198,7 +226,9 @@ cat > "$BUILD_DIR/index.html" << HEADER
@@ -216,7 +246,7 @@ for html in $(ls "$BUILD_DIR"/[0-9][0-9]-*.html 2>/dev/null | sort); do
# Look up nice topic name or fallback
topic="${TOPIC_MAP[$topic_raw]}"
if [[ -z "$topic" ]]; then
- topic=$(echo "$topic_raw" | sed 's/-/ /g' | sed 's/.*/\u&/')
+ topic=$(echo "$topic_raw" | sed 's/-/ /g' | sed 's/.*/\\u&/')
fi
# Handle kapitel number
@@ -228,22 +258,66 @@ for html in $(ls "$BUILD_DIR"/[0-9][0-9]-*.html 2>/dev/null | sort); do
pdf_filename="${filename%.html}.pdf"
- # Check if PDF exists
- pdf_link=""
- if [[ -f "$BUILD_DIR/$pdf_filename" ]]; then
- pdf_link="PDF"
+ # Determine whether this topic is configured as disabled for this course
+ disabled_full=false
+ disabled_buttons=false
+ for t in ${DISABLED_FULL["$COURSE"]}; do
+ if [[ "$topic_raw" == "$t" ]]; then
+ disabled_full=true
+ break
+ fi
+ done
+ if [[ "$disabled_full" == false ]]; then
+ for t in ${DISABLED_BUTTONS["$COURSE"]}; do
+ if [[ "$topic_raw" == "$t" ]]; then
+ disabled_buttons=true
+ break
+ fi
+ done
+ fi
+
+ # Decide card class
+ card_class="kapitel-card"
+ if [[ "$disabled_full" == true ]] || [[ "$disabled_buttons" == true ]]; then
+ card_class="$card_class disabled"
+ fi
+
+ # Build link/button HTML depending on disabled state
+ if [[ "$disabled_full" == true ]]; then
+ # non-interactive card (visually dimmed and not clickable)
+ link_html=""
+ slides_html="Folien"
+ pdf_html=""
+ if [[ -f "$BUILD_DIR/$pdf_filename" ]]; then
+ pdf_html="PDF"
+ fi
+ elif [[ "$disabled_buttons" == true ]]; then
+ # link stays clickable, but buttons are disabled; card appears dimmed
+ link_html="$kapitel_label
$topic
"
+ slides_html="Folien"
+ pdf_html=""
+ if [[ -f "$BUILD_DIR/$pdf_filename" ]]; then
+ pdf_html="PDF"
+ fi
+ else
+ # normal interactive card
+ pdf_link=""
+ if [[ -f "$BUILD_DIR/$pdf_filename" ]]; then
+ pdf_link="PDF"
+ fi
+ link_html="$kapitel_label
$topic
"
+ slides_html="Folien"
+ pdf_html="$pdf_link"
fi
cat >> "$BUILD_DIR/index.html" << LINK
-
-
- $kapitel_label
- $topic
-
-
Folien
- $pdf_link
+
+ $link_html
+ $slides_html
+ $pdf_html
LINK
+
done
# Add klausurfolien entry if it exists
@@ -264,6 +338,28 @@ if [[ -f "$BUILD_DIR/klausurfolien.html" ]]; then
KLAUSUR
fi
+# Add klausurfragen entry if it exists (HTML and/or PDF)
+if [[ -f "$BUILD_DIR/klausurfragen.html" ]] || [[ -f "$BUILD_DIR/klausurfragen.pdf" ]]; then
+ pdf_link=""
+ if [[ -f "$BUILD_DIR/klausurfragen.pdf" ]]; then
+ pdf_link="
PDF"
+ fi
+ slides_link=""
+ if [[ -f "$BUILD_DIR/klausurfragen.html" ]]; then
+ slides_link="
Folien"
+ fi
+ cat >> "$BUILD_DIR/index.html" << KLAUSURFRAGEN
+
+KLAUSURFRAGEN
+fi
+
cat >> "$BUILD_DIR/index.html" << FOOTER
@@ -272,7 +368,7 @@ cat >> "$BUILD_DIR/index.html" << FOOTER