diff --git a/.github/workflows/verify_build.yml b/.github/workflows/verify_build.yml index ebfdb79..0a3fbc3 100644 --- a/.github/workflows/verify_build.yml +++ b/.github/workflows/verify_build.yml @@ -4,6 +4,7 @@ on: pull_request: paths: - "docs/**" + - "scripts/**" - "package.json" - "package-lock.json" @@ -21,5 +22,8 @@ jobs: - name: Install dependencies run: npm ci + - name: Check mock banner inclusion + run: npm run lint:mocks + - name: Build site run: npx vitepress build docs diff --git a/CHANGELOG.md b/CHANGELOG.md index 7c7b81c..613cdf8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,11 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/). ## [Unreleased] +### Added — Shared mock banner +- New shared mock banner under `docs/public/design-system/v1/mock-banner.{css,js}` — auto-injects a "this is a mock" strip across the top of every prototype, with optional `data-banner-text` override +- CI check `npm run lint:mocks` (wired into `.github/workflows/verify_build.yml`) fails the build if a prototype HTML file under `docs/public/projects/` doesn't reference the shared banner; allowlist supported for deliberate exceptions (currently `deltag-aarhus`) +- Migrated all eight prototypes (opkraevningsoverblik, salary-negotiation, climate-nudging × 3, agentic-orchestration, book-aarhus, deltag-aarhus-timeline, wcag-contrast-checker) onto the shared component, removing six per-prototype banner copies + ### Added — Opkrævningsoverblik BBR-beregner - New "Beregner" tab in the Opkrævningsoverblik prototype that calculates four BBR-driven municipal fees: rottebekæmpelse (with the >250 m² rate split), renovation, skorstensfejer, and ejendomsskat (grundskyld) - Editable mock-BBR data (grundareal, grundværdi, bygninger med type/m²/ildsteder) per test user with per-field reset and live recalculation diff --git a/CLAUDE.md b/CLAUDE.md index bfabce8..8d0ae9c 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -108,6 +108,7 @@ Pages sharing the same `passwordGroup` only prompt once per browser session. The - Place mock HTML files in `docs/public/projects//mocks/` - Link to mocks with the base path prefix: `/research-projects/projects//mocks/file.html` - Use `target="_blank"` on all mock links to bypass VitePress's client-side router + - Include the shared mock banner in each HTML file (CI enforces this — see `docs/projects/design-system/components.md` → "Mock banner") 6. Update `CHANGELOG.md` ## Building locally diff --git a/docs/projects/design-system/components.md b/docs/projects/design-system/components.md index be5bfc3..d9ae930 100644 --- a/docs/projects/design-system/components.md +++ b/docs/projects/design-system/components.md @@ -237,3 +237,30 @@ a stat. Tint by setting `color` on the parent (or via ``` + +## Mock banner + +A shared "this is a mock" banner that every research prototype is +expected to load. Lives outside `.ds` so prototypes that opt out of the +design system can still use it. The companion script auto-injects the +markup and reserves 32 px of `padding-top` on ``. + +```html + + +``` + +Override the text with `data-banner-text`: + +```html + +``` + +The default text is `"Dette er en mock-up, ikke det rigtige eller endelige produkt."` + +A CI check (`npm run lint:mocks`) verifies that every HTML file under +`docs/public/projects/` references the script. If a prototype +deliberately uses a different banner — for example one that mimics an +external product's staging warning — add its path to the `ALLOWLIST` in +`scripts/check-mock-banners.mjs`. diff --git a/docs/public/design-system/v1/README.md b/docs/public/design-system/v1/README.md index e02a448..c24d855 100644 --- a/docs/public/design-system/v1/README.md +++ b/docs/public/design-system/v1/README.md @@ -25,6 +25,10 @@ prototypes that mix this with Tailwind or another framework. (`ds-container`, `ds-stack`, `ds-cluster`, `ds-grid`). - **components.css** — buttons, badges, cards, form inputs, tables, modals, sidebar nav, stat cards, alerts. +- **mock-banner.css** + **mock-banner.js** — shared "this is a mock" + banner. Loaded standalone (not part of `index.css`) so any prototype + can use it, whether or not it opts into `.ds`. CI fails if a prototype + HTML under `docs/public/projects/` doesn't reference the script. - **playground.html** — live gallery of every component. ## Playground diff --git a/docs/public/design-system/v1/mock-banner.css b/docs/public/design-system/v1/mock-banner.css new file mode 100644 index 0000000..9f9219b --- /dev/null +++ b/docs/public/design-system/v1/mock-banner.css @@ -0,0 +1,36 @@ +/* + * Shared mock banner for ITKdev Research prototypes. + * + * Loaded standalone — not part of .ds — so any prototype can use it, + * including those that opt out of the design system. Uses :where() + * for low specificity so prototypes can override locally if needed. + * + * Pair with mock-banner.js, which auto-injects the markup and adds + * the matching body padding-top. + */ + +:where(.mock-banner) { + position: fixed; + top: 0; + left: 0; + right: 0; + height: 32px; + display: flex; + align-items: center; + justify-content: center; + padding: 0 16px; + background: #fef9e7; + color: #666; + text-align: center; + font-size: 12px; + font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif; + letter-spacing: 0.3px; + border-bottom: 1px solid #f0e6c0; + z-index: 1000; + pointer-events: none; +} + +:where(.mock-banner strong) { + font-weight: 600; + margin-right: 4px; +} diff --git a/docs/public/design-system/v1/mock-banner.js b/docs/public/design-system/v1/mock-banner.js new file mode 100644 index 0000000..11c3f8e --- /dev/null +++ b/docs/public/design-system/v1/mock-banner.js @@ -0,0 +1,47 @@ +/* + * Auto-injects a "this is a mock" banner at the top of the page. + * + * Usage: + * + * + * + * Idempotent: a second invocation is a no-op. + * Text priority: data-banner-text on the script tag > existing + * .mock-banner markup in the page > built-in default. + */ +(function () { + const DEFAULT_TEXT = 'Dette er en mock-up, ikke det rigtige eller endelige produkt.'; + const BANNER_HEIGHT = '32px'; + + function init() { + if (!document.body) return; + + const existing = document.querySelector('.mock-banner'); + const script = document.currentScript + || document.querySelector('script[src*="mock-banner.js"]'); + const override = script && script.getAttribute('data-banner-text'); + + let banner = existing; + if (!banner) { + banner = document.createElement('div'); + banner.className = 'mock-banner'; + banner.setAttribute('role', 'note'); + document.body.insertBefore(banner, document.body.firstChild); + } + + if (override) { + banner.textContent = override; + } else if (!banner.textContent.trim()) { + banner.textContent = DEFAULT_TEXT; + } + + document.body.style.paddingTop = BANNER_HEIGHT; + } + + if (document.readyState === 'loading') { + document.addEventListener('DOMContentLoaded', init, { once: true }); + } else { + init(); + } +})(); diff --git a/docs/public/projects/agentic-orchestration/mocks/unified-platform.css b/docs/public/projects/agentic-orchestration/mocks/unified-platform.css index 3d30e41..b44b582 100644 --- a/docs/public/projects/agentic-orchestration/mocks/unified-platform.css +++ b/docs/public/projects/agentic-orchestration/mocks/unified-platform.css @@ -23,21 +23,6 @@ body { flex-shrink: 0; } -/* ── Mock banner ── */ -.mock-banner { - position: fixed; - top: 0; - left: 0; - right: 0; - background: #fef9e7; - color: #666; - text-align: center; - padding: 4px 16px; - border-bottom: 1px solid #f0e6c0; - font-size: 12px; - z-index: 200; -} - /* ── Sidebar ── */ .sidebar { width: 230px; @@ -45,7 +30,6 @@ body { border-right: 1px solid #e5e7eb; display: flex; flex-direction: column; - padding-top: 28px; flex-shrink: 0; } diff --git a/docs/public/projects/agentic-orchestration/mocks/unified-platform.html b/docs/public/projects/agentic-orchestration/mocks/unified-platform.html index 3f81c63..08baa56 100644 --- a/docs/public/projects/agentic-orchestration/mocks/unified-platform.html +++ b/docs/public/projects/agentic-orchestration/mocks/unified-platform.html @@ -5,13 +5,12 @@ Agentic Orchestration Studio — Unified Platform Mock + + -
- MOCK — Agentic Orchestration Studio: Unified Platform (Flowable + n8n + Grafana) -
-