<!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>