Skip to content

Optimize CSS for Tailwind v4 tree-shaking#11

Merged
dave-atx merged 19 commits intotailwind4from
feature/oklch-color-optimization
Jan 17, 2026
Merged

Optimize CSS for Tailwind v4 tree-shaking#11
dave-atx merged 19 commits intotailwind4from
feature/oklch-color-optimization

Conversation

@dave-atx
Copy link
Owner

@dave-atx dave-atx commented Jan 14, 2026

Summary

This PR refactors assets/css/main.css to maximize tree-shakeability with Tailwind CSS v4:

  • Convert 6 CSS sections to @utility blocks that are only included when the class is detected in hugo_stats.json
  • Reorganize CSS into 10 clearly documented sections explaining why each section is structured the way it is
  • Add comprehensive documentation of what can/cannot be tree-shaken and why
  • Include test site for verifying tree-shaking behavior

Tree-Shakeable Utilities Added

Utility Purpose Included When
@utility icon SVG sizing Icons used on page
@utility toc ToC container ToC enabled
@utility highlight-wrapper Code block wrapper Code blocks present
@utility highlight Code block base Code blocks present
@utility copy-button Copy button styling Code blocks present
@utility copy-textarea Hidden textarea Code blocks present

Sections That Must Remain Raw

  • Chroma syntax highlighting (~200 lines) - targets Hugo-generated classes
  • RTL prose overrides - requires .prose specificity for typography plugin
  • Hamburger menu - uses CSS state selectors (:has, :checked)
  • Browser compatibility - vendor pseudo-elements
  • Hugo-generated HTML - tables, code elements from Markdown

Verification

Tree-shaking verified working:

  • @utility icon: INCLUDED when icons detected
  • @utility toc: EXCLUDED when ToC not detected (tree-shaken!)
  • @utility highlight-wrapper: EXCLUDED (tree-shaken!)
  • Raw selectors: Always included as designed

Test plan

  • Build exampleSite and verify no visual regressions
  • Check CSS output for expected utility inclusion/exclusion
  • Test RTL, dark mode, code highlighting still work
  • Review hugo_stats.json for class detection

🤖 Generated with Claude Code

dave-atx and others added 8 commits January 14, 2026 01:19
Migrate all color scheme files from RGB to OKLCH color format,
leveraging Tailwind CSS v4's native color space support.

Changes:
- Convert all RGB color values to OKLCH for better perceptual uniformity
- Use official Tailwind v4 color palette values from theme.css
- Enable wider P3 color gamut support for more vivid colors
- Improve color consistency across different displays

Fixes #8

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Tree-shakeable: icon styles only included when icons are used.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Tree-shakeable: ToC container styles only included when ToC is enabled.
Descendant selectors remain raw (target Hugo-generated HTML).

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Tree-shakeable: highlight-wrapper, highlight, copy-button, copy-textarea
utilities only included when code blocks are present.

Parent-child hover interaction (.highlight:hover > .copy-button) remains
raw as it cannot be expressed as a single utility.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Organized into 10 sections:
1. Tailwind Configuration
2. Tree-Shakeable Utilities (@Utility blocks)
3. Global Styles
4. Browser Compatibility (pseudo-elements)
5. CSS State Management (:has, :checked)
6. Typography Plugin Overrides (RTL)
7. Hugo-Generated HTML (ToC, tables, code)
8. Third-Party Library Classes (KaTeX)
9. Chroma Syntax Highlighting
10. Dynamic Includes

Each section includes comments explaining why the CSS is structured that way.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Test site with pages for:
- Baseline (plain text only)
- Code blocks (Chroma + copy buttons)
- Table of contents (ToC utility)
- Icons (icon utility)

Includes README with testing instructions.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
@dave-atx dave-atx changed the title Optimize color schemes with Tailwind v4 OKLCH colors Jan 15, 2026
Addresses review feedback:
- Convert --color-neutral from #fff to oklch(100% 0 0) for consistency
- Use a single constant hue value per palette (neutral, primary, secondary)
- Recalculate all OKLCH values from original RGB to match closely

