coursecode 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (362) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +322 -0
  3. package/THIRD_PARTY_NOTICES.md +22 -0
  4. package/bin/cli.js +331 -0
  5. package/framework/assets/logo-coursecode-black.svg +14 -0
  6. package/framework/assets/logo-coursecode-white.svg +14 -0
  7. package/framework/assets/logo-coursecode.svg +14 -0
  8. package/framework/css/01-base.css +160 -0
  9. package/framework/css/02-layout.css +499 -0
  10. package/framework/css/accessibility.css +834 -0
  11. package/framework/css/components/accordions.css +710 -0
  12. package/framework/css/components/assessments.css +520 -0
  13. package/framework/css/components/audio-player.css +570 -0
  14. package/framework/css/components/badges.css +80 -0
  15. package/framework/css/components/breadcrumbs.css +87 -0
  16. package/framework/css/components/buttons.css +707 -0
  17. package/framework/css/components/callouts.css +1280 -0
  18. package/framework/css/components/cards.css +475 -0
  19. package/framework/css/components/carousel.css +193 -0
  20. package/framework/css/components/checkbox-group.css +123 -0
  21. package/framework/css/components/checklist.css +203 -0
  22. package/framework/css/components/collapse.css +96 -0
  23. package/framework/css/components/comparison.css +33 -0
  24. package/framework/css/components/content-image.css +36 -0
  25. package/framework/css/components/document-gallery.css +425 -0
  26. package/framework/css/components/dropdown.css +115 -0
  27. package/framework/css/components/embed-frame.css +142 -0
  28. package/framework/css/components/engagement.css +412 -0
  29. package/framework/css/components/features.css +35 -0
  30. package/framework/css/components/flip-cards.css +253 -0
  31. package/framework/css/components/footer.css +353 -0
  32. package/framework/css/components/forms.css +294 -0
  33. package/framework/css/components/hero.css +216 -0
  34. package/framework/css/components/images.css +528 -0
  35. package/framework/css/components/interactive-timeline.css +274 -0
  36. package/framework/css/components/intro-cards.css +30 -0
  37. package/framework/css/components/lightbox.css +666 -0
  38. package/framework/css/components/loading.css +65 -0
  39. package/framework/css/components/modals.css +235 -0
  40. package/framework/css/components/notifications.css +107 -0
  41. package/framework/css/components/quote.css +150 -0
  42. package/framework/css/components/sidebar.css +684 -0
  43. package/framework/css/components/slide-header.css +52 -0
  44. package/framework/css/components/spinner.css +62 -0
  45. package/framework/css/components/stats.css +44 -0
  46. package/framework/css/components/steps.css +232 -0
  47. package/framework/css/components/tables.css +90 -0
  48. package/framework/css/components/tabs.css +347 -0
  49. package/framework/css/components/timeline.css +154 -0
  50. package/framework/css/components/toggle.css +95 -0
  51. package/framework/css/components/tooltip.css +226 -0
  52. package/framework/css/components/video-player.css +438 -0
  53. package/framework/css/design-tokens.css +707 -0
  54. package/framework/css/framework.css +86 -0
  55. package/framework/css/interactions/accessibility.css +75 -0
  56. package/framework/css/interactions/base.css +92 -0
  57. package/framework/css/interactions/drag-drop.css +295 -0
  58. package/framework/css/interactions/fill-in-the-blank.css +236 -0
  59. package/framework/css/interactions/hotspots.css +69 -0
  60. package/framework/css/interactions/index.css +45 -0
  61. package/framework/css/interactions/interactive-image.css +359 -0
  62. package/framework/css/interactions/likert.css +126 -0
  63. package/framework/css/interactions/matching.css +354 -0
  64. package/framework/css/interactions/numeric-input.css +78 -0
  65. package/framework/css/interactions/sequencing.css +378 -0
  66. package/framework/css/interactions/true-false.css +177 -0
  67. package/framework/css/layouts/article.css +258 -0
  68. package/framework/css/layouts/base.css +30 -0
  69. package/framework/css/layouts/canvas.css +38 -0
  70. package/framework/css/layouts/focused.css +236 -0
  71. package/framework/css/layouts/index.css +29 -0
  72. package/framework/css/layouts/presentation.css +191 -0
  73. package/framework/css/layouts/traditional.css +52 -0
  74. package/framework/css/responsive.css +439 -0
  75. package/framework/css/utilities/accessibility-utils.css +59 -0
  76. package/framework/css/utilities/animations.css +419 -0
  77. package/framework/css/utilities/borders.css +72 -0
  78. package/framework/css/utilities/colors.css +76 -0
  79. package/framework/css/utilities/container.css +46 -0
  80. package/framework/css/utilities/decorative.css +442 -0
  81. package/framework/css/utilities/display.css +257 -0
  82. package/framework/css/utilities/flexbox.css +80 -0
  83. package/framework/css/utilities/grid.css +69 -0
  84. package/framework/css/utilities/icons.css +534 -0
  85. package/framework/css/utilities/lists.css +190 -0
  86. package/framework/css/utilities/spacing.css +167 -0
  87. package/framework/css/utilities/tables.css +81 -0
  88. package/framework/css/utilities/typography.css +159 -0
  89. package/framework/css/utilities/visibility.css +117 -0
  90. package/framework/docs/COURSE_AUTHORING_GUIDE.md +1773 -0
  91. package/framework/docs/COURSE_OUTLINE_GUIDE.md +725 -0
  92. package/framework/docs/COURSE_OUTLINE_TEMPLATE.md +161 -0
  93. package/framework/docs/DATA_MODEL.md +409 -0
  94. package/framework/docs/FRAMEWORK_GUIDE.md +1088 -0
  95. package/framework/docs/USER_GUIDE.md +583 -0
  96. package/framework/docs/examples/cloudflare-channel-relay.js +169 -0
  97. package/framework/docs/examples/cloudflare-data-worker.js +102 -0
  98. package/framework/docs/examples/cloudflare-error-worker.js +228 -0
  99. package/framework/index.html +175 -0
  100. package/framework/js/app/AppActions.js +410 -0
  101. package/framework/js/app/AppState.js +225 -0
  102. package/framework/js/app/AppUI.js +616 -0
  103. package/framework/js/assessment/AssessmentActions.js +615 -0
  104. package/framework/js/assessment/AssessmentFactory.js +471 -0
  105. package/framework/js/assessment/AssessmentState.js +322 -0
  106. package/framework/js/assessment/AssessmentUI.js +451 -0
  107. package/framework/js/automation/api-engagement.js +196 -0
  108. package/framework/js/automation/api-interactions.js +167 -0
  109. package/framework/js/automation/api.js +242 -0
  110. package/framework/js/automation/index.js +41 -0
  111. package/framework/js/components/interactions/drag-drop.js +884 -0
  112. package/framework/js/components/interactions/fill-in.js +535 -0
  113. package/framework/js/components/interactions/hotspot.js +702 -0
  114. package/framework/js/components/interactions/interaction-base.js +511 -0
  115. package/framework/js/components/interactions/likert.js +301 -0
  116. package/framework/js/components/interactions/matching.js +699 -0
  117. package/framework/js/components/interactions/multiple-choice.js +377 -0
  118. package/framework/js/components/interactions/numeric.js +271 -0
  119. package/framework/js/components/interactions/sequencing.js +423 -0
  120. package/framework/js/components/interactions/true-false.js +241 -0
  121. package/framework/js/components/ui-components/accordion.js +442 -0
  122. package/framework/js/components/ui-components/alert.js +88 -0
  123. package/framework/js/components/ui-components/audio-player.js +1193 -0
  124. package/framework/js/components/ui-components/callout.js +121 -0
  125. package/framework/js/components/ui-components/carousel.js +145 -0
  126. package/framework/js/components/ui-components/checkbox-group.js +87 -0
  127. package/framework/js/components/ui-components/checklist.js +40 -0
  128. package/framework/js/components/ui-components/collapse.js +114 -0
  129. package/framework/js/components/ui-components/comparison.js +30 -0
  130. package/framework/js/components/ui-components/conditional-display.js +150 -0
  131. package/framework/js/components/ui-components/content-image.js +41 -0
  132. package/framework/js/components/ui-components/dropdown.js +262 -0
  133. package/framework/js/components/ui-components/embed-frame.js +274 -0
  134. package/framework/js/components/ui-components/features.js +33 -0
  135. package/framework/js/components/ui-components/flip-card.js +230 -0
  136. package/framework/js/components/ui-components/form-validator.js +76 -0
  137. package/framework/js/components/ui-components/hero.js +49 -0
  138. package/framework/js/components/ui-components/index.js +12 -0
  139. package/framework/js/components/ui-components/interactive-image.js +235 -0
  140. package/framework/js/components/ui-components/interactive-timeline.js +285 -0
  141. package/framework/js/components/ui-components/intro-cards.js +35 -0
  142. package/framework/js/components/ui-components/lightbox.js +652 -0
  143. package/framework/js/components/ui-components/modal.js +386 -0
  144. package/framework/js/components/ui-components/notifications.js +145 -0
  145. package/framework/js/components/ui-components/progress.js +88 -0
  146. package/framework/js/components/ui-components/quote.js +41 -0
  147. package/framework/js/components/ui-components/stats.js +33 -0
  148. package/framework/js/components/ui-components/steps.js +41 -0
  149. package/framework/js/components/ui-components/tabs.js +255 -0
  150. package/framework/js/components/ui-components/timeline.js +42 -0
  151. package/framework/js/components/ui-components/toggle-group.js +73 -0
  152. package/framework/js/components/ui-components/tooltip.js +458 -0
  153. package/framework/js/components/ui-components/value-display.js +133 -0
  154. package/framework/js/components/ui-components/video-player.js +686 -0
  155. package/framework/js/core/component-catalog.js +121 -0
  156. package/framework/js/core/event-bus.js +178 -0
  157. package/framework/js/core/interaction-catalog.js +149 -0
  158. package/framework/js/dev/runtime-linter.js +1725 -0
  159. package/framework/js/drivers/cmi5-driver.js +768 -0
  160. package/framework/js/drivers/driver-factory.js +77 -0
  161. package/framework/js/drivers/driver-interface.js +110 -0
  162. package/framework/js/drivers/http-driver-base.js +241 -0
  163. package/framework/js/drivers/lti-driver.js +508 -0
  164. package/framework/js/drivers/proxy-driver.js +444 -0
  165. package/framework/js/drivers/scorm-12-driver.js +560 -0
  166. package/framework/js/drivers/scorm-2004-driver.js +775 -0
  167. package/framework/js/drivers/scorm-driver-base.js +112 -0
  168. package/framework/js/engagement/engagement-manager.js +404 -0
  169. package/framework/js/engagement/engagement-progress.js +191 -0
  170. package/framework/js/engagement/engagement-trackers.js +215 -0
  171. package/framework/js/engagement/requirement-strategies.js +268 -0
  172. package/framework/js/main.js +727 -0
  173. package/framework/js/managers/accessibility-manager.js +499 -0
  174. package/framework/js/managers/assessment-manager.js +230 -0
  175. package/framework/js/managers/audio-manager.js +944 -0
  176. package/framework/js/managers/comment-manager.js +88 -0
  177. package/framework/js/managers/flag-manager.js +86 -0
  178. package/framework/js/managers/interaction-manager.js +254 -0
  179. package/framework/js/managers/interaction-registry.js +96 -0
  180. package/framework/js/managers/objective-manager.js +423 -0
  181. package/framework/js/managers/score-manager.js +441 -0
  182. package/framework/js/managers/video-manager.js +536 -0
  183. package/framework/js/navigation/Breadcrumbs.js +234 -0
  184. package/framework/js/navigation/NavigationActions.js +1132 -0
  185. package/framework/js/navigation/NavigationState.js +276 -0
  186. package/framework/js/navigation/NavigationUI.js +574 -0
  187. package/framework/js/navigation/document-gallery.js +357 -0
  188. package/framework/js/navigation/navigation-helpers.js +175 -0
  189. package/framework/js/navigation/navigation-validators.js +174 -0
  190. package/framework/js/state/index.js +8 -0
  191. package/framework/js/state/lms-connection.js +482 -0
  192. package/framework/js/state/lms-error-utils.js +58 -0
  193. package/framework/js/state/state-commits.js +200 -0
  194. package/framework/js/state/state-domains.js +86 -0
  195. package/framework/js/state/state-manager.js +502 -0
  196. package/framework/js/state/state-validation.js +311 -0
  197. package/framework/js/state/transaction-log.js +41 -0
  198. package/framework/js/state/xapi-statement-service.js +325 -0
  199. package/framework/js/utilities/access-control.js +99 -0
  200. package/framework/js/utilities/breakpoint-manager.js +315 -0
  201. package/framework/js/utilities/canvas-slide.js +35 -0
  202. package/framework/js/utilities/conditional-display.js +388 -0
  203. package/framework/js/utilities/course-channel.js +214 -0
  204. package/framework/js/utilities/course-helpers.js +420 -0
  205. package/framework/js/utilities/data-reporter.js +273 -0
  206. package/framework/js/utilities/error-reporter.js +313 -0
  207. package/framework/js/utilities/hotspot-helper.js +341 -0
  208. package/framework/js/utilities/icons.js +348 -0
  209. package/framework/js/utilities/logger.js +92 -0
  210. package/framework/js/utilities/markdown-renderer.js +45 -0
  211. package/framework/js/utilities/scroll-tracker.js +68 -0
  212. package/framework/js/utilities/ui-initializer.js +146 -0
  213. package/framework/js/utilities/utilities.js +293 -0
  214. package/framework/js/utilities/view-manager.js +227 -0
  215. package/framework/js/validation/html-validators.js +422 -0
  216. package/framework/js/validation/scorm-validators.js +438 -0
  217. package/framework/js/vendor/pipwerks.js +931 -0
  218. package/framework/scripts/generate-narration.js +629 -0
  219. package/framework/scripts/tts-providers/azure-provider.js +178 -0
  220. package/framework/scripts/tts-providers/base-provider.js +81 -0
  221. package/framework/scripts/tts-providers/deepgram-provider.js +135 -0
  222. package/framework/scripts/tts-providers/elevenlabs-provider.js +148 -0
  223. package/framework/scripts/tts-providers/google-provider.js +272 -0
  224. package/framework/scripts/tts-providers/index.js +158 -0
  225. package/framework/scripts/tts-providers/openai-provider.js +143 -0
  226. package/framework/version.json +63 -0
  227. package/lib/authoring-api.js +919 -0
  228. package/lib/build-linter.js +450 -0
  229. package/lib/build-packaging.js +186 -0
  230. package/lib/build.js +88 -0
  231. package/lib/cloud.js +691 -0
  232. package/lib/convert.js +341 -0
  233. package/lib/course-parser.js +936 -0
  234. package/lib/course-writer.js +258 -0
  235. package/lib/create.js +248 -0
  236. package/lib/css-index.js +237 -0
  237. package/lib/dev.js +51 -0
  238. package/lib/export-content.js +1246 -0
  239. package/lib/headless-browser.js +413 -0
  240. package/lib/import.js +377 -0
  241. package/lib/index.js +80 -0
  242. package/lib/info.js +79 -0
  243. package/lib/interaction-formatters.js +568 -0
  244. package/lib/manifest/cmi5-manifest.js +63 -0
  245. package/lib/manifest/lti-tool-config.js +53 -0
  246. package/lib/manifest/manifest-factory.js +99 -0
  247. package/lib/manifest/scorm-12-manifest.js +61 -0
  248. package/lib/manifest/scorm-2004-manifest.js +94 -0
  249. package/lib/manifest/scorm-proxy-manifest.js +104 -0
  250. package/lib/manifest-parser.js +96 -0
  251. package/lib/mcp-prompts.js +753 -0
  252. package/lib/mcp-server.js +316 -0
  253. package/lib/narration.js +53 -0
  254. package/lib/pdf-structure.js +142 -0
  255. package/lib/preview-export.js +231 -0
  256. package/lib/preview-routes-api.js +662 -0
  257. package/lib/preview-routes-editing.js +159 -0
  258. package/lib/preview-routes-lms.js +230 -0
  259. package/lib/preview-server.js +564 -0
  260. package/lib/project-utils.js +269 -0
  261. package/lib/proxy-templates/proxy.html +68 -0
  262. package/lib/proxy-templates/scorm-bridge.js +112 -0
  263. package/lib/scaffold.js +193 -0
  264. package/lib/schema-extractor.js +361 -0
  265. package/lib/slide-source-editor.js +586 -0
  266. package/lib/stub-player/app-viewer.js +195 -0
  267. package/lib/stub-player/app.js +370 -0
  268. package/lib/stub-player/catalog-panel.js +312 -0
  269. package/lib/stub-player/config-panel.js +1303 -0
  270. package/lib/stub-player/content-generator.js +586 -0
  271. package/lib/stub-player/content-viewer.js +173 -0
  272. package/lib/stub-player/debug-panel.js +420 -0
  273. package/lib/stub-player/edit-mode.js +922 -0
  274. package/lib/stub-player/edit-utils.js +400 -0
  275. package/lib/stub-player/header-bar.js +354 -0
  276. package/lib/stub-player/interaction-editor.js +210 -0
  277. package/lib/stub-player/interactions-panel.js +565 -0
  278. package/lib/stub-player/lms-api.js +1094 -0
  279. package/lib/stub-player/login-screen.js +74 -0
  280. package/lib/stub-player/outline-mode.js +689 -0
  281. package/lib/stub-player/styles/_assessments-panel.css +245 -0
  282. package/lib/stub-player/styles/_base.css +89 -0
  283. package/lib/stub-player/styles/_catalog-icons.css +96 -0
  284. package/lib/stub-player/styles/_catalog-panel.css +291 -0
  285. package/lib/stub-player/styles/_config-panel.css +636 -0
  286. package/lib/stub-player/styles/_content-viewer.css +834 -0
  287. package/lib/stub-player/styles/_debug-panel.css +576 -0
  288. package/lib/stub-player/styles/_edit-mode.css +128 -0
  289. package/lib/stub-player/styles/_header-bar.css +343 -0
  290. package/lib/stub-player/styles/_interaction-editor.css +140 -0
  291. package/lib/stub-player/styles/_interactions-panel.css +1038 -0
  292. package/lib/stub-player/styles/_login-screen.css +102 -0
  293. package/lib/stub-player/styles/_outline-mode.css +752 -0
  294. package/lib/stub-player/styles.css +15 -0
  295. package/lib/stub-player.js +160 -0
  296. package/lib/test-data-reporting.js +176 -0
  297. package/lib/test-error-reporting.js +146 -0
  298. package/lib/token.js +86 -0
  299. package/lib/upgrade.js +257 -0
  300. package/lib/validation-rules.js +517 -0
  301. package/lib/vite-plugin-content-discovery.js +296 -0
  302. package/package.json +108 -0
  303. package/schemas/XMLSchema.dtd +402 -0
  304. package/schemas/adlcp_v1p3.xsd +111 -0
  305. package/schemas/adlnav_v1p3.xsd +61 -0
  306. package/schemas/adlseq_v1p3.xsd +93 -0
  307. package/schemas/common/anyElement.xsd +27 -0
  308. package/schemas/common/dataTypes.xsd +138 -0
  309. package/schemas/common/elementNames.xsd +767 -0
  310. package/schemas/common/elementTypes.xsd +786 -0
  311. package/schemas/common/rootElement.xsd +31 -0
  312. package/schemas/common/vocabTypes.xsd +345 -0
  313. package/schemas/common/vocabValues.xsd +257 -0
  314. package/schemas/datatypes.dtd +203 -0
  315. package/schemas/ims_xml.xsd +35 -0
  316. package/schemas/imscp_v1p1.xsd +368 -0
  317. package/schemas/imsss_v1p0.xsd +67 -0
  318. package/schemas/imsss_v1p0auxresource.xsd +19 -0
  319. package/schemas/imsss_v1p0control.xsd +20 -0
  320. package/schemas/imsss_v1p0delivery.xsd +17 -0
  321. package/schemas/imsss_v1p0limit.xsd +47 -0
  322. package/schemas/imsss_v1p0objective.xsd +67 -0
  323. package/schemas/imsss_v1p0random.xsd +16 -0
  324. package/schemas/imsss_v1p0rollup.xsd +46 -0
  325. package/schemas/imsss_v1p0seqrule.xsd +108 -0
  326. package/schemas/imsss_v1p0util.xsd +94 -0
  327. package/schemas/license.txt +17 -0
  328. package/schemas/lom.xsd +102 -0
  329. package/schemas/lomCustom.xsd +62 -0
  330. package/schemas/lomLoose.xsd +62 -0
  331. package/schemas/lomStrict.xsd +62 -0
  332. package/schemas/xml.xsd +81 -0
  333. package/template/.env.example +92 -0
  334. package/template/course/assets/audio/example-intro.mp3 +0 -0
  335. package/template/course/assets/audio/example-ui-demo--compact-player.mp3 +0 -0
  336. package/template/course/assets/audio/example-ui-demo--demo-modal.mp3 +0 -0
  337. package/template/course/assets/audio/example-ui-demo--full-player.mp3 +0 -0
  338. package/template/course/assets/docs/example_md_1.md +39 -0
  339. package/template/course/assets/docs/example_md_2.md +41 -0
  340. package/template/course/assets/docs/example_pdf_1_thumbnail.png +0 -0
  341. package/template/course/assets/docs/example_pdf_2.pdf +0 -0
  342. package/template/course/assets/images/course-architecture.svg +36 -0
  343. package/template/course/assets/images/logo.svg +14 -0
  344. package/template/course/assets/widgets/counter-demo.html +190 -0
  345. package/template/course/assets/widgets/gravity-painter.html +384 -0
  346. package/template/course/course-config.js +539 -0
  347. package/template/course/icons.js +19 -0
  348. package/template/course/interactions/PLUGIN_GUIDE.md +97 -0
  349. package/template/course/slides/example-course-structure.js +138 -0
  350. package/template/course/slides/example-final-exam.js +144 -0
  351. package/template/course/slides/example-finishing.js +127 -0
  352. package/template/course/slides/example-interactions-showcase.js +615 -0
  353. package/template/course/slides/example-preview-tour.js +129 -0
  354. package/template/course/slides/example-remedial.js +143 -0
  355. package/template/course/slides/example-summary.js +103 -0
  356. package/template/course/slides/example-ui-showcase.js +1805 -0
  357. package/template/course/slides/example-welcome.js +123 -0
  358. package/template/course/slides/example-workflow.js +140 -0
  359. package/template/course/theme.css +165 -0
  360. package/template/eslint.config.js +47 -0
  361. package/template/package.json +28 -0
  362. package/template/vite.config.js +339 -0
