Skip to content

Commit f69feab

Browse files
authored
refactor: visuals and vault behavior (#5)
2 parents 6826268 + 1d651ad commit f69feab

30 files changed

+1641
-599
lines changed

public/bubble-decrypt.html

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,12 @@
3434
padding: 10px 12px;
3535
background: #f9fafb;
3636
border-bottom: 1px solid #e5e7eb;
37+
cursor: grab;
38+
user-select: none;
39+
}
40+
41+
.header:active {
42+
cursor: grabbing;
3743
}
3844

3945
.header-left {

public/bubble-decrypt.js

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66

77
let port = null;
88
let currentPlaintext = '';
9+
let dragging = false;
910

1011
// DOM Elements
1112
const plaintextEl = document.getElementById('plaintext');
@@ -105,3 +106,33 @@ document.addEventListener('keydown', (e) => {
105106
port.postMessage({ type: 'close' });
106107
}
107108
});
109+
110+
/**
111+
* Drag support - header is the drag handle
112+
*/
113+
const header = document.querySelector('.header');
114+
115+
header?.addEventListener('mousedown', () => {
116+
dragging = true;
117+
if (port) {
118+
port.postMessage({ type: 'drag-start' });
119+
}
120+
});
121+
122+
window.addEventListener('mouseup', () => {
123+
if (dragging) {
124+
dragging = false;
125+
if (port) {
126+
port.postMessage({ type: 'drag-end' });
127+
}
128+
}
129+
});
130+
131+
window.addEventListener('mousemove', (e) => {
132+
if (!dragging || !port) return;
133+
port.postMessage({
134+
type: 'drag-move',
135+
deltaX: e.movementX,
136+
deltaY: e.movementY,
137+
});
138+
});