Each palette now uses a fixed hue derived from the circular mean of the
original RGB colors, ensuring visual consistency across the color scale.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
@dave-atx
Copy link
Owner Author

Color Comparison: RGB → OKLCH

All scheme files have been updated with:

  1. --color-neutral: oklch(100% 0 0) instead of #fff for OKLCH consistency
  2. Constant hue per palette - each palette (neutral, primary, secondary) now uses a single fixed hue value
  3. Accurate color matching - OKLCH values calculated to match original RGB values

Avocado Scheme

Palette Hue Notes
Stone (neutral) 58° Warm brownish-gray
Lime (primary) 128° Yellow-green
Emerald (secondary) 166° Teal-green
Detailed color table

Stone (neutral)

Level Original RGB OKLCH
base rgb(255, 255, 255) oklch(100% 0 0)
50 rgb(250, 250, 249) oklch(98.5% 0 58)
100 rgb(245, 245, 244) oklch(97% 0 58)
200 rgb(231, 229, 228) oklch(92.3% 0.003 58)
300 rgb(214, 211, 209) oklch(86.9% 0.004 58)
400 rgb(168, 162, 158) oklch(71.6% 0.009 58)
500 rgb(120, 113, 108) oklch(55.3% 0.012 58)
600 rgb(87, 83, 78) oklch(44.4% 0.01 58)
700 rgb(68, 64, 60) oklch(37.4% 0.009 58)
800 rgb(41, 37, 36) oklch(26.8% 0.006 58)
900 rgb(28, 25, 23) oklch(21.6% 0.006 58)
950 rgb(12, 10, 9) oklch(14.7% 0.004 58)

Lime (primary)

Level Original RGB OKLCH
50 rgb(247, 254, 231) oklch(98.6% 0.031 128)
100 rgb(236, 252, 203) oklch(96.7% 0.066 128)
200 rgb(217, 249, 157) oklch(93.8% 0.122 128)
300 rgb(190, 242, 100) oklch(89.7% 0.179 128)
400 rgb(163, 230, 53) oklch(84.9% 0.207 128)
500 rgb(132, 204, 22) oklch(76.8% 0.204 128)
600 rgb(101, 163, 13) oklch(64.8% 0.175 128)
700 rgb(77, 124, 15) oklch(53.2% 0.141 128)
800 rgb(63, 98, 18) oklch(45.3% 0.113 128)
900 rgb(54, 83, 20) oklch(40.5% 0.096 128)
950 rgb(26, 46, 5) oklch(27.4% 0.069 128)

Emerald (secondary)

Level Original RGB OKLCH
50 rgb(236, 253, 245) oklch(97.9% 0.021 166)
100 rgb(209, 250, 229) oklch(95% 0.051 166)
200 rgb(167, 243, 208) oklch(90.5% 0.089 166)
300 rgb(110, 231, 183) oklch(84.5% 0.13 166)
400 rgb(52, 211, 153) oklch(77.3% 0.153 166)
500 rgb(16, 185, 129) oklch(69.6% 0.149 166)
600 rgb(5, 150, 105) oklch(59.6% 0.127 166)
700 rgb(4, 120, 87) oklch(50.8% 0.105 166)
800 rgb(6, 95, 70) oklch(43.2% 0.086 166)
900 rgb(6, 78, 59) oklch(37.8% 0.073 166)
950 rgb(2, 44, 34) oklch(26.2% 0.049 166)

Cherry Scheme

Palette Hue Notes
Neutral Pure gray (no chroma)
Rose (primary) 13° Red-pink
Green (secondary) 153° True green
Detailed color table

Neutral

