thumbgate 1.5.8 โ†’ 1.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -6,6 +6,8 @@
6
6
  <title>ThumbGate Dashboard โ€” Gate Stats, Approval Rate, Prevention Impact</title>
7
7
  <meta name="description" content="Live dashboard showing gate enforcement stats, approval rate trends, prevention impact, and system health for ThumbGate pre-action gates.">
8
8
  <link rel="canonical" href="https://thumbgate-production.up.railway.app/dashboard">
9
+ <link rel="icon" type="image/png" href="/thumbgate-icon.png">
10
+ <link rel="apple-touch-icon" href="/assets/brand/thumbgate-mark.svg">
9
11
  <meta name="robots" content="noindex">
10
12
  <!-- Privacy-friendly analytics by Plausible -->
11
13
  <script defer data-domain="thumbgate-production.up.railway.app" src="https://plausible.io/js/script.js"></script>
@@ -26,7 +28,8 @@
26
28
  /* NAV */
27
29
  nav { position: sticky; top: 0; z-index: 50; background: rgba(10,10,11,0.85); backdrop-filter: blur(12px); border-bottom: 1px solid var(--border); padding: 14px 0; }
28
30
  nav .container { display: flex; justify-content: space-between; align-items: center; }
29
- .nav-logo { font-weight: 700; font-size: 15px; color: var(--text); text-decoration: none; }
31
+ .nav-logo { font-weight: 700; font-size: 15px; color: var(--text); text-decoration: none; display: inline-flex; align-items: center; gap: 8px; }
32
+ .nav-logo .logo-mark { width: 28px; height: 28px; display: block; }
30
33
  .nav-links { display: flex; gap: 16px; align-items: center; }
31
34
  .nav-links a { color: var(--text-muted); text-decoration: none; font-size: 13px; }
32
35
  .nav-links a:hover { color: var(--text); }
@@ -168,7 +171,7 @@
168
171
 
169
172
  <nav>
170
173
  <div class="container">
171
- <a href="/" class="nav-logo">๐Ÿ‘๐Ÿ‘Ž ThumbGate Dashboard</a>
174
+ <a href="/" class="nav-logo"><img src="/assets/brand/thumbgate-mark-inline.svg" alt="ThumbGate" class="logo-mark" width="28" height="28"><span class="logo-text">ThumbGate Dashboard</span></a>
172
175
  <div class="nav-links">
173
176
  <a href="/dashboard" class="active" style="color:var(--cyan);">Dashboard</a>
174
177
  <a href="/lessons">Lessons</a>
@@ -219,6 +222,32 @@
219
222
  <a class="stat-card" data-card-action="gates" onclick="selectCard(this,'gates');return false;" href="#" style="cursor:pointer;text-decoration:none;color:inherit;display:block;" title="Click to view active gates"><div class="stat-label">Active Gates</div><div class="stat-value cyan" id="statGates">โ€”</div></a>
220
223
  </div>
221
224
 
225
+ <div class="panel" id="reviewDeltaPanel" style="margin-bottom:20px;">
226
+ <div style="display:flex;justify-content:space-between;gap:16px;align-items:flex-start;flex-wrap:wrap;">
227
+ <div>
228
+ <h3 style="margin:0 0 8px 0;font-size:14px;letter-spacing:0.04em;text-transform:uppercase;color:var(--text-muted);">๐Ÿ†• Since Last Review</h3>
229
+ <p class="template-summary" id="reviewDeltaHeadline" style="margin-bottom:0;">No review checkpoint yet. Mark the current dashboard as reviewed to start seeing only new changes.</p>
230
+ </div>
231
+ <button class="btn-outline" id="reviewCheckpointBtn" onclick="markReviewed()">Mark Current Dashboard Reviewed</button>
232
+ </div>
233
+ <div class="generated-grid" id="reviewDeltaStats" style="margin-top:16px;">
234
+ <div class="team-card"><div class="team-kicker">New feedback</div><div class="team-value" id="reviewDeltaFeedback">0</div><div class="team-note">events since checkpoint</div></div>
235
+ <div class="team-card"><div class="team-kicker">New negatives</div><div class="team-value" id="reviewDeltaNegative">0</div><div class="team-note">fresh review risk</div></div>
236
+ <div class="team-card"><div class="team-kicker">New lessons</div><div class="team-value" id="reviewDeltaLessons">0</div><div class="team-note">promoted since checkpoint</div></div>
237
+ <div class="team-card"><div class="team-kicker">New blocks</div><div class="team-value" id="reviewDeltaBlocks">0</div><div class="team-note">gate hits since checkpoint</div></div>
238
+ </div>
239
+ <div class="team-columns" style="margin-top:16px;">
240
+ <div class="panel">
241
+ <h3>Checkpoint</h3>
242
+ <div id="reviewDeltaCheckpoint" class="template-summary" style="margin-bottom:0;">Waiting for dashboard data...</div>
243
+ </div>
244
+ <div class="panel">
245
+ <h3>Newest items</h3>
246
+ <div id="reviewDeltaLatest" class="template-summary" style="margin-bottom:0;">No new review activity yet.</div>
247
+ </div>
248
+ </div>
249
+ </div>
250
+
222
251
  <!-- TABS -->
223
252
  <div class="tabs">
224
253
  <div class="tab active" onclick="switchTab('search')">๐Ÿ” Search Memories</div>
@@ -706,8 +735,70 @@ async function loadDashboardData() {
706
735
  } catch (e) { /* insights degrade gracefully */ }
707
736
  }
708
737
 
