#!/usr/bin/env node /** * Final CSS Cleanup Script - Fix remaining syntax issues * Targets specific patterns found in the CSS files */ const fs = require('fs'); const path = require('path'); const CSS_DIR = './assets/css'; function finalCleanup(filePath) { try { let content = fs.readFileSync(filePath, 'utf8'); const fileName = path.basename(filePath); console.log(`\nšŸ”§ Final cleanup: ${fileName}`); const originalContent = content; // 1. Fix opening braces followed by semicolons content = content.replace(/\s*{\s*;+\s*\n\s*;+/g, ' {\n'); // 2. Fix lines that are just semicolons content = content.replace(/^\s*;+\s*$/gm, ''); // 3. Fix malformed CSS custom property names content = content.replace(/--hvac--webkit-webkit-webkit-webkit-([a-z-]+)/g, '--hvac-$1'); // 4. Fix incorrect border-radius as custom property content = content.replace(/--hvac-border-radius:\s*4px;/g, '--hvac-border-radius: 4px;'); // 5. Fix multiple border-radius declarations in :root content = content.replace(/(--hvac-[^:]+:\s*[^;]+;)\s*(border-radius:\s*[^;]+;\s*){2,}/g, '$1'); // 6. Fix properties without line breaks between them content = content.replace(/;\s*([a-z-]+:\s*[^;]+;)([a-z-])/g, ';\n $1\n $2'); // 7. Fix text--webkit-transform to text-transform content = content.replace(/text--webkit-transform:/g, 'text-transform:'); // 8. Fix -ms-transform: uppercase (should be text-transform) content = content.replace(/-ms-transform:\s*uppercase;/g, 'text-transform: uppercase;'); // 9. Fix malformed pseudo-selectors content = content.replace(/\.\s*;\s*\n\s*([a-z-]+):\s*/g, '.$1:'); content = content.replace(/:\s*focus,\s*\.([a-z-]+):\s*focus/g, ':focus,\n.$1:focus'); // 10. Fix malformed webkit border-radius content = content.replace(/-webkit-webkit-border-radius:/g, '-webkit-border-radius:'); content = content.replace(/-webkit-webkit-webkit-webkit-webkit-webkit-webkit-border-radius:/g, '-webkit-border-radius:'); // 11. Fix concatenated flex properties content = content.replace(/flex-wrap:\s*wrap;display:\s*flex;/g, 'flex-wrap: wrap;\n display: flex;'); // 12. Fix malformed media queries content = content.replace(/@media\s*\(\s*;\s*/g, '@media ('); // 13. Fix malformed selector continuations content = content.replace(/;\s*([a-z-]+):\s*([a-z]+)\s*{/g, ';\n}\n\n.$1:$2 {'); // 14. Fix background-size missing prefix content = content.replace(/(\s+)-webkit-background-size:/g, '$1background-size:'); // 15. Fix specific pattern in hvac-registration.css content = content.replace(/form-section:\s*last-child/g, 'form-section:last-child'); content = content.replace(/\.\s*form-section:\s*last-child/g, '.form-section:last-child'); // 16. Fix textarea/select focus selectors content = content.replace(/;\s*\n\s*textarea:\s*focus,/g, ' textarea:focus,'); content = content.replace(/select:\s*focus\s*{/g, 'select:focus {'); // 17. Fix malformed link hover selectors content = content.replace(/;\s*\n\s*a:\s*hover\s*{/g, ' a:hover {'); // 18. Fix CSS at-rule pseudo-elements content = content.replace(/\.\s*;\s*\n\s*hvac-([a-z-]+):\s*:/g, '.hvac-$1::'); // 19. Clean up extra whitespace content = content.replace(/\n{3,}/g, '\n\n'); content = content.replace(/[ \t]+$/gm, ''); if (content !== originalContent) { fs.writeFileSync(filePath, content, 'utf8'); console.log(` āœ… Final cleanup applied`); return true; } else { console.log(` • No issues found`); return false; } } catch (error) { console.error(`Error in final cleanup for ${filePath}:`, error.message); return false; } } function validateCSS(filePath) { try { const content = fs.readFileSync(filePath, 'utf8'); const fileName = path.basename(filePath); const issues = []; // Check for common syntax errors if (content.match(/{\s*;/)) issues.push('Semicolon after opening brace'); if (content.match(/^\s*;+\s*$/m)) issues.push('Lines with only semicolons'); if (content.match(/--webkit--webkit-/)) issues.push('Duplicate webkit in property names'); if (content.match(/text--webkit-transform/)) issues.push('Malformed text-transform'); if (content.match(/-ms-transform:\s*uppercase/)) issues.push('Incorrect transform usage'); if (content.match(/;\s*[a-z-]+:\s*[^;]+;[a-z-]/)) issues.push('Missing line breaks between properties'); // Check for balanced braces const openBraces = (content.match(/\{/g) || []).length; const closeBraces = (content.match(/\}/g) || []).length; if (openBraces !== closeBraces) issues.push(`Unbalanced braces (${openBraces} vs ${closeBraces})`); console.log(`šŸ“‹ ${fileName}: ${issues.length === 0 ? 'āœ… Valid' : 'āŒ Issues: ' + issues.join(', ')}`); return issues.length === 0; } catch (error) { console.error(`Error validating ${filePath}:`, error.message); return false; } } function main() { console.log('HVAC Community Events - Final CSS Cleanup'); console.log('='.repeat(60)); if (!fs.existsSync(CSS_DIR)) { console.error(`CSS directory not found: ${CSS_DIR}`); process.exit(1); } const targetFiles = [ 'hvac-common.css', 'hvac-dashboard.css', 'hvac-registration.css', 'hvac-event-summary.css', 'hvac-email-attendees.css', 'hvac-mobile-nav.css', 'hvac-animations.css', 'hvac-certificates.css', 'hvac-attendee-profile.css', 'hvac-print.css' ].map(file => path.join(CSS_DIR, file)); const existingFiles = targetFiles.filter(filePath => fs.existsSync(filePath)); console.log('\nšŸ”§ CLEANUP PHASE'); console.log('-'.repeat(40)); let cleanedCount = 0; existingFiles.forEach(filePath => { if (finalCleanup(filePath)) { cleanedCount++; } }); console.log('\nšŸ“Š VALIDATION PHASE'); console.log('-'.repeat(40)); let validCount = 0; existingFiles.forEach(filePath => { if (validateCSS(filePath)) { validCount++; } }); console.log('\n' + '='.repeat(60)); console.log('SUMMARY'); console.log('='.repeat(60)); console.log(`šŸ“ Files processed: ${existingFiles.length}`); console.log(`šŸ”§ Files cleaned: ${cleanedCount}`); console.log(`āœ… Files validated: ${validCount}/${existingFiles.length}`); if (validCount === existingFiles.length) { console.log('\nšŸŽ‰ SUCCESS: All CSS files are now clean and valid!'); } else { console.log(`\nāš ļø ${existingFiles.length - validCount} files still have issues`); } } if (require.main === module) { main(); } module.exports = { finalCleanup, validateCSS };