Level Original RGB OKLCH
base rgb(255, 255, 255) oklch(100% 0 0)
50 rgb(250, 250, 250) oklch(98.5% 0 0)
100 rgb(245, 245, 245) oklch(97% 0 0)
200 rgb(229, 229, 229) oklch(92.2% 0 0)
300 rgb(212, 212, 212) oklch(87% 0 0)
400 rgb(163, 163, 163) oklch(71.5% 0 0)
500 rgb(115, 115, 115) oklch(55.6% 0 0)
600 rgb(82, 82, 82) oklch(43.9% 0 0)
700 rgb(64, 64, 64) oklch(37.1% 0 0)
800 rgb(38, 38, 38) oklch(26.9% 0 0)
900 rgb(23, 23, 23) oklch(20.5% 0 0)
950 rgb(10, 10, 10) oklch(14.5% 0 0)

Rose (primary)

Level Original RGB OKLCH
50 rgb(255, 241, 242) oklch(96.9% 0.015 13)
100 rgb(255, 228, 230) oklch(94.1% 0.03 13)
200 rgb(254, 205, 211) oklch(89.2% 0.056 13)
300 rgb(253, 164, 175) oklch(81% 0.106 13)
400 rgb(251, 113, 133) oklch(71.9% 0.169 13)
500 rgb(244, 63, 94) oklch(64.5% 0.215 13)
600 rgb(225, 29, 72) oklch(58.6% 0.222 13)
700 rgb(190, 18, 60) oklch(51.4% 0.198 13)
800 rgb(159, 18, 57) oklch(45.5% 0.171 13)
900 rgb(136, 19, 55) oklch(41% 0.15 13)
950 rgb(76, 5, 25) oklch(27.1% 0.101 13)

Green (secondary)

Level Original RGB OKLCH
50 rgb(240, 253, 244) oklch(98.2% 0.018 153)
100 rgb(220, 252, 231) oklch(96.2% 0.043 153)
200 rgb(187, 247, 208) oklch(92.5% 0.081 153)
300 rgb(134, 239, 172) oklch(87.1% 0.136 153)
400 rgb(74, 222, 128) oklch(80% 0.182 153)
500 rgb(34, 197, 94) oklch(72.3% 0.192 153)
600 rgb(22, 163, 74) oklch(62.7% 0.17 153)
700 rgb(21, 128, 61) oklch(52.7% 0.137 153)
800 rgb(22, 101, 52) oklch(44.8% 0.108 153)
900 rgb(20, 83, 45) oklch(39.3% 0.09 153)
950 rgb(5, 46, 22) oklch(26.6% 0.063 153)

Congo Scheme

Palette Hue Notes
Zinc (neutral) 281° Cool purple-gray
Violet (primary) 293° Purple-violet
Fuchsia (secondary) 322° Magenta-pink
Detailed color table

Zinc (neutral)

Level Original RGB OKLCH
base rgb(255, 255, 255) oklch(100% 0 0)
50 rgb(250, 250, 250) oklch(98.5% 0 281)
100 rgb(244, 244, 245) oklch(96.7% 0 281)
200 rgb(228, 228, 231) oklch(92% 0.004 281)
300 rgb(212, 212, 216) oklch(87.1% 0.005 281)
400 rgb(161, 161, 170) oklch(71.2% 0.013 281)
500 rgb(113, 113, 122) oklch(55.2% 0.014 281)
600 rgb(82, 82, 91) oklch(44.2% 0.015 281)
700 rgb(63, 63, 70) oklch(37% 0.012 281)
800 rgb(39, 39, 42) oklch(27.4% 0.005 281)
900 rgb(24, 24, 27) oklch(21% 0.006 281)
950 rgb(3, 7, 18) oklch(13% 0.027 281)

Violet (primary)

