| <!DOCTYPE html> |
| <html lang="en"> |
| <head> |
| <meta charset="UTF-8"> |
| <meta name="viewport" content="width=device-width, initial-scale=1.0"> |
| <title>HSPA/RIGOR Platform — Documentation Dashboard</title> |
| <style> |
| *, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; } |
| :root { |
| --bg-primary: #020617; --bg-secondary: #0f172a; --bg-tertiary: #1e293b; |
| --bg-glass: rgba(30,41,59,0.7); --border-subtle: rgba(148,163,184,0.12); |
| --border-medium: rgba(148,163,184,0.2); --text-primary: #f1f5f9; |
| --text-secondary: #94a3b8; --text-muted: #64748b; |
| --accent-blue: #3b82f6; --accent-green: #22c55e; --accent-amber: #f59e0b; |
| --accent-purple: #a855f7; --accent-rose: #f43f5e; --accent-cyan: #06b6d4; |
| --accent-emerald: #10b981; --accent-indigo: #6366f1; |
| --font-sans: 'Inter',-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,sans-serif; |
| --font-mono: 'JetBrains Mono','Fira Code',Consolas,monospace; |
| } |
| body { font-family: var(--font-sans); background: var(--bg-primary); color: var(--text-primary); min-height: 100vh; line-height: 1.6; } |
| ::-webkit-scrollbar { width: 8px; height: 8px; } |
| ::-webkit-scrollbar-track { background: var(--bg-secondary); } |
| ::-webkit-scrollbar-thumb { background: var(--bg-tertiary); border-radius: 4px; } |
| .glass { background: var(--bg-glass); backdrop-filter: blur(16px); -webkit-backdrop-filter: blur(16px); border: 1px solid var(--border-subtle); } |
| .hidden { display: none !important; } |
| .fade-in { animation: fadeIn 0.3s ease-out forwards; } |
| @keyframes fadeIn { from { opacity: 0; transform: translateY(8px); } to { opacity: 1; transform: translateY(0); } } |
| .header { position: sticky; top: 0; z-index: 100; background: var(--bg-glass); backdrop-filter: blur(20px); -webkit-backdrop-filter: blur(20px); border-bottom: 1px solid var(--border-subtle); } |
| .header-inner { max-width: 1400px; margin: 0 auto; padding: 12px 24px; display: flex; align-items: center; justify-content: space-between; gap: 16px; } |
| .brand { display: flex; align-items: center; gap: 12px; } |
| .brand-icon { width: 40px; height: 40px; border-radius: 10px; background: linear-gradient(135deg, var(--accent-blue), var(--accent-cyan)); display: flex; align-items: center; justify-content: center; box-shadow: 0 0 20px rgba(59,130,246,0.15); font-weight: 800; font-size: 18px; color: white; } |
| .brand-text h1 { font-size: 17px; font-weight: 700; letter-spacing: -0.3px; } |
| .brand-text p { font-size: 11px; color: var(--text-secondary); margin-top: 1px; } |
| .sim-panel { display: flex; align-items: center; gap: 12px; } |
| .sim-progress { display: flex; align-items: center; gap: 8px; opacity: 0; transition: opacity 0.3s; } |
| .sim-progress.active { opacity: 1; } |
| .sim-percent { font-family: var(--font-mono); font-size: 12px; color: var(--accent-green); font-weight: 600; } |
| .sim-bar-bg { width: 120px; height: 6px; background: var(--bg-tertiary); border-radius: 3px; overflow: hidden; } |
| .sim-bar-fill { height: 100%; width: 0%; background: linear-gradient(90deg, var(--accent-green), var(--accent-emerald)); border-radius: 3px; transition: width 0.1s linear; } |
| .btn { display: inline-flex; align-items: center; gap: 6px; padding: 7px 14px; border-radius: 6px; font-size: 12px; font-weight: 600; border: none; cursor: pointer; transition: all 0.2s; font-family: var(--font-sans); } |
| .btn-green { background: rgba(34,197,94,0.85); color: white; } |
| .btn-green:hover { background: var(--accent-green); } |
| .btn-green:disabled { opacity: 0.5; cursor: not-allowed; } |
| .btn-slate { background: var(--bg-tertiary); color: var(--text-secondary); border: 1px solid var(--border-medium); } |
| .btn-slate:hover { background: var(--text-muted); color: white; } |
| .nav-bar { background: rgba(15,23,42,0.6); border-bottom: 1px solid var(--border-subtle); } |
| .nav-inner { max-width: 1400px; margin: 0 auto; padding: 0 24px; display: flex; align-items: center; gap: 4px; } |
| .nav-tab { display: flex; align-items: center; gap: 6px; padding: 12px 16px; font-size: 12px; font-weight: 600; color: var(--text-muted); background: none; border: none; border-bottom: 2px solid transparent; cursor: pointer; transition: all 0.2s; white-space: nowrap; } |
| .nav-tab:hover { color: var(--text-secondary); background: rgba(255,255,255,0.03); } |
| .nav-tab.active { color: var(--accent-blue); border-bottom-color: var(--accent-blue); background: rgba(59,130,246,0.06); } |
| .nav-tab svg { width: 14px; height: 14px; } |
| .search-box { margin-left: auto; position: relative; } |
| .search-box input { width: 220px; padding: 7px 12px 7px 32px; background: var(--bg-tertiary); border: 1px solid var(--border-medium); border-radius: 6px; color: var(--text-primary); font-size: 12px; font-family: var(--font-sans); outline: none; transition: all 0.2s; } |
| .search-box input:focus { border-color: var(--accent-blue); box-shadow: 0 0 0 3px rgba(59,130,246,0.15); } |
| .search-box input::placeholder { color: var(--text-muted); } |
| .search-icon { position: absolute; left: 10px; top: 50%; transform: translateY(-50%); color: var(--text-muted); pointer-events: none; } |
| .main { max-width: 1400px; margin: 0 auto; padding: 24px; } |
| .stats-grid { display: grid; grid-template-columns: repeat(5, 1fr); gap: 12px; margin-bottom: 24px; } |
| .stat-card { padding: 20px; border-radius: 12px; text-align: center; transition: transform 0.2s, box-shadow 0.2s; } |
| .stat-card:hover { transform: translateY(-2px); } |
| .stat-icon { width: 36px; height: 36px; margin: 0 auto 10px; border-radius: 8px; display: flex; align-items: center; justify-content: center; } |
| .stat-label { font-size: 10px; font-weight: 600; text-transform: uppercase; letter-spacing: 0.5px; margin-bottom: 6px; } |
| .stat-value { font-size: 28px; font-weight: 800; font-family: var(--font-mono); } |
| .stat-blue { background: rgba(59,130,246,0.08); border: 1px solid rgba(59,130,246,0.2); } |
| .stat-blue .stat-icon { background: rgba(59,130,246,0.15); color: var(--accent-blue); } |
| .stat-blue .stat-label { color: var(--accent-blue); } .stat-blue .stat-value { color: var(--accent-blue); } |
| .stat-green { background: rgba(34,197,94,0.08); border: 1px solid rgba(34,197,94,0.2); } |
| .stat-green .stat-icon { background: rgba(34,197,94,0.15); color: var(--accent-green); } |
| .stat-green .stat-label { color: var(--accent-green); } .stat-green .stat-value { color: var(--accent-green); } |
| .stat-amber { background: rgba(245,158,11,0.08); border: 1px solid rgba(245,158,11,0.2); } |
| .stat-amber .stat-icon { background: rgba(245,158,11,0.15); color: var(--accent-amber); } |
| .stat-amber .stat-label { color: var(--accent-amber); } .stat-amber .stat-value { color: var(--accent-amber); } |
| .stat-purple { background: rgba(168,85,247,0.08); border: 1px solid rgba(168,85,247,0.2); } |
| .stat-purple .stat-icon { background: rgba(168,85,247,0.15); color: var(--accent-purple); } |
| .stat-purple .stat-label { color: var(--accent-purple); } .stat-purple .stat-value { color: var(--accent-purple); } |
| .stat-rose { background: rgba(244,63,94,0.08); border: 1px solid rgba(244,63,94,0.2); } |
| .stat-rose .stat-icon { background: rgba(244,63,94,0.15); color: var(--accent-rose); } |
| .stat-rose .stat-label { color: var(--accent-rose); } .stat-rose .stat-value { color: var(--accent-rose); } |
| .overview-desc { padding: 24px; border-radius: 12px; margin-bottom: 24px; } |
| .overview-desc h2 { font-size: 16px; font-weight: 700; margin-bottom: 12px; } |
| .overview-desc p { font-size: 13px; color: var(--text-secondary); line-height: 1.7; margin-bottom: 16px; } |
| .overview-features { display: grid; grid-template-columns: repeat(3, 1fr); gap: 12px; } |
| .feature-card { padding: 16px; background: rgba(255,255,255,0.03); border-radius: 8px; border: 1px solid var(--border-subtle); } |
| .feature-card h3 { font-size: 13px; font-weight: 600; margin-bottom: 6px; } |
| .feature-card p { font-size: 11px; color: var(--text-muted); line-height: 1.6; margin: 0; } |
| .volume-nav { display: grid; grid-template-columns: repeat(4, 1fr); gap: 12px; } |
| .volume-card { padding: 16px; border-radius: 12px; text-align: left; cursor: pointer; transition: all 0.2s; border: 1px solid transparent; } |
| .volume-card:hover { transform: translateY(-2px); filter: brightness(1.1); } |
| .volume-card .vol-icon { width: 32px; height: 32px; margin-bottom: 10px; } |
| .volume-card .vol-num { font-size: 10px; font-weight: 600; text-transform: uppercase; letter-spacing: 0.5px; margin-bottom: 2px; } |
| .volume-card .vol-name { font-size: 13px; font-weight: 600; line-height: 1.3; } |
| .volume-card .vol-count { font-size: 11px; margin-top: 4px; opacity: 0.7; } |
| .volume-section { border-radius: 12px; overflow: hidden; margin-bottom: 12px; transition: all 0.2s; } |
| .volume-header { width: 100%; display: flex; align-items: center; gap: 12px; padding: 16px 20px; background: none; border: none; color: var(--text-primary); font-size: 14px; font-weight: 600; cursor: pointer; text-align: left; transition: background 0.2s; } |
| .volume-header:hover { background: rgba(255,255,255,0.03); } |
| .volume-header .chevron { transition: transform 0.2s; color: var(--text-muted); flex-shrink: 0; } |
| .volume-header.expanded .chevron { transform: rotate(90deg); } |
| .volume-header .vol-badge { margin-left: auto; font-size: 11px; font-weight: 500; color: var(--text-muted); } |
| .volume-body { max-height: 0; overflow: hidden; transition: max-height 0.3s ease-out; } |
| .volume-body.open { max-height: 2000px; } |
| .figure-item { padding: 14px 20px 14px 52px; border-left: 2px solid var(--border-subtle); margin-left: 20px; cursor: pointer; transition: background 0.2s; position: relative; } |
| .figure-item:hover { background: rgba(255,255,255,0.03); } |
| .figure-item.active { background: rgba(255,255,255,0.05); } |
| .figure-item h4 { font-size: 13px; font-weight: 500; color: var(--text-primary); margin-bottom: 4px; } |
| .figure-item .fig-desc { font-size: 11px; color: var(--text-muted); line-height: 1.5; margin-bottom: 8px; } |
| .figure-item .fig-tags { display: flex; flex-wrap: wrap; gap: 4px; } |
| .figure-item .fig-tag { padding: 2px 8px; border-radius: 4px; font-size: 10px; font-weight: 500; } |
| .figures-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 12px; } |
| .figure-card { padding: 16px; border-radius: 10px; cursor: pointer; transition: all 0.2s; border: 1px solid transparent; } |
| .figure-card:hover { transform: translateY(-2px); filter: brightness(1.08); } |
| .figure-card .fig-header { display: flex; justify-content: space-between; align-items: flex-start; margin-bottom: 8px; } |
| .figure-card .fig-id { font-family: var(--font-mono); font-size: 11px; font-weight: 600; } |
| .figure-card .fig-vol { font-size: 10px; color: var(--text-muted); } |
| .figure-card h3 { font-size: 12px; font-weight: 600; line-height: 1.4; margin-bottom: 6px; } |
| .figure-card .fig-desc-short { font-size: 11px; color: var(--text-muted); line-height: 1.5; margin-bottom: 10px; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; } |
| .tables-section { margin-bottom: 24px; } |
| .tables-section h2 { font-size: 16px; font-weight: 700; margin-bottom: 16px; } |
| .cc-tables-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 10px; } |
| .cc-table-item { padding: 12px; background: rgba(255,255,255,0.03); border-radius: 8px; border: 1px solid var(--border-subtle); transition: all 0.2s; } |
| .cc-table-item:hover { background: rgba(255,255,255,0.05); border-color: var(--border-medium); } |
| .cc-table-item .cc-header { display: flex; justify-content: space-between; align-items: center; margin-bottom: 6px; } |
| .cc-table-item .cc-num { font-family: var(--font-mono); font-size: 11px; color: var(--text-muted); } |
| .cc-table-item .cc-cat { padding: 2px 6px; border-radius: 4px; font-size: 9px; font-weight: 600; text-transform: uppercase; letter-spacing: 0.3px; } |
| .cc-table-item .cc-title { font-size: 12px; font-weight: 500; line-height: 1.4; } |
| .vol-tables-list { display: flex; flex-direction: column; gap: 10px; } |
| .vol-tables-item { padding: 12px 16px; background: rgba(255,255,255,0.02); border-radius: 8px; border: 1px solid var(--border-subtle); } |
| .vol-tables-item .vt-header { display: flex; align-items: center; gap: 8px; margin-bottom: 8px; } |
| .vol-tables-item .vt-name { font-size: 13px; font-weight: 600; } |
| .vol-tables-item .vt-tags { display: flex; flex-wrap: wrap; gap: 4px; } |
| .matrix-table-wrap { overflow-x: auto; margin-bottom: 24px; } |
| .matrix-table { width: 100%; border-collapse: collapse; font-size: 12px; } |
| .matrix-table th { text-align: left; padding: 10px 12px; color: var(--text-muted); font-weight: 600; font-size: 11px; text-transform: uppercase; letter-spacing: 0.3px; border-bottom: 1px solid var(--border-medium); } |
| .matrix-table td { padding: 10px 12px; border-bottom: 1px solid var(--border-subtle); vertical-align: top; } |
| .matrix-table tr:hover { background: rgba(255,255,255,0.02); } |
| .matrix-table .claim-num { font-family: var(--font-mono); font-weight: 700; color: var(--accent-blue); } |
| .matrix-table .fig-badge { display: inline-block; padding: 2px 6px; border-radius: 4px; font-size: 10px; font-weight: 500; margin-right: 4px; margin-bottom: 2px; } |
| .matrix-note { text-align: center; font-size: 11px; color: var(--text-muted); padding: 12px; } |
| .footer { border-top: 1px solid var(--border-subtle); margin-top: 40px; padding: 16px 24px; } |
| .footer-inner { max-width: 1400px; margin: 0 auto; display: flex; justify-content: space-between; align-items: center; font-size: 11px; color: var(--text-muted); } |
| .footer-inner .version { font-family: var(--font-mono); } |
| .vol-blue { background: rgba(59,130,246,0.06); border-color: rgba(59,130,246,0.25); } |
| .vol-blue .vol-icon { color: var(--accent-blue); } .vol-blue .vol-num { color: var(--accent-blue); } |
| .vol-blue .fig-tag { background: rgba(59,130,246,0.15); color: #93c5fd; } .vol-blue .fig-id { color: var(--accent-blue); } |
| .vol-green { background: rgba(34,197,94,0.06); border-color: rgba(34,197,94,0.25); } |
| .vol-green .vol-icon { color: var(--accent-green); } .vol-green .vol-num { color: var(--accent-green); } |
| .vol-green .fig-tag { background: rgba(34,197,94,0.15); color: #86efac; } .vol-green .fig-id { color: var(--accent-green); } |
| .vol-amber { background: rgba(245,158,11,0.06); border-color: rgba(245,158,11,0.25); } |
| .vol-amber .vol-icon { color: var(--accent-amber); } .vol-amber .vol-num { color: var(--accent-amber); } |
| .vol-amber .fig-tag { background: rgba(245,158,11,0.15); color: #fcd34d; } .vol-amber .fig-id { color: var(--accent-amber); } |
| .vol-purple { background: rgba(168,85,247,0.06); border-color: rgba(168,85,247,0.25); } |
| .vol-purple .vol-icon { color: var(--accent-purple); } .vol-purple .vol-num { color: var(--accent-purple); } |
| .vol-purple .fig-tag { background: rgba(168,85,247,0.15); color: #d8b4fe; } .vol-purple .fig-id { color: var(--accent-purple); } |
| .vol-rose { background: rgba(244,63,94,0.06); border-color: rgba(244,63,94,0.25); } |
| .vol-rose .vol-icon { color: var(--accent-rose); } .vol-rose .vol-num { color: var(--accent-rose); } |
| .vol-rose .fig-tag { background: rgba(244,63,94,0.15); color: #fda4af; } .vol-rose .fig-id { color: var(--accent-rose); } |
| .vol-cyan { background: rgba(6,182,212,0.06); border-color: rgba(6,182,212,0.25); } |
| .vol-cyan .vol-icon { color: var(--accent-cyan); } .vol-cyan .vol-num { color: var(--accent-cyan); } |
| .vol-cyan .fig-tag { background: rgba(6,182,212,0.15); color: #67e8f9; } .vol-cyan .fig-id { color: var(--accent-cyan); } |
| .vol-emerald { background: rgba(16,185,129,0.06); border-color: rgba(16,185,129,0.25); } |
| .vol-emerald .vol-icon { color: var(--accent-emerald); } .vol-emerald .vol-num { color: var(--accent-emerald); } |
| .vol-emerald .fig-tag { background: rgba(16,185,129,0.15); color: #6ee7b7; } .vol-emerald .fig-id { color: var(--accent-emerald); } |
| .vol-indigo { background: rgba(99,102,241,0.06); border-color: rgba(99,102,241,0.25); } |
| .vol-indigo .vol-icon { color: var(--accent-indigo); } .vol-indigo .vol-num { color: var(--accent-indigo); } |
| .vol-indigo .fig-tag { background: rgba(99,102,241,0.15); color: #a5b4fc; } .vol-indigo .fig-id { color: var(--accent-indigo); } |
| .cat-IP { background: rgba(139,92,246,0.15); color: #c4b5fd; } .cat-Nav { background: rgba(148,163,184,0.15); color: #cbd5e1; } |
| .cat-Ref { background: rgba(100,116,139,0.15); color: #94a3b8; } .cat-Genomics { background: rgba(34,197,94,0.15); color: #86efac; } |
| .cat-Clinical { background: rgba(244,63,94,0.15); color: #fda4af; } .cat-QA { background: rgba(245,158,11,0.15); color: #fcd34d; } |
| .cat-Legal { background: rgba(59,130,246,0.15); color: #93c5fd; } .cat-Risk { background: rgba(249,115,22,0.15); color: #fdba74; } |
| .cat-Regulatory { background: rgba(239,68,68,0.15); color: #fca5a5; } .cat-Security { background: rgba(234,179,8,0.15); color: #fde047; } |
| .cat-Software { background: rgba(168,85,247,0.15); color: #d8b4fe; } .cat-Evidence { background: rgba(99,102,241,0.15); color: #a5b4fc; } |
| .cat-Ops { background: rgba(6,182,212,0.15); color: #67e8f9; } .cat-Privacy { background: rgba(236,72,153,0.15); color: #f9a8d4; } |
| .cat-DevOps { background: rgba(20,184,166,0.15); color: #5eead4; } |
| @media (max-width: 1024px) { .stats-grid { grid-template-columns: repeat(3, 1fr); } .figures-grid { grid-template-columns: repeat(2, 1fr); } .volume-nav { grid-template-columns: repeat(2, 1fr); } .cc-tables-grid { grid-template-columns: repeat(2, 1fr); } .overview-features { grid-template-columns: 1fr; } } |
| @media (max-width: 640px) { .stats-grid { grid-template-columns: repeat(2, 1fr); } .figures-grid { grid-template-columns: 1fr; } .volume-nav { grid-template-columns: 1fr; } .cc-tables-grid { grid-template-columns: 1fr; } .header-inner { flex-wrap: wrap; } .search-box input { width: 160px; } .nav-inner { overflow-x: auto; } } |
| </style> |
| <base target="_blank"> |
| </head> |
| <body> |
| <header class="header"> |
| <div class="header-inner"> |
| <div class="brand"> |
| <div class="brand-icon">H</div> |
| <div class="brand-text"> |
| <h1>HSPA/RIGOR Platform</h1> |
| <p>Patent- & Regulatory-Grade Documentation</p> |
| </div> |
| </div> |
| <div class="sim-panel"> |
| <div class="sim-progress" id="simProgress"> |
| <span class="sim-percent" id="simPercent">0%</span> |
| <div class="sim-bar-bg"><div class="sim-bar-fill" id="simBar"></div></div> |
| </div> |
| <button class="btn btn-green" id="btnSim" onclick="startSimulation()"> |
| <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"><polygon points="5 3 19 12 5 21 5 3"/></svg> |
| Simulate |
| </button> |
| <button class="btn btn-slate" onclick="resetSimulation()"> |
| <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M3 12a9 9 0 1 0 9-9 9.75 9.75 0 0 0-6.74 2.74L3 8"/><path d="M3 3v5h5"/></svg> |
| Reset |
| </button> |
| </div> |
| </div> |
| </header> |
|
|
| <nav class="nav-bar"> |
| <div class="nav-inner"> |
| <button class="nav-tab active" data-tab="overview" onclick="switchTab('overview')"> |
| <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M2 12s3-7 10-7 10 7 10 7-3 7-10 7-10-7-10-7Z"/><circle cx="12" cy="12" r="3"/></svg> |
| Overview |
| </button> |
| <button class="nav-tab" data-tab="architecture" onclick="switchTab('architecture')"> |
| <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><ellipse cx="12" cy="5" rx="9" ry="3"/><path d="M3 5V19A9 3 0 0 0 21 19V5"/><path d="M3 12A9 3 0 0 0 21 12"/></svg> |
| Volumes |
| </button> |
| <button class="nav-tab" data-tab="figures" onclick="switchTab('figures')"> |
| <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M14.5 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V7.5L14.5 2z"/><polyline points="14 2 14 8 20 8"/><line x1="16" y1="13" x2="8" y2="13"/><line x1="16" y1="17" x2="8" y2="17"/><line x1="10" y1="9" x2="8" y2="9"/></svg> |
| Figures |
| </button> |
| <button class="nav-tab" data-tab="tables" onclick="switchTab('tables')"> |
| <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect x="2" y="2" width="20" height="8" rx="2" ry="2"/><rect x="2" y="14" width="20" height="8" rx="2" ry="2"/><line x1="6" y1="6" x2="6.01" y2="6"/><line x1="6" y1="18" x2="6.01" y2="18"/></svg> |
| Tables |
| </button> |
| <button class="nav-tab" data-tab="matrix" onclick="switchTab('matrix')"> |
| <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><line x1="6" y1="3" x2="6" y2="15"/><circle cx="18" cy="6" r="3"/><circle cx="6" cy="18" r="3"/><path d="M18 9a9 9 0 0 1-9 9"/></svg> |
| Cross-Ref |
| </button> |
| <div class="search-box"> |
| <svg class="search-icon" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="11" cy="11" r="8"/><line x1="21" y1="21" x2="16.65" y2="16.65"/></svg> |
| <input type="text" id="searchInput" placeholder="Search figures, tables..." oninput="handleSearch(this.value)"> |
| </div> |
| </div> |
| </nav> |
|
|
| <main class="main" id="mainContent"> |
| <div id="tab-overview" class="tab-content"> |
| <div class="stats-grid"> |
| <div class="stat-card stat-blue"> |
| <div class="stat-icon"><svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><ellipse cx="12" cy="5" rx="9" ry="3"/><path d="M3 5V19A9 3 0 0 0 21 19V5"/><path d="M3 12A9 3 0 0 0 21 12"/></svg></div> |
| <div class="stat-label">Volumes</div><div class="stat-value">8</div> |
| </div> |
| <div class="stat-card stat-green"> |
| <div class="stat-icon"><svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M14.5 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V7.5L14.5 2z"/><polyline points="14 2 14 8 20 8"/><line x1="16" y1="13" x2="8" y2="13"/><line x1="16" y1="17" x2="8" y2="17"/><line x1="10" y1="9" x2="8" y2="9"/></svg></div> |
| <div class="stat-label">Figures</div><div class="stat-value">50</div> |
| </div> |
| <div class="stat-card stat-amber"> |
| <div class="stat-icon"><svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect x="2" y="2" width="20" height="8" rx="2" ry="2"/><rect x="2" y="14" width="20" height="8" rx="2" ry="2"/><line x1="6" y1="6" x2="6.01" y2="6"/><line x1="6" y1="18" x2="6.01" y2="18"/></svg></div> |
| <div class="stat-label">Tables</div><div class="stat-value">100</div> |
| </div> |
| <div class="stat-card stat-purple"> |
| <div class="stat-icon"><svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><line x1="6" y1="3" x2="6" y2="15"/><circle cx="18" cy="6" r="3"/><circle cx="6" cy="18" r="3"/><path d="M18 9a9 9 0 0 1-9 9"/></svg></div> |
| <div class="stat-label">Cross-Refs</div><div class="stat-value">28</div> |
| </div> |
| <div class="stat-card stat-rose"> |
| <div class="stat-icon"><svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M12 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 10z"/></svg></div> |
| <div class="stat-label">USPTO Claims</div><div class="stat-value">7</div> |
| </div> |
| </div> |
|
|
| <div class="overview-desc glass"> |
| <h2>Platform Overview</h2> |
| <p>The <strong style="color:var(--accent-blue)">HSPA/RIGOR Platform</strong> (Hyper-Synchronous Processing Array / Reproducible Integrated Genomic Operations Repository) is a comprehensive, patent-grade documentation system for genomic processing, post-quantum cryptographic security, and regulatory compliance. Consistent numbering across USPTO, FDA, whitepaper, dissertation, and software documentation ensures complete traceability.</p> |
| <div class="overview-features"> |
| <div class="feature-card"> |
| <h3 style="color:var(--accent-blue)">Scientific Assimilation</h3> |
| <p>NLP-powered literature ingestion, NER, entity linking, and automated adapter generation for GWAS catalogs.</p> |
| </div> |
| <div class="feature-card"> |
| <h3 style="color:var(--accent-green)">Genomic Processing</h3> |
| <p>PRS calculation (PRS-CS, LDpred2), LD correction, ancestry calibration, and population transferability analysis.</p> |
| </div> |
| <div class="feature-card"> |
| <h3 style="color:var(--accent-amber)">Zero-Trust Security</h3> |
| <p>NIST PQC algorithms (ML-KEM, ML-DSA, SLH-DSA), Merkle DAG ledger, blockchain anchoring, and immutable audit trails.</p> |
| </div> |
| </div> |
| </div> |
|
|
| <div class="volume-nav" id="overviewVolumes"></div> |
| </div> |
|
|
| <div id="tab-architecture" class="tab-content hidden"></div> |
| <div id="tab-figures" class="tab-content hidden"></div> |
| <div id="tab-tables" class="tab-content hidden"></div> |
| <div id="tab-matrix" class="tab-content hidden"></div> |
| </main> |
|
|
| <footer class="footer"> |
| <div class="footer-inner"> |
| <span>HSPA/RIGOR Platform Documentation</span> |
| <span class="version">v2.0.0 | 16 July 2026</span> |
| </div> |
| </footer> |
| <script> |
| const volumes = [ |
| { id: "v1", title: "System Architecture", icon: "database", color: "blue", |
| children: [ |
| { id: "f1", title: "Overall HSPA/RIGOR Platform Architecture", tables: ["Table 1","Table 10","Table 72","Table 100"], desc: "Mermaid flowchart: External Inputs → SAE → Core Block → Security → Ledger → Outputs" }, |
| { id: "f2", title: "Scientific Assimilation Engine (SAE)", tables: ["Table 2","Table 3","Table 4"], desc: "Document → Section Splitter → Paragraph Splitter → Sentence Tokenizer → NER → Entity Linker → Triple Extractor → Knowledge Graph" }, |
| { id: "f3", title: "Core Computational Block", tables: ["Table 11","Table 15","Table 17","Table 21"], desc: "GWAS Summary Stats → QC → LD Reference Selection → PRS Method → Score → Calibration → Clinical Report" }, |
| { id: "f4", title: "NLP Processing Pipeline", tables: ["Table 2"], desc: "Raw Text → Pre-processing → Tokenization → POS Tagging → Dependency Parsing → Constituency Parsing → Relation Extraction → JSON-LD" }, |
| { id: "f5", title: "Named Entity Recognition Architecture", tables: ["Table 3"], desc: "Token Sequence → BioBERT Embeddings → BiLSTM → CRF Decoder → Entity Tags → Entity Linking → Knowledge Base" }, |
| { id: "f6", title: "Repository Resolution Engine", tables: ["Table 4","Table 75"], desc: "Recognized Entity → Repository Mapping → URL Template Resolution → External API → Local Cache → Standardized Schema" }, |
| { id: "f7", title: "Dependency Graph Construction", tables: ["Table 7","Table 8"], desc: "Extracted Triples → Node Deduplication + Edge Creation → Graph Database → Semantic Query Interface" }, |
| { id: "f8", title: "Automated Adapter Generator", tables: ["Table 5","Table 9"], desc: "Data Schema → Template Engine → Code Generation → Sandbox Testing → Deploy Adapter (or Error Feedback Loop)" }, |
| { id: "f9", title: "Pipeline Orchestration Controller", tables: ["Table 6","Table 96"], desc: "Scheduler → Workflow Parser → DAG Validator → Task Dispatcher → Completion Check → Cleanup & Log → Notification" }, |
| { id: "f10", title: "Runtime Service Topology", tables: ["Table 38","Table 40","Table 97"], desc: "API Gateway ↔ Auth Service → Orchestrator ↔ Event Queue → PRS Calculation → SET Ledger Node" } |
| ]}, |
| { id: "v2", title: "Genomic Processing", icon: "activity", color: "green", |
| children: [ |
| { id: "f11", title: "GWAS Summary Statistics Import", tables: ["Table 11","Table 12","Table 13"], desc: "GWAS Catalog/FTP → Format Detection → Column Mapping/VCF Parser → Standard Schema → QC → GWAS Inventory DB" }, |
| { id: "f12", title: "Reference Genome Pipeline", tables: ["Table 14"], desc: "Reference FASTA → Indexing → Chromosome Splitting → Liftover Chain Storage → Build Registry → Reference Genome Catalog" }, |
| { id: "f13", title: "Variant Calling Pipeline", tables: ["Table 16"], desc: "Raw Reads (FASTQ) → Alignment (BWA/minimap2) → Duplicate Marking → BQSR → Variant Calling (GATK/DeepVariant) → Filtering → Cohort VCF → QC Metrics" }, |
| { id: "f14", title: "PRS Workflow", tables: ["Table 15","Table 17","Table 18"], desc: "GWAS Summary Statistics + LD Reference Panel → PRS Method Selection (PRS-CS/LDpred2) → Score Individuals → Ancestry Calibration → Clinical Report" }, |
| { id: "f15", title: "LD Correction Workflow", tables: ["Table 15","Table 18"], desc: "GWAS Summary Statistics → Match to LD Panel SNPs → Compute LD Matrix → Shrinkage/Regularization → Update Effect Sizes → Posterior Effect Sizes" }, |
| { id: "f16", title: "Ancestry PCA", tables: ["Table 19","Table 20"], desc: "Reference Genotypes → PCA → PC Loadings → Target Genotypes → Project onto Loadings → Population Assignment → Sample Projection Table" }, |
| { id: "f17", title: "PRS Calibration", tables: ["Table 21"], desc: "Raw PRS → Decile Binning → Observed Disease Rate + Predicted Risk → Calibration Curve → AUC/R² Metrics" }, |
| { id: "f18", title: "Population Transferability", tables: ["Table 22"], desc: "GWAS EUR → PRS Model → Score EUR Target + Score AFR Target → Performance Metrics → Transferability Report" } |
| ]}, |
| { id: "v3", title: "Security", icon: "shield", color: "amber", |
| children: [ |
| { id: "f19", title: "Zero Trust Architecture", tables: ["Table 24","Table 91"], desc: "User/Service → Policy Enforcement Point → Policy Decision Point ↔ Policy Rules → Resource/API" }, |
| { id: "f20", title: "ML-KEM Key Exchange", tables: ["Table 25","Table 84"], desc: "ClientHello (ML-KEM-1024) → ServerHello + Encapsulated Key → Shared Secret (Kyber.CCAKEM.Decap) → Encrypted Application Data (AES-256-GCM)" }, |
| { id: "f21", title: "ML-DSA Signature Flow", tables: ["Table 26","Table 31"], desc: "Data Payload → Hash (SHA3-512) → ML-DSA.Sign → Signature → ML-DSA.Verify → Valid?" }, |
| { id: "f22", title: "Merkle DAG", tables: ["Table 28","Table 85"], desc: "GWAS Result + PRS Model + Calibration → Individual Hashes → Merkle Root → Batch Root" }, |
| { id: "f23", title: "Ledger Synchronization", tables: ["Table 29","Table 37"], desc: "Node A → New DAG Node (content-hash) → Node B → Verify & Store → ACK + Signature → Consistent State" }, |
| { id: "f24", title: "Blockchain Anchoring", tables: ["Table 27","Table 30"], desc: "Batch Root → SLH-DSA Sign (Off-chain) → Blockchain Transaction → Smart Contract Anchor → Immutable Timestamp Proof" } |
| ]}, |
| { id: "v4", title: "Software", icon: "code", color: "purple", |
| children: [ |
| { id: "f25", title: "PostgreSQL Schema", tables: ["Table 32","Table 33","Table 34","Table 35","Table 36","Table 37","Table 86","Table 87"], desc: "ER Diagram: CASES ↔ EXHIBITS ↔ CLAIMS ↔ PRS_RUNS ↔ LEDGER_NODES" }, |
| { id: "f26", title: "Entity Relationship Diagram", tables: ["Table 32–37","Table 100"], desc: "CASE ↔ EXHIBIT ↔ CLAIM ↔ PRS_RUN ↔ LEDGER_NODE ↔ BLOCK" }, |
| { id: "f27", title: "API Architecture", tables: ["Table 38","Table 39","Table 88","Table 97"], desc: "Client → API Gateway → Auth Service + Pipeline Orchestrator + Query Service → PostgreSQL" }, |
| { id: "f28", title: "Authentication Flow", tables: ["Table 39","Table 91"], desc: "User → Frontend → Auth Service → JWT → API → Validate Token → Protected Resource" }, |
| { id: "f29", title: "React Dashboard", tables: ["Table 41"], desc: "Widget Registry + Active Cases + PRS Run Status + Report Viewer ↔ API Gateway → Backend Services" }, |
| { id: "f30", title: "Event Queue", tables: ["Table 40","Table 97"], desc: "Orchestrator → Message Queue → Ledger Sync Worker + Notification Service + Audit Log Writer" } |
| ]}, |
| { id: "v5", title: "FDA & Regulatory", icon: "book", color: "rose", |
| children: [ |
| { id: "f31", title: "Risk Management (ISO 14971)", tables: ["Table 42","Table 43","Table 44","Table 81"], desc: "Risk Management Plan → Hazard Identification → Risk Estimation → Evaluation → Controls → Verification → Residual Risk → Post-Market Monitoring" }, |
| { id: "f32", title: "Hazard Controls", tables: ["Table 44","Table 82"], desc: "Hazard: Incorrect PRS → Checksum Verification + Sandbox Testing + Manual Review Flag → Effectiveness Verified → Residual Risk Low/Medium" }, |
| { id: "f33", title: "Traceability Matrix", tables: ["Table 45","Table 83"], desc: "User Need → Design Input → Design Output → Verification → Validation" }, |
| { id: "f34", title: "Verification Flow", tables: ["Table 46"], desc: "Test Case → Execute → Record Result → Compare to Expected → Pass/Fail → Defect Log → Fix → Re-execute" }, |
| { id: "f35", title: "Validation Workflow", tables: ["Table 47","Table 48"], desc: "Validation Protocol → Assemble Cohort → Execute PRS Pipeline → Compute Metrics → Acceptance Criteria? → Approve or Investigate" }, |
| { id: "f36", title: "Clinical Release Process", tables: ["Table 49","Table 61","Table 80"], desc: "Release Candidate → SBOM Review → Security Scan → Verification Results → Validation Results → IRB Approval → Release Checklist → Deploy or Fix" } |
| ]}, |
| { id: "v6", title: "AI", icon: "eye", color: "cyan", |
| children: [ |
| { id: "f37", title: "Transformer Architecture", tables: ["Table 51","Table 52"], desc: "Input Tokens → Embedding + Positional Encoding → Encoder Layer ×N → Decoder Layer ×N → Linear Projection → Softmax → Output Probabilities" }, |
| { id: "f38", title: "Attention Blocks", tables: ["Table 52"], desc: "Q + K → MatMul → Scale → Optional Mask → Softmax → MatMul with V → Attention Output" }, |
| { id: "f39", title: "Reasoning Loop", tables: ["Table 53","Table 56"], desc: "Question → Answer → Core Block → Attention → Add & Norm → MLP → Add & Norm → Repeat ×4 → Output" }, |
| { id: "f40", title: "Training Pipeline", tables: ["Table 54","Table 55","Table 56"], desc: "Dataset → Preprocess → Forward Pass → Loss → Backward Pass → Optimizer → Log Metrics → Evaluation → Checkpoint → Save" } |
| ]}, |
| { id: "v7", title: "Reproducibility", icon: "git", color: "emerald", |
| children: [ |
| { id: "f41", title: "Docker Build Graph", tables: ["Table 57","Table 58","Table 96"], desc: "Git Commit → Dockerfile → docker build → Docker Image → Container Registry → Pipeline Execution → PRS Output" }, |
| { id: "f42", title: "Provenance Manifest", tables: ["Table 60","Table 63","Table 79"], desc: "Input Data + Process + Output Artifact → Provenance Record → Provenance Graph Database (W3C PROV)" }, |
| { id: "f43", title: "Git Version Graph", tables: ["Table 59"], desc: "main branch → commits a1b2c3, d4e5f6 (v1.0.0), 7a8b9c, 0d1e2f (v2.0.0)" }, |
| { id: "f44", title: "Artifact Lineage", tables: ["Table 60","Table 65"], desc: "GWAS Raw Data + LD Panel → PRS Model → PRS Scores → Clinical Report → Lineage Records at each step" }, |
| { id: "f45", title: "Chain of Custody", tables: ["Table 64","Table 71","Table 89"], desc: "Artifact Created → Transfer to Custodian → Secure Storage → Transfer to Expert → Court Submission → Integrity Verification → Custody Log" } |
| ]}, |
| { id: "v8", title: "Litigation Evidence", icon: "users", color: "indigo", |
| children: [ |
| { id: "f46", title: "Court Evidence Flow", tables: ["Table 66","Table 70","Table 71"], desc: "Scientific Artifact → Content Hash → ML-DSA Sign by Expert → Exhibit Attachment → Court Filing → Docket Number → Opposing Verification" }, |
| { id: "f47", title: "Daubert Workflow", tables: ["Table 68"], desc: "Proffered Evidence → Tested? → Peer Reviewed? → Known Error Rate? → Standards Exist? → General Acceptance? → Admissibility Decision" }, |
| { id: "f48", title: "Scientific Citation Network", tables: ["Table 69"], desc: "Expert Report → Cites GWAS Study A (Supports) + GWAS Study B (Contradicts) + Methodology Paper (Background)" }, |
| { id: "f49", title: "Evidence Provenance", tables: ["Table 63","Table 70","Table 89"], desc: "Raw Data → Processed Data → Analysis Results → Exhibit Produced → Provenance Records at each transformation" }, |
| { id: "f50", title: "Expert Report Assembly", tables: ["Table 67","Table 73"], desc: "Case Materials → Background → Methods (Data Sources + Pipeline) → Results → Expert Opinions → Signature & Verification → Final Filing" } |
| ]} |
| ]; |
| |
| const crossCuttingTables = [ |
| { id: "t72", num: "72", title: "USPTO Claim-to-Figure Matrix", category: "IP" }, |
| { id: "t73", num: "73", title: "Figure-to-Table Cross-Reference", category: "Nav" }, |
| { id: "t74", num: "74", title: "Acronym & Abbreviation Glossary", category: "Ref" }, |
| { id: "t75", num: "75", title: "SNP Annotation Dictionary", category: "Genomics" }, |
| { id: "t76", num: "76", title: "Variant Classification Matrix (ACMG/AMP)", category: "Genomics" }, |
| { id: "t77", num: "77", title: "Population Allele Frequency Table", category: "Genomics" }, |
| { id: "t78", num: "78", title: "Clinical Performance Metrics (Per Disease)", category: "Clinical" }, |
| { id: "t79", num: "79", title: "Reproducibility Manifest Schema Validation Log", category: "QA" }, |
| { id: "t80", num: "80", title: "SPDX License Inventory", category: "Legal" }, |
| { id: "t81", num: "81", title: "Risk Register (Project Risks)", category: "Risk" }, |
| { id: "t82", num: "82", title: "ISO 14971 Hazard Analysis Detail", category: "Risk" }, |
| { id: "t83", num: "83", title: "FDA Traceability Matrix (Full)", category: "Regulatory" }, |
| { id: "t84", num: "84", title: "Cryptographic Key Hierarchy", category: "Security" }, |
| { id: "t85", num: "85", title: "Merkle Node Definitions (Extended)", category: "Security" }, |
| { id: "t86", num: "86", title: "PostgreSQL Data Dictionary (All Columns)", category: "Software" }, |
| { id: "t87", num: "87", title: "PostgreSQL Index Inventory", category: "Software" }, |
| { id: "t88", num: "88", title: "API Request/Response Example Catalog", category: "Software" }, |
| { id: "t89", num: "89", title: "Evidence Chain Metadata (Detailed)", category: "Evidence" }, |
| { id: "t90", num: "90", title: "Long-Term Archive Storage Inventory", category: "Ops" }, |
| { id: "t91", num: "91", title: "User Access Audit Log", category: "Security" }, |
| { id: "t92", num: "92", title: "Data Anonymization/Pseudonymization Map", category: "Privacy" }, |
| { id: "t93", num: "93", title: "Cohort Phenotype Definitions", category: "Clinical" }, |
| { id: "t94", num: "94", title: "Data Transfer Agreement Log", category: "Legal" }, |
| { id: "t95", num: "95", title: "Computational Environment Specification", category: "Ops" }, |
| { id: "t96", num: "96", title: "Build & Deployment Log", category: "DevOps" }, |
| { id: "t97", num: "97", title: "Inter-Component Message Schema Catalog", category: "Software" }, |
| { id: "t98", num: "98", title: "Configuration Parameter Registry", category: "Ops" }, |
| { id: "t99", num: "99", title: "Glossary of Scientific Terms", category: "Ref" }, |
| { id: "t100", num: "100", title: "Master Figure-Table-Volume Index", category: "Nav" } |
| ]; |
| |
| const roman = ["I","II","III","IV","V","VI","VII","VIII"]; |
| const claimMatrix = [ |
| { claim: "1", element: "Scientific assimilation engine", figs: "FIG. 1, FIG. 2", support: "Overall architecture and SAE detail" }, |
| { claim: "2", element: "NLP processing pipeline with NER", figs: "FIG. 4, FIG. 5", support: "Pipeline and entity recognition architecture" }, |
| { claim: "3", element: "Automatic adapter generation", figs: "FIG. 8", support: "Adapter generator workflow" }, |
| { claim: "4", element: "Immutable ledger via Merkle DAG", figs: "FIG. 22, FIG. 24", support: "DAG construction and blockchain anchoring" }, |
| { claim: "5", element: "PRS calculation with LD correction", figs: "FIG. 14, FIG. 15", support: "PRS and LD correction workflows" }, |
| { claim: "6", element: "Zero-trust security with PQC", figs: "FIG. 19, FIG. 20, FIG. 21", support: "Architecture, key exchange, and signing" }, |
| { claim: "7", element: "Reproducibility via containers/provenance", figs: "FIG. 41, FIG. 42", support: "Docker build and provenance manifest" } |
| ]; |
| |
| const svgs = { |
| database: `<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><ellipse cx="12" cy="5" rx="9" ry="3"/><path d="M3 5V19A9 3 0 0 0 21 19V5"/><path d="M3 12A9 3 0 0 0 21 12"/></svg>`, |
| activity: `<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M22 12h-4l-3 9L9 3l-3 9H2"/></svg>`, |
| shield: `<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M12 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 10z"/></svg>`, |
| code: `<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="16 18 22 12 16 6"/><polyline points="8 6 2 12 8 18"/></svg>`, |
| book: `<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M2 3h6a4 4 0 0 1 4 4v14a3 3 0 0 0-3-3H2z"/><path d="M22 3h-6a4 4 0 0 0-4 4v14a3 3 0 0 1 3-3h7z"/></svg>`, |
| eye: `<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M2 12s3-7 10-7 10 7 10 7-3 7-10 7-10-7-10-7Z"/><circle cx="12" cy="12" r="3"/></svg>`, |
| git: `<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><line x1="6" y1="3" x2="6" y2="15"/><circle cx="18" cy="6" r="3"/><circle cx="6" cy="18" r="3"/><path d="M18 9a9 9 0 0 1-9 9"/></svg>`, |
| users: `<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M17 21v-2a4 4 0 0 0-4-4H5a4 4 0 0 0-4 4v2"/><circle cx="9" cy="7" r="4"/><path d="M23 21v-2a4 4 0 0 0-3-3.87"/><path d="M16 3.13a4 4 0 0 1 0 7.75"/></svg>`, |
| chevronRight: `<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"><polyline points="9 18 15 12 9 6"/></svg>` |
| }; |
| |
| let currentTab = "overview", expanded = {}, selectedFigure = null, simInterval = null; |
| |
| function renderOverviewVolumes() { |
| document.getElementById("overviewVolumes").innerHTML = volumes.map((v, i) => ` |
| <div class="volume-card vol-${v.color}" onclick="navToVolume('${v.id}')"> |
| <div class="vol-icon">${svgs[v.icon]}</div> |
| <div class="vol-num">Volume ${roman[i]}</div> |
| <div class="vol-name">${v.title}</div> |
| <div class="vol-count">${v.children.length} figures</div> |
| </div> |
| `).join(""); |
| } |
| |
| function renderVolumes() { |
| const container = document.getElementById("tab-architecture"); |
| container.innerHTML = volumes.map((v, i) => { |
| const isOpen = expanded[v.id] || false; |
| return `<div class="volume-section vol-${v.color} glass"> |
| <button class="volume-header ${isOpen ? 'expanded' : ''}" onclick="toggleVolume('${v.id}')"> |
| <span class="chevron">${svgs.chevronRight}</span> |
| <span style="color:var(--accent-${v.color})">${svgs[v.icon]}</span> |
| <span>Volume ${roman[i]} — ${v.title}</span> |
| <span class="vol-badge">${v.children.length} figures</span> |
| </button> |
| <div class="volume-body ${isOpen ? 'open' : ''}" id="body-${v.id}"> |
| ${v.children.map(c => ` |
| <div class="figure-item ${selectedFigure === c.id ? 'active' : ''}" onclick="selectFigure('${c.id}')"> |
| <h4>${c.title}</h4> |
| <p class="fig-desc">${c.desc}</p> |
| <div class="fig-tags">${c.tables.map(t => `<span class="fig-tag">${t}</span>`).join('')}</div> |
| </div> |
| `).join('')} |
| </div> |
| </div>`; |
| }).join(""); |
| } |
| |
| function renderFigures() { |
| const allFigs = volumes.flatMap(v => v.children.map(c => ({...c, volColor: v.color, volTitle: v.title}))); |
| const container = document.getElementById("tab-figures"); |
| container.innerHTML = `<div class="figures-grid">${allFigs.map(f => ` |
| <div class="figure-card vol-${f.volColor}" onclick="selectFigure('${f.id}')"> |
| <div class="fig-header"> |
| <span class="fig-id">${f.id.toUpperCase()}</span> |
| <span class="fig-vol">${f.volTitle}</span> |
| </div> |
| <h3>${f.title.replace(/^FIG\. \d+ — /, '')}</h3> |
| <p class="fig-desc-short">${f.desc}</p> |
| <div class="fig-tags">${f.tables.slice(0,3).map(t => `<span class="fig-tag">${t}</span>`).join('')}${f.tables.length > 3 ? '<span class="fig-tag">+' + (f.tables.length - 3) + '</span>' : ''}</div> |
| </div> |
| `).join('')}</div>`; |
| } |
| |
| function renderTables() { |
| const container = document.getElementById("tab-tables"); |
| container.innerHTML = ` |
| <div class="tables-section"> |
| <h2>Cross-Cutting Tables (72–100)</h2> |
| <div class="cc-tables-grid">${crossCuttingTables.map(t => ` |
| <div class="cc-table-item"> |
| <div class="cc-header"> |
| <span class="cc-num">Table ${t.num}</span> |
| <span class="cc-cat cat-${t.category}">${t.category}</span> |
| </div> |
| <div class="cc-title">${t.title}</div> |
| </div> |
| `).join('')}</div> |
| </div> |
| <div class="tables-section"> |
| <h2>Volume-Specific Tables</h2> |
| <div class="vol-tables-list">${volumes.map((v, i) => { |
| const allTables = [...new Set(v.children.flatMap(c => c.tables))]; |
| return `<div class="vol-tables-item"> |
| <div class="vt-header"> |
| <span style="color:var(--accent-${v.color})">${svgs[v.icon]}</span> |
| <span class="vt-name">Volume ${roman[i]} — ${v.title}</span> |
| </div> |
| <div class="vt-tags">${allTables.map(t => `<span class="fig-tag" style="background:rgba(255,255,255,0.05);color:var(--text-secondary)">${t}</span>`).join('')}</div> |
| </div>`; |
| }).join('')}</div> |
| </div>`; |
| } |
| |
| function renderMatrix() { |
| const container = document.getElementById("tab-matrix"); |
| container.innerHTML = ` |
| <div class="glass" style="padding:24px;border-radius:12px;margin-bottom:24px;"> |
| <h2 style="font-size:16px;font-weight:700;margin-bottom:16px;">USPTO Claim-to-Figure Matrix (Table 72)</h2> |
| <div class="matrix-table-wrap"> |
| <table class="matrix-table"> |
| <thead><tr><th>Claim #</th><th>Claim Element</th><th>Figure(s)</th><th>Support</th></tr></thead> |
| <tbody>${claimMatrix.map(row => ` |
| <tr> |
| <td class="claim-num">${row.claim}</td> |
| <td>${row.element}</td> |
| <td>${row.figs.split(', ').map(f => `<span class="fig-badge" style="background:rgba(59,130,246,0.1);color:#93c5fd;border:1px solid rgba(59,130,246,0.2)">${f}</span>`).join('')}</td> |
| <td style="color:var(--text-muted);font-size:11px;">${row.support}</td> |
| </tr> |
| `).join('')}</tbody> |
| </table> |
| </div> |
| </div> |
| <div class="glass" style="padding:24px;border-radius:12px;"> |
| <h2 style="font-size:16px;font-weight:700;margin-bottom:16px;">Figure-to-Table Cross-Reference (Table 73)</h2> |
| <div class="matrix-table-wrap"> |
| <table class="matrix-table"> |
| <thead><tr><th>Figure</th><th>Title</th><th>Primary Tables</th></tr></thead> |
| <tbody>${volumes.flatMap(v => v.children.map(c => ({...c, volColor: v.color}))).slice(0,15).map(f => ` |
| <tr> |
| <td><span style="font-family:var(--font-mono);font-size:11px;color:var(--accent-${f.volColor})">${f.id.toUpperCase()}</span></td> |
| <td style="font-size:11px;">${f.title.replace(/^FIG\. \d+ — /, '')}</td> |
| <td>${f.tables.slice(0,3).map(t => `<span class="fig-badge" style="background:rgba(255,255,255,0.05);color:var(--text-secondary);border:1px solid var(--border-subtle)">${t}</span>`).join('')}${f.tables.length > 3 ? '<span style="font-size:10px;color:var(--text-muted)">+' + (f.tables.length - 3) + '</span>' : ''}</td> |
| </tr> |
| `).join('')}</tbody> |
| </table> |
| </div> |
| <div class="matrix-note">Showing 15 of 50 figures — use Volumes tab for full listing</div> |
| </div>`; |
| } |
| |
| function switchTab(tab) { |
| document.querySelectorAll('.tab-content').forEach(el => el.classList.add('hidden')); |
| document.querySelectorAll('.nav-tab').forEach(el => el.classList.remove('active')); |
| document.getElementById('tab-' + tab).classList.remove('hidden'); |
| document.querySelector('[data-tab="' + tab + '"]').classList.add('active'); |
| currentTab = tab; |
| if (tab === 'architecture') renderVolumes(); |
| if (tab === 'figures') renderFigures(); |
| if (tab === 'tables') renderTables(); |
| if (tab === 'matrix') renderMatrix(); |
| document.getElementById('tab-' + tab).classList.add('fade-in'); |
| setTimeout(() => document.getElementById('tab-' + tab).classList.remove('fade-in'), 300); |
| } |
| |
| function toggleVolume(vid) { |
| expanded[vid] = !expanded[vid]; |
| const btn = document.querySelector(`[onclick="toggleVolume('${vid}')"]`); |
| const body = document.getElementById('body-' + vid); |
| if (expanded[vid]) { btn.classList.add('expanded'); body.classList.add('open'); } |
| else { btn.classList.remove('expanded'); body.classList.remove('open'); } |
| } |
| |
| function selectFigure(fid) { |
| selectedFigure = selectedFigure === fid ? null : fid; |
| if (currentTab === 'architecture') renderVolumes(); |
| if (currentTab === 'figures') renderFigures(); |
| } |
| |
| function navToVolume(vid) { |
| expanded[vid] = true; |
| switchTab('architecture'); |
| setTimeout(() => { |
| const el = document.getElementById('body-' + vid); |
| if (el) el.scrollIntoView({ behavior: 'smooth', block: 'start' }); |
| }, 100); |
| } |
| |
| function handleSearch(q) { |
| q = q.toLowerCase(); |
| if (!q) { if (currentTab === 'architecture') renderVolumes(); if (currentTab === 'figures') renderFigures(); return; } |
| if (currentTab === 'architecture') { |
| const filtered = volumes.map(v => ({...v, children: v.children.filter(c => c.title.toLowerCase().includes(q) || c.desc.toLowerCase().includes(q) || c.tables.some(t => t.toLowerCase().includes(q)))})).filter(v => v.children.length > 0 || v.title.toLowerCase().includes(q)); |
| document.getElementById('tab-architecture').innerHTML = filtered.map((v, i) => { |
| const idx = volumes.findIndex(x => x.id === v.id); |
| return `<div class="volume-section vol-${v.color} glass"> |
| <button class="volume-header expanded" onclick="toggleVolume('${v.id}')"> |
| <span class="chevron" style="transform:rotate(90deg)">${svgs.chevronRight}</span> |
| <span style="color:var(--accent-${v.color})">${svgs[v.icon]}</span> |
| <span>Volume ${roman[idx]} — ${v.title}</span> |
| <span class="vol-badge">${v.children.length} matches</span> |
| </button> |
| <div class="volume-body open"> |
| ${v.children.map(c => `<div class="figure-item"><h4>${c.title}</h4><p class="fig-desc">${c.desc}</p><div class="fig-tags">${c.tables.map(t => `<span class="fig-tag">${t}</span>`).join('')}</div></div>`).join('')} |
| </div> |
| </div>`; |
| }).join('') || '<div style="text-align:center;padding:40px;color:var(--text-muted)">No results found</div>'; |
| } |
| if (currentTab === 'figures') { |
| const all = volumes.flatMap(v => v.children.map(c => ({...c, volColor: v.color, volTitle: v.title}))); |
| const filtered = all.filter(f => f.title.toLowerCase().includes(q) || f.desc.toLowerCase().includes(q) || f.tables.some(t => t.toLowerCase().includes(q))); |
| document.getElementById('tab-figures').innerHTML = filtered.length ? `<div class="figures-grid">${filtered.map(f => ` |
| <div class="figure-card vol-${f.volColor}"> |
| <div class="fig-header"><span class="fig-id">${f.id.toUpperCase()}</span><span class="fig-vol">${f.volTitle}</span></div> |
| <h3>${f.title.replace(/^FIG\. \d+ — /, '')}</h3> |
| <p class="fig-desc-short">${f.desc}</p> |
| <div class="fig-tags">${f.tables.slice(0,3).map(t => `<span class="fig-tag">${t}</span>`).join('')}${f.tables.length > 3 ? '<span class="fig-tag">+' + (f.tables.length - 3) + '</span>' : ''}</div> |
| </div> |
| `).join('')}</div>` : '<div style="text-align:center;padding:40px;color:var(--text-muted)">No figures found</div>'; |
| } |
| } |
| |
| function startSimulation() { |
| const btn = document.getElementById('btnSim'); |
| const progress = document.getElementById('simProgress'); |
| const bar = document.getElementById('simBar'); |
| const pct = document.getElementById('simPercent'); |
| btn.disabled = true; |
| progress.classList.add('active'); |
| let p = 0; |
| simInterval = setInterval(() => { |
| p += 1.5; |
| if (p >= 100) { p = 100; clearInterval(simInterval); setTimeout(() => { btn.disabled = false; progress.classList.remove('active'); }, 800); } |
| bar.style.width = p + '%'; |
| pct.textContent = Math.round(p) + '%'; |
| }, 80); |
| } |
| |
| function resetSimulation() { |
| clearInterval(simInterval); |
| document.getElementById('simBar').style.width = '0%'; |
| document.getElementById('simPercent').textContent = '0%'; |
| document.getElementById('simProgress').classList.remove('active'); |
| document.getElementById('btnSim').disabled = false; |
| } |
| |
| |
| renderOverviewVolumes(); |
| renderVolumes(); |
| renderFigures(); |
| renderTables(); |
| renderMatrix(); |
| </script> |
| </body> |
| </html> |