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,258 @@
1
+ /* ============================================================================
2
+ ARTICLE LAYOUT - Modern web-page feel
3
+ ============================================================================
4
+
5
+ PURPOSE: Documentation-style layout with:
6
+ - Minimal header (branding only, sidebar toggle optional)
7
+ - OPTIONAL sidebar (controlled by navigation.sidebar.enabled)
8
+ - Content-focused, scrollable main area
9
+ - Floating footer with compact navigation
10
+
11
+ BEST FOR: Modern "readable" courses, documentation-style content
12
+
13
+ ============================================================================ */
14
+
15
+ /* Sidebar visibility controlled by data attribute (JS sets from config) */
16
+ /* Hide sidebar toggle when sidebar is disabled */
17
+ [data-layout="article"]:not([data-sidebar-enabled="true"]) #sidebar-toggle {
18
+ display: none;
19
+ }
20
+
21
+ /* Show sidebar toggle when enabled - style as part of header */
22
+ [data-layout="article"][data-sidebar-enabled="true"] #sidebar-toggle {
23
+ display: flex;
24
+ color: var(--header-control-text);
25
+ }
26
+
27
+ [data-layout="article"][data-sidebar-enabled="true"] #sidebar-toggle:hover {
28
+ background: var(--header-control-bg-hover);
29
+ }
30
+
31
+ /* Show accessibility button as the unified menu (when sidebar is disabled) */
32
+ [data-layout="article"]:not([data-sidebar-enabled="true"]) #accessibility-button {
33
+ display: flex;
34
+ color: var(--header-control-text);
35
+ }
36
+
37
+ [data-layout="article"]:not([data-sidebar-enabled="true"]) #accessibility-button:hover {
38
+ background: var(--header-control-bg-hover);
39
+ }
40
+
41
+ /* When sidebar is enabled, hide the standalone accessibility button (settings in sidebar) */
42
+ [data-layout="article"][data-sidebar-enabled="true"] #accessibility-button {
43
+ display: none;
44
+ }
45
+
46
+ /* Hide sidebar when disabled */
47
+ [data-layout="article"]:not([data-sidebar-enabled="true"]) .sidebar {
48
+ display: none !important;
49
+ }
50
+
51
+ [data-layout="article"]:not([data-sidebar-enabled="true"]) #sidebar-backdrop {
52
+ display: none !important;
53
+ }
54
+
55
+ /* Minimal header styling */
56
+ [data-layout="article"] .course-header {
57
+ background: var(--header-bg);
58
+ border-bottom: 1px solid var(--header-border);
59
+ box-shadow: var(--shadow-sm);
60
+ --header-text: var(--color-primary);
61
+ --header-bg: var(--bg-surface);
62
+ --header-border: var(--border-default);
63
+ --header-control-bg: transparent;
64
+ --header-control-bg-hover: var(--color-primary-alpha-10);
65
+ --header-control-bg-active: var(--color-primary-alpha-20);
66
+ --header-control-text: var(--header-text);
67
+ --header-control-focus: var(--header-text);
68
+ }
69
+
70
+ /* Use brand color for logo, title, and icon */
71
+ [data-layout="article"] .course-header h1,
72
+ [data-layout="article"] .course-header .brand-title,
73
+ [data-layout="article"] .course-header #brand,
74
+ [data-layout="article"] .course-header #brand span.logo {
75
+ color: var(--header-text);
76
+ }
77
+
78
+ [data-layout="article"] .course-header #brand svg,
79
+ [data-layout="article"] .course-header #brand img {
80
+ filter: none;
81
+ /* Don't invert logo on light background */
82
+ }
83
+
84
+ /* Content area - centered, article-width */
85
+ [data-layout="article"] main#content {
86
+ max-width: 100%;
87
+ padding: var(--space-8) var(--space-6);
88
+ }
89
+
90
+ [data-layout="article"] main#content>section {
91
+ /* Width controlled by slideDefaults.contentWidth config via auto-wrapping */
92
+ border: none;
93
+ box-shadow: none;
94
+ background: transparent;
95
+ padding: 0;
96
+ }
97
+
98
+ /* Slide container inherits article width */
99
+ [data-layout="article"] #slide-container {
100
+ /* Width controlled by slideDefaults.contentWidth config via auto-wrapping */
101
+ margin: 0 auto;
102
+ }
103
+
104
+ /* Footer styling moved to components/footer.css - DATA-LAYOUT VARIANTS section */
105
+
106
+ /* Audio player styling moved to components/audio-player.css - DATA-LAYOUT VARIANTS section */
107
+
108
+ /* Button styling moved to components/buttons.css - DATA-LAYOUT VARIANTS section */
109
+ /* Engagement/gating styling moved to components/engagement.css - DATA-LAYOUT VARIANTS section */
110
+
111
+ /* Breadcrumbs visibility now controlled by navigation.breadcrumbs.enabled config */
112
+
113
+ /* Article layout sidebar - add left padding so nav item accent isn't flush with edge */
114
+ [data-layout="article"] .sidebar nav#menu {
115
+ padding-left: var(--space-2);
116
+ }
117
+
118
+ /* ============================================================================
119
+ ARTICLE LAYOUT SIDEBAR FOOTER - Horizontal status bar
120
+ ============================================================================ */
121
+
122
+ /* Show sidebar footer in article layout when sidebar is enabled */
123
+ [data-layout="article"][data-sidebar-enabled="true"] .nav-sidebar-footer {
124
+ display: flex;
125
+ align-items: center;
126
+ justify-content: space-between;
127
+ margin-top: auto;
128
+ padding: var(--space-3) var(--space-4);
129
+ border-top: 1px solid var(--sidebar-border);
130
+ background: var(--sidebar-bg);
131
+ }
132
+
133
+ /* Exit link - subtle text link style */
134
+ [data-layout="article"] .sidebar-exit-link {
135
+ display: flex;
136
+ align-items: center;
137
+ gap: var(--space-1);
138
+ padding: var(--space-1) var(--space-2);
139
+ background: transparent;
140
+ border: none;
141
+ border-radius: var(--radius-md);
142
+ font-size: var(--font-size-xs);
143
+ color: var(--sidebar-text);
144
+ opacity: 0.72;
145
+ cursor: pointer;
146
+ transition: opacity var(--transition-fast), color var(--transition-fast), background-color var(--transition-fast);
147
+ }
148
+
149
+ [data-layout="article"] .sidebar-exit-link:hover {
150
+ opacity: 1;
151
+ color: var(--color-danger);
152
+ background: color-mix(in srgb, var(--color-danger) 8%, transparent);
153
+ }
154
+
155
+ [data-layout="article"] .sidebar-exit-link:focus-visible {
156
+ opacity: 1;
157
+ outline: var(--focus-ring-width) solid var(--focus-ring-color);
158
+ outline-offset: var(--focus-ring-offset);
159
+ }
160
+
161
+ [data-layout="article"] .sidebar-exit-link svg {
162
+ width: 14px;
163
+ height: 14px;
164
+ }
165
+
166
+ /* Settings icon buttons - compact row */
167
+ [data-layout="article"] .sidebar-settings-icons {
168
+ display: flex;
169
+ align-items: center;
170
+ gap: var(--space-1);
171
+ }
172
+
173
+ [data-layout="article"] .sidebar-icon-btn {
174
+ display: flex;
175
+ align-items: center;
176
+ justify-content: center;
177
+ width: 30px;
178
+ height: 30px;
179
+ padding: 0;
180
+ background: color-mix(in srgb, var(--sidebar-text) 6%, transparent);
181
+ border: 1px solid color-mix(in srgb, var(--sidebar-text) 16%, transparent);
182
+ border-radius: var(--radius-md);
183
+ color: var(--sidebar-text);
184
+ opacity: 0.78;
185
+ cursor: pointer;
186
+ transition: opacity var(--transition-fast), background var(--transition-fast), border-color var(--transition-fast), transform var(--transition-interactive);
187
+ }
188
+
189
+ [data-layout="article"] .sidebar-icon-btn:hover {
190
+ opacity: 1;
191
+ background: var(--sidebar-hover-bg);
192
+ border-color: color-mix(in srgb, var(--sidebar-active-text) 32%, transparent);
193
+ transform: translateY(var(--motion-lift-sm));
194
+ }
195
+
196
+ [data-layout="article"] .sidebar-icon-btn:active {
197
+ transform: scale(var(--motion-press-scale));
198
+ }
199
+
200
+ [data-layout="article"] .sidebar-icon-btn:focus-visible {
201
+ opacity: 1;
202
+ outline: var(--focus-ring-width) solid var(--focus-ring-color);
203
+ outline-offset: var(--focus-ring-offset);
204
+ border-color: color-mix(in srgb, var(--sidebar-active-text) 36%, transparent);
205
+ }
206
+
207
+ [data-layout="article"] .sidebar-icon-btn svg {
208
+ width: 16px;
209
+ height: 16px;
210
+ }
211
+
212
+ [data-layout="article"] .sidebar-icon-btn .icon-text {
213
+ font-size: var(--font-size-xs);
214
+ font-weight: var(--font-weight-bold);
215
+ }
216
+
217
+ /* ============================================================================
218
+ MOBILE RESPONSIVE - Compact unified footer
219
+ ============================================================================
220
+ On mobile, use a single full-width compact footer bar at bottom.
221
+ Audio left, nav right in one unified bar. Shorter header.
222
+ Structure: footer > nav-controls > [nav-nav-buttons, audio-player, nav-exit-button]
223
+ ============================================================================ */
224
+
225
+ /* Mobile breakpoint - 767px and below */
226
+
227
+ /* Compact header - reduce height */
228
+ html.bp-max-mobile-landscape[data-layout="article"] .course-header {
229
+ padding: var(--space-2) var(--space-3);
230
+ }
231
+
232
+ html.bp-max-mobile-landscape[data-layout="article"] .course-header #brand img.logo {
233
+ height: 28px;
234
+ }
235
+
236
+ html.bp-max-mobile-landscape[data-layout="article"] .course-header .brand-title {
237
+ font-size: var(--font-size-sm);
238
+ }
239
+
240
+ /* Sidebar should end above the fixed footer */
241
+ html.bp-max-mobile-landscape[data-layout="article"] .sidebar {
242
+ height: calc(100% - 52px);
243
+ }
244
+
245
+ /* Mobile footer styling moved to components/footer.css - DATA-LAYOUT VARIANTS section */
246
+
247
+ /* Mobile audio player order moved to components/audio-player.css - DATA-LAYOUT VARIANTS section */
248
+
249
+
250
+
251
+ /* Mobile button styling moved to components/buttons.css - DATA-LAYOUT VARIANTS section */
252
+
253
+
254
+
255
+ /* Add bottom padding to content */
256
+ html.bp-max-mobile-landscape[data-layout="article"] main#content {
257
+ padding-bottom: calc(var(--space-8) + 52px);
258
+ }
@@ -0,0 +1,30 @@
1
+ /* ============================================================================
2
+ LAYOUT BASE - Shared tokens and base structure for all layouts
3
+ ============================================================================
4
+
5
+ PURPOSE: Common layout tokens and utilities used by all layout modes.
6
+
7
+ PATTERN: Each layout applies a `data-layout` attribute to <html>, then uses
8
+ CSS selectors like `[data-layout="X"]` to control visibility and positioning.
9
+
10
+ ============================================================================ */
11
+
12
+ :root {
13
+ /* Layout tokens - can be overridden per layout */
14
+ --layout-header-height: var(--header-height, 60px);
15
+ --layout-footer-height: var(--footer-height, 60px);
16
+ --layout-sidebar-width: var(--sidebar-width, 280px);
17
+
18
+ /* Floating nav tokens */
19
+ --layout-floating-nav-radius: var(--radius-xl);
20
+ --layout-floating-nav-padding: var(--space-2);
21
+ --layout-floating-nav-bg: var(--footer-floating-bg);
22
+ --layout-floating-nav-border: 1px solid var(--footer-floating-border);
23
+ --layout-floating-nav-shadow: var(--footer-floating-shadow);
24
+ }
25
+
26
+ /* Default layout is traditional if not specified */
27
+ html:not([data-layout]),
28
+ [data-layout="traditional"] {
29
+ --layout-mode: traditional;
30
+ }
@@ -0,0 +1,38 @@
1
+ /**
2
+ * Canvas Layout
3
+ *
4
+ * A true blank-slate layout. ALL framework CSS is reverted to browser
5
+ * defaults in the content area. Authors bring their own CSS via theme.css
6
+ * (which loads after framework.css and naturally wins via cascade order).
7
+ *
8
+ * Authors still get full access to LMS drivers, state, engagement,
9
+ * navigation, interactions, and all other framework JS infrastructure
10
+ * via window.CourseCode and course-config.js.
11
+ */
12
+
13
+ /* --- Hide all framework chrome --- */
14
+ [data-layout="canvas"] .course-header,
15
+ [data-layout="canvas"] .app-footer,
16
+ [data-layout="canvas"] .sidebar,
17
+ [data-layout="canvas"] #sidebar-backdrop,
18
+ [data-layout="canvas"] #sidebar-toggle,
19
+ [data-layout="canvas"] .nav-floating {
20
+ display: none !important;
21
+ }
22
+
23
+ /* --- Content fills viewport with no framework styling --- */
24
+ [data-layout="canvas"] .app-body {
25
+ padding: 0;
26
+ }
27
+
28
+ [data-layout="canvas"] main#content {
29
+ padding: 0;
30
+ background: none;
31
+ background-image: none;
32
+ }
33
+
34
+ /* --- Nuclear reset: revert ALL framework styles in slide content --- */
35
+ [data-layout="canvas"] #slide-container,
36
+ [data-layout="canvas"] #slide-container * {
37
+ all: revert;
38
+ }
@@ -0,0 +1,236 @@
1
+ /* ============================================================================
2
+ FOCUSED LAYOUT - Immersive experience
3
+ ============================================================================
4
+
5
+ PURPOSE: Minimal-chrome layout with:
6
+ - Header chrome hidden (no hover reveal)
7
+ - FAB sidebar toggle in top-left when sidebar is enabled
8
+ - OPTIONAL sidebar (controlled by navigation.sidebar.enabled)
9
+ - Content fills viewport, centered
10
+ - Floating centered footer with navigation
11
+
12
+ BEST FOR: Story-driven courses, multimedia-heavy content, immersive experiences
13
+
14
+ ============================================================================ */
15
+
16
+ /* Focused: hide header when sidebar disabled */
17
+ [data-layout="focused"]:not([data-sidebar-enabled="true"]) .course-header {
18
+ display: none !important;
19
+ }
20
+
21
+ /* Focused with sidebar: keep header in DOM but hide chrome, show only FAB toggle */
22
+ [data-layout="focused"][data-sidebar-enabled="true"] .course-header {
23
+ position: fixed;
24
+ top: 0;
25
+ left: 0;
26
+ width: 0;
27
+ height: 0;
28
+ overflow: visible;
29
+ background: transparent !important;
30
+ box-shadow: none !important;
31
+ border: none !important;
32
+ }
33
+
34
+ [data-layout="focused"][data-sidebar-enabled="true"] .course-header > * {
35
+ visibility: hidden;
36
+ }
37
+
38
+ [data-layout="focused"][data-sidebar-enabled="true"] .course-header #sidebar-toggle {
39
+ visibility: visible;
40
+ }
41
+
42
+ /* Sidebar visibility controlled by data attribute */
43
+ [data-layout="focused"]:not([data-sidebar-enabled="true"]) .sidebar {
44
+ display: none !important;
45
+ }
46
+
47
+ [data-layout="focused"]:not([data-sidebar-enabled="true"]) #sidebar-backdrop {
48
+ display: none !important;
49
+ }
50
+
51
+ [data-layout="focused"]:not([data-sidebar-enabled="true"]) #sidebar-toggle {
52
+ display: none !important;
53
+ }
54
+
55
+ /* FAB toggle button for focused layout - same pattern as presentation */
56
+ [data-layout="focused"][data-sidebar-enabled="true"] #sidebar-toggle {
57
+ --header-control-bg: var(--nav-edge-bg);
58
+ --header-control-bg-hover: var(--nav-edge-bg-hover);
59
+ --header-control-text: var(--text-primary);
60
+ --header-border: var(--nav-edge-border);
61
+ position: fixed;
62
+ top: var(--space-4);
63
+ left: var(--space-4);
64
+ z-index: var(--z-fixed);
65
+ width: var(--nav-edge-control-size);
66
+ height: var(--nav-edge-control-size);
67
+ border-radius: var(--radius-full);
68
+ background: var(--header-control-bg);
69
+ border: 1px solid var(--header-border);
70
+ box-shadow: var(--nav-edge-shadow);
71
+ display: flex;
72
+ align-items: center;
73
+ justify-content: center;
74
+ opacity: var(--nav-btn-edge-opacity);
75
+ transition: opacity var(--transition-fast), transform var(--transition-interactive), background var(--transition-fast), box-shadow var(--transition-interactive);
76
+ color: var(--header-control-text);
77
+ }
78
+
79
+ [data-layout="focused"][data-sidebar-enabled="true"] #sidebar-toggle:hover {
80
+ opacity: 1;
81
+ transform: scale(var(--nav-edge-hover-scale));
82
+ background: var(--header-control-bg-hover);
83
+ box-shadow: var(--nav-edge-shadow-hover);
84
+ }
85
+
86
+ [data-layout="focused"][data-sidebar-enabled="true"] #sidebar-toggle:active {
87
+ transform: scale(var(--nav-edge-active-scale));
88
+ }
89
+
90
+ /* App body fills full height (header is absolutely positioned, doesn't take space) */
91
+ [data-layout="focused"] .app-body {
92
+ height: 100%;
93
+ }
94
+
95
+ /* Content area - centered, fills viewport */
96
+ [data-layout="focused"] main#content {
97
+ display: flex;
98
+ align-items: center;
99
+ justify-content: center;
100
+ padding: var(--space-6);
101
+ height: 100%;
102
+ box-sizing: border-box;
103
+ }
104
+
105
+ [data-layout="focused"] main#content>section {
106
+ max-width: 1000px;
107
+ width: 100%;
108
+ border: none;
109
+ box-shadow: none;
110
+ background: transparent;
111
+ }
112
+
113
+ /* Slide container centered */
114
+ [data-layout="focused"] #slide-container {
115
+ max-width: 1000px;
116
+ margin: 0 auto;
117
+ }
118
+
119
+ /* Footer styling moved to components/footer.css - DATA-LAYOUT VARIANTS section */
120
+
121
+ /* Audio player styling moved to components/audio-player.css - DATA-LAYOUT VARIANTS section */
122
+
123
+ /* Button styling moved to components/buttons.css - DATA-LAYOUT VARIANTS section */
124
+ /* Engagement/gating styling moved to components/engagement.css - DATA-LAYOUT VARIANTS section */
125
+
126
+ /* Breadcrumbs visibility now controlled by navigation.breadcrumbs.enabled config */
127
+
128
+ /* Reduce motion */
129
+ @media (prefers-reduced-motion: reduce) {
130
+ [data-layout="focused"][data-sidebar-enabled="true"] #sidebar-toggle {
131
+ transition: none;
132
+ }
133
+
134
+ [data-layout="focused"][data-sidebar-enabled="true"] #sidebar-toggle:hover {
135
+ transform: none;
136
+ }
137
+ }
138
+
139
+ /* ============================================================================
140
+ FOCUSED LAYOUT SIDEBAR FOOTER - Horizontal status bar (same as article)
141
+ ============================================================================ */
142
+
143
+ /* Show sidebar footer in focused layout when sidebar is enabled */
144
+ [data-layout="focused"][data-sidebar-enabled="true"] .nav-sidebar-footer {
145
+ display: flex;
146
+ align-items: center;
147
+ justify-content: space-between;
148
+ margin-top: auto;
149
+ padding: var(--space-3) var(--space-4);
150
+ border-top: 1px solid var(--sidebar-border);
151
+ background: var(--sidebar-bg);
152
+ }
153
+
154
+ /* Exit link - subtle text link style */
155
+ [data-layout="focused"] .sidebar-exit-link {
156
+ display: flex;
157
+ align-items: center;
158
+ gap: var(--space-1);
159
+ padding: var(--space-1) var(--space-2);
160
+ background: transparent;
161
+ border: none;
162
+ border-radius: var(--radius-md);
163
+ font-size: var(--font-size-xs);
164
+ color: var(--sidebar-text);
165
+ opacity: 0.72;
166
+ cursor: pointer;
167
+ transition: opacity var(--transition-fast), color var(--transition-fast), background-color var(--transition-fast);
168
+ }
169
+
170
+ [data-layout="focused"] .sidebar-exit-link:hover {
171
+ opacity: 1;
172
+ color: var(--color-danger);
173
+ background: color-mix(in srgb, var(--color-danger) 8%, transparent);
174
+ }
175
+
176
+ [data-layout="focused"] .sidebar-exit-link:focus-visible {
177
+ opacity: 1;
178
+ outline: var(--focus-ring-width) solid var(--focus-ring-color);
179
+ outline-offset: var(--focus-ring-offset);
180
+ }
181
+
182
+ [data-layout="focused"] .sidebar-exit-link svg {
183
+ width: 14px;
184
+ height: 14px;
185
+ }
186
+
187
+ /* Settings icon buttons - compact row */
188
+ [data-layout="focused"] .sidebar-settings-icons {
189
+ display: flex;
190
+ align-items: center;
191
+ gap: var(--space-1);
192
+ }
193
+
194
+ [data-layout="focused"] .sidebar-icon-btn {
195
+ display: flex;
196
+ align-items: center;
197
+ justify-content: center;
198
+ width: 30px;
199
+ height: 30px;
200
+ padding: 0;
201
+ background: color-mix(in srgb, var(--sidebar-text) 6%, transparent);
202
+ border: 1px solid color-mix(in srgb, var(--sidebar-text) 16%, transparent);
203
+ border-radius: var(--radius-md);
204
+ color: var(--sidebar-text);
205
+ opacity: 0.78;
206
+ cursor: pointer;
207
+ transition: opacity var(--transition-fast), background var(--transition-fast), border-color var(--transition-fast), transform var(--transition-interactive);
208
+ }
209
+
210
+ [data-layout="focused"] .sidebar-icon-btn:hover {
211
+ opacity: 1;
212
+ background: var(--sidebar-hover-bg);
213
+ border-color: color-mix(in srgb, var(--sidebar-active-text) 32%, transparent);
214
+ transform: translateY(var(--motion-lift-sm));
215
+ }
216
+
217
+ [data-layout="focused"] .sidebar-icon-btn:active {
218
+ transform: scale(var(--motion-press-scale));
219
+ }
220
+
221
+ [data-layout="focused"] .sidebar-icon-btn:focus-visible {
222
+ opacity: 1;
223
+ outline: var(--focus-ring-width) solid var(--focus-ring-color);
224
+ outline-offset: var(--focus-ring-offset);
225
+ border-color: color-mix(in srgb, var(--sidebar-active-text) 36%, transparent);
226
+ }
227
+
228
+ [data-layout="focused"] .sidebar-icon-btn svg {
229
+ width: 16px;
230
+ height: 16px;
231
+ }
232
+
233
+ [data-layout="focused"] .sidebar-icon-btn .icon-text {
234
+ font-size: var(--font-size-xs);
235
+ font-weight: var(--font-weight-bold);
236
+ }
@@ -0,0 +1,29 @@
1
+ /* ============================================================================
2
+ LAYOUTS INDEX - Master import file for all layout styles
3
+ ============================================================================
4
+
5
+ PURPOSE: Central import point for the CourseCode layout system.
6
+ Layouts control the overall visual structure of the course (header, sidebar,
7
+ footer, content area positioning).
8
+
9
+ LAYOUTS:
10
+ - sidebar (default): Traditional LMS layout with slide-out navigation menu
11
+ - article: Modern web-page feel with minimal chrome and inline progress
12
+ - focused: Immersive layout with hidden navigation and floating controls
13
+ - presentation: Full-screen slideshow with edge navigation arrows
14
+ - canvas: Zero framework CSS — all styles reverted to browser defaults, author BYOs via theme.css
15
+
16
+ USAGE: Set `layout` in course-config.js:
17
+ export const courseConfig = {
18
+ layout: 'article', // 'sidebar' | 'article' | 'focused' | 'presentation' | 'canvas'
19
+ // ...
20
+ };
21
+
22
+ ============================================================================ */
23
+
24
+ @import './base.css';
25
+ @import './traditional.css';
26
+ @import './article.css';
27
+ @import './focused.css';
28
+ @import './presentation.css';
29
+ @import './canvas.css';