Level Original RGB OKLCH
50 rgb(245, 243, 255) oklch(96.9% 0.016 293)
100 rgb(237, 233, 254) oklch(94.3% 0.028 293)
200 rgb(221, 214, 254) oklch(89.4% 0.055 293)
300 rgb(196, 181, 253) oklch(81.1% 0.101 293)
400 rgb(167, 139, 250) oklch(70.9% 0.159 293)
500 rgb(139, 92, 246) oklch(60.6% 0.219 293)
600 rgb(124, 58, 237) oklch(54.1% 0.247 293)
700 rgb(109, 40, 217) oklch(49.1% 0.241 293)
800 rgb(91, 33, 182) oklch(43.2% 0.211 293)
900 rgb(76, 29, 149) oklch(38% 0.178 293)
950 rgb(46, 16, 101) oklch(28.3% 0.135 293)

Fuchsia (secondary)

Level Original RGB OKLCH
50 rgb(253, 244, 255) oklch(97.7% 0.017 322)
100 rgb(250, 232, 255) oklch(95.2% 0.036 322)
200 rgb(245, 208, 254) oklch(90.3% 0.073 322)
300 rgb(240, 171, 252) oklch(83.3% 0.132 322)
400 rgb(232, 121, 249) oklch(74.8% 0.207 322)
500 rgb(217, 70, 239) oklch(66.7% 0.259 322)
600 rgb(192, 38, 211) oklch(59.1% 0.257 322)
700 rgb(162, 28, 175) oklch(51.8% 0.226 322)
800 rgb(134, 25, 143) oklch(45.2% 0.192 322)
900 rgb(112, 26, 117) oklch(40.1% 0.16 322)
950 rgb(74, 4, 78) oklch(29.3% 0.131 322)

Fire Scheme

Palette Hue Notes
Stone (neutral) 58° Warm brownish-gray
Orange (primary) 52° Orange-amber
Rose (secondary) 13° Red-pink
Detailed color table

Stone (neutral) - Same as Avocado

Orange (primary)

Level Original RGB OKLCH
50 rgb(255, 247, 237) oklch(98% 0.016 52)
100 rgb(255, 237, 213) oklch(95.4% 0.037 52)
200 rgb(254, 215, 170) oklch(90.1% 0.073 52)
300 rgb(253, 186, 116) oklch(83.7% 0.117 52)
400 rgb(251, 146, 60) oklch(75.8% 0.159 52)
500 rgb(249, 115, 22) oklch(70.5% 0.187 52)
600 rgb(234, 88, 12) oklch(64.6% 0.194 52)
700 rgb(194, 65, 12) oklch(55.3% 0.174 52)
800 rgb(154, 52, 18) oklch(47% 0.143 52)
900 rgb(124, 45, 18) oklch(40.8% 0.116 52)
950 rgb(69, 10, 10) oklch(25.8% 0.089 52)

Rose (secondary) - Same as Cherry primary


Ocean Scheme

Palette Hue Notes
Slate (neutral) 259° Cool blue-gray
Blue (primary) 254° True blue
Cyan (secondary) 216° Cyan-blue
Detailed color table

Slate (neutral)

Level Original RGB OKLCH
base rgb(255, 255, 255) oklch(100% 0 0)
50 rgb(248, 250, 252) oklch(98.4% 0.003 259)
100 rgb(241, 245, 249) oklch(96.8% 0.007 259)
200 rgb(226, 232, 240) oklch(92.9% 0.013 259)
300 rgb(203, 213, 225) oklch(86.9% 0.02 259)
400 rgb(148, 163, 184) oklch(71.1% 0.035 259)
500 rgb(100, 116, 139) oklch(55.4% 0.041 259)
600 rgb(71, 85, 105) oklch(44.6% 0.037 259)
700 rgb(51, 65, 85) oklch(37.2% 0.039 259)
800 rgb(30, 41, 59) oklch(27.9% 0.037 259)
900 rgb(15, 23, 42) oklch(20.8% 0.04 259)
950 rgb(2, 6, 23) oklch(12.9% 0.041 259)

Blue (primary)