738
+ function formatReviewTimestamp(value) {
739
+ if (!value) return 'Not reviewed yet';
740
+ var date = new Date(value);
741
+ if (Number.isNaN(date.getTime())) return String(value);
742
+ return date.toLocaleString();
743
+ }
744
+
745
+ function renderReviewDelta(reviewDelta) {
746
+ var summary = reviewDelta || {};
747
+ var button = document.getElementById('reviewCheckpointBtn');
748
+ document.getElementById('reviewDeltaHeadline').textContent = summary.headline || 'No review checkpoint yet. Mark the current dashboard as reviewed to start seeing only new changes.';
749
+ document.getElementById('reviewDeltaFeedback').textContent = String(summary.feedbackAdded || 0);
750
+ document.getElementById('reviewDeltaNegative').textContent = String(summary.negativeAdded || 0);
751
+ document.getElementById('reviewDeltaLessons').textContent = String(summary.lessonsAdded || 0);
752
+ document.getElementById('reviewDeltaBlocks').textContent = String(summary.blocksAdded || 0);
753
+
754
+ var checkpointParts = [];
755
+ checkpointParts.push('<div><strong>Reviewed:</strong> ' + escHtml(formatReviewTimestamp(summary.reviewedAt)) + '</div>');
756
+ if (summary.previousHead || summary.currentHead) {
757
+ checkpointParts.push('<div style="margin-top:8px;"><strong>Git:</strong> ' + escHtml(summary.previousHead ? summary.previousHead.slice(0, 8) : 'none') + ' โ†’ ' + escHtml(summary.currentHead ? summary.currentHead.slice(0, 8) : 'none') + '</div>');
758
+ }
759
+ document.getElementById('reviewDeltaCheckpoint').innerHTML = checkpointParts.join('');
760
+
761
+ var latestBits = [];
762
+ if (summary.latestFeedback) {
763
+ latestBits.push('<div><strong>Feedback:</strong> ' + escHtml(summary.latestFeedback.title || 'Feedback event') + ' <span style="color:var(--text-muted);">(' + escHtml(formatReviewTimestamp(summary.latestFeedback.timestamp)) + ')</span></div>');
764
+ }
765
+ if (summary.latestLesson) {
766
+ latestBits.push('<div style="margin-top:8px;"><strong>Lesson:</strong> ' + escHtml(summary.latestLesson.title || 'Lesson event') + ' <span style="color:var(--text-muted);">(' + escHtml(formatReviewTimestamp(summary.latestLesson.timestamp)) + ')</span></div>');
767
+ }
768
+ document.getElementById('reviewDeltaLatest').innerHTML = latestBits.length
769
+ ? latestBits.join('')
770
+ : 'No new review activity yet.';
771
+
772
+ if (button) {
773
+ button.textContent = summary.hasBaseline ? 'Reset Review Baseline to Current State' : 'Mark Current Dashboard Reviewed';
774
+ }
775
+ }
776
+
777
+ async function markReviewed() {
778
+ var button = document.getElementById('reviewCheckpointBtn');
779
+ var previousLabel = button.textContent;
780
+ button.disabled = true;
781
+ button.textContent = 'Saving...';
782
+ try {
783
+ var res = await fetch('/v1/dashboard/review-state', {
784
+ method: 'POST',
785
+ headers: getHeaders()
786
+ });
787
+ if (!res.ok) throw new Error('Failed to save review checkpoint');
788
+ var body = await res.json();
789
+ renderReviewDelta(body.reviewDelta || {});
790
+ } catch (e) {
791
+ document.getElementById('reviewDeltaHeadline').textContent = e && e.message ? e.message : 'Failed to save review checkpoint';
792
+ } finally {
793
+ button.disabled = false;
794
+ if (button.textContent === 'Saving...') button.textContent = previousLabel;
795
+ }
796
+ }
797
+
709
798
  function renderDashboardData(data) {
710
799
  dashboardSnapshot = data;
800
+ var reviewButton = document.getElementById('reviewCheckpointBtn');
801
+ if (reviewButton) reviewButton.disabled = false;
711
802
  const gates = data.gates || data.activeGates || [];
712
803
  const gateStats = data.gateStats || {};
713
804
  document.getElementById('statGates').textContent = gates.length || gateStats.totalGates || 0;
@@ -723,6 +814,7 @@ function renderDashboardData(data) {
723
814
  }
724
815
 
725
816
  renderTeam(data.team || {}, data.analytics || {});
817
+ renderReviewDelta(data.reviewDelta || {});
726
818
  renderPredictive(data.predictive || {});
727
819
  renderSettingsStatus(data.settingsStatus || {});
728
820
  renderTemplates(data.templateLibrary || {});
@@ -1058,6 +1150,44 @@ function loadDemo() {
1058
1150
  document.getElementById('statNegative').textContent = '260';
1059
1151
  document.getElementById('statGates').textContent = '21';
1060
1152
  setSelectedCard('all');
1153
+ // Demo: 260 negative-feedback events have produced ~180 actual gate blocks
1154
+ // and ~85 bot deflections on /checkout/pro. Kept as illustrative defaults
1155
+ // so the savings card never reads "0" in demo mode.
1156
+ var demoSavings = TG_TOKEN_SAVINGS.compute(180, 85);
1157
+ var tEl = document.getElementById('statTokensSaved');
1158
+ var dEl = document.getElementById('statDollarsSaved');
1159
+ if (tEl) tEl.textContent = demoSavings.tokensSavedDisplay;
1160
+ if (dEl) dEl.textContent = 'โ‰ˆ ' + demoSavings.dollarsSavedDisplay + ' saved';
1161
+ renderTopBlockedGates([
1162
+ { name: 'gate:no-force-push', blocked: 47 },
1163
+ { name: 'gate:no-drop-prod', blocked: 31 },
1164
+ { name: 'gate:no-hallucinated-import', blocked: 28 },
1165
+ { name: 'gate:no-secret-commit', blocked: 19 },
1166
+ { name: 'gate:require-tests-before-done', blocked: 14 },
1167
+ { name: 'gate:no-figma-claim-without-check', blocked: 9 },
1168
+ ]);
1169
+ renderReviewDelta({
1170
+ hasBaseline: true,
1171
+ reviewedAt: '2025-06-18T09:00:00Z',
1172
+ previousHead: '9f1a2c3d',
1173
+ currentHead: '5c7e9b1a',
1174
+ feedbackAdded: 6,
1175
+ negativeAdded: 4,
1176
+ lessonsAdded: 2,
1177
+ blocksAdded: 5,
1178
+ warnsAdded: 1,
1179
+ headline: 'Since your last review: 6 feedback events ยท 4 negative ยท 2 lessons ยท 5 gate blocks.',
1180
+ latestFeedback: {
1181
+ title: 'Claimed fix worked without running tests',
1182
+ timestamp: '2025-06-22T10:20:00Z'
1183
+ },
1184
+ latestLesson: {
1185
+ title: 'MISTAKE: Claimed Figma compliance without visual verification',
1186
+ timestamp: '2025-06-21T08:10:00Z'
1187
+ }
1188
+ });
1189
+ document.getElementById('reviewCheckpointBtn').disabled = true;
1190
+ document.getElementById('reviewCheckpointBtn').textContent = 'Connect to save your own review checkpoint';
1061
1191
  // Sample memories โ€” realistic scenarios from real agent-driven development
1062
1192
  var demoResults = [
1063
1193
  { signal: 'down', title: 'Claimed fix worked without running tests', context: 'Agent announced "fixed and pushed" but never ran the test suite. CI failed on 3 tests. Gate now requires test evidence before any completion claim.', tags: ['anti-lying', 'verification-gap', 'ci', 'trust-breach'], timestamp: '2025-06-22T10:20:00Z' },
@@ -1079,19 +1209,17 @@ function loadDemo() {
1079
1209
  { signal: 'up', title: 'DPO export caught systematic failure pattern', context: 'Exported 47 preference pairs revealing that 80% of negative feedback involved claiming work was done without verification. Led to a new mandatory evidence gate.', tags: ['dpo-export', 'evidence-based', 'prevention', 'metric:ROI'], timestamp: '2025-06-05T10:15:00Z' }
1080
1210
  ];
1081
1211
  isDemo = true;
1082
- demoData = demoResults.slice(0, 3);
1212
+ demoData = demoResults;
1083
1213
  var teaserHtml = demoData.map(renderResult).join('');
1084
- var upgradeWall = '<div style="position:relative;margin-top:8px;">' +
1085
- '<div style="filter:blur(4px);pointer-events:none;opacity:0.4;">' + demoResults.slice(3, 6).map(renderResult).join('') + '</div>' +
1086
- '<div style="position:absolute;top:0;left:0;right:0;bottom:0;display:flex;align-items:center;justify-content:center;">' +
1087
- '<div style="text-align:center;background:rgba(10,10,15,0.92);border:1px solid #333;border-radius:12px;padding:28px 36px;">' +
1088
- '<div style="font-size:20px;font-weight:700;color:#fff;margin-bottom:8px;">Unlock your full dashboard</div>' +
1089
- '<div style="color:#aaa;margin-bottom:16px;">Pro shows your real feedback, gates, and lessons โ€” not sample data.</div>' +
1214
+ var upgradeBanner = '<div style="margin-bottom:12px;padding:12px 16px;background:linear-gradient(90deg,rgba(184,92,45,0.14),rgba(184,92,45,0.06));border:1px solid rgba(184,92,45,0.35);border-radius:10px;display:flex;align-items:center;justify-content:space-between;gap:16px;flex-wrap:wrap;">' +
1215
+ '<div style="color:#ddd;font-size:14px;">' +
1216
+ '<span style="color:#ffb98a;font-weight:700;">Live demo data below.</span> ' +
1217
+ 'Point ThumbGate at your own feedback to see <em>your</em> gates, lessons, and team signals โ€” no signup required.' +
1218
+ '</div>' +
1090
1219
  '<a href="https://buy.stripe.com/7sYcN5bmIf5IcSd8qf3sI0a" target="_blank" rel="noopener" ' +
1091
- 'style="display:inline-block;background:#b85c2d;color:#fff;padding:10px 24px;border-radius:8px;text-decoration:none;font-weight:700;">Start 7-day free trial</a>' +
1092
- '<div style="color:#666;font-size:12px;margin-top:10px;">npx thumbgate pro --activate --key=YOUR_KEY</div>' +
1093
- '</div></div></div>';
1094
- document.getElementById('searchResults').innerHTML = teaserHtml + upgradeWall;
1220
+ 'style="flex:none;background:#b85c2d;color:#fff;padding:8px 18px;border-radius:8px;text-decoration:none;font-weight:700;font-size:13px;white-space:nowrap;">Go Pro โ€” $19/mo</a>' +
1221
+ '</div>';
1222
+ document.getElementById('searchResults').innerHTML = upgradeBanner + teaserHtml;
1095
1223
  // Sample gates
1096
1224
  var demoGates = [
1097
1225
  { name: 'no-force-push', pattern: 'Block git push --force to main or master branches', action: 'block' },
package/public/index.html CHANGED
@@ -19,12 +19,21 @@
19
19
  <meta charset="UTF-8">
20
20
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
21
21
  __GOOGLE_SITE_VERIFICATION_META__
22
+ <link rel="icon" type="image/png" href="/thumbgate-icon.png">
23
+ <link rel="alternate icon" type="image/svg+xml" href="/assets/brand/thumbgate-mark.svg">
24
+ <link rel="apple-touch-icon" href="/assets/brand/thumbgate-mark.svg">
25
+ <meta property="og:image" content="/og.png">
22
26
  <title>ThumbGate โ€” Stop paying for the same AI mistake twice</title>
23
27
  <meta name="description" content="Stop paying for the same AI mistake twice. ThumbGate turns ๐Ÿ‘ thumbs up and ๐Ÿ‘Ž thumbs down feedback into history-aware lessons and Pre-Action Gates that block repeat AI agent mistakes before they reach the model โ€” self-improving agent governance with shared lessons and org visibility for Claude Code, Cursor, Codex, Gemini, Amp, and OpenCode.">
24
28
  <meta property="og:title" content="ThumbGate โ€” Stop paying for the same AI mistake twice">
25
29
  <meta property="og:description" content="Frontier LLMs are expensive and repeat mistakes cost real money. ThumbGate blocks known-bad AI agent actions before they hit the model โ€” zero tokens spent on retries, hallucinations, or repeat commands. Fix it once, your bill never sees it again.">
26
30
  <meta property="og:type" content="website">
31
+ <meta property="og:image" content="https://thumbgate-production.up.railway.app/og.png">
32
+ <meta name="twitter:card" content="summary_large_image">
33
+ <meta name="twitter:image" content="https://thumbgate-production.up.railway.app/og.png">
27
34
  <meta name="keywords" content="ThumbGate, thumbgate, save LLM tokens, reduce Claude API cost, reduce OpenAI cost, AI agent token savings, prevent LLM retries, prevent hallucination retries, stop AI token waste, pre-action gates, agent governance, Claude Code, Cursor, Codex, Gemini, Amp, OpenCode, workflow hardening, context engineering, AI authenticity, brand authenticity AI">
35
+ <link rel="icon" type="image/png" href="/thumbgate-icon.png">
36
+ <link rel="apple-touch-icon" href="/apple-touch-icon.png">
28
37
 
29
38
  <!-- Privacy-friendly analytics by Plausible -->
30
39
  <script defer data-domain="thumbgate-production.up.railway.app" src="https://plausible.io/js/script.js"></script>
@@ -266,7 +275,9 @@ __GA_BOOTSTRAP__
266
275
  /* NAV */
267
276
  nav { position: sticky; top: 0; z-index: 50; background: rgba(10,10,11,0.85); backdrop-filter: blur(12px); border-bottom: 1px solid var(--border); padding: 14px 0; }
268
277
  nav .container { display: flex; justify-content: space-between; align-items: center; }
269
- .nav-logo { font-weight: 700; font-size: 15px; letter-spacing: -0.02em; color: var(--text); text-decoration: none; }
278
+ .nav-logo { font-weight: 700; font-size: 15px; letter-spacing: -0.02em; color: var(--text); text-decoration: none; display: inline-flex; align-items: center; gap: 8px; }
279
+ .nav-logo .logo-mark { width: 28px; height: 28px; display: block; }
280
+ .nav-logo .logo-text { color: var(--text); }
270
281
  .nav-logo span { color: var(--cyan); }
271
282
  .nav-links { display: flex; gap: 24px; align-items: center; }
272
283
  .nav-links a { color: var(--text-muted); text-decoration: none; font-size: 13px; transition: color 0.15s; }
@@ -310,13 +321,17 @@ __GA_BOOTSTRAP__
310
321
  .first-gate-step { border: 1px solid var(--border); border-radius: 10px; background: rgba(10,10,11,0.62); padding: 14px; }
311
322
  .first-gate-step strong { display: block; color: var(--cyan); margin-bottom: 6px; }
312
323
  .first-gate-step p { font-size: 13px; line-height: 1.5; margin: 0; }
313
- .first-gate-example { font-family: var(--mono); color: var(--green); background: rgba(74,222,128,0.08); border: 1px solid rgba(74,222,128,0.24); border-radius: 8px; padding: 10px 12px; font-size: 12px; margin-top: 12px; overflow-x: auto; }
324
+ .first-gate-examples { display: grid; gap: 8px; margin-top: 12px; }
325
+ .first-gate-example { font-family: var(--mono); border-radius: 8px; padding: 10px 12px; font-size: 12px; overflow-x: auto; line-height: 1.55; }
326
+ .first-gate-example.signal-good { color: var(--green); background: rgba(74,222,128,0.08); border: 1px solid rgba(74,222,128,0.24); }
327
+ .first-gate-example.signal-fix { color: #fda4af; background: rgba(251,113,133,0.08); border: 1px solid rgba(251,113,133,0.24); }
314
328
 
315
329
  /* SOCIAL PROOF BAR */
316
- .proof-bar { display: flex; justify-content: center; flex-wrap: wrap; gap: 24px; font-size: 13px; color: var(--text-muted); padding: 0 0 8px; }
317
- .proof-bar a { display: inline-flex; align-items: center; gap: 6px; color: var(--text-muted); text-decoration: none; transition: color 0.15s; }
318
- .proof-bar a:hover { color: var(--cyan); }
319
- .proof-bar .dot { width: 4px; height: 4px; background: var(--border); border-radius: 50%; display: inline-block; }
330
+ .proof-bar { display: flex; justify-content: center; flex-wrap: wrap; gap: 10px; font-size: 13px; color: var(--text-muted); padding: 4px 0 12px; max-width: 1040px; margin: 0 auto; }
331
+ .proof-bar a { display: inline-flex; align-items: center; justify-content: center; min-height: 36px; padding: 8px 12px; border: 1px solid rgba(34,211,238,0.14); border-radius: 8px; background: rgba(17,17,19,0.72); color: var(--text-muted); text-decoration: none; line-height: 1.25; white-space: nowrap; transition: color 0.15s, border-color 0.15s, background-color 0.15s; }
332
+ .proof-bar a:hover, .proof-bar a:focus-visible { color: var(--cyan); border-color: rgba(34,211,238,0.42); background: rgba(34,211,238,0.08); outline: none; }
333
+ .proof-bar a:focus-visible { box-shadow: 0 0 0 3px rgba(34,211,238,0.18); }
334
+ .proof-bar .dot { display: none; }
320
335
 
321
336
  /* COMPATIBILITY */
322
337
  .compatibility { padding: 0 0 80px; }
@@ -368,6 +383,20 @@ __GA_BOOTSTRAP__
368
383
  }
369
384
  .seo-card .card-arrow { font-size: 13px; color: var(--cyan); margin-top: 12px; font-weight: 500; }
370
385
 
386
+ /* AUTORESEARCH PACK */
387
+ .autoresearch-pack { padding: 0 0 80px; }
388
+ .autoresearch-panel { border: 1px solid rgba(34,211,238,0.28); border-radius: 8px; background: linear-gradient(180deg, rgba(17,17,19,0.98) 0%, rgba(10,18,20,0.98) 100%); padding: 28px; }
389
+ .autoresearch-panel h2 { font-size: 30px; line-height: 1.18; margin-bottom: 12px; }
390
+ .autoresearch-panel > p { color: var(--text-muted); line-height: 1.65; max-width: 860px; margin-bottom: 22px; }
391
+ .autoresearch-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 14px; margin: 22px 0; }
392
+ .autoresearch-card { border: 1px solid var(--border); border-radius: 8px; background: rgba(10,10,11,0.62); padding: 18px; }
393
+ .autoresearch-card h3 { font-size: 16px; margin-bottom: 8px; }
394
+ .autoresearch-card p { color: var(--text-muted); font-size: 14px; line-height: 1.55; }
395
+ .autoresearch-cta { display: flex; gap: 12px; flex-wrap: wrap; align-items: center; margin-top: 18px; }
396
+ .autoresearch-cta a { display: inline-flex; align-items: center; min-height: 40px; padding: 10px 16px; border-radius: 8px; text-decoration: none; font-size: 14px; font-weight: 700; }
397
+ .autoresearch-cta .primary { background: var(--cyan); color: #041016; }
398
+ .autoresearch-cta .secondary { border: 1px solid var(--border); color: var(--text); }
399
+
371
400
  /* HOW IT WORKS */
372
401
  .how-it-works { padding: 80px 0; }
373
402
  .section-label { font-size: 12px; text-transform: uppercase; letter-spacing: 0.1em; color: var(--cyan); font-weight: 600; margin-bottom: 12px; text-align: center; }
@@ -470,7 +499,7 @@ __GA_BOOTSTRAP__
470
499
  #claude-code-section:hover, #thumbgate-gpt:hover { opacity: 1; }
471
500
 
472
501
  /* Simplify proof bar โ€” make it less overwhelming */
473
- .proof-bar { font-size: 11px; gap: 16px; opacity: 0.8; }
502
+ .proof-bar { font-size: 13px; gap: 10px; opacity: 1; }
474
503
 
475
504
  /* RESPONSIVE */
476
505
  @media (max-width: 700px) {
@@ -479,13 +508,15 @@ __GA_BOOTSTRAP__
479
508
  .first-gate-steps { grid-template-columns: 1fr; }
480
509
  .gpt-steps { grid-template-columns: 1fr; }
481
510
  .seo-grid { grid-template-columns: 1fr; }
511
+ .autoresearch-grid { grid-template-columns: 1fr; }
482
512
  .pricing-grid { grid-template-columns: 1fr; }
483
513
  .team-form { grid-template-columns: 1fr; }
484
514
  .hero { padding: 72px 0 56px; }
485
515
  .hero-actions { flex-direction: column; }
486
516
  .hero-actions a { width: 100%; }
487
517
  .nav-links a:not(.nav-cta) { display: none; }
488
- .proof-bar { gap: 16px; }
518
+ .proof-bar { gap: 8px; justify-content: flex-start; }
519
+ .proof-bar a { width: 100%; min-height: 42px; white-space: normal; }
489
520
  .proof-bar .dot { display: none; }
490
521
  }
491
522
  </style>
@@ -505,10 +536,11 @@ __GA_BOOTSTRAP__
505
536
  <!-- NAV -->
506
537
  <nav>
507
538
  <div class="container">
508
- <a href="#" class="nav-logo"><span>๐Ÿ‘๐Ÿ‘Ž</span> ThumbGate</a>
539
+ <a href="#" class="nav-logo"><img src="/assets/brand/thumbgate-mark-inline.svg" alt="ThumbGate" class="logo-mark" width="28" height="28"><span class="logo-text">ThumbGate</span></a>
509
540
  <div class="nav-links">
510
541
  <a href="#how-it-works">How It Works</a>
511
542
  <a href="#pricing">Pricing</a>
543
+ <a href="/guides/autoresearch-agent-safety">Autoresearch</a>
512
544
  <a href="#faq">FAQ</a>
513
545
  <a href="https://github.com/IgorGanapolsky/ThumbGate" target="_blank" rel="noopener">GitHub</a>
514
546
  <a href="#compatibility" style="display:none;">Compatibility</a>
@@ -603,7 +635,7 @@ __GA_BOOTSTRAP__
603
635
  <div class="hero-secondary-ctas" style="display:flex;gap:10px;flex-wrap:wrap;justify-content:center;margin-top:8px;opacity:0.7;">
604
636
  <a href="https://github.com/IgorGanapolsky/ThumbGate/releases/latest/download/thumbgate-claude-desktop.mcpb" class="btn-gpt-page" target="_blank" rel="noopener" onclick="posthog.capture('hero_claude_extension_click',{cta:'install_claude_extension'})" style="font-size:12px;padding:8px 16px;background:#d97706;color:#fff;box-shadow:none;">Install Claude Extension</a>
605
637
  <a href="/go/github?utm_source=website&utm_medium=hero_cta&utm_campaign=github_repo&cta_id=hero_star_github&cta_placement=hero" target="_blank" rel="noopener" class="btn-free" style="display:inline-flex;align-items:center;gap:6px;padding:8px 14px;border-radius:999px;font-size:12px;">โญ Star on GitHub</a>
606
- <a href="https://github.com/IgorGanapolsky/ThumbGate/releases/latest/download/thumbgate-codex-plugin.zip" class="btn-install-link" target="_blank" rel="noopener" onclick="posthog.capture('hero_codex_plugin_click',{cta:'install_codex_plugin'})" style="font-size:11px;color:var(--text-muted);text-decoration:none;padding:6px 10px;">Install Codex plugin โ†’</a>
638
+ <a href="/codex-plugin?utm_source=website&utm_medium=hero_cta&utm_campaign=codex_plugin&cta_id=hero_codex_plugin&cta_placement=hero" class="btn-install-link" onclick="posthog.capture('hero_codex_plugin_click',{cta:'install_codex_plugin'})" style="font-size:11px;color:var(--text-muted);text-decoration:none;padding:6px 10px;">Install Codex plugin โ†’</a>
607
639
  <a href="https://github.com/IgorGanapolsky/ThumbGate/tree/main/plugins/cursor-marketplace" class="btn-install-link" target="_blank" rel="noopener" onclick="posthog.capture('hero_cursor_plugin_click',{cta:'install_cursor_plugin'})" style="font-size:11px;color:var(--text-muted);text-decoration:none;padding:6px 10px;">Install Cursor plugin โ†’</a>
608
640
  <a href="/go/gpt?utm_source=website&utm_medium=hero_cta&utm_campaign=chatgpt_gpt&cta_id=hero_open_gpt&cta_placement=hero" class="btn-gpt-page" target="_blank" rel="noopener" onclick="posthog.capture('hero_cta_click',{cta:'open_gpt'})" style="font-size:11px;padding:6px 12px;background:transparent;border:1px solid rgba(74,222,128,0.3);color:var(--green);">Open ThumbGate GPT</a>
609
641
  </div>
@@ -628,44 +660,36 @@ __GA_BOOTSTRAP__
628
660
  <div class="first-gate-steps">
629
661
  <div class="first-gate-step">
630
662
  <strong>1. Install ThumbGate</strong>
631
- <p>Run <code>npx thumbgate init</code> in your repo. Or install the <a href="https://github.com/IgorGanapolsky/ThumbGate/releases/latest/download/thumbgate-claude-desktop.mcpb" style="color:var(--cyan);">Claude Extension</a>, <a href="https://github.com/IgorGanapolsky/ThumbGate/releases/latest/download/thumbgate-codex-plugin.zip" style="color:var(--cyan);">Codex plugin</a>, <a href="https://github.com/IgorGanapolsky/ThumbGate/tree/main/plugins/cursor-marketplace" style="color:var(--cyan);">Cursor plugin</a>, or <a href="/go/gpt" style="color:var(--cyan);">open the GPT</a>. Native ChatGPT rating buttons are not the ThumbGate capture path.</p>
663
+ <p>Run <code>npx thumbgate init</code> in your repo. Or install the <a href="https://github.com/IgorGanapolsky/ThumbGate/releases/latest/download/thumbgate-claude-desktop.mcpb" style="color:var(--cyan);">Claude Extension</a>, <a href="/codex-plugin" style="color:var(--cyan);">Codex plugin</a>, <a href="https://github.com/IgorGanapolsky/ThumbGate/tree/main/plugins/cursor-marketplace" style="color:var(--cyan);">Cursor plugin</a>, or <a href="/go/gpt" style="color:var(--cyan);">open the GPT</a>. Native ChatGPT rating buttons are not the ThumbGate capture path.</p>
632
664
  </div>
633
665
  <div class="first-gate-step">
634
666
  <strong>2. Give feedback</strong>
635
- <p>When your agent makes a mistake, give it a <code>thumbs down</code>. ThumbGate captures the context and distills a lesson from up to 8 prior entries.</p>
667
+ <p>Give <code>thumbs up</code> when the agent follows your standards, or <code>thumbs down</code> when it misses. ThumbGate captures the context and distills a lesson from up to 8 prior entries.</p>
636
668
  </div>
637
669
  <div class="first-gate-step">
638
670
  <strong>3. The gate blocks the repeat</strong>
639
671
  <p>Next time the agent tries the same mistake, the PreToolUse hook fires and physically blocks it. Upgrade after one real blocked repeat when you need the dashboard and exports.</p>
640
672
  </div>
641
673
  </div>
642
- <div class="first-gate-example">thumbs down: the answer ignored my request for exact files and tests; next time include file paths, commands, and verification evidence.</div>
674
+ <div class="first-gate-examples" aria-label="ThumbGate feedback examples">
675
+ <div class="first-gate-example signal-good">thumbs up: this review named exact files, commands, and tests; repeat this evidence-first format.</div>
676
+ <div class="first-gate-example signal-fix">thumbs down: the answer ignored my request for exact files and tests; next time include file paths, commands, and verification evidence.</div>
677
+ </div>
643
678
  </div>
644
- <div class="proof-bar">
679
+ <nav class="proof-bar" aria-label="ThumbGate install and proof links">
645
680
  <a href="https://github.com/IgorGanapolsky/ThumbGate/releases/latest/download/thumbgate-claude-desktop.mcpb" target="_blank" rel="noopener" style="color:var(--cyan);font-weight:600;">Claude Extension โ†’</a>
646
- <span class="dot"></span>
647
681
  <a href="https://github.com/IgorGanapolsky/ThumbGate/blob/main/.claude-plugin/README.md" target="_blank" rel="noopener">Claude marketplace install โ†’</a>
648
- <span class="dot"></span>
649
682
  <a href="/guide" rel="noopener">CLI setup guide โ†’</a>
650
- <span class="dot"></span>
651
- <a href="https://github.com/IgorGanapolsky/ThumbGate/releases/latest/download/thumbgate-codex-plugin.zip" target="_blank" rel="noopener">Codex plugin download โ†’</a>
652
- <span class="dot"></span>
683
+ <a href="/codex-plugin?utm_source=website&utm_medium=proof_bar&utm_campaign=codex_plugin&cta_id=proof_bar_codex_plugin&cta_placement=proof_bar">Codex plugin setup โ†’</a>
653
684
  <a href="/go/gpt?utm_source=website&utm_medium=proof_bar&utm_campaign=chatgpt_gpt&cta_id=proof_bar_open_gpt&cta_placement=proof_bar" target="_blank" rel="noopener">ThumbGate GPT โ†’</a>
654
- <span class="dot"></span>
655
685
  <a href="https://github.com/IgorGanapolsky/ThumbGate/blob/main/docs/VERIFICATION_EVIDENCE.md" target="_blank" rel="noopener">Verification evidence โ†’</a>
656
- <span class="dot"></span>
657
686
  <a href="https://github.com/IgorGanapolsky/ThumbGate/blob/main/docs/THUMBGATE_BENCH.md" target="_blank" rel="noopener">ThumbGate Bench โ†’</a>
658
- <span class="dot"></span>
659
687
  <a href="https://github.com/IgorGanapolsky/ThumbGate/actions" target="_blank" rel="noopener">Proof-backed CI โ†’</a>
660
- <span class="dot"></span>
661
688
  <a href="https://github.com/IgorGanapolsky/ThumbGate/actions" target="_blank" rel="noopener">CI and proof lanes โ†’</a>
662
- <span class="dot"></span>
663
689
  <a href="https://github.com/IgorGanapolsky/ThumbGate/blob/main/docs/RELEASE_CONFIDENCE.md" target="_blank" rel="noopener">Release confidence โ†’</a>
664
- <span class="dot"></span>
665
690
  <a href="https://www.producthunt.com/products/thumbgate" target="_blank" rel="noopener">Product Hunt โ†’</a>
666
- <span class="dot"></span>
667
691
  <a href="#compatibility">Claude Code ยท Cursor ยท Codex ยท Gemini ยท Amp ยท OpenCode</a>
668
- </div>
692
+ </nav>
669
693
  </div>
670
694
  </section>
671
695
 
@@ -793,10 +817,10 @@ __GA_BOOTSTRAP__
793
817
  <p>Claude Code, Codex, Gemini CLI, Amp, and OpenCode all use the same gateway and memory model. Any MCP-compatible agent gets pre-action gates, feedback memory, and enforcement out of the box.</p>
794
818
  <div class="card-arrow">Open the setup guide โ†’</div>
795
819
  </a>
796
- <a class="compat-card" href="https://github.com/IgorGanapolsky/ThumbGate/releases/latest/download/thumbgate-codex-plugin.zip" target="_blank" rel="noopener" onclick="if(typeof posthog!=='undefined')posthog.capture('compat_codex_plugin_click',{cta:'download_codex_plugin'})">
820
+ <a class="compat-card" href="/codex-plugin?utm_source=website&utm_medium=compatibility&utm_campaign=codex_plugin&cta_id=compat_codex_plugin&cta_placement=compatibility" rel="noopener" onclick="if(typeof posthog!=='undefined')posthog.capture('compat_codex_plugin_click',{cta:'open_codex_plugin_page'})">
797
821
  <h3>๐Ÿงฉ Codex plugin</h3>
798
- <p>Codex ships with a published standalone ThumbGate plugin bundle plus a repo-local plugin profile. Download the zip, extract it, and install without wiring MCP by hand. <a href="https://github.com/IgorGanapolsky/ThumbGate/blob/main/plugins/codex-profile/INSTALL.md" target="_blank" rel="noopener" style="color:var(--text-muted);text-decoration:underline;" onclick="event.stopPropagation();">Setup instructions โ†’</a></p>
799
- <div class="card-arrow">Download the Codex plugin โ†’</div>
822
+ <p>Codex gets a standalone ThumbGate plugin bundle, a repo-local plugin profile, and the same auto-updating MCP launcher. The runtime resolves <code>thumbgate@latest</code> when Codex starts, so npm fixes reach active installs. The install page includes the zip, MCP config, and verification path in one place.</p>
823
+ <div class="card-arrow">Open the Codex install page โ†’</div>
800
824
  </a>
801
825
  <a class="compat-card" href="/guides/cursor-prevent-repeated-mistakes.html" rel="noopener">
802
826
  <h3>๐ŸŽฏ Cursor plugin</h3>
@@ -810,7 +834,7 @@ __GA_BOOTSTRAP__
810
834
  </a>
811
835
  <a class="compat-card" href="https://mcp.so/server/thumbgate" target="_blank" rel="noopener" onclick="if(typeof posthog!=='undefined')posthog.capture('compat_mcp_so_click',{cta:'view_mcp_directory'})">
812
836
  <h3>๐Ÿ—‚๏ธ MCP Server Directory</h3>
813
- <p>ThumbGate is listed on <code>mcp.so</code> โ€” the largest public MCP server directory. Install via Smithery CLI, copy-paste config for your client, or verify it's a legitimate server before running it.</p>
837
+ <p>ThumbGate is listed on <code>mcp.so</code> so MCP-compatible clients can verify the package, copy the npx config, and confirm they are installing the real Pre-Action Gates server.</p>
814
838
  <div class="card-arrow">View on mcp.so โ†’</div>
815
839
  </a>
816
840
  <a class="compat-card" href="/go/gpt?utm_source=website&utm_medium=compatibility&utm_campaign=chatgpt_gpt&cta_id=compat_open_gpt&cta_placement=compatibility" target="_blank" rel="noopener">
@@ -829,7 +853,7 @@ __GA_BOOTSTRAP__
829
853
  <div class="agent-grid">
830
854
  <div class="agent-card">
831
855
  <h3>๐Ÿ” Live Dashboard Demo</h3>
832
- <p>Search lessons, inspect gates, and see exactly why risky actions were blocked. No signup or install required.</p>
856
+ <p>Search lessons, inspect gates, mark a review checkpoint, and see only what changed since the last pass. No signup or install required.</p>
833
857
  <a href="/dashboard" style="display:inline-block;margin-top:12px;color:var(--cyan);font-weight:600;text-decoration:underline;">Open Dashboard Demo โ†’</a>
834
858
  </div>
835
859
  <div class="agent-card">
@@ -909,6 +933,40 @@ __GA_BOOTSTRAP__
909
933
  <p>Why Gemini CLI buyers start with memory and convert when they see how memory becomes real pre-action gates.</p>
910
934
  <div class="card-arrow">Read the Gemini guide โ†’</div>
911
935
  </a>
936
+ <a class="seo-card" href="/guides/autoresearch-agent-safety">
937
+ <div class="seo-kicker">Autoresearch</div>
938
+ <h3>Autoresearch Safety for Self-Improving Agents</h3>
939
+ <p>Why benchmark-search loops need gates for holdout tests, proof trails, reward hacking, and unsafe promotions.</p>
940
+ <div class="card-arrow">Read the Autoresearch guide โ†’</div>
941
+ </a>
942
+ </div>
943
+ </div>
944
+ </section>
945
+
946
+ <section class="autoresearch-pack" id="autoresearch-pack">
947
+ <div class="container">
948
+ <div class="autoresearch-panel">
949
+ <div class="section-label" style="text-align:left;">Autoresearch Safety Pack</div>
950
+ <h2>Stop self-improving coding loops from hacking the benchmark.</h2>
951
+ <p>Autoresearch loops run experiments, inspect metrics, and accept better variants. ThumbGate gives those loops a Reliability Gateway: Pre-Action Gates for skipped holdout tests, fake proof, reward hacking, unsafe edits, and promotion without verification evidence.</p>
952
+ <div class="autoresearch-grid">
953
+ <div class="autoresearch-card">
954
+ <h3>Guard the metric</h3>
955
+ <p>Require primary and holdout checks before an agent can call a variant better. Block cherry-picked runs and missing baselines.</p>
956
+ </div>
957
+ <div class="autoresearch-card">
958
+ <h3>Preserve proof trails</h3>
959
+ <p>Promotion needs commands, logs, changed files, and verification evidence so the win survives review instead of becoming a vague claim.</p>
960
+ </div>
961
+ <div class="autoresearch-card">
962
+ <h3>Ship into CI</h3>
963
+ <p>Start with templates for <code>npm test</code>, Playwright duration, bundle size, lint, and CI failures, then add Team gates for shared workflows.</p>
964
+ </div>
965
+ </div>
966
+ <div class="autoresearch-cta">
967
+ <a class="primary" href="/guides/autoresearch-agent-safety?utm_source=website&utm_medium=autoresearch_pack&utm_campaign=autoresearch_safety&cta_id=autoresearch_guide&cta_placement=autoresearch_pack">Read the Autoresearch guide</a>
968
+ <a class="secondary" href="/checkout/pro?utm_source=website&utm_medium=autoresearch_pack&utm_campaign=autoresearch_safety&cta_id=autoresearch_pro_trial&cta_placement=autoresearch_pack&plan_id=pro&landing_path=%2F">Start Pro trial</a>
969
+ </div>
912
970
  </div>
913
971
  </div>
914
972
  </section>
@@ -916,7 +974,7 @@ __GA_BOOTSTRAP__
916
974
  <!-- HOW IT WORKS -->
917
975
  <section class="how-it-works" id="how-it-works">
918
976
  <div class="container">
919
- <div class="section-label">New in v1.5.8</div>
977
+ <div class="section-label">New in v1.7.0</div>
920
978
  <h2 class="section-title">Three steps to stop repeated AI failures</h2>
921
979
  <div class="steps">
922
980
  <div class="step">
@@ -1272,7 +1330,7 @@ __GA_BOOTSTRAP__
1272
1330
  <a href="https://www.linkedin.com/in/igorganapolsky" target="_blank" rel="noopener">LinkedIn</a>
1273
1331
  <a href="/blog">Blog</a>
1274
1332
  </div>
1275
- <span class="footer-copy">ยฉ 2026 Max Smith KDP LLC ยท MIT License ยท v1.5.8</span>
1333
+ <span class="footer-copy">ยฉ 2026 Max Smith KDP LLC ยท MIT License ยท v1.7.0</span>
1276
1334
  </div>
1277
1335
  </footer>
1278
1336
 
package/public/learn.html CHANGED
@@ -12,6 +12,8 @@
12
12
  <meta property="og:type" content="website">
13
13
  <meta property="og:url" content="https://thumbgate-production.up.railway.app/learn">
14
14
  <link rel="canonical" href="https://thumbgate-production.up.railway.app/learn">
15
+ <link rel="icon" type="image/png" href="/thumbgate-icon.png">
16
+ <link rel="apple-touch-icon" href="/assets/brand/thumbgate-mark.svg">
15
17
 
16
18
  <script type="application/ld+json">
17
19
  {
@@ -105,7 +107,8 @@
105
107
  nav { padding: 1rem 2rem; border-bottom: 1px solid var(--border); display: flex; gap: 1.5rem; align-items: center; }
106
108
  nav a { color: var(--muted); text-decoration: none; font-size: 0.9rem; }
107
109
  nav a:hover { color: var(--cyan); }
108
- nav .brand { color: var(--text); font-weight: 700; font-size: 1.1rem; }
110
+ nav .brand { color: var(--text); font-weight: 700; font-size: 1.1rem; display: inline-flex; align-items: center; gap: 8px; text-decoration: none; }
111
+ nav .brand .logo-mark { width: 28px; height: 28px; display: block; }
109
112
  h1 { font-size: 2.2rem; line-height: 1.2; margin: 2rem 0 1rem; }
110
113
  h2 { font-size: 1.5rem; margin: 2.5rem 0 1rem; color: var(--cyan); }
111
114
  p { color: var(--text); margin-bottom: 0.75rem; }
@@ -175,7 +178,7 @@
175
178
  <body>
176
179
 
177
180
  <nav>
178
- <a href="/" class="brand">๐Ÿ‘๐Ÿ‘Ž ThumbGate</a>
181
+ <a href="/" class="brand"><img src="/assets/brand/thumbgate-mark-inline.svg" alt="ThumbGate" class="logo-mark" width="28" height="28"><span class="logo-text">ThumbGate</span></a>
179
182
  <a href="/guide">Setup Guide</a>
180
183
  <a href="/learn">Learn</a>
181
184
  <a href="/dashboard">Dashboard</a>
@@ -261,6 +264,14 @@
261
264
  <span class="article-tag">Memory</span>
262
265
  <span class="article-tag">Enforcement</span>
263
266
  </a>
267
+
268
+ <a href="/guides/autoresearch-agent-safety" class="article-card">
269
+ <h3>Autoresearch Agent Safety for Self-Improving Coding Agents</h3>
270
+ <p>The control-plane story for benchmark-search loops that need holdout tests, proof trails, and reward-hacking gates.</p>
271
+ <span class="article-tag">Autoresearch</span>
272
+ <span class="article-tag">Holdout Proof</span>
273
+ <span class="article-tag">Gates</span>
274
+ </a>
264
275
  </div>
265
276
 
266
277
  <div class="cta-section">
@@ -4,6 +4,8 @@
4
4
  <meta charset="UTF-8">
5
5
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
6
  <title>ThumbGate โ€” Lessons Learned</title>
7
+ <link rel="icon" type="image/png" href="/thumbgate-icon.png">
8
+ <link rel="apple-touch-icon" href="/assets/brand/thumbgate-mark.svg">
7
9
  <script defer data-domain="thumbgate-production.up.railway.app" src="https://plausible.io/js/script.js"></script>
8
10
  <style>
9
11
  *, *::before, *::after { margin: 0; padding: 0; box-sizing: border-box; }
@@ -22,7 +24,8 @@
22
24
  /* NAV */
23
25
  nav { position: sticky; top: 0; z-index: 50; background: rgba(10,10,11,0.85); backdrop-filter: blur(12px); border-bottom: 1px solid var(--border); padding: 14px 0; }
24
26
  nav .container { display: flex; justify-content: space-between; align-items: center; }
25
- .nav-logo { font-weight: 700; font-size: 15px; color: var(--text); text-decoration: none; }
27
+ .nav-logo { font-weight: 700; font-size: 15px; color: var(--text); text-decoration: none; display: inline-flex; align-items: center; gap: 8px; }
28
+ .nav-logo .logo-mark { width: 28px; height: 28px; display: block; }
26
29
  .nav-links { display: flex; gap: 16px; align-items: center; }
27
30
  .nav-links a { color: var(--text-muted); text-decoration: none; font-size: 13px; }
28
31
  .nav-links a:hover { color: var(--text); }
@@ -185,7 +188,7 @@
185
188
 
186
189
  <nav>
187
190
  <div class="container">
188
- <a href="/dashboard" class="nav-logo">๐Ÿ‘๐Ÿ‘Ž ThumbGate</a>
191
+ <a href="/dashboard" class="nav-logo"><img src="/assets/brand/thumbgate-mark-inline.svg" alt="ThumbGate" class="logo-mark" width="28" height="28"><span class="logo-text">ThumbGate</span></a>
189
192
  <div class="nav-links">
190
193
  <a href="/dashboard">Dashboard</a>
191
194
  <a href="/lessons" class="active">Lessons</a>
package/public/pro.html CHANGED
@@ -11,6 +11,9 @@ __GOOGLE_SITE_VERIFICATION_META__
11
11
  <meta property="og:type" content="website">
12
12
  <meta property="og:url" content="__APP_ORIGIN__/pro">
13
13
  <link rel="canonical" href="__APP_ORIGIN__/pro">
14
+ <link rel="icon" type="image/png" href="/thumbgate-icon.png">
15
+ <link rel="apple-touch-icon" href="/assets/brand/thumbgate-mark.svg">
16
+ <meta property="og:image" content="/og.png">
14
17
  <meta name="keywords" content="ThumbGate Pro, AI agent reliability, pre-action gates, DPO export, local dashboard, review-ready evidence, Claude Code reliability, Codex reliability, Cursor reliability">
15
18
 
16
19
  <script defer data-domain="thumbgate-production.up.railway.app" src="https://plausible.io/js/script.js"></script>
@@ -169,8 +172,12 @@ __GA_BOOTSTRAP__
169
172
  font-weight: 700;
170
173
  letter-spacing: -0.02em;
171
174
  text-decoration: none;
175
+ display: inline-flex;
176
+ align-items: center;
177
+ gap: 8px;
172
178
  }
173
179
 
180
+ .nav-logo .logo-mark { width: 28px; height: 28px; display: block; }
174
181
  .nav-logo span { color: var(--cyan); }
175
182
 
176
183
  .nav-links {
@@ -777,7 +784,7 @@ __GA_BOOTSTRAP__
777
784
  <body>
778
785
  <nav>
779
786
  <div class="container">
780
- <a href="/" class="nav-logo"><span>๐Ÿ‘๐Ÿ‘Ž</span> ThumbGate Pro</a>
787
+ <a href="/" class="nav-logo"><img src="/assets/brand/thumbgate-mark-inline.svg" alt="ThumbGate" class="logo-mark" width="28" height="28"><span class="logo-text">ThumbGate Pro</span></a>
781
788
  <div class="nav-links">
782
789
  <a href="#why-pay">Why Pro</a>
783
790
  <a href="#proof">Proof</a>