@geotechcli/core 0.4.40 → 0.4.42

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.
Files changed (38) hide show
  1. package/dist/ingest/geotech-document-benchmark.d.ts +139 -0
  2. package/dist/ingest/geotech-document-benchmark.d.ts.map +1 -0
  3. package/dist/ingest/geotech-document-benchmark.js +438 -0
  4. package/dist/ingest/geotech-document-benchmark.js.map +1 -0
  5. package/dist/ingest/geotech-document.d.ts.map +1 -1
  6. package/dist/ingest/geotech-document.js +67 -9
  7. package/dist/ingest/geotech-document.js.map +1 -1
  8. package/dist/ingest/index.d.ts +1 -0
  9. package/dist/ingest/index.d.ts.map +1 -1
  10. package/dist/ingest/index.js +1 -0
  11. package/dist/ingest/index.js.map +1 -1
  12. package/dist/ingest/page-evidence-cache.d.ts +1 -1
  13. package/dist/ingest/page-evidence-cache.js +1 -1
  14. package/dist/meta/metadata.json +1 -1
  15. package/dist/report/html.d.ts.map +1 -1
  16. package/dist/report/html.js +212 -135
  17. package/dist/report/html.js.map +1 -1
  18. package/dist/report/ingest-dossier.d.ts.map +1 -1
  19. package/dist/report/ingest-dossier.js +15 -10
  20. package/dist/report/ingest-dossier.js.map +1 -1
  21. package/dist/verifier/findings.d.ts +25 -0
  22. package/dist/verifier/findings.d.ts.map +1 -1
  23. package/dist/verifier/findings.js +233 -0
  24. package/dist/verifier/findings.js.map +1 -1
  25. package/dist/verifier/index.d.ts +1 -1
  26. package/dist/verifier/index.d.ts.map +1 -1
  27. package/dist/verifier/index.js.map +1 -1
  28. package/dist/vision/geotech-document.d.ts +3 -0
  29. package/dist/vision/geotech-document.d.ts.map +1 -1
  30. package/dist/vision/geotech-document.js +23 -2
  31. package/dist/vision/geotech-document.js.map +1 -1
  32. package/dist/vision/preprocess.d.ts.map +1 -1
  33. package/dist/vision/preprocess.js +8 -3
  34. package/dist/vision/preprocess.js.map +1 -1
  35. package/dist/workspace/dossier.d.ts.map +1 -1
  36. package/dist/workspace/dossier.js +48 -2
  37. package/dist/workspace/dossier.js.map +1 -1
  38. package/package.json +1 -1
