AI Act Check
The live screen for the room at the MPP Hackathon Dublin. An agent pays 0.50 USD over Stripe MPP and the verdict lands here, next to the terminal, read from five to ten metres away. It extends the aiwithdiego.com site v5 system: same typeface, same colours, same marker. The site's night section becomes the stage. Every example on this page is drawn by public/tokens.css, the stylesheet the build links.
What came from the website, and what was extended
| Element | On aiwithdiego.com | Here |
|---|---|---|
| Typeface | Archivo, one family, contrast from the width axis (62% / 88% / 100% / 125%) | Same. Uppercase only in the 62% condensed display, as on the site. |
| Ink, white, grey | #0C0C10 #FFFFFF #76757E | Ink is the text on every tier fill. |
| Night section | #14113A bg, #F1EFFA text, #9C97C4 grey | Night is the stage. Grey lifted to #C9C5E8 for body (6.52:1 misses AAA; 10.79:1 passes). |
| Hot | #FF4F1A, the brand accent | Prohibited. Focus ring. |
| Hero marker | Peach, yellow, lilac strokes; 34 ms per letter, linear, ±0.9° tilt, radius .06em .14em .08em .16em | Yellow = high-risk, lilac = limited. The stroke is the arrival animation. |
| Live dot | #2BD46A with a 3px halo, next to Talk to Smith | Live status, paid tick, minimal tier. |
| Index rows | Hairline-ruled work index, no cards | Obligations, feed and steps are index rows. No card grid anywhere. |
| Easing | cubic-bezier(.2,.8,.2,1), 400 ms, 550 ms | Same tokens. |
00Principles
One answer per check
A keynote slide, not a dashboard. The tier is most of the screen; then what it means, why, and three things to do. The rest is a number.
One colour, one meaning
Hue belongs to the five tiers. Law, dates and roles are told apart by form (solid or dashed, filled or outlined), so a colour on screen always means a tier.
The marker is the arrival
A new verdict is revealed by the website's highlighter stroke at its own 34 ms a letter. Nothing else on the screen moves.
A slide, not a page
Type scales with --u from a 1920x1080 grid; the layout fills any viewport, 16:9 or not. Nothing scrolls.
01Colour tokens
All tokens live on :root. Swatches marked with a ratio show contrast against the stage #14113A, computed live from the tokens.
From the website
Stage (extended for the projector)
Tiers
Law labels
02Contrast
Computed live from the tokens with the WCAG 2.2 formula. Body text targets AAA (7:1); large text (24px bold or 30px and up) targets 4.5:1; non-text marks 3:1. Every row passes.
| Foreground | Background | Used for | Ratio | Target |
|---|
03Colour-blind check
Simulated with Machado (2009) matrices. For protanopia and deuteranopia, prohibited, high-risk and minimal all drift towards ochre and minimal sits close to high-risk in hue. That is why no tier relies on hue: each has its own word, its own glyph (⊘ ▲ ⓘ ○ dashed ?) and a different lightness (hot 0.27, live 0.49, lilac 0.67, yellow 0.79 relative luminance). Incomplete is the only outline.
04Typography
The first six rows are the live screen; the rest are the library. Archivo, the website's only typeface, as a variable font (width 62–125, weight 100–900) from Google Fonts. Sizes are design pixels at 1920x1080; shown here at 1:1. At 1080p on a 2 m tall screen, 24px is about 44 mm per em, readable from 10 m. Fallback: Helvetica Neue, whose condensed cut macOS maps to 62%. Tabular figures throughout.
--fs-stage · 230 · 62% · 800 · capsScreen: the tier word, fitted by --chars.
--fs-idle · 180 · 62% · 800 · capsScreen: idle headline.
--fs-meaning · 56 · 88% · 700Screen: what the tier means.
--fs-why · 36 · 100% · 500Screen: why and when.
--fs-duty · 32 · 100% · 400Screen: key duties.
--fs-strip · 24 · 100%Screen: bottom strip.
--fs-verdict · 150 · 62% · 800 · capsThe answer. Fits its 560 column: min(150, 540 / (chars × .43)).
--fs-hero · 104 · 62% · 800 · capsIdle headline only.
--fs-law · 56 · 62% · 800 · capsLaw group names.
--fs-feed · 44 · 62% · 800 · capsFeed tier word.
--fs-lead · 38 · 88% · 700Tier sentence, idle sub.
--fs-title · 30 · 88% · 700Matched rule, paid amount, product name.
--fs-body · 24 · 100% · 400Obligation text. The floor for running text at 1080p.
--fs-meta · 22 · 100% · 600–700Articles, dates, receipt, counts.
--fs-meta · 22 · 125% · 600Wide labels, sentence case (no uppercase labels).
--fs-min · 20 · 100% · 400Smallest text on stage. Disclaimer only.
05Spacing
A 4-point scale in design pixels, multiplied by --u. Screen gutters are --s-8 (64); column gaps --s-7 (48).
--s-1 · 4--s-2 · 8--s-3 · 12--s-4 · 16--s-5 · 24--s-6 · 32--s-7 · 48--s-8 · 64--s-9 · 9606Radii, lines, shadow
The site is near-square: 2px picture corners, 6px tabs. No pills, no rounded cards.
--r-0 · 0Regions, rules, rows
--r-chip · 3Article chips
--r-tag · 6Date tags, banner
--r-markThe marker, hand-drawn
--r-dot · 50%Status dot only
Lines and shadow
--rule-w2 design px. 1px rules vanish on projectors.--rule-law6, the top rule of a law group: solid for AI Act, dashed for GDPR.- No shadows on the screen.
--shadow-floatis the site's.browsershadow, kept for parity.
07Motion
One moment per check: the site's own hero marker sweeps behind the tier word. Under 450 ms.
| Token | Value | Use |
|---|---|---|
--e-mark | linear | The marker stroke, like a hand (site .hmark) |
--mark-per-char | 34 ms | Stroke length: HIGH-RISK = 306 ms |
--mark-tilt | -0.9° | Stroke angle |
--arrive-mark | 120 ms | Delay before the stroke starts |
--e / --t-base / --t-slow | site easing, 400 / 550 ms | Library only; nothing on the screen fades or slides |
| reduced motion | no animation | The verdict appears whole and at once |
High-risk
Allowed, with strict duties.
- Add .is-new to
.ac-screenfor one paint when a new receipt arrives; remove it before the next. - The stroke is the only motion on the screen: no fades, no slides, no pulsing dot.
- The ink word is dark on night until the stroke passes it, so the stroke reveals the answer.
<div class="ac-screen is-new"> … </div>
08The screen (assembled)
The keynote layout: header, the answer, at most three duties, one strip. Read in three seconds from ten metres. CV screening for a deployer, real engine output.
AI Act Check
A first-pass classification from your answers, not legal advice. Rules version 2026-11-10.
- .ac-screen > .ac-bar + main.ac-slide (
.ac-slide__body: hero, todo; then the disclaimer) + footer.ac-strip. - As a direct child of
bodyit fills the viewport at any ratio: type scales with the smaller axis, extra height goes to the hero row.
<div class="ac-screen" id="screen" aria-live="polite">
<header class="ac-bar">…</header>
<main class="ac-slide">
<div class="ac-slide__body">
<div class="ac-hero">…</div>
<section class="ac-todo">…</section>
</div>
<p class="ac-disclaimer">…</p>
</main>
<footer class="ac-strip">…</footer>
</div>09Brand bar
Logo, product name, takings and status. The takings line is the MPP story; the price lives in the agent's 402, not here.
AI Act Check
- .ac-bar__logo draws
--logo, the site's logo.png as a data URI set once per page (copy it from the mock). - Takings: sum of
amountover the feed. With none: No checks yet.
<header class="ac-bar"> <span class="ac-bar__logo" role="img" aria-label="AIwithDiego"></span> <h1 class="ac-bar__product">AI Act Check</h1> <div class="ac-bar__end"> <span>Earned <b>1.50 USD</b> from 3 checks</span> <span class="ac-status" role="status">Live</span> </div> </header>
10Hero
The answer, what it means, and one line of why and when. Nothing else competes with it.
High-risk
Allowed, with strict duties.
Employment · Annex III · from 2 Dec 2027
Prohibited
Banned in the EU.
Emotion recognition at work or in education · Art. 5(1)(f) · since 2 Feb 2025
- .ac-hero:
h2.ac-answer(230 design px, fitted by--chars),p.ac-meaning(glyph + sentence),p.ac-why. - Why line: short rule title · short article · from/since date, joined with “ · ”. See the spec for the derivation.
<div class="ac-hero"> <h2 class="ac-answer" data-tier="high" style="--chars:9"> <span class="ac-mark">High-risk</span> </h2> <p class="ac-meaning" data-tier="high"><span class="ac-glyph" aria-hidden="true"></span>Allowed, with strict duties.</p> <p class="ac-why">Employment · Annex III · from 2 Dec 2027</p> </div>
11Key duties
What you must do: at most three duties in plain text, one GDPR line, and the count of the rest. No article column.
What you must do
- Use it according to the provider's instructions.
- Assign trained, competent people to oversee it.
- Make sure the input data you control is relevant to the purpose.
GDPR too: lawful basis and notice, vendor contracts, impact assessment, right to a human decision
+19 more in the agent's answer
- .ac-todo[data-tier] (the dash takes the tier colour),
h3.ac-todo__head,ul.ac-todo__list,p.ac-gdpr,p.ac-more. - Duties:
key: truefirst, else the first three AI Act duties that are not Art. 4. GDPR line: never for prohibited. - Incomplete uses the same block: Still to answer, three question ids, +N more.
<section class="ac-todo" data-tier="high" aria-label="What you must do"> <h3 class="ac-todo__head">What you must do</h3> <ul class="ac-todo__list"> <li>Use it according to the provider's instructions.</li> <li>Assign trained, competent people to oversee it.</li> <li>Make sure the input data you control is relevant to the purpose.</li> </ul> <p class="ac-gdpr"><b>GDPR too:</b> lawful basis and notice, vendor contracts, impact assessment, right to a human decision</p> <p class="ac-more">+19 more in the agent's answer</p> </section>
12Bottom strip
One thin band: the payment on the left, earlier checks on the right.
- .ac-strip >
p.ac-strip__paid(tick + one span) and.ac-strip__earlier(label +ul.ac-strip__pills, up to 4). - Receipt shortened to first 8 + … + last 4; time
HH:MMEurope/Dublin. Empty: Paid checks line up here.
<div> <footer class="ac-strip"> <p class="ac-strip__paid"> <span class="ac-paid__tick" aria-hidden="true"></span> <span><b>Paid 0.50 USD</b> · receipt pi_3SQ9f…bXc4 · 14:04</span> </p> <div class="ac-strip__earlier"> <span>Earlier</span> <ul class="ac-strip__pills" aria-label="Earlier checks"> <li class="ac-pill" data-tier="limited"><span class="ac-glyph" aria-hidden="true"></span><b>Limited</b> <time>14:01</time> </li> <li class="ac-pill" data-tier="prohibited"><span class="ac-glyph" aria-hidden="true"></span><b>Prohibited</b> <time>13:58</time> </li> </ul> </div> </footer> </div>
13Earlier pill
A past check: glyph, tier word, time. Outlined in the tier colour (dashed for incomplete). Square-cornered like the site's tabs, not round.
- Prohibited
- High-risk
- Limited
- Minimal
- Incomplete
- li.ac-pill[data-tier] with
.ac-glyph,b,time.
<ul class="ds-row"> <li class="ac-pill" data-tier="prohibited"><span class="ac-glyph" aria-hidden="true"></span><b>Prohibited</b> <time>14:00</time> </li> <li class="ac-pill" data-tier="high"><span class="ac-glyph" aria-hidden="true"></span><b>High-risk</b> <time>14:01</time> </li> <li class="ac-pill" data-tier="limited"><span class="ac-glyph" aria-hidden="true"></span><b>Limited</b> <time>14:02</time> </li> <li class="ac-pill" data-tier="minimal"><span class="ac-glyph" aria-hidden="true"></span><b>Minimal</b> <time>14:03</time> </li> <li class="ac-pill" data-tier="incomplete"><span class="ac-glyph" aria-hidden="true"></span><b>Incomplete</b> <time>14:04</time> </li> </ul>
14Status dot
The site's online dot. Green with halo when the last poll worked; a red ring and words when it failed. No pulse.
- .ac-status live, .ac-status.is-offline inside the banner after two failed polls.
<div class="ds-row"> <span class="ac-status" role="status">Live</span> <span class="ac-status is-offline" role="status">Can't reach the server.</span> </div>
15Idle state
Before the first paid check: one headline, one sentence.
AI Act Check
- h2.ac-idle-title + p.ac-why inside
.ac-slide__body.
<div class="ac-slide__body"> <h2 class="ac-idle-title">Waiting for an agent to pay</h2> <p class="ac-why">…</p> </div>
16Incomplete state
The agent paid but left required questions unanswered.
AI Act Check
A first-pass classification from your answers, not legal advice. Rules version 2026-11-10.
- Hero with the dashed INCOMPLETE word; why line N questions unanswered; the key-duties block lists the first three ids.
<section class="ac-todo" data-tier="incomplete" aria-label="Still to answer"> <h3 class="ac-todo__head">Still to answer</h3> <ul class="ac-todo__list"> <li>gpai model</li> <li>manipulative techniques</li> <li>exploits vulnerabilities</li> </ul> <p class="ac-more">+16 more in the agent's answer</p> </section>
17Error state (offline)
The feed stopped answering. The last verdict stays up; the status becomes a banner. Neutral border, never a red block.
- Replaces .ac-status in the bar after two failed polls; the next good poll restores Live.
<span class="ac-banner" role="alert"> <span class="ac-status is-offline">Can't reach the server.</span> <span>Last check stays up.</span></span>
18Disclaimer
Ships with every verdict: one line at the foot of the slide, 20 design px.
A first-pass classification from your answers, not legal advice. Rules version 2026-11-10.
- Text from
verdict.disclaimerandverdict.rules_version.
<p class="ac-disclaimer">A first-pass classification from your answers, not legal advice. Rules version 2026-11-10.</p>
19Tier badge
Glyph and word in the tier colour. Used on the plain GET / page.
- .ac-tier[data-tier]; glyph is a CSS mask in tokens.css.
<div class="ds-row"> <span class="ac-tier" data-tier="prohibited"><span class="ac-glyph" aria-hidden="true"></span>Prohibited</span> <span class="ac-tier" data-tier="high"><span class="ac-glyph" aria-hidden="true"></span>High-risk</span> <span class="ac-tier" data-tier="limited"><span class="ac-glyph" aria-hidden="true"></span>Limited</span> <span class="ac-tier" data-tier="minimal"><span class="ac-glyph" aria-hidden="true"></span>Minimal</span> <span class="ac-tier" data-tier="incomplete"><span class="ac-glyph" aria-hidden="true"></span>Incomplete</span> </div>
20Article chip
A matched rule's articles. Kept for detail views.
Art. 6(2)Annex III point 4
- .ac-chips > .ac-chip.
<p class="ac-chips"> <span class="ac-chip">Art. 6(2)</span> <span class="ac-chip">Annex III point 4</span> </p>
21Date tag
Filled when a duty already binds, outlined when it applies later.
- .ac-date.is-now / .ac-date.is-later. Format 2 Dec 2027 (en-IE).
<div class="ds-row"> <span class="ac-date is-now">In force since 2 Feb 2025</span> <span class="ac-date is-later">From 2 Dec 2027</span> </div>
22Paid line (large)
The v1 receipt block. The screen uses the strip instead.
Paid 0.50 USD over Stripe MPP
- .ac-paid.
<div class="ac-paid"> <span class="ac-paid__tick" aria-hidden="true"></span> <p class="ac-paid__amount">Paid 0.50 USD <span>over Stripe MPP</span> </p> <p class="ac-paid__meta"> <span>Receipt <span class="ac-paid__id">pi_3SQ9fWLkdIwHu7ix0Jq2bXc4</span></span> <time>14:04:21</time> </p> </div>
23Law group header
Solid rule for AI Act, dashed for GDPR. For a full-list view.
AI Act
10 duties for the deployerGDPR
12 duties- .ac-law[data-law].
<div class="ds-stack"> <header class="ac-law" data-law="ai-act"> <h3 class="ac-law__name">AI Act</h3> <span class="ac-law__count">10 duties for the deployer</span> </header> <header class="ac-law" data-law="gdpr"> <h3 class="ac-law__name">GDPR</h3> <span class="ac-law__count">12 duties</span> </header> </div>
24Obligation row
Article, text, role when mixed. For a full-list view.
- Art. 26(2)Assign trained, competent people to oversee it.
- Art. 50(2)ProviderMark outputs in a machine-readable, detectable way as AI-generated (e.g. watermark or provenance metadata).
- .ac-ob:
.ac-ob__art+.ac-ob__text;.ac-ob--rule.ac-ob--stackfor narrow columns.
<ul class="ac-obs"> <li class="ac-ob"> <span class="ac-ob__art">Art. 26(2)</span> <span class="ac-ob__text">Assign trained, competent people to oversee it.</span> </li> <li class="ac-ob"> <span class="ac-ob__art">Art. 50(2)<span class="ac-ob__role">Provider</span></span> <span class="ac-ob__text">Mark outputs in a machine-readable, detectable way as AI-generated (e.g. watermark or provenance metadata).</span> </li> </ul>
25Feed band
The v1 earlier-checks band. The screen uses pills in the strip.
Earlier checks
- Limited
- Prohibited
- .ac-feed > .ac-feed__item.
<section class="ac-feed" aria-label="Earlier checks"> <h2 class="ac-feed__label">Earlier checks</h2> <ul style="display:contents"> <li class="ac-feed__item"> <span class="ac-tier" data-tier="limited"><span class="ac-glyph" aria-hidden="true"></span>Limited</span> <span class="ac-feed__meta"><b>Art. 50(1)</b> <span>15 duties</span></span> <span class="ac-feed__meta"> <span>0.50 USD</span> <span>14:01:47</span></span> </li> </ul> </section>
26v1 three-column verdict
The first screen, rejected as too busy for a stage on 9 Nov. Kept to show what not to put on the screen.
AI Act Check
Paid 0.50 USD over Stripe MPP
High-risk
Allowed, with strict duties.
Employment and workers management
Art. 6(2)Annex III point 4
A first-pass classification from your answers, not legal advice. Rules version 2026-11-10.
AI Act
10 duties for the deployer- Art. 4Take measures to build the AI literacy of staff who run or use the system, and keep a record.
- Art. 26(1)Use it according to the provider's instructions.
- Art. 26(2)Assign trained, competent people to oversee it.
- Art. 26(4)Make sure the input data you control is relevant to the purpose.
- Art. 26(5)Monitor it, and suspend it and tell the provider if it poses a risk.
- Art. 26(6)Keep the logs it generates for at least six months.
- Art. 26(11)Tell people when it is used to make or help make decisions about them.
- Art. 86Explain the decision to an affected person who asks.
- Art. 27If you are a public body or provide a public service, do a fundamental rights impact assessment before first use.
- Art. 26(7)Before using it at work, inform workers' representatives and the affected workers.
GDPR
12 duties- Arts. 5, 6, 13, 14, 32Lawful basis, transparency and security
- Arts. 28, 44-46AI vendors as processors
- Art. 35Data protection impact assessment
- Art. 22Solely automated decisions with significant effects
All 12 are in the agent's answer.
Earlier checks
- Limited
- Prohibited
- .ac-main, .ac-verdict, .ac-col.
<main class="ac-main">…</main>
27Screen layout
Design px on a 1920x1080 grid. Any viewport is filled: --u = min(100vw/1920, 100vh/1080) sizes the type, the grid stretches to 100vw x 100vh.
┌ ac-bar ─────────────────────────────────────────────────────────────────────────┐ │ logo │ AI Act Check Earned 1.50 USD from 3 checks ● Live │ ├ main.ac-slide ───────────────────────────────────────────────────────────────────┤ │ ▇▇▇ HIGH-RISK ▇▇▇ (hero row takes all extra height) │ │ ▲ Allowed, with strict duties. │ │ Employment · Annex III · from 2 Dec 2027 │ │ │ │ What you must do │ │ ─ duty 1 ─ duty 2 ─ duty 3 (one per line) │ │ GDPR too: impact assessment, right to a human decision │ │ +19 more in the agent's answer │ │ disclaimer, one line │ ├ footer.ac-strip ─────────────────────────────────────────────────────────────────┤ │ ✓ Paid 0.50 USD · receipt pi_3SQ9f…bXc4 · 14:04 Earlier [▲ HIGH 14:04] [⊘…] │ └─────────────────────────────────────────────────────────────────────────────────┘
28The 22-obligation rule
CV screening returns 22 duties. The screen shows three.
- Three duties: the ones Hank marks
key: true; if none, the first three AI Act duties that are not Art. 4. - One GDPR line: the short names of the matched
gdpr-rules (table in the spec). None for prohibited. - The rest is a number: +19 more in the agent's answer. The full list is in the JSON on Diego's terminal.
- Guard: if the slide body still overflows, drop the third duty and add it to the count. Never scroll, never shrink type.
29Accessibility
Contrast
Body ≥ 7:1 (text 15.77, text-2 10.79). Ink on every tier fill ≥ 5.94, all at large sizes. Rules are decorative; the incomplete outline is 6.52.
Not colour alone
Tier = word + glyph + lightness. Law = word + solid/dashed rule. Date = words + filled/outlined. Status = words + dot/ring.
Screen readers
One h1 (product), the answer is an h2, What you must do an h3. The screen is aria-live="polite": a new check reads as tier, sentence, why, duties, then the payment. Glyphs are aria-hidden.
Motion
The marker stroke is the only animation. prefers-reduced-motion removes it; the verdict appears whole. No flashing, no loops.
Forced colours
The marker becomes Highlight with HighlightText; glyphs, tick and dot become CanvasText.
Language and dates
lang="en". Dates as 2 Dec 2027, times 24 h Europe/Dublin. No interactive controls on the screen, so no focus order to manage; the focus ring (hot, 3px) exists for the plain page.
30Stylesheet
public/tokens.css exactly as linked above. Read-only for the build: anything missing goes in public/live.css and is named in the PR.