Add public showcase landing, doc summary cards, and chunk toggle
- index.php: public showcase landing page (hero, how-it-works, capabilities, evidence mock, login form) visible to unauthenticated visitors; full OG/SEO meta; app shell hidden behind auth as before - tools.css: showcase section styles (gradient hero, step cards, capability grid, CTA button, evidence mock, footer) - LegalTools.php: sourceFromChunk() batch-fetches doc_summaries from RAG DB for non-private chunks; excerpt shows doc summary when available, falls back to raw chunk text; chunk_text field always carries the raw excerpt - tools.js: renderEvidenceItem() shows doc summary as card body; adds a collapsible "View chunk" toggle when summary differs from raw chunk text Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -511,3 +511,365 @@ p {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
}
|
||||
|
||||
/* ─── Public showcase landing ──────────────────────────────────────────────── */
|
||||
|
||||
.showcase-page {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
min-height: 100vh;
|
||||
background: var(--bg);
|
||||
}
|
||||
|
||||
.showcase-header {
|
||||
background:
|
||||
linear-gradient(135deg, rgba(15, 118, 110, 0.92), rgba(17, 94, 89, 0.97) 70%),
|
||||
linear-gradient(315deg, rgba(194, 65, 12, 0.18), transparent 40%);
|
||||
color: #fff;
|
||||
padding: 64px 24px 72px;
|
||||
}
|
||||
|
||||
.showcase-header-inner {
|
||||
max-width: 860px;
|
||||
margin: 0 auto;
|
||||
display: flex;
|
||||
align-items: flex-end;
|
||||
justify-content: space-between;
|
||||
gap: 32px;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
.showcase-brand .eyebrow {
|
||||
color: rgba(255,255,255,0.72);
|
||||
}
|
||||
|
||||
.showcase-title {
|
||||
margin: 0 0 10px;
|
||||
font-size: clamp(2rem, 5vw, 3rem);
|
||||
font-weight: 800;
|
||||
line-height: 1.1;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.showcase-tagline {
|
||||
margin: 0 0 18px;
|
||||
font-size: 1.1rem;
|
||||
color: rgba(255,255,255,0.82);
|
||||
}
|
||||
|
||||
.powered-badge {
|
||||
display: inline-block;
|
||||
background: rgba(255,255,255,0.14);
|
||||
border: 1px solid rgba(255,255,255,0.28);
|
||||
border-radius: 999px;
|
||||
padding: 4px 14px;
|
||||
font-size: 0.78rem;
|
||||
font-weight: 600;
|
||||
color: rgba(255,255,255,0.9);
|
||||
text-decoration: none;
|
||||
transition: background 0.15s;
|
||||
}
|
||||
|
||||
.powered-badge:hover {
|
||||
background: rgba(255,255,255,0.22);
|
||||
}
|
||||
|
||||
.cta-button {
|
||||
display: inline-block;
|
||||
background: var(--coral);
|
||||
color: #fff;
|
||||
text-decoration: none;
|
||||
padding: 14px 28px;
|
||||
border-radius: 8px;
|
||||
font-weight: 700;
|
||||
font-size: 1rem;
|
||||
white-space: nowrap;
|
||||
transition: background 0.15s, transform 0.1s;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.cta-button:hover {
|
||||
background: #b83a0b;
|
||||
transform: translateY(-1px);
|
||||
}
|
||||
|
||||
.section-inner {
|
||||
max-width: 860px;
|
||||
margin: 0 auto;
|
||||
padding: 0 24px;
|
||||
}
|
||||
|
||||
.section-heading {
|
||||
margin: 0 0 8px;
|
||||
font-size: 1.5rem;
|
||||
font-weight: 800;
|
||||
color: var(--ink);
|
||||
}
|
||||
|
||||
.section-sub {
|
||||
margin: 0 0 36px;
|
||||
color: var(--muted);
|
||||
font-size: 0.98rem;
|
||||
}
|
||||
|
||||
/* How it works */
|
||||
.hiw-section {
|
||||
padding: 64px 0;
|
||||
background: var(--panel);
|
||||
border-bottom: 1px solid var(--line);
|
||||
}
|
||||
|
||||
.hiw-steps {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
|
||||
gap: 28px;
|
||||
}
|
||||
|
||||
.hiw-step {
|
||||
background: var(--bg);
|
||||
border: 1px solid var(--line);
|
||||
border-radius: 8px;
|
||||
padding: 24px;
|
||||
}
|
||||
|
||||
.hiw-num {
|
||||
font-size: 2rem;
|
||||
font-weight: 800;
|
||||
color: var(--teal);
|
||||
opacity: 0.4;
|
||||
margin-bottom: 12px;
|
||||
line-height: 1;
|
||||
}
|
||||
|
||||
.hiw-step h3 {
|
||||
margin: 0 0 8px;
|
||||
font-size: 1rem;
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
.hiw-step p {
|
||||
margin: 0;
|
||||
color: var(--muted);
|
||||
font-size: 0.9rem;
|
||||
line-height: 1.6;
|
||||
}
|
||||
|
||||
/* Capabilities */
|
||||
.cap-section {
|
||||
padding: 64px 0;
|
||||
border-bottom: 1px solid var(--line);
|
||||
}
|
||||
|
||||
.cap-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fit, minmax(155px, 1fr));
|
||||
gap: 16px;
|
||||
}
|
||||
|
||||
.cap-card {
|
||||
background: var(--panel);
|
||||
border: 1px solid var(--line);
|
||||
border-radius: 8px;
|
||||
padding: 20px;
|
||||
transition: box-shadow 0.15s;
|
||||
}
|
||||
|
||||
.cap-card:hover {
|
||||
box-shadow: 0 4px 16px rgba(15,118,110,0.1);
|
||||
}
|
||||
|
||||
.cap-label {
|
||||
display: inline-block;
|
||||
background: var(--soft-teal);
|
||||
color: var(--teal-dark);
|
||||
font-size: 0.72rem;
|
||||
font-weight: 700;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.06em;
|
||||
border-radius: 999px;
|
||||
padding: 3px 10px;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.cap-card h3 {
|
||||
margin: 0 0 6px;
|
||||
font-size: 0.95rem;
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
.cap-card p {
|
||||
margin: 0;
|
||||
color: var(--muted);
|
||||
font-size: 0.85rem;
|
||||
line-height: 1.55;
|
||||
}
|
||||
|
||||
/* Evidence trail explainer */
|
||||
.evidence-section {
|
||||
padding: 64px 0;
|
||||
background: var(--panel);
|
||||
border-bottom: 1px solid var(--line);
|
||||
}
|
||||
|
||||
.evidence-inner {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 1fr;
|
||||
gap: 48px;
|
||||
align-items: start;
|
||||
}
|
||||
|
||||
.evidence-copy h2 {
|
||||
margin: 0 0 14px;
|
||||
font-size: 1.5rem;
|
||||
font-weight: 800;
|
||||
}
|
||||
|
||||
.evidence-copy p {
|
||||
color: var(--muted);
|
||||
line-height: 1.7;
|
||||
margin: 0 0 18px;
|
||||
}
|
||||
|
||||
.evidence-list {
|
||||
margin: 0;
|
||||
padding-left: 20px;
|
||||
color: var(--muted);
|
||||
font-size: 0.9rem;
|
||||
line-height: 1.8;
|
||||
}
|
||||
|
||||
.evidence-mock {
|
||||
background: var(--bg);
|
||||
border: 1px solid var(--line);
|
||||
border-radius: 8px;
|
||||
padding: 20px;
|
||||
}
|
||||
|
||||
.mock-label {
|
||||
margin: 0 0 16px;
|
||||
font-size: 0.72rem;
|
||||
font-weight: 700;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.06em;
|
||||
color: var(--teal);
|
||||
}
|
||||
|
||||
.mock-step {
|
||||
display: flex;
|
||||
gap: 12px;
|
||||
margin-bottom: 14px;
|
||||
padding-bottom: 14px;
|
||||
border-bottom: 1px solid var(--line);
|
||||
font-size: 0.85rem;
|
||||
}
|
||||
|
||||
.mock-step:last-child {
|
||||
border-bottom: 0;
|
||||
margin-bottom: 0;
|
||||
padding-bottom: 0;
|
||||
}
|
||||
|
||||
.mock-step p {
|
||||
margin: 3px 0 0;
|
||||
color: var(--muted);
|
||||
font-size: 0.82rem;
|
||||
}
|
||||
|
||||
.mock-dot {
|
||||
width: 10px;
|
||||
height: 10px;
|
||||
border-radius: 50%;
|
||||
background: var(--teal);
|
||||
flex-shrink: 0;
|
||||
margin-top: 4px;
|
||||
}
|
||||
|
||||
.mock-dot--amber {
|
||||
background: var(--amber);
|
||||
}
|
||||
|
||||
.mock-done .mock-dot {
|
||||
background: var(--teal);
|
||||
}
|
||||
|
||||
/* Access / login gate */
|
||||
.access-section {
|
||||
padding: 64px 24px;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
background: var(--bg);
|
||||
}
|
||||
|
||||
/* Showcase footer */
|
||||
.showcase-footer {
|
||||
padding: 32px 24px;
|
||||
text-align: center;
|
||||
border-top: 1px solid var(--line);
|
||||
color: var(--muted);
|
||||
font-size: 0.85rem;
|
||||
}
|
||||
|
||||
.showcase-footer a {
|
||||
color: var(--teal);
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.showcase-footer a:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
.footer-disclaimer {
|
||||
margin: 6px 0 0;
|
||||
font-size: 0.78rem;
|
||||
opacity: 0.7;
|
||||
}
|
||||
|
||||
@media (max-width: 640px) {
|
||||
.showcase-header-inner {
|
||||
flex-direction: column;
|
||||
align-items: flex-start;
|
||||
}
|
||||
|
||||
.evidence-inner {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
|
||||
.cap-grid {
|
||||
grid-template-columns: 1fr 1fr;
|
||||
}
|
||||
}
|
||||
|
||||
/* Source card chunk toggle */
|
||||
.chunk-details {
|
||||
margin-top: 0.625rem;
|
||||
}
|
||||
|
||||
.chunk-toggle {
|
||||
cursor: pointer;
|
||||
font-size: 0.75rem;
|
||||
font-weight: 600;
|
||||
color: var(--teal);
|
||||
user-select: none;
|
||||
list-style: none;
|
||||
}
|
||||
|
||||
.chunk-toggle::-webkit-details-marker {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.chunk-details[open] .chunk-toggle {
|
||||
color: var(--teal-dark);
|
||||
}
|
||||
|
||||
.chunk-text {
|
||||
margin-top: 0.5rem;
|
||||
font-size: 0.7rem;
|
||||
line-height: 1.55;
|
||||
background: #f0fdf9;
|
||||
border: 1px solid #ccfbf1;
|
||||
border-radius: 6px;
|
||||
padding: 0.625rem 0.75rem;
|
||||
white-space: pre-wrap;
|
||||
overflow-x: auto;
|
||||
color: #374151;
|
||||
}
|
||||
|
||||
+10
-1
@@ -60,7 +60,7 @@ const els = {};
|
||||
|
||||
document.addEventListener('DOMContentLoaded', () => {
|
||||
Object.assign(els, {
|
||||
gate: document.querySelector('#passcodeGate'),
|
||||
gate: document.querySelector('#publicLanding'),
|
||||
app: document.querySelector('#appShell'),
|
||||
passcodeForm: document.querySelector('#passcodeForm'),
|
||||
loginEmail: document.querySelector('#loginEmail'),
|
||||
@@ -291,17 +291,26 @@ function renderEvidence(data) {
|
||||
function renderEvidenceItem(item) {
|
||||
const title = item.title || item.citation || 'Source';
|
||||
const body = item.excerpt || item.why_it_matters || item.citation || '';
|
||||
const chunkText = item.chunk_text || '';
|
||||
const meta = [
|
||||
item.package_or_corpus,
|
||||
item.section,
|
||||
item.score !== undefined && item.score !== null ? `score ${item.score}` : '',
|
||||
].filter(Boolean).join(' · ');
|
||||
|
||||
const chunkToggle = (chunkText && chunkText !== body) ? `
|
||||
<details class="chunk-details">
|
||||
<summary class="chunk-toggle">View chunk</summary>
|
||||
<pre class="chunk-text">${escapeHtml(chunkText)}</pre>
|
||||
</details>
|
||||
` : '';
|
||||
|
||||
return `
|
||||
<article class="source-card">
|
||||
<h4>${escapeHtml(title)}</h4>
|
||||
${meta ? `<p class="source-meta">${escapeHtml(meta)}</p>` : ''}
|
||||
<p>${escapeHtml(body)}</p>
|
||||
${chunkToggle}
|
||||
</article>
|
||||
`;
|
||||
}
|
||||
|
||||
+47
-10
@@ -70,7 +70,23 @@ final class DbnLegalToolsService
|
||||
}
|
||||
}
|
||||
|
||||
$hits = array_map(fn(array $chunk): array => $this->sourceFromChunk($chunk), array_slice($chunks, 0, $limit));
|
||||
$sharedDocIds = [];
|
||||
foreach (array_slice($chunks, 0, $limit) as $chunk) {
|
||||
if (($chunk['source_type'] ?? '') !== 'private' && isset($chunk['document_id'])) {
|
||||
$sharedDocIds[(int)$chunk['document_id']] = true;
|
||||
}
|
||||
}
|
||||
$docSummaries = $sharedDocIds ? $this->fetchDocSummaries(array_keys($sharedDocIds)) : [];
|
||||
|
||||
$hits = array_map(
|
||||
fn(array $chunk): array => $this->sourceFromChunk(
|
||||
$chunk,
|
||||
($chunk['source_type'] ?? '') !== 'private'
|
||||
? ($docSummaries[(int)($chunk['document_id'] ?? 0)] ?? null)
|
||||
: null
|
||||
),
|
||||
array_slice($chunks, 0, $limit)
|
||||
);
|
||||
$confidence = $this->citationConfidence($hits);
|
||||
|
||||
$trace[1] = $this->trace('Search tools used', $retrievalNote . '; returned ' . count($hits) . ' source hit(s).', 'complete');
|
||||
@@ -461,23 +477,44 @@ PROMPT;
|
||||
return array_values(array_filter($trail, 'is_array'));
|
||||
}
|
||||
|
||||
private function sourceFromChunk(array $chunk): array
|
||||
private function sourceFromChunk(array $chunk, ?string $docSummary = null): array
|
||||
{
|
||||
$title = (string)($chunk['document_title'] ?? $chunk['title'] ?? 'Untitled source');
|
||||
$score = isset($chunk['similarity']) ? round((float)$chunk['similarity'], 4) : null;
|
||||
$rawExcerpt = dbnToolsExcerpt((string)($chunk['content'] ?? ''), 620);
|
||||
return [
|
||||
'title' => $title,
|
||||
'excerpt' => dbnToolsExcerpt((string)($chunk['content'] ?? ''), 620),
|
||||
'title' => $title,
|
||||
'excerpt' => $docSummary ?? $rawExcerpt,
|
||||
'chunk_text' => $rawExcerpt,
|
||||
'package_or_corpus' => (string)($chunk['source_name'] ?? $chunk['source_type'] ?? 'Do Better Norge'),
|
||||
'score' => $score,
|
||||
'document_id' => isset($chunk['document_id']) ? (int)$chunk['document_id'] : null,
|
||||
'chunk_id' => isset($chunk['id']) ? (int)$chunk['id'] : null,
|
||||
'section' => $chunk['section_title'] ?? null,
|
||||
'authority_type' => $chunk['authority_type'] ?? null,
|
||||
'jurisdiction' => $chunk['jurisdiction'] ?? null,
|
||||
'score' => $score,
|
||||
'document_id' => isset($chunk['document_id']) ? (int)$chunk['document_id'] : null,
|
||||
'chunk_id' => isset($chunk['id']) ? (int)$chunk['id'] : null,
|
||||
'section' => $chunk['section_title'] ?? null,
|
||||
'authority_type' => $chunk['authority_type'] ?? null,
|
||||
'jurisdiction' => $chunk['jurisdiction'] ?? null,
|
||||
];
|
||||
}
|
||||
|
||||
private function fetchDocSummaries(array $docIds): array
|
||||
{
|
||||
if (!$docIds) {
|
||||
return [];
|
||||
}
|
||||
try {
|
||||
$db = dbnToolsRagDb();
|
||||
$placeholders = implode(',', array_fill(0, count($docIds), '?'));
|
||||
$stmt = $db->prepare(
|
||||
"SELECT document_id, summary FROM doc_summaries
|
||||
WHERE document_id IN ({$placeholders}) AND summary != ''"
|
||||
);
|
||||
$stmt->execute(array_values($docIds));
|
||||
return array_column($stmt->fetchAll(PDO::FETCH_ASSOC), 'summary', 'document_id');
|
||||
} catch (Throwable) {
|
||||
return [];
|
||||
}
|
||||
}
|
||||
|
||||
private function citationConfidence(array $hits): string
|
||||
{
|
||||
if (!$hits) {
|
||||
|
||||
@@ -9,35 +9,147 @@ $authenticated = dbnToolsIsAuthenticated();
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<title>Do Better Norge Legal Tools</title>
|
||||
<meta name="description" content="Do Better Norge legal preparation tools with source-grounded evidence trails.">
|
||||
<meta name="robots" content="noindex,nofollow">
|
||||
<link rel="canonical" href="https://tools.dobetternorge.no/">
|
||||
<meta property="og:title" content="Do Better Norge Legal Tools">
|
||||
<meta property="og:description" content="Legal preparation tools with visible evidence trails and uncertainty notes.">
|
||||
<title>Do Better Norge — AI Legal Research</title>
|
||||
<meta name="description" content="AI-powered family law research for Norway. Source-cited answers from curated legal corpora, with a post-generation reviewer pass. Powered by CaveauAI.">
|
||||
<meta name="robots" content="index, follow">
|
||||
<link rel="canonical" href="https://ai.dobetternorge.no/">
|
||||
<meta property="og:title" content="Do Better Norge — AI Legal Research">
|
||||
<meta property="og:description" content="Source-cited answers from curated Norwegian law corpora. Every claim checked against real sources before it reaches you.">
|
||||
<meta property="og:type" content="website">
|
||||
<meta property="og:url" content="https://tools.dobetternorge.no/">
|
||||
<meta property="og:url" content="https://ai.dobetternorge.no/">
|
||||
<meta name="theme-color" content="#f7f8fb">
|
||||
<link rel="stylesheet" href="assets/css/tools.css">
|
||||
</head>
|
||||
<body data-authenticated="<?= $authenticated ? 'true' : 'false' ?>">
|
||||
<section id="passcodeGate" class="gate<?= $authenticated ? ' is-hidden' : '' ?>" aria-labelledby="gateTitle">
|
||||
<div class="gate-panel">
|
||||
<p class="eyebrow">Do Better Norge</p>
|
||||
<h1 id="gateTitle">Legal Tools</h1>
|
||||
<p class="gate-copy">Legal information and preparation support, not final legal advice.</p>
|
||||
<form id="passcodeForm" class="passcode-form">
|
||||
<label for="loginEmail">Email</label>
|
||||
<input id="loginEmail" name="email" type="email" autocomplete="username email" required>
|
||||
<label for="loginPassword">Password</label>
|
||||
<div class="passcode-row">
|
||||
<input id="loginPassword" name="password" type="password" autocomplete="current-password" required>
|
||||
<button type="submit">Sign in</button>
|
||||
<div id="publicLanding" class="showcase-page<?= $authenticated ? ' is-hidden' : '' ?>">
|
||||
|
||||
<header class="showcase-header">
|
||||
<div class="showcase-header-inner">
|
||||
<div class="showcase-brand">
|
||||
<p class="eyebrow">Do Better Norge</p>
|
||||
<h1 class="showcase-title">AI Legal Research</h1>
|
||||
<p class="showcase-tagline">Source-cited answers from curated Norwegian law corpora</p>
|
||||
<a href="https://caveauai.bluenotelogic.com/" class="powered-badge" rel="noopener" target="_blank">Powered by CaveauAI</a>
|
||||
</div>
|
||||
<p id="gateStatus" class="form-status" role="status" aria-live="polite"></p>
|
||||
</form>
|
||||
</div>
|
||||
</section>
|
||||
<a href="#access" class="cta-button">Access Legal Tools →</a>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<section class="hiw-section">
|
||||
<div class="section-inner">
|
||||
<h2 class="section-heading">How it works</h2>
|
||||
<p class="section-sub">From question to reviewed, cited answer in three steps</p>
|
||||
<div class="hiw-steps">
|
||||
<div class="hiw-step">
|
||||
<div class="hiw-num">01</div>
|
||||
<h3>Curated legal corpus</h3>
|
||||
<p>Norwegian family law, ECHR rulings, and Lovdata sources are indexed, chunked, and embedded by CaveauAI’s ingestion pipeline.</p>
|
||||
</div>
|
||||
<div class="hiw-step">
|
||||
<div class="hiw-num">02</div>
|
||||
<h3>Hybrid retrieval</h3>
|
||||
<p>Your question triggers vector similarity search and keyword retrieval — sources are scored, re-ranked, and presented as a labelled evidence trail.</p>
|
||||
</div>
|
||||
<div class="hiw-step">
|
||||
<div class="hiw-num">03</div>
|
||||
<h3>Reviewed, cited answer</h3>
|
||||
<p>A post-generation reviewer checks every claim against retrieved sources before the answer reaches you. Citations are attached to real corpus documents.</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section class="cap-section">
|
||||
<div class="section-inner">
|
||||
<h2 class="section-heading">Five tools, one corpus</h2>
|
||||
<div class="cap-grid">
|
||||
<div class="cap-card">
|
||||
<span class="cap-label">Ask</span>
|
||||
<h3>Ask</h3>
|
||||
<p>Source-grounded legal questions with citations and explicit uncertainty notes.</p>
|
||||
</div>
|
||||
<div class="cap-card">
|
||||
<span class="cap-label">Search</span>
|
||||
<h3>Search</h3>
|
||||
<p>Retrieve up to seven relevant legal sources with titles, sections, and excerpts.</p>
|
||||
</div>
|
||||
<div class="cap-card">
|
||||
<span class="cap-label">Summarize</span>
|
||||
<h3>Summarize</h3>
|
||||
<p>Extract facts, dates, parties, and legal references from pasted text.</p>
|
||||
</div>
|
||||
<div class="cap-card">
|
||||
<span class="cap-label">Timeline</span>
|
||||
<h3>Timeline</h3>
|
||||
<p>Build a chronological event sequence from case notes or documents.</p>
|
||||
</div>
|
||||
<div class="cap-card">
|
||||
<span class="cap-label">Redact</span>
|
||||
<h3>Redact</h3>
|
||||
<p>Remove sensitive personal data with configurable Nordic / ECHR / Global profiles.</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section class="evidence-section">
|
||||
<div class="section-inner evidence-inner">
|
||||
<div class="evidence-copy">
|
||||
<h2>Every answer shows its work</h2>
|
||||
<p>Alongside each answer, the evidence trail shows which sources were retrieved, how they scored, which claims they support, and what remains uncertain. The legal reviewer pass checks all claims against the corpus before the answer is returned.</p>
|
||||
<ul class="evidence-list">
|
||||
<li>Source document, section, and authority type</li>
|
||||
<li>Similarity score per retrieved chunk</li>
|
||||
<li>Reviewer decision: approved / revised / insufficient support</li>
|
||||
<li>Explicit uncertainty statement when the corpus can’t support a claim</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="evidence-mock" aria-hidden="true">
|
||||
<p class="mock-label">Evidence Trail</p>
|
||||
<div class="mock-step mock-done">
|
||||
<span class="mock-dot"></span>
|
||||
<div><strong>Query interpreted</strong><p>Barneloven §42 custody arrangements</p></div>
|
||||
</div>
|
||||
<div class="mock-step mock-done">
|
||||
<span class="mock-dot"></span>
|
||||
<div><strong>3 sources retrieved</strong><p>Barneloven, ECHR Johansen v. Norway, Ot.prp. nr. 56</p></div>
|
||||
</div>
|
||||
<div class="mock-step mock-done">
|
||||
<span class="mock-dot"></span>
|
||||
<div><strong>Reviewer: approved</strong><p>All claims supported by corpus sources</p></div>
|
||||
</div>
|
||||
<div class="mock-step">
|
||||
<span class="mock-dot mock-dot--amber"></span>
|
||||
<div><strong>Uncertainty noted</strong><p>Recent amendments after 2024 may not be indexed</p></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section id="access" class="access-section" aria-labelledby="accessTitle">
|
||||
<div class="gate-panel">
|
||||
<p class="eyebrow">Do Better Norge</p>
|
||||
<h2 id="accessTitle">Access Legal Tools</h2>
|
||||
<p class="gate-copy">Legal information and preparation support, not final legal advice.</p>
|
||||
<form id="passcodeForm" class="passcode-form">
|
||||
<label for="loginEmail">Email</label>
|
||||
<input id="loginEmail" name="email" type="email" autocomplete="username email" required>
|
||||
<label for="loginPassword">Password</label>
|
||||
<div class="passcode-row">
|
||||
<input id="loginPassword" name="password" type="password" autocomplete="current-password" required>
|
||||
<button type="submit">Sign in</button>
|
||||
</div>
|
||||
<p id="gateStatus" class="form-status" role="status" aria-live="polite"></p>
|
||||
</form>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<footer class="showcase-footer">
|
||||
<p>Do Better Norge · Built with <a href="https://caveauai.bluenotelogic.com/" rel="noopener" target="_blank">CaveauAI</a> by Blue Note Logic</p>
|
||||
<p class="footer-disclaimer">Legal information and preparation support, not final legal advice. Not a substitute for professional legal counsel.</p>
|
||||
</footer>
|
||||
|
||||
</div>
|
||||
|
||||
<main id="appShell" class="app-shell<?= $authenticated ? '' : ' is-hidden' ?>">
|
||||
<header class="topbar">
|
||||
|
||||
Reference in New Issue
Block a user