Skip to content

CSS Phase C sprint C2: de-obfuscate the shared layer - 17 semantic re-keys, last hash-named file retired#372

Merged
pftg merged 22 commits into
masterfrom
css-migration/c2-deobfuscate-shared
Jul 19, 2026
Merged

CSS Phase C sprint C2: de-obfuscate the shared layer - 17 semantic re-keys, last hash-named file retired#372
pftg merged 22 commits into
masterfrom
css-migration/c2-deobfuscate-shared

Conversation

@pftg

@pftg pftg commented Jul 19, 2026

Copy link
Copy Markdown
Member

What this is

Phase C sprint C2 (spec §Phase C): the shared partials' fl-node-<hash> classes become semantic names, the last hash-named CSS file is retired, and the deferred cascade hardening lands. 22 commits, every one independently gated and revertable.

C2.1 + C2.2 — 17 semantic re-keys (one node per commit)

  • Testimonials partial: 10 nodes → testimonials-header/-header-col/-label/-heading/-subheading/-rating/-rating-count/-reviews-section/-quote-col/-reviews
  • CTA partial: 7 nodes → cta-banner/-box/-eyebrow/-heading/-text/-spacer/-button-row, swept across the partial and the 6 inline template copies (home, page/services, page/use-cases, services/single, use-cases/single, clients/single)
  • data-node attributes kept — system tests select on them; class strings only.

Gate per re-key: converged builds; every compiled bundle byte-identical after guarded reverse substitution — pixel parity by construction.

Purge-safelist companion (in the testimonials-reviews commit): PowerPack runtime classes (pp-swiper-button, pp-review-image) are never in hugo_stats.json and pre-C2 survived PurgeCSS only via the greedy /^fl-node/ entry matching their selectors. New greedy entries /^testimonials-/ + /^cta-banner/ give semantic prefixes the same protection (precedent: /^use-cases/). Caught by the gate when 10 declarations vanished; the safelist scope was chosen to preserve current rendering exactly.

