-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathsamd_decision_tree.html
More file actions
684 lines (653 loc) · 45.6 KB
/
samd_decision_tree.html
File metadata and controls
684 lines (653 loc) · 45.6 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>SaMD Regulatory Pathway Navigator - TechInHSR</title>
<script src="https://unpkg.com/react@18/umd/react.production.min.js"></script>
<script src="https://unpkg.com/react-dom@18/umd/react-dom.production.min.js"></script>
<script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
<script src="https://cdn.tailwindcss.com"></script>
<style>
@import url('https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700;900&display=swap');
body {
font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
}
.fade-in {
animation: fadeIn 0.3s ease-in;
}
@keyframes fadeIn {
from { opacity: 0; transform: translateY(10px); }
to { opacity: 1; transform: translateY(0); }
}
</style>
</head>
<body class="bg-slate-50">
<div id="root"></div>
<script type="text/babel">
const { useState } = React;
// Icon components
const ChevronRight = () => (
<svg className="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M9 5l7 7-7 7" />
</svg>
);
const CheckCircle = () => (
<svg className="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M9 12l2 2 4-4m6 2a9 9 0 11-18 0 9 9 0 0118 0z" />
</svg>
);
const AlertCircle = () => (
<svg className="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M12 8v4m0 4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z" />
</svg>
);
const RefreshCw = () => (
<svg className="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M4 4v5h.582m15.356 2A8.001 8.001 0 004.582 9m0 0H9m11 11v-5h-.581m0 0a8.003 8.003 0 01-15.357-2m15.357 2H15" />
</svg>
);
const InfoIcon = () => (
<svg className="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z" />
</svg>
);
const SaMDDecisionTree = () => {
const [currentStep, setCurrentStep] = useState('start');
const [history, setHistory] = useState([]);
const [answers, setAnswers] = useState({});
const decisionTree = {
start: {
question: "Let's determine if your software qualifies as a medical device",
info: "Software as a Medical Device (SaMD) means standalone software designed for medical purposes—it operates independently without being built into a hardware device.",
options: [
{ label: "Yes, it's standalone software for medical purposes", next: "medical_purpose", value: "yes" },
{ label: "No, it's not standalone or not for medical use", next: "not_samd", value: "no" },
{ label: "I'd like help figuring this out", next: "samd_check", value: "unsure" }
]
},
samd_check: {
question: "Which of these describes what your software does?",
info: "Medical purposes typically include functions like diagnosing, treating, or preventing disease; analyzing patient data to inform clinical decisions; or helping triage patients.",
options: [
{ label: "It performs at least one of these medical functions", next: "medical_purpose", value: "yes" },
{ label: "It doesn't perform these types of functions", next: "not_samd", value: "no" }
]
},
medical_purpose: {
question: "Before we continue, let's check: Could this be a 'general wellness' product?",
info: "Many people try to classify disease-specific education tools as 'general wellness' to avoid device regulations. Let's see if that applies here.",
options: [
{ label: "It might be general wellness - let me check", next: "general_wellness_check", value: "check" },
{ label: "No, it's clearly disease-specific medical software", next: "intended_use", value: "medical" }
]
},
general_wellness_check: {
question: "Does your software do any of the following?",
info: "Per FDA's 2026 General Wellness Guidance, products are NOT general wellness if they have any of these characteristics:",
type: "checklist",
disqualifiers: [
"Uses individual patient's clinical data to generate personalized recommendations",
"Provides risk scores or risk probability for a specific disease (like diabetes or heart disease)",
"Identifies individual risk factors based on clinical assessment",
"Prompts or guides specific clinical actions or medical management",
"Could be used for screening, monitoring, or managing a disease",
"References specific diseases with clinical thresholds or diagnostic criteria"
],
options: [
{ label: "Yes, it does one or more of these", next: "not_general_wellness", value: "disqualified" },
{ label: "No, none of these apply", next: "general_wellness_qualified", value: "qualified" }
]
},
not_general_wellness: {
question: "Your software does not qualify as general wellness",
info: "Based on FDA's 2026 General Wellness Guidance, your software is a medical device, not a general wellness product.",
details: [
{
title: "Why It Matters",
content: "The FDA's general wellness policy only applies to low-risk products for maintaining general health or promoting healthy lifestyles. Products that use clinical data for disease-specific risk assessment or management are regulated as medical devices."
},
{
title: "Key Distinction",
content: "General wellness = 'Exercise 30 minutes daily for heart health' (population-level advice). Medical device = 'Based on your blood pressure, glucose, and family history, here are personalized recommendations to reduce your cardiovascular risk' (individual clinical assessment)."
}
],
options: [
{ label: "Understood, continue with device classification", next: "intended_use", value: "continue" }
]
},
general_wellness_qualified: {
conclusion: true,
result: {
type: "general_wellness",
title: "Your Product May Qualify as General Wellness",
details: [
"If your software truly provides only general health education without disease-specific risk assessment, it may qualify for FDA's general wellness enforcement discretion",
"General wellness products must be low-risk and intended only for maintaining general health",
"Important: Even general wellness products must comply with other regulations like FTC advertising rules and HIPAA if handling health data",
"We recommend reviewing FDA's 2026 General Wellness Guidance to confirm your classification"
]
},
options: [
{ label: "Start over with a different scenario", next: "start", value: "restart" }
]
},
intended_use: {
question: "Who will use the software and how?",
info: "This question is about the software's intended use once it's complete—not about your study design. We're asking about the end product.",
options: [
{ label: "Patients will use it to get personalized medical advice or education", next: "patient_facing_device", value: "patient" },
{ label: "Healthcare professionals will use it to help make clinical decisions", next: "hcp_cds_check", value: "hcp" },
{ label: "It's for administrative or non-clinical purposes", next: "not_device", value: "admin" }
]
},
patient_facing_device: {
question: "Your software provides medical information directly to patients",
info: "The FDA's 2022 Clinical Decision Support guidance (updated in 2026) clarifies that patient-facing software providing medical recommendations is regulated as a medical device.",
conclusion: true,
result: {
type: "device",
title: "Your Software is Classified as a Medical Device",
details: [
"Patient-facing software that provides medical recommendations falls under device regulations",
"This classification is based on the FDA CDS Guidance, which treats patient-facing clinical software differently from healthcare professional tools",
"Next, we'll help you determine the regulatory pathway for your specific study"
]
},
options: [
{ label: "Continue to determine study requirements", next: "study_procedures", value: "continue" }
]
},
hcp_cds_check: {
question: "Does your software meet all four of these criteria?",
info: "The 21st Century Cures Act provides an exclusion for certain Clinical Decision Support software. All four criteria must be met:",
criteria: [
"Doesn't acquire, process, or analyze medical images or signals from diagnostic devices",
"Displays or analyzes medical information like patient data, clinical guidelines, or research studies",
"Supports healthcare professionals (they make the final decisions, not the software)",
"Allows healthcare professionals to independently review how the software reached its recommendations"
],
options: [
{ label: "Yes, meets all four criteria", next: "not_device", value: "all" },
{ label: "No, doesn't meet all four", next: "is_device", value: "not_all" }
]
},
is_device: {
question: "Does your device qualify for any regulatory exemptions?",
info: "Certain devices may be exempt from requiring an Investigational Device Exemption (IDE) application under 21 CFR 812.2(c).",
options: [
{ label: "Yes, it qualifies for an exemption (pre-1976 device, 510(k)-cleared, or meets diagnostic exemption criteria)", next: "exempt_device", value: "exempt" },
{ label: "No exemptions apply", next: "study_procedures", value: "none" }
]
},
exempt_device: {
conclusion: true,
result: {
type: "exempt",
title: "Your Device Study May Qualify for IDE Exemption",
details: [
"Your device may be exempt from IDE requirements under 21 CFR 812.2(c)",
"Important note: IRB review is still required under 21 CFR 56, even for exempt devices",
"We recommend confirming exemption status with your IRB during protocol review"
]
},
options: [
{ label: "Start over", next: "start", value: "restart" }
]
},
study_procedures: {
question: "What activities are planned for your current study phase?",
info: "The regulatory requirements depend on what's actually happening in your study—specifically, whether the software's outputs could influence clinical care. Note: 'Participants' typically means the end-users (often clinicians) and/or patients whose care could be affected.",
options: [
{ label: "Algorithm development and training using synthetic or de-identified data (no clinical care involvement)", next: "clinical_evaluation_concept", value: "dev" },
{ label: "Testing where outputs are visible to clinicians or patients and could influence care decisions", next: "risk_mitigation_check", value: "visible" },
{ label: "Observational study where outputs are generated but not shared with anyone (used only for validation)", next: "clinical_evaluation_concept", value: "observational" }
]
},
risk_mitigation_check: {
question: "Does your study include risk mitigation protocols?",
info: "Even when outputs are visible, proper safeguards can reduce the risk level. The IRB will evaluate whether these protections are adequate.",
options: [
{ label: "Yes - outputs must be confirmed by standard clinical procedures before any action is taken", next: "nsr_with_mitigation", value: "mitigation" },
{ label: "Yes - outputs are advisory only, with clear disclaimers and independent clinical oversight", next: "nsr_with_mitigation", value: "advisory" },
{ label: "No - outputs could directly influence clinical decisions without independent confirmation", next: "significant_risk", value: "no_mitigation" },
{ label: "Unsure - need guidance on what constitutes adequate risk mitigation", next: "risk_mitigation_guidance", value: "unsure" }
]
},
risk_mitigation_guidance: {
question: "Understanding Risk Mitigation for Device Studies",
info: "Risk mitigation strategies can help classify a study as NSR even when outputs are visible to clinicians or patients:",
details: [
{
title: "Adequate Risk Mitigation May Include",
content: "Requiring all outputs to be confirmed by standard clinical procedures; treating outputs as advisory only with clear labeling; having independent clinical oversight review all outputs before they reach patients; ensuring the investigational device does not replace or override standard of care; implementing monitoring plans to detect any safety issues."
},
{
title: "What the IRB Will Evaluate",
content: "Whether the study design prevents the investigational device from directly influencing patient care; whether adequate safeguards exist to protect participants from potential harm; whether monitoring plans are sufficient to detect safety concerns; whether the risk mitigation strategies are documented in the protocol."
},
{
title: "Key Principle",
content: "The determination of SR vs. NSR depends on the specific study procedures and safeguards, not just the device's intended use. Work with your IRB to determine if your mitigation strategies are adequate."
}
],
options: [
{ label: "My study has adequate risk mitigation protocols", next: "nsr_with_mitigation", value: "yes" },
{ label: "My study does not have adequate risk mitigation", next: "significant_risk", value: "no" }
]
},
nsr_with_mitigation: {
question: "Your study may qualify as NSR with proper risk mitigation",
info: "Based on your responses, your study includes safeguards that may reduce the risk to NSR level. However, the final determination must be made by your IRB after reviewing your complete protocol.",
details: [
{
title: "Important Note",
content: "This is a preliminary assessment. Your IRB must review your specific study procedures, risk mitigation protocols, and monitoring plans to make the final SR/NSR determination."
},
{
title: "What to Include in Your IRB Submission",
content: "Detailed description of risk mitigation protocols; how outputs will be confirmed before any clinical action; monitoring and oversight procedures; clear documentation that the device will not replace standard of care; adverse event reporting plans."
}
],
options: [
{ label: "Continue to NSR determination", next: "irb_required_dev", value: "continue" }
]
},
clinical_evaluation_concept: {
question: "A note about an important regulatory distinction",
info: "There's a common misconception in the field that algorithm development doesn't require IRB review because 'there are no human subjects.' For medical device software, this isn't quite accurate. Here's why:",
details: [
{
title: "Clinical Investigation",
content: "This refers specifically to testing in human subjects to determine safety and effectiveness."
},
{
title: "Clinical Evaluation (IMDRF/FDA framework)",
content: "This is broader—it covers 'ongoing activities' throughout the product lifecycle, including establishing scientific validity (valid clinical association), technical testing (analytical validation), and demonstrating real-world performance (clinical validation)."
},
{
title: "What This Means for Your Work",
content: "Even during algorithm development and training, you're conducting clinical evaluation activities. For medical devices, IRB review applies to clinical evaluation work, not just clinical investigation phases. This is outlined in the FDA-adopted IMDRF SaMD Clinical Evaluation guidance."
}
],
options: [
{ label: "Got it, let's continue", next: "irb_required_dev", value: "proceed" }
]
},
irb_required_dev: {
question: "In your study, could the software's outputs be seen by clinicians or patients, or influence clinical decisions (directly or indirectly)?",
info: "This is the study-specific risk determination under 21 CFR 812.3(m). The key question is whether the investigational device could influence clinical care in your study, not just whether it could theoretically cause harm.",
options: [
{ label: "No - outputs are not visible to anyone providing or receiving care (development/validation only)", next: "nsr_determination", value: "no" },
{ label: "Yes, but with adequate risk mitigation protocols in place", next: "irb_final_determination", value: "yes_mitigated" },
{ label: "Yes, outputs could influence care without independent confirmation", next: "significant_risk", value: "yes_unmitigated" }
]
},
irb_final_determination: {
question: "Note: Your IRB will make the final determination",
info: "Studies where outputs are visible but have risk mitigation protocols may be classified as either NSR or SR depending on the specific safeguards and the IRB's assessment.",
details: [
{
title: "Factors the IRB Will Consider",
content: "Adequacy of risk mitigation protocols; whether outputs must be confirmed by standard procedures; monitoring and oversight plans; potential consequences if outputs are incorrect; whether the device could influence treatment decisions; adequacy of informed consent and patient protections."
},
{
title: "Possible Outcomes",
content: "NSR if safeguards are adequate: The IRB may determine your study is NSR if the risk mitigation protocols effectively prevent the device from directly influencing patient care. SR if safeguards are insufficient: The IRB may determine your study is SR if there's potential for the device to influence care in ways that could cause serious harm, even with mitigation protocols."
},
{
title: "What You Should Do",
content: "Submit a comprehensive protocol detailing all risk mitigation strategies; be prepared to discuss and potentially enhance your safeguards; work collaboratively with your IRB to determine the appropriate classification."
}
],
options: [
{ label: "I understand - my IRB will make the final determination", next: "nsr_determination", value: "understand" }
]
},
nsr_determination: {
conclusion: true,
result: {
type: "nsr",
title: "Your Study May Qualify as Nonsignificant Risk (NSR)",
requirements: [
"Device classification: Medical device (based on intended use)",
"Study risk level: NSR (determined by your specific study procedures and safeguards)",
"IRB review: Required under 21 CFR 56 for clinical evaluation activities",
"IDE pathway: Abbreviated IDE requirements per 21 CFR 812.2(b)",
"FDA submission: Not required (NSR studies are automatically granted IDE status when abbreviated requirements are met)"
],
next_steps: [
"Submit your protocol to the IRB with a detailed risk determination worksheet explaining why the study is NSR",
"If outputs are visible to participants, clearly document all risk mitigation protocols and safeguards",
"Meet the abbreviated IDE requirements: proper labeling, monitoring plan, and recordkeeping per 21 CFR 812.2(b)",
"Be prepared to discuss your risk mitigation strategies with the IRB—they may request additional safeguards",
"Plan ahead for when you move to later phases—those will likely require re-evaluation",
"Consider requesting a pre-submission meeting with the FDA Digital Health Center of Excellence to discuss your development pathway"
],
considerations: [
"IMPORTANT: This is a preliminary assessment. Your IRB makes the final SR/NSR determination based on your complete protocol and specific safeguards",
"If your study includes visible outputs with risk mitigation, the IRB will carefully evaluate whether those safeguards are adequate",
"When you move to patient deployment phases without adequate safeguards, the study will likely be reclassified as Significant Risk",
"Even though full Quality System Regulations (21 CFR 820) aren't required yet, many developers find it helpful to start implementing compatible practices early",
"Keep detailed documentation of your development, validation, and risk mitigation work—it will support your eventual regulatory submission"
]
},
options: [
{ label: "Start over with a different scenario", next: "start", value: "restart" }
]
},
significant_risk: {
conclusion: true,
result: {
type: "sr",
title: "Your Study is Classified as Significant Risk (SR)",
requirements: [
"Device classification: Medical device (based on intended use)",
"Study risk level: SR (participants exposed to device outputs)",
"IRB review: Required under 21 CFR 56",
"IDE pathway: Full IDE application per 21 CFR 812",
"FDA submission: Required before study initiation—both IRB and FDA must approve"
],
next_steps: [
"Prepare a comprehensive IDE application for FDA submission",
"Submit to your IRB—note that you cannot begin the study until you have both IRB and FDA approval",
"Develop detailed monitoring and safety protocols appropriate for the risk level",
"Establish clear procedures for adverse event identification and reporting",
"Implement Quality System Regulations (21 CFR 820) as these apply to SR device studies"
],
considerations: [
"SR classification indicates potential for serious harm, which is why FDA approval is required",
"The IDE application process typically takes several months—plan your timeline accordingly",
"FDA offers pre-submission meetings to discuss your IDE application strategy—these are often very helpful",
"You may want to consult with regulatory affairs specialists experienced in digital health IDEs"
]
},
options: [
{ label: "Start over with a different scenario", next: "start", value: "restart" }
]
},
not_device: {
conclusion: true,
result: {
type: "not_device",
title: "Your Software is Not Classified as a Medical Device",
details: [
"Based on your responses, your software doesn't meet the regulatory definition of a medical device",
"FDA device regulations (21 CFR 812) don't apply to your project",
"However, if your research involves human subjects, the Common Rule (45 CFR 46) may still apply",
"We recommend checking with your IRB about human subjects research requirements for your specific project"
]
},
options: [
{ label: "Start over", next: "start", value: "restart" }
]
},
not_samd: {
conclusion: true,
result: {
type: "not_samd",
title: "Your Software Doesn't Qualify as SaMD",
details: [
"Your software doesn't meet the criteria for Software as a Medical Device",
"This decision tool focuses specifically on SaMD regulatory requirements",
"Your software may be regulated under different frameworks depending on its purpose",
"For guidance on your specific situation, consider consulting with a regulatory affairs specialist"
]
},
options: [
{ label: "Start over", next: "start", value: "restart" }
]
}
};
const handleAnswer = (option) => {
setHistory([...history, { step: currentStep, answer: option }]);
setAnswers({ ...answers, [currentStep]: option });
setCurrentStep(option.next);
};
const handleReset = () => {
setCurrentStep('start');
setHistory([]);
setAnswers({});
};
const handleBack = () => {
if (history.length > 0) {
const newHistory = [...history];
const lastStep = newHistory.pop();
setHistory(newHistory);
setCurrentStep(lastStep.step);
const newAnswers = { ...answers };
delete newAnswers[lastStep.step];
setAnswers(newAnswers);
}
};
const currentNode = decisionTree[currentStep];
return (
<div className="min-h-screen bg-gradient-to-br from-slate-50 via-blue-50 to-indigo-50">
{/* Header */}
<div className="bg-white border-b border-slate-200 shadow-sm">
<div className="max-w-4xl mx-auto px-6 py-8">
<div className="flex items-start justify-between">
<div>
<h1 className="text-3xl font-bold text-slate-900 mb-2">
SaMD Regulatory Pathway Navigator
</h1>
<p className="text-slate-600 text-lg">
A guide to help you navigate medical device software regulations
</p>
</div>
<button
onClick={handleReset}
className="flex items-center gap-2 px-4 py-2 text-sm font-medium text-slate-600 hover:text-slate-900 hover:bg-slate-100 rounded-lg transition-colors"
>
<RefreshCw />
Start Over
</button>
</div>
</div>
</div>
{/* Progress */}
{history.length > 0 && (
<div className="max-w-4xl mx-auto px-6 py-4">
<div className="flex items-center gap-2 text-sm text-slate-500">
<span>Step {history.length + 1}</span>
<span>•</span>
<button
onClick={handleBack}
className="text-indigo-600 hover:text-indigo-700 font-medium"
>
← Go back
</button>
</div>
</div>
)}
{/* Main Content */}
<div className="max-w-4xl mx-auto px-6 py-8">
<div className="bg-white rounded-2xl shadow-lg border border-slate-200 overflow-hidden fade-in">
{/* Question */}
<div className="p-8 border-b border-slate-100">
<h2 className="text-2xl font-bold text-slate-900 mb-4">
{currentNode.question}
</h2>
{currentNode.info && (
<div className="bg-blue-50 border border-blue-200 rounded-lg p-4 mb-6">
<div className="flex gap-3">
<div className="flex-shrink-0 mt-0.5 text-blue-600">
<InfoIcon />
</div>
<p className="text-blue-900 text-sm leading-relaxed">
{currentNode.info}
</p>
</div>
</div>
)}
{currentNode.details && (
<div className="space-y-4 mb-6">
{currentNode.details.map((detail, idx) => (
<div key={idx} className="bg-slate-50 rounded-lg p-4 border border-slate-200">
<h3 className="font-semibold text-slate-900 mb-2">{detail.title}</h3>
<p className="text-slate-700 text-sm leading-relaxed">{detail.content}</p>
</div>
))}
</div>
)}
{currentNode.criteria && (
<div className="bg-slate-50 rounded-lg p-4 mb-6 border border-slate-200">
<ul className="space-y-2">
{currentNode.criteria.map((criterion, idx) => (
<li key={idx} className="flex gap-2 text-sm text-slate-700">
<div className="flex-shrink-0 mt-0.5 text-green-600">
<CheckCircle />
</div>
<span>{criterion}</span>
</li>
))}
</ul>
</div>
)}
{currentNode.disqualifiers && (
<div className="bg-amber-50 rounded-lg p-4 mb-6 border border-amber-200">
<ul className="space-y-2">
{currentNode.disqualifiers.map((item, idx) => (
<li key={idx} className="flex gap-2 text-sm text-amber-900">
<div className="flex-shrink-0 mt-0.5 text-amber-600">
<AlertCircle />
</div>
<span>{item}</span>
</li>
))}
</ul>
</div>
)}
</div>
{/* Options/Results */}
{currentNode.conclusion ? (
<div className="p-8">
<div className={`rounded-xl p-6 mb-6 border ${
currentNode.result.type === 'nsr' ? 'bg-green-50 border-green-200' :
currentNode.result.type === 'sr' ? 'bg-blue-50 border-blue-200' :
currentNode.result.type === 'device' ? 'bg-blue-50 border-blue-200' :
currentNode.result.type === 'general_wellness' ? 'bg-green-50 border-green-200' :
'bg-slate-50 border-slate-200'
}`}>
<h3 className="text-xl font-bold mb-4 text-slate-900">
{currentNode.result.title}
</h3>
{currentNode.result.details && (
<ul className="space-y-2 mb-4">
{currentNode.result.details.map((detail, idx) => (
<li key={idx} className="flex gap-2 text-sm text-slate-700">
<div className="flex-shrink-0 mt-0.5">
<ChevronRight />
</div>
<span>{detail}</span>
</li>
))}
</ul>
)}
{currentNode.result.requirements && (
<div className="mb-4">
<h4 className="font-semibold mb-2 text-slate-900">Regulatory Requirements:</h4>
<ul className="space-y-2">
{currentNode.result.requirements.map((req, idx) => (
<li key={idx} className="flex gap-2 text-sm text-slate-700">
<div className="flex-shrink-0 mt-0.5 text-green-600">
<CheckCircle />
</div>
<span>{req}</span>
</li>
))}
</ul>
</div>
)}
{currentNode.result.next_steps && (
<div className="mb-4">
<h4 className="font-semibold mb-2 text-slate-900">Recommended Next Steps:</h4>
<ul className="space-y-2">
{currentNode.result.next_steps.map((step, idx) => (
<li key={idx} className="flex gap-2 text-sm text-slate-700">
<div className="flex-shrink-0 mt-1">
<span className="inline-flex items-center justify-center w-5 h-5 rounded-full bg-indigo-100 text-indigo-700 text-xs font-medium">
{idx + 1}
</span>
</div>
<span>{step}</span>
</li>
))}
</ul>
</div>
)}
{currentNode.result.considerations && (
<div className="bg-slate-100 border border-slate-300 rounded-lg p-4 mt-4">
<h4 className="font-semibold mb-2 text-slate-900 flex items-center gap-2">
<div className="flex-shrink-0 text-slate-600">
<InfoIcon />
</div>
Additional Considerations:
</h4>
<ul className="space-y-1 text-sm text-slate-700">
{currentNode.result.considerations.map((item, idx) => (
<li key={idx} className="flex gap-2">
<span className="flex-shrink-0">•</span>
<span>{item}</span>
</li>
))}
</ul>
</div>
)}
</div>
<div className="flex gap-3">
{currentNode.options.map((option, idx) => (
<button
key={idx}
onClick={() => handleAnswer(option)}
className="flex-1 px-6 py-3 bg-indigo-600 text-white font-medium rounded-lg hover:bg-indigo-700 transition-colors shadow-sm"
>
{option.label}
</button>
))}
</div>
</div>
) : (
<div className="p-8">
<div className="space-y-3">
{currentNode.options.map((option, idx) => (
<button
key={idx}
onClick={() => handleAnswer(option)}
className="w-full text-left p-4 border-2 border-slate-200 rounded-lg hover:border-indigo-400 hover:bg-indigo-50 transition-all group"
>
<div className="flex items-center justify-between">
<span className="font-medium text-slate-900 group-hover:text-indigo-900">
{option.label}
</span>
<div className="text-slate-400 group-hover:text-indigo-600">
<ChevronRight />
</div>
</div>
</button>
))}
</div>
</div>
)}
</div>
{/* Footer */}
<div className="mt-8 text-center text-sm text-slate-500 space-y-1">
<p>
Based on 21 CFR 56, 812 and FDA/IMDRF SaMD Clinical Evaluation Guidance
</p>
<p>
Created by Tamiko Eto, MA, CIP | TechInHSR LLC
</p>
<p>
<a href="https://techinshsr.com" className="text-indigo-600 hover:underline">techinshsr.com</a>
</p>
</div>
</div>
</div>
);
};
// Render the app
ReactDOM.render(<SaMDDecisionTree />, document.getElementById('root'));
</script>
</body>
</html>