Skip to content

Use the CMP design system across the entire website #129

Description

@alexeygrigorev

Product decision

Use the adopted Course Management Platform (CMP) design system as the visual authority for the entire DataTalks.Club Django website. Public content, accounts, and custom Studio extend CMP; copied CMP learner/course pages are not redesigned to match later public-site experiments.

This is a migration umbrella, not one big-bang implementation issue. Each child ships one complete route family with its content, states, responsive/dark/accessibility behavior, tests, and owner-reviewed screenshots. Shared changes land with the first real consumer and must not globally restyle an unverified surface.

Normative authority

Content, URL, SEO, privacy, event, course, and management behavior remain governed by their owning specifications/issues. This umbrella establishes visual authority; it does not reopen those product contracts.

Exact visual authority and provenance

The source is exact CMP commit 98a235283904b4ef9ad29e196298540756cf1bcc, dated 2026-08-04. Do not use a moving branch, memory, or a screenshot from a later public experiment.

Primary references at that commit:

  • templates/base.html, SHA-256 f51666391e33aec905f43312215bfd82094bfb0088414594f40bcbdfc21560b8: application shell, header/footer, content width, type stack, theme control, account menu;
  • courses/static/courses.css, SHA-256 282ed7b15df2502a8d4c2e9cd45ef1f8e92771835243d3cbc590f78db9ed5f8f: tokens, controls, forms, alerts, badges, breadcrumbs, lists, dark mode, and responsive rules;
  • courses/templates/courses/course_list.html and _course_list_card.html: catalogue hero, section hierarchy, divided rows, metadata, actions, archive, and empty states;
  • courses/templates/courses/course.html: representative content/detail hierarchy;
  • copied account/social-account templates: compact form/panel/error patterns;
  • copied cadmin templates, adopted mechanically as studio_courses, for dense management presentation.

The adopted website versions course_platform_templates/base.html and courses/static/courses.css include explicit, checksum-recorded DTC overlays. Those overlays preserve canonical same-host navigation, one account menu, capability-gated Studio, accessibility/security semantics, local assets, announcements, responsive fixes, and the renamed Studio Courses namespace. The source remains the design authority; the overlay ledger is the review boundary for necessary website integration.

Token contract

Reuse the existing variables and semantic classes; do not copy their current hex values into a new palette:

  • surfaces/borders: --page-bg, --surface-bg, --surface-muted, --border-muted, with app-surface, app-surface-muted, app-border, and app-divide;
  • text/actions: --text-primary, --text-heading, --text-muted, --link-color, --link-hover, with app-text, app-heading, app-muted, and app-link;
  • controls/state: input, success, warning, danger, info, and --focus-ring tokens with the existing primer-button, form-control, badge, alert, breadcrumb, pagination, account-menu, and theme-control patterns;
  • typography: CMP’s Inter, ui-sans-serif, system sans stack, normal tracking, and restrained catalogue/detail heading scale;
  • dark mode: the existing body.dark-mode token switch and local theme control; no page-specific dark palette;
  • motion/focus: the accepted shared reduced-motion and keyboard-focus behavior, including Remove pointer-click orange outlines from header controls #126’s modality correction when accepted.

Composition contract

  • Use the CMP app-content-shell (56rem) and recorded wider shared-header navigation integration; base horizontal/vertical spacing remains px-4/md:px-8 and py-5/md:py-10.
  • Default public discovery is a semantic full-width divided list, not a marketing card grid. Use bounded cards/panels only where CMP uses them for a real object, form, alert, or grouped detail.
  • Preserve semantic landmarks, one page H1, ordered heading levels, readable line lengths, breadcrumbs where the route hierarchy needs them, clear primary links, honest empty/error states, and server-rendered operation without JavaScript.
  • Reuse CMP buttons/forms/lists/cards rather than parallel .button, .card, .hero, .panel, palette, radius, or shadow systems. Any genuinely missing primitive must be token-backed, narrowly reusable, documented in the adoption overlay, and introduced with an actual consumer and test.
  • Keep templates readable, indented, line-broken, and non-minified. No generated HTML source replaces reviewed Django templates.

Repository audit — current main

