9b22947eb2
Pass 1: deterministic regex with Nordic/European/ECHR/Global packs covering fødselsnummer, Swedish personnummer, Danish/Finnish CPR, UK NI, French INSEE, IBAN, EU phones, ECHR application numbers, DOB, and national ID label patterns. Pass 2: LLM semantic scan (Azure OpenAI) finds names, orgs, places and identifying descriptions missed by regex. Runs on pre-redacted text so no raw PII reaches the LLM. Adds region selector (Nordic/European/ECHR/Global) to the Redact UI. Falls back gracefully when Azure is not yet configured. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
150 lines
7.3 KiB
PHP
150 lines
7.3 KiB
PHP
<?php
|
|
declare(strict_types=1);
|
|
|
|
require_once __DIR__ . '/includes/bootstrap.php';
|
|
$authenticated = dbnToolsIsAuthenticated();
|
|
?>
|
|
<!doctype html>
|
|
<html lang="en">
|
|
<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.com/">
|
|
<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.">
|
|
<meta property="og:type" content="website">
|
|
<meta property="og:url" content="https://tools.dobetternorge.com/">
|
|
<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>
|
|
<p id="gateStatus" class="form-status" role="status" aria-live="polite"></p>
|
|
</form>
|
|
</div>
|
|
</section>
|
|
|
|
<main id="appShell" class="app-shell<?= $authenticated ? '' : ' is-hidden' ?>">
|
|
<header class="topbar">
|
|
<div>
|
|
<p class="eyebrow">Do Better Norge</p>
|
|
<h1>Legal Tools Hub</h1>
|
|
</div>
|
|
<div class="topbar-actions">
|
|
<span id="healthPill" class="status-pill">Session active</span>
|
|
<button id="healthButton" class="secondary-button" type="button">Health</button>
|
|
</div>
|
|
</header>
|
|
|
|
<div class="disclaimer" role="note">
|
|
Legal information and preparation support, not final legal advice. Pasted text is processed in memory by default.
|
|
</div>
|
|
|
|
<section class="workspace" aria-label="Legal tools workspace">
|
|
<nav class="tool-rail" aria-label="Tools">
|
|
<button type="button" class="tool-tab is-active" data-tool="ask" aria-pressed="true">
|
|
<span>Ask</span>
|
|
<small>Source-grounded</small>
|
|
</button>
|
|
<button type="button" class="tool-tab" data-tool="search" aria-pressed="false">
|
|
<span>Search</span>
|
|
<small>Legal sources</small>
|
|
</button>
|
|
<button type="button" class="tool-tab" data-tool="summarize" aria-pressed="false">
|
|
<span>Summarize</span>
|
|
<small>Pasted text</small>
|
|
</button>
|
|
<button type="button" class="tool-tab" data-tool="timeline" aria-pressed="false">
|
|
<span>Timeline</span>
|
|
<small>Events</small>
|
|
</button>
|
|
<button type="button" class="tool-tab" data-tool="redact" aria-pressed="false">
|
|
<span>Redact</span>
|
|
<small>Privacy</small>
|
|
</button>
|
|
</nav>
|
|
|
|
<section class="tool-panel" aria-labelledby="toolTitle">
|
|
<div class="tool-heading">
|
|
<div>
|
|
<p id="toolKind" class="eyebrow">Source-grounded Legal Ask</p>
|
|
<h2 id="toolTitle">Ask a legal question</h2>
|
|
</div>
|
|
<span id="toolBadge" class="tool-badge">family-legal</span>
|
|
</div>
|
|
|
|
<form id="toolForm" class="tool-form">
|
|
<div class="control-row" id="languageControl">
|
|
<span class="control-label">Language</span>
|
|
<label><input type="radio" name="language" value="en" checked> English</label>
|
|
<label><input type="radio" name="language" value="no"> Norsk</label>
|
|
</div>
|
|
|
|
<div class="control-row is-hidden" id="redactionControl">
|
|
<span class="control-label">Mode</span>
|
|
<label><input type="radio" name="redactionMode" value="standard" checked> Standard</label>
|
|
<label><input type="radio" name="redactionMode" value="strict"> Strict</label>
|
|
<span class="control-label" style="margin-left:1.25rem">Region</span>
|
|
<label><input type="radio" name="redactionRegion" value="nordic" checked> Nordic</label>
|
|
<label><input type="radio" name="redactionRegion" value="european"> European</label>
|
|
<label><input type="radio" name="redactionRegion" value="echr"> ECHR</label>
|
|
<label><input type="radio" name="redactionRegion" value="global"> Global</label>
|
|
</div>
|
|
|
|
<label class="input-label" for="toolInput" id="inputLabel">Question</label>
|
|
<textarea id="toolInput" name="toolInput" rows="10" required></textarea>
|
|
|
|
<div class="form-footer">
|
|
<p id="toolStatus" class="form-status" role="status" aria-live="polite"></p>
|
|
<button id="runButton" type="submit">Run Tool</button>
|
|
</div>
|
|
</form>
|
|
|
|
<section id="results" class="results" aria-live="polite">
|
|
<div class="empty-state">
|
|
<h3>Ready</h3>
|
|
<p>Choose a tool, run a request, and the answer will show the evidence trail beside it.</p>
|
|
</div>
|
|
</section>
|
|
</section>
|
|
|
|
<aside class="reasoning-panel" aria-labelledby="reasoningTitle">
|
|
<div class="reasoning-head">
|
|
<p class="eyebrow">Evidence trail</p>
|
|
<h2 id="reasoningTitle">Reasoning</h2>
|
|
</div>
|
|
<ol id="traceList" class="trace-list">
|
|
<li>
|
|
<span class="trace-status waiting"></span>
|
|
<div>
|
|
<strong>Waiting</strong>
|
|
<p>Run a tool to see interpretation, retrieval, confidence, uncertainty, and next step.</p>
|
|
</div>
|
|
</li>
|
|
</ol>
|
|
</aside>
|
|
</section>
|
|
</main>
|
|
|
|
<script>
|
|
window.DBN_TOOLS_AUTHENTICATED = <?= $authenticated ? 'true' : 'false' ?>;
|
|
</script>
|
|
<script src="assets/js/tools.js" defer></script>
|
|
</body>
|
|
</html>
|