C2.3-C2.6

  • skin-65eda28877e04.csslegacy-theme-skin.css — last hash-named file (criterion 2). 16 template refs swept, including the root-level layouts/course/list.html that a themes-scoped grep misses. Name not pre-approved — one-commit revertable if you prefer another. Gate: every bundle fingerprint byte-identical.
  • dynamic-404-590.cssdynamic-404.css (node 590 retired in R9); ExecuteAsTemplate output names unchanged. Byte-identical.
  • 586.css masked-background deletion: .single-content pre { background-color:#F5F6F8 } never painted (style.css's .blog pre #282a36 wins the tie later in every bundle; Chroma inlines dracula on fenced blocks; the two non-.blog .single-content contexts contain no <pre> — audit-verified). Gate: per-bundle decl-diff is exactly this one declaration across the 16 carrying bundles; codeblock screenshot lock green.
  • Safe-edit headers on the 5 legacy shared files (affects-pages + ownership-map pointer). Output-inert (verified byte-identical).

Verification

  • Full macOS system suite: 65 runs / 119 screenshots / 0 failures, zero baseline changes
  • Linux full suite via bin/dtest-all on the branch head
  • Phase C criterion-2 metric: template fl-* refs down by the 17 shared-partial nodes; zero hash-named CSS files remain

Flagged for Paul

  • legacy-theme-skin.css name — say the word and it's one commit to change.
  • Discovered, NOT shipped: the .jt-reviews-box swiper-arrow design (hover arrows, 44% placement) has been silently purged in production all along — restoring it is an intentional visual change needing your design call.

🤖 Generated with Claude Code

https://claude.ai/code/session_01GYRU9wGepomJo5hSuqtu7V

Summary by CodeRabbit

  • New Features

    • Added more stable styling hooks for CTA banners and testimonials across supported pages.
    • Preserved testimonial and CTA styles, including responsive layouts, ratings, navigation, spacing, and typography.
    • Updated CSS asset loading for legacy theme styling and 404-page backgrounds.
  • Bug Fixes

    • Prevented testimonial and CTA styles from being removed during CSS optimization.
    • Removed an unintended code-block background color.
  • Documentation

    • Updated CSS bundle ownership, migration tracking, and loading-order documentation.

Paul Keen and others added 22 commits July 19, 2026 02:59
Class rename only (data-node attrs kept - system tests select on them).
Gate: every compiled bundle byte-identical after reverse substitution.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GYRU9wGepomJo5hSuqtu7V
…r-col

Class rename only; gate: all bundles byte-identical after reverse
substitution (first run was build flicker; converged rerun clean).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GYRU9wGepomJo5hSuqtu7V
Class rename only; gate: all bundles byte-identical after reverse
substitution (clean-destination rebuild).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GYRU9wGepomJo5hSuqtu7V
Class rename only; gate: converged builds, all bundles byte-identical
after reverse substitution.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GYRU9wGepomJo5hSuqtu7V
…ading

Class rename only; gate: converged builds, all bundles byte-identical
after reverse substitution.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GYRU9wGepomJo5hSuqtu7V
Class rename only; gate: converged builds, all bundles byte-identical
after reverse substitution.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GYRU9wGepomJo5hSuqtu7V
…g-count

Class rename only; gate: converged builds, all bundles byte-identical
after reverse substitution.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GYRU9wGepomJo5hSuqtu7V
…ws-section

Class rename only; gate: converged builds, all bundles byte-identical
after reverse substitution.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GYRU9wGepomJo5hSuqtu7V
…-col

Class rename only; gate: converged builds, all bundles byte-identical
after reverse substitution.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GYRU9wGepomJo5hSuqtu7V
…ws (+ purge safelist companion)

The reviews-module rename needs a safelist companion: PowerPack runtime
classes (pp-swiper-button, pp-review-image) are never in hugo_stats.json
and pre-C2 survived PurgeCSS only because their selectors contained an
fl-node-* class, which /^fl-node/ keeps greedily. New greedy entries
/^testimonials-/ + /^cta-banner/ give semantic component prefixes the
same protection (precedent: /^use-cases/ already in the list).

C2.1 COMPLETE: all 10 testimonial nodes semantic. Gate: every compiled
bundle byte-identical after reverse substitution - pixel parity by
construction.

Discovered for Paul (follow-up, NOT shipped): .jt-reviews-box swiper
arrow styling (hover arrows at 44%, bottom placement) has been silently
purged in production all along - pp-swiper classes are runtime-only and
those selectors have no shield. Restoring it = intentional visual
change; needs a design decision.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GYRU9wGepomJo5hSuqtu7V
Class rename only; gate: converged builds, all bundles byte-identical
after guarded reverse substitution.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GYRU9wGepomJo5hSuqtu7V
Class rename only; gate: converged builds, all bundles byte-identical
after guarded reverse substitution.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GYRU9wGepomJo5hSuqtu7V
Class rename only; gate: converged builds, all bundles byte-identical
after guarded reverse substitution.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GYRU9wGepomJo5hSuqtu7V
Class rename only; gate: converged builds, all bundles byte-identical
after guarded reverse substitution.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GYRU9wGepomJo5hSuqtu7V
Class rename only; gate: converged builds, all bundles byte-identical
after guarded reverse substitution.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GYRU9wGepomJo5hSuqtu7V
Class rename only; gate: converged builds, all bundles byte-identical
after guarded reverse substitution.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GYRU9wGepomJo5hSuqtu7V
Class rename only; gate: converged builds, all bundles byte-identical
after guarded reverse substitution.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GYRU9wGepomJo5hSuqtu7V
…n.css

Last hash-named CSS file retired (success criterion 2). git mv + sed of
all 16 template refs (15 in themes/ + the root-level
layouts/course/list.html override the themes-scoped grep missed) +
comment refs in critical/ files + live docs; archived docs untouched.

NAME NOT PRE-APPROVED: 'legacy-theme-skin.css' - single-commit
revertable if Paul prefers another name.

Gate: converged builds, every bundle fingerprint byte-identical (file
content unchanged; concat output is content-addressed).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GYRU9wGepomJo5hSuqtu7V
Node-id 590 retired with the homepage delta port (R9). Both
ExecuteAsTemplate call sites keep their output name, so the published
resource is unchanged. Gate: all bundle fingerprints byte-identical.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GYRU9wGepomJo5hSuqtu7V
… 586.css

Deferred cascade hardening from the burn-down. The #F5F6F8 declaration
never painted: (1) style.css's .blog pre #282a36 loads later at equal
specificity on every page that renders .single-content inside .blog;
(2) Chroma noClasses=true inlines the dracula background on every
fenced block; (3) the only .single-content contexts without a .blog
wrapper (simple pages, careers) contain no <pre> at all (audit-verified).

Gate: per-bundle decl-diff = exactly this one declaration across the 16
586-carrying bundles, 0 extra; codeblock screenshot lock green.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GYRU9wGepomJo5hSuqtu7V
'affects pages' + ownership-map pointer on 586.css, style.css,
theme-main.css, component-bundle.css, legacy-theme-skin.css
(criterion 4 closure for the legacy layer). Comment-only; gate: all
bundle fingerprints byte-identical.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GYRU9wGepomJo5hSuqtu7V
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GYRU9wGepomJo5hSuqtu7V
@pftg
pftg merged commit 9a6dff4 into master Jul 19, 2026
2 checks passed
@pftg
pftg deleted the css-migration/c2-deobfuscate-shared branch July 19, 2026 01:53
@coderabbitai

coderabbitai Bot commented Jul 19, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Caution

Review failed

The pull request is closed.

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 4e02a5ff-884d-43c1-8bf7-e7400b2472b6

📥 Commits

Reviewing files that changed from the base of the PR and between ec642c2 and 3029d25.

📒 Files selected for processing (48)
  • docs/projects/2509-css-migration/2026-07-12-css-maintainability-redesign.md
  • docs/projects/2509-css-migration/TASK-TRACKER.md
  • docs/projects/2509-css-migration/css-bundle-ownership-map.md
  • docs/projects/2509-css-migration/css-loading-order-analysis.md
  • layouts/course/list.html
  • postcss.config.js
  • themes/beaver/assets/css/586.css
  • themes/beaver/assets/css/component-bundle.css
  • themes/beaver/assets/css/components/cta-banner.css
  • themes/beaver/assets/css/components/testimonials.css
  • themes/beaver/assets/css/critical/about-us-critical.css
  • themes/beaver/assets/css/critical/careers-critical.css
  • themes/beaver/assets/css/critical/clients-critical.css
  • themes/beaver/assets/css/critical/fl-common-modules.css
  • themes/beaver/assets/css/critical/homepage-critical.css
  • themes/beaver/assets/css/critical/single-careers.css
  • themes/beaver/assets/css/critical/single-clients.css
  • themes/beaver/assets/css/critical/single-services.css
  • themes/beaver/assets/css/critical/single-use-cases.css
  • themes/beaver/assets/css/dynamic-404.css
  • themes/beaver/assets/css/legacy-theme-skin.css
  • themes/beaver/assets/css/pages/about-us.css
  • themes/beaver/assets/css/pages/clients.css
  • themes/beaver/assets/css/pages/homepage.css
  • themes/beaver/assets/css/pages/services.css
  • themes/beaver/assets/css/pages/single-service.css
  • themes/beaver/assets/css/pages/single-use-cases.css
  • themes/beaver/assets/css/pages/use-cases.css
  • themes/beaver/assets/css/style.css
  • themes/beaver/assets/css/theme-main.css
  • themes/beaver/layouts/404.html
  • themes/beaver/layouts/clients/single.html
  • themes/beaver/layouts/course/single.html
  • themes/beaver/layouts/home.html
  • themes/beaver/layouts/page/about.html
  • themes/beaver/layouts/page/clients.html
  • themes/beaver/layouts/page/services.html
  • themes/beaver/layouts/page/single.html
  • themes/beaver/layouts/page/use-cases.html
  • themes/beaver/layouts/partials/assets/careers-css-resources.html
  • themes/beaver/layouts/partials/assets/contact-us-css-resources.html
  • themes/beaver/layouts/partials/assets/homepage-css-resources.html
  • themes/beaver/layouts/partials/assets/single-career-css-resources.html
  • themes/beaver/layouts/partials/page/cta.html
  • themes/beaver/layouts/partials/page/testimonials.html
  • themes/beaver/layouts/services/single.html
  • themes/beaver/layouts/single.html
  • themes/beaver/layouts/use-cases/single.html

📝 Walkthrough

Walkthrough

The change replaces builder-generated CSS hooks with semantic CTA and testimonials classes, updates critical CSS selectors and PurgeCSS safelisting, renames shared skin and dynamic 404 assets, adjusts bundle references, and records the Phase C migration status.

Changes

CSS asset wiring and migration documentation

Layer / File(s) Summary
Asset references and migration records
docs/projects/2509-css-migration/*, themes/beaver/layouts/*, layouts/course/list.html, themes/beaver/assets/css/dynamic-404.css, themes/beaver/assets/css/legacy-theme-skin.css
Bundle references now use legacy-theme-skin.css and dynamic-404.css; migration documentation, ownership maps, and loading-order records use the updated names.
Selector preservation and shared CSS cleanup
postcss.config.js, themes/beaver/assets/css/586.css
PurgeCSS preserves testimonials- and cta-banner/ selectors, while the 586 stylesheet removes the pre background color and gains ownership notes.

Semantic component markup

Layer / File(s) Summary
CTA and testimonials hooks
themes/beaver/layouts/partials/page/*, themes/beaver/layouts/{home.html,services/single.html,use-cases/single.html}, themes/beaver/layouts/page/*
CTA and testimonial markup uses stable semantic classes while retaining existing data-node attributes and content structure.

Component and page CSS

Layer / File(s) Summary
Shared component selectors
themes/beaver/assets/css/components/*
CTA and testimonials rules now target semantic classes, including responsive layout, review cards, pagination, ratings, and typography.
Page selectors and CSS ownership headers
themes/beaver/assets/css/pages/*, themes/beaver/assets/css/{style.css,theme-main.css,component-bundle.css}
Page-specific testimonial and CTA rules use semantic selectors, and shared stylesheet headers document bundle ownership and migration phase notes.

Critical CSS

Layer / File(s) Summary
Critical selector retargeting and literal references
themes/beaver/assets/css/critical/*
Critical CTA and testimonial controls use semantic container selectors; unchanged color and border declarations reference legacy-theme-skin.css in their KEEP LITERAL comments.

Estimated code review effort: 4 (Complex) | ~45 minutes

Possibly related PRs

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch css-migration/c2-deobfuscate-shared

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

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.

1 participant