Django searches templates in this order:

  1. course_platform_templates/;
  2. project templates/;
  3. installed-app templates.

Current inheritance is:

Surface Current inheritance Audit finding
/, /unified/, and templates/public/** hubs/details page → core/base.html → logical base.htmlcourse_platform_templates/base.html Already receives CMP shell/tokens; compositions repeat utility patterns and must be migrated by route family, not globally guessed.
Docs, FAQ, Slack, and other templates/review/** surfaces page → core/base.html → adopted CMP base Same shell; page structures remain separate review-era compositions.
Accounts/allauth copied or overlaid page → adopted CMP base Closest non-course reference; preserve provider/session/form behavior while aligning any website-owned account composition.
Copied course/learner pages copied page → adopted CMP base Visual source of truth. #128 owns the one current project shadow and the protected no-shadow rule. Do not redesign these pages.
Copied Studio Courses page → studio_courses/base.html → adopted CMP base Already CMP-derived and mechanically renamed; preserve its dense management composition and behavior.
Custom Studio page → studio/base.html → adopted CMP base, plus core/studio.css Shell/tokens are shared, but .panel, .eyebrow, status/card grids, raw button colors, large radii, and shadows form a scoped parallel component vocabulary to migrate in its own slice.
Dormant project shell templates/base.html loading core/site.css Lower precedence makes it currently unreachable, but it contains an independent #0b5fff palette, large marketing hero, card grids, .button system, distinct header/footer, and orange focus. It is a competing fallback and must not remain able to render.
Shared website overlays core/site_shell.css, core/accessibility.css, associated local JS Allowed integration when token-backed and limited to navigation/accessibility behavior. They must not become a second page-composition system.

All current public/review templates already resolve the adopted base. The work is therefore a controlled composition migration plus fail-closed anti-drift protection—not a new design-system build and not permission to rewrite every template at once.

Delivery sequence and child ownership

Prerequisite correction

Initial fast vertical slice — created and fully groomed

#130 is the only child created now. It covers the pages the owner is actively reviewing and lets the team validate density, hierarchy, and evidence expectations before opening the remaining implementation issues.

Subsequent bounded children — create/groom after the first-slice design acceptance

  1. Editorial collections and details: /blog, /podcast, /books, their canonical detail pages, and contextual Person details. Preserve Ship real public content on the final editorial route map #105’s exact .html canonicals, pagination, media/transcripts, relations, SEO, and read-only projection.
  2. Knowledge/support surfaces: /wiki including search/graph/special/detail states, /docs/, /faq/, /slack.html, and the public 404. Preserve query/data/feed routes, content rendering, and established URL spellings.
  3. Accounts/authentication: website-owned login plus copied account/allauth settings, connection, signup, cancellation, error, and logout states. Preserve durable identity, provider, next, session, denial, private-cache, and recovery contracts.
  4. Custom Studio: templates/studio/** and core/studio.css only. Replace the parallel panel vocabulary with CMP management primitives while preserving every capability, CSRF, audit, masked-value, concurrency, private/no-store/noindex, and Studio/admin-API parity contract. Copied studio_courses/** is reference/non-goal, not a redesign target.

Each child must be independently deployable and revertible, name exact routes/templates/states, retain all behavior, and include its own inspected screenshots and [HUMAN] design acceptance. Do not open all four before the first-slice result is accepted; use that accepted evidence to groom them precisely. A child may add a shared primitive only with a real consumer, and its tests must prove that it does not unexpectedly alter already accepted or not-yet-migrated route families.

Exact coordination with active work

#125 and #126 are parallel ownership boundaries rather than dependencies for page composition. When either lands, later children start from its accepted shared shell. The umbrella cannot be declared complete until their global footer/focus results are present and regression-verified across the representative final matrix.

Umbrella acceptance criteria

  • Every planned child is linked here, fully groomed before implementation, independently tested/accepted, and closed or left open only for an explicitly labelled HUMAN gate.
  • Every public, account, and custom-Studio HTML route resolves the adopted CMP base and token/component system; copied Course and Studio Courses pages retain their accepted CMP composition.
  • No renderable project-level alternate base.html, competing public stylesheet, duplicate palette/type/radius/shadow system, unrecorded copied-file overlay, inline page theme, or silent template shadow remains.
  • Typography, shell width, section/list/card hierarchy, buttons, forms, pagination, breadcrumbs, alerts, statuses, dark mode, focus, reduced motion, and responsive rules follow the contract above across all migrated states.
  • Canonical URLs, redirects, status/method behavior, SEO/robots/sitemap/structured data, content values/order, forms, sessions, permissions, mutations, cache policy, and no-JavaScript usefulness remain unchanged except in their separately accepted owning issues.
  • Templates remain readable and non-minified; CSS/template anti-shadow and provenance tests fail closed on a new alternate system or protected-name collision.
  • Each child passes focused Django/contracts plus applicable content/SEO/link/accessibility checks and make test-playwright-core; final consolidation passes the CMP verifier and the normal uv/Make quality gates with no model/migration drift caused by this visual work.
  • At approximately 1440×900 and 390×844, representative light/dark screenshots cover every route family plus its important empty/error/denied/form state. Independent testing opens every image and records no overflow, clipping, missing assets, console/page/request errors, debug page, or error page.
  • Keyboard, pointer, touch, skip link, visible focus, theme persistence, 200% zoom/reflow, 320/390 px widths, reduced motion, semantic headings/landmarks, descriptive links/icons, target sizes, and light/dark contrast remain usable.
  • [HUMAN] The product owner accepts each vertical slice against deterministic references from exact CMP commit 98a235..., and finally accepts a cross-site desktop/mobile/light/dark contact sheet as one coherent design family. “Looks similar” or automated pixel similarity alone is insufficient.

Global browser/evidence contract

For each child, use deterministic synthetic or checked public data and no PII. Store screenshots only below .tmp/screenshots/issue-<child>/, identify the exact source commit/reference template and candidate fingerprint, and inspect every screenshot. At minimum:

  1. desktop 1440×900 and mobile 390×844 in light and dark mode for the route family’s primary hub/form;
  2. representative detail plus empty/error/denied states appropriate to the family;
  3. keyboard and pointer focus, 200% zoom/reflow, 320 px overflow, reduced motion, theme switching/persistence, local assets, console/page/request errors, and JavaScript-disabled public reading;
  4. explicit comparison notes for allowed DTC integration differences from the pinned CMP reference; and
  5. focused browser assertions plus make test-playwright-core using the repository’s supported local Chromium path. Cross-browser claims require separately installed/reviewed evidence and must not be inferred from Chromium screenshots.

Non-goals

  • No redesign or rewrite of copied CMP course/learner templates, copied Studio Courses composition, scoring, submissions, enrollment, peer review, dashboards, leaderboards, certificates, or course operations.
  • No change to URL spelling, redirects, SEO/canonical/robots/sitemap policy, content projection, event data/registration, account identity/provider flow, Studio permissions/API parity, models, migrations, jobs, email, infrastructure, analytics, or legal wording.
  • No SPA, JavaScript-only content, new frontend framework, remote font/icon/CDN dependency, page builder, arbitrary theme editor, separate public stylesheet, generated/minified template source, or request-time external fetch.
  • No global CSS rewrite that changes unreviewed pages. No “modernization” that replaces CMP with a new visual language.
  • No production/deployment/AWS/Search Console mutation while grooming or implementing a child.

Process handoff

#129 stays open as the umbrella and receives Refs #129 from accepted child commits; it is not an implementation branch. Start #130 only after #128 merges. For every child: engineer implements/tests without committing, a separate tester freezes and verifies the candidate plus screenshots, product management accepts the user-visible result, the owner completes the named [HUMAN] design gate, and only then does the engineer commit/close that child. The orchestrator locally merges without a pull request and on-call alone observes post-push CI/deployment.

Metadata

Metadata

Assignees

No one assigned

    Labels

    P0Must-have or release-blockingaccessibilityArea: accessibilityadminArea: adminauthArea: authcontentArea: contentenhancementNew feature or requestepicParent issue grouping implementation workeventsArea: eventsfoundationArea: foundationfrontendArea: frontendintegrationArea: integrationseoArea: seotestingArea: testing

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions