{% import '_icons.html' as icons %} {# Shared recursive course-outline renderer - one section/lesson tree markup used by both the loaded-course dashboard view and the lesson page's sidebar, so the two stay visually and behaviorally in sync instead of drifting apart as separate copies. Needs `toggleTree()` (JS) and the .tree-*/.lesson-*/.status-icon/.watched-badge CSS to be defined by whichever page imports this - see course_dashboard.html for the canonical versions. Flat list styling (no per-row box/border), a leading chevron that doubles as the expand affordance instead of a separate right-edge button, and indentation for hierarchy - the chevron's rotation is driven purely by CSS (:has(+ .tree-content.expanded)), so toggling is just adding/removing one class on .tree-content; nothing in JS ever touches the icon directly. `current_lesson` (a Lesson object, not a path string) is optional - when given, the matching row gets a `current` class instead of being a plain click target, and stays unclickable since you're already there. Path-string comparison isn't used for this because the lesson page's incoming URL can be in several different formats (see find_lesson_in_tree) - comparing lesson.path (the raw absolute filesystem path, always unique and unambiguous) sidesteps all of that. #} {% macro render_tree_node(node, course_path, current_lesson=none, depth=0) %} {% set stats = section_stats(node) %}