Inspiration

"Ghost text" is what designers call copy you can barely see. Low-contrast text is one of the most common accessibility failures on the web and in print — pastel packaging, light-grey placeholders, white labels on mint buttons. As a packaging and product designer I know the rule, but checking two hex codes at a time doesn't fit how we work: in screenshots and proofs.

What it does

Drop a screenshot, mockup or packaging proof. Ghostlight sweeps it with a "ghost light" (the lamp left burning on an empty stage), raises a ghost wherever text sinks below the WCAG contrast line, and groups them into a ledger by colour pair.

  • Exorcise — repaints each ghost with the nearest passing colour, moving only OKLCH lightness so hue and brand survive.
  • Possession — re-scan as people with protanopia, deuteranopia, tritanopia, achromatopsia or low-vision blur see it.
  • Séance palette — up to 8 colours, every text/background pair, failing pairs fade; export CSS variables and a Markdown report.
  • Targets AA, AA large and AAA. Ratios are floored, never rounded up: 4.497 is a ghost. Every spooky element does a job — the metaphor explains the function. Runs 100% in the browser: no uploads, no accounts.

How we built it

Built with Kiro CLI, spec-first. Steering docs fixed the vocabulary, architecture and design system; Kiro generated a color-engine spec (EARS requirements, design with correctness properties, task plan) and implemented the pure engine (colour, colour-vision simulation, scanner) test-first. Two custom agents: ghost-smith (builder, works only from tasks.md) and ghost-auditor (read-only, audits our own UI palette with the Ghostlight engine — every pair passes). Hooks run tests on save and give each run its git context. Property-based tests (fast-check) prove contrast is symmetric and in [1,21], exorcise always reaches the target and is idempotent, and repainting never smears flat areas.

Challenges we ran into

Real screenshots flagged gradients and rounded box corners as ghosts. The spec evolved through three revisions (text-likeness, anti-aliasing core, glyphs cross rows and columns) and a performance requirement that cut scan time from ~375 to ~240 ms.

Accomplishments that we're proud of

An accessibility tool that passes its own audit, and a horror theme where nothing is decoration.

What we learned

A steering line like "floor, never round up" travels from requirements to code to a property test without repeating it.

What's next for Ghostlight

Font-size awareness, a Figma plugin, and batch scanning of whole design systems.

Built With

Share this project:

Updates

Submission history