public/manifest.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"manifest_version": 3,
3-
"name": "Quack - Universal Web Encryption",
3+
"name": "Quack!",
44
"version": "0.1.0",
55
"description": "Encrypt your messages anywhere on the web with post-quantum cryptography",
66
"icons": {

public/overlay-encrypt.html

Lines changed: 153 additions & 92 deletions
Original file line numberDiff line numberDiff line change
@@ -1,175 +1,236 @@
1-
<!doctype html>
1+
<!DOCTYPE html>
22
<html lang="en">
33
<head>
4-
<meta charset="UTF-8" />
5-
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
4+
<meta charset="UTF-8">
5+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
66
<title>Quack Encrypt</title>
77
<style>
8-
:root { color-scheme: light; }
9-
* { box-sizing: border-box; }
10-
body {
8+
* {
119
margin: 0;
10+
padding: 0;
11+
box-sizing: border-box;
12+
}
13+
14+
body {
1215
font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
1316
background: transparent;
17+
overflow: hidden;
1418
}
19+
1520
.bubble {
16-
position: relative;
17-
width: 340px;
18-
max-height: 420px;
1921
background: #ffffff;
20-
color: #111827;
2122
border-radius: 12px;
22-
box-shadow: 0 16px 36px rgba(0, 0, 0, 0.16);
23+
box-shadow: 0 4px 20px rgba(0, 0, 0, 0.15);
2324
overflow: hidden;
2425
display: none;
2526
flex-direction: column;
26-
border: none;
27+
max-height: 520px;
2728
}
29+
2830
.header {
2931
display: flex;
3032
align-items: center;
3133
justify-content: space-between;
32-
padding: 6px 10px;
33-
background: linear-gradient(120deg, #f7b267, #f79d65);
34-
color: #0b0c0f;
34+
padding: 10px 12px;
35+
background: #f9fafb;
36+
border-bottom: 1px solid #e5e7eb;
3537
cursor: grab;
3638
user-select: none;
37-
min-height: 32px;
3839
}
40+
41+
.header:active {
42+
cursor: grabbing;
43+
}
44+
45+
.header-left {
46+
display: flex;
47+
align-items: center;
48+
gap: 8px;
49+
}
50+
51+
.duck-icon {
52+
font-size: 18px;
53+
}
54+
3955
.title {
40-
font-weight: 700;
41-
font-size: 13px;
42-
letter-spacing: 0.01em;
56+
font-size: 12px;
57+
color: #6b7280;
58+
font-weight: 600;
4359
}
60+
4461
.close-btn {
62+
background: none;
4563
border: none;
46-
background: rgba(0, 0, 0, 0.08);
47-
width: 24px;
48-
height: 24px;
49-
border-radius: 7px;
5064
cursor: pointer;
51-
font-weight: 700;
52-
color: #111827;
65+
padding: 4px;
66+
border-radius: 4px;
67+
color: #6b7280;
68+
font-size: 16px;
5369
line-height: 1;
54-
display: inline-flex;
55-
align-items: center;
56-
justify-content: center;
70+
transition: background 0.15s, color 0.15s;
5771
}
58-
.close-btn:hover { background: rgba(0, 0, 0, 0.14); }
59-
60-
.section {
61-
padding: 10px;
72+
73+
.close-btn:hover {
74+
background: #e5e7eb;
75+
color: #374151;
76+
}
77+
78+
.content {
79+
flex: 1;
80+
padding: 12px;
6281
display: flex;
6382
flex-direction: column;
64-
gap: 8px;
65-
overflow: auto;
66-
max-height: 380px;
83+
gap: 10px;
84+
overflow-y: auto;
6785
}
68-
86+
6987
.textarea {
7088
width: 100%;
71-
min-height: 110px;
89+
min-height: 80px;
7290
resize: vertical;
73-
border-radius: 10px;
91+
border-radius: 8px;
7492
border: 1px solid #e5e7eb;
7593
padding: 10px;
7694
font-size: 14px;
95+
line-height: 1.5;
7796
font-family: inherit;
97+
color: #111827;
7898
outline: none;
99+
transition: border-color 0.15s, box-shadow 0.15s;
79100
}
101+
80102
.textarea:focus {
81-
border-color: #f79d65;
82-
box-shadow: 0 0 0 2px rgba(247, 157, 101, 0.24);
103+
border-color: #ea711a;
104+
box-shadow: 0 0 0 2px rgba(234, 113, 26, 0.15);
83105
}
84-
.row {
106+
107+
.textarea:read-only {
108+
background: #f9fafb;
109+
color: #374151;
110+
cursor: default;
111+
resize: none;
112+
}
113+
114+
.key-row {
85115
display: flex;
86116
align-items: center;
87117
gap: 8px;
88118
}
89-
.label {
119+
120+
.key-label {
90121
font-size: 12px;
91-
font-weight: 700;
122+
font-weight: 600;
92123
color: #6b7280;
93-
letter-spacing: 0.02em;
94-
text-transform: uppercase;
124+
white-space: nowrap;
95125
}
96-
select {
126+
127+
.key-select {
97128
flex: 1;
98-
border-radius: 10px;
129+
border-radius: 6px;
99130
border: 1px solid #e5e7eb;
100-
padding: 8px 10px;
101-
font-size: 14px;
131+
padding: 6px 8px;
132+
font-size: 13px;
133+
font-family: inherit;
134+
color: #111827;
102135
outline: none;
136+
background: #ffffff;
137+
transition: border-color 0.15s, box-shadow 0.15s;
138+
}
139+
140+
.key-select:focus {
141+
border-color: #ea711a;
142+
box-shadow: 0 0 0 2px rgba(234, 113, 26, 0.15);
143+
}
144+
145+
.status {
146+
font-size: 11px;
147+
color: #6b7280;
148+
text-align: center;
149+
display: none;
103150
}
104-
select:focus {
105-
border-color: #f79d65;
106-
box-shadow: 0 0 0 2px rgba(247, 157, 101, 0.24);
151+
152+
.status.visible {
153+
display: block;
107154
}
108-
.buttons {
155+
156+
.status.error {
157+
color: #ef4444;
158+
}
159+
160+
.status.success {
161+
color: #10b981;
162+
}
163+
164+
.footer {
165+
padding: 8px 12px;
166+
border-top: 1px solid #e5e7eb;
109167
display: flex;
168+
align-items: center;
110169
gap: 8px;
111-
margin-top: 4px;
170+
background: #f9fafb;
112171
}
172+
113173
.btn {
114-
border: 1px solid transparent;
115-
border-radius: 10px;
116-
padding: 10px 12px;
117-
font-weight: 700;
174+
border: none;
175+
border-radius: 8px;
176+
padding: 10px 14px;
118177
cursor: pointer;
119-
font-size: 14px;
178+
font-size: 13px;
179+
font-weight: 700;
180+
transition: background 0.2s, transform 0.1s;
120181
flex: 1;
121-
transition: background 150ms ease, color 150ms ease, border-color 150ms ease, box-shadow 150ms ease;
182+
text-align: center;
122183
}
184+
185+
.btn:active {
186+
transform: scale(0.98);
187+
}
188+
123189
.btn-primary {
124190
background: #ea711a;
125-
color: #fff;
126-
box-shadow: 0 12px 24px rgba(234, 113, 26, 0.22);
191+
color: #ffffff;
192+
}
193+
194+
.btn-primary:hover {
195+
background: #db5810;
127196
}
128-
.btn-primary:hover { background: #db5810; }
197+
198+
.btn-primary.copied {
199+
background: #10b981;
200+
}
201+
129202
.btn-secondary {
130-
background: #fff;
203+
background: #e5e7eb;
131204
color: #1f2937;
132-
border-color: #e5e7eb;
133205
}
206+
134207
.btn-secondary:hover {
135-
background: #f9fafb;
136-
border-color: #f79d65;
137-
}
138-
.status {
139-
font-size: 12px;
140-
color: #6b7280;
141-
margin-top: -2px;
142-
}
143-
.status.error { color: #b91c1c; }
144-
.cipher-box {
145-
background: #f9fafb;
146-
border-radius: 10px;
147-
padding: 8px 10px;
148-
font-size: 13px;
208+
background: #d1d5db;
149209
color: #111827;
150-
min-height: 32px;
151-
box-shadow: inset 0 0 0 1px #e5e7eb;
152-
word-break: break-word;
153210
}
154211
</style>
155212
</head>
156213
<body>
157214
<div class="bubble" id="bubble">
158215
<div class="header" id="drag-handle">
159-
<div class="title" id="bubble-title">Quack</div>
160-
<button class="close-btn" id="close-btn" aria-label="Close">×</button>
216+
<div class="header-left">
217+
<span class="duck-icon">🦆</span>
218+
<span class="title" id="bubble-title">Encrypt</span>
219+
</div>
220+
<button class="close-btn" id="close-btn" aria-label="Close"></button>
161221
</div>
162-
<div class="section">
222+
<div class="content">
163223
<textarea class="textarea" id="encrypt-text" placeholder="Type your message..."></textarea>
164-
<div class="row">
165-
<div class="label">Key</div>
166-
<select id="encrypt-key"></select>
167-
</div>
168-
<div class="buttons">
169-
<button class="btn btn-primary" id="encrypt-submit">Duck it</button>
170-
<button class="btn btn-secondary" id="encrypt-cancel">Dismiss</button>
224+
<div class="status" id="encrypt-status"></div>
225+
<div class="key-row" id="key-row">
226+
<span class="key-label">Group</span>
227+
<select class="key-select" id="encrypt-key"></select>
171228
</div>
172229
</div>
230+
<div class="footer" id="footer">
231+
<button class="btn btn-primary" id="encrypt-submit">🦆 Duck it</button>
232+
<button class="btn btn-secondary" id="encrypt-cancel">Dismiss</button>
233+
</div>
173234
</div>
174235

175236
<script src="overlay-encrypt.js"></script>

0 commit comments

Comments
 (0)