Level Original RGB OKLCH
50 rgb(239, 246, 255) oklch(97% 0.014 254)
100 rgb(219, 234, 254) oklch(93.2% 0.032 254)
200 rgb(191, 219, 254) oklch(88.2% 0.057 254)
300 rgb(147, 197, 253) oklch(80.9% 0.096 254)
400 rgb(96, 165, 250) oklch(71.4% 0.143 254)
500 rgb(59, 130, 246) oklch(62.3% 0.188 254)
600 rgb(37, 99, 235) oklch(54.6% 0.215 254)
700 rgb(29, 78, 216) oklch(48.8% 0.217 254)
800 rgb(30, 64, 175) oklch(42.4% 0.181 254)
900 rgb(30, 58, 138) oklch(37.9% 0.138 254)
950 rgb(23, 37, 8) oklch(24.4% 0.052 254)

Cyan (secondary)

Level Original RGB OKLCH
50 rgb(236, 254, 255) oklch(98.4% 0.019 216)
100 rgb(207, 250, 254) oklch(95.6% 0.044 216)
200 rgb(165, 243, 252) oklch(91.7% 0.077 216)
300 rgb(103, 232, 249) oklch(86.5% 0.115 216)
400 rgb(34, 211, 238) oklch(79.7% 0.134 216)
500 rgb(6, 182, 212) oklch(71.5% 0.126 216)
600 rgb(8, 145, 178) oklch(60.9% 0.111 216)
700 rgb(14, 116, 144) oklch(52% 0.094 216)
800 rgb(21, 94, 117) oklch(45% 0.077 216)
900 rgb(22, 78, 99) oklch(39.8% 0.066 216)
950 rgb(8, 51, 69) oklch(30.2% 0.055 216)

Sapphire Scheme

Palette Hue Notes
Slate (neutral) 258° Cool blue-gray
Indigo (primary) 276° Blue-violet
Pink (secondary) 354° Pink-rose
Detailed color table

Slate (neutral) - Similar to Ocean, hue 258°

Indigo (primary)

Level Original RGB OKLCH
50 rgb(238, 242, 255) oklch(96.2% 0.018 276)
100 rgb(224, 231, 255) oklch(93% 0.033 276)
200 rgb(199, 210, 254) oklch(87% 0.062 276)
300 rgb(165, 180, 252) oklch(78.5% 0.104 276)
400 rgb(129, 140, 248) oklch(68% 0.158 276)
500 rgb(99, 102, 241) oklch(58.5% 0.204 276)
600 rgb(79, 70, 229) oklch(51.1% 0.23 276)
700 rgb(67, 56, 202) oklch(45.7% 0.215 276)
800 rgb(55, 48, 163) oklch(39.8% 0.177 276)
900 rgb(49, 46, 129) oklch(35.9% 0.135 276)
950 rgb(30, 27, 75) oklch(25.7% 0.086 276)

Pink (secondary)

Level Original RGB OKLCH
50 rgb(253, 242, 248) oklch(97.1% 0.014 354)
100 rgb(252, 231, 243) oklch(94.8% 0.028 354)
200 rgb(251, 207, 232) oklch(89.9% 0.059 354)
300 rgb(249, 168, 212) oklch(82.3% 0.11 354)
400 rgb(244, 114, 182) oklch(72.5% 0.175 354)
500 rgb(236, 72, 153) oklch(65.6% 0.212 354)
600 rgb(219, 39, 119) oklch(59.2% 0.218 354)
700 rgb(190, 24, 93) oklch(52.5% 0.199 354)
800 rgb(157, 23, 77) oklch(45.9% 0.17 354)
900 rgb(131, 24, 67) oklch(40.8% 0.144 354)
950 rgb(80, 7, 36) oklch(28.4% 0.105 354)

Slate Scheme

Palette Hue Notes
Gray (neutral) 261° Cool blue-gray
Slate (primary) 259° Cool blue-gray
Gray (secondary) 261° Cool blue-gray
Detailed color table

Gray (neutral/secondary)

