Add Tool info links and MCP section to tool cards and preview pages

- Dashboard: add "Tool info" link → preview.php on every tool card footer
- Landing page: convert lt-card <a> to div+onclick, add footer with "Learn more" link and copyable MCP slug pill
- preview.php: add MCP Integration section per tool (slug, copy button, claude_desktop_config.json snippet, login note)
- CSS: lt-card__footer, lt-card__mcp-pill, lt-preview-mcp section styles

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-05-24 21:25:09 +02:00
parent 61425d7f17
commit 38d617bf02
4 changed files with 207 additions and 5 deletions
+119
View File
@@ -877,3 +877,122 @@ body[data-active-tool='citations'] .results {
padding: 0.55rem 1rem; padding: 0.55rem 1rem;
} }
} }
/* ── Landing page card footer (Tool info + MCP pill) ──────────── */
.lt-card__footer {
display: flex;
align-items: center;
gap: 0.6rem;
flex-wrap: wrap;
margin-top: 1rem;
padding-top: 0.75rem;
border-top: 1px solid rgba(0, 32, 91, 0.08);
}
.lt-card__footer-link--primary {
font-family: ui-monospace, 'IBM Plex Mono', monospace;
font-size: 0.68rem;
font-weight: 700;
letter-spacing: 0.06em;
text-transform: uppercase;
color: var(--dbn-blue);
text-decoration: none;
}
.lt-card__footer-link--primary:hover { color: var(--dbn-red); }
.lt-card__mcp-pill {
font-family: ui-monospace, 'IBM Plex Mono', monospace;
font-size: 0.64rem;
background: #f1f5f9;
border: 1px solid #e2e8f0;
color: #64748b;
padding: 2px 8px;
border-radius: 4px;
cursor: pointer;
white-space: nowrap;
margin-left: auto;
transition: background 0.15s;
}
.lt-card__mcp-pill:hover { background: #e2e8f0; }
/* ── Preview page MCP section ─────────────────────────────────── */
.lt-preview-mcp {
background: #f8fafc;
border-top: 1px solid #e5e7eb;
border-bottom: 1px solid #e5e7eb;
padding: 3rem 1.5rem;
}
.lt-preview-mcp__inner {
max-width: 760px;
margin: 0 auto;
display: flex;
flex-direction: column;
gap: 1.25rem;
}
.lt-preview-mcp__head {
display: flex;
align-items: flex-start;
gap: 1rem;
}
.lt-preview-mcp__icon { font-size: 1.6rem; line-height: 1; flex-shrink: 0; margin-top: 0.15rem; }
.lt-preview-mcp__title {
font-size: 1.25rem;
font-weight: 700;
color: var(--dbn-blue);
margin: 0 0 0.25rem;
}
.lt-preview-mcp__sub { font-size: 0.9rem; color: #6b7280; margin: 0; }
.lt-preview-mcp__slug-row {
display: flex;
align-items: center;
gap: 0.75rem;
background: #fff;
border: 1px solid #e5e7eb;
border-radius: 8px;
padding: 0.7rem 1rem;
flex-wrap: wrap;
}
.lt-preview-mcp__slug-label { font-size: 0.8rem; color: #6b7280; flex-shrink: 0; }
.lt-preview-mcp__slug {
font-family: ui-monospace, 'IBM Plex Mono', monospace;
font-size: 0.9rem;
color: var(--dbn-blue);
font-weight: 600;
flex: 1;
}
.lt-preview-mcp__copy {
padding: 0.3rem 0.85rem;
background: var(--dbn-blue);
color: #fff;
border: none;
border-radius: 5px;
font-size: 0.78rem;
font-weight: 600;
cursor: pointer;
flex-shrink: 0;
transition: background 0.15s;
}
.lt-preview-mcp__copy:hover { background: var(--dbn-soft-blue); }
.lt-preview-mcp__snippet { display: flex; flex-direction: column; gap: 0.4rem; }
.lt-preview-mcp__snippet-label {
font-family: ui-monospace, 'IBM Plex Mono', monospace;
font-size: 0.7rem;
color: #9ca3af;
text-transform: uppercase;
letter-spacing: 0.06em;
}
.lt-preview-mcp__pre {
background: #1e293b;
color: #e2e8f0;
font-family: ui-monospace, 'IBM Plex Mono', monospace;
font-size: 0.82rem;
line-height: 1.65;
padding: 1.1rem 1.25rem;
border-radius: 8px;
overflow-x: auto;
margin: 0;
}
.lt-preview-mcp__note {
font-size: 0.82rem;
color: #9ca3af;
margin: 0;
}
.lt-preview-mcp__note a { color: var(--dbn-blue); }
+8 -1
View File
@@ -125,6 +125,7 @@ $dashL = [
'guide_link' => 'Guide', 'guide_link' => 'Guide',
'tech_link' => 'Technical', 'tech_link' => 'Technical',
'open_tool' => 'Open tool', 'open_tool' => 'Open tool',
'tool_info' => 'Tool info',
], ],
'no' => [ 'no' => [
'acct_header' => 'Konto', 'acct_header' => 'Konto',
@@ -152,6 +153,7 @@ $dashL = [
'guide_link' => 'Guide', 'guide_link' => 'Guide',
'tech_link' => 'Teknisk', 'tech_link' => 'Teknisk',
'open_tool' => 'Åpne verktøy', 'open_tool' => 'Åpne verktøy',
'tool_info' => 'Verktøyinfo',
], ],
'uk' => [ 'uk' => [
'acct_header' => 'Обліковий запис', 'acct_header' => 'Обліковий запис',
@@ -179,6 +181,7 @@ $dashL = [
'guide_link' => 'Посібник', 'guide_link' => 'Посібник',
'tech_link' => 'Технічний', 'tech_link' => 'Технічний',
'open_tool' => 'Відкрити', 'open_tool' => 'Відкрити',
'tool_info' => 'Про інструмент',
], ],
'pl' => [ 'pl' => [
'acct_header' => 'Konto', 'acct_header' => 'Konto',
@@ -206,6 +209,7 @@ $dashL = [
'guide_link' => 'Poradnik', 'guide_link' => 'Poradnik',
'tech_link' => 'Techniczny', 'tech_link' => 'Techniczny',
'open_tool' => 'Otwórz', 'open_tool' => 'Otwórz',
'tool_info' => 'Info',
], ],
]; ];
$dl = $dashL[$uiLang] ?? $dashL['en']; $dl = $dashL[$uiLang] ?? $dashL['en'];
@@ -462,9 +466,12 @@ window.DBN_TOOLS_LANG = <?= json_encode($uiLang, JSON_UNESCAPED_UNICODE) ?>;
</div> </div>
<p style="margin:0; font-size:.98rem; color:#4b5563; line-height:1.55;"><?= htmlspecialchars($item['description']) ?></p> <p style="margin:0; font-size:.98rem; color:#4b5563; line-height:1.55;"><?= htmlspecialchars($item['description']) ?></p>
<div class="dash-card-footer"> <div class="dash-card-footer">
<a href="/preview.php?tool=<?= htmlspecialchars($slug) ?><?= $uiLang !== 'en' ? '&amp;lang=' . urlencode($uiLang) : '' ?>" onclick="event.stopPropagation();"
style="color:#374151; font-size:.88rem; text-decoration:none; white-space:nowrap;"><?= htmlspecialchars($dl['tool_info']) ?></a>
<?php if ($docs): ?> <?php if ($docs): ?>
<span style="color:#d1d5db;" aria-hidden="true">·</span>
<a href="<?= htmlspecialchars($docs[0] . $langSuffix) ?>" onclick="event.stopPropagation();" <a href="<?= htmlspecialchars($docs[0] . $langSuffix) ?>" onclick="event.stopPropagation();"
style="color:#00205B; font-size:.88rem; font-weight:600; text-decoration:none; white-space:nowrap;"><?= htmlspecialchars($dl['about_link']) ?></a> style="color:#374151; font-size:.88rem; text-decoration:none; white-space:nowrap;"><?= htmlspecialchars($dl['about_link']) ?></a>
<span style="color:#d1d5db;" aria-hidden="true">·</span> <span style="color:#d1d5db;" aria-hidden="true">·</span>
<a href="<?= htmlspecialchars($docs[1] . $langSuffix) ?>" onclick="event.stopPropagation();" <a href="<?= htmlspecialchars($docs[1] . $langSuffix) ?>" onclick="event.stopPropagation();"
style="color:#374151; font-size:.88rem; text-decoration:none; white-space:nowrap;"><?= htmlspecialchars($dl['guide_link']) ?></a> style="color:#374151; font-size:.88rem; text-decoration:none; white-space:nowrap;"><?= htmlspecialchars($dl['guide_link']) ?></a>
+30 -4
View File
@@ -56,6 +56,19 @@ $toolsLogin = 'https://dobetternorge.no/tools-login.php?return=' . urlencode('/
$registerUrl = 'https://dobetternorge.no/register.php'; $registerUrl = 'https://dobetternorge.no/register.php';
require_once __DIR__ . '/includes/tool-svgs.php'; require_once __DIR__ . '/includes/tool-svgs.php';
$toolMcpSlugs = [
'transcribe' => 'dbn.transcribe_audio',
'timeline' => 'dbn.timeline',
'redact' => 'dbn.redact',
'korrespond' => 'dbn.korrespond',
'barnevernet' => 'dbn.barnevernet_analyze',
'advocate' => 'dbn.advocate_brief',
'deep-research' => 'dbn.deep_research',
'discrepancy' => 'dbn.discrepancy_find',
'corpus' => 'dbn.list_documents',
'citations' => 'dbn.citation_graph',
];
?> ?>
<!doctype html> <!doctype html>
<html lang="<?= htmlspecialchars($uiLang) ?>"> <html lang="<?= htmlspecialchars($uiLang) ?>">
@@ -212,8 +225,14 @@ window.DBN_TOOLS_LANG = <?= json_encode($uiLang, JSON_UNESCAPED_UNICODE) ?>;
<span class="lt-card__arrow"><?= htmlspecialchars(dbnToolsT('primary_access', $uiLang)) ?> &#x2192;</span> <span class="lt-card__arrow"><?= htmlspecialchars(dbnToolsT('primary_access', $uiLang)) ?> &#x2192;</span>
</div> </div>
</a> </a>
<?php foreach ($tools as $slug => $item): ?> <?php foreach ($tools as $slug => $item):
<a class="lt-card" href="preview.php?tool=<?= htmlspecialchars($slug) ?>" data-tool="<?= htmlspecialchars($slug) ?>"> $previewUrl = 'preview.php?tool=' . urlencode($slug) . ($uiLang !== 'en' ? '&lang=' . urlencode($uiLang) : '');
$mcpSlug = $toolMcpSlugs[$slug] ?? null;
?>
<div class="lt-card" data-tool="<?= htmlspecialchars($slug) ?>"
onclick="location.href='<?= htmlspecialchars($previewUrl) ?>'"
style="cursor:pointer;" tabindex="0" role="link"
onkeydown="if(event.key==='Enter')location.href='<?= htmlspecialchars($previewUrl) ?>'">
<div class="lt-card__art" aria-hidden="true"> <div class="lt-card__art" aria-hidden="true">
<?= $toolSvgs[$slug] ?? '' ?> <?= $toolSvgs[$slug] ?? '' ?>
</div> </div>
@@ -221,9 +240,16 @@ window.DBN_TOOLS_LANG = <?= json_encode($uiLang, JSON_UNESCAPED_UNICODE) ?>;
<p class="lt-card__badge"><?= htmlspecialchars($item['badge']) ?></p> <p class="lt-card__badge"><?= htmlspecialchars($item['badge']) ?></p>
<h3 class="lt-card__title"><?= htmlspecialchars($item['label']) ?></h3> <h3 class="lt-card__title"><?= htmlspecialchars($item['label']) ?></h3>
<p class="lt-card__desc"><?= htmlspecialchars($item['description']) ?></p> <p class="lt-card__desc"><?= htmlspecialchars($item['description']) ?></p>
<span class="lt-card__arrow"><?= htmlspecialchars(dbnToolsT('learn_more', $uiLang)) ?></span> <div class="lt-card__footer">
<a href="<?= htmlspecialchars($previewUrl) ?>" onclick="event.stopPropagation();"
class="lt-card__footer-link lt-card__footer-link--primary"><?= htmlspecialchars(dbnToolsT('learn_more', $uiLang)) ?> →</a>
<?php if ($mcpSlug): ?>
<code class="lt-card__mcp-pill" onclick="event.stopPropagation(); navigator.clipboard.writeText('<?= htmlspecialchars($mcpSlug) ?>').then(()=>{this.textContent='Copied!';setTimeout(()=>{this.textContent='<?= htmlspecialchars($mcpSlug) ?>';},1200);});"
title="Copy MCP slug"><?= htmlspecialchars($mcpSlug) ?></code>
<?php endif; ?>
</div>
</div> </div>
</a> </div>
<?php endforeach; ?> <?php endforeach; ?>
</div> </div>
</section> </section>
+50
View File
@@ -17,6 +17,20 @@ $tool = $tools[$slug];
$returnPath = '/'; $returnPath = '/';
$toolsLogin = 'https://dobetternorge.no/tools-login.php?return=' . urlencode($returnPath); $toolsLogin = 'https://dobetternorge.no/tools-login.php?return=' . urlencode($returnPath);
$toolMcpSlugs = [
'transcribe' => 'dbn.transcribe_audio',
'timeline' => 'dbn.timeline',
'redact' => 'dbn.redact',
'korrespond' => 'dbn.korrespond',
'barnevernet' => 'dbn.barnevernet_analyze',
'advocate' => 'dbn.advocate_brief',
'deep-research' => 'dbn.deep_research',
'discrepancy' => 'dbn.discrepancy_find',
'corpus' => 'dbn.list_documents',
'citations' => 'dbn.citation_graph',
];
$toolMcpSlug = $toolMcpSlugs[$slug] ?? null;
// ── Localized pitch + feature content (en / no; uk/pl fall back to en) ──────── // ── Localized pitch + feature content (en / no; uk/pl fall back to en) ────────
$localizedContent = [ $localizedContent = [
@@ -560,6 +574,42 @@ $sample = $samples[$slug];
</div> </div>
</section> </section>
<?php if ($toolMcpSlug): ?>
<section class="lt-preview-mcp">
<div class="lt-preview-mcp__inner">
<div class="lt-preview-mcp__head">
<span class="lt-preview-mcp__icon" aria-hidden="true">⚙️</span>
<div>
<h2 class="lt-preview-mcp__title"><?= $uiLang === 'no' ? 'MCP-integrasjon' : 'MCP Integration' ?></h2>
<p class="lt-preview-mcp__sub"><?= $uiLang === 'no' ? 'Bruk dette verktøyet direkte fra Claude Desktop, Claude Code eller Cursor.' : 'Use this tool directly from Claude Desktop, Claude Code, or Cursor.' ?></p>
</div>
</div>
<div class="lt-preview-mcp__slug-row">
<span class="lt-preview-mcp__slug-label"><?= $uiLang === 'no' ? 'MCP-verktøyslug' : 'MCP tool slug' ?></span>
<code class="lt-preview-mcp__slug" id="mcpSlugCode"><?= htmlspecialchars($toolMcpSlug) ?></code>
<button class="lt-preview-mcp__copy" onclick="navigator.clipboard.writeText('<?= htmlspecialchars($toolMcpSlug) ?>').then(()=>{this.textContent='<?= $uiLang === 'no' ? 'Kopiert!' : 'Copied!' ?>';setTimeout(()=>{this.textContent='<?= $uiLang === 'no' ? 'Kopier' : 'Copy' ?>';},1400);});"><?= $uiLang === 'no' ? 'Kopier' : 'Copy' ?></button>
</div>
<div class="lt-preview-mcp__snippet">
<p class="lt-preview-mcp__snippet-label">claude_desktop_config.json</p>
<pre class="lt-preview-mcp__pre">{
"mcpServers": {
"dbn-tools": {
"command": "npx",
"args": ["-y", "@dobetternorge/mcp"],
"env": { "DBN_API_TOKEN": "YOUR_TOKEN" }
}
}
}</pre>
</div>
<p class="lt-preview-mcp__note">
<?= $uiLang === 'no'
? 'API-token krever Plus- eller Pro-plan. <a href="' . htmlspecialchars($toolsLogin) . '">Logg inn</a> for å generere token og se full oppsettsguide.'
: 'API tokens require a Plus or Pro plan. <a href="' . htmlspecialchars($toolsLogin) . '">Log in</a> to generate a token and view the full setup guide.' ?>
</p>
</div>
</section>
<?php endif; ?>
<section class="lt-preview-cta"> <section class="lt-preview-cta">
<div class="lt-preview-cta__inner"> <div class="lt-preview-cta__inner">
<p class="lt-preview-cta__eyebrow">Do Better Norge members</p> <p class="lt-preview-cta__eyebrow">Do Better Norge members</p>