<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Siteimprove Accessibility Report</title>
<style>
:root {
--si-blue: #003058;
--si-light: #f5f7fa;
--fail-bg: #fff5f5;
--fail-text: #c53030;
--border: #e2e8f0;
}
body {
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
background: #fff;
color: #333;
margin: 0;
padding: 2rem;
}
.container {
max-width: 1200px;
margin: 0 auto;
}
/* Header */
header {
border-bottom: 2px solid var(--si-blue);
padding-bottom: 1rem;
margin-bottom: 2rem;
display: flex;
justify-content: space-between;
align-items: center;
}
h1 {
color: var(--si-blue);
margin: 0;
font-size: 1.8rem;
}
.meta {
color: #666;
font-size: 0.9rem;
}
/* Page Card */
.page-card {
border: 1px solid var(--border);
border-radius: 8px;
margin-bottom: 2rem;
overflow: hidden;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.05);
}
.page-header {
background: var(--si-light);
padding: 1rem 1.5rem;
border-bottom: 1px solid var(--border);
font-weight: 600;
font-size: 1.1rem;
display: flex;
justify-content: space-between;
}
.page-url {
color: var(--si-blue);
font-family: monospace;
}
.issue-count {
background: var(--fail-text);
color: white;
padding: 2px 8px;
border-radius: 12px;
font-size: 0.8rem;
}
/* Violations Table */
.violation {
padding: 1.5rem;
border-bottom: 1px solid var(--border);
}
.violation:last-child {
border-bottom: none;
}
.rule-header {
display: flex;
align-items: baseline;
margin-bottom: 0.5rem;
}
.rule-id {
font-family: monospace;
color: #666;
background: #eee;
padding: 2px 6px;
border-radius: 4px;
font-size: 0.8rem;
margin-right: 10px;
}
.rule-title {
font-weight: 700;
color: var(--si-blue);
font-size: 1.1rem;
text-decoration: none;
}
.rule-title:hover {
text-decoration: underline;
}
.criteria-badge {
margin-left: auto;
background: #e6fffa;
color: #2c7a7b;
padding: 2px 8px;
border-radius: 4px;
font-size: 0.8rem;
border: 1px solid #b2f5ea;
}
.rule-desc {
margin: 0.5rem 0 1rem 0;
color: #555;
line-height: 1.5;
font-size: 0.95rem;
}
/* Instances */
.instances {
background: var(--fail-bg);
border-radius: 6px;
padding: 1rem;
}
.instance-item {
margin-bottom: 0.75rem;
font-family: monospace;
font-size: 0.85rem;
border-left: 3px solid var(--fail-text);
padding-left: 10px;
}
.instance-item:last-child {
margin-bottom: 0;
}
.selector {
color: var(--si-blue);
font-weight: bold;
display: block;
margin-bottom: 2px;
}
.code-snippet {
color: #555;
display: block;
white-space: pre-wrap;
word-break: break-all;
}
.empty-state {
text-align: center;
padding: 4rem;
color: #999;
}
</style>
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.14/dist/vue.js"></script>
</head>
<body>
<div id="app" class="container">
<header>
<div>
<h1>Siteimprove Report</h1>
<div class="meta">Engine: {{ engine }} | Date: {{ testDate }}</div>
</div>
</header>
<div v-if="loading" class="empty-state">Loading report...</div>
<div v-else-if="error" class="empty-state" style="color:red">{{ error }}</div>
<div v-else>
<div v-for="page in pages" :key="page.url" class="page-card">
<div class="page-header">
<span class="page-url">{{ page.url }}</span>
<span class="issue-count">{{ page.violations.length }} Rules Failed</span>
</div>
<div class="page-body">
<div v-for="violation in page.violations" :key="violation.ruleId" class="violation">
<div class="rule-header">
<span class="rule-id">{{ violation.ruleId.toUpperCase() }}</span>
<a :href="violation.helpUrl" target="_blank" class="rule-title">{{ violation.title }}</a>
<span class="criteria-badge">{{ violation.criteria }}</span>
</div>
<p class="rule-desc">{{ violation.description }}</p>
<div class="instances">
<div v-for="(instance, idx) in violation.instances" :key="idx" class="instance-item">
<span class="selector">{{ instance.selector }}</span>
<span class="code-snippet">{{ instance.html }}</span>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<script>
new Vue({
el: '#app',
data: {
loading: true,
error: '',
pages: [],
engine: '',
testDate: ''
},
mounted() {
// Load the Siteimprove JSON specifically
fetch('/accessibility-scans/siteimprove-static.json')
.then(r => {
if (!r.ok) throw new Error("Report file not found. Run 'gulp siteimprove' first.");
return r.json();
})
.then(data => {
this.pages = data.pages || [];
if (data.meta) {
this.engine = data.meta.engine;
this.testDate = new Date(data.meta.date).toLocaleString();
}
this.loading = false;
})
.catch(e => {
this.error = e.message;
this.loading = false;
});
}
});
</script>
</body>
</html>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Siteimprove Accessibility Report</title>
<style>
:root {
--si-blue: #003058;
--si-light: #f5f7fa;
--fail-bg: #fff5f5;
--fail-text: #c53030;
--border: #e2e8f0;
}
body { font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif; background: #fff; color: #333; margin: 0; padding: 2rem; }
.container { max-width: 1200px; margin: 0 auto; }
/* Header */
header { border-bottom: 2px solid var(--si-blue); padding-bottom: 1rem; margin-bottom: 2rem; display: flex; justify-content: space-between; align-items: center; }
h1 { color: var(--si-blue); margin: 0; font-size: 1.8rem; }
.meta { color: #666; font-size: 0.9rem; }
/* Page Card */
.page-card { border: 1px solid var(--border); border-radius: 8px; margin-bottom: 2rem; overflow: hidden; box-shadow: 0 2px 4px rgba(0,0,0,0.05); }
.page-header { background: var(--si-light); padding: 1rem 1.5rem; border-bottom: 1px solid var(--border); font-weight: 600; font-size: 1.1rem; display: flex; justify-content: space-between; }
.page-url { color: var(--si-blue); font-family: monospace; }
.issue-count { background: var(--fail-text); color: white; padding: 2px 8px; border-radius: 12px; font-size: 0.8rem; }
/* Violations Table */
.violation { padding: 1.5rem; border-bottom: 1px solid var(--border); }
.violation:last-child { border-bottom: none; }
.rule-header { display: flex; align-items: baseline; margin-bottom: 0.5rem; }
.rule-id { font-family: monospace; color: #666; background: #eee; padding: 2px 6px; border-radius: 4px; font-size: 0.8rem; margin-right: 10px; }
.rule-title { font-weight: 700; color: var(--si-blue); font-size: 1.1rem; text-decoration: none; }
.rule-title:hover { text-decoration: underline; }
.criteria-badge { margin-left: auto; background: #e6fffa; color: #2c7a7b; padding: 2px 8px; border-radius: 4px; font-size: 0.8rem; border: 1px solid #b2f5ea; }
.rule-desc { margin: 0.5rem 0 1rem 0; color: #555; line-height: 1.5; font-size: 0.95rem; }
/* Instances */
.instances { background: var(--fail-bg); border-radius: 6px; padding: 1rem; }
.instance-item { margin-bottom: 0.75rem; font-family: monospace; font-size: 0.85rem; border-left: 3px solid var(--fail-text); padding-left: 10px; }
.instance-item:last-child { margin-bottom: 0; }
.selector { color: var(--si-blue); font-weight: bold; display: block; margin-bottom: 2px; }
.code-snippet { color: #555; display: block; white-space: pre-wrap; word-break: break-all; }
.empty-state { text-align: center; padding: 4rem; color: #999; }
</style>
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.14/dist/vue.js"></script>
</head>
<body>
<div id="app" class="container">
{% raw %}
<header>
<div>
<h1>Siteimprove Report</h1>
<div class="meta">Engine: {{ engine }} | Date: {{ testDate }}</div>
</div>
</header>
<div v-if="loading" class="empty-state">Loading report...</div>
<div v-else-if="error" class="empty-state" style="color:red">{{ error }}</div>
<div v-else>
<div v-for="page in pages" :key="page.url" class="page-card">
<div class="page-header">
<span class="page-url">{{ page.url }}</span>
<span class="issue-count">{{ page.violations.length }} Rules Failed</span>
</div>
<div class="page-body">
<div v-for="violation in page.violations" :key="violation.ruleId" class="violation">
<div class="rule-header">
<span class="rule-id">{{ violation.ruleId.toUpperCase() }}</span>
<a :href="violation.helpUrl" target="_blank" class="rule-title">{{ violation.title }}</a>
<span class="criteria-badge">{{ violation.criteria }}</span>
</div>
<p class="rule-desc">{{ violation.description }}</p>
<div class="instances">
<div v-for="(instance, idx) in violation.instances" :key="idx" class="instance-item">
<span class="selector">{{ instance.selector }}</span>
<span class="code-snippet">{{ instance.html }}</span>
</div>
</div>
</div>
</div>
</div>
</div>
{% endraw %}
</div>
<script>
new Vue({
el: '#app',
data: {
loading: true,
error: '',
pages: [],
engine: '',
testDate: ''
},
mounted() {
// Load the Siteimprove JSON specifically
fetch('/accessibility-scans/siteimprove-static.json')
.then(r => {
if (!r.ok) throw new Error("Report file not found. Run 'gulp siteimprove' first.");
return r.json();
})
.then(data => {
this.pages = data.pages || [];
if (data.meta) {
this.engine = data.meta.engine;
this.testDate = new Date(data.meta.date).toLocaleString();
}
this.loading = false;
})
.catch(e => {
this.error = e.message;
this.loading = false;
});
}
});
</script>
</body>
</html>
No notes defined.