Back to Course Pipeline
Level 2 — Detail

HTML Templates & Module Architecture

How the Learning Skill course pages are structured: module layout, hero variants, navigation, interactive elements, and responsive design.

On this page
  • Module Structure — .module, .module-content, .module-header and the large numbers
  • Hero Templates — L0 Hero vs. L1-L3 Hero
  • Navigation Components — Breadcrumbs, Sibling Nav, Level Indicator & more
  • Interactive Elements — Code/Plain Text Toggle, Tooltips, Quiz, FAQ
  • Responsive & Integration Mode — Breakpoints and Standalone vs. Embedded
01
Module Structure
The foundational skeleton of every content section

Every course page consists of a sequence of .moduleA fullscreen section with scroll-snap-align: start that occupies the entire viewport height. sections. Each module is a self-contained content block with a large, faded number (01, 02, ...), a title, and a body area.

The CSS class hierarchy follows a fixed pattern:

ClassRoleDetails
.moduleOuter containermin-height: 100dvh, scroll-snap, alternating background
.module-contentCentered content areamax-width: 820px, horizontally centered
.module-headerNumber + TitleFlexbox, align-items: flex-start
.module-numberLarge faded numberopacity: .12, font-size: clamp(4rem,10vw,7rem)
.module-bodyBody text + codemax-width: 70ch on paragraphs
.screenOptional fullscreen containerUsed for individual "screens" within a module
<!-- The HTML template of a module --> <section class="module" id="mod1"> <div class="module-content"> <!-- Header: Large number + title --> <div class="module-header"> <span class="module-number">01</span> <div> <div class="module-title">Title here</div> <div class="module-subtitle">Subtitle</div> </div> </div> <!-- Body: Text, code blocks, toggles --> <div class="module-body"> <p>Module content...</p> <!-- Code block --> <div class="code-block"> <code>...</code> </div> </div> </div> </section> <!-- CSS: Alternating backgrounds --> .module:nth-child(odd) { background: #fff } .module:nth-child(even) { background: var(--color-warm-gray-bg) }

section.module is the outer container. It occupies at least the full viewport height (min-height: 100dvh) and uses scroll-snap-align: start so the browser gently snaps to module boundaries while scrolling.

.module-content limits content width to 820px and centers the block horizontally. This ensures optimal readability.

.module-number displays a decorative number (01, 02, ...) in a very large font size at only 12% opacity. It serves as a visual orientation aid, not navigation.

Alternating backgrounds: Odd modules get white, even modules get the warm gray tone #F3EFEB. This creates a subtle rhythm while scrolling.

02
Hero Templates
Two variants: L0 Hero and L1-L3 Hero

The Learning Skill uses two different hero variants. The L0 Hero (overview page) shows the skill title, an audience badge, and the module count. The L1-L3 Hero (detail pages) instead shows a back button, the level indicator, a page overview list, and the page title.

<!-- ========== L0 HERO (Overview Page) ========== --> <section class="hero" id="hero"> <div> <!-- Badge: Target audience --> <span class="hero-badge"> Developer Perspective </span> <!-- Title --> <h1>Learning Skill v2.0</h1> <!-- Subtitle --> <p class="hero-sub"> How the skill understands codebases and turns them into interactive courses. </p> <!-- Module counter --> <div class="hero-count"> 5 Modules · 15 min read </div> </div> </section>

L0 Hero is the entry page. It shows a .hero-badge with the target audience (User/Developer), the large skill title, a subtitle, and optionally a module counter.

No back button, no level indicator: L0 is the top level. Users arrive here, they don't navigate back from here.

Background: Always var(--color-deep-blue) (#000099) with white text.

<!-- ========== L1-L3 HERO (Detail Pages) ========== --> <section class="hero" id="hero"> <div> <!-- Back button: Link to parent page --> <a href="../l1/course-pipeline_dev_en.html" class="hero-back"> <svg viewBox="0 0 16 16"> <path d="M9.78 12.78a.75.75..."/> </svg> Back to Course Pipeline </a> <!-- Level indicator: 4 dots --> <div class="level-indicator"> <div class="level-dot done"></div> <!-- L0 --> <div class="level-dot done"></div> <!-- L1 --> <div class="level-dot active"></div> <!-- L2 = current --> <div class="level-dot empty"></div> <!-- L3 --> </div> <!-- Badge + Title --> <span class="hero-badge">Level 2 — Detail</span> <h1>HTML Templates & Module Architecture</h1> <p class="hero-sub">Description text...</p> <!-- Page overview --> <div class="page-overview"> <div class="page-overview-title"> On this page </div> <ul class="page-overview-list"> <li>Module Structure — ...</li> <li>Hero Templates — ...</li> <li>Navigation — ...</li> </ul> </div> </div> </section>

L1-L3 Hero always includes a back button (.hero-back) linking to the parent page. The SVG arrow points left.

Level Indicator: 4 dots that visually show the current level. .done = filled orange, .active = orange with white border + glow, .empty = transparent.

Page Overview: A compact table of contents with orange bullet points. Helps the reader quickly decide whether the page is relevant.

03
Navigation Components
Breadcrumbs, deep-dive links, sibling nav, and more

The Learning Skill navigation consists of several independent components that are combined depending on the page type. All live in the fixed .nav bar at the top of the screen.

.nav-breadcrumb Path display: L0 > L1 > L2 Only on L1-L3 pages
.nav-dots Module dots for jumping Generated via JS
.level-indicator 4 dots in the hero section done / active / empty
.sibling-nav Links to sibling pages Before footer, blue BG
.hero-back Back link in hero SVG arrow + text
.nav-right Language + GitHub icon Flag + SVG icon
<!-- ===== BREADCRUMB (L1-L3 Nav Bar) ===== --> <div class="nav-breadcrumb"> <a href="../index_dev_en.html">L0 Overview</a> <span class="sep">&#9656;</span> <a href="../l1/course-pipeline_dev_en.html">L1 Course Pipeline</a> <span class="sep">&#9656;</span> <span class="current">L2 HTML Templates</span> </div> <!-- ===== DEEP-DIVE LINK (in module body) ===== --> <a href="../l3/detail-page.html" class="deep-dive-link"> Deep-Dive: Detail Page → </a> <!-- ===== SIBLING NAV (before footer) ===== --> <section class="sibling-nav"> <div class="sibling-nav-inner"> <div class="sibling-nav-title"> More Developer L2 Pages </div> <div class="sibling-nav-grid"> <a href="page.html" class="sibling-nav-link"> <div class="sibling-nav-link-title"> Page Name </div> <div class="sibling-nav-link-sub"> Short description </div> </a> <!-- .active on the current page --> <a class="sibling-nav-link active">...</a> </div> </div> </section> <!-- ===== NAV BAR: L0 vs. L1-L3 ===== --> <!-- L0: Only logo/title + language switch --> <nav class="nav"> <div class="nav-title">Learning Skill</div> <div class="nav-right">...</div> </nav> <!-- L1-L3: Breadcrumb + dots + language switch --> <nav class="nav"> <div class="nav-breadcrumb">...</div> <div class="nav-dots"></div> <div class="nav-right">...</div> </nav> <!-- ===== AUDIENCE SWITCH (L0 only) ===== --> <div class="audience-switch"> <a href="index_en.html" class="audience-btn">Users</a> <a href="index_dev_en.html" class="audience-btn active">Developers</a> </div>

Breadcrumb: Shows the hierarchical path. Each level is a link, the current page is shown in bold (.current). The separators (.sep) use the Unicode triangle ▸.

Deep-Dive Link: Appears at the end of a module when an L3 deep-dive exists. Arrow icon (→) indicates a deeper level.

Sibling Nav: Grid layout with all sibling pages at the same level. The current page gets .active (orange border).

Nav Bar Differences: L0 shows only a title + language switch. L1-L3 replace the title with breadcrumbs and add the module dots.

Audience Switch: Only on L0 pages. Two buttons: Users and Developers. The active perspective is highlighted.

04
Interactive Elements
Toggle, tooltips, quiz, FAQ accordion, and flow diagrams

The Learning Skill uses several interactive components to make complex content accessible. The central element is the Code/Plain Text Toggle — every code block has a plain text explanation as an alternative.

.toggle-block Switch between Code & Plain Text Tabs + Panels + JS
.tooltip Hover explanations Dashed underline + popup
.quiz-block Multiple-choice questions Answer buttons + feedback
.faq-item Expandable questions Click-to-expand accordion
.flow-diagram Process visualization CSS Grid + arrows
<!-- ===== CODE/PLAIN TEXT TOGGLE ===== --> <div class="toggle-block" id="toggle1"> <!-- Tab bar --> <div class="toggle-tabs"> <button class="toggle-tab active" onclick="toggleView('toggle1','code')"> Code </button> <button class="toggle-tab" onclick="toggleView('toggle1','text')"> Plain Text </button> </div> <!-- Code panel --> <div class="toggle-panel code-panel active" data-panel="code"> <code>...formatted code...</code> </div> <!-- Plain text panel --> <div class="toggle-panel text-panel" data-panel="text"> <p>Understandable explanation...</p> </div> </div> /* ===== JavaScript: toggleView() ===== */ function toggleView(blockId, panel) { const block = document.getElementById(blockId); // Deactivate all tabs block.querySelectorAll('.toggle-tab') .forEach(t => t.classList.remove('active')); // Hide all panels block.querySelectorAll('.toggle-panel') .forEach(p => p.classList.remove('active')); // Activate selected panel block.querySelector( `[data-panel="${panel}"]` ).classList.add('active'); // Activate matching tab block.querySelectorAll('.toggle-tab') .forEach(t => { if ( (panel === 'code' && t.textContent === 'Code') || (panel === 'text' && t.textContent === 'Plain Text') ) t.classList.add('active'); }); } /* ===== TOOLTIP: CSS + Positioning ===== */ .tooltip { position: relative; border-bottom: 1px dashed var(--color-impulse-orange); cursor: help; } .tooltip .tooltip-text { visibility: hidden; opacity: 0; position: fixed; /* fixed, not absolute! */ z-index: 2000; max-width: 280px; transition: opacity .2s; } /* JS positions the tooltip via mouseenter */ document.querySelectorAll('.tooltip').forEach(tip => { tip.addEventListener('mouseenter', e => { const tt = tip.querySelector('.tooltip-text'); const rect = tip.getBoundingClientRect(); tt.style.left = rect.left + 'px'; tt.style.top = (rect.bottom + 8) + 'px'; }); });

Toggle Mechanics: Each toggle block has a unique ID. The toggleView() function switches between code and plain text panels by moving the .active class.

Code Panel: Dark background (#000066), monospace font, syntax-highlighted with span classes (.code-keyword, .code-string, .code-orange, .code-comment).

Plain Text Panel: White background, normal body font. Explains the code in understandable language without requiring technical background.

Tooltip: Uses position: fixed instead of absolute so the tooltip is not clipped by overflow-hidden containers. JavaScript calculates position dynamically via getBoundingClientRect().

Quiz/FAQ: Follow the same pattern: a container with a click handler that toggles .active classes. Quiz answers receive .correct or .wrong after clicking.

05
Responsive & Integration Mode
Breakpoints, standalone vs. embedded

The course pages are optimized for two breakpoints and support both standalone operation (own URL) and embedding within a parent application.

Breakpoints:

Desktop
> 768px
Tablet
481 - 768px
Mobile
≤ 480px
/* ===== MEDIA QUERIES ===== */ /* Tablet: More compact modules */ @media (max-width: 768px) { .module { padding: 4rem 1.2rem 3rem; min-height: auto; /* No fullscreen */ } .module-header { flex-direction: column; gap: .5rem; } .module-number { font-size: 3.5rem; } .hero h1 { font-size: 1.8rem; } .nav-breadcrumb { font-size: .72rem; } .sibling-nav-grid { grid-template-columns: 1fr; } } /* Mobile: Single-column layout */ @media (max-width: 480px) { .nav { padding: .5rem .8rem; } .nav-dots { display: none; /* Hide dots */ } .hero { padding: 4.5rem 1rem 2.5rem; min-height: 60dvh; } .code-block code { font-size: .7rem; } .toggle-tabs { flex-direction: column; } } <!-- ===== FOOTER: STANDALONE ===== --> <footer style="background:#F3EFEB; border-top:2px solid #E4DAD4; padding:2rem"> <div style="max-width:820px; margin:0 auto; display:flex; justify-content:space-between; align-items:center; flex-wrap:wrap; gap:1rem; font-size:.85rem; color:#6B6560"> <span>&copy; 2026 Mark Zimmermann</span> <div style="display:flex; gap:1.5rem"> <a href="...imprint...">Imprint</a> <a href="...github...">GitHub</a> </div> </div> </footer> <!-- ===== FOOTER: EMBEDDED (iframe) ===== --> <!-- No own footer — the host app provides header and footer. The nav bar and footer are hidden via CSS: --> <style> /* When ?embedded=true in the URL */ .embedded .nav { display: none; } .embedded footer { display: none; } .embedded .hero { padding-top: 2rem; /* No nav offset */ } </style>

768px Breakpoint: Modules lose min-height: 100dvh and become only as tall as their content. The header switches from horizontal (number beside title) to vertical (number above title). Breadcrumbs get smaller.

480px Breakpoint: The module dots in the nav bar are hidden (not enough space). Toggle tabs stack vertically. Code blocks get an even smaller font for better readability on narrow screens.

Standalone Footer: Shows copyright, imprint link, and GitHub link. Warm gray background (#F3EFEB) with darker border on top (#E4DAD4).

Integration Mode: When the page is embedded via iframe, nav and footer can be hidden via CSS. The host application then takes over the outer navigation. Hero padding is reduced since no fixed nav bar needs space.

No Deep-Dive to L3: This topic does not have an L3 deep-dive. The templates and patterns shown here cover the complete HTML architecture of the Learning Skill. For CSS variables and design tokens, see the Design System page.
More Developer L2 Pages