broadfield-dev commited on
Commit
2c143bb
·
verified ·
1 Parent(s): 9737a84

Update templates/client.html

Browse files
Files changed (1) hide show
  1. templates/client.html +324 -36
templates/client.html CHANGED
@@ -2,55 +2,343 @@
2
  <html lang="en">
3
  <head>
4
  <meta charset="UTF-8">
 
5
  <title>EE Secure Client</title>
6
- <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet">
7
  <style>
8
- body { background: #f8f9fa; padding: 40px; }
9
- .result { background: white; border: 1px solid #ddd; padding: 25px; border-radius: 10px; min-height: 220px; }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
10
  </style>
11
  </head>
12
  <body>
13
- <div class="container">
14
- <h1 class="mb-4">🔒 Equivariant Encryption Client</h1>
15
- <p class="lead">Your prompt is encrypted locally before leaving this browser.</p>
16
-
17
- <form method="POST">
18
- <div class="mb-3">
19
- <label class="form-label">Server Space URL</label>
20
- <input type="url" class="form-control" name="server_url"
21
- placeholder="https://your-ee-processor.hf.space" required>
 
 
 
 
 
 
 
 
 
 
 
 
 
22
  </div>
23
- <div class="mb-3">
24
- <label class="form-label">EE Model Name</label>
25
- <input type="text" class="form-control" name="ee_model_name"
26
- placeholder="yourusername/qwen3-0.6b-dp-ee" required>
 
 
 
27
  </div>
28
- <div class="mb-3">
29
- <label class="form-label">Your Secret EE Seed</label>
30
- <input type="number" class="form-control" name="ee_seed" value="424242" required>
31
- <small class="text-muted">Same seed you used when transforming the model</small>
 
 
 
 
 
 
 
32
  </div>
33
- <div class="mb-3">
34
- <label class="form-label">Your Prompt</label>
35
- <textarea class="form-control" name="prompt" rows="5" required></textarea>
 
 
 
 
 
 
36
  </div>
37
- <div class="mb-3">
38
- <label class="form-label">Max New Tokens</label>
39
- <input type="number" class="form-control" name="max_tokens" value="512">
 
 
 
40
  </div>
41
- <button type="submit" class="btn btn-primary btn-lg">Encrypt & Send to Blind Server</button>
42
- </form>
 
 
 
43
 
44
- {% if result %}
45
- <h4 class="mt-5">Response from server (decrypted on your side):</h4>
46
- <div class="result">{{ result }}</div>
47
- {% endif %}
48
 
49
- {% if error %}
50
- <div class="alert alert-danger mt-5">{{ error }}</div>
51
- {% endif %}
52
  </div>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
53
 
54
- <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.bundle.min.js"></script>
 
 
 
 
 
 
55
  </body>
56
  </html>
 
2
  <html lang="en">
3
  <head>
4
  <meta charset="UTF-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
  <title>EE Secure Client</title>
7
+ <link href="https://fonts.googleapis.com/css2?family=IBM+Plex+Mono:wght@400;500&family=IBM+Plex+Sans:wght@300;400;500;600&display=swap" rel="stylesheet">
8
  <style>
9
+ :root {
10
+ --bg: #0d0f12;
11
+ --surface: #161a20;
12
+ --border: #252b34;
13
+ --border-hover: #3a4452;
14
+ --accent: #00d4aa;
15
+ --accent-dim: rgba(0, 212, 170, 0.12);
16
+ --text: #e2e8f0;
17
+ --text-muted: #64748b;
18
+ --text-dim: #94a3b8;
19
+ --danger: #f87171;
20
+ --danger-dim: rgba(248, 113, 113, 0.1);
21
+ --mono: 'IBM Plex Mono', monospace;
22
+ --sans: 'IBM Plex Sans', sans-serif;
23
+ }
24
+
25
+ * { box-sizing: border-box; margin: 0; padding: 0; }
26
+
27
+ body {
28
+ background: var(--bg);
29
+ color: var(--text);
30
+ font-family: var(--sans);
31
+ min-height: 100vh;
32
+ padding: 48px 24px;
33
+ }
34
+
35
+ .page {
36
+ max-width: 620px;
37
+ margin: 0 auto;
38
+ }
39
+
40
+ /* Header */
41
+ .header {
42
+ margin-bottom: 40px;
43
+ }
44
+ .header-badge {
45
+ display: inline-flex;
46
+ align-items: center;
47
+ gap: 7px;
48
+ background: var(--accent-dim);
49
+ border: 1px solid rgba(0,212,170,0.25);
50
+ color: var(--accent);
51
+ font-family: var(--mono);
52
+ font-size: 11px;
53
+ letter-spacing: 0.08em;
54
+ text-transform: uppercase;
55
+ padding: 5px 12px;
56
+ border-radius: 4px;
57
+ margin-bottom: 16px;
58
+ }
59
+ .lock-dot {
60
+ width: 7px; height: 7px;
61
+ background: var(--accent);
62
+ border-radius: 50%;
63
+ animation: blink 2.5s ease-in-out infinite;
64
+ }
65
+ @keyframes blink { 0%,100%{opacity:1} 50%{opacity:0.3} }
66
+
67
+ h1 {
68
+ font-size: 26px;
69
+ font-weight: 600;
70
+ letter-spacing: -0.02em;
71
+ color: var(--text);
72
+ margin-bottom: 6px;
73
+ }
74
+ .subtitle {
75
+ font-size: 14px;
76
+ color: var(--text-muted);
77
+ line-height: 1.5;
78
+ }
79
+
80
+ /* Card */
81
+ .card {
82
+ background: var(--surface);
83
+ border: 1px solid var(--border);
84
+ border-radius: 10px;
85
+ padding: 28px;
86
+ margin-bottom: 20px;
87
+ }
88
+
89
+ .section-label {
90
+ font-family: var(--mono);
91
+ font-size: 10px;
92
+ letter-spacing: 0.1em;
93
+ text-transform: uppercase;
94
+ color: var(--text-muted);
95
+ margin-bottom: 16px;
96
+ padding-bottom: 10px;
97
+ border-bottom: 1px solid var(--border);
98
+ }
99
+
100
+ /* Form */
101
+ .field { margin-bottom: 20px; }
102
+ .field:last-child { margin-bottom: 0; }
103
+
104
+ label {
105
+ display: block;
106
+ font-size: 13px;
107
+ font-weight: 500;
108
+ color: var(--text-dim);
109
+ margin-bottom: 7px;
110
+ }
111
+ label span {
112
+ font-family: var(--mono);
113
+ font-size: 11px;
114
+ color: var(--text-muted);
115
+ font-weight: 400;
116
+ }
117
+
118
+ input, textarea {
119
+ width: 100%;
120
+ background: var(--bg);
121
+ border: 1px solid var(--border);
122
+ border-radius: 6px;
123
+ padding: 10px 14px;
124
+ color: var(--text);
125
+ font-family: var(--sans);
126
+ font-size: 14px;
127
+ transition: border-color 0.15s;
128
+ outline: none;
129
+ -webkit-appearance: none;
130
+ }
131
+ input:focus, textarea:focus {
132
+ border-color: var(--accent);
133
+ box-shadow: 0 0 0 3px rgba(0,212,170,0.08);
134
+ }
135
+ input::placeholder, textarea::placeholder {
136
+ color: var(--text-muted);
137
+ }
138
+ textarea {
139
+ resize: vertical;
140
+ min-height: 120px;
141
+ line-height: 1.6;
142
+ font-family: var(--mono);
143
+ font-size: 13px;
144
+ }
145
+
146
+ /* Inline row */
147
+ .field-row {
148
+ display: grid;
149
+ grid-template-columns: 1fr 1fr;
150
+ gap: 16px;
151
+ }
152
+
153
+ /* Submit */
154
+ .btn {
155
+ width: 100%;
156
+ padding: 13px;
157
+ background: var(--accent);
158
+ color: #0d0f12;
159
+ border: none;
160
+ border-radius: 6px;
161
+ font-family: var(--sans);
162
+ font-size: 14px;
163
+ font-weight: 600;
164
+ cursor: pointer;
165
+ letter-spacing: 0.01em;
166
+ transition: opacity 0.15s, transform 0.1s;
167
+ margin-top: 4px;
168
+ }
169
+ .btn:hover { opacity: 0.88; }
170
+ .btn:active { transform: scale(0.99); }
171
+ .btn:disabled { opacity: 0.4; cursor: not-allowed; }
172
+
173
+ /* Result */
174
+ .result-card {
175
+ background: var(--surface);
176
+ border: 1px solid var(--border);
177
+ border-radius: 10px;
178
+ overflow: hidden;
179
+ }
180
+ .result-header {
181
+ display: flex;
182
+ align-items: center;
183
+ justify-content: space-between;
184
+ padding: 14px 20px;
185
+ border-bottom: 1px solid var(--border);
186
+ background: rgba(0,212,170,0.04);
187
+ }
188
+ .result-header-label {
189
+ font-family: var(--mono);
190
+ font-size: 11px;
191
+ letter-spacing: 0.08em;
192
+ text-transform: uppercase;
193
+ color: var(--accent);
194
+ }
195
+ .result-body {
196
+ padding: 20px;
197
+ font-family: var(--mono);
198
+ font-size: 13px;
199
+ line-height: 1.7;
200
+ color: var(--text);
201
+ white-space: pre-wrap;
202
+ word-break: break-word;
203
+ }
204
+
205
+ /* Error */
206
+ .error-card {
207
+ background: var(--danger-dim);
208
+ border: 1px solid rgba(248,113,113,0.25);
209
+ border-radius: 8px;
210
+ padding: 14px 18px;
211
+ font-size: 13px;
212
+ color: var(--danger);
213
+ font-family: var(--mono);
214
+ line-height: 1.6;
215
+ word-break: break-all;
216
+ }
217
+ .error-card::before {
218
+ content: "ERROR — ";
219
+ font-weight: 500;
220
+ }
221
+
222
+ /* Loading state */
223
+ .btn.loading {
224
+ position: relative;
225
+ color: transparent;
226
+ }
227
+ .btn.loading::after {
228
+ content: '';
229
+ position: absolute;
230
+ inset: 0;
231
+ margin: auto;
232
+ width: 18px; height: 18px;
233
+ border: 2px solid rgba(13,15,18,0.3);
234
+ border-top-color: #0d0f12;
235
+ border-radius: 50%;
236
+ animation: spin 0.7s linear infinite;
237
+ }
238
+ @keyframes spin { to { transform: rotate(360deg); } }
239
+
240
+ .help-text {
241
+ font-size: 12px;
242
+ color: var(--text-muted);
243
+ margin-top: 5px;
244
+ }
245
  </style>
246
  </head>
247
  <body>
248
+ <div class="page">
249
+
250
+ <div class="header">
251
+ <div class="header-badge">
252
+ <span class="lock-dot"></span>
253
+ End-to-end encrypted
254
+ </div>
255
+ <h1>Equivariant Encryption Client</h1>
256
+ <p class="subtitle">Prompts are encrypted locally before leaving this Space — the inference server only ever sees scrambled embeddings.</p>
257
+ </div>
258
+
259
+ <form method="POST" id="mainForm">
260
+
261
+ <div class="card">
262
+ <div class="section-label">Connection</div>
263
+
264
+ <div class="field">
265
+ <label>Server Space URL</label>
266
+ <input type="url" name="server_url"
267
+ placeholder="https://your-ee-server.hf.space"
268
+ value="{{ form.get('server_url', '') }}"
269
+ required>
270
  </div>
271
+
272
+ <div class="field">
273
+ <label>EE Model <span>— from Hugging Face Hub</span></label>
274
+ <input type="text" name="ee_model_name"
275
+ placeholder="username/model-ee"
276
+ value="{{ form.get('ee_model_name', '') }}"
277
+ required>
278
  </div>
279
+ </div>
280
+
281
+ <div class="card">
282
+ <div class="section-label">Encryption Key</div>
283
+
284
+ <div class="field">
285
+ <label>Secret Seed <span>— never leaves this client</span></label>
286
+ <input type="number" name="ee_seed"
287
+ value="{{ form.get('ee_seed', '424242') }}"
288
+ required>
289
+ <p class="help-text">Use the same seed that was used when transforming the model.</p>
290
  </div>
291
+ </div>
292
+
293
+ <div class="card">
294
+ <div class="section-label">Prompt</div>
295
+
296
+ <div class="field">
297
+ <label>Your message</label>
298
+ <textarea name="prompt" required
299
+ placeholder="Enter your prompt here...">{{ form.get('prompt', '') }}</textarea>
300
  </div>
301
+
302
+ <div class="field">
303
+ <label>Max new tokens</label>
304
+ <input type="number" name="max_tokens"
305
+ value="{{ form.get('max_tokens', '256') }}"
306
+ min="1" max="2048">
307
  </div>
308
+ </div>
309
+
310
+ <button type="submit" class="btn" id="submitBtn">
311
+ Encrypt &amp; Send →
312
+ </button>
313
 
314
+ </form>
 
 
 
315
 
316
+ {% if error %}
317
+ <div style="margin-top:20px">
318
+ <div class="error-card">{{ error }}</div>
319
  </div>
320
+ {% endif %}
321
+
322
+ {% if result %}
323
+ <div style="margin-top:20px">
324
+ <div class="result-card">
325
+ <div class="result-header">
326
+ <span class="result-header-label">Server response</span>
327
+ <span style="font-size:12px; color: var(--text-muted); font-family: var(--mono);">decrypted locally</span>
328
+ </div>
329
+ <div class="result-body">{{ result }}</div>
330
+ </div>
331
+ </div>
332
+ {% endif %}
333
+
334
+ </div>
335
 
336
+ <script>
337
+ document.getElementById('mainForm').addEventListener('submit', function() {
338
+ const btn = document.getElementById('submitBtn');
339
+ btn.classList.add('loading');
340
+ btn.disabled = true;
341
+ });
342
+ </script>
343
  </body>
344
  </html>