Level Original RGB OKLCH
base rgb(255, 255, 255) oklch(100% 0 0)
50 rgb(249, 250, 251) oklch(98.5% 0.002 261)
100 rgb(243, 244, 246) oklch(96.7% 0.003 261)
200 rgb(229, 231, 235) oklch(92.8% 0.006 261)
300 rgb(209, 213, 219) oklch(87.2% 0.009 261)
400 rgb(156, 163, 175) oklch(71.4% 0.019 261)
500 rgb(107, 114, 128) oklch(55.1% 0.023 261)
600 rgb(75, 85, 99) oklch(44.6% 0.026 261)
700 rgb(55, 65, 81) oklch(37.3% 0.031 261)
800 rgb(31, 41, 55) oklch(27.8% 0.03 261)
900 rgb(17, 24, 39) oklch(21% 0.032 261)
950 rgb(17, 24, 39) / rgb(10, 10, 10) oklch(21% 0.032 261) / oklch(14.5% 0 261)

Slate (primary) - Same as Ocean Slate neutral, hue 259°

Addresses review feedback on main.css:

1. Avoid CSS reordering - keep original structure, only make necessary changes
2. Change Tailwind source config to exclude all files then include only
   hugo_stats.json and public/**/* for better tree-shaking control
3. Move .prose blockquote RTL support into @Utility prose block
4. Convert .katex-display to @Utility for tree-shaking
5. Convert .chroma classes to @Utility chroma with nested selectors
6. Convert .icon, .toc, .highlight-*, .copy-* to @Utility blocks

Tree-shaking verified working:
- Baseline CSS (no features): 5,148 bytes
- Full CSS (all features): 12,814 bytes
- 60% reduction when feature-specific classes not used

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
@dave-atx
Copy link
Owner Author

Review Feedback Addressed (main.css)

I've addressed all the review comments on main.css in commit 2a22918:

1. Avoid reordering CSS to keep diff small ✅

  • Reset main.css to the base branch and made only targeted changes
  • Kept original structure and ordering where possible
  • Diff reduced from major reorganization to focused changes

2. Change Tailwind source file config ✅

/* Before */
@source "hugo_stats.json";
@source not "themes/*";

/* After */
@source not "*";
@source "hugo_stats.json";
@source "public/**/*";

This excludes all source files by default and only includes:

  • hugo_stats.json for class detection
  • public/**/* for the generated site directory

3. Move .prose blockquote RTL support to @Utility section ✅

Moved all RTL support styles as nested selectors inside @utility prose:

@utility prose {
  /* ... existing prose config ... */

  /* RTL support */
  blockquote {
    @apply rtl:border-l-0 rtl:border-r-4 rtl:pr-4;
  }
  ul > li,
  ol > li {
    @apply rtl:mr-7 rtl:pl-0 rtl:pr-2;
  }
  /* ... etc ... */
}

4. Make .katex-display a @Utility

@utility katex-display {
  overflow: auto hidden;
}

5. Make .chroma classes @Utility

Converted all chroma syntax highlighting styles to a single @utility chroma block with nested selectors:

@utility chroma {
  @apply rounded-md bg-neutral-50 py-3 text-neutral-700 dark:bg-neutral-700 dark:text-neutral-200;

  pre { @apply m-0 p-0; }
  .lntable { @apply m-0 block w-auto overflow-auto text-base; }
  /* ... all other chroma descendant selectors ... */
}

Additional Conversions

Also converted these to @Utility for consistency:

  • @utility icon - SVG sizing
  • @utility toc - Table of contents
  • @utility highlight-wrapper - Code block wrapper
  • @utility highlight - Code block base
  • @utility copy-button - Copy button styling
  • @utility copy-textarea - Hidden textarea

Tree-Shaking Verification ✅

