Apply Do Better Norge tools brand redesign (CSS + all tool pages)

New dbn-tools-redesign.css with warm paper surface, navy tools nav, gold
accent, and per-tool themes via body[data-active-tool]. Updated all 21 tool
PHP pages, shared layout/nav/footer includes, and advocate route (new).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-05-24 11:26:39 +02:00
parent c997f204b5
commit e09ee62c62
60 changed files with 2583 additions and 6 deletions
+1
View File
@@ -71,6 +71,7 @@ if ($detail) {
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin> <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Crimson+Pro:wght@400;600;700&family=IBM+Plex+Sans:wght@400;500;600;700&display=swap"> <link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Crimson+Pro:wght@400;600;700&family=IBM+Plex+Sans:wght@400;500;600;700&display=swap">
<link rel="stylesheet" href="assets/css/tools.css"> <link rel="stylesheet" href="assets/css/tools.css">
<link rel="stylesheet" href="assets/css/dbn-tools-redesign.css">
</head> </head>
<body data-authenticated="true" class="lt-app"> <body data-authenticated="true" class="lt-app">
<script> <script>
+281
View File
@@ -0,0 +1,281 @@
<?php
declare(strict_types=1);
require_once __DIR__ . '/includes/bootstrap.php';
$uiLang = dbnToolsCurrentLanguage();
$isAuthed = dbnToolsIsAuthenticated();
$langPath = '/advocate-about.php';
$toolsLogin = 'https://dobetternorge.no/tools-login.php?return=' . urlencode('/advocate.php');
$registerUrl = 'https://dobetternorge.no/register.php';
$ctaUrl = $isAuthed ? '/advocate.php' : $toolsLogin;
$_pt = require __DIR__ . '/translations/advocate-about.php';
$t = $_pt[$uiLang] ?? $_pt['en'];
?>
<!doctype html>
<html lang="<?= htmlspecialchars($uiLang) ?>">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Advocate — AI partisan briefs for child-welfare cases · Do Better Norge Tools</title>
<meta name="description" content="Advocate uses Hard-RAG and a fine-tuned legal LLM to generate partisan briefs for child-welfare cases — grounded in Lovdata, ECHR HUDOC, and Bufdir guidance, always arguing for your selected party.">
<meta name="robots" content="index, follow">
<link rel="canonical" href="https://tools.dobetternorge.no/advocate-about.php">
<meta property="og:title" content="Advocate — AI partisan briefs for child-welfare cases">
<meta property="og:description" content="Select your party role and get an adversarial brief grounded in 220,000+ Norwegian legal passages. Covers barneloven, barnevernsloven, and ECHR Art. 8.">
<meta property="og:type" content="website">
<meta name="theme-color" content="#00205B">
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Crimson+Pro:wght@400;600;700&family=IBM+Plex+Sans:wght@400;500;600;700&display=swap">
<link rel="stylesheet" href="assets/css/tools.css">
<link rel="stylesheet" href="assets/css/dbn-tools-redesign.css">
</head>
<body class="kdoc-page">
<header class="lt-nav">
<a href="https://dobetternorge.no" class="lt-nav__brand">
<picture>
<source srcset="assets/images/logo-header.webp" type="image/webp">
<img class="lt-nav__logo" src="assets/images/logo-header.png" alt="Do Better Norge" width="140" height="36" loading="eager">
</picture>
<span class="lt-nav__badge">Legal Tools</span>
</a>
<div class="lt-nav__right">
<nav class="shell-lang-switcher" aria-label="Language">
<?php foreach (dbnToolsSupportedLanguages() as $langCode): ?>
<a href="<?= htmlspecialchars($langPath . '?lang=' . $langCode) ?>" class="<?= $langCode === $uiLang ? 'is-active' : '' ?>"><?= htmlspecialchars(dbnToolsLanguageLabel($langCode)) ?></a>
<?php endforeach; ?>
</nav>
<?php if ($isAuthed): ?>
<a href="/advocate.php" class="lt-nav__cta lt-nav__cta--enter"><?= htmlspecialchars($t['nav_open']) ?></a>
<?php else: ?>
<a href="<?= htmlspecialchars($toolsLogin) ?>" class="lt-nav__cta"><?= htmlspecialchars($t['nav_signin']) ?></a>
<?php endif; ?>
</div>
</header>
<nav class="kdoc-doc-nav" aria-label="Advocate documentation">
<div class="kdoc-doc-nav__inner">
<a href="/advocate-about.php" class="is-active"><?= htmlspecialchars($t['nav_about']) ?></a>
<a href="/advocate-guide.php"><?= htmlspecialchars($t['nav_guide']) ?></a>
<a href="/advocate-tech.php"><?= htmlspecialchars($t['nav_howit']) ?></a>
<?php if ($isAuthed): ?>
<a href="/advocate.php"><?= htmlspecialchars($t['nav_opentool']) ?></a>
<?php endif; ?>
</div>
</nav>
<!-- Hero -->
<section class="kdoc-hero" style="background: linear-gradient(rgba(0,20,60,0.82),rgba(0,20,60,0.88)), url('assets/images/advocate/hero-marketing.png') center/cover no-repeat;">
<div class="kdoc-hero__inner">
<p class="kdoc-hero__kicker"><?= htmlspecialchars($t['hero_kicker']) ?></p>
<h1 class="kdoc-hero__title"><?= htmlspecialchars($t['hero_title']) ?></h1>
<p class="kdoc-hero__sub"><?= htmlspecialchars($t['hero_sub']) ?></p>
<div class="kdoc-hero__stats">
<div class="kdoc-hero__stat">
<strong>220K+</strong>
<span><?= htmlspecialchars($t['stat_legal']) ?></span>
</div>
<div class="kdoc-hero__stat">
<strong>9</strong>
<span><?= htmlspecialchars($t['stat_roles']) ?></span>
</div>
<div class="kdoc-hero__stat">
<strong>8</strong>
<span><?= htmlspecialchars($t['stat_slices']) ?></span>
</div>
<div class="kdoc-hero__stat">
<strong>7</strong>
<span><?= htmlspecialchars($t['stat_pipeline']) ?></span>
</div>
</div>
<div class="kdoc-hero__ctas">
<a href="<?= htmlspecialchars($ctaUrl) ?>" class="kdoc-btn-primary"><?= htmlspecialchars($t['btn_try']) ?></a>
<a href="/advocate-guide.php" class="kdoc-btn-secondary"><?= htmlspecialchars($t['btn_guide']) ?></a>
<a href="/advocate-tech.php" class="kdoc-btn-secondary"><?= htmlspecialchars($t['btn_howit']) ?></a>
</div>
</div>
</section>
<!-- What you get -->
<section class="kdoc-section--alt">
<div class="kdoc-section">
<p class="kdoc-section__eyebrow"><?= htmlspecialchars($t['what_eyebrow']) ?></p>
<h2 class="kdoc-section__title"><?= htmlspecialchars($t['what_title']) ?></h2>
<div class="kdoc-features">
<div class="kdoc-feature-card">
<span class="kdoc-feature-card__icon">&#9878;&#65039;</span>
<h3 class="kdoc-feature-card__title"><?= htmlspecialchars($t['f1_title']) ?></h3>
<p class="kdoc-feature-card__body"><?= htmlspecialchars($t['f1_body']) ?></p>
</div>
<div class="kdoc-feature-card">
<span class="kdoc-feature-card__icon">&#128220;</span>
<h3 class="kdoc-feature-card__title"><?= htmlspecialchars($t['f2_title']) ?></h3>
<p class="kdoc-feature-card__body"><?= htmlspecialchars($t['f2_body']) ?></p>
</div>
<div class="kdoc-feature-card">
<span class="kdoc-feature-card__icon">&#128196;</span>
<h3 class="kdoc-feature-card__title"><?= htmlspecialchars($t['f3_title']) ?></h3>
<p class="kdoc-feature-card__body"><?= $t['f3_body_html'] ?></p>
</div>
</div>
</div>
</section>
<!-- How it works (3-step) -->
<div class="kdoc-section">
<p class="kdoc-section__eyebrow"><?= htmlspecialchars($t['how_eyebrow']) ?></p>
<h2 class="kdoc-section__title"><?= htmlspecialchars($t['how_title']) ?></h2>
<p class="kdoc-section__sub"><?= htmlspecialchars($t['how_sub']) ?></p>
<div class="kdoc-steps">
<div class="kdoc-step-card">
<span class="kdoc-step-card__num">1</span>
<h3 class="kdoc-step-card__title"><?= htmlspecialchars($t['s1_title']) ?></h3>
<p class="kdoc-step-card__body"><?= htmlspecialchars($t['s1_body']) ?></p>
<p class="kdoc-step-card__example"><?= htmlspecialchars($t['s1_example']) ?></p>
<img src="assets/images/advocate/role-selector.png" alt="Role selector dropdown showing 9 party options" class="kdoc-step-card__screenshot" loading="lazy">
</div>
<span class="kdoc-step-arrow" aria-hidden="true">&rarr;</span>
<div class="kdoc-step-card">
<span class="kdoc-step-card__num">2</span>
<h3 class="kdoc-step-card__title"><?= htmlspecialchars($t['s2_title']) ?></h3>
<p class="kdoc-step-card__body"><?= htmlspecialchars($t['s2_body']) ?></p>
<p class="kdoc-step-card__example"><?= htmlspecialchars($t['s2_example']) ?></p>
</div>
<span class="kdoc-step-arrow" aria-hidden="true">&rarr;</span>
<div class="kdoc-step-card">
<span class="kdoc-step-card__num">3</span>
<h3 class="kdoc-step-card__title"><?= htmlspecialchars($t['s3_title']) ?></h3>
<p class="kdoc-step-card__body"><?= $t['s3_body_html'] ?></p>
<p class="kdoc-step-card__example"><?= htmlspecialchars($t['s3_example']) ?></p>
<img src="assets/images/advocate/output-brief.png" alt="Advocate output showing strongest arguments and the partisan brief" class="kdoc-step-card__screenshot" loading="lazy">
</div>
</div>
</div>
<!-- Screenshots -->
<section class="kdoc-section--alt">
<div class="kdoc-section">
<p class="kdoc-section__eyebrow"><?= htmlspecialchars($t['ss_eyebrow']) ?></p>
<h2 class="kdoc-section__title"><?= htmlspecialchars($t['ss_title']) ?></h2>
<div class="kdoc-gallery">
<div class="kdoc-gallery__item">
<img src="assets/images/advocate/form-top.png" alt="Advocate form — role selector, case description, engine, corpus slices" class="kdoc-screenshot" loading="lazy">
<p class="kdoc-gallery__caption"><?= htmlspecialchars($t['g1_caption']) ?></p>
</div>
<div class="kdoc-gallery__item">
<img src="assets/images/advocate/output-brief.png" alt="Advocate output — strongest arguments and partisan brief with citations" class="kdoc-screenshot" loading="lazy">
<p class="kdoc-gallery__caption"><?= htmlspecialchars($t['g2_caption']) ?></p>
</div>
<div class="kdoc-gallery__item">
<img src="assets/images/advocate/sub-questions.png" alt="Sub-question research trail with ECHR and uploaded document sources" class="kdoc-screenshot" loading="lazy">
<p class="kdoc-gallery__caption"><?= htmlspecialchars($t['g3_caption']) ?></p>
</div>
<div class="kdoc-gallery__item">
<img src="assets/images/advocate/output-next.png" alt="Analysis — gaps in opposing position, uncertainties, and next practical step" class="kdoc-screenshot" loading="lazy">
<p class="kdoc-gallery__caption"><?= htmlspecialchars($t['g4_caption']) ?></p>
</div>
</div>
</div>
</section>
<!-- Fine-tuned LLM spotlight -->
<div class="kdoc-section">
<p class="kdoc-section__eyebrow"><?= htmlspecialchars($t['hood_eyebrow']) ?></p>
<h2 class="kdoc-section__title"><?= htmlspecialchars($t['hood_title']) ?></h2>
<div class="kdoc-llm-spotlight">
<div>
<span class="kdoc-llm-spotlight__badge"><?= htmlspecialchars($t['llm_badge']) ?></span>
<h3 class="kdoc-llm-spotlight__title">dbn-legal-agent</h3>
<p class="kdoc-llm-spotlight__body"><?= $t['llm_body_html'] ?></p>
</div>
<div class="kdoc-llm-stats">
<div class="kdoc-llm-stat">
<strong>QLoRA</strong>
<span><?= htmlspecialchars($t['llm_s1']) ?></span>
</div>
<div class="kdoc-llm-stat">
<strong>barnevernsloven</strong>
<span><?= htmlspecialchars($t['llm_s2']) ?></span>
</div>
<div class="kdoc-llm-stat">
<strong>gpt-4o</strong>
<span><?= htmlspecialchars($t['llm_s3']) ?></span>
</div>
<div class="kdoc-llm-stat">
<strong>7-step</strong>
<span><?= htmlspecialchars($t['llm_s4']) ?></span>
</div>
</div>
</div>
</div>
<!-- Party roles coverage -->
<section class="kdoc-section--alt">
<div class="kdoc-section">
<p class="kdoc-section__eyebrow"><?= htmlspecialchars($t['roles_eyebrow']) ?></p>
<h2 class="kdoc-section__title"><?= htmlspecialchars($t['roles_title']) ?></h2>
<p class="kdoc-section__sub"><?= htmlspecialchars($t['roles_sub']) ?></p>
<div class="kdoc-bodies">
<div class="kdoc-body-card">
<p class="kdoc-body-card__name">Biological mother</p>
<p class="kdoc-body-card__law">barneloven · ECHR Art. 8</p>
</div>
<div class="kdoc-body-card">
<p class="kdoc-body-card__name">Biological father</p>
<p class="kdoc-body-card__law">barneloven · ECHR Art. 8</p>
</div>
<div class="kdoc-body-card">
<p class="kdoc-body-card__name">Both biological parents</p>
<p class="kdoc-body-card__law">barneloven · barnevernsloven</p>
</div>
<div class="kdoc-body-card">
<p class="kdoc-body-card__name">Foster carer / long-term placement</p>
<p class="kdoc-body-card__law">barnevernsloven § 4-19a</p>
</div>
<div class="kdoc-body-card">
<p class="kdoc-body-card__name">Adoptive parent</p>
<p class="kdoc-body-card__law">adopsjonsloven · barnevernsloven</p>
</div>
<div class="kdoc-body-card">
<p class="kdoc-body-card__name">Child (via representative)</p>
<p class="kdoc-body-card__law">barneloven · FNs barnekonvensjon</p>
</div>
<div class="kdoc-body-card">
<p class="kdoc-body-card__name">Extended family</p>
<p class="kdoc-body-card__law">barneloven · ECHR Art. 8</p>
</div>
<div class="kdoc-body-card">
<p class="kdoc-body-card__name">Child welfare services (Barnevernet)</p>
<p class="kdoc-body-card__law">barnevernsloven · fvl</p>
</div>
<div class="kdoc-body-card">
<p class="kdoc-body-card__name">Other</p>
<p class="kdoc-body-card__law">fvl (general)</p>
</div>
</div>
</div>
</section>
<!-- CTA strip -->
<section class="kdoc-cta-strip">
<h2 class="kdoc-cta-strip__title"><?= htmlspecialchars($t['cta_title']) ?></h2>
<p class="kdoc-cta-strip__sub"><?= htmlspecialchars($t['cta_sub']) ?></p>
<div class="kdoc-hero__ctas">
<?php if ($isAuthed): ?>
<a href="/advocate.php" class="kdoc-btn-primary"><?= htmlspecialchars($t['btn_open']) ?></a>
<?php else: ?>
<a href="<?= htmlspecialchars($toolsLogin) ?>" class="kdoc-btn-primary"><?= htmlspecialchars($t['btn_signin_cta']) ?></a>
<a href="<?= htmlspecialchars($registerUrl) ?>" class="kdoc-btn-secondary"><?= htmlspecialchars($t['btn_register']) ?></a>
<?php endif; ?>
</div>
</section>
<?php require_once __DIR__ . '/includes/footer.php'; ?>
<script src="assets/js/tools.js" defer></script>
</body>
</html>
+323
View File
@@ -0,0 +1,323 @@
<?php
declare(strict_types=1);
require_once __DIR__ . '/includes/bootstrap.php';
$uiLang = dbnToolsCurrentLanguage();
$isAuthed = dbnToolsIsAuthenticated();
$langPath = '/advocate-guide.php';
$toolsLogin = 'https://dobetternorge.no/tools-login.php?return=' . urlencode('/advocate.php');
$registerUrl = 'https://dobetternorge.no/register.php';
$ctaUrl = $isAuthed ? '/advocate.php' : $toolsLogin;
$_pt = require __DIR__ . '/translations/advocate-guide.php';
$t = $_pt[$uiLang] ?? $_pt['en'];
?>
<!doctype html>
<html lang="<?= htmlspecialchars($uiLang) ?>">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Advocate User Guide — How to generate partisan legal briefs · Do Better Norge Tools</title>
<meta name="description" content="Step-by-step guide to using Advocate: selecting your party role, configuring corpus slices, uploading case files, and reading the adversarial brief output.">
<meta name="robots" content="index, follow">
<link rel="canonical" href="https://tools.dobetternorge.no/advocate-guide.php">
<meta property="og:title" content="Advocate User Guide — How to generate partisan legal briefs">
<meta property="og:description" content="Learn every Advocate control: role selection, corpus slices, advanced settings, file upload, output panels, and the counter-brief feature.">
<meta property="og:type" content="website">
<meta name="theme-color" content="#00205B">
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Crimson+Pro:wght@400;600;700&family=IBM+Plex+Sans:wght@400;500;600;700&display=swap">
<link rel="stylesheet" href="assets/css/tools.css">
<link rel="stylesheet" href="assets/css/dbn-tools-redesign.css">
</head>
<body class="kdoc-page">
<header class="lt-nav">
<a href="https://dobetternorge.no" class="lt-nav__brand">
<picture>
<source srcset="assets/images/logo-header.webp" type="image/webp">
<img class="lt-nav__logo" src="assets/images/logo-header.png" alt="Do Better Norge" width="140" height="36" loading="eager">
</picture>
<span class="lt-nav__badge">Legal Tools</span>
</a>
<div class="lt-nav__right">
<nav class="shell-lang-switcher" aria-label="Language">
<?php foreach (dbnToolsSupportedLanguages() as $langCode): ?>
<a href="<?= htmlspecialchars($langPath . '?lang=' . $langCode) ?>" class="<?= $langCode === $uiLang ? 'is-active' : '' ?>"><?= htmlspecialchars(dbnToolsLanguageLabel($langCode)) ?></a>
<?php endforeach; ?>
</nav>
<?php if ($isAuthed): ?>
<a href="/advocate.php" class="lt-nav__cta lt-nav__cta--enter"><?= htmlspecialchars($t['nav_open']) ?></a>
<?php else: ?>
<a href="<?= htmlspecialchars($toolsLogin) ?>" class="lt-nav__cta"><?= htmlspecialchars($t['nav_signin']) ?></a>
<?php endif; ?>
</div>
</header>
<nav class="kdoc-doc-nav" aria-label="Advocate documentation">
<div class="kdoc-doc-nav__inner">
<a href="/advocate-about.php"><?= htmlspecialchars($t['nav_about']) ?></a>
<a href="/advocate-guide.php" class="is-active"><?= htmlspecialchars($t['nav_guide']) ?></a>
<a href="/advocate-tech.php"><?= htmlspecialchars($t['nav_howit']) ?></a>
<?php if ($isAuthed): ?>
<a href="/advocate.php"><?= htmlspecialchars($t['nav_opentool']) ?></a>
<?php endif; ?>
</div>
</nav>
<!-- Hero -->
<section class="kdoc-hero" style="background: linear-gradient(rgba(0,20,60,0.78),rgba(0,20,60,0.86)), url('assets/images/advocate/hero-guide.png') center/cover no-repeat;">
<div class="kdoc-hero__inner">
<p class="kdoc-hero__kicker"><?= htmlspecialchars($t['hero_kicker']) ?></p>
<h1 class="kdoc-hero__title"><?= htmlspecialchars($t['hero_title']) ?></h1>
<p class="kdoc-hero__sub"><?= htmlspecialchars($t['hero_sub']) ?></p>
</div>
</section>
<!-- Table of contents -->
<div class="kdoc-section">
<p class="kdoc-section__eyebrow"><?= htmlspecialchars($t['toc_title']) ?></p>
<nav class="kdoc-toc" aria-label="Guide contents">
<a href="#s1"><?= htmlspecialchars($t['s1_head']) ?></a>
<a href="#s2"><?= htmlspecialchars($t['s2_head']) ?></a>
<a href="#s3"><?= htmlspecialchars($t['s3_head']) ?></a>
<a href="#s4"><?= htmlspecialchars($t['s4_head']) ?></a>
<a href="#s5"><?= htmlspecialchars($t['s5_head']) ?></a>
<a href="#s6"><?= htmlspecialchars($t['s6_head']) ?></a>
<a href="#s7"><?= htmlspecialchars($t['s7_head']) ?></a>
<a href="#s8"><?= htmlspecialchars($t['s8_head']) ?></a>
<a href="#s9"><?= htmlspecialchars($t['s9_head']) ?></a>
<a href="#s10"><?= htmlspecialchars($t['s10_head']) ?></a>
<a href="#s11"><?= htmlspecialchars($t['s11_head']) ?></a>
</nav>
</div>
<!-- Step 1: Language -->
<section class="kdoc-section--alt" id="s1">
<div class="kdoc-section">
<h2 class="kdoc-guide-step__title"><?= htmlspecialchars($t['s1_title']) ?></h2>
<p class="kdoc-guide-step__body"><?= htmlspecialchars($t['s1_body']) ?></p>
<img src="assets/images/advocate/form-top.png" alt="Advocate form top showing language pills, role selector, and engine options" class="kdoc-screenshot" loading="lazy">
</div>
</section>
<!-- Step 2: Role -->
<div class="kdoc-section" id="s2">
<h2 class="kdoc-guide-step__title"><?= htmlspecialchars($t['s2_title']) ?></h2>
<p class="kdoc-guide-step__body"><?= htmlspecialchars($t['s2_body']) ?></p>
<div class="kdoc-table-wrap">
<table class="kdoc-table">
<thead>
<tr>
<th><?= htmlspecialchars($t['s2_table_col1']) ?></th>
<th><?= htmlspecialchars($t['s2_table_col2']) ?></th>
<th><?= htmlspecialchars($t['s2_table_col3']) ?></th>
</tr>
</thead>
<tbody>
<tr><td>Biological mother</td><td>barneloven · ECHR Art. 8</td><td>Opposing or challenging care orders, contact restrictions</td></tr>
<tr><td>Biological father</td><td>barneloven · ECHR Art. 8</td><td>Contact rights, parental involvement, procedural challenges</td></tr>
<tr><td>Both biological parents</td><td>barneloven · barnevernsloven</td><td>Joint challenge to omsorgsovertakelse or placement decisions</td></tr>
<tr><td>Foster carer / long-term placement</td><td>barnevernsloven § 4-19a</td><td>Opposing reunification or arguing for continued placement</td></tr>
<tr><td>Adoptive parent</td><td>adopsjonsloven · barnevernsloven</td><td>Adoption approval challenges, post-adoption contact disputes</td></tr>
<tr><td>Child (via representative)</td><td>barneloven · FNs barnekonvensjon</td><td>Child's independent interests — <em>barnets beste</em> arguments</td></tr>
<tr><td>Extended family</td><td>barneloven · ECHR Art. 8</td><td>Grandparent/sibling contact or kinship placement claims</td></tr>
<tr><td>Child welfare services (Barnevernet)</td><td>barnevernsloven · fvl</td><td>Defending care orders, justifying interventions</td></tr>
<tr><td>Other</td><td>fvl (general)</td><td>Describe in the custom text field — agent adapts framing</td></tr>
</tbody>
</table>
</div>
<img src="assets/images/advocate/role-selector.png" alt="Role selector dropdown open showing all 9 party options" class="kdoc-screenshot" loading="lazy">
</div>
<!-- Step 3: Case description -->
<section class="kdoc-section--alt" id="s3">
<div class="kdoc-section">
<h2 class="kdoc-guide-step__title"><?= htmlspecialchars($t['s3_title']) ?></h2>
<p class="kdoc-guide-step__body"><?= htmlspecialchars($t['s3_body']) ?></p>
<p class="kdoc-guide-step__tip"><strong>&#128161;</strong> <?= htmlspecialchars($t['s3_tip']) ?></p>
</div>
</section>
<!-- Step 4: Engine -->
<div class="kdoc-section" id="s4">
<h2 class="kdoc-guide-step__title"><?= htmlspecialchars($t['s4_title']) ?></h2>
<p class="kdoc-guide-step__body"><?= htmlspecialchars($t['s4_body']) ?></p>
<div class="kdoc-table-wrap">
<table class="kdoc-table">
<thead>
<tr>
<th><?= htmlspecialchars($t['s4_table_col1']) ?></th>
<th><?= htmlspecialchars($t['s4_table_col2']) ?></th>
<th><?= htmlspecialchars($t['s4_table_col3']) ?></th>
</tr>
</thead>
<tbody>
<tr><td>Azure gpt-4o-mini ★</td><td>1545 s</td><td>Fast drafts, most cases — default choice</td></tr>
<tr><td>Azure gpt-4o</td><td>60180 s</td><td>Complex multi-party cases requiring maximum depth</td></tr>
<tr><td>GPU (cuttlefish)</td><td>3090 s</td><td>Local inference, no Azure dependency</td></tr>
<tr><td>Norwegian specialist (dbn-legal-agent) &#127475;&#127476;</td><td>4090 s</td><td>Barneloven, barnevernsloven, and ECHR Art. 8 — tighter legal register</td></tr>
</tbody>
</table>
</div>
</div>
<!-- Step 5: Corpus slices -->
<section class="kdoc-section--alt" id="s5">
<div class="kdoc-section">
<h2 class="kdoc-guide-step__title"><?= htmlspecialchars($t['s5_title']) ?></h2>
<p class="kdoc-guide-step__body"><?= htmlspecialchars($t['s5_body']) ?></p>
<div class="kdoc-table-wrap">
<table class="kdoc-table">
<thead>
<tr>
<th><?= htmlspecialchars($t['s5_table_col1']) ?></th>
<th><?= htmlspecialchars($t['s5_table_col2']) ?></th>
<th><?= htmlspecialchars($t['s5_table_col3']) ?></th>
<th><?= htmlspecialchars($t['s5_table_col4']) ?></th>
</tr>
</thead>
<tbody>
<tr><td><strong>Family Law Core</strong></td><td>ON</td><td>Barneloven, custody, samvær, mediation</td><td>Always — core for all cases</td></tr>
<tr><td><strong>Child Welfare</strong></td><td>ON</td><td>Barnevern, omsorgsovertakelse, foster care</td><td>Always — core for all cases</td></tr>
<tr><td><strong>ECHR</strong></td><td>ON</td><td>Art. 8 family life, Art. 9 religion, HUDOC vs Norway</td><td>Always — ECHR Art. 8 is central to most cases</td></tr>
<tr><td>Hague Convention</td><td>OFF</td><td>INCADAT, cross-border abduction, wrongful removal</td><td>International child-abduction / relocation cases</td></tr>
<tr><td>Norwegian Courts</td><td>OFF</td><td>Høyesterett + Lagmannsrett family decisions</td><td>When domestic appellate precedent is key</td></tr>
<tr><td>Bufdir Guidance</td><td>OFF</td><td>Bufdir, Barneombudet, Statsforvalteren guidance</td><td>Cases involving procedural compliance by authorities</td></tr>
<tr><td>Broader Legal Support</td><td>OFF</td><td>Arbeidsmiljøloven, NOUers, statutes, government background</td><td>Cases with employment, housing, or welfare angles</td></tr>
<tr><td>DBN Resources</td><td>OFF</td><td>Do Better Norge guides, flashcards, resource directory</td><td>Supplement with lay-accessible DBN materials</td></tr>
</tbody>
</table>
</div>
<img src="assets/images/advocate/corpus-slices.png" alt="8 corpus slice toggles with ON/OFF state and upload zone" class="kdoc-screenshot" loading="lazy">
</div>
</section>
<!-- Step 6: Advanced controls -->
<div class="kdoc-section" id="s6">
<h2 class="kdoc-guide-step__title"><?= htmlspecialchars($t['s6_title']) ?></h2>
<p class="kdoc-guide-step__body"><?= htmlspecialchars($t['s6_body']) ?></p>
<div class="kdoc-table-wrap">
<table class="kdoc-table">
<thead>
<tr>
<th><?= htmlspecialchars($t['s6_table_col1']) ?></th>
<th><?= htmlspecialchars($t['s6_table_col2']) ?></th>
<th><?= htmlspecialchars($t['s6_table_col3']) ?></th>
<th><?= htmlspecialchars($t['s6_table_col4']) ?></th>
</tr>
</thead>
<tbody>
<tr><td><strong>Sub-questions</strong></td><td>3 5</td><td>4</td><td>Adversarial research angles generated per case. More = broader coverage, slower.</td></tr>
<tr><td><strong>Chunks / sub-Q</strong></td><td>4 10</td><td>6</td><td>Corpus passages retrieved per sub-question before reranking.</td></tr>
<tr><td><strong>Similarity floor</strong></td><td>0.20 0.60</td><td>0.30</td><td>Minimum similarity score for uploaded-doc chunks to be included.</td></tr>
<tr><td><strong>Sources kept</strong></td><td>8 14</td><td>12</td><td>Top sources passed to synthesis after dedup and rerank.</td></tr>
<tr><td><strong>Temperature</strong></td><td>0.05 0.40</td><td>0.15</td><td>Keep low (≤ 0.20) for grounded legal briefs; raise slightly for more creative framing.</td></tr>
</tbody>
</table>
</div>
<img src="assets/images/advocate/advanced-controls.png" alt="Advanced controls sliders and branching panel" class="kdoc-screenshot" loading="lazy">
</div>
<!-- Step 7: Upload -->
<section class="kdoc-section--alt" id="s7">
<div class="kdoc-section">
<h2 class="kdoc-guide-step__title"><?= htmlspecialchars($t['s7_title']) ?></h2>
<p class="kdoc-guide-step__body"><?= htmlspecialchars($t['s7_body']) ?></p>
<p class="kdoc-guide-step__tip"><strong>&#128161;</strong> <?= htmlspecialchars($t['s7_tip']) ?></p>
</div>
</section>
<!-- Step 8: Preview angles -->
<div class="kdoc-section" id="s8">
<h2 class="kdoc-guide-step__title"><?= htmlspecialchars($t['s8_title']) ?></h2>
<p class="kdoc-guide-step__body"><?= htmlspecialchars($t['s8_body']) ?></p>
<p class="kdoc-guide-step__tip"><strong>&#128161;</strong> <?= htmlspecialchars($t['s8_tip']) ?></p>
</div>
<!-- Step 9: Understanding output -->
<section class="kdoc-section--alt" id="s9">
<div class="kdoc-section">
<h2 class="kdoc-guide-step__title"><?= htmlspecialchars($t['s9_title']) ?></h2>
<p class="kdoc-guide-step__body"><?= htmlspecialchars($t['s9_body']) ?></p>
<div class="kdoc-output-panels">
<div class="kdoc-output-panel">
<h3 class="kdoc-output-panel__title"><?= htmlspecialchars($t['s9_p1_title']) ?></h3>
<p><?= htmlspecialchars($t['s9_p1_body']) ?></p>
</div>
<div class="kdoc-output-panel">
<h3 class="kdoc-output-panel__title"><?= htmlspecialchars($t['s9_p2_title']) ?></h3>
<p><?= htmlspecialchars($t['s9_p2_body']) ?></p>
</div>
<div class="kdoc-output-panel">
<h3 class="kdoc-output-panel__title"><?= htmlspecialchars($t['s9_p3_title']) ?></h3>
<p><?= htmlspecialchars($t['s9_p3_body']) ?></p>
</div>
<div class="kdoc-output-panel">
<h3 class="kdoc-output-panel__title"><?= htmlspecialchars($t['s9_p4_title']) ?></h3>
<p><?= htmlspecialchars($t['s9_p4_body']) ?></p>
</div>
</div>
<div class="kdoc-gallery">
<div class="kdoc-gallery__item">
<img src="assets/images/advocate/output-brief.png" alt="Output — strongest arguments and advocate brief with citations" class="kdoc-screenshot" loading="lazy">
</div>
<div class="kdoc-gallery__item">
<img src="assets/images/advocate/sub-questions.png" alt="Sub-question research trail with ECHR and uploaded document sources" class="kdoc-screenshot" loading="lazy">
</div>
</div>
</div>
</section>
<!-- Step 10: Counter-brief -->
<div class="kdoc-section" id="s10">
<h2 class="kdoc-guide-step__title"><?= htmlspecialchars($t['s10_title']) ?></h2>
<p class="kdoc-guide-step__body"><?= htmlspecialchars($t['s10_body']) ?></p>
<img src="assets/images/advocate/output-next.png" alt="What remains uncertain, next practical step, and counter-brief prompt" class="kdoc-screenshot" loading="lazy">
</div>
<!-- Step 11: Tips -->
<section class="kdoc-section--alt" id="s11">
<div class="kdoc-section">
<h2 class="kdoc-guide-step__title"><?= htmlspecialchars($t['s11_title']) ?></h2>
<ul class="kdoc-tips">
<li><?= htmlspecialchars($t['tip1']) ?></li>
<li><?= htmlspecialchars($t['tip2']) ?></li>
<li><?= htmlspecialchars($t['tip3']) ?></li>
<li><?= htmlspecialchars($t['tip4']) ?></li>
<li><?= htmlspecialchars($t['tip5']) ?></li>
<li><?= htmlspecialchars($t['tip6']) ?></li>
</ul>
</div>
</section>
<!-- Reasoning pipeline screenshot -->
<div class="kdoc-section">
<p class="kdoc-section__eyebrow">Under the hood</p>
<h2 class="kdoc-section__title">The 7-step reasoning pipeline — visible as it runs.</h2>
<p class="kdoc-section__sub">Every step from query interpretation to citation confidence is logged in the Reasoning panel in real time. Nothing is hidden.</p>
<img src="assets/images/advocate/reasoning-pipeline.png" alt="7-step reasoning panel showing pipeline steps completing in sequence" class="kdoc-screenshot" loading="lazy">
<p style="text-align:center;margin-top:1rem;"><a href="/advocate-tech.php" class="kdoc-inline-link">Read the full architecture →</a></p>
</div>
<!-- CTA strip -->
<section class="kdoc-cta-strip">
<h2 class="kdoc-cta-strip__title"><?= htmlspecialchars($t['cta_title']) ?></h2>
<p class="kdoc-cta-strip__sub"><?= htmlspecialchars($t['cta_sub']) ?></p>
<div class="kdoc-hero__ctas">
<?php if ($isAuthed): ?>
<a href="/advocate.php" class="kdoc-btn-primary"><?= htmlspecialchars($t['btn_open']) ?></a>
<?php else: ?>
<a href="<?= htmlspecialchars($toolsLogin) ?>" class="kdoc-btn-primary"><?= htmlspecialchars($t['btn_signin_cta']) ?></a>
<a href="<?= htmlspecialchars($registerUrl) ?>" class="kdoc-btn-secondary"><?= htmlspecialchars($t['btn_register']) ?></a>
<?php endif; ?>
</div>
</section>
<?php require_once __DIR__ . '/includes/footer.php'; ?>
<script src="assets/js/tools.js" defer></script>
</body>
</html>
+300
View File
@@ -0,0 +1,300 @@
<?php
declare(strict_types=1);
require_once __DIR__ . '/includes/bootstrap.php';
$uiLang = dbnToolsCurrentLanguage();
$isAuthed = dbnToolsIsAuthenticated();
$langPath = '/advocate-tech.php';
$toolsLogin = 'https://dobetternorge.no/tools-login.php?return=' . urlencode('/advocate.php');
$registerUrl = 'https://dobetternorge.no/register.php';
$ctaUrl = $isAuthed ? '/advocate.php' : $toolsLogin;
$_pt = require __DIR__ . '/translations/advocate-tech.php';
$t = $_pt[$uiLang] ?? $_pt['en'];
?>
<!doctype html>
<html lang="<?= htmlspecialchars($uiLang) ?>">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Advocate — How it works: Hard-RAG pipeline and fine-tuned LLM · Do Better Norge Tools</title>
<meta name="description" content="Technical deep-dive into Advocate's 7-step pipeline: adversarial query expansion, hybrid Hard-RAG retrieval, dbn-legal-agent synthesis, and citation confidence verification.">
<meta name="robots" content="index, follow">
<link rel="canonical" href="https://tools.dobetternorge.no/advocate-tech.php">
<meta property="og:title" content="Advocate — How it works: Hard-RAG and fine-tuned Norwegian law LLM">
<meta property="og:description" content="7-step pipeline: query expansion, slice resolution, hybrid retrieval with RRF and reranking, dbn-legal-agent synthesis, citation confidence. 220K+ passages indexed.">
<meta property="og:type" content="website">
<meta name="theme-color" content="#00205B">
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Crimson+Pro:wght@400;600;700&family=IBM+Plex+Sans:wght@400;500;600;700&display=swap">
<link rel="stylesheet" href="assets/css/tools.css">
<link rel="stylesheet" href="assets/css/dbn-tools-redesign.css">
</head>
<body class="kdoc-page">
<header class="lt-nav">
<a href="https://dobetternorge.no" class="lt-nav__brand">
<picture>
<source srcset="assets/images/logo-header.webp" type="image/webp">
<img class="lt-nav__logo" src="assets/images/logo-header.png" alt="Do Better Norge" width="140" height="36" loading="eager">
</picture>
<span class="lt-nav__badge">Legal Tools</span>
</a>
<div class="lt-nav__right">
<nav class="shell-lang-switcher" aria-label="Language">
<?php foreach (dbnToolsSupportedLanguages() as $langCode): ?>
<a href="<?= htmlspecialchars($langPath . '?lang=' . $langCode) ?>" class="<?= $langCode === $uiLang ? 'is-active' : '' ?>"><?= htmlspecialchars(dbnToolsLanguageLabel($langCode)) ?></a>
<?php endforeach; ?>
</nav>
<?php if ($isAuthed): ?>
<a href="/advocate.php" class="lt-nav__cta lt-nav__cta--enter"><?= htmlspecialchars($t['nav_open']) ?></a>
<?php else: ?>
<a href="<?= htmlspecialchars($toolsLogin) ?>" class="lt-nav__cta"><?= htmlspecialchars($t['nav_signin']) ?></a>
<?php endif; ?>
</div>
</header>
<nav class="kdoc-doc-nav" aria-label="Advocate documentation">
<div class="kdoc-doc-nav__inner">
<a href="/advocate-about.php"><?= htmlspecialchars($t['nav_about']) ?></a>
<a href="/advocate-guide.php"><?= htmlspecialchars($t['nav_guide']) ?></a>
<a href="/advocate-tech.php" class="is-active"><?= htmlspecialchars($t['nav_howit']) ?></a>
<?php if ($isAuthed): ?>
<a href="/advocate.php"><?= htmlspecialchars($t['nav_opentool']) ?></a>
<?php endif; ?>
</div>
</nav>
<!-- Hero -->
<section class="kdoc-hero" style="background: linear-gradient(rgba(5,15,40,0.85),rgba(5,15,40,0.92)), url('assets/images/advocate/hero-tech.png') center/cover no-repeat;">
<div class="kdoc-hero__inner">
<p class="kdoc-hero__kicker"><?= htmlspecialchars($t['hero_kicker']) ?></p>
<h1 class="kdoc-hero__title"><?= htmlspecialchars($t['hero_title']) ?></h1>
<p class="kdoc-hero__sub"><?= htmlspecialchars($t['hero_sub']) ?></p>
<div class="kdoc-hero__stats">
<div class="kdoc-hero__stat">
<strong>220K+</strong>
<span><?= htmlspecialchars($t['stat_legal']) ?></span>
</div>
<div class="kdoc-hero__stat">
<strong>8</strong>
<span><?= htmlspecialchars($t['stat_slices']) ?></span>
</div>
<div class="kdoc-hero__stat">
<strong>7</strong>
<span><?= htmlspecialchars($t['stat_steps']) ?></span>
</div>
<div class="kdoc-hero__stat">
<strong>dbn</strong>
<span><?= htmlspecialchars($t['stat_model']) ?></span>
</div>
</div>
</div>
</section>
<!-- 7-step pipeline -->
<div class="kdoc-section">
<p class="kdoc-section__eyebrow"><?= htmlspecialchars($t['pipe_eyebrow']) ?></p>
<h2 class="kdoc-section__title"><?= htmlspecialchars($t['pipe_title']) ?></h2>
<p class="kdoc-section__sub"><?= htmlspecialchars($t['pipe_sub']) ?></p>
<div class="kdoc-pipeline">
<div class="kdoc-pipeline__step">
<span class="kdoc-pipeline__num">1</span>
<h3 class="kdoc-pipeline__title"><?= htmlspecialchars($t['step1_title']) ?></h3>
<p class="kdoc-pipeline__body"><?= htmlspecialchars($t['step1_body']) ?></p>
</div>
<span class="kdoc-pipeline__arrow" aria-hidden="true">&#8595;</span>
<div class="kdoc-pipeline__step">
<span class="kdoc-pipeline__num">2</span>
<h3 class="kdoc-pipeline__title"><?= htmlspecialchars($t['step2_title']) ?></h3>
<p class="kdoc-pipeline__body"><?= htmlspecialchars($t['step2_body']) ?></p>
</div>
<span class="kdoc-pipeline__arrow" aria-hidden="true">&#8595;</span>
<div class="kdoc-pipeline__step">
<span class="kdoc-pipeline__num">3</span>
<h3 class="kdoc-pipeline__title"><?= htmlspecialchars($t['step3_title']) ?></h3>
<p class="kdoc-pipeline__body"><?= htmlspecialchars($t['step3_body']) ?></p>
</div>
<span class="kdoc-pipeline__arrow" aria-hidden="true">&#8595;</span>
<div class="kdoc-pipeline__step">
<span class="kdoc-pipeline__num">4</span>
<h3 class="kdoc-pipeline__title"><?= htmlspecialchars($t['step4_title']) ?></h3>
<p class="kdoc-pipeline__body"><?= htmlspecialchars($t['step4_body']) ?></p>
</div>
<span class="kdoc-pipeline__arrow" aria-hidden="true">&#8595;</span>
<div class="kdoc-pipeline__step">
<span class="kdoc-pipeline__num">5</span>
<h3 class="kdoc-pipeline__title"><?= htmlspecialchars($t['step5_title']) ?></h3>
<p class="kdoc-pipeline__body"><?= htmlspecialchars($t['step5_body']) ?></p>
</div>
<span class="kdoc-pipeline__arrow" aria-hidden="true">&#8595;</span>
<div class="kdoc-pipeline__step">
<span class="kdoc-pipeline__num">6</span>
<h3 class="kdoc-pipeline__title"><?= htmlspecialchars($t['step6_title']) ?></h3>
<p class="kdoc-pipeline__body"><?= htmlspecialchars($t['step6_body']) ?></p>
</div>
<span class="kdoc-pipeline__arrow" aria-hidden="true">&#8595;</span>
<div class="kdoc-pipeline__step">
<span class="kdoc-pipeline__num">7</span>
<h3 class="kdoc-pipeline__title"><?= htmlspecialchars($t['step7_title']) ?></h3>
<p class="kdoc-pipeline__body"><?= htmlspecialchars($t['step7_body']) ?></p>
</div>
</div>
<img src="assets/images/advocate/reasoning-pipeline.png" alt="7-step reasoning panel showing query expansion, retrieval, and synthesis completing in sequence" class="kdoc-screenshot" style="margin-top:2rem" loading="lazy">
</div>
<!-- Hard-RAG retrieval -->
<section class="kdoc-section--alt">
<div class="kdoc-section">
<p class="kdoc-section__eyebrow"><?= htmlspecialchars($t['rag_eyebrow']) ?></p>
<h2 class="kdoc-section__title"><?= htmlspecialchars($t['rag_title']) ?></h2>
<p class="kdoc-section__sub"><?= htmlspecialchars($t['rag_sub']) ?></p>
<div class="kdoc-rag-flow">
<div class="kdoc-rag-flow__box"><?= htmlspecialchars($t['rag_step1']) ?></div>
<span class="kdoc-rag-flow__arrow" aria-hidden="true">&darr;</span>
<div class="kdoc-rag-flow__box"><?= htmlspecialchars($t['rag_step2']) ?></div>
<span class="kdoc-rag-flow__arrow" aria-hidden="true">&darr;</span>
<div class="kdoc-rag-flow__box"><?= htmlspecialchars($t['rag_step3']) ?></div>
<span class="kdoc-rag-flow__arrow" aria-hidden="true">&darr;</span>
<div class="kdoc-rag-flow__box"><?= htmlspecialchars($t['rag_step4']) ?></div>
<span class="kdoc-rag-flow__arrow" aria-hidden="true">&darr;</span>
<div class="kdoc-rag-flow__box"><?= htmlspecialchars($t['rag_step5']) ?></div>
<span class="kdoc-rag-flow__arrow" aria-hidden="true">&darr;</span>
<div class="kdoc-rag-flow__box"><?= htmlspecialchars($t['rag_step6']) ?></div>
<span class="kdoc-rag-flow__arrow" aria-hidden="true">&darr;</span>
<div class="kdoc-rag-flow__box"><?= htmlspecialchars($t['rag_step7']) ?></div>
<span class="kdoc-rag-flow__arrow" aria-hidden="true">&darr;</span>
<div class="kdoc-rag-flow__box kdoc-rag-flow__box--final"><?= htmlspecialchars($t['rag_step8']) ?></div>
</div>
<img src="assets/images/advocate/sub-questions.png" alt="Sub-question research trail showing retrieved ECHR cases and uploaded document sources" class="kdoc-screenshot" style="margin-top:2rem" loading="lazy">
</div>
</section>
<!-- Corpus slices -->
<div class="kdoc-section">
<p class="kdoc-section__eyebrow"><?= htmlspecialchars($t['corpus_eyebrow']) ?></p>
<h2 class="kdoc-section__title"><?= htmlspecialchars($t['corpus_title']) ?></h2>
<p class="kdoc-section__sub"><?= htmlspecialchars($t['corpus_sub']) ?></p>
<div class="kdoc-corpus-stats">
<div class="kdoc-corpus-stat"><strong>220K+</strong><span>passages indexed</span></div>
<div class="kdoc-corpus-stat"><strong>8</strong><span>corpus slices</span></div>
<div class="kdoc-corpus-stat"><strong>1,731</strong><span>tribunal decisions</span></div>
<div class="kdoc-corpus-stat"><strong>23+</strong><span>ECHR judgments vs Norway</span></div>
<div class="kdoc-corpus-stat"><strong>nomic-embed</strong><span>embedding model</span></div>
<div class="kdoc-corpus-stat"><strong>Hybrid</strong><span>BM25 + vector search</span></div>
</div>
<div class="kdoc-chips" style="margin-top:1.5rem">
<span class="kdoc-chip">family_core</span>
<span class="kdoc-chip">child_welfare</span>
<span class="kdoc-chip">echr</span>
<span class="kdoc-chip">hague_convention</span>
<span class="kdoc-chip">norwegian_courts</span>
<span class="kdoc-chip">bufdir_guidance</span>
<span class="kdoc-chip">broader_legal</span>
<span class="kdoc-chip">dbn_resources</span>
</div>
<div class="kdoc-table-wrap" style="margin-top:2rem">
<table class="kdoc-table">
<thead>
<tr>
<th>Party role</th>
<th>Recommended slices</th>
</tr>
</thead>
<tbody>
<tr><td>Biological parents</td><td>family_core · child_welfare · echr · norwegian_courts</td></tr>
<tr><td>Foster carer / adoptive parent</td><td>child_welfare · echr · bufdir_guidance</td></tr>
<tr><td>Child (via representative)</td><td>family_core · child_welfare · echr · dbn_resources</td></tr>
<tr><td>Extended family</td><td>family_core · echr · norwegian_courts</td></tr>
<tr><td>Barnevernet</td><td>child_welfare · bufdir_guidance · broader_legal</td></tr>
<tr><td>Cross-border / international</td><td>hague_convention · echr · family_core</td></tr>
</tbody>
</table>
</div>
</div>
<!-- dbn-legal-agent fine-tune -->
<section class="kdoc-section--alt">
<div class="kdoc-section">
<p class="kdoc-section__eyebrow"><?= htmlspecialchars($t['llm_eyebrow']) ?></p>
<h2 class="kdoc-section__title"><?= htmlspecialchars($t['llm_title']) ?></h2>
<div class="kdoc-llm-spotlight">
<div>
<span class="kdoc-llm-spotlight__badge">Fine-tuned model</span>
<h3 class="kdoc-llm-spotlight__title">dbn-legal-agent</h3>
<p class="kdoc-llm-spotlight__body"><?= $t['llm_body_html'] ?></p>
<div class="kdoc-chips" style="margin-top:1rem">
<span class="kdoc-chip">QLoRA</span>
<span class="kdoc-chip">barnevernsloven</span>
<span class="kdoc-chip">barneloven</span>
<span class="kdoc-chip">ECHR Art. 8</span>
<span class="kdoc-chip">child-welfare corpus</span>
<span class="kdoc-chip">gpt-4o co-pipeline</span>
</div>
</div>
</div>
<div class="kdoc-table-wrap" style="margin-top:2rem">
<table class="kdoc-table">
<thead>
<tr>
<th><?= htmlspecialchars($t['llm_table_col1']) ?></th>
<th><?= htmlspecialchars($t['llm_table_col2']) ?></th>
</tr>
</thead>
<tbody>
<tr><td>Query interpretation</td><td>Classifies case type, identifies applicable statute sets</td></tr>
<tr><td>Query expansion</td><td>Generates adversarial sub-questions framed for the selected party</td></tr>
<tr><td>Slice resolution</td><td>Maps case facts to relevant corpus slices</td></tr>
<tr><td>Synthesis — argument structure</td><td>Shapes YOUR STRONGEST ARGUMENTS using child-welfare procedural vocabulary</td></tr>
<tr><td>Synthesis — brief text</td><td>Drafts partisan advocate brief in grounded legal register</td></tr>
<tr><td>Synthesis — gaps + uncertainties</td><td>Identifies weaknesses in opposing position from same retrieval pass</td></tr>
<tr><td>Citation confidence</td><td>Verifies each § number against source passage; flags low-confidence citations</td></tr>
</tbody>
</table>
</div>
</div>
</section>
<!-- Privacy by design -->
<div class="kdoc-section">
<p class="kdoc-section__eyebrow"><?= htmlspecialchars($t['privacy_eyebrow']) ?></p>
<h2 class="kdoc-section__title"><?= htmlspecialchars($t['privacy_title']) ?></h2>
<ul class="kdoc-privacy-list">
<li><?= htmlspecialchars($t['privacy_p1']) ?></li>
<li><?= htmlspecialchars($t['privacy_p2']) ?></li>
<li><?= htmlspecialchars($t['privacy_p3']) ?></li>
<li><?= htmlspecialchars($t['privacy_p4']) ?></li>
<li><?= htmlspecialchars($t['privacy_p5']) ?></li>
<li><?= htmlspecialchars($t['privacy_p6']) ?></li>
</ul>
</div>
<!-- CTA strip -->
<section class="kdoc-cta-strip">
<h2 class="kdoc-cta-strip__title"><?= htmlspecialchars($t['cta_title']) ?></h2>
<p class="kdoc-cta-strip__sub"><?= htmlspecialchars($t['cta_sub']) ?></p>
<div class="kdoc-hero__ctas">
<?php if ($isAuthed): ?>
<a href="/advocate.php" class="kdoc-btn-primary"><?= htmlspecialchars($t['btn_open']) ?></a>
<?php else: ?>
<a href="<?= htmlspecialchars($toolsLogin) ?>" class="kdoc-btn-primary"><?= htmlspecialchars($t['btn_signin_cta']) ?></a>
<a href="<?= htmlspecialchars($registerUrl) ?>" class="kdoc-btn-secondary"><?= htmlspecialchars($t['btn_register']) ?></a>
<?php endif; ?>
</div>
</section>
<?php require_once __DIR__ . '/includes/footer.php'; ?>
<script src="assets/js/tools.js" defer></script>
</body>
</html>
+806
View File
@@ -0,0 +1,806 @@
@import url('https://fonts.googleapis.com/css2?family=Crimson+Pro:wght@400;500;600;700;800&family=IBM+Plex+Sans:wght@400;500;600;700&family=IBM+Plex+Mono:wght@400;500;600&display=swap');
:root {
--dbn-red: #ba0c2f;
--dbn-red-dark: #9a0a26;
--dbn-blue: #00205b;
--dbn-blue-dark: #001540;
--dbn-soft-blue: #003d7a;
--dbn-gold: #f4c542;
--dbn-gold-deep: #b88a2c;
--dbn-paper: #f6f2ea;
--dbn-ivory: #fffaf3;
--dbn-ink: #16130f;
--dbn-muted: #5a544d;
--dbn-line: rgba(22, 19, 15, 0.16);
--dbn-font-display: 'Crimson Pro', Georgia, 'Times New Roman', serif;
--dbn-font-body: 'IBM Plex Sans', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
--dbn-font-mono: 'IBM Plex Mono', ui-monospace, SFMono-Regular, Consolas, monospace;
--dbn-shadow-paper: 0 1px 0 rgba(22, 19, 15, 0.04), 0 12px 32px -22px rgba(0, 32, 91, 0.18);
--dbn-shadow-paper-lg: 0 18px 45px rgba(22, 19, 15, 0.10);
}
html {
scroll-behavior: smooth;
}
body {
background:
linear-gradient(90deg, rgba(0, 32, 91, 0.055) 1px, transparent 1px),
linear-gradient(180deg, rgba(186, 12, 47, 0.04), transparent 38rem),
var(--dbn-paper) !important;
background-size: 44px 44px, auto, auto !important;
color: var(--dbn-ink);
font-family: var(--dbn-font-body);
-webkit-font-smoothing: antialiased;
text-rendering: optimizeLegibility;
}
body.lt-landing {
background: #fff !important;
}
a:focus-visible,
button:focus-visible,
input:focus-visible,
textarea:focus-visible,
select:focus-visible {
outline: 3px solid rgba(244, 197, 66, 0.34);
outline-offset: 3px;
}
.dbn-nav,
.lt-nav {
background: rgba(0, 32, 91, 0.97) !important;
border-bottom: 1px solid rgba(244, 197, 66, 0.34) !important;
box-shadow: 0 8px 24px rgba(0, 15, 40, 0.22) !important;
backdrop-filter: blur(12px);
-webkit-backdrop-filter: blur(12px);
min-height: 64px;
}
.dbn-nav {
padding-inline: clamp(14px, 3vw, 48px);
}
.dbn-nav__brand,
.lt-nav__brand {
align-items: center;
color: #fff;
display: inline-flex;
gap: 14px;
min-width: 0;
text-decoration: none;
}
.dbn-nav__brandmark {
display: none !important;
}
.dbn-nav__brand-logo,
.lt-nav__logo {
background: rgba(255, 255, 255, 0.96);
border-radius: 5px;
box-shadow: 0 4px 16px rgba(0, 0, 0, 0.18);
display: block;
height: 34px;
object-fit: contain;
padding: 3px 7px;
width: auto;
}
.dbn-nav__brand-text {
display: grid;
gap: 1px;
min-width: 0;
}
.dbn-nav__brandname {
color: #fff;
font-family: var(--dbn-font-display);
font-size: 1.08rem;
font-weight: 700;
letter-spacing: 0;
line-height: 1;
}
.dbn-nav__product,
.lt-nav__badge {
color: rgba(244, 197, 66, 0.70);
font-family: var(--dbn-font-mono);
font-size: 0.68rem;
font-weight: 700;
letter-spacing: 0.10em;
line-height: 1;
text-transform: uppercase;
}
.dbn-nav__links {
margin-left: clamp(1rem, 3vw, 2.2rem);
}
.dbn-nav__link,
.dbn-nav__logout,
.dbn-nav__login,
.lt-nav__secondary-link,
.lt-nav__btn-join {
border-radius: 6px;
color: rgba(255, 255, 255, 0.78);
font-family: var(--dbn-font-body);
font-weight: 700;
text-decoration: none;
}
.dbn-nav__link:hover,
.dbn-nav__link.is-active,
.dbn-nav__logout:hover,
.dbn-nav__login:hover,
.lt-nav__secondary-link:hover,
.lt-nav__btn-join:hover {
background: rgba(255, 255, 255, 0.10);
color: #fff;
}
.dbn-nav__panel {
border: 1px solid rgba(22, 19, 15, 0.14);
border-radius: 14px;
box-shadow: var(--dbn-shadow-paper-lg);
overflow: hidden;
}
.dbn-nav__panel-item:hover {
background: var(--dbn-paper);
}
.dbn-nav__panel-badge {
background: rgba(0, 32, 91, 0.09);
border-radius: 6px;
color: var(--dbn-blue);
font-family: var(--dbn-font-mono);
}
.dbn-nav__langs,
.shell-lang-switcher {
background: rgba(255, 255, 255, 0.09);
border: 1px solid rgba(255, 255, 255, 0.16);
border-radius: 8px;
padding: 3px;
}
.dbn-nav__lang,
.shell-lang-switcher a {
border-radius: 6px;
color: rgba(255, 255, 255, 0.72);
font-family: var(--dbn-font-mono);
font-weight: 700;
text-decoration: none;
}
.dbn-nav__lang.is-active,
.dbn-nav__lang:hover,
.shell-lang-switcher a.is-active,
.shell-lang-switcher a:hover {
background: rgba(255, 255, 255, 0.18);
color: #fff;
}
.dbn-nav__login,
.lt-nav__btn-signin,
.lt-nav__cta {
background: var(--dbn-red) !important;
border: 1px solid var(--dbn-red) !important;
border-radius: 999px !important;
box-shadow: 0 6px 20px rgba(186, 12, 47, 0.30);
color: #fff !important;
padding: 0.55rem 1rem;
transition: background 160ms ease, box-shadow 160ms ease, transform 160ms ease;
}
.dbn-nav__login:hover,
.lt-nav__btn-signin:hover,
.lt-nav__cta:hover {
background: var(--dbn-red-dark) !important;
box-shadow: 0 10px 24px rgba(186, 12, 47, 0.38);
transform: translateY(-1px);
}
.app-shell,
.dash-shell,
.dashboard-shell {
max-width: 1500px;
padding: clamp(18px, 3vw, 34px);
}
.manifesto,
.dashboard-manifesto {
background:
radial-gradient(circle at 0 0, rgba(186, 12, 47, 0.16), transparent 28rem),
linear-gradient(120deg, rgba(255, 255, 255, 0.82), rgba(255, 255, 255, 0.50)) !important;
border: 1px solid rgba(22, 19, 15, 0.17) !important;
border-radius: 8px !important;
box-shadow: var(--dbn-shadow-paper);
overflow: hidden;
}
.manifesto-title,
.dash-main__head h1,
.tool-heading h2,
.lt-hero__title,
.lt-tools__title,
.kdoc-hero__title {
color: var(--dbn-blue);
font-family: var(--dbn-font-display);
letter-spacing: 0 !important;
}
.manifesto-title {
line-height: 0.96;
}
.manifesto-eyebrow,
.eyebrow,
.lt-hero__kicker,
.lt-tools__eyebrow,
.lt-card__badge,
.kdoc-hero__kicker,
.control-label,
.tool-badge {
font-family: var(--dbn-font-mono) !important;
letter-spacing: 0.10em;
text-transform: uppercase;
}
.manifesto-eyebrow,
.eyebrow,
.lt-tools__eyebrow,
.kdoc-hero__kicker {
color: var(--dbn-red) !important;
}
.manifesto-stat strong {
color: var(--dbn-blue);
font-family: var(--dbn-font-display);
}
.disclaimer,
.guest-banner,
.status-card {
background: rgba(255, 250, 243, 0.86) !important;
border: 1px solid rgba(22, 19, 15, 0.14) !important;
border-left: 4px solid var(--dbn-red) !important;
border-radius: 8px !important;
box-shadow: var(--dbn-shadow-paper);
color: var(--dbn-muted);
}
.workspace {
gap: clamp(14px, 2vw, 22px);
grid-template-columns: minmax(190px, 230px) minmax(0, 1fr) minmax(290px, 360px);
}
.tool-rail,
.tool-panel,
.reasoning-panel,
.dash-sidebar,
.dash-main,
.dashboard-tool-card,
.lt-card,
.lt-gate__card,
.lt-trust__item,
.kdoc-card,
.kdoc-step-card,
.kdoc-section,
.kdoc-screenshot,
.pricing-card {
background: rgba(255, 255, 255, 0.92) !important;
border: 1px solid rgba(22, 19, 15, 0.15) !important;
border-radius: 8px !important;
box-shadow: var(--dbn-shadow-paper) !important;
}
.tool-panel {
position: relative;
overflow: hidden;
}
.tool-panel::before {
background: var(--tool-accent, var(--dbn-red));
content: '';
display: block;
height: 5px;
inset: 0 0 auto;
position: absolute;
}
.tool-heading {
border-bottom: 1px solid rgba(22, 19, 15, 0.12);
padding-top: 0.4rem;
}
.tool-badge {
background: rgba(0, 32, 91, 0.08);
border: 1px solid rgba(0, 32, 91, 0.12);
border-radius: 999px;
color: var(--dbn-blue);
max-width: 100%;
overflow-wrap: anywhere;
white-space: normal;
}
.tool-tab,
.dash-sidebar__item {
border-radius: 7px;
color: var(--dbn-ink);
text-decoration: none;
transition: background 150ms ease, border-color 150ms ease, color 150ms ease, transform 150ms ease;
}
.tool-tab:hover,
.tool-tab.is-active,
.dash-sidebar__item:hover,
.dash-sidebar__item.is-active {
background: var(--dbn-ivory);
color: var(--dbn-blue);
transform: translateX(3px);
}
.tool-tab.is-active,
.dash-sidebar__item.is-active {
border-left: 4px solid var(--tool-accent, var(--dbn-red));
}
.tool-tab em,
.dashboard-tool-card__icon {
background: rgba(0, 32, 91, 0.08);
border-radius: 6px;
color: var(--dbn-blue);
font-family: var(--dbn-font-mono);
font-style: normal;
font-weight: 800;
}
.tool-form,
.results,
.deep-research-results {
color: var(--dbn-ink);
}
.control-row,
.dr-control-card,
.adv-role-row,
.doc-picker-section,
.advanced-panel,
.expert-field,
.branch-panel {
background: rgba(255, 250, 243, 0.52);
border: 1px solid rgba(22, 19, 15, 0.12);
border-radius: 8px;
}
.control-row,
.adv-role-row {
padding: 12px 14px;
}
.control-label {
color: var(--dbn-blue) !important;
font-size: 0.76rem;
font-weight: 800;
}
input,
textarea,
select,
.adv-role-select,
.tf-input,
.tf-select,
.tf-area {
background: #fff !important;
border: 1px solid rgba(22, 19, 15, 0.18) !important;
border-radius: 8px !important;
color: var(--dbn-ink) !important;
font-family: var(--dbn-font-body) !important;
}
input:focus,
textarea:focus,
select:focus,
.adv-role-select:focus {
border-color: rgba(0, 32, 91, 0.45) !important;
box-shadow: 0 0 0 4px rgba(0, 32, 91, 0.10) !important;
outline: 0 !important;
}
.upload-zone,
.tf-upload {
background:
linear-gradient(90deg, rgba(0, 32, 91, 0.04) 1px, transparent 1px),
rgba(255, 255, 255, 0.72) !important;
background-size: 28px 28px, auto !important;
border: 2px dashed rgba(0, 32, 91, 0.22) !important;
border-radius: 12px !important;
}
.upload-zone:hover,
.tf-upload:hover {
background-color: #fff !important;
border-color: var(--tool-accent, var(--dbn-red)) !important;
}
.form-footer button,
.primary-button,
.doc-picker-btn,
.adv-preview-btn,
.korr-chip,
.lt-card__arrow,
.dashboard-tool-card strong {
border-radius: 6px;
font-family: var(--dbn-font-body);
font-weight: 800;
}
.form-footer button,
.primary-button,
.doc-picker-dialog__confirm {
background: var(--tool-accent, var(--dbn-red)) !important;
border-color: var(--tool-accent, var(--dbn-red)) !important;
box-shadow: 0 6px 20px rgba(186, 12, 47, 0.18);
color: #fff !important;
}
.form-footer button:hover,
.primary-button:hover,
.doc-picker-dialog__confirm:hover {
filter: brightness(0.92);
transform: translateY(-1px);
}
.results,
.deep-research-results {
background:
linear-gradient(180deg, rgba(255, 255, 255, 0.96), rgba(255, 250, 243, 0.84)) !important;
border: 1px solid rgba(22, 19, 15, 0.13) !important;
border-radius: 8px !important;
}
.empty-state h3 {
color: var(--dbn-blue);
font-family: var(--dbn-font-display);
}
body[data-active-tool='workbench'] { --tool-accent: var(--dbn-blue); }
body[data-active-tool='transcribe'] { --tool-accent: #0f766e; }
body[data-active-tool='timeline'] { --tool-accent: #b88a2c; }
body[data-active-tool='redact'] { --tool-accent: #111827; }
body[data-active-tool='summarize'] { --tool-accent: #7c2d12; }
body[data-active-tool='legal-analysis'] { --tool-accent: var(--dbn-blue); }
body[data-active-tool='korrespond'] { --tool-accent: var(--dbn-red); }
body[data-active-tool='barnevernet'] { --tool-accent: #92400e; }
body[data-active-tool='advocate'] { --tool-accent: #4b5563; }
body[data-active-tool='deep-research'] { --tool-accent: #0f766e; }
body[data-active-tool='discrepancy'] { --tool-accent: #7f1d1d; }
body[data-active-tool='corpus'] { --tool-accent: var(--dbn-blue); }
body[data-active-tool='citations'] { --tool-accent: var(--dbn-gold-deep); }
body[data-active-tool='translate'] { --tool-accent: #1d4ed8; }
.workbench-page .topbar,
.workbench-hero,
.workbench-panel {
background: rgba(255, 255, 255, 0.92) !important;
border: 1px solid rgba(22, 19, 15, 0.15) !important;
border-radius: 8px !important;
box-shadow: var(--dbn-shadow-paper) !important;
}
.workbench-page .topbar {
align-items: center;
border-bottom: 1px solid rgba(22, 19, 15, 0.15) !important;
margin-bottom: 14px;
padding: clamp(16px, 3vw, 26px);
}
.workbench-page .topbar h1,
.workbench-hero h2,
.workbench-panel h2 {
color: var(--dbn-blue);
font-family: var(--dbn-font-display);
letter-spacing: 0 !important;
}
.workbench-hero {
display: grid;
gap: 18px;
grid-template-columns: minmax(0, 1.1fr) minmax(280px, 0.75fr);
overflow: hidden;
padding: clamp(22px, 4vw, 38px);
position: relative;
}
.workbench-hero::before {
background: var(--dbn-red);
content: '';
inset: 0 auto 0 0;
position: absolute;
width: 5px;
}
.workbench-hero__panel {
background:
linear-gradient(135deg, rgba(0, 32, 91, 0.10), rgba(255, 250, 243, 0.80));
border: 1px solid rgba(0, 32, 91, 0.14);
border-radius: 8px;
padding: 18px;
}
.workbench-kicker {
color: var(--dbn-red);
font-family: var(--dbn-font-mono);
font-size: 0.74rem;
font-weight: 800;
letter-spacing: 0.11em;
text-transform: uppercase;
}
.workbench-grid {
gap: 14px;
}
.workbench-panel {
overflow: hidden;
padding: clamp(18px, 3vw, 28px) !important;
position: relative;
}
.workbench-panel::before {
background: var(--dbn-red);
content: '';
height: 5px;
inset: 0 0 auto;
position: absolute;
}
.workbench-section-head {
border-bottom: 1px solid rgba(22, 19, 15, 0.11);
margin-bottom: 16px;
padding-bottom: 12px;
}
.workbench-field span,
.workbench-check span {
color: var(--dbn-blue);
font-weight: 800;
}
.workbench-clear,
.workbench-dashboard-link,
.status-pill {
border-radius: 999px !important;
font-family: var(--dbn-font-body);
font-weight: 800;
}
.workbench-clear {
background: var(--dbn-red) !important;
border: 1px solid var(--dbn-red) !important;
color: #fff !important;
}
@media (max-width: 900px) {
.workbench-hero {
grid-template-columns: 1fr;
}
}
body[data-active-tool='transcribe'] .results {
background:
linear-gradient(180deg, rgba(1, 22, 39, 0.04), rgba(255, 255, 255, 0.94)),
repeating-linear-gradient(90deg, transparent 0 18px, rgba(15, 118, 110, 0.08) 18px 20px) !important;
}
body[data-active-tool='timeline'] .results {
background:
linear-gradient(90deg, rgba(184, 138, 44, 0.14) 1px, transparent 1px),
linear-gradient(#fff, #fffaf3) !important;
background-size: 34px 34px, auto !important;
}
body[data-active-tool='redact'] .results {
background:
repeating-linear-gradient(180deg, #fff 0 27px, rgba(17, 24, 39, 0.06) 27px 28px) !important;
}
body[data-active-tool='korrespond'] .results,
body[data-active-tool='translate'] .results {
background:
linear-gradient(90deg, rgba(186, 12, 47, 0.20) 0 4px, transparent 4px),
repeating-linear-gradient(180deg, #fff 0 31px, rgba(0, 32, 91, 0.06) 31px 32px) !important;
}
body[data-active-tool='barnevernet'] .results {
background:
linear-gradient(135deg, rgba(146, 64, 14, 0.12), transparent 44%),
#f8edcf !important;
}
body[data-active-tool='advocate'] .results,
body[data-active-tool='legal-analysis'] .results {
border: 3px double rgba(0, 32, 91, 0.32) !important;
}
body[data-active-tool='deep-research'] .results {
background:
linear-gradient(90deg, rgba(15, 118, 110, 0.10) 1px, transparent 1px),
#fff !important;
background-size: 36px 36px, auto !important;
}
body[data-active-tool='discrepancy'] .results {
background:
linear-gradient(90deg, rgba(186, 12, 47, 0.08), rgba(15, 118, 110, 0.08)),
#fff !important;
}
body[data-active-tool='corpus'] .results {
background:
linear-gradient(90deg, rgba(0, 32, 91, 0.05) 1px, transparent 1px),
linear-gradient(180deg, #fff, #fffaf3) !important;
background-size: 42px 42px, auto !important;
}
body[data-active-tool='citations'] .results {
background:
radial-gradient(circle at 50% 45%, rgba(244, 197, 66, 0.20), transparent 18rem),
linear-gradient(90deg, rgba(0, 32, 91, 0.055) 1px, transparent 1px),
#fff !important;
background-size: auto, 38px 38px, auto !important;
}
.lt-hero {
background:
radial-gradient(ellipse 80% 65% at 50% 0%, rgba(186, 12, 47, 0.26), transparent),
linear-gradient(148deg, var(--dbn-blue-dark), var(--dbn-blue) 58%, #180010) !important;
}
.lt-hero__title,
.lt-hero__body {
color: #fff;
}
.lt-hero__kicker,
.lt-hero__stat strong {
color: var(--dbn-gold) !important;
}
.lt-card:hover,
.dashboard-tool-card:hover,
.lt-gate__card:hover {
border-color: rgba(186, 12, 47, 0.26) !important;
box-shadow: var(--dbn-shadow-paper-lg) !important;
transform: translateY(-5px);
}
.lt-card__title,
.dashboard-tool-card h2,
.lt-gate__card-title,
.kdoc-section h2,
.pricing-card h2 {
color: var(--dbn-blue);
font-family: var(--dbn-font-display);
}
.dashboard-tool-card {
position: relative;
}
.dashboard-tool-card::before,
.lt-card::before {
background: var(--dbn-red);
content: '';
height: 100%;
left: 0;
position: absolute;
top: 0;
width: 4px;
}
.lt-footer {
background:
radial-gradient(circle at 14% 0%, rgba(186, 12, 47, 0.32), transparent 24rem),
linear-gradient(135deg, var(--dbn-blue-dark), var(--dbn-soft-blue)) !important;
color: rgba(255, 255, 255, 0.86);
}
.lt-footer a {
color: rgba(255, 255, 255, 0.84);
}
.lt-footer a:hover {
color: #fff;
}
.lt-footer__logo {
background: rgba(255, 255, 255, 0.96);
border-radius: 5px;
padding: 4px 7px;
}
.kdoc-page {
background:
linear-gradient(90deg, rgba(0, 32, 91, 0.055) 1px, transparent 1px),
var(--dbn-paper) !important;
background-size: 44px 44px, auto !important;
}
.kdoc-hero {
border-bottom: 4px solid var(--dbn-gold);
}
@media (max-width: 1180px) {
.workspace {
grid-template-columns: 1fr;
width: 100%;
}
.tool-rail,
.reasoning-panel {
position: static;
}
.tool-rail {
display: grid !important;
grid-template-columns: repeat(auto-fit, minmax(142px, 1fr));
max-height: none !important;
max-width: 100%;
overflow: visible !important;
width: 100%;
}
.tool-tab {
min-width: 0;
width: 100%;
}
.tool-tab span,
.tool-tab small,
.tool-tab em {
min-width: 0;
overflow-wrap: anywhere;
}
}
@media (max-width: 860px) {
.dbn-nav,
.lt-nav {
align-items: flex-start;
flex-wrap: wrap;
height: auto;
padding-block: 10px;
}
.dbn-nav__links,
.dbn-nav__right,
.lt-nav__right {
flex-wrap: wrap;
margin-left: 0;
width: 100%;
}
.dbn-nav__brandname {
font-size: 0.98rem;
}
.tool-heading {
align-items: flex-start;
flex-direction: column;
}
}
@media (prefers-reduced-motion: reduce) {
*,
*::before,
*::after {
animation-duration: 0.001ms !important;
scroll-behavior: auto !important;
transition-duration: 0.001ms !important;
}
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 57 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 70 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 66 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 97 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 34 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 44 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 82 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 85 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 197 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 434 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 43 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 267 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 32 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 366 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 161 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 97 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 118 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 140 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 133 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 267 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 32 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 883 KiB

+1
View File
@@ -57,6 +57,7 @@ $status = (string)($_GET['status'] ?? '');
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin> <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Crimson+Pro:wght@400;600;700&family=IBM+Plex+Sans:wght@400;500;600;700&display=swap"> <link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Crimson+Pro:wght@400;600;700&family=IBM+Plex+Sans:wght@400;500;600;700&display=swap">
<link rel="stylesheet" href="assets/css/tools.css"> <link rel="stylesheet" href="assets/css/tools.css">
<link rel="stylesheet" href="assets/css/dbn-tools-redesign.css">
<style> <style>
.billing-shell { max-width: 1000px; margin: 0 auto; padding: 2rem 1.5rem 4rem; } .billing-shell { max-width: 1000px; margin: 0 auto; padding: 2rem 1.5rem 4rem; }
.billing-shell h1 { font-family: 'Crimson Pro', serif; margin: 0 0 0.5rem; } .billing-shell h1 { font-family: 'Crimson Pro', serif; margin: 0 0 0.5rem; }
+2
View File
@@ -27,6 +27,7 @@ if (!$result) {
<meta charset="utf-8"><title>Ikke funnet — Min Sak</title> <meta charset="utf-8"><title>Ikke funnet — Min Sak</title>
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Crimson+Pro:wght@400;700&family=IBM+Plex+Sans:wght@400;500;600&display=swap"> <link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Crimson+Pro:wght@400;700&family=IBM+Plex+Sans:wght@400;500;600&display=swap">
<link rel="stylesheet" href="assets/css/tools.css"> <link rel="stylesheet" href="assets/css/tools.css">
<link rel="stylesheet" href="assets/css/dbn-tools-redesign.css">
</head><body><main style="max-width:720px;margin:4rem auto;padding:0 1.5rem;text-align:center;font-family:'IBM Plex Sans',sans-serif;"> </head><body><main style="max-width:720px;margin:4rem auto;padding:0 1.5rem;text-align:center;font-family:'IBM Plex Sans',sans-serif;">
<h1 style="font-family:'Crimson Pro',serif;color:#00205B;">Analysen finnes ikke</h1> <h1 style="font-family:'Crimson Pro',serif;color:#00205B;">Analysen finnes ikke</h1>
<p>Den lagrede analysen ble ikke funnet, eller du har ikke tilgang til den.</p> <p>Den lagrede analysen ble ikke funnet, eller du har ikke tilgang til den.</p>
@@ -101,6 +102,7 @@ function crField(string $label, string $value): string {
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin> <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Crimson+Pro:wght@400;700&family=IBM+Plex+Sans:wght@400;500;600;700&family=JetBrains+Mono:wght@400;500&display=swap"> <link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Crimson+Pro:wght@400;700&family=IBM+Plex+Sans:wght@400;500;600;700&family=JetBrains+Mono:wght@400;500&display=swap">
<link rel="stylesheet" href="assets/css/tools.css"> <link rel="stylesheet" href="assets/css/tools.css">
<link rel="stylesheet" href="assets/css/dbn-tools-redesign.css">
<style> <style>
.cr-shell { max-width: 980px; margin: 0 auto; padding: 2rem 1.5rem 4rem; font-family: 'IBM Plex Sans', sans-serif; } .cr-shell { max-width: 980px; margin: 0 auto; padding: 2rem 1.5rem 4rem; font-family: 'IBM Plex Sans', sans-serif; }
.cr-header { display: flex; align-items: flex-start; gap: 1rem; margin-bottom: 1.25rem; } .cr-header { display: flex; align-items: flex-start; gap: 1rem; margin-bottom: 1.25rem; }
+1
View File
@@ -40,6 +40,7 @@ require_once __DIR__ . '/includes/tool-svgs.php';
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin> <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Crimson+Pro:wght@400;600;700&family=IBM+Plex+Sans:wght@400;500;600;700&display=swap"> <link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Crimson+Pro:wght@400;600;700&family=IBM+Plex+Sans:wght@400;500;600;700&display=swap">
<link rel="stylesheet" href="assets/css/tools.css"> <link rel="stylesheet" href="assets/css/tools.css">
<link rel="stylesheet" href="assets/css/dbn-tools-redesign.css">
</head> </head>
<body data-authenticated="true" class="lt-app"> <body data-authenticated="true" class="lt-app">
<script> <script>
+1
View File
@@ -43,6 +43,7 @@ $layoutReturnUrl = urlencode($_SERVER['REQUEST_URI'] ?? '/');
<meta name="dbn-credits" content="<?= $layoutFreeTierBalance ?>"> <meta name="dbn-credits" content="<?= $layoutFreeTierBalance ?>">
<?php endif; ?> <?php endif; ?>
<link rel="stylesheet" href="assets/css/tools.css"> <link rel="stylesheet" href="assets/css/tools.css">
<link rel="stylesheet" href="assets/css/dbn-tools-redesign.css">
</head> </head>
<body data-authenticated="<?= $layoutIsGuest ? 'false' : 'true' ?>" data-active-tool="<?= htmlspecialchars($toolName) ?>"> <body data-authenticated="<?= $layoutIsGuest ? 'false' : 'true' ?>" data-active-tool="<?= htmlspecialchars($toolName) ?>">
<script> <script>
+3 -2
View File
@@ -58,8 +58,9 @@ $dashboardNav = [
<meta charset="utf-8"> <meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1"> <meta name="viewport" content="width=device-width, initial-scale=1">
<title><?= htmlspecialchars($dashboardTitle) ?> · <?= htmlspecialchars(dbnToolsT('dash_page_subtitle', $uiLang)) ?> · Do Better Norge</title> <title><?= htmlspecialchars($dashboardTitle) ?> · <?= htmlspecialchars(dbnToolsT('dash_page_subtitle', $uiLang)) ?> · Do Better Norge</title>
<link rel="stylesheet" href="/assets/css/tools.css"> <link rel="stylesheet" href="../assets/css/tools.css">
<link rel="stylesheet" href="/assets/css/dashboard.css"> <link rel="stylesheet" href="../assets/css/dashboard.css">
<link rel="stylesheet" href="../assets/css/dbn-tools-redesign.css">
</head> </head>
<body data-authenticated="true" data-dashboard-page="<?= htmlspecialchars($dashboardPage) ?>"> <body data-authenticated="true" data-dashboard-page="<?= htmlspecialchars($dashboardPage) ?>">
<script> <script>
+2 -2
View File
@@ -22,7 +22,7 @@
</section><!-- /workspace --> </section><!-- /workspace -->
</main><!-- /appShell --> </main><!-- /appShell -->
<?php require_once __DIR__ . '/footer.php'; ?> <?php require_once __DIR__ . '/footer.php'; ?>
<link rel="stylesheet" href="/assets/css/doc-picker.css"> <link rel="stylesheet" href="assets/css/doc-picker.css">
<?php <?php
// Expose current UI language + add-on i18n map for tools.js (legal-analysis add-on // Expose current UI language + add-on i18n map for tools.js (legal-analysis add-on
// can fire from any tool page, so it needs strings without depending on per-tool maps). // can fire from any tool page, so it needs strings without depending on per-tool maps).
@@ -59,7 +59,7 @@ $_footerAddonI18n = [
<script src="<?= htmlspecialchars((string)$extraScript) ?>" defer></script> <script src="<?= htmlspecialchars((string)$extraScript) ?>" defer></script>
<?php endforeach; endif; ?> <?php endforeach; endif; ?>
<script src="assets/js/corpus-save.js" defer></script> <script src="assets/js/corpus-save.js" defer></script>
<script src="/assets/js/doc-picker.js" defer></script> <script src="assets/js/doc-picker.js" defer></script>
<!-- Doc picker modal (shared across all tool pages) --> <!-- Doc picker modal (shared across all tool pages) -->
<div id="docPickerBackdrop" class="doc-picker-backdrop" hidden role="dialog" aria-modal="true" aria-labelledby="docPickerTitle"> <div id="docPickerBackdrop" class="doc-picker-backdrop" hidden role="dialog" aria-modal="true" aria-labelledby="docPickerTitle">
+9
View File
@@ -14,11 +14,20 @@ $_navTools = dbnToolsLaunchedTools($_navLang);
$_navPath = strtok((string)($_SERVER['REQUEST_URI'] ?? '/'), '?') ?: '/'; $_navPath = strtok((string)($_SERVER['REQUEST_URI'] ?? '/'), '?') ?: '/';
$_navOnDash = str_starts_with($_navPath, '/dashboard'); $_navOnDash = str_starts_with($_navPath, '/dashboard');
$_navReturnUrl = urlencode($_navPath); $_navReturnUrl = urlencode($_navPath);
$_navScriptPath = str_replace('\\', '/', (string)($_SERVER['SCRIPT_NAME'] ?? ''));
$_navAssetBase = str_contains($_navScriptPath, '/dashboard/') ? '../assets' : 'assets';
?> ?>
<nav class="dbn-nav" role="navigation" aria-label="<?= htmlspecialchars(dbnToolsT('suite_title', $_navLang)) ?>"> <nav class="dbn-nav" role="navigation" aria-label="<?= htmlspecialchars(dbnToolsT('suite_title', $_navLang)) ?>">
<a class="dbn-nav__brand" href="/dashboard.php"> <a class="dbn-nav__brand" href="/dashboard.php">
<picture>
<source srcset="<?= htmlspecialchars($_navAssetBase) ?>/images/logo-header.webp" type="image/webp">
<img class="dbn-nav__brand-logo" src="<?= htmlspecialchars($_navAssetBase) ?>/images/logo-header.png" alt="Do Better Norge" width="140" height="36" loading="eager">
</picture>
<span class="dbn-nav__brandmark" aria-hidden="true">⚖</span> <span class="dbn-nav__brandmark" aria-hidden="true">⚖</span>
<span class="dbn-nav__brand-text">
<span class="dbn-nav__brandname">Do Better Norge</span> <span class="dbn-nav__brandname">Do Better Norge</span>
<span class="dbn-nav__product">Legal Tools</span>
</span>
</a> </a>
<div class="dbn-nav__links" role="menubar"> <div class="dbn-nav__links" role="menubar">
+1
View File
@@ -79,6 +79,7 @@ require_once __DIR__ . '/includes/tool-svgs.php';
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin> <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Crimson+Pro:wght@400;600;700&family=IBM+Plex+Sans:wght@400;500;600;700&display=swap"> <link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Crimson+Pro:wght@400;600;700&family=IBM+Plex+Sans:wght@400;500;600;700&display=swap">
<link rel="stylesheet" href="assets/css/tools.css"> <link rel="stylesheet" href="assets/css/tools.css">
<link rel="stylesheet" href="assets/css/dbn-tools-redesign.css">
</head> </head>
<body data-authenticated="<?= $isAuthed ? 'true' : 'false' ?>" class="lt-landing"> <body data-authenticated="<?= $isAuthed ? 'true' : 'false' ?>" class="lt-landing">
<script> <script>
+1
View File
@@ -29,6 +29,7 @@ $t = $_pt[$uiLang] ?? $_pt['en'];
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin> <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Crimson+Pro:wght@400;600;700&family=IBM+Plex+Sans:wght@400;500;600;700&display=swap"> <link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Crimson+Pro:wght@400;600;700&family=IBM+Plex+Sans:wght@400;500;600;700&display=swap">
<link rel="stylesheet" href="assets/css/tools.css"> <link rel="stylesheet" href="assets/css/tools.css">
<link rel="stylesheet" href="assets/css/dbn-tools-redesign.css">
</head> </head>
<body class="kdoc-page"> <body class="kdoc-page">
+1
View File
@@ -27,6 +27,7 @@ $t = $_pt[$uiLang] ?? $_pt['en'];
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin> <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Crimson+Pro:wght@400;600;700&family=IBM+Plex+Sans:wght@400;500;600;700&display=swap"> <link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Crimson+Pro:wght@400;600;700&family=IBM+Plex+Sans:wght@400;500;600;700&display=swap">
<link rel="stylesheet" href="assets/css/tools.css"> <link rel="stylesheet" href="assets/css/tools.css">
<link rel="stylesheet" href="assets/css/dbn-tools-redesign.css">
</head> </head>
<body class="kdoc-page"> <body class="kdoc-page">
+1
View File
@@ -27,6 +27,7 @@ $t = $_pt[$uiLang] ?? $_pt['en'];
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin> <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Crimson+Pro:wght@400;600;700&family=IBM+Plex+Sans:wght@400;500;600;700&family=IBM+Plex+Mono:wght@400;500&display=swap"> <link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Crimson+Pro:wght@400;600;700&family=IBM+Plex+Sans:wght@400;500;600;700&family=IBM+Plex+Mono:wght@400;500&display=swap">
<link rel="stylesheet" href="assets/css/tools.css"> <link rel="stylesheet" href="assets/css/tools.css">
<link rel="stylesheet" href="assets/css/dbn-tools-redesign.css">
</head> </head>
<body class="kdoc-page"> <body class="kdoc-page">
+1
View File
@@ -57,6 +57,7 @@ $toolIcons = [
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin> <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Crimson+Pro:wght@400;600;700&family=IBM+Plex+Sans:wght@400;500;600;700&display=swap"> <link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Crimson+Pro:wght@400;600;700&family=IBM+Plex+Sans:wght@400;500;600;700&display=swap">
<link rel="stylesheet" href="assets/css/tools.css"> <link rel="stylesheet" href="assets/css/tools.css">
<link rel="stylesheet" href="assets/css/dbn-tools-redesign.css">
<style> <style>
/* ── MCP page styles ───────────────────────────────────────── */ /* ── MCP page styles ───────────────────────────────────────── */
.mcp-hero { .mcp-hero {
+2
View File
@@ -30,6 +30,7 @@ if (!FreeTier::isPaidTier($tier)) {
<head><meta charset="utf-8"><title>Min Sak — Do Better Norge</title> <head><meta charset="utf-8"><title>Min Sak — Do Better Norge</title>
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Crimson+Pro:wght@400;700&family=IBM+Plex+Sans:wght@400;500;600&display=swap"> <link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Crimson+Pro:wght@400;700&family=IBM+Plex+Sans:wght@400;500;600&display=swap">
<link rel="stylesheet" href="assets/css/tools.css"> <link rel="stylesheet" href="assets/css/tools.css">
<link rel="stylesheet" href="assets/css/dbn-tools-redesign.css">
</head><body><main style="max-width:720px;margin:4rem auto;padding:0 1.5rem;text-align:center;font-family:'IBM Plex Sans',sans-serif;"> </head><body><main style="max-width:720px;margin:4rem auto;padding:0 1.5rem;text-align:center;font-family:'IBM Plex Sans',sans-serif;">
<h1 style="font-family:'Crimson Pro',serif;font-size:2.4rem;margin:0 0 0.5rem;color:#00205B;">Min Sak — bygg din egen sak</h1> <h1 style="font-family:'Crimson Pro',serif;font-size:2.4rem;margin:0 0 0.5rem;color:#00205B;">Min Sak — bygg din egen sak</h1>
<p style="color:#4b5563;font-size:1.1rem;margin-bottom:2rem;">Last opp dokumentene fra saken din én gang, og la <strong>alle</strong> verktøyene jobbe på din private korpus.</p> <p style="color:#4b5563;font-size:1.1rem;margin-bottom:2rem;">Last opp dokumentene fra saken din én gang, og la <strong>alle</strong> verktøyene jobbe på din private korpus.</p>
@@ -62,6 +63,7 @@ $pct = $quota > 0 ? min(100, round(($used / $quota) * 100)) : 0;
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin> <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Crimson+Pro:wght@400;700&family=IBM+Plex+Sans:wght@400;500;600;700&display=swap"> <link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Crimson+Pro:wght@400;700&family=IBM+Plex+Sans:wght@400;500;600;700&display=swap">
<link rel="stylesheet" href="assets/css/tools.css"> <link rel="stylesheet" href="assets/css/tools.css">
<link rel="stylesheet" href="assets/css/dbn-tools-redesign.css">
<style> <style>
.ms-shell { max-width: 980px; margin: 0 auto; padding: 2rem 1.5rem 4rem; font-family: 'IBM Plex Sans', sans-serif; } .ms-shell { max-width: 980px; margin: 0 auto; padding: 2rem 1.5rem 4rem; font-family: 'IBM Plex Sans', sans-serif; }
.ms-shell h1 { font-family: 'Crimson Pro', serif; margin: 0; } .ms-shell h1 { font-family: 'Crimson Pro', serif; margin: 0; }
+1
View File
@@ -484,6 +484,7 @@ $sample = $samples[$slug];
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin> <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Crimson+Pro:wght@400;600;700&family=Roboto:wght@300;400;500;700&family=IBM+Plex+Mono:wght@400;700&display=swap"> <link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Crimson+Pro:wght@400;600;700&family=Roboto:wght@300;400;500;700&family=IBM+Plex+Mono:wght@400;700&display=swap">
<link rel="stylesheet" href="assets/css/tools.css"> <link rel="stylesheet" href="assets/css/tools.css">
<link rel="stylesheet" href="assets/css/dbn-tools-redesign.css">
</head> </head>
<body class="lt-landing lt-preview-page"> <body class="lt-landing lt-preview-page">
+1
View File
@@ -125,6 +125,7 @@ $topups = [
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin> <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Crimson+Pro:wght@400;600;700&family=IBM+Plex+Sans:wght@400;500;600;700&display=swap"> <link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Crimson+Pro:wght@400;600;700&family=IBM+Plex+Sans:wght@400;500;600;700&display=swap">
<link rel="stylesheet" href="assets/css/tools.css"> <link rel="stylesheet" href="assets/css/tools.css">
<link rel="stylesheet" href="assets/css/dbn-tools-redesign.css">
<style> <style>
.pricing-shell { max-width: 1200px; margin: 0 auto; padding: 2rem 1.5rem 4rem; } .pricing-shell { max-width: 1200px; margin: 0 auto; padding: 2rem 1.5rem 4rem; }
.pricing-hero { text-align: center; margin-bottom: 3rem; } .pricing-hero { text-align: center; margin-bottom: 3rem; }
+1
View File
@@ -29,6 +29,7 @@ $t = $_pt[$uiLang] ?? $_pt['en'];
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin> <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Crimson+Pro:wght@400;600;700&family=IBM+Plex+Sans:wght@400;500;600;700&display=swap"> <link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Crimson+Pro:wght@400;600;700&family=IBM+Plex+Sans:wght@400;500;600;700&display=swap">
<link rel="stylesheet" href="assets/css/tools.css"> <link rel="stylesheet" href="assets/css/tools.css">
<link rel="stylesheet" href="assets/css/dbn-tools-redesign.css">
</head> </head>
<body class="kdoc-page"> <body class="kdoc-page">
+1
View File
@@ -27,6 +27,7 @@ $t = $_pt[$uiLang] ?? $_pt['en'];
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin> <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Crimson+Pro:wght@400;600;700&family=IBM+Plex+Sans:wght@400;500;600;700&display=swap"> <link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Crimson+Pro:wght@400;600;700&family=IBM+Plex+Sans:wght@400;500;600;700&display=swap">
<link rel="stylesheet" href="assets/css/tools.css"> <link rel="stylesheet" href="assets/css/tools.css">
<link rel="stylesheet" href="assets/css/dbn-tools-redesign.css">
</head> </head>
<body class="kdoc-page"> <body class="kdoc-page">
+1
View File
@@ -27,6 +27,7 @@ $t = $_pt[$uiLang] ?? $_pt['en'];
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin> <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Crimson+Pro:wght@400;600;700&family=IBM+Plex+Sans:wght@400;500;600;700&family=IBM+Plex+Mono:wght@400;500&display=swap"> <link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Crimson+Pro:wght@400;600;700&family=IBM+Plex+Sans:wght@400;500;600;700&family=IBM+Plex+Mono:wght@400;500&display=swap">
<link rel="stylesheet" href="assets/css/tools.css"> <link rel="stylesheet" href="assets/css/tools.css">
<link rel="stylesheet" href="assets/css/dbn-tools-redesign.css">
</head> </head>
<body class="kdoc-page"> <body class="kdoc-page">
+247
View File
@@ -0,0 +1,247 @@
<?php
return array (
'en' =>
array (
'nav_about' => 'About',
'nav_guide' => 'User guide',
'nav_howit' => 'How it works',
'nav_opentool' => '← Open the tool',
'nav_signin' => 'Sign in',
'nav_open' => 'Open Advocate →',
'hero_kicker' => 'AI Legal Briefs · Child Welfare · Hard-RAG Grounded',
'hero_title' => 'Your AI advocate. Argues your side.',
'hero_sub' => 'Advocate generates a partisan legal brief for your child-welfare case — grounded in Lovdata statutes, ECHR judgments, and Bufdir guidance. Every argument is framed to strengthen your position. Every citation is verified against 220,000+ indexed legal passages before it reaches you.',
'stat_legal' => 'legal passages indexed',
'stat_roles' => 'party roles',
'stat_slices' => 'corpus slices',
'stat_pipeline' => 'pipeline steps',
'btn_try' => 'Try Advocate free →',
'btn_guide' => 'User guide',
'btn_howit' => 'How it works',
'what_eyebrow' => 'What you get',
'what_title' => 'A brief that fights in your corner.',
'f1_title' => 'Argue FOR your client',
'f1_body' => 'Every sub-question, retrieval pass, and the final brief is framed to strengthen your client\'s position — and expose weaknesses in the opposing side. Select your party role once; the agent stays partisan throughout.',
'f2_title' => 'Verified statute and ECHR citations',
'f2_body' => 'Sources drawn from Lovdata, ECHR HUDOC, Bufdir guidance, and Norwegian court decisions. Every claim in the brief is traced to a retrieved passage. If it can\'t be verified — it doesn\'t appear.',
'f3_title' => 'Upload your own case files',
'f3_body_html' => 'Drop in PDFs, court orders, expert reports (DOCX or TXT). Your documents are chunked and searched alongside the legal corpus — blended into the same retrieval pass. Processed <strong>in memory only</strong>, never stored or logged.',
'how_eyebrow' => 'How it works',
'how_title' => 'Select your role → describe the dispute → get your brief.',
'how_sub' => 'Three steps from blank form to a legally grounded partisan brief. No legal training required.',
's1_title' => 'Choose who you\'re representing',
's1_body' => 'Select from 9 party roles — biological parents, foster carer, adoptive parent, child, extended family, or Barnevernet. The agent frames every sub-question and citation to argue for the selected party.',
's1_example' => 'E.g. "Biological father" — the brief argues for preserving or restoring parental contact under barneloven and ECHR Art. 8.',
's2_title' => 'Describe the dispute',
's2_body' => 'Paste or type the facts of the case (up to 4,000 chars). Optionally upload case documents — court orders, expert reports, correspondence. The agent reads both the legal corpus and your files.',
's2_example' => 'Output: YOUR STRONGEST ARGUMENTS · Advocate brief · GAPS IN THE OPPOSING POSITION · Sub-question research trail.',
's3_title' => 'Get your adversarial brief',
's3_body_html' => 'The agent generates adversarial sub-questions, retrieves applicable law, and synthesises a partisan brief with inline citations. One click to <strong>run a counter-brief</strong> for the opposing party — useful for anticipating the other side\'s arguments.',
's3_example' => 'Runs in 15180 s depending on engine. Counter-brief available in one click.',
'ss_eyebrow' => 'Screenshots',
'ss_title' => 'See it in action.',
'g1_caption' => 'The form: select who you\'re representing, describe the case, choose engine and corpus.',
'g2_caption' => 'Output: your strongest arguments with citation sources, then the full advocate brief.',
'g3_caption' => 'Research trail: each sub-question with retrieved sources — ECHR cases and uploaded documents.',
'g4_caption' => 'Analysis: gaps in the opposing position, what remains uncertain, and your next practical step.',
'hood_eyebrow' => 'Under the hood',
'hood_title' => 'Powered by a purpose-built legal LLM.',
'llm_badge' => 'Fine-tuned model',
'llm_body_html' => 'A QLoRA fine-tune trained on Norwegian child-welfare and administrative law text. Unlike a general-purpose LLM, dbn-legal-agent understands the procedural vocabulary of barnevernsloven and barneloven — what ECHR Art. 8 requires in care-order cases, how Barnevernet\'s duty of assessment under §§ 4-1, 4-4 can be challenged, what the proportionality threshold is for omsorgsovertakelse. It runs alongside Azure gpt-4o to shape the argument structure of every brief.',
'llm_s1' => 'fine-tune method',
'llm_s2' => 'child-welfare law',
'llm_s3' => 'drafting backbone',
'llm_s4' => 'pipeline architecture',
'roles_eyebrow' => 'Party roles',
'roles_title' => '9 roles. Each frames the brief to argue your side.',
'roles_sub' => 'Selecting a party role tells the agent whose position to defend. Sub-questions, retrieval, and the final brief all follow the chosen side.',
'cta_title' => 'Ready to build your case?',
'cta_sub' => 'Free for Do Better Norge members. No credit card required.',
'btn_open' => 'Open Advocate →',
'btn_signin_cta' => 'Sign in to use Advocate →',
'btn_register' => 'Register free',
),
'no' =>
array (
'nav_about' => 'Om',
'nav_guide' => 'Brukerveiledning',
'nav_howit' => 'Hvordan det fungerer',
'nav_opentool' => '← Åpne verktøyet',
'nav_signin' => 'Logg inn',
'nav_open' => 'Åpne Advocate →',
'hero_kicker' => 'AI Juridiske sammendrag · Barnevern · Hard-RAG Grounded',
'hero_title' => 'Din AI-advokat. Argumenterer for din side.',
'hero_sub' => 'Advocate genererer et partisk juridisk sammendrag for barnevernssaken din — basert på Lovdata-lover, ECHR-dommer og Bufdirs veiledning. Hvert argument er utformet for å styrke din posisjon. Hver § henvisning er verifisert mot 220 000+ indekserte juridiske passasjer.',
'stat_legal' => 'juridiske passasjer indeksert',
'stat_roles' => 'partsroller',
'stat_slices' => 'corpus-seksjoner',
'stat_pipeline' => 'pipeline-trinn',
'btn_try' => 'Prøv Advocate gratis →',
'btn_guide' => 'Brukerveiledning',
'btn_howit' => 'Hvordan det fungerer',
'what_eyebrow' => 'Hva du får',
'what_title' => 'Et sammendrag som kjemper for deg.',
'f1_title' => 'Argumenter FOR din klient',
'f1_body' => 'Hvert delspørsmål, hentingspass og det endelige sammendraget er utformet for å styrke din klients posisjon — og avdekke svakheter på motsatt side. Velg partsrolle én gang; agenten forblir partisk gjennom hele prosessen.',
'f2_title' => 'Verifiserte lov- og ECHR-henvisninger',
'f2_body' => 'Kilder hentet fra Lovdata, ECHR HUDOC, Bufdirs veiledning og norske rettsavgjørelser. Hvert påstand i sammendraget er sporet til et hentet avsnitt. Hvis det ikke kan verifiseres — vises det ikke.',
'f3_title' => 'Last opp dine egne saksdokumenter',
'f3_body_html' => 'Last opp PDF-er, kjennelser, sakkyndige rapporter (DOCX eller TXT). Dokumentene dine deles inn og søkes ved siden av det juridiske korpuset — blandet inn i samme hentingspass. Behandles <strong>kun i minne</strong>, aldri lagret eller logget.',
'how_eyebrow' => 'Hvordan det fungerer',
'how_title' => 'Velg din rolle → beskriv tvisten → få ditt sammendrag.',
'how_sub' => 'Tre trinn fra tom skjema til et juridisk forankret partisk sammendrag. Ingen juridisk opplæring kreves.',
's1_title' => 'Velg hvem du representerer',
's1_body' => 'Velg blant 9 partsroller — biologiske foreldre, fosterforelder, adoptivforelder, barn, utvidet familie eller Barnevernet. Agenten utformer hvert delspørsmål og hver henvisning for å argumentere for den valgte parten.',
's1_example' => 'F.eks. "Biologisk far" — sammendraget argumenterer for å bevare eller gjenopprette foreldrekontakt under barneloven og EMK Art. 8.',
's2_title' => 'Beskriv tvisten',
's2_body' => 'Lim inn eller skriv fakta i saken (opptil 4 000 tegn). Last eventuelt opp saksdokumenter — kjennelser, sakkyndige rapporter, korrespondanse. Agenten leser både det juridiske korpuset og filene dine.',
's2_example' => 'Utdata: DINE STERKESTE ARGUMENTER · Advokatsammendrag · HULL I MOTPARTENS POSISJON · Forskningsspor for delspørsmål.',
's3_title' => 'Få ditt motstandsorienterte sammendrag',
's3_body_html' => 'Agenten genererer motstandsorienterte delspørsmål, henter gjeldende lov og syntetiserer et partisk sammendrag med innebygde henvisninger. Ett klikk for å <strong>kjøre et motstridende sammendrag</strong> for motparten — nyttig for å forutse motpartens argumenter.',
's3_example' => 'Kjører på 15180 s avhengig av motor. Motstridende sammendrag tilgjengelig med ett klikk.',
'ss_eyebrow' => 'Skjermbilder',
'ss_title' => 'Se det i aksjon.',
'g1_caption' => 'Skjemaet: velg hvem du representerer, beskriv saken, velg motor og corpus.',
'g2_caption' => 'Utdata: dine sterkeste argumenter med kildehenvisninger, deretter det fullstendige advokatsammendraget.',
'g3_caption' => 'Forskningsspor: hvert delspørsmål med hentede kilder — ECHR-saker og opplastede dokumenter.',
'g4_caption' => 'Analyse: hull i motpartens posisjon, hva som gjenstår usikkert, og ditt neste praktiske skritt.',
'hood_eyebrow' => 'Under panseret',
'hood_title' => 'Drevet av en spesialbygd juridisk LLM.',
'llm_badge' => 'Finjustert modell',
'llm_body_html' => 'En QLoRA-finjustering trent på norsk barnevernsrett og forvaltningsrett. dbn-legal-agent forstår det prosessuelle vokabularet i barnevernsloven og barneloven — hva EMK Art. 8 krever i omsorgsovertakelsessaker, hvordan Barnevernets vurderingsplikt under §§ 4-1, 4-4 kan utfordres, og hva proporsjonalitetskravet er for omsorgsovertakelse.',
'llm_s1' => 'finjusteringsmetode',
'llm_s2' => 'barnevernsrett',
'llm_s3' => 'utkastgrunnlag',
'llm_s4' => 'pipeline-arkitektur',
'roles_eyebrow' => 'Partsroller',
'roles_title' => '9 roller. Hver utformer sammendraget for å argumentere for din side.',
'roles_sub' => 'Å velge en partsrolle forteller agenten hvilken posisjon som skal forsvares. Delspørsmål, henting og det endelige sammendraget følger alle den valgte siden.',
'cta_title' => 'Klar til å bygge saken din?',
'cta_sub' => 'Gratis for Do Better Norge-medlemmer. Ingen kredittkort nødvendig.',
'btn_open' => 'Åpne Advocate →',
'btn_signin_cta' => 'Logg inn for å bruke Advocate →',
'btn_register' => 'Registrer gratis',
),
'uk' =>
array (
'nav_about' => 'Про нас',
'nav_guide' => 'Посібник користувача',
'nav_howit' => 'Як це працює',
'nav_opentool' => '← Відкрити інструмент',
'nav_signin' => 'Увійти',
'nav_open' => 'Відкрити Advocate →',
'hero_kicker' => 'AI Юридичні резюме · Захист дітей · Hard-RAG Grounded',
'hero_title' => 'Ваш AI-адвокат. Аргументує на вашу користь.',
'hero_sub' => 'Advocate генерує упереджене юридичне резюме для вашої справи із захисту дітей — на основі норвезьких законів Lovdata, рішень ЄСПЛ та керівництва Bufdir. Кожен аргумент сформульований для зміцнення вашої позиції. Кожна цитата § перевіряється по 220 000+ індексованих правових положень.',
'stat_legal' => 'індексовані правові положення',
'stat_roles' => 'ролі сторін',
'stat_slices' => 'розділи корпусу',
'stat_pipeline' => 'кроки конвеєра',
'btn_try' => 'Спробуйте Advocate безкоштовно →',
'btn_guide' => 'Посібник користувача',
'btn_howit' => 'Як це працює',
'what_eyebrow' => 'Що ви отримуєте',
'what_title' => 'Резюме, яке бореться на вашому боці.',
'f1_title' => 'Аргументуйте НА КОРИСТЬ вашого клієнта',
'f1_body' => 'Кожне підпитання, прохід отримання та фінальне резюме сформульовані для зміцнення позиції вашого клієнта — і виявлення слабких місць протилежної сторони. Виберіть роль сторони один раз; агент залишається упередженим протягом усього процесу.',
'f2_title' => 'Перевірені цитати законів та ЄСПЛ',
'f2_body' => 'Джерела з Lovdata, ЄСПЛ HUDOC, керівництва Bufdir та норвезьких судових рішень. Кожне твердження в резюме прив\'язане до отриманого фрагменту. Якщо неможливо перевірити — не з\'являється.',
'f3_title' => 'Завантажте власні файли справи',
'f3_body_html' => 'Завантажуйте PDF-файли, судові накази, висновки експертів (DOCX або TXT). Ваші документи розбиваються на частини і шукаються разом із правовим корпусом. Обробляється <strong>лише в пам\'яті</strong>, ніколи не зберігається.',
'how_eyebrow' => 'Як це працює',
'how_title' => 'Оберіть роль → опишіть суперечку → отримайте резюме.',
'how_sub' => 'Три кроки від порожньої форми до юридично обґрунтованого упередженого резюме. Юридична освіта не потрібна.',
's1_title' => 'Виберіть, кого ви представляєте',
's1_body' => 'Виберіть з 9 ролей сторін — біологічні батьки, прийомний вихователь, усиновлювач, дитина, розширена сім\'я або Barnevernet. Агент формулює кожне підпитання та цитату для аргументації на користь обраної сторони.',
's1_example' => 'Напр. "Біологічний батько" — резюме аргументує за збереження або відновлення батьківського контакту.',
's2_title' => 'Опишіть суперечку',
's2_body' => 'Вставте або введіть факти справи (до 4 000 символів). За бажанням завантажте документи справи — судові накази, висновки експертів, листування. Агент читає і правовий корпус, і ваші файли.',
's2_example' => 'Вивід: ВАШІ НАЙСИЛЬНІШІ АРГУМЕНТИ · Адвокатське резюме · ПРОГАЛИНИ В ПОЗИЦІЇ ОПОНЕНТА · Дослідницький слід підпитань.',
's3_title' => 'Отримайте своє змагальне резюме',
's3_body_html' => 'Агент генерує змагальні підпитання, отримує застосовне право та синтезує упереджене резюме з вбудованими цитатами. Один клік для <strong>запуску контррезюме</strong> для протилежної сторони.',
's3_example' => 'Виконується за 15–180 с залежно від двигуна. Контррезюме доступне в один клік.',
'ss_eyebrow' => 'Скріншоти',
'ss_title' => 'Дивіться це в дії.',
'g1_caption' => 'Форма: виберіть, кого ви представляєте, опишіть справу, виберіть двигун і корпус.',
'g2_caption' => 'Вивід: ваші найсильніші аргументи з джерелами, потім повне адвокатське резюме.',
'g3_caption' => 'Дослідницький слід: кожне підпитання з отриманими джерелами — справи ЄСПЛ і завантажені документи.',
'g4_caption' => 'Аналіз: прогалини в позиції опонента, що залишається невизначеним, і ваш наступний практичний крок.',
'hood_eyebrow' => 'Під капотом',
'hood_title' => 'Потужна спеціалізована юридична LLM.',
'llm_badge' => 'Модель з тонким налаштуванням',
'llm_body_html' => 'Модель QLoRA, налаштована на текст норвезького права із захисту дітей та адміністративного права. dbn-legal-agent розуміє процедурну лексику barnevernsloven і barneloven — що вимагає ЄСПЛ Стаття 8 у справах про опіку, як можна оскаржити оцінювальний обов\'язок Barnevernet.',
'llm_s1' => 'метод налаштування',
'llm_s2' => 'право захисту дітей',
'llm_s3' => 'основа складання',
'llm_s4' => 'архітектура конвеєра',
'roles_eyebrow' => 'Ролі сторін',
'roles_title' => '9 ролей. Кожна формулює резюме для аргументації на вашому боці.',
'roles_sub' => 'Вибір ролі сторони вказує агенту, яку позицію захищати. Підпитання, отримання та фінальне резюме слідують обраній стороні.',
'cta_title' => 'Готові будувати свою справу?',
'cta_sub' => 'Безкоштовно для членів Do Better Norge. Кредитна картка не потрібна.',
'btn_open' => 'Відкрити Advocate →',
'btn_signin_cta' => 'Увійти, щоб використовувати Advocate →',
'btn_register' => 'Зареєструватися безкоштовно',
),
'pl' =>
array (
'nav_about' => 'O nas',
'nav_guide' => 'Podręcznik użytkownika',
'nav_howit' => 'Jak to działa',
'nav_opentool' => '← Otwórz narzędzie',
'nav_signin' => 'Zaloguj się',
'nav_open' => 'Otwórz Advocate →',
'hero_kicker' => 'AI Pisma prawne · Opieka nad dziećmi · Hard-RAG Grounded',
'hero_title' => 'Twój AI-adwokat. Argumentuje po Twojej stronie.',
'hero_sub' => 'Advocate generuje stronnicze pismo prawne dla Twojej sprawy dotyczącej opieki nad dziećmi — oparte na norweskich przepisach Lovdata, orzeczeniach ECHR i wytycznych Bufdir. Każdy argument jest sformułowany, aby wzmocnić Twoją pozycję. Każda cytacja § jest weryfikowana w odniesieniu do 220 000+ zindeksowanych przepisów.',
'stat_legal' => 'zindeksowane przepisy prawne',
'stat_roles' => 'role stron',
'stat_slices' => 'sekcje korpusu',
'stat_pipeline' => 'kroki pipeline',
'btn_try' => 'Wypróbuj Advocate za darmo →',
'btn_guide' => 'Podręcznik użytkownika',
'btn_howit' => 'Jak to działa',
'what_eyebrow' => 'Co otrzymujesz',
'what_title' => 'Pismo, które walczy po Twojej stronie.',
'f1_title' => 'Argumentuj NA RZECZ swojego klienta',
'f1_body' => 'Każde podpytanie, przejście pobierania i finalne pismo jest sformułowane, aby wzmocnić pozycję klienta — i ujawnić słabości strony przeciwnej. Wybierz rolę strony raz; agent pozostaje stronniczy przez cały czas.',
'f2_title' => 'Zweryfikowane cytaty z ustaw i ECHR',
'f2_body' => 'Źródła z Lovdata, ECHR HUDOC, wytycznych Bufdir i norweskich orzeczeń sądowych. Każde twierdzenie w piśmie jest powiązane z pobranym fragmentem. Jeśli nie można zweryfikować — nie pojawia się.',
'f3_title' => 'Prześlij własne akta sprawy',
'f3_body_html' => 'Prześlij pliki PDF, postanowienia sądowe, opinie biegłych (DOCX lub TXT). Dokumenty są dzielone na fragmenty i przeszukiwane obok korpusu prawnego. Przetwarzane <strong>tylko w pamięci</strong>, nigdy nie przechowywane.',
'how_eyebrow' => 'Jak to działa',
'how_title' => 'Wybierz rolę → opisz spór → otrzymaj pismo.',
'how_sub' => 'Trzy kroki od pustego formularza do prawnie ugruntowanego stronniczego pisma. Nie jest wymagana wiedza prawnicza.',
's1_title' => 'Wybierz, kogo reprezentujesz',
's1_body' => 'Wybierz spośród 9 ról stron — biologiczni rodzice, opiekun zastępczy, rodzic adopcyjny, dziecko, dalsza rodzina lub Barnevernet. Agent formułuje każde podpytanie i cytację, aby argumentować na rzecz wybranej strony.',
's1_example' => 'Np. "Ojciec biologiczny" — pismo argumentuje za utrzymaniem lub przywróceniem kontaktu rodzicielskiego.',
's2_title' => 'Opisz spór',
's2_body' => 'Wklej lub wpisz fakty sprawy (do 4 000 znaków). Opcjonalnie prześlij dokumenty sprawy — postanowienia sądowe, opinie biegłych, korespondencję. Agent czyta zarówno korpus prawny, jak i Twoje pliki.',
's2_example' => 'Wynik: TWOJE NAJSILNIEJSZE ARGUMENTY · Pismo adwokackie · LUKI W POZYCJI STRONY PRZECIWNEJ · Ślad badawczy podpytań.',
's3_title' => 'Otrzymaj swoje pismo adversarialne',
's3_body_html' => 'Agent generuje adversarialne podpytania, pobiera obowiązujące prawo i syntezuje stronnicze pismo z cytacjami inline. Jedno kliknięcie, aby <strong>uruchomić kontropinię</strong> dla strony przeciwnej.',
's3_example' => 'Działa w 15180 s w zależności od silnika. Kontropinia dostępna jednym kliknięciem.',
'ss_eyebrow' => 'Zrzuty ekranu',
'ss_title' => 'Zobacz to w akcji.',
'g1_caption' => 'Formularz: wybierz, kogo reprezentujesz, opisz sprawę, wybierz silnik i korpus.',
'g2_caption' => 'Wynik: Twoje najsilniejsze argumenty ze źródłami, a następnie pełne pismo adwokackie.',
'g3_caption' => 'Ślad badawczy: każde podpytanie z pobranymi źródłami — sprawy ECHR i przesłane dokumenty.',
'g4_caption' => 'Analiza: luki w pozycji strony przeciwnej, co pozostaje niepewne i Twój następny praktyczny krok.',
'hood_eyebrow' => 'Pod maską',
'hood_title' => 'Zasilany przez specjalnie zaprojektowany model LLM do prawa.',
'llm_badge' => 'Model dostosowany',
'llm_body_html' => 'Model QLoRA dostosowany do tekstów norweskiego prawa dotyczącego opieki nad dziećmi i prawa administracyjnego. dbn-legal-agent rozumie słownictwo proceduralne barnevernsloven i barneloven — czego wymaga ECHR Art. 8 w sprawach o opiekę, jak można zakwestionować obowiązek oceny Barnevernet.',
'llm_s1' => 'metoda dostosowania',
'llm_s2' => 'prawo opieki nad dziećmi',
'llm_s3' => 'szkielet pisania',
'llm_s4' => 'architektura pipeline',
'roles_eyebrow' => 'Role stron',
'roles_title' => '9 ról. Każda formułuje pismo, aby argumentować po Twojej stronie.',
'roles_sub' => 'Wybór roli strony informuje agenta, czyją pozycję bronić. Podpytania, pobieranie i finalne pismo podążają za wybraną stroną.',
'cta_title' => 'Gotowy do budowania swojej sprawy?',
'cta_sub' => 'Darmowe dla członków Do Better Norge. Nie jest wymagana karta kredytowa.',
'btn_open' => 'Otwórz Advocate →',
'btn_signin_cta' => 'Zaloguj się, aby użyć Advocate →',
'btn_register' => 'Zarejestruj się za darmo',
),
);
+327
View File
@@ -0,0 +1,327 @@
<?php
return array (
'en' =>
array (
'nav_about' => 'About',
'nav_guide' => 'User guide',
'nav_howit' => 'How it works',
'nav_opentool' => '← Open the tool',
'nav_signin' => 'Sign in',
'nav_open' => 'Open Advocate →',
'hero_kicker' => 'User Guide · Advocate · Step-by-step',
'hero_title' => 'How to use Advocate.',
'hero_sub' => 'A complete walkthrough of every control — from selecting your party role to reading the brief and running a counter-argument.',
'toc_title' => 'In this guide',
's1_head' => '1. Language',
's2_head' => '2. Who you\'re representing',
's3_head' => '3. Case description',
's4_head' => '4. Engine',
's5_head' => '5. Corpus slices',
's6_head' => '6. Advanced controls',
's7_head' => '7. Upload case files',
's8_head' => '8. Preview research angles',
's9_head' => '9. Understanding the output',
's10_head' => '10. Counter-brief',
's11_head' => '11. Tips',
's1_title' => 'Language',
's1_body' => 'Four language pills appear at the top of the form: EN, NO, UK, PL. Switching language changes the form labels and the UI only — the agent always outputs the brief in English regardless of this setting. Use your language to read the form more comfortably.',
's2_title' => 'Who you\'re representing',
's2_body' => 'The most important control. Select the party whose position the agent should argue for. The dropdown sets the framing for every sub-question, every retrieval pass, and the final brief.',
's2_table_col1' => 'Role',
's2_table_col2' => 'Governing law',
's2_table_col3' => 'Typical use',
's3_title' => 'Case description',
's3_body' => 'Type or paste the facts of the case — up to 4,000 characters. Describe what happened, what the dispute is, and what matters most to your client. The more specific you are, the more targeted the sub-questions and the more relevant the retrieved statutes.',
's3_tip' => 'Tip: include key dates, the names of the bodies involved (e.g. Barnevernet, Statsforvalteren), and the specific decisions being challenged.',
's4_title' => 'Engine',
's4_body' => 'Four engines are available. All use the same Hard-RAG pipeline and the same corpus — only the synthesis model differs.',
's4_table_col1' => 'Engine',
's4_table_col2' => 'Speed',
's4_table_col3' => 'Best for',
's5_title' => 'Corpus slices',
's5_body' => 'Eight toggleable slices control which parts of the legal corpus are searched. Three are ON by default — the core slices for most child-welfare cases. Enable additional slices for more targeted research.',
's5_table_col1' => 'Slice',
's5_table_col2' => 'Default',
's5_table_col3' => 'Covers',
's5_table_col4' => 'Enable when',
's6_title' => 'Advanced controls',
's6_body' => 'Click "Advanced controls" to expand five sliders that tune retrieval depth and synthesis behaviour. The defaults are calibrated for most cases — adjust only if you need deeper or narrower research.',
's6_table_col1' => 'Control',
's6_table_col2' => 'Range',
's6_table_col3' => 'Default',
's6_table_col4' => 'What it does',
's7_title' => 'Upload case files',
's7_body' => 'Drop PDF, DOCX, or TXT files into the upload zone (or click Browse). Up to 5 files. Your documents are chunked into 512-token passages, embedded with nomic-embed-text, and searched alongside the legal corpus in the same retrieval pass. Files are processed in memory only — nothing is stored or retained after your session ends.',
's7_tip' => 'Tip: upload the Barnevernet assessment report, court order, or expert report most relevant to the case. The agent will cite passages from your files alongside Lovdata statutes.',
's8_title' => 'Preview research angles',
's8_body' => 'Click "Preview research angles first" instead of "Research my case" to see the adversarial sub-questions the agent has generated before it runs the full retrieval. You can edit any sub-question and then click "Run with these angles" — or discard and run fresh.',
's8_tip' => 'Tip: use Preview when the case is complex or unusual. Editing a sub-question lets you steer the retrieval toward a specific statute or procedural issue.',
's9_title' => 'Understanding the output',
's9_body' => 'The output area has four distinct panels:',
's9_p1_title' => 'YOUR STRONGEST ARGUMENTS',
's9_p1_body' => 'A bullet list of the most powerful points in favour of your client, each with inline source numbers. Click a source number to open the full passage in a modal.',
's9_p2_title' => 'Advocate brief',
's9_p2_body' => 'The full partisan brief — prose paragraphs grounded in retrieved statutes and ECHR authorities, all framed to argue for the selected party.',
's9_p3_title' => 'GAPS IN THE OPPOSING POSITION',
's9_p3_body' => 'Weaknesses in the other side\'s case, identified from the same retrieval. Useful for anticipating counter-arguments in court or mediation.',
's9_p4_title' => 'Sub-question research trail',
's9_p4_body' => 'Each adversarial sub-question the agent generated, with its retrieved sources listed beneath. Corpus passages show the Lovdata or ECHR reference; uploaded-doc passages show the filename and excerpt. Click "Branch ↓" to run a deeper dive on any single sub-question.',
's10_title' => 'Counter-brief',
's10_body' => 'At the top of the output, a banner shows "See the other side? [Opposing party] — Run counter-brief →". Clicking it pre-fills the form with the opposing party role and re-runs the same case description. Useful for stress-testing your arguments before a hearing.',
's11_title' => 'Tips for best results',
'tip1' => 'Be specific in the case description — vague facts produce vague sub-questions.',
'tip2' => 'Upload the most relevant document (e.g. the assessment report) to blend case-specific passages with corpus law.',
'tip3' => 'Use the Norwegian specialist engine (dbn-legal-agent) for Barneloven, Barnevernsloven, and ECHR Art. 8 cases — it produces tighter legal register.',
'tip4' => 'Enable ECHR slice if the case involves proportionality arguments or cross-border elements.',
'tip5' => 'Enable Hague Convention slice for international child-abduction or wrongful-removal cases.',
'tip6' => 'Run a counter-brief before a hearing to anticipate the arguments you\'ll need to rebut.',
'cta_title' => 'Ready to build your case?',
'cta_sub' => 'Free for Do Better Norge members. No credit card required.',
'btn_open' => 'Open Advocate →',
'btn_signin_cta' => 'Sign in to use Advocate →',
'btn_register' => 'Register free',
),
'no' =>
array (
'nav_about' => 'Om',
'nav_guide' => 'Brukerveiledning',
'nav_howit' => 'Hvordan det fungerer',
'nav_opentool' => '← Åpne verktøyet',
'nav_signin' => 'Logg inn',
'nav_open' => 'Åpne Advocate →',
'hero_kicker' => 'Brukerveiledning · Advocate · Steg for steg',
'hero_title' => 'Slik bruker du Advocate.',
'hero_sub' => 'En komplett gjennomgang av hvert kontrollpunkt — fra valg av partsrolle til lesing av sammendraget og kjøring av et motsvar.',
'toc_title' => 'I denne veiledningen',
's1_head' => '1. Språk',
's2_head' => '2. Hvem du representerer',
's3_head' => '3. Saksbeskrivelse',
's4_head' => '4. Motor',
's5_head' => '5. Corpus-seksjoner',
's6_head' => '6. Avanserte innstillinger',
's7_head' => '7. Last opp saksdokumenter',
's8_head' => '8. Forhåndsvis forskningsvinkler',
's9_head' => '9. Forstå utdataene',
's10_head' => '10. Motsammendrag',
's11_head' => '11. Tips',
's1_title' => 'Språk',
's1_body' => 'Fire språkknapper vises øverst i skjemaet: EN, NO, UK, PL. Å bytte språk endrer kun skjemamerkene og brukergrensesnittet — agenten sender alltid ut sammendraget på engelsk uavhengig av denne innstillingen.',
's2_title' => 'Hvem du representerer',
's2_body' => 'Den viktigste kontrollen. Velg parten hvis posisjon agenten skal argumentere for. Rullegardinmenyen setter rammen for hvert delspørsmål, hvert hentingspass og det endelige sammendraget.',
's2_table_col1' => 'Rolle',
's2_table_col2' => 'Gjeldende lov',
's2_table_col3' => 'Typisk bruk',
's3_title' => 'Saksbeskrivelse',
's3_body' => 'Skriv inn eller lim inn faktaene i saken — opptil 4 000 tegn. Beskriv hva som skjedde, hva tvisten er, og hva som er viktigst for din klient.',
's3_tip' => 'Tips: ta med nøkkeldatoer, navnene på involverte organer, og de spesifikke avgjørelsene som utfordres.',
's4_title' => 'Motor',
's4_body' => 'Fire motorer er tilgjengelige. Alle bruker samme Hard-RAG-pipeline og same corpus — bare syntesemodellen er forskjellig.',
's4_table_col1' => 'Motor',
's4_table_col2' => 'Hastighet',
's4_table_col3' => 'Best for',
's5_title' => 'Corpus-seksjoner',
's5_body' => 'Åtte bryterbare seksjoner kontrollerer hvilke deler av det juridiske korpuset som søkes. Tre er PÅ som standard — kjernestykker for de fleste barnevernssaker.',
's5_table_col1' => 'Seksjon',
's5_table_col2' => 'Standard',
's5_table_col3' => 'Dekker',
's5_table_col4' => 'Aktiver når',
's6_title' => 'Avanserte innstillinger',
's6_body' => 'Klikk "Avanserte innstillinger" for å utvide fem glidere som justerer hentingsdybde og synteseadferd.',
's6_table_col1' => 'Kontroll',
's6_table_col2' => 'Område',
's6_table_col3' => 'Standard',
's6_table_col4' => 'Hva den gjør',
's7_title' => 'Last opp saksdokumenter',
's7_body' => 'Slipp PDF, DOCX eller TXT-filer i opplastingssonen. Opptil 5 filer. Dokumentene deles inn i 512-token passasjer og søkes ved siden av det juridiske korpuset. Filer behandles kun i minne — ingenting lagres.',
's7_tip' => 'Tips: last opp den mest relevante rapporten (f.eks. Barnevernets utredningsrapport) for å blande saksspecifikke passasjer med lov.',
's8_title' => 'Forhåndsvis forskningsvinkler',
's8_body' => 'Klikk "Forhåndsvis forskningsvinkler" for å se de motstandsorienterte delspørsmålene før full henting. Du kan redigere spørsmål og klikke "Kjør med disse vinklene".',
's8_tip' => 'Tips: bruk forhåndsvisning for komplekse eller uvanlige saker.',
's9_title' => 'Forstå utdataene',
's9_body' => 'Utdataområdet har fire distinkte paneler:',
's9_p1_title' => 'DINE STERKESTE ARGUMENTER',
's9_p1_body' => 'En punktliste over de mest kraftfulle punktene til fordel for din klient, med inline kildenumre.',
's9_p2_title' => 'Advokatsammendrag',
's9_p2_body' => 'Det fullstendige partiske sammendraget — prosaavsnitt forankret i hentede lover og ECHR-autoriteter.',
's9_p3_title' => 'HULL I MOTPARTENS POSISJON',
's9_p3_body' => 'Svakheter i motpartens sak, identifisert fra den samme hentingen.',
's9_p4_title' => 'Forskningsspor for delspørsmål',
's9_p4_body' => 'Hvert motstandsorientert delspørsmål med hentede kilder. Klikk "Forgren ↓" for å dykke dypere inn i et enkelt delspørsmål.',
's10_title' => 'Motsammendrag',
's10_body' => 'Øverst i utdataene vises et banner med "Se den andre siden? — Kjør motsammendrag →". Klikk for å kjøre det samme tilfellet med motsatt partsrolle.',
's11_title' => 'Tips for best resultat',
'tip1' => 'Vær spesifikk i saksbeskrivelsen — vage fakta gir vage delspørsmål.',
'tip2' => 'Last opp det mest relevante dokumentet for å blande saksspecifikke passasjer med lov.',
'tip3' => 'Bruk norsk spesialistmotor (dbn-legal-agent) for Barneloven, Barnevernsloven og EMK Art. 8-saker.',
'tip4' => 'Aktiver ECHR-seksjonen for proporsjonalitetsargumenter eller grenseoverskridende elementer.',
'tip5' => 'Aktiver Haag-konvensjonsseksjonen for internasjonale barnebortføringssaker.',
'tip6' => 'Kjør et motsammendrag før et rettsmøte for å forutse argumentene du må tilbakevise.',
'cta_title' => 'Klar til å bygge saken din?',
'cta_sub' => 'Gratis for Do Better Norge-medlemmer. Ingen kredittkort nødvendig.',
'btn_open' => 'Åpne Advocate →',
'btn_signin_cta' => 'Logg inn for å bruke Advocate →',
'btn_register' => 'Registrer gratis',
),
'uk' =>
array (
'nav_about' => 'Про нас',
'nav_guide' => 'Посібник користувача',
'nav_howit' => 'Як це працює',
'nav_opentool' => '← Відкрити інструмент',
'nav_signin' => 'Увійти',
'nav_open' => 'Відкрити Advocate →',
'hero_kicker' => 'Посібник · Advocate · Покроково',
'hero_title' => 'Як користуватися Advocate.',
'hero_sub' => 'Повний покроковий огляд кожного елемента управління — від вибору ролі сторони до читання резюме та запуску контраргументу.',
'toc_title' => 'У цьому посібнику',
's1_head' => '1. Мова',
's2_head' => '2. Кого ви представляєте',
's3_head' => '3. Опис справи',
's4_head' => '4. Двигун',
's5_head' => '5. Розділи корпусу',
's6_head' => '6. Розширені налаштування',
's7_head' => '7. Завантаження файлів справи',
's8_head' => '8. Попередній перегляд кутів дослідження',
's9_head' => '9. Розуміння виведення',
's10_head' => '10. Контррезюме',
's11_head' => '11. Поради',
's1_title' => 'Мова',
's1_body' => 'Чотири мовні кнопки з\'являються у верхній частині форми: EN, NO, UK, PL. Зміна мови змінює лише мітки форми та інтерфейс.',
's2_title' => 'Кого ви представляєте',
's2_body' => 'Найважливіший елемент управління. Виберіть сторону, позицію якої агент повинен аргументувати.',
's2_table_col1' => 'Роль',
's2_table_col2' => 'Застосовне право',
's2_table_col3' => 'Типове використання',
's3_title' => 'Опис справи',
's3_body' => 'Введіть або вставте факти справи — до 4 000 символів. Опишіть, що сталося, у чому полягає суперечка, і що найважливіше для вашого клієнта.',
's3_tip' => 'Порада: включіть ключові дати, назви залучених органів та конкретні рішення, що оскаржуються.',
's4_title' => 'Двигун',
's4_body' => 'Доступні чотири двигуни. Всі використовують той самий конвеєр Hard-RAG і той самий корпус.',
's4_table_col1' => 'Двигун',
's4_table_col2' => 'Швидкість',
's4_table_col3' => 'Найкраще для',
's5_title' => 'Розділи корпусу',
's5_body' => 'Вісім перемикальних розділів контролюють, які частини правового корпусу шукаються. Три УВІМКНЕНІ за замовчуванням.',
's5_table_col1' => 'Розділ',
's5_table_col2' => 'За замовчуванням',
's5_table_col3' => 'Охоплює',
's5_table_col4' => 'Увімкнути коли',
's6_title' => 'Розширені налаштування',
's6_body' => 'Натисніть "Розширені налаштування", щоб розгорнути п\'ять повзунків.',
's6_table_col1' => 'Елемент управління',
's6_table_col2' => 'Діапазон',
's6_table_col3' => 'За замовчуванням',
's6_table_col4' => 'Що робить',
's7_title' => 'Завантаження файлів справи',
's7_body' => 'Перетягніть PDF, DOCX або TXT файли в зону завантаження. До 5 файлів. Обробляється лише в пам\'яті — нічого не зберігається.',
's7_tip' => 'Порада: завантажте найбільш релевантний документ для поєднання конкретних пасажів справи із законодавством.',
's8_title' => 'Попередній перегляд кутів дослідження',
's8_body' => 'Натисніть "Попередній перегляд кутів дослідження" перед повним пошуком. Ви можете редагувати підпитання та натиснути "Запустити з цими кутами".',
's8_tip' => 'Порада: використовуйте попередній перегляд для складних або незвичних справ.',
's9_title' => 'Розуміння виведення',
's9_body' => 'Область виведення має чотири різні панелі:',
's9_p1_title' => 'ВАШІ НАЙСИЛЬНІШІ АРГУМЕНТИ',
's9_p1_body' => 'Маркований список найпотужніших аргументів на користь вашого клієнта.',
's9_p2_title' => 'Адвокатське резюме',
's9_p2_body' => 'Повне упереджене резюме — прозові абзаци, засновані на отриманих законах та авторитетах ЄСПЛ.',
's9_p3_title' => 'ПРОГАЛИНИ В ПОЗИЦІЇ ОПОНЕНТА',
's9_p3_body' => 'Слабкі місця у справі іншої сторони.',
's9_p4_title' => 'Дослідницький слід підпитань',
's9_p4_body' => 'Кожне змагальне підпитання з отриманими джерелами. Натисніть "Розгалужити ↓" для глибшого занурення.',
's10_title' => 'Контррезюме',
's10_body' => 'Угорі виведення з\'являється банер "Побачити іншу сторону? — Запустити контррезюме →". Натисніть, щоб запустити ту саму справу з протилежною роллю сторони.',
's11_title' => 'Поради для найкращих результатів',
'tip1' => 'Будьте конкретними в описі справи — розпливчасті факти дають розпливчасті підпитання.',
'tip2' => 'Завантажте найбільш релевантний документ для поєднання конкретних пасажів справи із законодавством.',
'tip3' => 'Використовуйте норвезький спеціалізований двигун для справ barnevernsloven та ЄСПЛ Стаття 8.',
'tip4' => 'Увімкніть розділ ЄСПЛ для аргументів пропорційності або транскордонних елементів.',
'tip5' => 'Увімкніть розділ Гаазької конвенції для міжнародного викрадення дітей.',
'tip6' => 'Запустіть контррезюме перед слуханням для передбачення аргументів.',
'cta_title' => 'Готові будувати свою справу?',
'cta_sub' => 'Безкоштовно для членів Do Better Norge. Кредитна картка не потрібна.',
'btn_open' => 'Відкрити Advocate →',
'btn_signin_cta' => 'Увійти, щоб використовувати Advocate →',
'btn_register' => 'Зареєструватися безкоштовно',
),
'pl' =>
array (
'nav_about' => 'O nas',
'nav_guide' => 'Podręcznik użytkownika',
'nav_howit' => 'Jak to działa',
'nav_opentool' => '← Otwórz narzędzie',
'nav_signin' => 'Zaloguj się',
'nav_open' => 'Otwórz Advocate →',
'hero_kicker' => 'Podręcznik · Advocate · Krok po kroku',
'hero_title' => 'Jak używać Advocate.',
'hero_sub' => 'Kompletny przewodnik po każdym elemencie sterowania — od wyboru roli strony do czytania pisma i uruchamiania kontrargumentu.',
'toc_title' => 'W tym przewodniku',
's1_head' => '1. Język',
's2_head' => '2. Kogo reprezentujesz',
's3_head' => '3. Opis sprawy',
's4_head' => '4. Silnik',
's5_head' => '5. Sekcje korpusu',
's6_head' => '6. Zaawansowane ustawienia',
's7_head' => '7. Prześlij akta sprawy',
's8_head' => '8. Podgląd kątów badań',
's9_head' => '9. Rozumienie wyników',
's10_head' => '10. Kontrpismo',
's11_head' => '11. Wskazówki',
's1_title' => 'Język',
's1_body' => 'Cztery przyciski języka pojawiają się na górze formularza: EN, NO, UK, PL. Zmiana języka zmienia tylko etykiety formularza i interfejs użytkownika.',
's2_title' => 'Kogo reprezentujesz',
's2_body' => 'Najważniejszy element sterowania. Wybierz stronę, której pozycję agent powinien bronić.',
's2_table_col1' => 'Rola',
's2_table_col2' => 'Obowiązujące prawo',
's2_table_col3' => 'Typowe zastosowanie',
's3_title' => 'Opis sprawy',
's3_body' => 'Wpisz lub wklej fakty sprawy — do 4 000 znaków. Opisz, co się stało, jaki jest spór i co jest najważniejsze dla Twojego klienta.',
's3_tip' => 'Wskazówka: uwzględnij kluczowe daty, nazwy zaangażowanych organów i konkretne decyzje, które są kwestionowane.',
's4_title' => 'Silnik',
's4_body' => 'Dostępne są cztery silniki. Wszystkie używają tego samego pipeline Hard-RAG i tego samego korpusu.',
's4_table_col1' => 'Silnik',
's4_table_col2' => 'Prędkość',
's4_table_col3' => 'Najlepszy do',
's5_title' => 'Sekcje korpusu',
's5_body' => 'Osiem przełączalnych sekcji kontroluje, które części korpusu prawnego są przeszukiwane. Trzy są WŁĄCZONE domyślnie.',
's5_table_col1' => 'Sekcja',
's5_table_col2' => 'Domyślnie',
's5_table_col3' => 'Obejmuje',
's5_table_col4' => 'Włącz gdy',
's6_title' => 'Zaawansowane ustawienia',
's6_body' => 'Kliknij "Zaawansowane ustawienia", aby rozwinąć pięć suwaków.',
's6_table_col1' => 'Sterowanie',
's6_table_col2' => 'Zakres',
's6_table_col3' => 'Domyślnie',
's6_table_col4' => 'Co robi',
's7_title' => 'Prześlij akta sprawy',
's7_body' => 'Przeciągnij pliki PDF, DOCX lub TXT do strefy przesyłania. Do 5 plików. Przetwarzane tylko w pamięci — nic nie jest przechowywane.',
's7_tip' => 'Wskazówka: prześlij najbardziej istotny dokument, aby połączyć fragmenty specyficzne dla sprawy z prawem.',
's8_title' => 'Podgląd kątów badań',
's8_body' => 'Kliknij "Podgląd kątów badań" przed pełnym pobieraniem. Możesz edytować podpytania i kliknąć "Uruchom z tymi kątami".',
's8_tip' => 'Wskazówka: użyj podglądu przy złożonych lub nietypowych sprawach.',
's9_title' => 'Rozumienie wyników',
's9_body' => 'Obszar wyników ma cztery odrębne panele:',
's9_p1_title' => 'TWOJE NAJSILNIEJSZE ARGUMENTY',
's9_p1_body' => 'Lista punktowana najpotężniejszych argumentów na rzecz Twojego klienta.',
's9_p2_title' => 'Pismo adwokackie',
's9_p2_body' => 'Pełne stronnicze pismo — akapity prozą oparte na pobranych przepisach i orzeczeniach ECHR.',
's9_p3_title' => 'LUKI W POZYCJI STRONY PRZECIWNEJ',
's9_p3_body' => 'Słabości sprawy drugiej strony.',
's9_p4_title' => 'Ślad badawczy podpytań',
's9_p4_body' => 'Każde adversarialne podpytanie z pobranymi źródłami. Kliknij "Rozgałęź ↓" dla głębszego zagłębienia.',
's10_title' => 'Kontrpismo',
's10_body' => 'Na górze wyników pojawia się baner "Zobacz drugą stronę? — Uruchom kontrpismo →". Kliknij, aby uruchomić tę samą sprawę z rolą strony przeciwnej.',
's11_title' => 'Wskazówki dla najlepszych wyników',
'tip1' => 'Bądź konkretny w opisie sprawy — niejasne fakty dają niejasne podpytania.',
'tip2' => 'Prześlij najbardziej istotny dokument, aby połączyć fragmenty specyficzne dla sprawy z prawem.',
'tip3' => 'Użyj norweskiego silnika specjalistycznego dla spraw barnevernsloven i ECHR Art. 8.',
'tip4' => 'Włącz sekcję ECHR dla argumentów proporcjonalności lub elementów transgranicznych.',
'tip5' => 'Włącz sekcję Konwencji Haskiej dla przypadków międzynarodowego uprowadzenia dzieci.',
'tip6' => 'Uruchom kontrpismo przed rozprawą, aby przewidzieć argumenty do obalenia.',
'cta_title' => 'Gotowy do budowania swojej sprawy?',
'cta_sub' => 'Darmowe dla członków Do Better Norge. Nie jest wymagana karta kredytowa.',
'btn_open' => 'Otwórz Advocate →',
'btn_signin_cta' => 'Zaloguj się, aby użyć Advocate →',
'btn_register' => 'Zarejestruj się za darmo',
),
);
+263
View File
@@ -0,0 +1,263 @@
<?php
return array (
'en' =>
array (
'nav_about' => 'About',
'nav_guide' => 'User guide',
'nav_howit' => 'How it works',
'nav_opentool' => '← Open the tool',
'nav_signin' => 'Sign in',
'nav_open' => 'Open Advocate →',
'hero_kicker' => 'Architecture · Hard-RAG · Fine-tuned LLM',
'hero_title' => 'How Advocate builds your brief.',
'hero_sub' => 'A 7-step pipeline that turns your case description into a legally grounded partisan brief — adversarial sub-questions, hybrid retrieval from 220,000+ passages, and a fine-tuned Norwegian law model for synthesis.',
'stat_legal' => 'legal passages indexed',
'stat_slices' => 'corpus slices',
'stat_steps' => 'pipeline steps',
'stat_model' => 'fine-tuned model',
'pipe_eyebrow' => 'Pipeline architecture',
'pipe_title' => 'Seven steps from case facts to partisan brief.',
'pipe_sub' => 'Each step is visible in the Reasoning panel as the run progresses. No black-box generation — every retrieval pass, dedup, and synthesis is logged.',
'step1_title' => 'Query interpretation',
'step1_body' => 'The seed text is parsed for case type, parties involved, applicable acts, and time context. If the input is clear enough, this step is skipped and the raw seed is passed directly to expansion.',
'step2_title' => 'Query expansion',
'step2_body' => 'The agent generates 35 adversarial sub-questions, each framed to strengthen the selected party\'s position. Sub-questions target different legal angles: procedural obligations, proportionality, ECHR anchors, evidentiary standards.',
'step3_title' => 'Slice resolution',
'step3_body' => 'Active corpus slices are resolved into a Qdrant filter. Candidate documents from the selected slices constrain the vector search space — preventing retrieval from unrelated areas of law.',
'step4_title' => 'Upload indexing',
'step4_body' => 'Uploaded files are chunked into 512-token passages and embedded with nomic-embed-text. The resulting vectors are stored in an in-memory index — searched in the same retrieval pass as the legal corpus, then discarded at session end.',
'step5_title' => 'Retrieval',
'step5_body' => 'For each sub-question: hybrid BM25 + vector search → RRF fusion → reranker. Corpus hits and upload hits are merged, deduped, and trimmed to the configured "Sources kept" limit. Output: N unique ranked passages.',
'step6_title' => 'Synthesis',
'step6_body' => 'The selected engine (dbn-legal-agent or Azure gpt-4o) synthesises the full output: YOUR STRONGEST ARGUMENTS, the advocate brief, GAPS IN THE OPPOSING POSITION, uncertainties, and the next practical step. All framed for the selected party role.',
'step7_title' => 'Citation confidence',
'step7_body' => 'Each inline citation is verified against its source passage. A confidence score is computed and surfaced in the output header. Low-confidence citations are flagged. No hallucinated § numbers reach the final brief.',
'rag_eyebrow' => 'Hard-RAG retrieval',
'rag_title' => 'Every claim traced to a source.',
'rag_sub' => 'Hard-RAG means no citation appears in the brief unless it was retrieved from the corpus or your uploaded files. The retrieval pipeline is deterministic and logged.',
'rag_step1' => 'Active slices → Qdrant payload filter',
'rag_step2' => 'Sub-questions → BM25 keyword search',
'rag_step3' => 'Sub-questions → vector similarity search',
'rag_step4' => 'RRF fusion (rank-based merge)',
'rag_step5' => 'Cross-encoder reranker',
'rag_step6' => 'Upload chunks merged',
'rag_step7' => 'Dedup → top N sources',
'rag_step8' => 'Synthesis with citations',
'corpus_eyebrow' => 'Knowledge base',
'corpus_title' => '220,000+ passages across 8 corpus slices.',
'corpus_sub' => 'The same corpus that powers Korrespond. Indexed from Lovdata, ECHR HUDOC, Norwegian appellate decisions, and Bufdir guidance.',
'llm_eyebrow' => 'Fine-tuned model',
'llm_title' => 'dbn-legal-agent — trained for Norwegian child-welfare law.',
'llm_body_html' => 'A QLoRA fine-tune trained on Norwegian child-welfare and administrative law text. dbn-legal-agent understands the procedural vocabulary of barnevernsloven and barneloven — the proportionality threshold for omsorgsovertakelse, how Barnevernet\'s § 4-1 / 4-4 duty of assessment can be challenged, what ECHR Art. 8 requires in care-order cases, and how the principle of <em>barnets beste</em> is weighed against parental rights in Norwegian courts.',
'llm_table_col1' => 'Pipeline step',
'llm_table_col2' => 'dbn-legal-agent role',
'privacy_eyebrow' => 'Privacy by design',
'privacy_title' => 'Your case data never leaves the request.',
'privacy_p1' => 'Uploaded files are chunked and embedded in-memory only — vectors are discarded when your session ends.',
'privacy_p2' => 'Case descriptions are used for retrieval and synthesis only. They are not logged, stored, or used for training.',
'privacy_p3' => 'The Qdrant corpus is read-only during retrieval — no user data is written to the vector database.',
'privacy_p4' => 'Azure OpenAI processing occurs within EU-region endpoints (West Europe).',
'privacy_p5' => 'Session-scoped uploads: each run gets a fresh in-memory index, isolated from other users.',
'privacy_p6' => 'No cookies, no persistent identifiers, no cross-session tracking on the doc pages.',
'cta_title' => 'See it in action.',
'cta_sub' => 'Free for Do Better Norge members. No credit card required.',
'btn_open' => 'Open Advocate →',
'btn_signin_cta' => 'Sign in to use Advocate →',
'btn_register' => 'Register free',
),
'no' =>
array (
'nav_about' => 'Om',
'nav_guide' => 'Brukerveiledning',
'nav_howit' => 'Hvordan det fungerer',
'nav_opentool' => '← Åpne verktøyet',
'nav_signin' => 'Logg inn',
'nav_open' => 'Åpne Advocate →',
'hero_kicker' => 'Arkitektur · Hard-RAG · Finjustert LLM',
'hero_title' => 'Slik bygger Advocate sammendraget ditt.',
'hero_sub' => 'En 7-trinns pipeline som gjør saksbeskrivelsen din til et juridisk forankret partisk sammendrag — motstandsorienterte delspørsmål, hybrid henting fra 220 000+ passasjer og en finjustert norsk rettsmodell.',
'stat_legal' => 'juridiske passasjer indeksert',
'stat_slices' => 'corpus-seksjoner',
'stat_steps' => 'pipeline-trinn',
'stat_model' => 'finjustert modell',
'pipe_eyebrow' => 'Pipeline-arkitektur',
'pipe_title' => 'Sju trinn fra saksfakta til partisk sammendrag.',
'pipe_sub' => 'Hvert trinn er synlig i Begrunnelsespanelet mens kjøringen pågår.',
'step1_title' => 'Søkefortolkning',
'step1_body' => 'Seed-teksten analyseres for sakstype, involverte parter, gjeldende lover og tidssammenheng.',
'step2_title' => 'Søkeutvidelse',
'step2_body' => 'Agenten genererer 35 motstandsorienterte delspørsmål, hvert utformet for å styrke den valgte partens posisjon.',
'step3_title' => 'Seksjonsoppløsning',
'step3_body' => 'Aktive corpus-seksjoner løses til et Qdrant-filter. Kandidatdokumenter begrenser søkerommet.',
'step4_title' => 'Opplastingsindeksering',
'step4_body' => 'Opplastede filer deles inn i 512-token passasjer og innbygges med nomic-embed-text. Lagres kun i minne.',
'step5_title' => 'Henting',
'step5_body' => 'For hvert delspørsmål: hybrid BM25 + vektorsøk → RRF-sammenslåing → omrangering. Korpus- og opplastingstreff slås sammen, dedupes og trimmes.',
'step6_title' => 'Syntese',
'step6_body' => 'Den valgte motoren syntetiserer hele utdataene: DINE STERKESTE ARGUMENTER, advokatsammendrag, HULL I MOTPARTENS POSISJON, usikkerheter og neste steg.',
'step7_title' => 'Sitatkonfidens',
'step7_body' => 'Hvert inline-sitat verifiseres mot kildepassasjen. En konfidenspoengsum beregnes. Ingen hallusinerte §-numre.',
'rag_eyebrow' => 'Hard-RAG-henting',
'rag_title' => 'Hvert påstand sporet til en kilde.',
'rag_sub' => 'Hard-RAG betyr at ingen referanse vises i sammendraget med mindre den ble hentet fra korpuset eller filene dine.',
'rag_step1' => 'Aktive seksjoner → Qdrant nyttlast-filter',
'rag_step2' => 'Delspørsmål → BM25-nøkkelordssøk',
'rag_step3' => 'Delspørsmål → vektorsimilaritetssøk',
'rag_step4' => 'RRF-sammenslåing (rangbasert sammenslåing)',
'rag_step5' => 'Kryss-koder omrangerer',
'rag_step6' => 'Opplastingsstykker slås sammen',
'rag_step7' => 'Dedup → topp N-kilder',
'rag_step8' => 'Syntese med referanser',
'corpus_eyebrow' => 'Kunnskapsbase',
'corpus_title' => '220 000+ passasjer over 8 corpus-seksjoner.',
'corpus_sub' => 'Samme corpus som driver Korrespond. Indeksert fra Lovdata, ECHR HUDOC, norske lagmannsrettavgjørelser og Bufdir-veiledning.',
'llm_eyebrow' => 'Finjustert modell',
'llm_title' => 'dbn-legal-agent — trent for norsk barnevernsrett.',
'llm_body_html' => 'En QLoRA-finjustering trent på norsk barnevernsrett og forvaltningsrett. dbn-legal-agent forstår det prosessuelle vokabularet i barnevernsloven og barneloven — proporsjonalitetsterskelen for omsorgsovertakelse, hvordan Barnevernets vurderingsplikt kan utfordres, og hva EMK Art. 8 krever i omsorgsovertakelsessaker.',
'llm_table_col1' => 'Pipeline-trinn',
'llm_table_col2' => 'dbn-legal-agent rolle',
'privacy_eyebrow' => 'Personvern etter design',
'privacy_title' => 'Saksdataene dine forlater aldri forespørselen.',
'privacy_p1' => 'Opplastede filer behandles kun i minne — vektorer slettes når sesjonen avsluttes.',
'privacy_p2' => 'Saksbeskrivelser brukes kun for henting og syntese. De logges ikke eller lagres.',
'privacy_p3' => 'Qdrant-korpuset er skrivebeskyttet under henting.',
'privacy_p4' => 'Azure OpenAI-behandling skjer innen EU-regionsendepunkter (Vest-Europa).',
'privacy_p5' => 'Sesjonsscoped opplastinger: hvert kjøring får en ny minneindeks, isolert fra andre brukere.',
'privacy_p6' => 'Ingen informasjonskapsler, ingen vedvarende identifikatorer på dokumentsidene.',
'cta_title' => 'Se det i aksjon.',
'cta_sub' => 'Gratis for Do Better Norge-medlemmer. Ingen kredittkort nødvendig.',
'btn_open' => 'Åpne Advocate →',
'btn_signin_cta' => 'Logg inn for å bruke Advocate →',
'btn_register' => 'Registrer gratis',
),
'uk' =>
array (
'nav_about' => 'Про нас',
'nav_guide' => 'Посібник користувача',
'nav_howit' => 'Як це працює',
'nav_opentool' => '← Відкрити інструмент',
'nav_signin' => 'Увійти',
'nav_open' => 'Відкрити Advocate →',
'hero_kicker' => 'Архітектура · Hard-RAG · Fine-tuned LLM',
'hero_title' => 'Як Advocate будує ваше резюме.',
'hero_sub' => '7-кроковий конвеєр, що перетворює опис вашої справи на юридично обґрунтоване упереджене резюме.',
'stat_legal' => 'індексовані правові положення',
'stat_slices' => 'розділи корпусу',
'stat_steps' => 'кроки конвеєра',
'stat_model' => 'модель з тонким налаштуванням',
'pipe_eyebrow' => 'Архітектура конвеєра',
'pipe_title' => 'Сім кроків від фактів справи до упередженого резюме.',
'pipe_sub' => 'Кожен крок видно на панелі обґрунтування під час виконання.',
'step1_title' => 'Інтерпретація запиту',
'step1_body' => 'Вихідний текст аналізується для типу справи, залучених сторін, застосовних законів.',
'step2_title' => 'Розширення запиту',
'step2_body' => 'Агент генерує 3–5 змагальних підпитань, кожне з яких сформульоване для зміцнення позиції обраної сторони.',
'step3_title' => 'Вирішення розділів',
'step3_body' => 'Активні розділи корпусу перетворюються на фільтр Qdrant.',
'step4_title' => 'Індексування завантажень',
'step4_body' => 'Завантажені файли розбиваються на пасажі по 512 токенів та вбудовуються з nomic-embed-text. Зберігаються лише в пам\'яті.',
'step5_title' => 'Отримання',
'step5_body' => 'Для кожного підпитання: гібридний BM25 + векторний пошук → злиття RRF → ранжування. Пасажі корпусу та завантажень об\'єднуються і дедублюються.',
'step6_title' => 'Синтез',
'step6_body' => 'Вибраний двигун синтезує повний вивід: ВАШІ НАЙСИЛЬНІШІ АРГУМЕНТИ, адвокатське резюме, ПРОГАЛИНИ В ПОЗИЦІЇ ОПОНЕНТА, невизначеності та наступний крок.',
'step7_title' => 'Достовірність цитат',
'step7_body' => 'Кожна вбудована цитата перевіряється по вихідному пасажу. Жодних вигаданих § номерів.',
'rag_eyebrow' => 'Отримання Hard-RAG',
'rag_title' => 'Кожне твердження прив\'язане до джерела.',
'rag_sub' => 'Hard-RAG означає, що жодна цитата не з\'являється в резюме, якщо вона не була отримана з корпусу або ваших файлів.',
'rag_step1' => 'Активні розділи → фільтр навантаження Qdrant',
'rag_step2' => 'Підпитання → ключове слово BM25',
'rag_step3' => 'Підпитання → векторний пошук подібності',
'rag_step4' => 'Злиття RRF',
'rag_step5' => 'Кросс-кодер ранжування',
'rag_step6' => 'Фрагменти завантажень об\'єднані',
'rag_step7' => 'Дедублікація → топ N джерел',
'rag_step8' => 'Синтез з цитатами',
'corpus_eyebrow' => 'База знань',
'corpus_title' => '220 000+ пасажів у 8 розділах корпусу.',
'corpus_sub' => 'Той самий корпус, що живить Korrespond. Індексований з Lovdata, ЄСПЛ HUDOC, норвезьких апеляційних рішень та керівництва Bufdir.',
'llm_eyebrow' => 'Модель з тонким налаштуванням',
'llm_title' => 'dbn-legal-agent — навчена для норвезького права із захисту дітей.',
'llm_body_html' => 'Модель QLoRA, налаштована на текст норвезького права із захисту дітей та адміністративного права. dbn-legal-agent розуміє процедурну лексику barnevernsloven і barneloven.',
'llm_table_col1' => 'Крок конвеєра',
'llm_table_col2' => 'Роль dbn-legal-agent',
'privacy_eyebrow' => 'Конфіденційність за дизайном',
'privacy_title' => 'Ваші дані справи ніколи не покидають запит.',
'privacy_p1' => 'Завантажені файли обробляються лише в пам\'яті — вектори видаляються по закінченні сесії.',
'privacy_p2' => 'Описи справ використовуються лише для отримання та синтезу. Не журналюються і не зберігаються.',
'privacy_p3' => 'Корпус Qdrant доступний лише для читання під час отримання.',
'privacy_p4' => 'Обробка Azure OpenAI відбувається в кінцевих точках регіону ЄС (Західна Європа).',
'privacy_p5' => 'Завантаження в рамках сесії: кожен запуск отримує новий індекс у пам\'яті, ізольований від інших.',
'privacy_p6' => 'Без файлів cookie, без постійних ідентифікаторів на сторінках документів.',
'cta_title' => 'Побачте це в дії.',
'cta_sub' => 'Безкоштовно для членів Do Better Norge. Кредитна картка не потрібна.',
'btn_open' => 'Відкрити Advocate →',
'btn_signin_cta' => 'Увійти, щоб використовувати Advocate →',
'btn_register' => 'Зареєструватися безкоштовно',
),
'pl' =>
array (
'nav_about' => 'O nas',
'nav_guide' => 'Podręcznik użytkownika',
'nav_howit' => 'Jak to działa',
'nav_opentool' => '← Otwórz narzędzie',
'nav_signin' => 'Zaloguj się',
'nav_open' => 'Otwórz Advocate →',
'hero_kicker' => 'Architektura · Hard-RAG · Fine-tuned LLM',
'hero_title' => 'Jak Advocate buduje Twoje pismo.',
'hero_sub' => '7-krokowy pipeline, który przekształca opis Twojej sprawy w prawnie ugruntowane stronnicze pismo.',
'stat_legal' => 'zindeksowane przepisy prawne',
'stat_slices' => 'sekcje korpusu',
'stat_steps' => 'kroki pipeline',
'stat_model' => 'model dostosowany',
'pipe_eyebrow' => 'Architektura pipeline',
'pipe_title' => 'Siedem kroków od faktów sprawy do stronniczego pisma.',
'pipe_sub' => 'Każdy krok jest widoczny w panelu Reasoning podczas przebiegu.',
'step1_title' => 'Interpretacja zapytania',
'step1_body' => 'Tekst źródłowy jest analizowany pod kątem typu sprawy, zaangażowanych stron i obowiązujących przepisów.',
'step2_title' => 'Rozszerzenie zapytania',
'step2_body' => 'Agent generuje 35 adversarialnych podpytań, każde sformułowane w celu wzmocnienia pozycji wybranej strony.',
'step3_title' => 'Rozwiązanie sekcji',
'step3_body' => 'Aktywne sekcje korpusu są przekształcane w filtr Qdrant.',
'step4_title' => 'Indeksowanie przesłanych plików',
'step4_body' => 'Przesłane pliki są dzielone na fragmenty po 512 tokenów i osadzane z nomic-embed-text. Przechowywane tylko w pamięci.',
'step5_title' => 'Pobieranie',
'step5_body' => 'Dla każdego podpytania: hybryda BM25 + wyszukiwanie wektorowe → fuzja RRF → reranking. Fragmenty korpusu i przesłanych plików są łączone i deduplikowane.',
'step6_title' => 'Synteza',
'step6_body' => 'Wybrany silnik syntetyzuje pełny wynik: TWOJE NAJSILNIEJSZE ARGUMENTY, pismo adwokackie, LUKI W POZYCJI STRONY PRZECIWNEJ, niepewności i następny krok.',
'step7_title' => 'Pewność cytacji',
'step7_body' => 'Każda cytacja inline jest weryfikowana względem fragmentu źródłowego. Żadnych halucynowanych § numerów.',
'rag_eyebrow' => 'Pobieranie Hard-RAG',
'rag_title' => 'Każde twierdzenie powiązane ze źródłem.',
'rag_sub' => 'Hard-RAG oznacza, że żadna cytacja nie pojawia się w piśmie, chyba że została pobrana z korpusu lub przesłanych plików.',
'rag_step1' => 'Aktywne sekcje → filtr ładunku Qdrant',
'rag_step2' => 'Podpytania → wyszukiwanie słów kluczowych BM25',
'rag_step3' => 'Podpytania → wektorowe wyszukiwanie podobieństwa',
'rag_step4' => 'Fuzja RRF',
'rag_step5' => 'Cross-encoder reranking',
'rag_step6' => 'Fragmenty przesłanych plików połączone',
'rag_step7' => 'Dedup → top N źródeł',
'rag_step8' => 'Synteza z cytacjami',
'corpus_eyebrow' => 'Baza wiedzy',
'corpus_title' => '220 000+ fragmentów w 8 sekcjach korpusu.',
'corpus_sub' => 'Ten sam korpus, który napędza Korrespond. Zindeksowany z Lovdata, ECHR HUDOC, norweskich orzeczeń apelacyjnych i wytycznych Bufdir.',
'llm_eyebrow' => 'Model dostosowany',
'llm_title' => 'dbn-legal-agent — wytrenowany dla norweskiego prawa opieki nad dziećmi.',
'llm_body_html' => 'Model QLoRA dostosowany do tekstów norweskiego prawa dotyczącego opieki nad dziećmi i prawa administracyjnego. dbn-legal-agent rozumie słownictwo proceduralne barnevernsloven i barneloven.',
'llm_table_col1' => 'Krok pipeline',
'llm_table_col2' => 'Rola dbn-legal-agent',
'privacy_eyebrow' => 'Prywatność przez projekt',
'privacy_title' => 'Dane Twojej sprawy nigdy nie opuszczają żądania.',
'privacy_p1' => 'Przesłane pliki są przetwarzane tylko w pamięci — wektory są usuwane po zakończeniu sesji.',
'privacy_p2' => 'Opisy spraw są używane tylko do pobierania i syntezy. Nie są rejestrowane ani przechowywane.',
'privacy_p3' => 'Korpus Qdrant jest tylko do odczytu podczas pobierania.',
'privacy_p4' => 'Przetwarzanie Azure OpenAI odbywa się w punktach końcowych regionu UE (Europa Zachodnia).',
'privacy_p5' => 'Przesyłanie w zakresie sesji: każde uruchomienie otrzymuje nowy indeks w pamięci, odizolowany od innych.',
'privacy_p6' => 'Bez ciasteczek, bez stałych identyfikatorów na stronach dokumentów.',
'cta_title' => 'Zobacz to w akcji.',
'cta_sub' => 'Darmowe dla członków Do Better Norge. Nie jest wymagana karta kredytowa.',
'btn_open' => 'Otwórz Advocate →',
'btn_signin_cta' => 'Zaloguj się, aby użyć Advocate →',
'btn_register' => 'Zarejestruj się za darmo',
),
);
+1
View File
@@ -55,6 +55,7 @@ function imgSlot(string $slot, string $file, string $label, string $caption, str
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin> <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Crimson+Pro:wght@400;600;700&family=IBM+Plex+Sans:wght@400;500;600;700&display=swap"> <link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Crimson+Pro:wght@400;600;700&family=IBM+Plex+Sans:wght@400;500;600;700&display=swap">
<link rel="stylesheet" href="assets/css/tools.css"> <link rel="stylesheet" href="assets/css/tools.css">
<link rel="stylesheet" href="assets/css/dbn-tools-redesign.css">
</head> </head>
<body class="kdoc-page"> <body class="kdoc-page">
+2 -1
View File
@@ -25,8 +25,9 @@ $langPath = '/workbench.php';
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin> <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Crimson+Pro:wght@400;600;700&family=IBM+Plex+Sans:wght@400;500;600;700&display=swap"> <link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Crimson+Pro:wght@400;600;700&family=IBM+Plex+Sans:wght@400;500;600;700&display=swap">
<link rel="stylesheet" href="assets/css/tools.css"> <link rel="stylesheet" href="assets/css/tools.css">
<link rel="stylesheet" href="assets/css/dbn-tools-redesign.css">
</head> </head>
<body data-authenticated="true" class="lt-app workbench-page"> <body data-authenticated="true" data-active-tool="workbench" class="lt-app workbench-page">
<script> <script>
window.DBN_TOOLS_AUTHENTICATED = true; window.DBN_TOOLS_AUTHENTICATED = true;
window.DBN_TOOLS_LANG = <?= json_encode($uiLang, JSON_UNESCAPED_UNICODE) ?>; window.DBN_TOOLS_LANG = <?= json_encode($uiLang, JSON_UNESCAPED_UNICODE) ?>;