mirror of
https://github.com/pbakaus/impeccable.git
synced 2026-09-12 06:06:37 +03:00
Item 1 (hero liveness theater):
- pulsing-dot now merges declarations per selector across rule blocks
(cascade-approximate), descends into media queries, and strips
prefers-reduced-motion: reduce overrides before the predicate runs.
Catches the shipped split-block constructions (size in the base rule,
animation added later or inside a no-preference media block).
- Dots whose element sits inside a header/nav landmark are promoted to
error severity (string-level landmark ranges in both engines); the
browser engine additionally promotes dots resting in the first ~900px.
- blinking-cursor findings in the first ~900px or inside header/nav are
promoted from advisory to warning.
- Per-finding severity overrides now flow through static-html,
browser-injected serialization, and detect-url.
Item 2 (nav-CTA contrast constructions):
- The a24-opus 01/002 header CTA already fires (specificity cascade +
oklch + var() all resolved); systematic sweep found two remaining
escapes and closes both:
- own gradient background on a SAFE_TAGS element (checkColors styled-
control exception now treats an own gradient as an own surface,
contrast measured against the worst stop)
- ::before/::after full-cover surface (static cascade marks pseudo
surfaces; browser adapter reads the pseudo computed style) so text is
measured against the surface the browser actually paints
- nav-cta-constructions fixture locks all eight computable construction
families; background-image: url() remains unflaggable by design.
Item 3 (shape-assembled-illustration, slop/advisory):
- New rule for large inline SVGs composing a pictorial scene from >= 8
primitive shapes at >= 200x200 intrinsic size with >= 3 distinct fills.
Charts (axis labels), stroke-only technical drawings, icons/logos
(small explicit size), and pattern-tiled backgrounds are exempt.
1.8 percent fire rate over the 3069-sample eval corpus, all verified
pictorial scenes; zero fires across val-a22/val-a24.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
115 lines
3.1 KiB
HTML
115 lines
3.1 KiB
HTML
<!DOCTYPE html>
|
|
<html>
|
|
<head>
|
|
<title>Pulsing status dot fixture</title>
|
|
<style>
|
|
:root { --dot: 8px; }
|
|
|
|
/* FLAG: tiny circular live dot on an infinite opacity pulse. */
|
|
.live-dot {
|
|
width: 7px; height: 7px;
|
|
border-radius: 50%;
|
|
background: #22c55e;
|
|
animation: pulse 2.4s ease-out infinite;
|
|
}
|
|
@keyframes pulse {
|
|
0%, 100% { opacity: 1; }
|
|
50% { opacity: 0.3; }
|
|
}
|
|
|
|
/* FLAG: box-shadow ripple variant, var-sized, pill radius. */
|
|
.status .dot {
|
|
width: var(--dot); height: var(--dot);
|
|
border-radius: 999px;
|
|
background: #ef4444;
|
|
animation: ripple 1.8s linear infinite;
|
|
}
|
|
@keyframes ripple {
|
|
0% { box-shadow: 0 0 0 0 rgba(239, 68, 68, 0.4); }
|
|
100% { box-shadow: 0 0 0 6px rgba(239, 68, 68, 0); }
|
|
}
|
|
|
|
/* FLAG: longhand animation-name + iteration-count. */
|
|
.beacon {
|
|
width: 10px; height: 10px;
|
|
border-radius: 50%;
|
|
background: #f59e0b;
|
|
animation-name: pulse;
|
|
animation-duration: 2s;
|
|
animation-iteration-count: infinite;
|
|
}
|
|
|
|
/* PASS: rotation-only spinner — same size class, must never flag. */
|
|
.spinner {
|
|
width: 14px; height: 14px;
|
|
border-radius: 50%;
|
|
border: 2px solid #e5e7eb;
|
|
border-top-color: #3b82f6;
|
|
animation: spin 0.8s linear infinite;
|
|
}
|
|
@keyframes spin { to { transform: rotate(360deg); } }
|
|
|
|
/* PASS: named pulse but the local keyframes only rotate. */
|
|
.fake-pulse {
|
|
width: 8px; height: 8px;
|
|
border-radius: 50%;
|
|
animation: pulse-ring 1s linear infinite;
|
|
}
|
|
@keyframes pulse-ring { to { transform: rotate(180deg); } }
|
|
|
|
/* PASS: large breathing card — not a dot. */
|
|
.breathing-card {
|
|
width: 240px; height: 120px;
|
|
border-radius: 16px;
|
|
animation: pulse 3s ease-in-out infinite;
|
|
}
|
|
|
|
/* PASS: finite attention pulse (no infinite). */
|
|
.nudge {
|
|
width: 8px; height: 8px;
|
|
border-radius: 50%;
|
|
animation: pulse 0.6s ease-out 3;
|
|
}
|
|
|
|
/* PASS: square badge, not circular. */
|
|
.square-badge {
|
|
width: 12px; height: 12px;
|
|
border-radius: 2px;
|
|
animation: pulse 2s infinite;
|
|
}
|
|
|
|
/* FLAG (error): header logo dot whose size and animation live in
|
|
separate rule blocks, animation added inside a matching media query,
|
|
with a reduced-motion reset that must not mask the default. */
|
|
.rec-mark {
|
|
width: 10px; height: 10px;
|
|
border-radius: 50%;
|
|
background: #dc2626;
|
|
}
|
|
@media (prefers-reduced-motion: no-preference) {
|
|
.rec-mark { animation: pulse 2.4s ease-in-out infinite; }
|
|
}
|
|
@media (prefers-reduced-motion: reduce) {
|
|
.rec-mark { animation: none; }
|
|
}
|
|
</style>
|
|
</head>
|
|
<body>
|
|
<header>
|
|
<a href="#top"><span class="rec-mark"></span> Brand</a>
|
|
</header>
|
|
<span class="live-dot"></span>
|
|
<span class="status"><i class="dot"></i> Online</span>
|
|
<span class="beacon"></span>
|
|
<span class="spinner"></span>
|
|
<span class="fake-pulse"></span>
|
|
<div class="breathing-card">Card</div>
|
|
<span class="nudge"></span>
|
|
<span class="square-badge"></span>
|
|
<!-- FLAG: Tailwind utility variant -->
|
|
<span class="animate-ping w-2 h-2 rounded-full bg-emerald-500"></span>
|
|
<!-- PASS: Tailwind pulse on a large skeleton block -->
|
|
<div class="animate-pulse rounded-md w-48 h-6 bg-gray-200"></div>
|
|
</body>
|
|
</html>
|