diff --git a/index.html b/index.html
index 06cff1c..5686b46 100644
--- a/index.html
+++ b/index.html
@@ -423,6 +423,35 @@ html, body {
fill: currentColor;
}
+/* Chat safety plan button — always visible, subtle */
+#chat-safety-plan-btn {
+ flex-shrink: 0;
+ width: 44px;
+ height: 44px;
+ background: transparent;
+ color: #8b949e;
+ border: 1px solid #30363d;
+ border-radius: 12px;
+ cursor: pointer;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ transition: background 0.2s, color 0.2s, border-color 0.2s;
+ -webkit-appearance: none;
+}
+#chat-safety-plan-btn:hover,
+#chat-safety-plan-btn:focus {
+ background: #161b22;
+ color: #58a6ff;
+ border-color: #58a6ff;
+ outline: 2px solid #58a6ff;
+ outline-offset: 2px;
+}
+#chat-safety-plan-btn svg {
+ width: 20px;
+ height: 20px;
+}
+
/* ===== MODALS ===== */
.modal-overlay {
position: fixed;
@@ -675,6 +704,9 @@ html, body {
+
@@ -813,6 +845,7 @@ Sovereignty and service always.`;
// Safety Plan Elements
var safetyPlanBtn = document.getElementById('safety-plan-btn');
+ var chatSafetyPlanBtn = document.getElementById('chat-safety-plan-btn');
var crisisSafetyPlanBtn = document.getElementById('crisis-safety-plan-btn');
var safetyPlanModal = document.getElementById('safety-plan-modal');
var closeSafetyPlan = document.getElementById('close-safety-plan');
@@ -1290,6 +1323,15 @@ Sovereignty and service always.`;
_activateSafetyPlanFocusTrap(safetyPlanBtn);
});
+ // Chat input area safety plan button — always visible (#38)
+ if (chatSafetyPlanBtn) {
+ chatSafetyPlanBtn.addEventListener('click', function() {
+ loadSafetyPlan();
+ safetyPlanModal.classList.add('active');
+ _activateSafetyPlanFocusTrap(chatSafetyPlanBtn);
+ });
+ }
+
// Crisis panel safety plan button (if crisis panel is visible)
if (crisisSafetyPlanBtn) {
crisisSafetyPlanBtn.addEventListener('click', function() {
diff --git a/tests/test_safety_plan_in_chat.py b/tests/test_safety_plan_in_chat.py
new file mode 100644
index 0000000..63211dd
--- /dev/null
+++ b/tests/test_safety_plan_in_chat.py
@@ -0,0 +1,102 @@
+"""
+Tests for #38 — Safety plan accessible from chat (not just overlay).
+
+Verifies:
+1. Safety plan button exists in the input area
+2. Button has proper ARIA attributes
+3. Button is keyboard focusable
+4. Button does not require crisis detection to be visible
+"""
+
+import re
+import unittest
+from pathlib import Path
+
+
+INDEX_HTML = Path(__file__).parent.parent / "index.html"
+
+
+class TestSafetyPlanInChat(unittest.TestCase):
+ @classmethod
+ def setUpClass(cls):
+ cls.html = INDEX_HTML.read_text()
+
+ def test_chat_safety_plan_button_exists(self):
+ """Button #chat-safety-plan-btn exists in the DOM."""
+ self.assertIn('id="chat-safety-plan-btn"', self.html)
+
+ def test_button_has_aria_label(self):
+ """Button has aria-label for screen readers."""
+ match = re.search(
+ r'