@@ -0,0 +1,1805 @@
1
+ /**
2
+ * UI Components Showcase
3
+ * This slide demonstrates available UI components with collapsible code examples.
4
+ * See COURSE_AUTHORING_GUIDE.md for full documentation.
5
+ */
6
+
7
+ export const slide = {
8
+ render(_root, _context) {
9
+ const container = document.createElement('div');
10
+ container.innerHTML = `
11
+ <div class="stack-lg">
12
+
13
+ <!-- Header -->
14
+ <div class="stack-md">
15
+ <div class="callout callout--info">
16
+ <h2 class="text-xl font-bold m-0">UI Components Showcase</h2>
17
+ <p class="m-0">Explore the available components. Click "View Code" to see the HTML for each example.</p>
18
+ </div>
19
+ </div>
20
+
21
+ <!-- Main Tabs -->
22
+ <div id="demo-tabs" data-component="tabs">
23
+ <div class="tab-list" role="tablist">
24
+ <button class="tab-button active" data-action="select-tab" data-tab="static" role="tab">Static & Layout</button>
25
+ <button class="tab-button" data-action="select-tab" data-tab="interactive" role="tab">Interactive</button>
26
+ <button class="tab-button" data-action="select-tab" data-tab="forms" role="tab">Forms</button>
27
+ <button class="tab-button" data-action="select-tab" data-tab="feedback" role="tab">Feedback</button>
28
+ <button class="tab-button" data-action="select-tab" data-tab="images" role="tab">Images</button>
29
+ <button class="tab-button" data-action="select-tab" data-tab="audio" role="tab">Audio</button>
30
+ <button class="tab-button" data-action="select-tab" data-tab="video" role="tab">Video</button>
31
+ </div>
32
+
33
+ <!-- Tab 1: Static & Layout -->
34
+ <div id="static" class="tab-content active" role="tabpanel">
35
+ <div class="stack-lg">
36
+
37
+ <!-- Buttons -->
38
+ <section class="card no-hover">
39
+ <h3 class="text-lg font-bold border-bottom pb-2 mb-4">Buttons</h3>
40
+ <div class="stack-md">
41
+ <div class="flex flex-wrap gap-2">
42
+ <button class="btn btn-primary">Primary</button>
43
+ <button class="btn btn-secondary">Secondary</button>
44
+ <button class="btn btn-success">Success</button>
45
+ <button class="btn btn-warning">Warning</button>
46
+ <button class="btn btn-danger">Danger</button>
47
+ <button class="btn btn-info">Info</button>
48
+ </div>
49
+ <div class="flex flex-wrap gap-2 items-end">
50
+ <button class="btn btn-primary btn-sm">Small</button>
51
+ <button class="btn btn-primary">Regular</button>
52
+ <button class="btn btn-primary btn-lg">Large</button>
53
+ <button class="btn btn-primary" disabled>Disabled</button>
54
+ <button class="btn btn-outline-primary">Outline Primary</button>
55
+ <button class="btn btn-outline-secondary">Outline Secondary</button>
56
+ </div>
57
+
58
+ <div data-component="collapse" class="mt-3">
59
+ <button type="button" class="btn btn-sm btn-secondary collapse-trigger" data-action="toggle-collapse" aria-controls="code-buttons" aria-expanded="false">
60
+ <span class="collapse-text-show">Show Code Example</span>
61
+ <span class="collapse-text-hide">Hide Code Example</span>
62
+ </button>
63
+ <div class="collapse-panel mt-3" id="code-buttons">
64
+ <pre class="bg-gray-100 p-3 rounded text-xs overflow-x-auto"><code>&lt;button class="btn btn-primary"&gt;Primary&lt;/button&gt;
65
+ &lt;button class="btn btn-secondary"&gt;Secondary&lt;/button&gt;
66
+ &lt;button class="btn btn-primary btn-lg"&gt;Large&lt;/button&gt;
67
+ &lt;button class="btn btn-outline-primary"&gt;Outline&lt;/button&gt;</code></pre>
68
+ </div>
69
+ </div>
70
+ </div>
71
+ </section>
72
+
73
+ <!-- Badges -->
74
+ <section class="card no-hover">
75
+ <h3 class="text-lg font-bold border-bottom pb-2 mb-4">Badges</h3>
76
+ <div class="stack-md">
77
+ <div class="flex flex-wrap gap-2 items-center">
78
+ <span class="badge badge-primary">Primary</span>
79
+ <span class="badge badge-secondary">Secondary</span>
80
+ <span class="badge badge-success">Success</span>
81
+ <span class="badge badge-warning">Warning</span>
82
+ <span class="badge badge-danger">Danger</span>
83
+ <span class="badge badge-info">Info</span>
84
+ </div>
85
+ <div class="flex flex-wrap gap-2 items-center">
86
+ <span class="badge badge-outline">Outline</span>
87
+ <span class="badge badge-primary badge-borderless">Borderless</span>
88
+ <span class="hero-badge">Hero Badge</span>
89
+ <span class="hero-badge hero-badge-borderless">Hero Borderless</span>
90
+ </div>
91
+
92
+ <div data-component="collapse" class="mt-3">
93
+ <button type="button" class="btn btn-sm btn-secondary collapse-trigger" data-action="toggle-collapse" aria-controls="code-badges" aria-expanded="false">
94
+ <span class="collapse-text-show">Show Code Example</span>
95
+ <span class="collapse-text-hide">Hide Code Example</span>
96
+ </button>
97
+ <div class="collapse-panel mt-3" id="code-badges">
98
+ <pre class="bg-gray-100 p-3 rounded text-xs overflow-x-auto"><code>&lt;span class="badge badge-primary"&gt;Primary&lt;/span&gt;
99
+ &lt;span class="badge badge-outline"&gt;Outline&lt;/span&gt;
100
+ &lt;span class="badge badge-primary badge-borderless"&gt;Borderless&lt;/span&gt;
101
+ &lt;span class="hero-badge"&gt;Hero Badge&lt;/span&gt;
102
+ &lt;span class="hero-badge hero-badge-borderless"&gt;Hero Borderless&lt;/span&gt;</code></pre>
103
+ </div>
104
+ </div>
105
+ </div>
106
+ </section>
107
+
108
+ <!-- Callouts -->
109
+ <section class="card no-hover">
110
+ <h3 class="text-lg font-bold border-bottom pb-2 mb-4">Callouts</h3>
111
+ <div class="stack-md">
112
+ <p class="text-sm text-primary m-0">All modern <code>.callout</code> variants are shown below.</p>
113
+ <div class="callout callout--neutral" data-component="callout" data-icon="book-open">
114
+ <h4 class="callout__title">Neutral context</h4>
115
+ <div class="callout__body">
116
+ <p>Use neutral for non-urgent explanatory context, notes, and transitional guidance.</p>
117
+ </div>
118
+ </div>
119
+ <div class="callout callout--info" data-component="callout" data-icon="sparkles" data-icon-size="md">
120
+ <h4 class="callout__title">Modern default (recommended)</h4>
121
+ <div class="callout__body">
122
+ <p>Use this as the default informational callout in new content.</p>
123
+ </div>
124
+ <div class="callout__meta">Meta text slot example</div>
125
+ </div>
126
+ <div class="callout callout--success" data-component="callout" data-icon="check-circle">
127
+ <h4 class="callout__title">Success</h4>
128
+ <div class="callout__body">
129
+ <p>Positive confirmations, completion states, and successful outcomes.</p>
130
+ </div>
131
+ </div>
132
+ <div class="callout callout--warning" data-component="callout" data-icon="alert-triangle">
133
+ <h4 class="callout__title">Warning</h4>
134
+ <div class="callout__body">
135
+ <p>Cautionary guidance when users should double-check before continuing.</p>
136
+ </div>
137
+ </div>
138
+ <div class="callout callout--danger" data-component="callout" data-icon="octagon-alert">
139
+ <h4 class="callout__title">Danger</h4>
140
+ <div class="callout__body">
141
+ <p>Errors, critical problems, and high-severity states.</p>
142
+ </div>
143
+ </div>
144
+ <div class="callout callout--success callout--compact" data-component="callout" data-icon="check" data-icon-size="xs">
145
+ <h4 class="callout__title">Compact success</h4>
146
+ <div class="callout__body">
147
+ <p>Great for checklist confirmations and short feedback.</p>
148
+ </div>
149
+ </div>
150
+ <div class="callout callout--neutral callout--spacious" data-component="callout" data-icon="layers">
151
+ <h4 class="callout__title">Spacious neutral</h4>
152
+ <div class="callout__body">
153
+ <p>Use spacious density when you want a calmer, editorial rhythm around longer context.</p>
154
+ </div>
155
+ </div>
156
+ <div class="callout callout--info callout--actionable" data-component="callout" data-icon="mouse-pointer" tabindex="0">
157
+ <h4 class="callout__title">Actionable info</h4>
158
+ <div class="callout__body">
159
+ <p>Use actionable when the whole panel acts like an interactive target.</p>
160
+ </div>
161
+ <div class="callout__actions">
162
+ <button class="btn btn-sm btn-outline-primary">Open</button>
163
+ </div>
164
+ </div>
165
+ <div class="callout callout--warning callout--dismissible" data-component="callout" data-icon="shield" data-icon-class="icon-warning">
166
+ <button class="callout__dismiss" aria-label="Dismiss">×</button>
167
+ <h4 class="callout__title">Warning with action slot</h4>
168
+ <div class="callout__body">
169
+ <p>For higher attention states, pair warning content with a clear next action.</p>
170
+ </div>
171
+ <div class="callout__actions">
172
+ <button class="btn btn-sm btn-outline-secondary">Review</button>
173
+ </div>
174
+ </div>
175
+ <div class="callout callout--danger callout--filled" data-component="callout" data-icon="stop-circle">
176
+ <h4 class="callout__title">Filled danger</h4>
177
+ <div class="callout__body">
178
+ <p>Reserve the filled variant for urgent, blocking states only.</p>
179
+ </div>
180
+ </div>
181
+ <div data-component="collapse" class="mt-3">
182
+ <button type="button" class="btn btn-sm btn-secondary collapse-trigger" data-action="toggle-collapse" aria-controls="code-callouts" aria-expanded="false">
183
+ <span class="collapse-text-show">Show Code Example</span>
184
+ <span class="collapse-text-hide">Hide Code Example</span>
185
+ </button>
186
+ <div class="collapse-panel mt-3" id="code-callouts">
187
+ <pre class="bg-gray-100 p-3 rounded text-xs overflow-x-auto"><code>&lt;!-- Severity --&gt;
188
+ &lt;aside class="callout callout--neutral" data-component="callout" data-icon="book-open"&gt;...&lt;/aside&gt;
189
+ &lt;aside class="callout callout--info" data-component="callout" data-icon="sparkles" data-icon-size="md"&gt;...&lt;/aside&gt;
190
+ &lt;aside class="callout callout--success" data-component="callout" data-icon="check-circle"&gt;...&lt;/aside&gt;
191
+ &lt;aside class="callout callout--warning" data-component="callout" data-icon="alert-triangle"&gt;...&lt;/aside&gt;
192
+ &lt;aside class="callout callout--danger" data-component="callout" data-icon="octagon-alert"&gt;...&lt;/aside&gt;
193
+
194
+ &lt;!-- Density --&gt;
195
+ &lt;aside class="callout callout--compact" data-component="callout" data-icon="check" data-icon-size="xs"&gt;...&lt;/aside&gt;
196
+ &lt;aside class="callout callout--spacious" data-component="callout" data-icon="layers"&gt;...&lt;/aside&gt;
197
+
198
+ &lt;!-- Style + behavior --&gt;
199
+ &lt;aside class="callout callout--filled" data-component="callout" data-icon="stop-circle"&gt;...&lt;/aside&gt;
200
+ &lt;aside class="callout callout--actionable" data-component="callout" data-icon="mouse-pointer"&gt;...&lt;/aside&gt;
201
+ &lt;aside class="callout callout--dismissible"&gt;
202
+ &lt;button class="callout__dismiss" aria-label="Dismiss"&gt;×&lt;/button&gt;
203
+ &lt;/aside&gt;
204
+
205
+ &lt;!-- Slots --&gt;
206
+ &lt;aside class="callout callout--info" data-component="callout" data-icon="auto"&gt;
207
+ &lt;h4 class="callout__title"&gt;Title&lt;/h4&gt;
208
+ &lt;div class="callout__body"&gt;&lt;p&gt;Message text&lt;/p&gt;&lt;/div&gt;
209
+ &lt;div class="callout__meta"&gt;Meta line&lt;/div&gt;
210
+ &lt;div class="callout__actions"&gt;&lt;button class="btn btn-sm btn-outline-secondary"&gt;Action&lt;/button&gt;&lt;/div&gt;
211
+ &lt;/aside&gt;</code></pre>
212
+ </div>
213
+ </div>
214
+ </div>
215
+ </section>
216
+
217
+ <!-- Layout Grid -->
218
+ <section class="card no-hover">
219
+ <h3 class="text-lg font-bold border-bottom pb-2 mb-4">Grid Layouts</h3>
220
+ <div class="stack-md">
221
+ <p>Responsive grid utilities: <code>.cols-2</code>, <code>.cols-3</code>, <code>.cols-auto-fit</code></p>
222
+ <div class="cols-3 gap-4">
223
+ <div class="p-4 bg-gray-100 rounded text-center">Col 1</div>
224
+ <div class="p-4 bg-gray-100 rounded text-center">Col 2</div>
225
+ <div class="p-4 bg-gray-100 rounded text-center">Col 3</div>
226
+ </div>
227
+ <div class="split-60-40 gap-4 mt-4">
228
+ <div class="p-4 bg-gray-100 rounded text-center">60% Width</div>
229
+ <div class="p-4 bg-gray-100 rounded text-center">40% Width</div>
230
+ </div>
231
+ </div>
232
+ </section>
233
+
234
+ <!-- Intro Cards Pattern -->
235
+ <section class="card no-hover">
236
+ <h3 class="text-lg font-bold border-bottom pb-2 mb-4">Intro Cards Pattern</h3>
237
+ <p class="mb-4">Use for welcome slides and feature overviews. Cards are equal-width and stack on mobile.</p>
238
+
239
+ <div data-component="intro-cards" class="mb-4">
240
+ <div class="intro-card">
241
+ <div class="card-icon">🎯</div>
242
+ <h3>First Feature</h3>
243
+ <p>Brief description of the first key feature or benefit.</p>
244
+ </div>
245
+ <div class="intro-card">
246
+ <div class="card-icon">⚡</div>
247
+ <h3>Second Feature</h3>
248
+ <p>Brief description of the second key feature or benefit.</p>
249
+ </div>
250
+ <div class="intro-card">
251
+ <div class="card-icon">✨</div>
252
+ <h3>Third Feature</h3>
253
+ <p>Brief description of the third key feature or benefit.</p>
254
+ </div>
255
+ </div>
256
+
257
+ <div data-component="collapse">
258
+ <button type="button" class="btn btn-sm btn-secondary collapse-trigger" data-action="toggle-collapse" aria-controls="code-intro-cards" aria-expanded="false">
259
+ <span class="collapse-text-show">Show Code Example</span>
260
+ <span class="collapse-text-hide">Hide Code Example</span>
261
+ </button>
262
+ <div class="collapse-panel mt-3" id="code-intro-cards">
263
+ <pre class="bg-gray-100 p-3 rounded text-xs overflow-x-auto"><code>&lt;div data-component="intro-cards"&gt;
264
+ &lt;div class="intro-card"&gt;
265
+ &lt;div class="card-icon"&gt;🎯&lt;/div&gt;
266
+ &lt;h3&gt;Feature Title&lt;/h3&gt;
267
+ &lt;p&gt;Description text.&lt;/p&gt;
268
+ &lt;/div&gt;
269
+ &lt;!-- Add more intro-card divs --&gt;
270
+ &lt;/div&gt;</code></pre>
271
+ </div>
272
+ </div>
273
+ </section>
274
+
275
+ <!-- Steps Pattern -->
276
+ <section class="card no-hover">
277
+ <h3 class="text-lg font-bold border-bottom pb-2 mb-4">Steps Pattern</h3>
278
+ <p class="mb-4">Use for processes, workflows, or sequential instructions.</p>
279
+
280
+ <div data-component="steps" class="mb-4" data-steps-style="connected">
281
+ <div class="step">
282
+ <div class="step-number">1</div>
283
+ <div class="step-content">
284
+ <h3>First Step</h3>
285
+ <p>Description of what happens in this step.</p>
286
+ </div>
287
+ </div>
288
+ <div class="step">
289
+ <div class="step-number">2</div>
290
+ <div class="step-content">
291
+ <h3>Second Step</h3>
292
+ <p>Description of what happens in this step.</p>
293
+ </div>
294
+ </div>
295
+ <div class="step">
296
+ <div class="step-number">3</div>
297
+ <div class="step-content">
298
+ <h3>Third Step</h3>
299
+ <p>Description of what happens in this step.</p>
300
+ </div>
301
+ </div>
302
+ </div>
303
+
304
+ <div data-component="collapse">
305
+ <button type="button" class="btn btn-sm btn-secondary collapse-trigger" data-action="toggle-collapse" aria-controls="code-steps" aria-expanded="false">
306
+ <span class="collapse-text-show">Show Code Example</span>
307
+ <span class="collapse-text-hide">Hide Code Example</span>
308
+ </button>
309
+ <div class="collapse-panel mt-3" id="code-steps">
310
+ <pre class="bg-gray-100 p-3 rounded text-xs overflow-x-auto"><code>&lt;div data-component="steps" data-steps-style="connected"&gt;
311
+ &lt;div class="step"&gt;
312
+ &lt;div class="step-number"&gt;1&lt;/div&gt;
313
+ &lt;div class="step-content"&gt;
314
+ &lt;h3&gt;Step Title&lt;/h3&gt;
315
+ &lt;p&gt;Step description.&lt;/p&gt;
316
+ &lt;/div&gt;
317
+ &lt;/div&gt;
318
+ &lt;!-- Add more step divs --&gt;
319
+ &lt;/div&gt;</code></pre>
320
+ </div>
321
+ </div>
322
+ </section>
323
+
324
+ <!-- Feature Comparison Pattern -->
325
+ <section class="card no-hover">
326
+ <h3 class="text-lg font-bold border-bottom pb-2 mb-4">Pros/Cons Comparison</h3>
327
+ <p class="mb-4">Use side-by-side cards for comparing options or listing pros/cons.</p>
328
+
329
+ <div class="card-grid-2 gap-6 mb-4">
330
+ <div class="card card-accent-left" data-accent="success">
331
+ <div class="card-body stack-sm">
332
+ <h3 class="font-bold text-success">✓ Pros</h3>
333
+ <ul class="list-styled">
334
+ <li>First advantage point</li>
335
+ <li>Second advantage point</li>
336
+ <li>Third advantage point</li>
337
+ </ul>
338
+ </div>
339
+ </div>
340
+ <div class="card card-accent-left" data-accent="warning">
341
+ <div class="card-body stack-sm">
342
+ <h3 class="font-bold text-warning">✗ Cons</h3>
343
+ <ul class="list-styled">
344
+ <li>First disadvantage point</li>
345
+ <li>Second disadvantage point</li>
346
+ </ul>
347
+ </div>
348
+ </div>
349
+ </div>
350
+
351
+ <div data-component="collapse">
352
+ <button type="button" class="btn btn-sm btn-secondary collapse-trigger" data-action="toggle-collapse" aria-controls="code-comparison" aria-expanded="false">
353
+ <span class="collapse-text-show">Show Code Example</span>
354
+ <span class="collapse-text-hide">Hide Code Example</span>
355
+ </button>
356
+ <div class="collapse-panel mt-3" id="code-comparison">
357
+ <pre class="bg-gray-100 p-3 rounded text-xs overflow-x-auto"><code>&lt;div class="card-grid-2 gap-6"&gt;
358
+ &lt;div class="card card-accent-left" data-accent="success"&gt;
359
+ &lt;div class="card-body stack-sm"&gt;
360
+ &lt;h3 class="font-bold text-success"&gt;✓ Pros&lt;/h3&gt;
361
+ &lt;ul class="list-styled"&gt;
362
+ &lt;li&gt;Advantage&lt;/li&gt;
363
+ &lt;/ul&gt;
364
+ &lt;/div&gt;
365
+ &lt;/div&gt;
366
+ &lt;div class="card card-accent-left" data-accent="warning"&gt;
367
+ &lt;div class="card-body stack-sm"&gt;
368
+ &lt;h3 class="font-bold text-warning"&gt;✗ Cons&lt;/h3&gt;
369
+ &lt;ul class="list-styled"&gt;
370
+ &lt;li&gt;Disadvantage&lt;/li&gt;
371
+ &lt;/ul&gt;
372
+ &lt;/div&gt;
373
+ &lt;/div&gt;
374
+ &lt;/div&gt;</code></pre>
375
+ </div>
376
+ </div>
377
+ </section>
378
+
379
+ <!-- Card with Header -->
380
+ <section class="card no-hover">
381
+ <h3 class="text-lg font-bold border-bottom pb-2 mb-4">Card with Header</h3>
382
+ <p class="mb-4">Use <code>.card-header</code>, <code>.card-body</code>, and <code>.card-footer</code> inside a <code>.card</code>. The header has a default background, auto-bold headings, and bleeds to card edges. No extra classes needed.</p>
383
+
384
+ <div class="card-grid-3 gap-6 mb-4">
385
+ <div class="card">
386
+ <div class="card-header">
387
+ <h4>Default Header</h4>
388
+ </div>
389
+ <div class="card-body stack-sm">
390
+ <p>Just <code>.card-header</code> with an <code>&lt;h4&gt;</code>. Background and bold are automatic.</p>
391
+ </div>
392
+ <div class="card-footer">
393
+ <button class="btn btn-sm btn-primary">Action</button>
394
+ </div>
395
+ </div>
396
+ <div class="card card-accent-top" data-accent="success">
397
+ <div class="card-header">
398
+ <h4>With Subtitle</h4>
399
+ <p class="text-sm text-muted">Subtitle text supported</p>
400
+ </div>
401
+ <div class="card-body stack-sm">
402
+ <ul class="list-styled">
403
+ <li>Combine with <code>.card-accent-top</code></li>
404
+ <li>Subtitles auto-reset margins</li>
405
+ <li>Footer is always optional</li>
406
+ </ul>
407
+ </div>
408
+ </div>
409
+ <div class="card">
410
+ <div class="card-header bg-success-subtle">
411
+ <h4>Custom Background</h4>
412
+ </div>
413
+ <div class="card-body stack-sm">
414
+ <p>Override the default with any <code>.bg-*</code> class on the header.</p>
415
+ </div>
416
+ <div class="card-footer no-border">
417
+ <p class="text-sm text-muted">Footer with <code>.no-border</code></p>
418
+ </div>
419
+ </div>
420
+ </div>
421
+
422
+ <div data-component="collapse">
423
+ <button type="button" class="btn btn-sm btn-secondary collapse-trigger" data-action="toggle-collapse" aria-controls="code-card-header" aria-expanded="false">
424
+ <span class="collapse-text-show">Show Code Example</span>
425
+ <span class="collapse-text-hide">Hide Code Example</span>
426
+ </button>
427
+ <div class="collapse-panel mt-3" id="code-card-header">
428
+ <pre class="bg-gray-100 p-3 rounded text-xs overflow-x-auto"><code>&lt;!-- Simplest usage — background and bold are automatic --&gt;
429
+ &lt;div class="card"&gt;
430
+ &lt;div class="card-header"&gt;
431
+ &lt;h4&gt;Title&lt;/h4&gt;
432
+ &lt;/div&gt;
433
+ &lt;div class="card-body"&gt;
434
+ &lt;p&gt;Content&lt;/p&gt;
435
+ &lt;/div&gt;
436
+ &lt;/div&gt;
437
+
438
+ &lt;!-- With footer --&gt;
439
+ &lt;div class="card"&gt;
440
+ &lt;div class="card-header"&gt;
441
+ &lt;h4&gt;Title&lt;/h4&gt;
442
+ &lt;p class="text-sm text-muted"&gt;Optional subtitle&lt;/p&gt;
443
+ &lt;/div&gt;
444
+ &lt;div class="card-body stack-sm"&gt;
445
+ &lt;p&gt;Body content.&lt;/p&gt;
446
+ &lt;/div&gt;
447
+ &lt;div class="card-footer"&gt;
448
+ &lt;button class="btn btn-sm btn-primary"&gt;Action&lt;/button&gt;
449
+ &lt;/div&gt;
450
+ &lt;/div&gt;
451
+
452
+ &lt;!-- Override header background --&gt;
453
+ &lt;div class="card"&gt;
454
+ &lt;div class="card-header bg-primary-subtle"&gt;
455
+ &lt;h4&gt;Colored&lt;/h4&gt;
456
+ &lt;/div&gt;
457
+ &lt;div class="card-body"&gt;...&lt;/div&gt;
458
+ &lt;/div&gt;</code></pre>
459
+ </div>
460
+ </div>
461
+ </section>
462
+
463
+ <!-- Features Pattern -->
464
+ <section class="card no-hover">
465
+ <h3 class="text-lg font-bold border-bottom pb-2 mb-4">Features Pattern</h3>
466
+ <p class="mb-4">Use for highlighting 3-4 key features or selling points.</p>
467
+
468
+ <div data-component="features" class="mb-4">
469
+ <div class="feature-item">
470
+ <span class="emoji icon-2xl">🚀</span>
471
+ <h3>Fast Performance</h3>
472
+ <p>Lightning-fast load times.</p>
473
+ </div>
474
+ <div class="feature-item">
475
+ <span class="emoji icon-2xl">📱</span>
476
+ <h3>Mobile Ready</h3>
477
+ <p>Works on any device.</p>
478
+ </div>
479
+ <div class="feature-item">
480
+ <span class="emoji icon-2xl">🎨</span>
481
+ <h3>Easy to Customize</h3>
482
+ <p>Full design system support.</p>
483
+ </div>
484
+ </div>
485
+
486
+ <div data-component="collapse">
487
+ <button type="button" class="btn btn-sm btn-secondary collapse-trigger" data-action="toggle-collapse" aria-controls="code-features" aria-expanded="false">
488
+ <span class="collapse-text-show">Show Code Example</span>
489
+ <span class="collapse-text-hide">Hide Code Example</span>
490
+ </button>
491
+ <div class="collapse-panel mt-3" id="code-features">
492
+ <pre class="bg-gray-100 p-3 rounded text-xs overflow-x-auto"><code>&lt;div data-component="features"&gt;
493
+ &lt;div class="feature-item"&gt;
494
+ &lt;span&gt;🚀&lt;/span&gt;
495
+ &lt;h3&gt;Feature Title&lt;/h3&gt;
496
+ &lt;p&gt;Description text.&lt;/p&gt;
497
+ &lt;/div&gt;
498
+ &lt;!-- Add more feature-item divs --&gt;
499
+ &lt;/div&gt;</code></pre>
500
+ </div>
501
+ </div>
502
+ </section>
503
+
504
+ <!-- Comparison Pattern -->
505
+ <section class="card no-hover">
506
+ <h3 class="text-lg font-bold border-bottom pb-2 mb-4">Comparison Pattern</h3>
507
+ <p class="mb-4">Use for comparing two options with one highlighted as recommended.</p>
508
+
509
+ <div data-component="comparison" class="mb-4">
510
+ <div class="comparison-item">
511
+ <h3>Basic Plan</h3>
512
+ <ul class="list-styled">
513
+ <li>Up to 10 users</li>
514
+ <li>5GB storage</li>
515
+ <li>Email support</li>
516
+ </ul>
517
+ </div>
518
+ <div class="comparison-item highlight">
519
+ <h3>Pro Plan ⭐</h3>
520
+ <ul class="list-styled">
521
+ <li>Unlimited users</li>
522
+ <li>100GB storage</li>
523
+ <li>Priority support</li>
524
+ <li>Advanced analytics</li>
525
+ </ul>
526
+ </div>
527
+ </div>
528
+
529
+ <div data-component="collapse">
530
+ <button type="button" class="btn btn-sm btn-secondary collapse-trigger" data-action="toggle-collapse" aria-controls="code-comparison-pattern" aria-expanded="false">
531
+ <span class="collapse-text-show">Show Code Example</span>
532
+ <span class="collapse-text-hide">Hide Code Example</span>
533
+ </button>
534
+ <div class="collapse-panel mt-3" id="code-comparison-pattern">
535
+ <pre class="bg-gray-100 p-3 rounded text-xs overflow-x-auto"><code>&lt;div data-component="comparison"&gt;
536
+ &lt;div class="comparison-item"&gt;
537
+ &lt;h3&gt;Option A&lt;/h3&gt;
538
+ &lt;ul&gt;&lt;li&gt;Feature&lt;/li&gt;&lt;/ul&gt;
539
+ &lt;/div&gt;
540
+ &lt;div class="comparison-item highlight"&gt;
541
+ &lt;h3&gt;Option B (Recommended)&lt;/h3&gt;
542
+ &lt;ul&gt;&lt;li&gt;Feature&lt;/li&gt;&lt;/ul&gt;
543
+ &lt;/div&gt;
544
+ &lt;/div&gt;</code></pre>
545
+ </div>
546
+ </div>
547
+ </section>
548
+
549
+ <!-- Stats Pattern -->
550
+ <section class="card no-hover">
551
+ <h3 class="text-lg font-bold border-bottom pb-2 mb-4">Stats Pattern</h3>
552
+ <p class="mb-4">Use for displaying key metrics or statistics.</p>
553
+
554
+ <div data-component="stats" class="mb-4">
555
+ <div class="stat">
556
+ <span class="stat-value">99%</span>
557
+ <span class="stat-label">Satisfaction</span>
558
+ </div>
559
+ <div class="stat">
560
+ <span class="stat-value">500+</span>
561
+ <span class="stat-label">Courses</span>
562
+ </div>
563
+ <div class="stat">
564
+ <span class="stat-value">24/7</span>
565
+ <span class="stat-label">Support</span>
566
+ </div>
567
+ </div>
568
+
569
+ <div data-component="collapse">
570
+ <button type="button" class="btn btn-sm btn-secondary collapse-trigger" data-action="toggle-collapse" aria-controls="code-stats" aria-expanded="false">
571
+ <span class="collapse-text-show">Show Code Example</span>
572
+ <span class="collapse-text-hide">Hide Code Example</span>
573
+ </button>
574
+ <div class="collapse-panel mt-3" id="code-stats">
575
+ <pre class="bg-gray-100 p-3 rounded text-xs overflow-x-auto"><code>&lt;div data-component="stats"&gt;
576
+ &lt;div class="stat"&gt;
577
+ &lt;span class="stat-value"&gt;99%&lt;/span&gt;
578
+ &lt;span class="stat-label"&gt;Satisfaction&lt;/span&gt;
579
+ &lt;/div&gt;
580
+ &lt;!-- Add more stat divs --&gt;
581
+ &lt;/div&gt;</code></pre>
582
+ </div>
583
+ </div>
584
+ </section>
585
+
586
+ <!-- Hero Pattern -->
587
+ <section class="card no-hover">
588
+ <h3 class="text-lg font-bold border-bottom pb-2 mb-4">Hero Pattern</h3>
589
+ <p class="mb-4">Use for full-width intro sections with a call to action.</p>
590
+
591
+ <div data-component="hero" class="hero-gradient mb-4">
592
+ <div class="hero-content">
593
+ <h2 class="hero-title">Welcome to the Course</h2>
594
+ <p class="hero-subtitle">Learn everything you need to know about our topic.</p>
595
+ <div class="hero-cta">
596
+ <button class="btn btn-primary">Get Started</button>
597
+ </div>
598
+ </div>
599
+ </div>
600
+
601
+ <div data-component="collapse">
602
+ <button type="button" class="btn btn-sm btn-secondary collapse-trigger" data-action="toggle-collapse" aria-controls="code-hero" aria-expanded="false">
603
+ <span class="collapse-text-show">Show Code Example</span>
604
+ <span class="collapse-text-hide">Hide Code Example</span>
605
+ </button>
606
+ <div class="collapse-panel mt-3" id="code-hero">
607
+ <pre class="bg-gray-100 p-3 rounded text-xs overflow-x-auto"><code>&lt;div data-component="hero" class="hero-gradient"&gt;
608
+ &lt;div class="hero-content"&gt;
609
+ &lt;h1 class="hero-title"&gt;Welcome&lt;/h1&gt;
610
+ &lt;p class="hero-subtitle"&gt;Subtitle text&lt;/p&gt;
611
+ &lt;div class="hero-cta"&gt;
612
+ &lt;button class="btn btn-primary"&gt;Get Started&lt;/button&gt;
613
+ &lt;/div&gt;
614
+ &lt;/div&gt;
615
+ &lt;/div&gt;</code></pre>
616
+ </div>
617
+ </div>
618
+ </section>
619
+
620
+ <!-- Timeline Pattern -->
621
+ <section class="card no-hover">
622
+ <h3 class="text-lg font-bold border-bottom pb-2 mb-4">Timeline Pattern</h3>
623
+ <p class="mb-4">Use for chronological events or history. (Note: This is a static pattern; see Interactive tab for the interactive timeline component.)</p>
624
+
625
+ <div data-component="timeline" class="mb-4">
626
+ <div class="timeline-item">
627
+ <span class="timeline-date">2020</span>
628
+ <div class="timeline-marker"></div>
629
+ <div class="timeline-content">
630
+ <h3>Company Founded</h3>
631
+ <p>We started with a simple idea to revolutionize learning.</p>
632
+ </div>
633
+ </div>
634
+ <div class="timeline-item">
635
+ <span class="timeline-date">2022</span>
636
+ <div class="timeline-marker"></div>
637
+ <div class="timeline-content">
638
+ <h3>Major Milestone</h3>
639
+ <p>Reached 1 million users across 50 countries.</p>
640
+ </div>
641
+ </div>
642
+ <div class="timeline-item">
643
+ <span class="timeline-date">2024</span>
644
+ <div class="timeline-marker"></div>
645
+ <div class="timeline-content">
646
+ <h3>AI Integration</h3>
647
+ <p>Launched AI-powered authoring tools.</p>
648
+ </div>
649
+ </div>
650
+ </div>
651
+
652
+ <div data-component="collapse">
653
+ <button type="button" class="btn btn-sm btn-secondary collapse-trigger" data-action="toggle-collapse" aria-controls="code-timeline" aria-expanded="false">
654
+ <span class="collapse-text-show">Show Code Example</span>
655
+ <span class="collapse-text-hide">Hide Code Example</span>
656
+ </button>
657
+ <div class="collapse-panel mt-3" id="code-timeline">
658
+ <pre class="bg-gray-100 p-3 rounded text-xs overflow-x-auto"><code>&lt;div data-component="timeline"&gt;
659
+ &lt;div class="timeline-item"&gt;
660
+ &lt;span class="timeline-date"&gt;2020&lt;/span&gt;
661
+ &lt;div class="timeline-marker"&gt;&lt;/div&gt;
662
+ &lt;div class="timeline-content"&gt;
663
+ &lt;h3&gt;Event Title&lt;/h3&gt;
664
+ &lt;p&gt;Description&lt;/p&gt;
665
+ &lt;/div&gt;
666
+ &lt;/div&gt;
667
+ &lt;/div&gt;</code></pre>
668
+ </div>
669
+ </div>
670
+ </section>
671
+
672
+ <!-- Quote Pattern -->
673
+ <section class="card no-hover">
674
+ <h3 class="text-lg font-bold border-bottom pb-2 mb-4">Quote Pattern</h3>
675
+ <p class="mb-4">Use for testimonials, quotes, or citations.</p>
676
+
677
+ <div data-component="quote" class="quote-card mb-4">
678
+ <p class="quote-text">"This training completely changed how I approach my work. The interactive elements made complex topics easy to understand."</p>
679
+ <div class="quote-attribution">
680
+ <img class="quote-avatar" src="https://i.pravatar.cc/80?img=32" alt="Jane Smith">
681
+ <span class="quote-author">Jane Smith</span>
682
+ <span class="quote-role">Senior Manager, Acme Corp</span>
683
+ </div>
684
+ </div>
685
+
686
+ <div data-component="collapse">
687
+ <button type="button" class="btn btn-sm btn-secondary collapse-trigger" data-action="toggle-collapse" aria-controls="code-quote" aria-expanded="false">
688
+ <span class="collapse-text-show">Show Code Example</span>
689
+ <span class="collapse-text-hide">Hide Code Example</span>
690
+ </button>
691
+ <div class="collapse-panel mt-3" id="code-quote">
692
+ <pre class="bg-gray-100 p-3 rounded text-xs overflow-x-auto"><code>&lt;div data-component="quote" class="quote-card"&gt;
693
+ &lt;p class="quote-text"&gt;"Quote text here."&lt;/p&gt;
694
+ &lt;div class="quote-attribution"&gt;
695
+ &lt;img class="quote-avatar" src="avatar.jpg" alt="Name"&gt;
696
+ &lt;span class="quote-author"&gt;Name&lt;/span&gt;
697
+ &lt;span class="quote-role"&gt;Title&lt;/span&gt;
698
+ &lt;/div&gt;
699
+ &lt;/div&gt;</code></pre>
700
+ </div>
701
+ </div>
702
+ </section>
703
+
704
+ <!-- Checklist Pattern -->
705
+ <section class="card no-hover">
706
+ <h3 class="text-lg font-bold border-bottom pb-2 mb-4">Checklist Pattern</h3>
707
+ <p class="mb-4">Use for task lists, requirements, or progress tracking.</p>
708
+
709
+ <div data-component="checklist" class="mb-4">
710
+ <div class="checklist-progress">
711
+ <div class="checklist-progress-bar">
712
+ <div class="checklist-progress-fill" style="width: 60%"></div>
713
+ </div>
714
+ <span class="checklist-progress-text">3 of 5 complete</span>
715
+ </div>
716
+ <div class="checklist-item completed">
717
+ <div class="checklist-text"><strong>Complete orientation</strong></div>
718
+ </div>
719
+ <div class="checklist-item completed">
720
+ <div class="checklist-text"><strong>Watch training videos</strong></div>
721
+ </div>
722
+ <div class="checklist-item completed">
723
+ <div class="checklist-text"><strong>Read documentation</strong></div>
724
+ </div>
725
+ <div class="checklist-item">
726
+ <div class="checklist-text"><strong>Pass assessment</strong></div>
727
+ <span class="checklist-status status-required">Required</span>
728
+ </div>
729
+ <div class="checklist-item">
730
+ <div class="checklist-text"><strong>Get certified</strong></div>
731
+ </div>
732
+ </div>
733
+
734
+ <div data-component="collapse">
735
+ <button type="button" class="btn btn-sm btn-secondary collapse-trigger" data-action="toggle-collapse" aria-controls="code-checklist" aria-expanded="false">
736
+ <span class="collapse-text-show">Show Code Example</span>
737
+ <span class="collapse-text-hide">Hide Code Example</span>
738
+ </button>
739
+ <div class="collapse-panel mt-3" id="code-checklist">
740
+ <pre class="bg-gray-100 p-3 rounded text-xs overflow-x-auto"><code>&lt;div data-component="checklist"&gt;
741
+ &lt;div class="checklist-progress"&gt;
742
+ &lt;div class="checklist-progress-bar"&gt;
743
+ &lt;div class="checklist-progress-fill" style="width: 60%"&gt;&lt;/div&gt;
744
+ &lt;/div&gt;
745
+ &lt;span class="checklist-progress-text"&gt;3 of 5 complete&lt;/span&gt;
746
+ &lt;/div&gt;
747
+ &lt;div class="checklist-item completed"&gt;
748
+ &lt;div class="checklist-text"&gt;&lt;strong&gt;Task&lt;/strong&gt;&lt;/div&gt;
749
+ &lt;/div&gt;
750
+ &lt;div class="checklist-item"&gt;
751
+ &lt;div class="checklist-text"&gt;&lt;strong&gt;Task&lt;/strong&gt;&lt;/div&gt;
752
+ &lt;span class="checklist-status status-required"&gt;Required&lt;/span&gt;
753
+ &lt;/div&gt;
754
+ &lt;/div&gt;</code></pre>
755
+ </div>
756
+ </div>
757
+ </section>
758
+
759
+ </div>
760
+ </div>
761
+
762
+ <!-- Tab 2: Interactive -->
763
+ <div id="interactive" class="tab-content" role="tabpanel" hidden>
764
+ <div class="stack-lg">
765
+
766
+ <!-- Accordion -->
767
+ <section class="card no-hover">
768
+ <h3 class="text-lg font-bold border-bottom pb-2 mb-4">Accordion</h3>
769
+ <div class="accordion mb-4" id="demo-accordion" data-component="accordion" data-mode="multi">
770
+ <div data-title="Section 1">
771
+ Content for section 1.
772
+ </div>
773
+ <div data-title="Section 2">
774
+ Content for section 2.
775
+ </div>
776
+ </div>
777
+
778
+ <div data-component="collapse">
779
+ <button type="button" class="btn btn-sm btn-secondary collapse-trigger" data-action="toggle-collapse" aria-controls="code-accordion" aria-expanded="false">
780
+ <span class="collapse-text-show">Show Code Example</span>
781
+ <span class="collapse-text-hide">Hide Code Example</span>
782
+ </button>
783
+ <div class="collapse-panel mt-3" id="code-accordion">
784
+ <pre class="bg-gray-100 p-3 rounded text-xs overflow-x-auto"><code>&lt;div class="accordion" data-component="accordion" data-mode="multi"&gt;
785
+ &lt;div data-title="Section Title"&gt;
786
+ Content here.
787
+ &lt;/div&gt;
788
+ &lt;/div&gt;</code></pre>
789
+ </div>
790
+ </div>
791
+ </section>
792
+
793
+ <!-- Collapse (Show/Hide) -->
794
+ <section class="card no-hover">
795
+ <h3 class="text-lg font-bold border-bottom pb-2 mb-4">Collapse (Show/Hide)</h3>
796
+ <div data-component="collapse" class="mb-4">
797
+ <button class="btn btn-secondary collapse-trigger" data-action="toggle-collapse" aria-controls="demo-collapse" aria-expanded="false">
798
+ <span class="collapse-text-show">Show Transcript</span>
799
+ <span class="collapse-text-hide">Hide Transcript</span>
800
+ </button>
801
+ <div class="collapse-panel mt-3" id="demo-collapse">
802
+ <div class="p-4 bg-gray-100 rounded">
803
+ <p>This is expandable content that can be shown or hidden. Use it for transcripts, additional details, or optional information that doesn't need to be visible by default.</p>
804
+ </div>
805
+ </div>
806
+ </div>
807
+
808
+ <div data-component="collapse">
809
+ <button type="button" class="btn btn-sm btn-secondary collapse-trigger" data-action="toggle-collapse" aria-controls="code-collapse" aria-expanded="false">
810
+ <span class="collapse-text-show">Show Code Example</span>
811
+ <span class="collapse-text-hide">Hide Code Example</span>
812
+ </button>
813
+ <div class="collapse-panel mt-3" id="code-collapse">
814
+ <pre class="bg-gray-100 p-3 rounded text-xs overflow-x-auto"><code>&lt;div data-component="collapse"&gt;
815
+ &lt;button class="btn btn-secondary collapse-trigger" data-action="toggle-collapse" aria-controls="my-panel"&gt;
816
+ &lt;span class="collapse-text-show"&gt;Show&lt;/span&gt;
817
+ &lt;span class="collapse-text-hide"&gt;Hide&lt;/span&gt;
818
+ &lt;/button&gt;
819
+ &lt;div class="collapse-panel mt-3" id="my-panel"&gt;
820
+ Content here.
821
+ &lt;/div&gt;
822
+ &lt;/div&gt;</code></pre>
823
+ </div>
824
+ </div>
825
+ </section>
826
+
827
+ <!-- Modals -->
828
+ <section class="card no-hover">
829
+ <h3 class="text-lg font-bold border-bottom pb-2 mb-4">Modals</h3>
830
+ <div class="flex gap-2 mb-4">
831
+ <button class="btn btn-primary"
832
+ data-component="modal-trigger"
833
+ data-title="Demo Modal"
834
+ data-body="#demo-modal-body"
835
+ data-footer="#demo-modal-footer"
836
+ data-audio-src="audio/example-ui-showcase--demo-modal.mp3"
837
+ data-audio-required="false">
838
+ Launch Modal with Audio
839
+ </button>
840
+ </div>
841
+
842
+ <div data-component="collapse">
843
+ <button type="button" class="btn btn-sm btn-secondary collapse-trigger" data-action="toggle-collapse" aria-controls="code-modal" aria-expanded="false">
844
+ <span class="collapse-text-show">Show Code Example</span>
845
+ <span class="collapse-text-hide">Hide Code Example</span>
846
+ </button>
847
+ <div class="collapse-panel mt-3" id="code-modal">
848
+ <pre class="bg-gray-100 p-3 rounded text-xs overflow-x-auto"><code>&lt;button class="btn btn-primary"
849
+ data-component="modal-trigger"
850
+ data-title="Modal Title"
851
+ data-body="#my-modal-body"
852
+ data-footer="#my-modal-footer"&gt;
853
+ Open Modal
854
+ &lt;/button&gt;</code></pre>
855
+ </div>
856
+ </div>
857
+ </section>
858
+
859
+ <!-- Flip Cards -->
860
+ <section class="card no-hover">
861
+ <h3 class="text-lg font-bold border-bottom pb-2 mb-4">Flip Cards</h3>
862
+ <div class="cols-3 gap-4 mb-4">
863
+ <div class="flip-card" data-component="flip-card">
864
+ <div class="flip-card-inner">
865
+ <div class="flip-card-front">
866
+ <span class="flip-card-icon">🃏</span>
867
+ <h3 class="flip-card-title">Default</h3>
868
+ <p class="text-sm text-muted">Click to reveal</p>
869
+ </div>
870
+ <div class="flip-card-back">
871
+ <h3 class="flip-card-title">Back Side</h3>
872
+ <p class="flip-card-text">Primary gradient background</p>
873
+ </div>
874
+ </div>
875
+ </div>
876
+ <div class="flip-card" data-component="flip-card">
877
+ <div class="flip-card-inner">
878
+ <div class="flip-card-front">
879
+ <span class="flip-card-icon">🎨</span>
880
+ <h3 class="flip-card-title">Secondary</h3>
881
+ <p class="text-sm text-muted">Click to reveal</p>
882
+ </div>
883
+ <div class="flip-card-back bg-secondary">
884
+ <h3 class="flip-card-title">Variant</h3>
885
+ <p class="flip-card-text">Using .bg-secondary</p>
886
+ </div>
887
+ </div>
888
+ </div>
889
+ <div class="flip-card" data-component="flip-card">
890
+ <div class="flip-card-inner">
891
+ <div class="flip-card-front">
892
+ <span class="flip-card-icon">📋</span>
893
+ <h3 class="flip-card-title">More Variants</h3>
894
+ <p class="text-sm text-muted">Click for list</p>
895
+ </div>
896
+ <div class="flip-card-back bg-dark">
897
+ <h3 class="flip-card-title">Back Variants</h3>
898
+ <p class="flip-card-text text-xs">.bg-light, .bg-dark, .bg-success-subtle, .bg-warning-subtle, .bg-danger-subtle, .bg-info-subtle</p>
899
+ </div>
900
+ </div>
901
+ </div>
902
+ </div>
903
+
904
+ <div data-component="collapse">
905
+ <button type="button" class="btn btn-sm btn-secondary collapse-trigger" data-action="toggle-collapse" aria-controls="code-flipcard" aria-expanded="false">
906
+ <span class="collapse-text-show">Show Code Example</span>
907
+ <span class="collapse-text-hide">Hide Code Example</span>
908
+ </button>
909
+ <div class="collapse-panel mt-3" id="code-flipcard">
910
+ <pre class="bg-gray-100 p-3 rounded text-xs overflow-x-auto"><code>&lt;div class="flip-card" data-component="flip-card"&gt;
911
+ &lt;div class="flip-card-inner"&gt;
912
+ &lt;div class="flip-card-front"&gt;
913
+ &lt;span class="flip-card-icon"&gt;🃏&lt;/span&gt;
914
+ &lt;h3 class="flip-card-title"&gt;Title&lt;/h3&gt;
915
+ &lt;/div&gt;
916
+ &lt;div class="flip-card-back"&gt;
917
+ &lt;h3 class="flip-card-title"&gt;Back&lt;/h3&gt;
918
+ &lt;p class="flip-card-text"&gt;Content&lt;/p&gt;
919
+ &lt;/div&gt;
920
+ &lt;/div&gt;
921
+ &lt;/div&gt;</code></pre>
922
+ </div>
923
+ </div>
924
+ </section>
925
+
926
+ <!-- Interactive Timeline -->
927
+ <section class="card no-hover">
928
+ <h3 class="text-lg font-bold border-bottom pb-2 mb-4">Interactive Timeline</h3>
929
+ <p class="mb-4">Click each event to expand details. Use <code>data-component="interactive-timeline"</code> for auto-initialization.</p>
930
+ <div class="interactive-timeline" id="demo-timeline" data-component="interactive-timeline">
931
+ <div class="timeline-event" data-event-id="1998" tabindex="0">
932
+ <div class="timeline-marker"></div>
933
+ <div class="timeline-date">1998</div>
934
+ <div class="timeline-summary">
935
+ <h4>AICC Standard</h4>
936
+ <p>First interoperability standard</p>
937
+ </div>
938
+ <div class="timeline-details">
939
+ <p>The Aviation Industry CBT Committee established the first standards for computer-based training interoperability, enabling courses to work across different LMS platforms.</p>
940
+ </div>
941
+ </div>
942
+ <div class="timeline-event" data-event-id="2001" tabindex="-1">
943
+ <div class="timeline-marker"></div>
944
+ <div class="timeline-date">2001</div>
945
+ <div class="timeline-summary">
946
+ <h4>SCORM 1.2</h4>
947
+ <p>Industry standard adopted</p>
948
+ </div>
949
+ <div class="timeline-details">
950
+ <p>SCORM 1.2 became the dominant standard for eLearning content packaging and runtime communication, still widely used today in legacy systems.</p>
951
+ </div>
952
+ </div>
953
+ <div class="timeline-event" data-event-id="2013" tabindex="-1">
954
+ <div class="timeline-marker"></div>
955
+ <div class="timeline-date">2013</div>
956
+ <div class="timeline-summary">
957
+ <h4>xAPI / Tin Can</h4>
958
+ <p>Experience tracking arrives</p>
959
+ </div>
960
+ <div class="timeline-details">
961
+ <p>The Experience API (xAPI) introduced statement-based tracking, enabling learning experiences beyond the LMS — from mobile apps to simulations to real-world activities.</p>
962
+ </div>
963
+ </div>
964
+ <div class="timeline-event" data-event-id="2016" tabindex="-1">
965
+ <div class="timeline-marker"></div>
966
+ <div class="timeline-date">2016</div>
967
+ <div class="timeline-summary">
968
+ <h4>cmi5</h4>
969
+ <p>xAPI meets LMS</p>
970
+ </div>
971
+ <div class="timeline-details">
972
+ <p>cmi5 bridged the gap between xAPI's flexibility and LMS requirements, providing a standardized profile for launching and tracking content in managed learning environments.</p>
973
+ </div>
974
+ </div>
975
+ </div>
976
+
977
+ <div data-component="collapse" class="mt-4">
978
+ <button type="button" class="btn btn-sm btn-secondary collapse-trigger" data-action="toggle-collapse" aria-controls="code-interactive-timeline" aria-expanded="false">
979
+ <span class="collapse-text-show">Show Code Example</span>
980
+ <span class="collapse-text-hide">Hide Code Example</span>
981
+ </button>
982
+ <div class="collapse-panel mt-3" id="code-interactive-timeline">
983
+ <pre class="bg-gray-100 p-3 rounded text-xs overflow-x-auto"><code>&lt;div class="interactive-timeline" data-component="interactive-timeline"&gt;
984
+ &lt;div class="timeline-event" data-event-id="2020" tabindex="0"&gt;
985
+ &lt;div class="timeline-marker"&gt;&lt;/div&gt;
986
+ &lt;div class="timeline-date"&gt;2020&lt;/div&gt;
987
+ &lt;div class="timeline-summary"&gt;
988
+ &lt;h4&gt;Event Title&lt;/h4&gt;
989
+ &lt;p&gt;Brief summary&lt;/p&gt;
990
+ &lt;/div&gt;
991
+ &lt;div class="timeline-details"&gt;
992
+ &lt;p&gt;Expanded details shown on click.&lt;/p&gt;
993
+ &lt;/div&gt;
994
+ &lt;/div&gt;
995
+ &lt;/div&gt;</code></pre>
996
+ </div>
997
+ </div>
998
+ </section>
999
+
1000
+ <!-- Embed Frame (Custom Widget) -->
1001
+ <section class="card no-hover">
1002
+ <h3 class="text-lg font-bold border-bottom pb-2 mb-4">Embed Frame (Custom HTML/JS App)</h3>
1003
+ <p class="mb-4">Embed sandboxed HTML/JS applications using <code>data-component="embed-frame"</code>. The iframe provides complete CSS isolation and communicates via <code>postMessage</code>.</p>
1004
+
1005
+ <div class="cols-2 gap-6" style="align-items: start;">
1006
+ <!-- The Widget -->
1007
+ <div class="stack-sm">
1008
+ <div data-component="embed-frame"
1009
+ data-src="assets/widgets/gravity-painter.html"
1010
+ data-embed-id="gravity-painter"
1011
+ data-aspect-ratio="3/4">
1012
+ </div>
1013
+ <p class="text-xs text-muted text-center">✨ Click and drag to paint with particles • Create 100+ to complete</p>
1014
+ </div>
1015
+
1016
+ <!-- Feature Notes -->
1017
+ <div class="stack-md">
1018
+ <div class="callout callout--info callout--compact">
1019
+ <h4 class="font-bold text-sm mb-2">🔒 CSS Isolation</h4>
1020
+ <p class="text-sm">Course styles don't affect the widget. The iframe creates a completely separate styling context.</p>
1021
+ </div>
1022
+
1023
+ <div class="callout callout--success callout--compact">
1024
+ <h4 class="font-bold text-sm mb-2">📡 postMessage Bridge</h4>
1025
+ <p class="text-sm">Widget sets flags via <code>coursecode:flag</code> messages. Works with existing engagement requirements.</p>
1026
+ </div>
1027
+
1028
+ <div class="callout callout--compact">
1029
+ <h4 class="font-bold text-sm mb-2">📐 Aspect Ratio</h4>
1030
+ <p class="text-sm">Use <code>data-aspect-ratio</code> for fixed proportions, or omit for auto-height mode with resize messages.</p>
1031
+ </div>
1032
+
1033
+ <div class="callout callout--warning callout--compact">
1034
+ <h4 class="font-bold text-sm mb-2">⚡ Engagement Gating</h4>
1035
+ <p class="text-sm">Gate with <code>{ type: 'flag', key: 'gravity-painter-complete' }</code> in requirements.</p>
1036
+ </div>
1037
+ </div>
1038
+ </div>
1039
+
1040
+ <div data-component="collapse" class="mt-4">
1041
+ <button type="button" class="btn btn-sm btn-secondary collapse-trigger" data-action="toggle-collapse" aria-controls="code-embed-frame" aria-expanded="false">
1042
+ <span class="collapse-text-show">Show Code Example</span>
1043
+ <span class="collapse-text-hide">Hide Code Example</span>
1044
+ </button>
1045
+ <div class="collapse-panel mt-3" id="code-embed-frame">
1046
+ <pre class="bg-gray-100 p-3 rounded text-xs overflow-x-auto"><code>&lt;div data-component="embed-frame"
1047
+ data-src="assets/widgets/my-widget.html"
1048
+ data-embed-id="my-widget"
1049
+ data-aspect-ratio="16/9"&gt;
1050
+ &lt;/div&gt;</code></pre>
1051
+ </div>
1052
+ </div>
1053
+ </section>
1054
+ </div>
1055
+ </div>
1056
+
1057
+ <!-- Tab 3: Forms -->
1058
+ <div id="forms" class="tab-content" role="tabpanel" hidden>
1059
+ <div class="stack-lg">
1060
+
1061
+ <form data-component="form-validator" data-success-message="Form valid!" class="stack-lg">
1062
+
1063
+ <!-- Inputs -->
1064
+ <section class="card no-hover">
1065
+ <h3 class="text-lg font-bold border-bottom pb-2 mb-4">Text Inputs</h3>
1066
+ <div class="stack-md">
1067
+ <div class="form-group">
1068
+ <label class="form-label required">Username</label>
1069
+ <input type="text" class="form-control" required placeholder="Enter username">
1070
+ </div>
1071
+ <div class="form-group">
1072
+ <label class="form-label">Bio</label>
1073
+ <textarea class="form-control" rows="3"></textarea>
1074
+ <span class="form-help">Tell us about yourself</span>
1075
+ </div>
1076
+ </div>
1077
+
1078
+ <div data-component="collapse" class="mt-3">
1079
+ <button type="button" class="btn btn-sm btn-secondary collapse-trigger" data-action="toggle-collapse" aria-controls="code-text-inputs" aria-expanded="false">
1080
+ <span class="collapse-text-show">Show Code Example</span>
1081
+ <span class="collapse-text-hide">Hide Code Example</span>
1082
+ </button>
1083
+ <div class="collapse-panel mt-3" id="code-text-inputs">
1084
+ <pre class="bg-gray-100 p-3 rounded text-xs overflow-x-auto"><code>&lt;div class="form-group"&gt;
1085
+ &lt;label class="form-label required"&gt;Label&lt;/label&gt;
1086
+ &lt;input type="text" class="form-control" required&gt;
1087
+ &lt;/div&gt;</code></pre>
1088
+ </div>
1089
+ </div>
1090
+ </section>
1091
+
1092
+ <!-- Toggles -->
1093
+ <section class="card no-hover">
1094
+ <h3 class="text-lg font-bold border-bottom pb-2 mb-4">Toggles</h3>
1095
+ <div id="demo-toggles" data-component="toggle-group" class="stack-sm">
1096
+ <label class="toggle-switch">
1097
+ <input type="checkbox" data-label="Default Toggle">
1098
+ <span class="toggle-slider"></span>
1099
+ <span class="toggle-label">Default Toggle</span>
1100
+ </label>
1101
+ <label class="toggle-switch toggle-success">
1102
+ <input type="checkbox" checked data-label="Success Toggle">
1103
+ <span class="toggle-slider"></span>
1104
+ <span class="toggle-label">Success Toggle</span>
1105
+ </label>
1106
+ </div>
1107
+
1108
+ <div data-component="collapse" class="mt-3">
1109
+ <button type="button" class="btn btn-sm btn-secondary collapse-trigger" data-action="toggle-collapse" aria-controls="code-toggles" aria-expanded="false">
1110
+ <span class="collapse-text-show">Show Code Example</span>
1111
+ <span class="collapse-text-hide">Hide Code Example</span>
1112
+ </button>
1113
+ <div class="collapse-panel mt-3" id="code-toggles">
1114
+ <pre class="bg-gray-100 p-3 rounded text-xs overflow-x-auto"><code>&lt;label class="toggle-switch"&gt;
1115
+ &lt;input type="checkbox" data-label="Toggle Label"&gt;
1116
+ &lt;span class="toggle-slider"&gt;&lt;/span&gt;
1117
+ &lt;span class="toggle-label"&gt;Toggle Label&lt;/span&gt;
1118
+ &lt;/label&gt;</code></pre>
1119
+ </div>
1120
+ </div>
1121
+ </section>
1122
+
1123
+ <!-- Radios & Checkboxes -->
1124
+ <section class="card no-hover">
1125
+ <h3 class="text-lg font-bold border-bottom pb-2 mb-4">Selection Controls</h3>
1126
+ <div class="cols-2 gap-6">
1127
+ <div>
1128
+ <h4 class="text-sm font-bold mb-2">Radio Group</h4>
1129
+ <div class="radio-group" id="demo-radios">
1130
+ <label class="radio-option">
1131
+ <input type="radio" name="demo-radio" value="Option 1">
1132
+ <span class="radio-custom"></span>
1133
+ <div class="radio-label">Option 1</div>
1134
+ </label>
1135
+ <label class="radio-option">
1136
+ <input type="radio" name="demo-radio" value="Option 2">
1137
+ <span class="radio-custom"></span>
1138
+ <div class="radio-label">Option 2</div>
1139
+ </label>
1140
+ </div>
1141
+ </div>
1142
+ <div>
1143
+ <h4 class="text-sm font-bold mb-2">Checkbox Group</h4>
1144
+ <div class="checkbox-group" id="demo-checkboxes" data-component="checkbox-group">
1145
+ <label class="checkbox-option">
1146
+ <input type="checkbox" value="Choice A">
1147
+ <span class="checkbox-custom"></span>
1148
+ <div class="checkbox-label">Choice A</div>
1149
+ </label>
1150
+ <label class="checkbox-option">
1151
+ <input type="checkbox" value="Choice B">
1152
+ <span class="checkbox-custom"></span>
1153
+ <div class="checkbox-label">Choice B</div>
1154
+ </label>
1155
+ </div>
1156
+ </div>
1157
+ </div>
1158
+
1159
+ <div data-component="collapse" class="mt-3">
1160
+ <button type="button" class="btn btn-sm btn-secondary collapse-trigger" data-action="toggle-collapse" aria-controls="code-selection" aria-expanded="false">
1161
+ <span class="collapse-text-show">Show Code Example</span>
1162
+ <span class="collapse-text-hide">Hide Code Example</span>
1163
+ </button>
1164
+ <div class="collapse-panel mt-3" id="code-selection">
1165
+ <pre class="bg-gray-100 p-3 rounded text-xs overflow-x-auto"><code>&lt;label class="radio-option"&gt;
1166
+ &lt;input type="radio" name="group" value="value"&gt;
1167
+ &lt;span class="radio-custom"&gt;&lt;/span&gt;
1168
+ &lt;div class="radio-label"&gt;Label&lt;/div&gt;
1169
+ &lt;/label&gt;</code></pre>
1170
+ </div>
1171
+ </div>
1172
+ </section>
1173
+
1174
+ <!-- Dropdown -->
1175
+ <section class="card no-hover">
1176
+ <h3 class="text-lg font-bold border-bottom pb-2 mb-4">Custom Dropdown</h3>
1177
+ <div class="form-group">
1178
+ <label class="form-label">Select Item</label>
1179
+ <div class="custom-dropdown" id="demo-dropdown" data-component="dropdown">
1180
+ <button type="button" class="dropdown-trigger" data-action="toggle-dropdown">
1181
+ <span class="dropdown-text">Choose...</span>
1182
+ </button>
1183
+ <div class="dropdown-menu">
1184
+ <div class="dropdown-item" data-value="Item 1" data-action="select-item">Item 1</div>
1185
+ <div class="dropdown-item" data-value="Item 2" data-action="select-item">Item 2</div>
1186
+ <div class="dropdown-item" data-value="Item 3" data-action="select-item">Item 3</div>
1187
+ </div>
1188
+ </div>
1189
+ </div>
1190
+
1191
+ <div data-component="collapse" class="mt-3">
1192
+ <button type="button" class="btn btn-sm btn-secondary collapse-trigger" data-action="toggle-collapse" aria-controls="code-dropdown" aria-expanded="false">
1193
+ <span class="collapse-text-show">Show Code Example</span>
1194
+ <span class="collapse-text-hide">Hide Code Example</span>
1195
+ </button>
1196
+ <div class="collapse-panel mt-3" id="code-dropdown">
1197
+ <pre class="bg-gray-100 p-3 rounded text-xs overflow-x-auto"><code>&lt;div class="custom-dropdown" data-component="dropdown"&gt;
1198
+ &lt;button type="button" class="dropdown-trigger" data-action="toggle-dropdown"&gt;
1199
+ &lt;span class="dropdown-text"&gt;Select...&lt;/span&gt;
1200
+ &lt;/button&gt;
1201
+ &lt;div class="dropdown-menu"&gt;
1202
+ &lt;div class="dropdown-item" data-value="1" data-action="select-item"&gt;Item 1&lt;/div&gt;
1203
+ &lt;/div&gt;
1204
+ &lt;/div&gt;</code></pre>
1205
+ </div>
1206
+ </div>
1207
+ </section>
1208
+
1209
+ <div class="mt-4">
1210
+ <button type="submit" class="btn btn-primary">Validate Form</button>
1211
+ </div>
1212
+
1213
+ </form>
1214
+ </div>
1215
+ </div>
1216
+
1217
+ <!-- Tab 4: Feedback -->
1218
+ <div id="feedback" class="tab-content" role="tabpanel" hidden>
1219
+ <div class="stack-lg">
1220
+
1221
+ <!-- Notifications -->
1222
+ <section class="card no-hover">
1223
+ <h3 class="text-lg font-bold border-bottom pb-2 mb-4">Notifications</h3>
1224
+ <p class="mb-4">Toast notifications that appear at the top right.</p>
1225
+ <div class="flex flex-wrap gap-2">
1226
+ <button class="btn btn-success" data-action="show-notification" data-type="success" data-message="Success message!">Success</button>
1227
+ <button class="btn btn-info" data-action="show-notification" data-type="info" data-message="Info message.">Info</button>
1228
+ <button class="btn btn-warning" data-action="show-notification" data-type="warning" data-message="Warning message.">Warning</button>
1229
+ <button class="btn btn-danger" data-action="show-notification" data-type="danger" data-message="Error message.">Error</button>
1230
+ </div>
1231
+
1232
+ <div data-component="collapse" class="mt-4">
1233
+ <button type="button" class="btn btn-sm btn-secondary collapse-trigger" data-action="toggle-collapse" aria-controls="code-notifications" aria-expanded="false">
1234
+ <span class="collapse-text-show">Show Code Example</span>
1235
+ <span class="collapse-text-hide">Hide Code Example</span>
1236
+ </button>
1237
+ <div class="collapse-panel mt-3" id="code-notifications">
1238
+ <pre class="bg-gray-100 p-3 rounded text-xs overflow-x-auto"><code>&lt;button data-action="show-notification"
1239
+ data-type="success"
1240
+ data-message="Success message!"&gt;
1241
+ Show Notification
1242
+ &lt;/button&gt;</code></pre>
1243
+ </div>
1244
+ </div>
1245
+ </section>
1246
+
1247
+ <!-- Tooltips -->
1248
+ <section class="card no-hover">
1249
+ <h3 class="text-lg font-bold border-bottom pb-2 mb-4">Tooltips</h3>
1250
+ <div class="stack-md">
1251
+
1252
+ <p class="font-bold mb-0">Positions</p>
1253
+ <div class="flex flex-wrap gap-3">
1254
+ <button class="btn btn-secondary" data-tooltip="Top position (default)" data-tooltip-position="top">Top</button>
1255
+ <button class="btn btn-secondary" data-tooltip="Right position" data-tooltip-position="right">Right</button>
1256
+ <button class="btn btn-secondary" data-tooltip="Bottom position" data-tooltip-position="bottom">Bottom</button>
1257
+ <button class="btn btn-secondary" data-tooltip="Left position" data-tooltip-position="left">Left</button>
1258
+ </div>
1259
+
1260
+ <p class="font-bold mb-0">Timing</p>
1261
+ <div class="flex flex-wrap gap-3">
1262
+ <button class="btn btn-secondary" data-tooltip="Default 500ms delay">Default (500ms)</button>
1263
+ <button class="btn btn-secondary" data-tooltip="Instant — no delay!" data-tooltip-delay="0">Instant</button>
1264
+ <button class="btn btn-secondary" data-tooltip="Longer 1s delay" data-tooltip-delay="1000">Slow (1s)</button>
1265
+ </div>
1266
+
1267
+ <p class="font-bold mb-0">Themes &amp; Customization</p>
1268
+ <div class="flex flex-wrap gap-3">
1269
+ <button class="btn btn-secondary" data-tooltip="Dark theme (default)">Dark</button>
1270
+ <button class="btn btn-secondary" data-tooltip="Light theme variant" data-tooltip-theme="light">Light</button>
1271
+ <button class="btn btn-secondary" data-tooltip="This tooltip has a wider max-width of 400px, useful for longer explanations." data-tooltip-width="400">Wide (400px)</button>
1272
+ <button class="btn btn-secondary" data-tooltip="Line 1\\nLine 2\\nLine 3">Multi-line</button>
1273
+ </div>
1274
+
1275
+ <p class="font-bold mb-0">Icon Tooltips</p>
1276
+ <p>Use <code>.tooltip-icon</code> for inline contextual help<span class="tooltip-icon" data-tooltip="Icons scale with font size and use your course's primary color."></span></p>
1277
+ <h4>Heading with info<span class="tooltip-icon" data-tooltip="Tooltip icons work inside headings too." data-tooltip-delay="0"></span></h4>
1278
+ <p class="text-sm">Small text with icon<span class="tooltip-icon" data-tooltip="Automatically scales down with smaller text."></span> — icons size proportionally.</p>
1279
+ </div>
1280
+
1281
+ <div data-component="collapse" class="mt-4">
1282
+ <button type="button" class="btn btn-sm btn-secondary collapse-trigger" data-action="toggle-collapse" aria-controls="code-tooltips" aria-expanded="false">
1283
+ <span class="collapse-text-show">Show Code Example</span>
1284
+ <span class="collapse-text-hide">Hide Code Example</span>
1285
+ </button>
1286
+ <div class="collapse-panel mt-3" id="code-tooltips">
1287
+ <pre class="bg-gray-100 p-3 rounded text-xs overflow-x-auto"><code>&lt;!-- Inline tooltip on any element --&gt;
1288
+ &lt;button data-tooltip="Tooltip text" data-tooltip-position="top"&gt;Hover me&lt;/button&gt;
1289
+
1290
+ &lt;!-- Custom delay (0 = instant, default = 500ms) --&gt;
1291
+ &lt;span data-tooltip="No delay!" data-tooltip-delay="0"&gt;Instant&lt;/span&gt;
1292
+
1293
+ &lt;!-- Light theme, custom width --&gt;
1294
+ &lt;span data-tooltip="Wide content" data-tooltip-theme="light" data-tooltip-width="400"&gt;Wide&lt;/span&gt;
1295
+
1296
+ &lt;!-- Multi-line (use \n) --&gt;
1297
+ &lt;span data-tooltip="Line 1\nLine 2"&gt;Multi-line&lt;/span&gt;
1298
+
1299
+ &lt;!-- Icon tooltip (no inner text needed) --&gt;
1300
+ &lt;span class="tooltip-icon" data-tooltip="Contextual help text"&gt;&lt;/span&gt;</code></pre>
1301
+ </div>
1302
+ </div>
1303
+ </section>
1304
+
1305
+ </div>
1306
+ </div>
1307
+
1308
+ <!-- Tab 5: Images -->
1309
+ <div id="images" class="tab-content" role="tabpanel" hidden>
1310
+ <div class="stack-lg">
1311
+
1312
+ <!-- Carousel -->
1313
+ <section class="card no-hover">
1314
+ <h3 class="text-lg font-bold border-bottom pb-2 mb-4">Carousel</h3>
1315
+ <div class="carousel" id="demo-carousel" data-component="carousel">
1316
+ <div class="carousel-track">
1317
+ <div class="carousel-slide">
1318
+ <img src="https://picsum.photos/800/400?random=20" alt="Slide 1" class="img-fluid img-rounded">
1319
+ </div>
1320
+ <div class="carousel-slide">
1321
+ <img src="https://picsum.photos/800/400?random=21" alt="Slide 2" class="img-fluid img-rounded">
1322
+ </div>
1323
+ <div class="carousel-slide">
1324
+ <img src="https://picsum.photos/800/400?random=22" alt="Slide 3" class="img-fluid img-rounded">
1325
+ </div>
1326
+ </div>
1327
+ <button class="carousel-button prev" data-action="prev-slide" aria-label="Previous">&#10094;</button>
1328
+ <button class="carousel-button next" data-action="next-slide" aria-label="Next">&#10095;</button>
1329
+ <div class="carousel-dots"></div>
1330
+ </div>
1331
+
1332
+ <div data-component="collapse" class="mt-4">
1333
+ <button type="button" class="btn btn-sm btn-secondary collapse-trigger" data-action="toggle-collapse" aria-controls="code-carousel" aria-expanded="false">
1334
+ <span class="collapse-text-show">Show Code Example</span>
1335
+ <span class="collapse-text-hide">Hide Code Example</span>
1336
+ </button>
1337
+ <div class="collapse-panel mt-3" id="code-carousel">
1338
+ <pre class="bg-gray-100 p-3 rounded text-xs overflow-x-auto"><code>&lt;div class="carousel" data-component="carousel"&gt;
1339
+ &lt;div class="carousel-track"&gt;
1340
+ &lt;div class="carousel-slide"&gt;&lt;img src="slide.jpg"&gt;&lt;/div&gt;
1341
+ &lt;/div&gt;
1342
+ &lt;button class="carousel-button prev" data-action="prev-slide"&gt;‹&lt;/button&gt;
1343
+ &lt;button class="carousel-button next" data-action="next-slide"&gt;›&lt;/button&gt;
1344
+ &lt;div class="carousel-dots"&gt;&lt;/div&gt;
1345
+ &lt;/div&gt;</code></pre>
1346
+ </div>
1347
+ </div>
1348
+ </section>
1349
+
1350
+ <!-- Lightbox -->
1351
+ <section class="card no-hover">
1352
+ <h3 class="text-lg font-bold border-bottom pb-2 mb-4">Lightbox (Click-to-Enlarge)</h3>
1353
+ <p class="mb-4">Click any image to enlarge. Use <code>data-component="lightbox"</code> on links. Gallery mode enables prev/next navigation.</p>
1354
+ <div class="image-gallery-3 gap-4">
1355
+ <a href="https://picsum.photos/800/600?random=1" data-component="lightbox" class="image-link" data-lightbox-gallery="demo-gallery" data-lightbox-caption="Mountain landscape at sunset">
1356
+ <img src="https://picsum.photos/400/300?random=1" alt="Landscape 1" class="img-rounded">
1357
+ </a>
1358
+ <a href="https://picsum.photos/800/600?random=2" data-component="lightbox" class="image-link" data-lightbox-gallery="demo-gallery" data-lightbox-caption="Serene forest path">
1359
+ <img src="https://picsum.photos/400/300?random=2" alt="Landscape 2" class="img-rounded">
1360
+ </a>
1361
+ <a href="https://picsum.photos/800/600?random=3" data-component="lightbox" class="image-link" data-lightbox-gallery="demo-gallery" data-lightbox-caption="Ocean waves at dawn">
1362
+ <img src="https://picsum.photos/400/300?random=3" alt="Landscape 3" class="img-rounded">
1363
+ </a>
1364
+ </div>
1365
+ <p class="text-sm text-muted mt-3">Keyboard: <strong>ESC</strong> to close, <strong>←/→</strong> arrows for gallery navigation.</p>
1366
+
1367
+ <div data-component="collapse" class="mt-4">
1368
+ <button type="button" class="btn btn-sm btn-secondary collapse-trigger" data-action="toggle-collapse" aria-controls="code-lightbox" aria-expanded="false">
1369
+ <span class="collapse-text-show">Show Code Example</span>
1370
+ <span class="collapse-text-hide">Hide Code Example</span>
1371
+ </button>
1372
+ <div class="collapse-panel mt-3" id="code-lightbox">
1373
+ <pre class="bg-gray-100 p-3 rounded text-xs overflow-x-auto"><code>&lt;a href="full-image.jpg" data-component="lightbox" class="image-link"
1374
+ data-lightbox-gallery="gallery-name"
1375
+ data-lightbox-caption="Image Caption"&gt;
1376
+ &lt;img src="thumbnail.jpg" alt="Description"&gt;
1377
+ &lt;/a&gt;</code></pre>
1378
+ </div>
1379
+ </div>
1380
+ </section>
1381
+
1382
+ <!-- Markdown & PDF Lightbox -->
1383
+ <section class="card no-hover">
1384
+ <h3 class="text-lg font-bold border-bottom pb-2 mb-4">Markdown & PDF Lightbox</h3>
1385
+ <p class="mb-4">Click any preview to view the full document. Markdown thumbnails are auto-rendered; PDFs show a styled placeholder with filename.</p>
1386
+ <div class="flex gap-4 flex-wrap items-start justify-between">
1387
+ <a href="assets/docs/example_md_1.md" data-component="lightbox" data-lightbox-caption="Sample Document" data-lightbox-subtitle="Sample Document" style="width: 200px; height: 150px;"></a>
1388
+ <a href="assets/docs/example_md_2.md" data-component="lightbox" data-lightbox-caption="Reference Table" data-lightbox-subtitle="Reference Table" style="width: 200px; height: 150px;"></a>
1389
+ <a href="assets/docs/example_pdf_1.pdf" data-component="lightbox" data-lightbox-caption="Quick Reference Guide" data-lightbox-thumbnail="assets/docs/example_pdf_1_thumbnail.png" data-lightbox-subtitle="Quick Reference Guide" style="width: 200px; height: 150px;"></a>
1390
+ </div>
1391
+ </section>
1392
+
1393
+ <!-- Image Galleries -->
1394
+ <section class="card no-hover">
1395
+ <h3 class="text-lg font-bold border-bottom pb-2 mb-4">Image Gallery Layouts</h3>
1396
+ <div class="stack-md">
1397
+ <div>
1398
+ <p class="font-bold text-sm mb-2"><code>.image-gallery-4</code> - Fixed 4 columns</p>
1399
+ <div class="image-gallery-4 gap-2">
1400
+ <img src="https://picsum.photos/200/200?random=4" alt="Sample" class="img-fluid img-rounded-sm">
1401
+ <img src="https://picsum.photos/200/200?random=5" alt="Sample" class="img-fluid img-rounded-sm">
1402
+ <img src="https://picsum.photos/200/200?random=6" alt="Sample" class="img-fluid img-rounded-sm">
1403
+ <img src="https://picsum.photos/200/200?random=7" alt="Sample" class="img-fluid img-rounded-sm">
1404
+ </div>
1405
+ </div>
1406
+ <div>
1407
+ <p class="font-bold text-sm mb-2"><code>.image-gallery-uniform</code> - Square aspect ratio</p>
1408
+ <div class="image-gallery-3 image-gallery-uniform gap-2">
1409
+ <img src="https://picsum.photos/300/400?random=8" alt="Sample" class="img-fluid">
1410
+ <img src="https://picsum.photos/400/300?random=9" alt="Sample" class="img-fluid">
1411
+ <img src="https://picsum.photos/350/350?random=10" alt="Sample" class="img-fluid">
1412
+ </div>
1413
+ </div>
1414
+ </div>
1415
+ </section>
1416
+
1417
+ <!-- Linked Images with Hover Effects -->
1418
+ <section class="card no-hover">
1419
+ <h3 class="text-lg font-bold border-bottom pb-2 mb-4">Linked Image Hover Effects</h3>
1420
+ <div class="cols-3 gap-4">
1421
+ <div class="text-center">
1422
+ <a href="javascript:void(0)" class="image-link">
1423
+ <img src="https://picsum.photos/200/150?random=11" alt="Default" class="img-rounded">
1424
+ </a>
1425
+ <p class="text-sm text-muted mt-2"><code>.image-link</code></p>
1426
+ </div>
1427
+ <div class="text-center">
1428
+ <a href="javascript:void(0)" class="image-link image-link-lift">
1429
+ <img src="https://picsum.photos/200/150?random=12" alt="Lift" class="img-rounded">
1430
+ </a>
1431
+ <p class="text-sm text-muted mt-2"><code>.image-link-lift</code></p>
1432
+ </div>
1433
+ <div class="text-center">
1434
+ <a href="javascript:void(0)" class="image-link image-link-zoom">
1435
+ <img src="https://picsum.photos/200/150?random=13" alt="Zoom" class="img-rounded">
1436
+ </a>
1437
+ <p class="text-sm text-muted mt-2"><code>.image-link-zoom</code></p>
1438
+ </div>
1439
+ </div>
1440
+ </section>
1441
+
1442
+ <!-- Image Shapes -->
1443
+ <section class="card no-hover">
1444
+ <h3 class="text-lg font-bold border-bottom pb-2 mb-4">Image Shapes & Effects</h3>
1445
+ <div class="flex flex-wrap gap-4 items-end">
1446
+ <div class="text-center">
1447
+ <img src="https://picsum.photos/100/100?random=14" alt="Rounded" class="img-rounded">
1448
+ <p class="text-xs text-muted mt-2">.img-rounded</p>
1449
+ </div>
1450
+ <div class="text-center">
1451
+ <img src="https://picsum.photos/100/100?random=15" alt="Circle" class="img-circle">
1452
+ <p class="text-xs text-muted mt-2">.img-circle</p>
1453
+ </div>
1454
+ <div class="text-center">
1455
+ <img src="https://picsum.photos/100/100?random=16" alt="Bordered" class="img-bordered">
1456
+ <p class="text-xs text-muted mt-2">.img-bordered</p>
1457
+ </div>
1458
+ <div class="text-center">
1459
+ <img src="https://picsum.photos/100/100?random=17" alt="Shadow" class="img-rounded img-shadow">
1460
+ <p class="text-xs text-muted mt-2">.img-shadow</p>
1461
+ </div>
1462
+ <div class="text-center">
1463
+ <img src="https://picsum.photos/100/100?random=18" alt="Shadow Large" class="img-rounded img-shadow-lg">
1464
+ <p class="text-xs text-muted mt-2">.img-shadow-lg</p>
1465
+ </div>
1466
+ </div>
1467
+
1468
+ <div data-component="collapse" class="mt-4">
1469
+ <button type="button" class="btn btn-sm btn-secondary collapse-trigger" data-action="toggle-collapse" aria-controls="code-image-shapes" aria-expanded="false">
1470
+ <span class="collapse-text-show">Show Code Example</span>
1471
+ <span class="collapse-text-hide">Hide Code Example</span>
1472
+ </button>
1473
+ <div class="collapse-panel mt-3" id="code-image-shapes">
1474
+ <pre class="bg-gray-100 p-3 rounded text-xs overflow-x-auto"><code>&lt;img src="image.jpg" class="img-rounded"&gt;
1475
+ &lt;img src="image.jpg" class="img-circle"&gt;
1476
+ &lt;img src="image.jpg" class="img-bordered"&gt;
1477
+ &lt;img src="image.jpg" class="img-shadow"&gt;</code></pre>
1478
+ </div>
1479
+ </div>
1480
+ </section>
1481
+
1482
+ </div>
1483
+ </div>
1484
+
1485
+ <!-- Tab 6: Audio Components -->
1486
+ <div id="audio" class="tab-content pt-4" role="tabpanel" hidden>
1487
+ <div class="stack-lg">
1488
+
1489
+ <!-- Audio Player Variations -->
1490
+ <section class="card no-hover">
1491
+ <h3 class="text-lg font-bold border-bottom pb-2 mb-4">Standalone Audio Player Components</h3>
1492
+ <p class="mb-4">These are <strong>standalone audio players</strong> using <code>data-component="audio-player"</code>. Multiple players can be visible simultaneously - each controls its own audio track.</p>
1493
+
1494
+ <div class="stack-md">
1495
+ <!-- Full Size Player Demo -->
1496
+ <div class="callout callout--info">
1497
+ <h4 class="font-bold mb-2">Full Size Player</h4>
1498
+ <p class="text-sm mb-3">Complete controls with progress bar, time display, and all playback options.</p>
1499
+ <div class="mt-2" data-component="audio-player"
1500
+ data-audio-src="audio/example-ui-showcase--full-player.mp3"
1501
+ data-audio-id="full-player-demo">
1502
+ </div>
1503
+ </div>
1504
+
1505
+ <!-- Compact Player Demo -->
1506
+ <div class="callout">
1507
+ <h4 class="font-bold mb-2">Compact Player</h4>
1508
+ <p class="text-sm mb-3">Minimal controls (play/pause, restart, mute) - same style used in modals.</p>
1509
+ <div class="mt-2" data-component="audio-player"
1510
+ data-audio-src="audio/example-ui-showcase--compact-player.mp3"
1511
+ data-audio-id="compact-player-demo"
1512
+ data-audio-compact="true">
1513
+ </div>
1514
+ </div>
1515
+
1516
+ <!-- How Standalone Audio Works -->
1517
+ <div class="callout callout--success">
1518
+ <h4 class="font-bold mb-2">How Standalone Audio Works</h4>
1519
+ <ul class="list-disc ml-4 stack-sm text-sm">
1520
+ <li>Add <code>data-component="audio-player"</code> to any element</li>
1521
+ <li>Set <code>data-audio-src</code> to your audio file path</li>
1522
+ <li>Set <code>data-audio-id</code> for unique identification (required for gating)</li>
1523
+ <li>Add <code>data-audio-compact="true"</code> for minimal controls</li>
1524
+ <li>Add <code>data-audio-required="true"</code> to enable completion tracking</li>
1525
+ <li>Multiple players can exist on one slide (if no slide-level audio)</li>
1526
+ </ul>
1527
+ </div>
1528
+ </div>
1529
+
1530
+ <div data-component="collapse" class="mt-4">
1531
+ <button type="button" class="btn btn-sm btn-secondary collapse-trigger" data-action="toggle-collapse" aria-controls="code-audio" aria-expanded="false">
1532
+ <span class="collapse-text-show">Show Code Example</span>
1533
+ <span class="collapse-text-hide">Hide Code Example</span>
1534
+ </button>
1535
+ <div class="collapse-panel mt-3" id="code-audio">
1536
+ <pre class="bg-gray-100 p-3 rounded text-xs overflow-x-auto"><code>&lt;div data-component="audio-player"
1537
+ data-audio-src="audio/file.mp3"
1538
+ data-audio-id="unique-id"
1539
+ data-audio-compact="true"&gt;
1540
+ &lt;/div&gt;</code></pre>
1541
+ </div>
1542
+ </div>
1543
+ </section>
1544
+
1545
+ <!-- Player Comparison -->
1546
+ <section class="card no-hover">
1547
+ <h3 class="text-lg font-bold border-bottom pb-2 mb-4">Audio Modes Comparison</h3>
1548
+ <table class="table table-striped">
1549
+ <thead>
1550
+ <tr>
1551
+ <th>Mode</th>
1552
+ <th>Configuration</th>
1553
+ <th>Location</th>
1554
+ </tr>
1555
+ </thead>
1556
+ <tbody>
1557
+ <tr><td>📄 Slide Audio</td><td>Defined in <code>course-config.js</code></td><td>Full player in nav footer</td></tr>
1558
+ <tr><td>🪟 Modal Audio</td><td><code>data-audio-src</code> on modal trigger</td><td>Compact player in modal footer</td></tr>
1559
+ <tr><td>🎵 Standalone</td><td><code>data-component="audio-player"</code></td><td>Inline, anywhere in content</td></tr>
1560
+ </tbody>
1561
+ </table>
1562
+ </section>
1563
+
1564
+ <!-- Audio Mutual Exclusivity -->
1565
+ <section class="card no-hover">
1566
+ <h3 class="text-lg font-bold border-bottom pb-2 mb-4">Audio Context Rules</h3>
1567
+ <div class="callout callout--warning">
1568
+ <p class="mb-2"><strong>⚠️ Singleton Constraint:</strong> Only one audio track plays at a time.</p>
1569
+ <ul class="list-disc ml-4 stack-sm text-sm">
1570
+ <li>Playing any audio automatically pauses other audio</li>
1571
+ <li>Slides with slide-level audio cannot have modal or standalone audio</li>
1572
+ <li>Modal and standalone audio can coexist on slides without slide audio</li>
1573
+ <li>The linter will catch invalid configurations</li>
1574
+ </ul>
1575
+ </div>
1576
+ </section>
1577
+
1578
+ </div>
1579
+ </div>
1580
+
1581
+ <!-- Tab 7: Video Components -->
1582
+ <div id="video" class="tab-content pt-4" role="tabpanel" hidden>
1583
+ <div class="stack-lg">
1584
+
1585
+ <!-- Video Player Demo -->
1586
+ <section class="card no-hover">
1587
+ <h3 class="text-lg font-bold border-bottom pb-2 mb-4">Video Player Component</h3>
1588
+ <p class="mb-4">Embed videos using the <code>data-component="video-player"</code> declarative component. Supports native HTML5 video with custom controls overlay.</p>
1589
+
1590
+ <div class="stack-md">
1591
+ <!-- YouTube Video Example -->
1592
+ <div class="callout callout--info">
1593
+ <h4 class="font-bold mb-2">YouTube Video</h4>
1594
+ <p class="text-sm mb-3">YouTube videos embed with native platform controls.</p>
1595
+ <div class="mt-3" data-component="video-player"
1596
+ data-video-src="https://youtu.be/q2_c2_WfJFg"
1597
+ data-video-id="youtube-demo">
1598
+ </div>
1599
+ </div>
1600
+
1601
+ <!-- Native Video Example -->
1602
+ <div class="callout">
1603
+ <h4 class="font-bold mb-2">Native HTML5 Video</h4>
1604
+ <p class="text-sm mb-3">Local files use custom controls with progress tracking.</p>
1605
+ <div class="mt-3" data-component="video-player"
1606
+ data-video-src="https://interactive-examples.mdn.mozilla.net/media/cc0-videos/flower.mp4"
1607
+ data-video-id="native-demo">
1608
+ </div>
1609
+ </div>
1610
+
1611
+ <!-- Usage Guide -->
1612
+ <div class="callout callout--success">
1613
+ <h4 class="font-bold mb-2">How to Use Video Players</h4>
1614
+ <ul class="list-disc ml-4 stack-sm text-sm">
1615
+ <li>Add <code>data-component="video-player"</code> to any element</li>
1616
+ <li>Set <code>data-video-src</code> to your video file path</li>
1617
+ <li>Set <code>data-video-id</code> for unique identification</li>
1618
+ <li>Add <code>data-video-poster</code> for a poster image</li>
1619
+ <li>Add <code>data-video-required="true"</code> for completion tracking</li>
1620
+ <li>Add <code>data-video-captions</code> for subtitles (.vtt file)</li>
1621
+ </ul>
1622
+ </div>
1623
+ </div>
1624
+
1625
+ <div data-component="collapse" class="mt-4">
1626
+ <button type="button" class="btn btn-sm btn-secondary collapse-trigger" data-action="toggle-collapse" aria-controls="code-video" aria-expanded="false">
1627
+ <span class="collapse-text-show">Show Code Example</span>
1628
+ <span class="collapse-text-hide">Hide Code Example</span>
1629
+ </button>
1630
+ <div class="collapse-panel mt-3" id="code-video">
1631
+ <pre class="bg-gray-100 p-3 rounded text-xs overflow-x-auto"><code>&lt;div data-component="video-player"
1632
+ data-video-src="video/file.mp4"
1633
+ data-video-id="unique-id"
1634
+ data-video-poster="poster.jpg"&gt;
1635
+ &lt;/div&gt;</code></pre>
1636
+ </div>
1637
+ </div>
1638
+ </section>
1639
+
1640
+ <!-- Video Lightbox -->
1641
+ <section class="card no-hover">
1642
+ <h3 class="text-lg font-bold border-bottom pb-2 mb-4">Video Lightbox (Click-to-Play)</h3>
1643
+ <p class="mb-4">Click a thumbnail to open the video in a lightbox overlay. Uses the same <code>data-component="lightbox"</code> attribute as images - the component auto-detects video URLs.</p>
1644
+
1645
+ <div class="cols-2 gap-4">
1646
+ <!-- YouTube Video Lightbox -->
1647
+ <div class="text-center">
1648
+ <a href="https://youtu.be/q2_c2_WfJFg" data-component="lightbox" class="image-link block" data-lightbox-caption="YouTube Video Demo">
1649
+ <div class="aspect-16-9 rounded overflow-hidden">
1650
+ <img src="https://img.youtube.com/vi/q2_c2_WfJFg/mqdefault.jpg" alt="YouTube Video" class="img-cover">
1651
+ </div>
1652
+ </a>
1653
+ <p class="text-sm text-muted mt-2">YouTube</p>
1654
+ </div>
1655
+
1656
+ <!-- Vimeo Video Lightbox -->
1657
+ <div class="text-center">
1658
+ <a href="https://vimeo.com/824804225" data-component="lightbox" class="image-link block" data-lightbox-caption="Vimeo Video Demo">
1659
+ <div class="aspect-16-9 rounded overflow-hidden">
1660
+ <img src="https://picsum.photos/seed/vimeo/320/180" alt="Vimeo Video" class="img-cover">
1661
+ </div>
1662
+ </a>
1663
+ <p class="text-sm text-muted mt-2">Vimeo</p>
1664
+ </div>
1665
+ </div>
1666
+
1667
+ <div class="callout callout--success mt-4">
1668
+ <h4 class="font-bold mb-2">How Video Lightbox Works</h4>
1669
+ <ul class="list-disc ml-4 stack-sm text-sm">
1670
+ <li>Use <code>data-component="lightbox"</code> on any link pointing to a video URL</li>
1671
+ <li>Supports YouTube (youtu.be, youtube.com), Vimeo, and native video (.mp4, .webm)</li>
1672
+ <li>Videos auto-play when the lightbox opens</li>
1673
+ <li>Playback stops automatically when the lightbox closes</li>
1674
+ </ul>
1675
+ </div>
1676
+ </section>
1677
+
1678
+ <!-- Video Controls -->
1679
+ <section class="card no-hover">
1680
+ <h3 class="text-lg font-bold border-bottom pb-2 mb-4">Video Controls</h3>
1681
+ <p class="mb-4">Native videos display custom controls. External embeds (YouTube/Vimeo) use their native UI.</p>
1682
+ <table class="table table-striped">
1683
+ <thead>
1684
+ <tr>
1685
+ <th>Control</th>
1686
+ <th>Action</th>
1687
+ </tr>
1688
+ </thead>
1689
+ <tbody>
1690
+ <tr><td>▶️ Play/Pause</td><td>Toggle playback (click overlay or button)</td></tr>
1691
+ <tr><td>📊 Progress Bar</td><td>Click or drag to seek</td></tr>
1692
+ <tr><td>🔇 Mute</td><td>Toggle audio</td></tr>
1693
+ <tr><td>⏱️ Time Display</td><td>Shows current position / duration</td></tr>
1694
+ <tr><td>📺 Fullscreen</td><td>Double-click video or use button</td></tr>
1695
+ </tbody>
1696
+ </table>
1697
+ </section>
1698
+
1699
+ <!-- Engagement Gating -->
1700
+ <section class="card no-hover">
1701
+ <h3 class="text-lg font-bold border-bottom pb-2 mb-4">Engagement Gating</h3>
1702
+ <div class="callout callout--warning">
1703
+ <p class="mb-2"><strong>Video Completion Requirements</strong></p>
1704
+ <p class="text-sm mb-3">Videos can gate navigation. Add <code>data-video-required="true"</code> to the player, then configure requirements in course-config.js:</p>
1705
+ <pre class="bg-gray-100 p-3 rounded text-xs"><code>engagement: {
1706
+ required: true,
1707
+ requirements: [
1708
+ { type: 'videoComplete', videoId: 'sample-video', message: 'Watch the video' }
1709
+ ]
1710
+ }</code></pre>
1711
+ </div>
1712
+ </section>
1713
+
1714
+ </div>
1715
+ </div>
1716
+
1717
+ </div>
1718
+
1719
+ <!-- Hidden Modal Content -->
1720
+ <div id="audio-modal-content" style="display: none;">
1721
+ <div class="stack-md">
1722
+ <p><strong>Demo Modal with Audio</strong></p>
1723
+ <p>This modal demonstrates audio narration with built-in audio controls rendered in the modal footer.</p>
1724
+ <ul class="list-disc ml-4 stack-sm">
1725
+ <li><strong>Compact Controls:</strong> Modals render minimal audio controls (play/pause, restart, mute)</li>
1726
+ <li><strong>Position Persistence:</strong> Audio position is saved when you close and reopen</li>
1727
+ <li><strong>Completion Tracking:</strong> Required audio completion can gate modal closing</li>
1728
+ <li><strong>Mute Preference:</strong> Mute state persists across your entire session</li>
1729
+ </ul>
1730
+ </div>
1731
+ </div>
1732
+
1733
+ <!-- Templates -->
1734
+ <template id="demo-modal-body">
1735
+ <p>This is a modal content area. You can put any HTML here.</p>
1736
+ </template>
1737
+ <template id="demo-modal-footer">
1738
+ <button class="btn btn-secondary" data-action="close-modal">Close</button>
1739
+ <button class="btn btn-primary" data-action="close-modal">Save Changes</button>
1740
+ </template>
1741
+ </div>
1742
+ `;
1743
+
1744
+ return container;
1745
+ }
1746
+ };
1747
+
1748
+ /**
1749
+ * Narration for ui-demo slide components.
1750
+ *
1751
+ * This slide demonstrates various UI components including:
1752
+ * - Interactive Tab: Modal with audio narration (data-audio-src="audio/example-ui-showcase--demo-modal.mp3")
1753
+ * - Audio Components Tab: Two standalone audio players demonstrating full and compact modes
1754
+ *
1755
+ * Since this slide has NO slide-level audio, it can have modal and standalone audio.
1756
+ *
1757
+ * MULTI-KEY FORMAT with audio narration:
1758
+ * - 'demo-modal': Narration for the modal in Interactive tab
1759
+ * - 'full-player': Narration for the full-size standalone audio player demo
1760
+ * - 'compact-player': Narration for the compact standalone audio player demo
1761
+ *
1762
+ * Run `npm run narration` to generate audio files:
1763
+ * - course/assets/audio/example-ui-showcase--demo-modal.mp3
1764
+ * - course/assets/audio/example-ui-showcase--full-player.mp3
1765
+ * - course/assets/audio/example-ui-showcase--compact-player.mp3
1766
+ *
1767
+ * Reference in slide HTML:
1768
+ * - Modal audio: data-audio-src="audio/example-ui-showcase--demo-modal.mp3"
1769
+ * - Full player: data-audio-src="audio/example-ui-showcase--full-player.mp3"
1770
+ * - Compact player: data-audio-src="audio/example-ui-showcase--compact-player.mp3"
1771
+ */
1772
+ export const narration = {
1773
+ 'demo-modal': `
1774
+ Welcome to the Demo Modal with Audio.
1775
+
1776
+ This modal demonstrates how the framework handles audio narration with built-in audio controls rendered in the modal footer.
1777
+
1778
+ Key capabilities include:
1779
+
1780
+ - Compact Controls: Modals render minimal audio controls - play pause, restart, and mute
1781
+ - Position Persistence: Audio position is saved when you close and reopen this modal
1782
+ - Completion Tracking: Required audio completion can gate modal closing
1783
+ - Mute Preference: Your mute state persists across the entire session
1784
+
1785
+ Use the controls in the modal footer to manage playback. Close this modal when you're done.
1786
+ `,
1787
+ 'full-player': `
1788
+ This is the full-size audio player.
1789
+
1790
+ It includes a progress bar that you can click to seek, time display showing current position and total duration, and all standard playback controls.
1791
+
1792
+ The full-size player is ideal for primary narration where you want learners to have complete control over their listening experience.
1793
+
1794
+ You can have multiple standalone players on the same slide. Try playing this while the compact player below is also visible - when you play one, it automatically pauses the other.
1795
+ `,
1796
+ 'compact-player': `
1797
+ This is the compact audio player.
1798
+
1799
+ It uses the same minimal control set as modal audio - just play pause, restart, and mute buttons.
1800
+
1801
+ The compact player is useful when you want audio controls that take up less space, or when embedded in smaller UI elements like callouts or sidebars.
1802
+
1803
+ Notice that both players are visible at the same time, but only one audio track plays at a time due to the singleton audio architecture.
1804
+ `
1805
+ };