refactor(print): preserve authored colour by default; opt-in .print-color-exact / .print-no-color (Phase 3) - #37
Conversation
…nt-color-exact and .print-no-color
The blanket reset
* { background: transparent !important; color: CanvasText !important }
was destroying every authored colour in print -- <mark> lost its highlight,
.is-success lost its green, badges lost their tint. The new contract:
- Default: authored colour reaches paper. Browsers handle ink-saving via
their own print-color-adjust: economy heuristic, so semantic colour
survives.
- .print-color-exact: opt-in for colour-coded data that loses meaning
when flattened (status pills, syntax highlighting, charts). Forces
print-color-adjust: exact on every descendant.
- .print-no-color: opt-in for ink-on-paper output where ink-saving is
the contract. Restores the pre-Phase-3 blanket reset for the marked
subtree.
box-shadow and text-shadow are still suppressed in print, but no longer
with !important -- an authored shadow that explicitly overrides the print
layer is now the consumer's call.
!important in print is now reserved for selectors whose semantics require
defeating consumer-authored CSS:
- nav, aside, button, input, select, textarea, dialog, [popover], .no-print
-- content negative-space that must vanish from print
- details > summary -- disclosure widget carries no print value
- .print-color-exact and .print-no-color -- when the consumer marks a
region with them they are explicitly asking to override authored colour
docs/demo.html: new #print section with mark, success/error text, no-print
badge, print-color-exact callout, print-no-color callout, and a manual
verification checklist. Nav-entry added under CSS Layers.
CHANGELOG.md: open with this as a BREAKING entry, including a migration
note pointing consumers who relied on the old flatten at .print-no-color.
docs/architecture.md: slashed.print description updated to reflect the
opt-in model and the precise list of justified !important selectors.
audits/comparative-audit-2026.md: F-04 struck from P1 roadmap; Phase 3
entry appended to the Resolution Log.
dist/: bundles regenerated to match.
Co-authored-by: Jack Granatowski <contact@codeslash.net>
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Plus Run ID: ⛔ Files ignored due to path filters (2)
📒 Files selected for processing (5)
📝 WalkthroughWalkthroughPrint colour handling shifts from a blanket reset to opt-in control. The stylesheet removes forced-transparent backgrounds and preserves authored colours by default, while ChangesPrint Colour Preservation Phase 3
Estimated code review effort🎯 2 (Simple) | ⏱️ ~12 minutes Possibly related PRs
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Warning There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure. 🔧 ESLint
ESLint skipped: no ESLint configuration detected in root package.json. To enable, add Comment |
This pull request was created by @kiro-agent on behalf of @jackgranatowski 👻
Comment with /kiro fix to address specific feedback or /kiro all to address everything.
Learn about Kiro autonomous agent
Phase 3 of the perfection roadmap. Reverses the print-stylesheet colour contract: authored colour is preserved by default, ink-on-paper is now an opt-in. Resolves F-04.
Stacked on
main(post-#36).Why
core/print.cssshipped a blanket resetinside
@media print, which destroyed every authored colour.<mark>lost its highlight,.is-successlost its green, status pills lost their tint, syntax highlighting collapsed to monochrome. That is a contract no integrator opts into knowingly — it is the default, applied unconditionally, with!important.The audit captured this as F-04 ("Print
!importantblock destroys all background colors including intentional ones"). Phase 3 reverses the default and gives consumers explicit opt-ins in both directions.What changes
core/print.cssprint-color-adjust: economyheuristic, so semantic colour survives without anything special on the consumer's side..print-color-exact: opt-in. Forcesprint-color-adjust: exact(and the-webkit-prefix) on the marked subtree. Use for colour-coded data that loses meaning when the browser flattens it (status pills, syntax highlighting, charts, severity callouts)..print-no-color: opt-in. Restores the pre-Phase-3 blanket reset (background: transparent,color: CanvasText) for the marked subtree. Use where ink-saving is the contract (corporate boilerplate forms, append-to-existing-document templates).box-shadowandtext-shadoware still suppressed in print, but no longer with!important. An authored shadow that explicitly overrides the print layer is now the consumer's call.!importantin print is now reserved for selectors whose semantics require defeating consumer-authored CSS:nav, aside, button, input, select, textarea, dialog, [popover], .no-print— content negative-space that must vanish from printdetails > summary— disclosure widget carries no print value.print-color-exactand.print-no-color— the consumer is explicitly asking to override authored colourdetails { display: block }anddetails:not([open]) > :not(summary) { display: block }lose their!important— they win against the UA stylesheet on layered-author > UA precedence alone, and dropping!importantis more cooperative if a consumer has authored their owndetailsprint rules.docs/demo.html#printsection with:<mark>, success/error text, link withhref).no-printbadge.print-color-exactcallout.print-no-colorcalloutOpen print previewbuttonCHANGELOG.md.print-no-color.docs/architecture.mdslashed.printparagraph rewritten to reflect the opt-in model and the precise list of justified!importantselectors.audits/comparative-audit-2026.mddist/* { background: transparent !important }is gone from the@media printblock in both bundles. The two opt-in classes appear in their place.Verification
npm run lint:css— cleannpm run build— both bundles regenerate cleanlydist/slashed.essential.css— no blankettransparent !importantinside@media printoutside the new opt-in classesplaywright install --with-deps chromiumcovers it. No tokens.spec assertions touch print.#printsection indocs/demo.htmlcarries the checklist).Resolves
F-04. Closes the only print-related finding from
audits/comparative-audit-2026.md.What does NOT change
@pagerule and--sf-print-*tokens.a[href]::after { content: " (" attr(href) ")" }) andabbr[title]handling.img/svg/video/canvas/figure/table/pre/blockquote,tr,thead, headings, and paragraphs.nav, aside, …, .no-print).detailscontent-preservation cluster.Next phases
overflow: clip).Summary by CodeRabbit
New Features
.print-color-exactand.print-no-colorclasses enable custom print behavior.Documentation