Site Configuration CSS Size Notes
Baseline (no features) 5,148 bytes Plain pages only
Full test (all features) 12,814 bytes Code, ToC, icons
Savings 60% When features not used
dave-atx and others added 3 commits January 16, 2026 08:50
- Update @source directives to exclude all by default, then include
  hugo_stats.json and public/**/* for proper class detection
- Convert icon, toc, highlight-wrapper, highlight, copy-button,
  copy-textarea, katex-display, and chroma to @Utility blocks
- Move RTL support and first-child adjustment into @Utility prose
- Use nested selectors throughout for cleaner structure
- Keep .prose div.chroma raw for necessary specificity

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add test site in test-tree-shaking/ to verify Tailwind CSS v4 tree-shaking:

- baseline/: Basic page with no special utilities
- with-code/: Code blocks testing .chroma, .highlight utilities
- with-toc/: Table of contents testing .toc utility
- with-icons/: Icon shortcode testing .icon utility

Configuration:
- Enable class-based syntax highlighting (noClasses = false)
- Enable hugo_stats.json generation for class detection

Verified tree-shaking results:
- INCLUDED: .chroma (42 rules), .toc (6 rules), .highlight (2 rules),
  .prose (89 rules), .icon (1 rule)
- EXCLUDED: .katex-display, .copy-textarea, .highlight-wrapper

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Rename template directories to follow Hugo conventions:
- layouts/_markup/ -> layouts/markup/
- layouts/_partials/ -> layouts/partials/
- layouts/_shortcodes/ -> layouts/shortcodes/

Add base templates:
- layouts/_default/baseof.html
- layouts/_default/list.html
- layouts/_default/single.html

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
@dave-atx
Copy link
Owner Author

Tree-Shaking Implementation Verified

I've added a comprehensive test site and verified that the Tailwind CSS v4 tree-shaking is working correctly.

Test Site: test-tree-shaking/

The test site includes four pages to verify utility inclusion/exclusion:

Page Purpose Utilities Tested
baseline/ Plain page, no special features Basic layout only
with-code/ Code blocks with syntax highlighting .chroma, .highlight
with-toc/ Table of contents enabled .toc
with-icons/ Icon shortcodes .icon

Configuration Added

  • markup.toml - Enables class-based syntax highlighting (noClasses = false) for proper .chroma class generation
  • hugo.toml - Basic Hugo config with buildStats enabled for hugo_stats.json generation

Tree-Shaking Test Results

CSS File Size: 39,205 bytes

Utilities INCLUDED (correctly - used on pages):

Utility Rules Source
.chroma 42 Code blocks on with-code page
.prose 89 Article content on all pages
.toc 6 Table of contents on with-toc page
.highlight 2 Code block wrappers
.icon 1 Icon shortcodes on with-icons page

Utilities EXCLUDED (correctly tree-shaken - not used):

  • .katex-display - No KaTeX math used
  • .copy-textarea - Not used
  • .highlight-wrapper - Not used

Commits

  1. 28d4165 - Add tree-shaking test site with comprehensive utility testing
  2. 564527a - Reorganize layouts directory structure (remove underscore prefixes)

How to Run Tests

cd test-tree-shaking
hugo --gc
# Check generated CSS in public/ for utility inclusion
# Check hugo_stats.json for detected classes

The tree-shaking is working as designed - utilities are included only when their corresponding classes are detected in hugo_stats.json.

- Use @import "tailwindcss" source(none) instead of @source not "*"
  (idiomatic Tailwind v4 syntax per official docs)
- Make publish directory configurable via site.Params.publishDir
  with "public" as default for flexibility
- Update comment to explain the @source configuration

Verified: .chroma .gl generates correct underline CSS
(text-decoration-line:underline)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
@dave-atx
Copy link
Owner Author

Additional main.css Review Feedback Addressed

Commit 53d9f16 addresses the remaining pending review comments:

1. Use idiomatic Tailwind v4 source configuration

Before:

@import "tailwindcss";
@source not "*";
@source "hugo_stats.json";
@source "public/**/*";

