Skip to content

refactor(print): preserve authored colour by default; opt-in .print-color-exact / .print-no-color (Phase 3) - #37

Merged
jackgranatowski merged 1 commit into
mainfrom
chore/phase-3-print
May 21, 2026
Merged

refactor(print): preserve authored colour by default; opt-in .print-color-exact / .print-no-color (Phase 3)#37
jackgranatowski merged 1 commit into
mainfrom
chore/phase-3-print

Conversation

@kiro-agent

@kiro-agent kiro-agent Bot commented May 20, 2026

Copy link
Copy Markdown

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.css shipped a blanket reset

* { background: transparent !important; color: CanvasText !important; }

inside @media print, which destroyed every authored colour. <mark> lost its highlight, .is-success lost 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 !important block 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.css

  • Default: authored colour reaches paper. Browsers handle ink-saving via their own print-color-adjust: economy heuristic, so semantic colour survives without anything special on the consumer's side.
  • .print-color-exact: opt-in. Forces print-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-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 — the consumer is explicitly asking to override authored colour
  • details { display: block } and details:not([open]) > :not(summary) { display: block } lose their !important — they win against the UA stylesheet on layered-author > UA precedence alone, and dropping !important is more cooperative if a consumer has authored their own details print rules.

docs/demo.html

  • New #print section with:
    • default-survival example (<mark>, success/error text, link with href)
    • .no-print badge
    • .print-color-exact callout
    • .print-no-color callout
    • 7-step manual-verification checklist
    • Open print preview button
  • Nav-entry added under CSS Layers.

CHANGELOG.md

  • Opens with this as the first entry, marked ⚠️ BREAKING.
  • Migration note points consumers who relied on the old flatten at .print-no-color.

docs/architecture.md

  • slashed.print paragraph rewritten to reflect the opt-in model and the precise list of justified !important selectors.

audits/comparative-audit-2026.md

  • F-04 struck from the P1 roadmap.
  • Phase 3 entry appended to the Resolution Log.
  • F-04 removed from the "Remaining open" list.

dist/

  • Both bundles regenerated. The blanket * { background: transparent !important } is gone from the @media print block in both bundles. The two opt-in classes appear in their place.

Verification

  • npm run lint:css — clean
  • npm run build — both bundles regenerate cleanly
  • ✅ Sanity grep on dist/slashed.essential.css — no blanket transparent !important inside @media print outside the new opt-in classes
  • ⏳ Playwright not run in this sandbox; CI's playwright install --with-deps chromium covers it. No tokens.spec assertions touch print.
  • 📋 Manual print-preview verification deferred to the reviewer (the new #print section in docs/demo.html carries the checklist).

Resolves

F-04. Closes the only print-related finding from audits/comparative-audit-2026.md.

What does NOT change

  • The @page rule and --sf-print-* tokens.
  • Link-URL expansion (a[href]::after { content: " (" attr(href) ")" }) and abbr[title] handling.
  • Page-break rules for img/svg/video/canvas/figure/table/pre/blockquote, tr, thead, headings, and paragraphs.
  • The hide-list (nav, aside, …, .no-print).
  • The details content-preservation cluster.

Next phases

  • Phase 4 — Named container queries (F-10).
  • Phase 5 — Motion API polish (F-13, F-17, F-18, .sr-only overflow: clip).
  • Phase 6 — Demo coverage and regression tests (F-14, N-04, N-05).

Summary by CodeRabbit

  • New Features

    • Print colors now preserved by default; new .print-color-exact and .print-no-color classes enable custom print behavior.
    • Added interactive Print demo section with preview functionality.
  • Documentation

    • CHANGELOG updated with print behavior changes and migration guidance.
    • Architecture documentation clarified with updated print styling rules.

Review Change Stack

…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>
@coderabbitai

coderabbitai Bot commented May 20, 2026

Copy link
Copy Markdown

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 8ae178bf-fc04-4fef-b52e-2cf2119f7205

📥 Commits

Reviewing files that changed from the base of the PR and between 21f6041 and 80797be.

⛔ Files ignored due to path filters (2)
  • dist/slashed.essential.css is excluded by !**/dist/**
  • dist/slashed.full.css is excluded by !**/dist/**
📒 Files selected for processing (5)
  • CHANGELOG.md
  • audits/comparative-audit-2026.md
  • core/print.css
  • docs/architecture.md
  • docs/demo.html

📝 Walkthrough

Walkthrough

Print colour handling shifts from a blanket reset to opt-in control. The stylesheet removes forced-transparent backgrounds and preserves authored colours by default, while .print-color-exact and .print-no-color let consumers override. Shadow suppression and display hiding narrow their !important scope to semantic contexts. Changelog, architecture, audit, and demo documentation accompany the implementation.

Changes

Print Colour Preservation Phase 3

Layer / File(s) Summary
Core print stylesheet contract and rules
core/print.css
Adds expanded documentation of the print-color-adjust default and opt-in classes. Replaces blanket !important background/text/shadow reset with narrower shadow suppression only. Updates <details> visibility to preserve content with !important only on details > summary. Introduces .print-color-exact (forces exact color adjustment) and .print-no-color (forces transparent backgrounds and CanvasText text).
Architecture, changelog, and migration guidance
docs/architecture.md, CHANGELOG.md
Clarifies slashed.print section to document preserved authored-color default, opt-in mechanisms via .print-no-color and .print-color-exact, and reserved !important usage for semantic selectors only. Documents breaking change in changelog with migration instructions to wrap affected regions in .print-no-color.
Demo section and audit documentation
audits/comparative-audit-2026.md, docs/demo.html
Marks F-04 print issue resolved in Phase 3 roadmap and adds dedicated Phase 3 section documenting the solution. Adds Print demo section with sidebar nav entry, descriptive content, opt-in behaviour checklist, print-preview trigger button, and JavaScript handler for window.print().

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~12 minutes

Possibly related PRs

  • codeslash-dev/SLASHED#33: Updates the comparative audit roadmap to mark finding F-04 (print colour/background reset) as resolved in Phase 3, documenting the same print-colour-preservation remediation.
🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title directly and specifically describes the main change: reversing the print color contract to preserve authored colors by default while adding opt-in classes for alternative behaviors, with Phase 3 context.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch chore/phase-3-print

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

If the error stems from missing dependencies, add them to the package.json file. For unrecoverable errors (e.g., due to private dependencies), disable the tool in the CodeRabbit configuration.

ESLint skipped: no ESLint configuration detected in root package.json. To enable, add eslint to devDependencies.


Comment @coderabbitai help to get the list of available commands and usage tips.

@jackgranatowski
jackgranatowski merged commit b61987e into main May 21, 2026
4 checks passed
@jackgranatowski
jackgranatowski deleted the chore/phase-3-print branch May 31, 2026 18:00
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants