File size: 4,205 Bytes
5f43c7d
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
import React from "react";
import { ShieldCheck, Lock, Sparkles, Trash2, X } from "lucide-react";
import { C, FD, FB, FM } from "../theme.js";

// Privacy disclosure for the hosted Space. Shown once on first run (localStorage) and
// re-openable any time via the "Privacy" button. The Space keeps NOTHING: uploads are
// isolated per-browser and deleted on exit / Clear / within 24h, and nothing derived
// from them ever leaves (enricher + sharing are off — HER_ENRICH=0 / HER_SHARE=0). The
// only outbound call is the one-time model download from Hugging Face.

const SEEN_KEY = "her.disclaimer.v1";

export function needsDisclaimer() {
  try { return localStorage.getItem(SEEN_KEY) !== "1"; } catch { return true; }
}

export default function DisclaimerModal({ onDone }) {
  function close() {
    try { localStorage.setItem(SEEN_KEY, "1"); } catch { /* ignore */ }
    onDone();
  }

  return (
    <div onClick={close} style={{ position: "fixed", inset: 0, background: "rgba(15,14,13,.82)", zIndex: 100, display: "flex", alignItems: "center", justifyContent: "center", padding: 20, fontFamily: FB }}>
      <div className="pop" onClick={(e) => e.stopPropagation()} style={{ width: "min(540px,94vw)", background: C.panel, border: `1px solid ${C.border}`, borderRadius: 14, boxShadow: "0 24px 70px rgba(0,0,0,.55)", overflow: "hidden" }}>
        {/* header */}
        <div style={{ padding: "20px 22px 14px", borderBottom: `1px solid ${C.borderSoft}`, display: "flex", alignItems: "center", gap: 11 }}>
          <div style={{ width: 36, height: 36, borderRadius: 9, background: C.orange, display: "flex", alignItems: "center", justifyContent: "center", flexShrink: 0 }}>
            <Lock size={18} color="#fff" />
          </div>
          <div style={{ flex: 1 }}>
            <div style={{ fontFamily: FD, fontWeight: 700, fontSize: 18, color: C.text }}>Your sessions are private</div>
            <div style={{ fontFamily: FM, fontSize: 11, color: C.muted, marginTop: 2 }}>हेर · what you upload stays yours</div>
          </div>
          <X size={18} color={C.muted} style={{ cursor: "pointer" }} onClick={close} />
        </div>

        {/* body */}
        <div style={{ padding: "16px 22px 8px", display: "flex", flexDirection: "column", gap: 13 }}>
          <Row icon={Trash2} c={C.cyan} title="We never store your sessions"
            body="Files you upload are isolated to your browser and deleted when you leave, when you click “clear my data”, or within 24 hours — whichever comes first." />
          <Row icon={ShieldCheck} c={C.orange} title="Nothing leaves this Space"
            body="No code, commands, file paths, secrets — or even tool names — are ever sent anywhere. We don’t train on your sessions and we don’t share them." />
          <Row icon={Sparkles} c={C.amber} title="Analyzed here, then gone"
            body="The forensics run on the Space and the plain-English write-up is generated by a model running here. The only thing ever downloaded is that model itself, once." />
        </div>

        {/* footer */}
        <div style={{ padding: "12px 22px 18px", display: "flex", alignItems: "center", gap: 12, marginTop: 6 }}>
          <span style={{ fontFamily: FM, fontSize: 10, color: C.muted, flex: 1, lineHeight: 1.45, display: "flex", alignItems: "center", gap: 6 }}>
            <ShieldCheck size={12} color={C.cyan} /> Findings are computed here; your uploads are never retained.
          </span>
          <div onClick={close} className="lift"
            style={{ cursor: "pointer", background: C.orange, color: "#fff", fontFamily: FD, fontWeight: 700, fontSize: 14, borderRadius: 9, padding: "10px 22px" }}>
            Got it
          </div>
        </div>
      </div>
    </div>
  );
}

function Row({ icon: Icon, c, title, body }) {
  return (
    <div style={{ display: "flex", gap: 11, alignItems: "flex-start" }}>
      <Icon size={16} color={c} style={{ flexShrink: 0, marginTop: 2 }} />
      <div>
        <div style={{ fontSize: 13, fontWeight: 600, color: C.text }}>{title}</div>
        <div style={{ fontSize: 12, color: C.text2, lineHeight: 1.5, marginTop: 1 }}>{body}</div>
      </div>
    </div>
  );
}