After:

@import "tailwindcss" source(none);
@source "hugo_stats.json";
@source "{{ site.Params.publishDir | default "public" }}/**/*";

Per Tailwind CSS v4 docs, @import "tailwindcss" source(none) is the idiomatic way to disable automatic source detection.

2. Configurable publish directory

The publish directory path is now configurable via site.Params.publishDir with "public" as the default. Users with custom publishDir can override this in their params.toml:

[params]
publishDir = "dist"

3. Verified chroma .gl underline CSS

Confirmed that @utility chroma { .gl { @apply underline; } } generates correct CSS:

.chroma .gl{text-decoration-line:underline}
@dave-atx dave-atx force-pushed the feature/oklch-color-optimization branch from 23a3b24 to 2a22918 Compare January 16, 2026 22:01
- Resolved CSS formatting conflicts using compact style
- Removed test-tree-shaking directory (moved to separate repo)
- Kept OKLCH color optimization changes

Test site: https://github.com/dave-atx/congo-tree-shaking-tests

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
@dave-atx
Copy link
Owner Author

Update: Merge Conflicts Resolved

The merge conflicts from the previous commit have been fixed:

Changes Made

  1. Reset and re-merged tailwind4 branch into feature/oklch-color-optimization
  2. Resolved CSS conflicts using compact style (selectors on single lines) to match existing code style
  3. Removed test-tree-shaking/ directory from this repo - moved to separate test repository

Test Results ✅

All CSS tree-shaking tests pass:

  • .chroma styles: ✅ included when code blocks present
  • .toc styles: ✅ included when ToC enabled
  • .icon styles: ✅ included when icons used

Test Repository

Test site moved to: https://github.com/dave-atx/congo-tree-shaking-tests

This keeps the theme repo clean while providing a dedicated space for tree-shaking verification.


🤖 Generated with Claude Code

dave-atx and others added 2 commits January 17, 2026 00:01
Remove layouts reorganization that should not be on this branch.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Replace @source not "*" with @import "tailwindcss" source(none)
- Make publish directory configurable via site.Params.publishDir

Per Tailwind v4 docs, source(none) is the preferred way to disable
automatic source detection.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
@dave-atx
Copy link
Owner Author

Review Comments Addressed

All 11 review comments on main.css have been addressed and marked as resolved.

Changes Made in Commit 76b2dcb

  1. Use idiomatic Tailwind v4 source(none) syntax

    /* Before */
    @import "tailwindcss";
    @source not "*";
    
    /* After */
    @import "tailwindcss" source(none);

    Per Tailwind v4 docs, source(none) is the preferred way to disable automatic source detection.

  2. Configurable publish directory via Hugo template

    @source "{{ site.Params.publishDir | default "public" }}/**/*";

    Users can now override the publish directory in their params.toml:

    [params]
    publishDir = "dist"

Previously Addressed (in earlier commits)

  • ✅ OKLCH values for --color-neutral in all scheme files (uses oklch(100% 0 0))
  • ✅ Constant hue values per palette in all schemes
  • ✅ RTL support moved inside @utility prose
  • .katex-display converted to @utility
  • .chroma styles converted to @utility chroma with nested selectors
  • .gl underline verified generating text-decoration-line: underline;

Test Results

  • ✅ CSS compilation with Tailwind v4.1.18 successful
  • ✅ All scheme files (avocado, cherry, congo, fire, ocean, sapphire, slate) valid
  • ✅ Tree-shaking working as expected (utilities only included when classes detected)

🤖 Generated with Claude Code

dave-atx and others added 2 commits January 17, 2026 00:11
Mark all review comments as addressed and document the
changes made in this PR.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
@dave-atx dave-atx force-pushed the feature/oklch-color-optimization branch from 5383787 to 2f6102d Compare January 17, 2026 00:24
@dave-atx dave-atx merged commit 6a301e6 into tailwind4 Jan 17, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

1 participant