<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <title>DataTools — Data Cleaning Mastery</title> <link rel="preconnect" href="https://fonts.googleapis.com"> <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin> <link href="https://fonts.googleapis.com/css2?family=Fraunces:opsz,wght@9..144,400;9..144,500;9..144,600&family=Geist:wght@400;500;600&family=Geist+Mono:wght@400;500&display=swap" rel="stylesheet"> <style> :root { --bg: #fafaf7; --bg-sidebar: #f5f4ef; --surface: #ffffff; --surface-hover: #f8f7f3; --border: #e7e5dc; --border-strong: #d6d3c7; --ink: #1c1917; --ink-secondary: #57534e; --ink-tertiary: #a8a29e; --accent: #c2410c; --accent-hover: #9a3412; --accent-fill: #fef4ed; --accent-fill-strong: #fde4d3; --warn: #b45309; --warn-fill: #fef3c7; --info: #0369a1; --info-fill: #e0f2fe; --success: #15803d; --success-fill: #dcfce7; --danger: #b91c1c; --danger-fill: #fee2e2; --r-sm: 6px; --r-md: 10px; --r-lg: 14px; --font-display: "Fraunces", Georgia, serif; --font-body: "Geist", -apple-system, BlinkMacSystemFont, sans-serif; --font-mono: "Geist Mono", "SF Mono", Menlo, monospace; } * { box-sizing: border-box; } html, body { margin: 0; padding: 0; } body { font-family: var(--font-body); color: var(--ink); background: var(--bg); font-size: 14px; line-height: 1.5; -webkit-font-smoothing: antialiased; } /* ──────── Layout ──────── */ .app { display: grid; grid-template-columns: 232px 1fr; min-height: 100vh; } /* ──────── Sidebar ──────── */ .sidebar { background: var(--bg-sidebar); border-right: 1px solid var(--border); display: flex; flex-direction: column; height: 100vh; position: sticky; top: 0; } .brand { padding: 22px 22px 18px; display: flex; align-items: center; gap: 10px; border-bottom: 1px solid var(--border); } .brand-mark { width: 28px; height: 28px; border-radius: 7px; background: var(--ink); display: grid; place-items: center; color: #fef4ed; font-family: var(--font-display); font-weight: 600; font-size: 16px; line-height: 1; } .brand-name { font-family: var(--font-display); font-weight: 500; font-size: 16px; letter-spacing: -0.01em; } .nav { flex: 1; padding: 14px 12px; overflow-y: auto; } .nav-section { margin-bottom: 18px; } .nav-section-title { font-size: 10.5px; text-transform: uppercase; letter-spacing: 0.08em; color: var(--ink-tertiary); font-weight: 500; padding: 0 10px 6px; } .nav-item { display: flex; align-items: center; gap: 10px; padding: 7px 10px; border-radius: var(--r-sm); color: var(--ink-secondary); cursor: pointer; user-select: none; font-size: 13.5px; line-height: 1.3; } .nav-item:hover { background: rgba(0,0,0,0.04); color: var(--ink); } .nav-item.active { background: var(--surface); color: var(--ink); font-weight: 500; box-shadow: 0 1px 2px rgba(28,25,23,0.04); } .nav-item svg { width: 16px; height: 16px; flex-shrink: 0; stroke-width: 1.6; opacity: 0.85; } .sidebar-footer { border-top: 1px solid var(--border); padding: 12px; display: flex; align-items: center; gap: 8px; } .footer-btn { display: grid; place-items: center; width: 32px; height: 32px; border-radius: var(--r-sm); border: none; background: transparent; color: var(--ink-secondary); cursor: pointer; } .footer-btn:hover { background: rgba(0,0,0,0.05); color: var(--ink); } .footer-btn svg { width: 16px; height: 16px; stroke-width: 1.6; } .footer-meta { margin-left: auto; font-size: 11.5px; color: var(--ink-tertiary); font-family: var(--font-mono); } /* ──────── Main ──────── */ .main { padding: 32px 40px 80px; max-width: 1100px; width: 100%; } .page-header { display: flex; align-items: flex-end; justify-content: space-between; gap: 24px; margin-bottom: 28px; padding-bottom: 22px; border-bottom: 1px solid var(--border); } .page-title { font-family: var(--font-display); font-size: 32px; font-weight: 500; letter-spacing: -0.025em; margin: 0 0 4px; line-height: 1.1; } .page-subtitle { font-size: 13.5px; color: var(--ink-secondary); margin: 0; } .privacy-pill { display: inline-flex; align-items: center; gap: 6px; padding: 6px 10px; background: var(--success-fill); color: var(--success); border-radius: 999px; font-size: 12px; font-weight: 500; } .privacy-pill svg { width: 13px; height: 13px; stroke-width: 2; } /* ──────── Files card ──────── */ .section { margin-bottom: 28px; } .section-head { display: flex; align-items: baseline; justify-content: space-between; margin-bottom: 12px; gap: 12px; } .section-title { font-family: var(--font-display); font-size: 18px; font-weight: 500; letter-spacing: -0.015em; margin: 0; } .section-meta { font-size: 12.5px; color: var(--ink-tertiary); } .files-card { background: var(--surface); border: 1px solid var(--border); border-radius: var(--r-lg); overflow: hidden; } .file-row { display: grid; grid-template-columns: 1fr auto auto; align-items: center; gap: 16px; padding: 12px 16px; border-bottom: 1px solid var(--border); font-size: 13.5px; } .file-row:last-child { border-bottom: none; } .file-row:hover { background: var(--surface-hover); } .file-name { display: flex; align-items: center; gap: 10px; font-family: var(--font-mono); font-size: 13px; color: var(--ink); } .file-icon { width: 28px; height: 28px; border-radius: var(--r-sm); background: var(--accent-fill); display: grid; place-items: center; color: var(--accent); flex-shrink: 0; } .file-icon svg { width: 14px; height: 14px; stroke-width: 1.8; } .file-size { font-size: 12px; color: var(--ink-tertiary); font-family: var(--font-mono); } .file-remove { background: transparent; border: none; width: 26px; height: 26px; border-radius: var(--r-sm); display: grid; place-items: center; color: var(--ink-tertiary); cursor: pointer; } .file-remove:hover { background: var(--danger-fill); color: var(--danger); } .file-remove svg { width: 14px; height: 14px; stroke-width: 1.8; } .file-add { display: flex; align-items: center; justify-content: center; gap: 8px; padding: 12px 16px; background: var(--surface-hover); border: none; width: 100%; cursor: pointer; font: inherit; font-size: 13px; color: var(--ink-secondary); border-top: 1px dashed var(--border-strong); } .file-add:hover { color: var(--accent); background: var(--accent-fill); } .file-add svg { width: 14px; height: 14px; stroke-width: 2; } /* ──────── Action bar ──────── */ .action-bar { display: flex; align-items: center; gap: 10px; margin-top: 14px; } .btn { display: inline-flex; align-items: center; gap: 7px; padding: 9px 16px; border-radius: var(--r-md); border: 1px solid var(--border-strong); background: var(--surface); color: var(--ink); font: inherit; font-size: 13.5px; font-weight: 500; cursor: pointer; line-height: 1; } .btn:hover { background: var(--surface-hover); } .btn svg { width: 14px; height: 14px; stroke-width: 2; } .btn-primary { background: var(--ink); color: var(--bg); border-color: var(--ink); } .btn-primary:hover { background: #292524; } .btn-ghost { background: transparent; border-color: transparent; color: var(--ink-secondary); } .btn-ghost:hover { background: rgba(0,0,0,0.04); color: var(--ink); } /* ──────── Summary stats ──────── */ .stats { display: grid; grid-template-columns: repeat(4, 1fr); gap: 12px; margin-bottom: 28px; } .stat { background: var(--surface); border: 1px solid var(--border); border-radius: var(--r-lg); padding: 16px 18px; } .stat-label { font-size: 11.5px; text-transform: uppercase; letter-spacing: 0.06em; color: var(--ink-tertiary); font-weight: 500; margin-bottom: 6px; } .stat-value { font-family: var(--font-display); font-size: 28px; font-weight: 500; letter-spacing: -0.02em; line-height: 1; display: flex; align-items: baseline; gap: 6px; } .stat-unit { font-size: 12px; color: var(--ink-tertiary); font-family: var(--font-body); font-weight: 400; letter-spacing: 0; } .stat.is-warn .stat-value { color: var(--warn); } .stat.is-info .stat-value { color: var(--info); } /* ──────── Findings ──────── */ .findings { display: flex; flex-direction: column; gap: 14px; } .finding-group { background: var(--surface); border: 1px solid var(--border); border-radius: var(--r-lg); overflow: hidden; } .finding-group-head { display: flex; align-items: center; gap: 12px; padding: 14px 18px; border-bottom: 1px solid var(--border); background: var(--surface-hover); } .severity-dot { width: 8px; height: 8px; border-radius: 50%; flex-shrink: 0; } .severity-dot.warn { background: var(--warn); } .severity-dot.info { background: var(--info); } .severity-dot.success { background: var(--success); } .group-filename { font-family: var(--font-mono); font-size: 13.5px; font-weight: 500; color: var(--ink); } .group-counts { margin-left: auto; display: flex; align-items: center; gap: 10px; } .count-pill { display: inline-flex; align-items: center; gap: 5px; padding: 3px 9px; border-radius: 999px; font-size: 11.5px; font-weight: 500; line-height: 1.4; } .count-pill.warn { background: var(--warn-fill); color: var(--warn); } .count-pill.info { background: var(--info-fill); color: var(--info); } .finding-list { padding: 4px 0; } .finding { display: grid; grid-template-columns: 28px 1fr auto; gap: 12px; align-items: center; padding: 12px 18px; } .finding + .finding { border-top: 1px solid var(--border); } .finding:hover { background: var(--surface-hover); } .finding-icon { width: 24px; height: 24px; border-radius: var(--r-sm); display: grid; place-items: center; flex-shrink: 0; } .finding-icon svg { width: 12px; height: 12px; stroke-width: 2.2; } .finding-icon.warn { background: var(--warn-fill); color: var(--warn); } .finding-icon.info { background: var(--info-fill); color: var(--info); } .finding-body { min-width: 0; } .finding-title { font-size: 13.5px; color: var(--ink); margin: 0 0 2px; line-height: 1.35; } .finding-title strong { font-weight: 500; } .finding-meta { font-size: 12px; color: var(--ink-tertiary); font-family: var(--font-mono); } .finding-actions { display: flex; gap: 6px; align-items: center; } .action-link { background: transparent; border: none; color: var(--ink-secondary); font: inherit; font-size: 12.5px; font-weight: 500; cursor: pointer; padding: 5px 10px; border-radius: var(--r-sm); line-height: 1; } .action-link:hover { background: var(--bg); color: var(--ink); } .action-link.is-primary { color: var(--accent); } .action-link.is-primary:hover { background: var(--accent-fill); color: var(--accent-hover); } /* Small screens — collapse sidebar to icon rail */ @media (max-width: 900px) { .app { grid-template-columns: 64px 1fr; } .brand-name, .nav-section-title, .nav-item span, .footer-meta { display: none; } .nav-item { justify-content: center; padding: 9px; } .brand { padding: 18px; justify-content: center; } .sidebar-footer { flex-direction: column; } .main { padding: 24px 20px 60px; } .stats { grid-template-columns: repeat(2, 1fr); } } </style> </head> <body> <div class="app"> <!-- ──────── Sidebar ──────── --> <aside class="sidebar"> <div class="brand"> <div class="brand-mark">D</div> <div class="brand-name">DataTools</div> </div> <nav class="nav"> <div class="nav-section"> <div class="nav-item active"> <svg viewBox="0 0 24 24" fill="none" stroke="currentColor"><path d="M3 12l9-9 9 9M5 10v10h14V10"/></svg> <span>Home</span> </div> </div> <div class="nav-section"> <div class="nav-section-title">Data cleaners</div> <div class="nav-item"> <svg viewBox="0 0 24 24" fill="none" stroke="currentColor"><circle cx="12" cy="12" r="9"/><path d="M12 7v5l3 2"/></svg> <span>Fix missing values</span> </div> <div class="nav-item"> <svg viewBox="0 0 24 24" fill="none" stroke="currentColor"><path d="M3 12h4l3-8 4 16 3-8h4"/></svg> <span>Find unusual values</span> </div> <div class="nav-item"> <svg viewBox="0 0 24 24" fill="none" stroke="currentColor"><path d="M4 4h16v4H4zM4 12h10v4H4zM4 20h6"/></svg> <span>Clean text</span> </div> <div class="nav-item"> <svg viewBox="0 0 24 24" fill="none" stroke="currentColor"><path d="M4 6h16M4 12h16M4 18h10"/></svg> <span>Standardize formats</span> </div> <div class="nav-item"> <svg viewBox="0 0 24 24" fill="none" stroke="currentColor"><circle cx="11" cy="11" r="7"/><path d="M21 21l-4.5-4.5"/></svg> <span>Find duplicates</span> </div> <div class="nav-item"> <svg viewBox="0 0 24 24" fill="none" stroke="currentColor"><path d="M5 12l4 4L19 6"/></svg> <span>Quality check</span> </div> </div> <div class="nav-section"> <div class="nav-section-title">Transformations</div> <div class="nav-item"> <svg viewBox="0 0 24 24" fill="none" stroke="currentColor"><path d="M4 7h16M4 12h16M4 17h16"/><circle cx="8" cy="7" r="1.5" fill="currentColor"/><circle cx="14" cy="12" r="1.5" fill="currentColor"/><circle cx="10" cy="17" r="1.5" fill="currentColor"/></svg> <span>Map columns</span> </div> <div class="nav-item"> <svg viewBox="0 0 24 24" fill="none" stroke="currentColor"><path d="M7 4v8M17 12v8M7 12h10M5 12a2 2 0 100-4 2 2 0 000 4zM5 20a2 2 0 100-4 2 2 0 000 4zM19 12a2 2 0 100-4 2 2 0 000 4z"/></svg> <span>Combine files</span> </div> </div> <div class="nav-section"> <div class="nav-section-title">Automations</div> <div class="nav-item"> <svg viewBox="0 0 24 24" fill="none" stroke="currentColor"><path d="M12 2v4M12 18v4M4.93 4.93l2.83 2.83M16.24 16.24l2.83 2.83M2 12h4M18 12h4M4.93 19.07l2.83-2.83M16.24 7.76l2.83-2.83"/></svg> <span>Automated workflows</span> </div> </div> </nav> <div class="sidebar-footer"> <button class="footer-btn" title="Help"> <svg viewBox="0 0 24 24" fill="none" stroke="currentColor"><circle cx="12" cy="12" r="9"/><path d="M9.5 9a2.5 2.5 0 015 0c0 1.5-2.5 2-2.5 4M12 17h.01"/></svg> </button> <button class="footer-btn" title="Settings"> <svg viewBox="0 0 24 24" fill="none" stroke="currentColor"><circle cx="12" cy="12" r="3"/><path d="M19.4 15a1.65 1.65 0 00.33 1.82l.06.06a2 2 0 11-2.83 2.83l-.06-.06a1.65 1.65 0 00-1.82-.33 1.65 1.65 0 00-1 1.51V21a2 2 0 11-4 0v-.09a1.65 1.65 0 00-1-1.51 1.65 1.65 0 00-1.82.33l-.06.06a2 2 0 11-2.83-2.83l.06-.06a1.65 1.65 0 00.33-1.82 1.65 1.65 0 00-1.51-1H3a2 2 0 110-4h.09a1.65 1.65 0 001.51-1 1.65 1.65 0 00-.33-1.82l-.06-.06a2 2 0 112.83-2.83l.06.06a1.65 1.65 0 001.82.33h0a1.65 1.65 0 001-1.51V3a2 2 0 114 0v.09a1.65 1.65 0 001 1.51h0a1.65 1.65 0 001.82-.33l.06-.06a2 2 0 112.83 2.83l-.06.06a1.65 1.65 0 00-.33 1.82v0a1.65 1.65 0 001.51 1H21a2 2 0 110 4h-.09a1.65 1.65 0 00-1.51 1z"/></svg> </button> <span class="footer-meta">core · 359d</span> </div> </aside> <!-- ──────── Main ──────── --> <main class="main"> <header class="page-header"> <div> <h1 class="page-title">Data Cleaning Mastery</h1> <p class="page-subtitle">A 9-tool suite for cleaning, standardizing, and validating tabular data.</p> </div> <span class="privacy-pill"> <svg viewBox="0 0 24 24" fill="none" stroke="currentColor"><rect x="4" y="11" width="16" height="10" rx="2"/><path d="M8 11V7a4 4 0 018 0v4"/></svg> Runs 100% locally </span> </header> <!-- Files --> <section class="section"> <div class="section-head"> <h2 class="section-title">Files</h2> <span class="section-meta">3 files · 4.2 KB total</span> </div> <div class="files-card"> <div class="file-row"> <div class="file-name"> <span class="file-icon"> <svg viewBox="0 0 24 24" fill="none" stroke="currentColor"><path d="M14 2H6a2 2 0 00-2 2v16a2 2 0 002 2h12a2 2 0 002-2V8z"/><path d="M14 2v6h6"/></svg> </span> 26_format_emails.csv </div> <div class="file-size">1,674 B</div> <button class="file-remove" aria-label="Remove file"> <svg viewBox="0 0 24 24" fill="none" stroke="currentColor"><path d="M18 6L6 18M6 6l12 12"/></svg> </button> </div> <div class="file-row"> <div class="file-name"> <span class="file-icon"> <svg viewBox="0 0 24 24" fill="none" stroke="currentColor"><path d="M14 2H6a2 2 0 00-2 2v16a2 2 0 002 2h12a2 2 0 002-2V8z"/><path d="M14 2v6h6"/></svg> </span> 27_format_addresses.csv </div> <div class="file-size">2,043 B</div> <button class="file-remove" aria-label="Remove file"> <svg viewBox="0 0 24 24" fill="none" stroke="currentColor"><path d="M18 6L6 18M6 6l12 12"/></svg> </button> </div> <div class="file-row"> <div class="file-name"> <span class="file-icon"> <svg viewBox="0 0 24 24" fill="none" stroke="currentColor"><path d="M14 2H6a2 2 0 00-2 2v16a2 2 0 002 2h12a2 2 0 002-2V8z"/><path d="M14 2v6h6"/></svg> </span> 30_format_integration.csv </div> <div class="file-size">538 B</div> <button class="file-remove" aria-label="Remove file"> <svg viewBox="0 0 24 24" fill="none" stroke="currentColor"><path d="M18 6L6 18M6 6l12 12"/></svg> </button> </div> <button class="file-add"> <svg viewBox="0 0 24 24" fill="none" stroke="currentColor"><path d="M12 5v14M5 12h14"/></svg> Add more files </button> </div> <div class="action-bar"> <button class="btn btn-primary"> <svg viewBox="0 0 24 24" fill="none" stroke="currentColor"><path d="M4 4l16 8-16 8z"/></svg> Re-run analysis </button> <button class="btn"> <svg viewBox="0 0 24 24" fill="none" stroke="currentColor"><path d="M21 8v8a2 2 0 01-2 2H5a2 2 0 01-2-2V8M3 8l9 6 9-6M3 8h18"/></svg> Export report </button> <button class="btn btn-ghost">Clear results</button> </div> </section> <!-- Stats --> <section class="stats"> <div class="stat"> <div class="stat-label">Files analyzed</div> <div class="stat-value">3</div> </div> <div class="stat"> <div class="stat-label">Total findings</div> <div class="stat-value">6</div> </div> <div class="stat is-warn"> <div class="stat-label">Warnings</div> <div class="stat-value">1 <span class="stat-unit">to review</span></div> </div> <div class="stat is-info"> <div class="stat-label">Info</div> <div class="stat-value">5 <span class="stat-unit">suggestions</span></div> </div> </section> <!-- Findings --> <section class="section"> <div class="section-head"> <h2 class="section-title">Findings</h2> <span class="section-meta">Grouped by file · sorted by severity</span> </div> <div class="findings"> <!-- File 1 --> <div class="finding-group"> <div class="finding-group-head"> <span class="severity-dot warn"></span> <span class="group-filename">26_format_emails.csv</span> <div class="group-counts"> <span class="count-pill warn">1 warning</span> <span class="count-pill info">2 info</span> </div> </div> <div class="finding-list"> <div class="finding"> <span class="finding-icon warn"> <svg viewBox="0 0 24 24" fill="none" stroke="currentColor"><path d="M12 9v4M12 17h.01M10.29 3.86L1.82 18a2 2 0 001.71 3h16.94a2 2 0 001.71-3L13.71 3.86a2 2 0 00-3.42 0z"/></svg> </span> <div class="finding-body"> <p class="finding-title">3 cells contain <strong>trailing whitespace</strong> in column <code style="font-family:var(--font-mono);font-size:12.5px">email</code></p> <p class="finding-meta">rows 4, 11, 23 · likely caused by copy-paste from spreadsheet</p> </div> <div class="finding-actions"> <button class="action-link">Preview</button> <button class="action-link is-primary">Fix all</button> </div> </div> <div class="finding"> <span class="finding-icon info"> <svg viewBox="0 0 24 24" fill="none" stroke="currentColor"><circle cx="12" cy="12" r="9"/><path d="M12 16v-4M12 8h.01"/></svg> </span> <div class="finding-body"> <p class="finding-title">Mixed case detected in <code style="font-family:var(--font-mono);font-size:12.5px">email</code> column (e.g. <code style="font-family:var(--font-mono);font-size:12.5px">John@Gmail.com</code>)</p> <p class="finding-meta">7 affected rows · normalize to lowercase to enable dedup</p> </div> <div class="finding-actions"> <button class="action-link">Preview</button> <button class="action-link is-primary">Normalize</button> </div> </div> <div class="finding"> <span class="finding-icon info"> <svg viewBox="0 0 24 24" fill="none" stroke="currentColor"><circle cx="12" cy="12" r="9"/><path d="M12 16v-4M12 8h.01"/></svg> </span> <div class="finding-body"> <p class="finding-title">Gmail dot variants found (e.g. <code style="font-family:var(--font-mono);font-size:12.5px">j.smith@gmail.com</code> ≈ <code style="font-family:var(--font-mono);font-size:12.5px">jsmith@gmail.com</code>)</p> <p class="finding-meta">2 affected rows · Gmail ignores dots; treating as same address</p> </div> <div class="finding-actions"> <button class="action-link">Preview</button> <button class="action-link is-primary">Normalize</button> </div> </div> </div> </div> <!-- File 2 --> <div class="finding-group"> <div class="finding-group-head"> <span class="severity-dot info"></span> <span class="group-filename">27_format_addresses.csv</span> <div class="group-counts"> <span class="count-pill info">1 info</span> </div> </div> <div class="finding-list"> <div class="finding"> <span class="finding-icon info"> <svg viewBox="0 0 24 24" fill="none" stroke="currentColor"><circle cx="12" cy="12" r="9"/><path d="M12 16v-4M12 8h.01"/></svg> </span> <div class="finding-body"> <p class="finding-title">Non-standard street abbreviations in column <code style="font-family:var(--font-mono);font-size:12.5px">address_1</code></p> <p class="finding-meta">12 rows mix "Street/St/St.", "Avenue/Ave" — apply USPS-style normalization</p> </div> <div class="finding-actions"> <button class="action-link">Preview</button> <button class="action-link is-primary">Standardize</button> </div> </div> </div> </div> <!-- File 3 --> <div class="finding-group"> <div class="finding-group-head"> <span class="severity-dot info"></span> <span class="group-filename">30_format_integration.csv</span> <div class="group-counts"> <span class="count-pill info">2 info</span> </div> </div> <div class="finding-list"> <div class="finding"> <span class="finding-icon info"> <svg viewBox="0 0 24 24" fill="none" stroke="currentColor"><circle cx="12" cy="12" r="9"/><path d="M12 16v-4M12 8h.01"/></svg> </span> <div class="finding-body"> <p class="finding-title">Inconsistent date format in <code style="font-family:var(--font-mono);font-size:12.5px">signup_date</code> (mix of <code style="font-family:var(--font-mono);font-size:12.5px">MM/DD/YYYY</code> and <code style="font-family:var(--font-mono);font-size:12.5px">YYYY-MM-DD</code>)</p> <p class="finding-meta">5 affected rows · standardize to ISO 8601</p> </div> <div class="finding-actions"> <button class="action-link">Preview</button> <button class="action-link is-primary">Standardize</button> </div> </div> <div class="finding"> <span class="finding-icon info"> <svg viewBox="0 0 24 24" fill="none" stroke="currentColor"><circle cx="12" cy="12" r="9"/><path d="M12 16v-4M12 8h.01"/></svg> </span> <div class="finding-body"> <p class="finding-title">UTF-8 BOM detected at file start</p> <p class="finding-meta">may cause issues in downstream tools — strip on save</p> </div> <div class="finding-actions"> <button class="action-link">Preview</button> <button class="action-link is-primary">Strip</button> </div> </div> </div> </div> </div> </section> </main> </div> </body> </html>