@@ -31,15 +31,15 @@ function toneClass(tone) {
31
31
  function toneColor(tone) {
32
32
  switch (tone) {
33
33
  case 'good':
34
- return '#d9f5e8';
34
+ return '#0f3d2e';
35
35
  case 'warning':
36
- return '#f7e4bd';
36
+ return '#5f3b0b';
37
37
  case 'danger':
38
- return '#f9d3cf';
38
+ return '#5f1717';
39
39
  case 'accent':
40
- return '#d8e9f7';
40
+ return '#0b3b56';
41
41
  default:
42
- return '#e8edf3';
42
+ return '#1f2937';
43
43
  }
44
44
  }
45
45
  function parsePercent(value) {
@@ -213,9 +213,9 @@ function renderGroundModelCrossSection(profile) {
213
213
  `;
214
214
  }
215
215
  const width = 940;
216
- const height = 310;
217
- const plotTop = 58;
218
- const plotHeight = 182;
216
+ const height = 280;
217
+ const plotTop = 52;
218
+ const plotHeight = 158;
219
219
  const left = 84;
220
220
  const right = width - 44;
221
221
  const usableWidth = right - left;
@@ -246,11 +246,11 @@ function renderGroundModelCrossSection(profile) {
246
246
  </div>
247
247
  <div class="profile-shell cross-section-shell">
248
248
  <svg class="ground-cross-section" viewBox="0 0 ${width} ${height}" role="img" aria-label="AI-assisted ground model cross-section">
249
- <rect x="0" y="0" width="${width}" height="${height}" rx="18" fill="#ffffff" />
249
+ <rect x="0" y="0" width="${width}" height="${height}" rx="18" fill="#0f172a" />
250
250
  ${ticks.map((tick) => {
251
251
  const y = yForDepth(tick);
252
252
  return `
253
- <line x1="${left - 34}" y1="${y.toFixed(2)}" x2="${right + 12}" y2="${y.toFixed(2)}" stroke="#d8e0ea" stroke-width="1" />
253
+ <line x1="${left - 34}" y1="${y.toFixed(2)}" x2="${right + 12}" y2="${y.toFixed(2)}" stroke="#334155" stroke-width="1" />
254
254
  <text x="14" y="${(y + 4).toFixed(2)}" class="profile-axis">${escapeHtml(tick.toFixed(tick % 1 === 0 ? 0 : 1))} ${escapeHtml(profile.depthUnit)}</text>
255
255
  `;
256
256
  }).join('')}
@@ -261,7 +261,7 @@ function renderGroundModelCrossSection(profile) {
261
261
  <g>
262
262
  <title>${escapeHtml(`${layer.label}: ${layer.description}`)}</title>
263
263
  <path d="M ${left} ${y1.toFixed(2)} L ${right} ${y1.toFixed(2)} L ${right} ${y2.toFixed(2)} L ${left} ${y2.toFixed(2)} Z"
264
- fill="${toneColor(layer.tone)}" stroke="#7a8aa0" stroke-width="1.2" ${layer.uncertain ? 'stroke-dasharray="8 6"' : ''} opacity="0.88" />
264
+ fill="${toneColor(layer.tone)}" stroke="#64748b" stroke-width="1.2" ${layer.uncertain ? 'stroke-dasharray="8 6"' : ''} opacity="0.92" />
265
265
  <text x="${left + 18}" y="${(y1 + Math.min(34, (y2 - y1) / 2 + 5)).toFixed(2)}" class="profile-label">${escapeHtml(compactSvgText(layer.label, 32))}</text>
266
266
  <text x="${left + 18}" y="${(y1 + Math.min(52, (y2 - y1) / 2 + 23)).toFixed(2)}" class="profile-small">${escapeHtml(compactSvgText(layer.description, 64))}</text>
267
267
  </g>
@@ -274,8 +274,8 @@ function renderGroundModelCrossSection(profile) {
274
274
  const waterY = column.waterTableDepth != null ? yForDepth(column.waterTableDepth) : null;
275
275
  return `
276
276
  <g>
277
- <line x1="${x.toFixed(2)}" y1="${plotTop - 10}" x2="${x.toFixed(2)}" y2="${bottomY.toFixed(2)}" stroke="#0b4f8a" stroke-width="3" />
278
- <circle cx="${x.toFixed(2)}" cy="${plotTop - 12}" r="6" fill="#0b4f8a" />
277
+ <line x1="${x.toFixed(2)}" y1="${plotTop - 10}" x2="${x.toFixed(2)}" y2="${bottomY.toFixed(2)}" stroke="#06b6d4" stroke-width="3" />
278
+ <circle cx="${x.toFixed(2)}" cy="${plotTop - 12}" r="6" fill="#06b6d4" />
279
279
  <text x="${(x - 24).toFixed(2)}" y="28" class="profile-title">${escapeHtml(column.boreholeId)}</text>
280
280
  <text x="${(x - 36).toFixed(2)}" y="${height - 32}" class="profile-small">TD ${escapeHtml(depth.toFixed(2))} ${escapeHtml(profile.depthUnit)}</text>
281
281
  ${waterY != null ? `
@@ -304,9 +304,9 @@ function renderBoreholeProfile(profile) {
304
304
  `;
305
305
  }
306
306
  const plotTop = 44;
307
- const plotHeight = 420;
308
- const columnWidth = 132;
309
- const gap = 42;
307
+ const plotHeight = 330;
308
+ const columnWidth = 110;
309
+ const gap = 32;
310
310
  const axisWidth = 78;
311
311
  const width = axisWidth + profile.columns.length * columnWidth + Math.max(0, profile.columns.length - 1) * gap + 42;
312
312
  const height = plotTop + plotHeight + 74;
@@ -334,11 +334,11 @@ function renderBoreholeProfile(profile) {
334
334
  </div>
335
335
  <div class="profile-shell">
336
336
  <svg class="borehole-profile" viewBox="0 0 ${width} ${height}" role="img" aria-label="Borehole stratigraphy profile">
337
- <rect x="0" y="0" width="${width}" height="${height}" rx="18" fill="#ffffff" />
337
+ <rect x="0" y="0" width="${width}" height="${height}" rx="18" fill="#0f172a" />
338
338
  ${ticks.map((tick) => {
339
339
  const y = plotTop + (tick / profile.maxDepth) * plotHeight;
340
340
  return `
341
- <line x1="48" y1="${y.toFixed(2)}" x2="${width - 24}" y2="${y.toFixed(2)}" stroke="#d8e0ea" stroke-width="1" />
341
+ <line x1="48" y1="${y.toFixed(2)}" x2="${width - 24}" y2="${y.toFixed(2)}" stroke="#334155" stroke-width="1" />
342
342
  <text x="8" y="${(y + 4).toFixed(2)}" class="profile-axis">${escapeHtml(tick.toFixed(tick % 1 === 0 ? 0 : 1))} ${escapeHtml(profile.depthUnit)}</text>
343
343
  `;
344
344
  }).join('')}
@@ -351,7 +351,7 @@ function renderBoreholeProfile(profile) {
351
351
  <text x="${x}" y="24" class="profile-title">${escapeHtml(column.boreholeId)}</text>
352
352
  ${column.layers.map((layer) => layerRect(layer, columnIndex)).join('')}
353
353
  ${waterY != null ? `
354
- <line x1="${x - 8}" y1="${waterY.toFixed(2)}" x2="${x + columnWidth + 8}" y2="${waterY.toFixed(2)}" stroke="#0b4f8a" stroke-width="2" />
354
+ <line x1="${x - 8}" y1="${waterY.toFixed(2)}" x2="${x + columnWidth + 8}" y2="${waterY.toFixed(2)}" stroke="#06b6d4" stroke-width="2" />
355
355
  <text x="${x + 8}" y="${(waterY - 6).toFixed(2)}" class="profile-water">Groundwater</text>
356
356
  ` : ''}
357
357
  <text x="${x}" y="${height - 24}" class="profile-small">TD ${escapeHtml(column.totalDepth != null ? `${column.totalDepth.toFixed(2)} m` : 'unavailable')}</text>
@@ -418,8 +418,8 @@ function renderSourceEvidence(dossier) {
418
418
  ${card.warnings.length > 0 ? `<small>Human verification recommended: ${escapeHtml(String(card.warnings.length))} retained warning(s).</small>` : ''}
419
419
  <div class="evidence-actions" aria-label="${escapeHtml(`${card.pageLabel} review actions`)}">
420
420
  <a href="#processing-audit">Open source page</a>
421
- <button type="button" data-dossier-action="verified">Mark verified</button>
422
- <button type="button" data-dossier-action="flagged">Flag issue</button>
421
+ <button type="button" data-review-action="verified">Mark verified</button>
422
+ <button type="button" data-review-action="flagged">Flag issue</button>
423
423
  </div>
424
424
  </article>
425
425
  `).join('')}
@@ -493,7 +493,7 @@ function renderReviewBar(dossier) {
493
493
  <div class="review-actions">
494
494
  <a href="#parameters" class="primary-action">Approve Extraction</a>
495
495
  <a href="#risks">Flag for Review</a>
496
- <button type="button" onclick="window.print()">Export Dossier</button>
496
+ <button type="button" onclick="window.print()">Export Report</button>
497
497
  <a href="#ground-cross-section">Generate Ground Model</a>
498
498
  <a href="#source-evidence">Ask Geotech Agent</a>
499
499
  <a href="#processing-audit">Open Audit Trail</a>
@@ -529,32 +529,37 @@ export function renderIngestDossierAsHtml(dossier) {
529
529
  <head>
530
530
  <meta charset="utf-8" />
531
531
  <meta name="viewport" content="width=device-width, initial-scale=1" />
532
- <title>Geotechnical Intelligence Dossier - ${escapeHtml(dossier.title)}</title>
532
+ <title>Geotechnical Intelligence Report - ${escapeHtml(dossier.title)}</title>
533
533
  <style>
534
534
  :root {
535
- --bg: #f6f8fb;
536
- --surface: #ffffff;
537
- --surface-soft: #eef3f8;
538
- --text: #101828;
539
- --muted: #667085;
540
- --primary: #0b4f8a;
541
- --primary-soft: #e6f0fa;
542
- --success: #16875d;
543
- --success-soft: #e4f6ee;
544
- --warning: #b7791f;
545
- --warning-soft: #fff3d6;
546
- --danger: #b42318;
547
- --danger-soft: #fde5e2;
548
- --neutral: #475467;
549
- --neutral-soft: #edf1f6;
550
- --border: #d8e0ea;
551
- --shadow: 0 18px 45px rgba(16, 24, 40, 0.08);
552
- --radius: 16px;
553
- --radius-sm: 12px;
535
+ --bg: #060d1b;
536
+ --surface: #0f172a;
537
+ --surface-soft: #111827;
538
+ --surface-raised: #0b1120;
539
+ --text: #f8fafc;
540
+ --muted: #94a3b8;
541
+ --primary: #06b6d4;
542
+ --primary-soft: rgba(6, 182, 212, 0.12);
543
+ --success: #10b981;
544
+ --success-soft: rgba(16, 185, 129, 0.13);
545
+ --warning: #f59e0b;
546
+ --warning-soft: rgba(245, 158, 11, 0.13);
547
+ --danger: #ef4444;
548
+ --danger-soft: rgba(239, 68, 68, 0.13);
549
+ --neutral: #cbd5e1;
550
+ --neutral-soft: rgba(100, 116, 139, 0.15);
551
+ --border: #1e293b;
552
+ --border-strong: #334155;
553
+ --shadow: 0 20px 60px rgba(0, 0, 0, 0.28);
554
+ --radius: 14px;
555
+ --radius-sm: 10px;
554
556
  }
555
557
 
556
558
  * { box-sizing: border-box; }
557
- html { scroll-behavior: smooth; }
559
+ html {
560
+ scroll-behavior: smooth;
561
+ overflow-x: hidden;
562
+ }
558
563
  html, body { margin: 0; min-height: 100%; }
559
564
 
560
565
  body {
@@ -568,76 +573,100 @@ export function renderIngestDossierAsHtml(dossier) {
568
573
 
569
574
  .layout {
570
575
  display: grid;
571
- grid-template-columns: 280px minmax(0, 1fr);
572
- gap: 28px;
576
+ grid-template-columns: minmax(0, 1fr);
577
+ gap: 24px;
573
578
  width: 100%;
574
- max-width: 1580px;
579
+ max-width: 1280px;
575
580
  margin: 0 auto;
576
- padding: 28px;
581
+ padding: 16px 24px 120px;
577
582
  min-width: 0;
578
583
  }
579
584
 
580
585
  .sidebar {
581
586
  position: sticky;
582
- top: 28px;
583
- align-self: start;
584
- min-height: calc(100vh - 56px);
587
+ top: 0;
588
+ z-index: 30;
589
+ display: flex;
590
+ align-items: center;
591
+ justify-content: space-between;
592
+ gap: 18px;
593
+ align-self: stretch;
594
+ min-height: 58px;
585
595
  min-width: 0;
586
- padding: 22px;
596
+ padding: 12px 16px;
587
597
  border: 1px solid var(--border);
588
- border-radius: var(--radius);
589
- background: #0b1220;
598
+ border-radius: 14px;
599
+ background: rgba(11, 17, 32, 0.94);
590
600
  color: #f8fafc;
591
- box-shadow: var(--shadow);
601
+ box-shadow: 0 14px 44px rgba(0, 0, 0, 0.26);
602
+ backdrop-filter: blur(14px);
592
603
  }
593
604
 
594
605
  .brand {
595
- display: grid;
596
- gap: 8px;
597
- padding-bottom: 22px;
598
- border-bottom: 1px solid #263244;
599
- margin-bottom: 18px;
606
+ display: flex;
607
+ align-items: center;
608
+ gap: 10px;
609
+ padding: 0;
610
+ border-bottom: 0;
611
+ margin: 0;
612
+ min-width: 190px;
613
+ }
614
+
615
+ .brand::before {
616
+ content: "";
617
+ width: 28px;
618
+ height: 28px;
619
+ border-radius: 8px;
620
+ background: var(--primary);
621
+ box-shadow: 0 0 24px rgba(6, 182, 212, 0.28);
622
+ flex: 0 0 auto;
600
623
  }
601
624
 
602
- .brand strong { font-size: 1.05rem; }
603
- .brand span { color: #94a3b8; line-height: 1.5; font-size: 0.9rem; }
625
+ .brand strong { font-size: 0.96rem; white-space: nowrap; }
626
+ .brand span { display: none; }
604
627
 
605
628
  .nav-list {
606
- display: grid;
629
+ display: flex;
630
+ align-items: center;
631
+ justify-content: flex-end;
607
632
  gap: 6px;
633
+ flex-wrap: wrap;
608
634
  }
609
635
 
610
636
  .nav-list a {
611
- color: #dbeafe;
637
+ color: #cbd5e1;
612
638
  text-decoration: none;
613
- padding: 10px 12px;
614
- border-radius: 10px;
639
+ padding: 8px 10px;
640
+ border-radius: 8px;
615
641
  font-weight: 650;
616
- font-size: 0.94rem;
642
+ font-size: 0.8rem;
617
643
  overflow-wrap: anywhere;
618
644
  }
619
645
 
620
646
  .nav-list a:hover, .nav-list a:focus {
621
- background: #1f2937;
647
+ background: rgba(100, 116, 139, 0.16);
622
648
  outline: none;
623
649
  }
624
650
 
625
651
  .content {
626
652
  display: grid;
627
- gap: 26px;
653
+ gap: 28px;
628
654
  min-width: 0;
629
655
  max-width: 100%;
630
656
  }
631
657
 
632
658
  .hero {
633
- padding: 32px;
659
+ padding: 30px;
634
660
  border: 1px solid var(--border);
635
661
  border-radius: 18px;
636
- background: linear-gradient(135deg, #ffffff 0%, #eef6ff 100%);
662
+ background:
663
+ radial-gradient(circle at top right, rgba(6, 182, 212, 0.09), transparent 34%),
664
+ linear-gradient(135deg, #0b1120 0%, #0f172a 100%);
637
665
  box-shadow: var(--shadow);
638
666
  display: grid;
639
- gap: 24px;
667
+ gap: 22px;
640
668
  min-width: 0;
669
+ overflow: hidden;
641
670
  }
642
671
 
643
672
  .eyebrow {
@@ -646,7 +675,7 @@ export function renderIngestDossierAsHtml(dossier) {
646
675
  padding: 8px 12px;
647
676
  border-radius: 999px;
648
677
  background: var(--primary-soft);
649
- color: var(--primary);
678
+ color: #67e8f9;
650
679
  font-weight: 800;
651
680
  font-size: 0.78rem;
652
681
  text-transform: uppercase;
@@ -654,7 +683,7 @@ export function renderIngestDossierAsHtml(dossier) {
654
683
 
655
684
  .hero-main {
656
685
  display: grid;
657
- grid-template-columns: minmax(0, 1fr) 250px;
686
+ grid-template-columns: minmax(0, 1fr) 300px;
658
687
  gap: 24px;
659
688
  align-items: start;
660
689
  min-width: 0;
@@ -676,7 +705,7 @@ export function renderIngestDossierAsHtml(dossier) {
676
705
 
677
706
  .hero-subtitle {
678
707
  margin-top: 12px;
679
- color: var(--primary);
708
+ color: #67e8f9;
680
709
  font-weight: 800;
681
710
  font-size: 1.12rem;
682
711
  }
@@ -693,16 +722,19 @@ export function renderIngestDossierAsHtml(dossier) {
693
722
  display: grid;
694
723
  gap: 10px;
695
724
  padding: 18px;
696
- border: 1px solid var(--border);
725
+ border: 1px solid var(--border-strong);
697
726
  border-radius: var(--radius-sm);
698
- background: rgba(255, 255, 255, 0.72);
727
+ background: rgba(15, 23, 42, 0.74);
699
728
  color: var(--muted);
700
729
  font-size: 0.92rem;
701
730
  min-width: 0;
702
731
  overflow-wrap: anywhere;
703
732
  }
704
733
 
705
- .hero-meta strong { color: var(--text); }
734
+ .hero-meta strong {
735
+ color: var(--text);
736
+ overflow-wrap: anywhere;
737
+ }
706
738
 
707
739
  .status-badge-row {
708
740
  display: flex;
@@ -716,9 +748,10 @@ export function renderIngestDossierAsHtml(dossier) {
716
748
  gap: 4px;
717
749
  min-width: 126px;
718
750
  padding: 10px 12px;
719
- border: 1px solid rgba(102, 112, 133, 0.18);
720
- border-radius: 14px;
751
+ border: 1px solid currentColor;
752
+ border-radius: 999px;
721
753
  line-height: 1.2;
754
+ background: rgba(15, 23, 42, 0.74);
722
755
  }
723
756
 
724
757
  .status-badge span {
@@ -730,7 +763,7 @@ export function renderIngestDossierAsHtml(dossier) {
730
763
  }
731
764
 
732
765
  .status-badge strong {
733
- color: var(--text);
766
+ color: currentColor;
734
767
  font-size: 0.86rem;
735
768
  overflow-wrap: anywhere;
736
769
  }
@@ -765,6 +798,7 @@ export function renderIngestDossierAsHtml(dossier) {
765
798
  }
766
799
 
767
800
  .fact-card strong {
801
+ color: var(--text);
768
802
  font-size: 1rem;
769
803
  line-height: 1.45;
770
804
  overflow-wrap: anywhere;
@@ -805,11 +839,11 @@ export function renderIngestDossierAsHtml(dossier) {
805
839
  opacity: 0.75;
806
840
  }
807
841
 
808
- .tone-accent { background: var(--primary-soft); color: var(--primary); }
809
- .tone-good { background: var(--success-soft); color: var(--success); }
810
- .tone-warning { background: var(--warning-soft); color: var(--warning); }
811
- .tone-danger { background: var(--danger-soft); color: var(--danger); }
812
- .tone-neutral { background: var(--neutral-soft); color: var(--neutral); }
842
+ .tone-accent { background: var(--primary-soft); color: #22d3ee; border-color: rgba(6, 182, 212, 0.28); }
843
+ .tone-good { background: var(--success-soft); color: #34d399; border-color: rgba(16, 185, 129, 0.28); }
844
+ .tone-warning { background: var(--warning-soft); color: #fcd34d; border-color: rgba(245, 158, 11, 0.3); }
845
+ .tone-danger { background: var(--danger-soft); color: #f87171; border-color: rgba(239, 68, 68, 0.32); }
846
+ .tone-neutral { background: var(--neutral-soft); color: #cbd5e1; border-color: rgba(100, 116, 139, 0.28); }
813
847
 
814
848
  .action-bar {
815
849
  display: flex;
@@ -818,15 +852,15 @@ export function renderIngestDossierAsHtml(dossier) {
818
852
  }
819
853
 
820
854
  .action-bar button, .action-bar a {
821
- border: 1px solid var(--border);
822
- border-radius: 12px;
823
- background: var(--surface);
824
- color: var(--text);
825
- padding: 10px 13px;
855
+ border: 1px solid var(--border-strong);
856
+ border-radius: 8px;
857
+ background: var(--surface-soft);
858
+ color: #cbd5e1;
859
+ padding: 9px 12px;
826
860
  font: inherit;
827
861
  font-weight: 800;
828
862
  text-decoration: none;
829
- box-shadow: 0 1px 2px rgba(16, 24, 40, 0.04);
863
+ box-shadow: none;
830
864
  cursor: pointer;
831
865
  overflow-wrap: anywhere;
832
866
  }
@@ -834,7 +868,7 @@ export function renderIngestDossierAsHtml(dossier) {
834
868
  .action-bar .primary-action {
835
869
  background: var(--primary);
836
870
  border-color: var(--primary);
837
- color: #ffffff;
871
+ color: #06111f;
838
872
  }
839
873
 
840
874
  .review-bar {
@@ -913,6 +947,7 @@ export function renderIngestDossierAsHtml(dossier) {
913
947
  .section-heading h2 {
914
948
  font-size: 1.35rem;
915
949
  letter-spacing: 0;
950
+ color: var(--text);
916
951
  }
917
952
 
918
953
  .section-heading p {
@@ -948,30 +983,32 @@ export function renderIngestDossierAsHtml(dossier) {
948
983
  }
949
984
 
950
985
  .profile-shell, .table-shell {
951
- overflow-x: auto;
986
+ overflow: auto;
952
987
  border: 1px solid var(--border);
953
988
  border-radius: var(--radius);
954
989
  background: var(--surface);
955
990
  min-width: 0;
956
991
  max-width: 100%;
992
+ max-height: 560px;
957
993
  }
958
994
 
959
995
  .borehole-profile {
960
996
  display: block;
961
- min-width: 760px;
997
+ min-width: 680px;
962
998
  width: 100%;
963
999
  height: auto;
964
1000
  }
965
1001
 
966
1002
  .cross-section-shell {
967
1003
  background:
968
- linear-gradient(180deg, rgba(11, 79, 138, 0.04), rgba(22, 135, 93, 0.04)),
1004
+ linear-gradient(180deg, rgba(6, 182, 212, 0.06), rgba(16, 185, 129, 0.04)),
969
1005
  var(--surface);
1006
+ max-height: 360px;
970
1007
  }
971
1008
 
972
1009
  .ground-cross-section {
973
1010
  display: block;
974
- min-width: 840px;
1011
+ min-width: 760px;
975
1012
  width: 100%;
976
1013
  height: auto;
977
1014
  }
@@ -984,11 +1021,11 @@ export function renderIngestDossierAsHtml(dossier) {
984
1021
  border-left: 3px solid var(--warning);
985
1022
  }
986
1023
 
987
- .profile-title { font: 800 15px Inter, Segoe UI, sans-serif; fill: #101828; }
988
- .profile-label { font: 800 13px Inter, Segoe UI, sans-serif; fill: #101828; }
989
- .profile-small { font: 11px Inter, Segoe UI, sans-serif; fill: #475467; }
990
- .profile-axis { font: 11px Inter, Segoe UI, sans-serif; fill: #667085; }
991
- .profile-water { font: 800 11px Inter, Segoe UI, sans-serif; fill: #0b4f8a; }
1024
+ .profile-title { font: 800 15px Inter, Segoe UI, sans-serif; fill: #f8fafc; }
1025
+ .profile-label { font: 800 13px Inter, Segoe UI, sans-serif; fill: #f8fafc; }
1026
+ .profile-small { font: 11px Inter, Segoe UI, sans-serif; fill: #cbd5e1; }
1027
+ .profile-axis { font: 11px Inter, Segoe UI, sans-serif; fill: #94a3b8; }
1028
+ .profile-water { font: 800 11px Inter, Segoe UI, sans-serif; fill: #67e8f9; }
992
1029
 
993
1030
  .profile-notes {
994
1031
  color: var(--muted);
@@ -1003,19 +1040,20 @@ export function renderIngestDossierAsHtml(dossier) {
1003
1040
 
1004
1041
  th, td {
1005
1042
  padding: 13px 14px;
1006
- border-bottom: 1px solid rgba(11, 79, 138, 0.09);
1043
+ border-bottom: 1px solid rgba(100, 116, 139, 0.22);
1007
1044
  text-align: left;
1008
1045
  vertical-align: top;
1009
1046
  font-size: 0.92rem;
1010
1047
  line-height: 1.48;
1011
1048
  overflow-wrap: anywhere;
1049
+ color: #cbd5e1;
1012
1050
  }
1013
1051
 
1014
1052
  th {
1015
1053
  position: sticky;
1016
1054
  top: 0;
1017
1055
  z-index: 1;
1018
- background: var(--surface-soft);
1056
+ background: var(--surface-raised);
1019
1057
  color: var(--muted);
1020
1058
  font-size: 0.76rem;
1021
1059
  text-transform: uppercase;
@@ -1060,9 +1098,9 @@ export function renderIngestDossierAsHtml(dossier) {
1060
1098
 
1061
1099
  .trust-controls input {
1062
1100
  width: 100%;
1063
- border: 1px solid var(--border);
1101
+ border: 1px solid var(--border-strong);
1064
1102
  border-radius: 12px;
1065
- background: #ffffff;
1103
+ background: #0b1120;
1066
1104
  color: var(--text);
1067
1105
  padding: 11px 12px;
1068
1106
  font: inherit;
@@ -1073,8 +1111,8 @@ export function renderIngestDossierAsHtml(dossier) {
1073
1111
  }
1074
1112
 
1075
1113
  .trust-controls input:focus {
1076
- border-color: #93c5fd;
1077
- box-shadow: 0 0 0 4px rgba(11, 79, 138, 0.08);
1114
+ border-color: var(--primary);
1115
+ box-shadow: 0 0 0 4px rgba(6, 182, 212, 0.12);
1078
1116
  }
1079
1117
 
1080
1118
  .filter-row {
@@ -1084,7 +1122,7 @@ export function renderIngestDossierAsHtml(dossier) {
1084
1122
  }
1085
1123
 
1086
1124
  .filter-button {
1087
- border: 1px solid var(--border);
1125
+ border: 1px solid var(--border-strong);
1088
1126
  border-radius: 999px;
1089
1127
  background: var(--surface-soft);
1090
1128
  color: var(--muted);
@@ -1097,7 +1135,7 @@ export function renderIngestDossierAsHtml(dossier) {
1097
1135
 
1098
1136
  .filter-button.active {
1099
1137
  background: var(--primary);
1100
- color: #ffffff;
1138
+ color: #06111f;
1101
1139
  border-color: var(--primary);
1102
1140
  }
1103
1141
 
@@ -1137,10 +1175,10 @@ export function renderIngestDossierAsHtml(dossier) {
1137
1175
  }
1138
1176
 
1139
1177
  .evidence-actions a, .evidence-actions button {
1140
- border: 1px solid var(--border);
1178
+ border: 1px solid var(--border-strong);
1141
1179
  border-radius: 10px;
1142
- background: rgba(255, 255, 255, 0.62);
1143
- color: var(--primary);
1180
+ background: #0b1120;
1181
+ color: #67e8f9;
1144
1182
  padding: 8px 9px;
1145
1183
  font: inherit;
1146
1184
  font-size: 0.78rem;
@@ -1193,10 +1231,10 @@ export function renderIngestDossierAsHtml(dossier) {
1193
1231
  .audit-drawer small { color: var(--muted); }
1194
1232
 
1195
1233
  .disclosure-hint {
1196
- border: 1px solid var(--border);
1234
+ border: 1px solid var(--border-strong);
1197
1235
  border-radius: 999px;
1198
1236
  padding: 7px 11px;
1199
- color: var(--primary);
1237
+ color: #67e8f9;
1200
1238
  background: var(--primary-soft);
1201
1239
  font-weight: 800;
1202
1240
  white-space: nowrap;
@@ -1255,9 +1293,9 @@ export function renderIngestDossierAsHtml(dossier) {
1255
1293
  }
1256
1294
 
1257
1295
  .stage-chip {
1258
- color: var(--primary);
1296
+ color: #67e8f9;
1259
1297
  background: var(--primary-soft);
1260
- border-color: #b9d4ec;
1298
+ border-color: rgba(6, 182, 212, 0.32);
1261
1299
  }
1262
1300
 
1263
1301
  .footer-grid {
@@ -1299,39 +1337,78 @@ export function renderIngestDossierAsHtml(dossier) {
1299
1337
  }
1300
1338
 
1301
1339
  @media (max-width: 980px) {
1302
- .layout { grid-template-columns: minmax(0, 1fr); padding: 18px; max-width: 100%; }
1303
- .sidebar { position: static; min-height: auto; }
1304
- .nav-list { grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); }
1340
+ .layout { padding: 14px 16px 96px; max-width: 100%; }
1341
+ .sidebar { position: static; min-height: auto; align-items: flex-start; flex-direction: column; }
1342
+ .nav-list { justify-content: flex-start; }
1305
1343
  .hero-main { grid-template-columns: 1fr; }
1306
1344
  }
1307
1345
 
1308
1346
  @media (max-width: 620px) {
1309
1347
  body { padding-bottom: 0; }
1310
- .layout { display: block; width: 100%; max-width: 390px; margin: 0; padding: 12px; }
1348
+ .layout {
1349
+ display: grid;
1350
+ width: min(100vw, 390px);
1351
+ max-width: 390px;
1352
+ margin: 0;
1353
+ padding: 10px;
1354
+ gap: 18px;
1355
+ overflow: hidden;
1356
+ }
1311
1357
  .sidebar, .content, .hero, .data-section, .audit-drawer, .footer-grid {
1312
1358
  width: 100%;
1313
1359
  max-width: 100%;
1314
1360
  }
1315
- .sidebar { padding: 16px; min-height: auto; border-radius: 14px; }
1316
- .brand { gap: 5px; padding-bottom: 12px; margin-bottom: 10px; }
1361
+ .sidebar { padding: 14px; min-height: auto; border-radius: 14px; }
1362
+ .brand { gap: 8px; padding-bottom: 0; margin-bottom: 0; }
1317
1363
  .brand span { display: none; }
1318
- .nav-list { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 6px; }
1319
- .nav-list a { padding: 8px 9px; font-size: 0.82rem; }
1364
+ .nav-list {
1365
+ width: 100%;
1366
+ display: grid;
1367
+ grid-template-columns: repeat(2, minmax(0, 1fr));
1368
+ gap: 5px;
1369
+ }
1370
+ .nav-list a {
1371
+ min-width: 0;
1372
+ padding: 7px 8px;
1373
+ font-size: 0.74rem;
1374
+ line-height: 1.25;
1375
+ }
1320
1376
  .content { margin-top: 18px; }
1321
- .hero { padding: 22px; }
1377
+ .hero { padding: 20px; width: 100%; max-width: 100%; }
1378
+ .hero-main { width: 100%; max-width: 100%; grid-template-columns: minmax(0, 1fr); }
1379
+ .hero-main > div, .hero-meta, .status-badge-row {
1380
+ width: 100%;
1381
+ max-width: min(320px, 100%);
1382
+ }
1322
1383
  .executive-grid, .metric-grid, .card-grid, .evidence-grid, .footer-grid { grid-template-columns: 1fr; }
1323
1384
  .review-bar { position: static; transform: none; width: 100%; margin-top: 18px; border-radius: 18px; align-items: stretch; }
1324
1385
  .review-bar.visible { transform: none; }
1325
1386
  .review-actions { justify-content: flex-start; }
1326
- h1 { font-size: 1.72rem; max-width: 100%; }
1387
+ h1 { font-size: 1.72rem; max-width: min(320px, 100%); line-height: 1.08; }
1388
+ .hero-subtitle { max-width: min(320px, 100%); font-size: 0.96rem; line-height: 1.35; overflow-wrap: anywhere; }
1389
+ .hero-summary { max-width: min(320px, 100%); font-size: 0.95rem; line-height: 1.55; }
1390
+ .status-badge-row { display: grid; grid-template-columns: minmax(0, 1fr); }
1391
+ .status-badge {
1392
+ width: 100%;
1393
+ max-width: 100%;
1394
+ min-width: 0;
1395
+ padding: 9px 10px;
1396
+ border-radius: 18px;
1397
+ }
1398
+ .status-badge span, .status-badge strong {
1399
+ min-width: 0;
1400
+ overflow-wrap: anywhere;
1401
+ word-break: break-word;
1402
+ }
1403
+ table { min-width: 760px; }
1327
1404
  }
1328
1405
  </style>
1329
1406
  </head>
1330
1407
  <body>
1331
1408
  <div class="layout">
1332
- <aside class="sidebar" aria-label="Dossier navigation">
1409
+ <aside class="sidebar" aria-label="Report navigation">
1333
1410
  <div class="brand">
1334
- <strong>Geotechnical Intelligence Dossier</strong>
1411
+ <strong>GeotechCLI Intelligence</strong>
1335
1412
  <span>AI-assisted extraction, verification, and engineering interpretation from geotechnical reports.</span>
1336
1413
  </div>
1337
1414
  <nav class="nav-list">
@@ -1350,8 +1427,8 @@ export function renderIngestDossierAsHtml(dossier) {
1350
1427
  <header class="hero" id="overview">
1351
1428
  <div class="hero-main">
1352
1429
  <div>
1353
- <span class="eyebrow">Geotechnical Intelligence Dossier</span>
1354
- <h1>${escapeHtml(dossier.title)}</h1>
1430
+ <span class="eyebrow">Review Report</span>
1431
+ <h1>Geotechnical Intelligence Report</h1>
1355
1432
  <p class="hero-subtitle">${escapeHtml(subtitle)}</p>
1356
1433
  <p class="hero-summary">${escapeHtml(dossier.summary)}</p>
1357
1434
  ${renderStatusBadges(dossier)}
@@ -1461,7 +1538,7 @@ export function renderIngestDossierAsHtml(dossier) {
1461
1538
 
1462
1539
  const syncReviewBar = () => {
1463
1540
  if (!reviewBar) return;
1464
- reviewBar.classList.toggle('visible', window.innerWidth > 620 && window.scrollY > 420);
1541
+ reviewBar.classList.toggle('visible', window.innerWidth > 620 && window.scrollY > 640);
1465
1542
  };
1466
1543
 
1467
1544
  syncReviewBar();
@@ -1477,14 +1554,14 @@ export function renderIngestDossierAsHtml(dossier) {
1477
1554
  });
1478
1555
  });
1479
1556
 
1480
- document.querySelectorAll('[data-dossier-action]').forEach((control) => {
1557
+ document.querySelectorAll('[data-review-action]').forEach((control) => {
1481
1558
  control.addEventListener('click', () => {
1482
- const state = control.getAttribute('data-dossier-action') ?? '';
1559
+ const state = control.getAttribute('data-review-action') ?? '';
1483
1560
  control.setAttribute('data-state', state);
1484
1561
  control.textContent = state === 'verified' ? 'Verified' : 'Issue flagged';
1485
1562
  showToast(state === 'verified'
1486
- ? 'Evidence item marked verified in this local dossier view.'
1487
- : 'Evidence item flagged for engineering review in this local dossier view.');
1563
+ ? 'Evidence item marked verified in this local report view.'
1564
+ : 'Evidence item flagged for engineering review in this local report view.');
1488
1565
  });
1489
1566
  });
1490
1567
  })();