Files
AIRegulation-DocAnalysis/Prototype/cc29bcb0-df2d-4d50-9428-7caa406ecb29/compliance-analysis.html

536 lines
23 KiB
HTML
Raw Normal View History

<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>AI + Compliance Hub - Compliance Analysis</title>
<style>
:root {
--bg: #fafafa;
--surface: #ffffff;
--surface-warm: var(--surface);
--fg: #111111;
--fg-2: var(--fg);
--muted: #6b6b6b;
--meta: var(--muted);
--border: #e5e5e5;
--border-soft: var(--border);
--primary: #e20074;
--accent: var(--primary);
--accent-on: #ffffff;
--accent-hover: color-mix(in oklab, var(--accent), black 8%);
--accent-active: color-mix(in oklab, var(--accent), black 14%);
--success: #17a34a;
--warn: #eab308;
--danger: #dc2626;
--font-display: "TeleNeoWeb-Bold", "TeleNeoWeb-Medium", "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
--font-body: "TeleNeoWeb-Regular", "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
--font-mono: ui-monospace, "JetBrains Mono", "SF Mono", Menlo, monospace;
--text-xs: 12px;
--text-sm: 14px;
--text-base: 16px;
--text-lg: 20px;
--text-xl: 24px;
--text-2xl: 32px;
--text-3xl: 48px;
--text-4xl: 64px;
--leading-body: 1.5;
--leading-tight: 1.2;
--tracking-display: -0.01em;
--space-1: 4px;
--space-2: 8px;
--space-3: 12px;
--space-4: 16px;
--space-5: 20px;
--space-6: 24px;
--space-8: 32px;
--space-12: 48px;
--space-20: 80px;
--section-y-desktop: 80px;
--section-y-tablet: 48px;
--section-y-phone: 32px;
--radius-sm: 8px;
--radius-md: 12px;
--radius-lg: 16px;
--radius-pill: 9999px;
--elev-flat: none;
--elev-ring: 0 0 0 1px var(--border);
--elev-raised: 0 2px 8px color-mix(in oklab, var(--fg), transparent 92%);
--focus-ring: 0 0 0 3px color-mix(in oklab, var(--accent), transparent 70%);
--motion-fast: 150ms;
--motion-base: 200ms;
--ease-standard: cubic-bezier(0.2, 0, 0, 1);
--container-max: 1600px;
--container-gutter-desktop: 24px;
--container-gutter-tablet: 16px;
--container-gutter-phone: 12px;
--sidebar-w: 240px;
color-scheme: light;
}
@media (prefers-color-scheme: dark) {
:root:not([data-theme="light"]) {
--bg: #0f1014;
--surface: #17181d;
--surface-warm: #1d1f26;
--fg: #f5f7fb;
--fg-2: #e5e8ef;
--muted: #a2a9b8;
--meta: #858d9c;
--border: #2a2d35;
--border-soft: #21242c;
--accent-hover: color-mix(in oklab, var(--accent), white 12%);
--accent-active: color-mix(in oklab, var(--accent), black 6%);
--success: #22c55e;
--warn: #facc15;
--danger: #f87171;
--elev-raised: 0 14px 36px color-mix(in oklab, black, transparent 74%);
--focus-ring: 0 0 0 3px color-mix(in oklab, var(--accent), transparent 56%);
color-scheme: dark;
}
}
:root[data-theme="dark"] {
--bg: #0f1014;
--surface: #17181d;
--surface-warm: #1d1f26;
--fg: #f5f7fb;
--fg-2: #e5e8ef;
--muted: #a2a9b8;
--meta: #858d9c;
--border: #2a2d35;
--border-soft: #21242c;
--accent-hover: color-mix(in oklab, var(--accent), white 12%);
--accent-active: color-mix(in oklab, var(--accent), black 6%);
--success: #22c55e;
--warn: #facc15;
--danger: #f87171;
--elev-raised: 0 14px 36px color-mix(in oklab, black, transparent 74%);
--focus-ring: 0 0 0 3px color-mix(in oklab, var(--accent), transparent 56%);
color-scheme: dark;
}
:root[data-theme="light"] {
color-scheme: light;
}
* { box-sizing: border-box; }
body {
margin: 0;
background: var(--bg);
color: var(--fg);
font-family: var(--font-body);
font-size: var(--text-base);
line-height: var(--leading-body);
text-rendering: optimizeLegibility;
-webkit-font-smoothing: antialiased;
}
h1, h2, h3, h4 {
margin: 0;
font-family: var(--font-display);
line-height: var(--leading-tight);
letter-spacing: var(--tracking-display);
}
p { margin: 0; text-wrap: pretty; }
a { color: inherit; text-decoration: none; }
a:hover { color: var(--fg); text-decoration: underline; }
button { font: inherit; }
/* ── Sidebar shell ── */
.app-shell { display: grid; grid-template-columns: var(--sidebar-w) 1fr; min-height: 100vh; }
.sidebar { position: sticky; top: 0; height: 100vh; overflow-y: auto; display: flex; flex-direction: column; background: var(--surface); border-right: 1px solid var(--border); z-index: 10; }
.sidebar-brand { display: flex; align-items: center; gap: 10px; height: 56px; padding: 0 16px; border-bottom: 1px solid var(--border); flex-shrink: 0; }
.brand-logo { width: 26px; height: 26px; background: var(--accent); border-radius: 6px; display: flex; align-items: center; justify-content: center; flex-shrink: 0; }
.brand-logo svg { color: #fff; }
.sidebar-brand-name { font-family: var(--font-display); font-size: 13px; font-weight: 700; line-height: 1.2; }
.sidebar-brand-sub { font-size: 10px; color: var(--muted); font-family: var(--font-mono); letter-spacing: 0.04em; }
.sidebar-nav { flex: 1; padding: 12px 0; overflow-y: auto; }
.nav-group { padding: 0 8px 4px; }
.nav-group + .nav-group { margin-top: 12px; padding-top: 12px; border-top: 1px solid var(--border); }
.nav-group-label { font-family: var(--font-mono); font-size: 10px; text-transform: uppercase; letter-spacing: 0.1em; color: var(--muted); padding: 0 8px 6px; display: block; }
.nav-item { display: flex; align-items: center; gap: 10px; height: 36px; padding: 0 8px; border-radius: 6px; color: var(--muted); font-size: 13px; cursor: pointer; transition: background 140ms, color 140ms; position: relative; }
.nav-item:hover { background: color-mix(in oklab, var(--fg), transparent 94%); color: var(--fg); text-decoration: none; }
.nav-item.active { background: color-mix(in oklab, var(--accent), transparent 90%); color: var(--accent); font-weight: 600; }
.nav-item.active::before { content: ""; position: absolute; left: 0; top: 6px; bottom: 6px; width: 3px; border-radius: 0 3px 3px 0; background: var(--accent); }
.nav-icon { width: 16px; height: 16px; flex-shrink: 0; opacity: 0.7; }
.nav-item.active .nav-icon { opacity: 1; }
.sidebar-footer { border-top: 1px solid var(--border); padding: 10px 8px; flex-shrink: 0; display: flex; flex-direction: column; gap: 4px; }
.sidebar-user { display: flex; align-items: center; gap: 10px; padding: 8px; border-radius: 6px; cursor: pointer; }
.sidebar-user:hover { background: color-mix(in oklab, var(--fg), transparent 94%); }
.avatar { width: 30px; height: 30px; border-radius: 50%; background: var(--accent); color: #fff; font-size: 12px; font-weight: 700; display: flex; align-items: center; justify-content: center; flex-shrink: 0; }
.sidebar-user-info { min-width: 0; }
.sidebar-user-name { font-size: 13px; font-weight: 600; color: var(--fg); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.sidebar-user-role { font-size: 11px; color: var(--muted); font-family: var(--font-mono); }
.sidebar-action { display: flex; align-items: center; gap: 10px; height: 34px; padding: 0 8px; border-radius: 6px; color: var(--muted); font-size: 13px; cursor: pointer; border: none; background: transparent; width: 100%; text-align: left; transition: background 140ms, color 140ms; }
.sidebar-action:hover { background: color-mix(in oklab, var(--fg), transparent 94%); color: var(--fg); }
.content-area { display: flex; flex-direction: column; min-width: 0; min-height: 100vh; }
.content-topbar { position: sticky; top: 0; z-index: 5; display: flex; align-items: center; gap: 12px; height: 56px; padding: 0 24px; border-bottom: 1px solid var(--border); background: color-mix(in oklab, var(--bg), transparent 4%); backdrop-filter: blur(10px); }
.topbar-title { font-weight: 600; font-size: 15px; color: var(--fg); flex: 1; }
.search { display: flex; align-items: center; gap: 8px; border: 1px solid var(--border); border-radius: 6px; background: var(--surface); padding: 0 12px; height: 34px; width: 240px; }
.search input { border: 0; outline: none; background: transparent; width: 100%; color: var(--fg); font-size: 13px; }
.search input::placeholder { color: var(--muted); }
.footer { display: flex; align-items: center; justify-content: space-between; gap: 16px; min-height: 34px; padding: 0 24px; border-top: 1px solid var(--border); color: var(--muted); font-size: 11px; font-family: var(--font-mono); letter-spacing: 0.1em; text-transform: uppercase; }
.footer-status { display: inline-flex; align-items: center; gap: 8px; }
.footer-dot { width: 7px; height: 7px; border-radius: 50%; background: #19d3a2; box-shadow: 0 0 0 3px color-mix(in oklab, #19d3a2, transparent 82%); }
@media (max-width: 700px) { .app-shell { grid-template-columns: 1fr; } .sidebar { display: none; } }
/* ── Page / component styles ── */
.page {
max-width: 1600px;
margin: 0 auto;
padding: 24px;
display: grid;
gap: 20px;
}
.hero {
display: flex;
align-items: end;
justify-content: space-between;
gap: 20px;
}
.eyebrow {
color: var(--accent);
font-family: var(--font-mono);
font-size: var(--text-xs);
text-transform: uppercase;
letter-spacing: 0.08em;
margin-bottom: 8px;
}
.hero h1 { font-size: clamp(30px, 4vw, 44px); }
.hero p { color: var(--muted); max-width: 74ch; }
.btn {
min-height: 44px;
padding: 0 16px;
border-radius: var(--radius-sm);
border: 1px solid var(--border);
background: transparent;
color: var(--fg);
}
.btn-primary {
background: var(--accent);
border-color: var(--accent);
color: var(--accent-on);
}
.btn-primary:hover {
background: var(--accent-hover);
border-color: var(--accent-hover);
}
.workspace {
display: grid;
grid-template-columns: 0.95fr 1.25fr 0.9fr;
gap: 16px;
min-height: 760px;
}
.card {
border: 1px solid var(--border);
border-radius: var(--radius-md);
background: var(--surface);
padding: 18px;
min-width: 0;
}
.section-head {
display: flex;
justify-content: space-between;
align-items: center;
gap: 12px;
margin-bottom: 16px;
}
.section-head h2 { font-size: var(--text-xl); }
.helper {
color: var(--muted);
font-size: var(--text-sm);
}
.mono {
font-family: var(--font-mono);
font-variant-numeric: tabular-nums;
}
.source-list,
.finding-list,
.actions {
display: grid;
gap: 12px;
}
.source-item,
.finding,
.action-item,
.stage {
border: 1px solid var(--border);
border-radius: var(--radius-sm);
background: color-mix(in oklab, var(--surface), var(--bg) 14%);
padding: 14px;
}
.pill,
.status {
display: inline-flex;
align-items: center;
gap: 8px;
width: fit-content;
padding: 4px 10px;
border-radius: var(--radius-pill);
border: 1px solid var(--border);
font-size: var(--text-xs);
font-family: var(--font-mono);
}
.status::before {
content: "";
width: 7px;
height: 7px;
border-radius: 999px;
background: currentColor;
}
.status.ok { color: var(--success); }
.status.warn { color: color-mix(in oklab, var(--warn), black 24%); }
.status.risk { color: var(--danger); }
.paragraph {
border: 1px solid var(--border);
border-radius: var(--radius-sm);
background: var(--surface);
padding: 18px;
display: grid;
gap: 14px;
}
.paragraph mark {
background: color-mix(in oklab, var(--accent), white 80%);
color: inherit;
padding: 0 3px;
border-radius: 4px;
}
.stage-list {
display: grid;
gap: 12px;
margin-bottom: 16px;
}
.finding strong,
.source-item strong,
.action-item strong,
.stage strong {
display: block;
margin-bottom: 6px;
}
.score-row {
display: flex;
gap: 10px;
flex-wrap: wrap;
margin-top: 8px;
}
.progress {
height: 8px;
border-radius: 999px;
background: color-mix(in oklab, var(--fg), transparent 95%);
overflow: hidden;
margin-top: 10px;
}
.progress > span {
display: block;
height: 100%;
border-radius: inherit;
background: color-mix(in oklab, var(--accent), white 28%);
}
.conclusion {
margin-top: 16px;
border-top: 1px solid var(--border);
padding-top: 16px;
display: grid;
gap: 12px;
}
.conclusion-box {
border: 1px solid var(--border);
border-radius: var(--radius-sm);
padding: 16px;
background: color-mix(in oklab, var(--surface), var(--bg) 10%);
}
@media (max-width: 1280px) {
.workspace { grid-template-columns: 1fr; }
.hero { flex-direction: column; align-items: start; }
}
@media (max-width: 760px) {
.page { padding: 12px; }
}
</style>
</head>
<body data-page="analysis">
<div class="app-shell">
<aside class="sidebar" aria-label="Primary navigation">
<div class="sidebar-brand">
<div class="brand-logo">
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" aria-hidden="true">
<path d="M2 3.5h12v1.5H2zm5.25 1.5h1.5v8h-1.5zm-3 2h2.25v1.5H4.25zm5.25 0h2.25v1.5H9.5zm-3 3h2.5v1.5H6.5z" fill="currentColor"/>
</svg>
</div>
<div>
<div class="sidebar-brand-name">T-Systems</div>
<div class="sidebar-brand-sub">Regulation Hub</div>
</div>
</div>
<nav class="sidebar-nav" aria-label="Primary">
<div class="nav-group">
<span class="nav-group-label">主导航</span>
<a class="nav-item" href="index.html"><svg class="nav-icon" viewBox="0 0 16 16" fill="none"><path d="M2 2h5v5H2zm7 0h5v5H9zM2 9h5v5H2zm7 0h5v5H9z" fill="currentColor" opacity=".7"/></svg>概览</a>
<a class="nav-item" href="dashboard.html"><svg class="nav-icon" viewBox="0 0 16 16" fill="none"><path d="M1.5 2.5h13v1H1.5zm0 3h13v1H1.5zm0 3h8v1h-8zm0 3h6v1h-6z" fill="currentColor"/></svg>系统状态</a>
</div>
<div class="nav-group">
<span class="nav-group-label">工作台</span>
<a class="nav-item" href="document-management.html"><svg class="nav-icon" viewBox="0 0 16 16" fill="none"><path d="M3 1h7l3 3v11H3V1zm1 1v12h8V5h-3V2H4zm5 .5V4h1.5L9 1.5zM6 7h4v1H6zm0 2h4v1H6zm0 2h3v1H6z" fill="currentColor"/></svg>文档管理</a>
<a class="nav-item active" href="compliance-analysis.html"><svg class="nav-icon" viewBox="0 0 16 16" fill="none"><path d="M8 1l7 3-1 6a7 7 0 01-6 5A7 7 0 011 10L0 4l8-3zm0 1.2L1.3 4.8l.8 5.1A6 6 0 008 14.8a6 6 0 005.9-4.9l.8-5.1L8 2.2zM7.5 5h1v4.5l-1 .5V5zm0 5.5h1v1h-1v-1z" fill="currentColor"/></svg>合规分析</a>
</div>
<div class="nav-group">
<span class="nav-group-label">对话</span>
<a class="nav-item" href="regulation-chat.html"><svg class="nav-icon" viewBox="0 0 16 16" fill="none"><path d="M2 2h12a1 1 0 011 1v8a1 1 0 01-1 1H5l-3 2.5V3a1 1 0 011-1zm0 1v9.5L4.5 11H14V3H2zm2 2h8v1H4zm0 2h6v1H4z" fill="currentColor"/></svg>法规对话</a>
</div>
</nav>
<div class="sidebar-footer">
<div class="sidebar-user">
<div class="avatar">TS</div>
<div class="sidebar-user-info">
<div class="sidebar-user-name">T-Systems User</div>
<div class="sidebar-user-role">Compliance Analyst</div>
</div>
</div>
<button class="sidebar-action od-theme-toggle" type="button" data-od-theme aria-label="Toggle theme">
<svg width="14" height="14" viewBox="0 0 16 16" fill="none"><path d="M8 3a5 5 0 100 10A5 5 0 008 3zM2 8a6 6 0 1112 0A6 6 0 012 8z" fill="currentColor"/></svg>
主题
</button>
</div>
</aside>
<div class="content-area">
<header class="content-topbar">
<div class="topbar-title">合规分析</div>
<div class="search">
<svg width="14" height="14" viewBox="0 0 16 16" fill="none"><path d="M6.5 1a5.5 5.5 0 014.23 9.02l3.62 3.62-.7.71-3.63-3.63A5.5 5.5 0 116.5 1zm0 1a4.5 4.5 0 100 9 4.5 4.5 0 000-9z" fill="currentColor" opacity=".5"/></svg>
<input type="search" placeholder="Search findings…" aria-label="Search" />
</div>
<button class="btn btn-primary">New analysis</button>
</header>
<main class="page">
<section class="hero" data-od-id="analysis-hero">
<div>
<div class="eyebrow">Compliance analysis workspace</div>
<h1>From retrieved regulation to conclusion-ready action.</h1>
<p>This screen is built for a reviewer comparing one paragraph of product documentation against candidate regulations, system reasoning, and recommended changes. The rhythm is left-to-right: evidence retrieval, close reading, and decision output.</p>
</div>
<div style="display:flex; gap:12px; flex-wrap:wrap;">
<a class="btn" href="document-detail.html">Open parse detail</a>
<a class="btn btn-primary" href="regulation-chat.html">Ask follow-up in chat</a>
</div>
</section>
<section class="workspace" data-od-id="analysis-workspace">
<aside class="card">
<div class="section-head">
<h2>Retrieved regulations</h2>
<span class="helper">Top 10 by dense similarity</span>
</div>
<div class="source-list">
<div class="source-item">
<strong>GB 26112-2010 §4.2 Roof crush resistance</strong>
<div class="helper">Primary match · mandatory requirement · promoted as lead citation</div>
<div class="score-row">
<span class="pill">Vehicle safety</span>
<span class="status risk">High impact</span>
</div>
</div>
<div class="source-item">
<strong>C-NCAP rulebook §3.1 occupant safety context</strong>
<div class="helper">Supporting match · interpretation context · not mandatory on its own</div>
<div class="score-row">
<span class="pill">Assessment</span>
<span class="status warn">Context only</span>
</div>
</div>
<div class="source-item">
<strong>Internal design note: structure validation test plan</strong>
<div class="helper">Evidence match · useful support artifact with no direct legal force</div>
<div class="score-row">
<span class="pill">Evidence</span>
<span class="status ok">Supporting</span>
</div>
</div>
</div>
</aside>
<section class="card">
<div class="section-head">
<h2>Document paragraph under review</h2>
<span class="helper">Chunk 148 · supplier safety narrative</span>
</div>
<div class="paragraph">
<p><strong>Source text</strong></p>
<p>The roof support structure is designed to satisfy national crush-resistance requirements, and the module enclosure preserves occupant safety under static load conditions. Validation results are available in the body engineering report and are considered aligned with the current certification baseline.</p>
<p><strong>Analysis focus</strong></p>
<p>The system flags that the narrative claims compliance but omits the explicit load threshold. The phrase <mark>satisfy national crush-resistance requirements</mark> should be tied to a stated requirement derived from <mark>GB 26112-2010 §4.2</mark> to avoid unsupported compliance language.</p>
</div>
<div class="section-head" style="margin-top:18px;">
<h2>Analysis stages</h2>
<span class="helper">Streaming reasoning workflow</span>
</div>
<div class="stage-list">
<div class="stage">
<strong>1. Clause retrieval</strong>
<div class="helper">Dense retrieval found 10 nearby standards; 3 were promoted after category scoring.</div>
<div class="progress"><span style="width:100%"></span></div>
</div>
<div class="stage">
<strong>2. Requirement extraction</strong>
<div class="helper">Relevant mandatory threshold identified and isolated for reviewer verification.</div>
<div class="progress"><span style="width:100%"></span></div>
</div>
<div class="stage">
<strong>3. Gap analysis</strong>
<div class="helper">Document contains claim language but no direct numeric evidence or linked report identifier.</div>
<div class="progress"><span style="width:88%"></span></div>
</div>
<div class="stage">
<strong>4. Recommendation synthesis</strong>
<div class="helper">Drafting precise remediation text for reviewer approval.</div>
<div class="progress"><span style="width:62%"></span></div>
</div>
</div>
</section>
<aside class="card">
<div class="section-head">
<h2>Findings and conclusion</h2>
<span class="helper">Reviewer-ready output</span>
</div>
<div class="finding-list">
<div class="finding">
<strong>Unsupported compliance statement</strong>
<p class="helper">The paragraph asserts conformity without quoting the actual threshold or citing a specific verification artifact.</p>
<span class="status risk" style="margin-top:10px;">Needs revision</span>
</div>
<div class="finding">
<strong>Evidence linkage incomplete</strong>
<p class="helper">Body engineering report exists, but the report ID and page range are missing from the narrative used in the dossier.</p>
<span class="status warn" style="margin-top:10px;">Evidence gap</span>
</div>
</div>
<div class="conclusion">
<div class="conclusion-box">
<strong>Recommended replacement text</strong>
<p class="helper">"The roof support structure was validated in accordance with GB 26112-2010 §4.2; see the linked body engineering report for the supporting test result and formal threshold statement."</p>
</div>
<div class="actions">
<div class="action-item">
<strong>Next action</strong>
<p class="helper">Assign to Body Structure team for wording update, then rerun the same paragraph through clause verification.</p>
</div>
<div class="action-item">
<strong>Escalation</strong>
<p class="helper">If report ID cannot be linked within 24 hours, downgrade dossier status and notify homologation lead.</p>
</div>
</div>
</div>
</aside>
</section>
</main>
<footer class="footer">
<span>T-Systems Regulation Hub</span>
<div class="footer-status"><span class="footer-dot" aria-hidden="true"></span><span>Online</span></div>
</footer>
</div>
</div>
<script src="ui-preferences.js"></script>
</body>
</html>