Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
04af188
merge 'develop' into 'refactor/visual' (#3)
0xneves Feb 5, 2026
2b46938
refactor: first wp text changes
0xneves Feb 5, 2026
e2c53b5
feat: setup screen revamp
0xneves Feb 6, 2026
9544a88
refactor: send user to setup if not completed
0xneves Feb 6, 2026
72fd13d
fix: await onVaultUpdate to prevent save interruption on popup close …
0xneves Feb 6, 2026
62278cd
fix: removing scroll from setup second screen
0xneves Feb 6, 2026
b1a86ed
refactor: removing scroll from identiy creation screen
0xneves Feb 6, 2026
50ea823
refactor: removing scroll from you are ready page
0xneves Feb 6, 2026
0597019
refactor: removed duplicated buttons on tab cards
0xneves Feb 6, 2026
ed5cc9e
refactor: removing width expansion on scroll
0xneves Feb 6, 2026
44c49d2
refactor: adding quack logo svg
0xneves Feb 6, 2026
3e92a02
refactor: changing icons on top-right dashboard
0xneves Feb 6, 2026
eedccce
refactor: adding heart to group icons
0xneves Feb 6, 2026
0431e55
refactor: removing useless tips and small text changes
0xneves Feb 6, 2026
b59b682
refactor: adding animation on the copy buttom upon encrypting
0xneves Feb 6, 2026
fe5e81d
fix: wrong text wrap and loose x axis upon decrypt
0xneves Feb 6, 2026
2c8f891
fix: more space for decrypt group result showing
0xneves Feb 6, 2026
9be9435
fix: master password was not correctly cached
0xneves Feb 6, 2026
ec35c1a
refactor: avoid auto-lock glitch when popup is open
0xneves Feb 6, 2026
626a5dd
feat: choose lock time in settings
0xneves Feb 6, 2026
655a8ba
refactor: better summary in settings
0xneves Feb 6, 2026
3e163d0
refactor: quack in-text behavior
0xneves Feb 6, 2026
8d8bbc6
fix: missing error in missing decryption key
0xneves Feb 6, 2026
1d651ad
feat: stealth mode
0xneves Feb 6, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions public/bubble-decrypt.html
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,12 @@
padding: 10px 12px;
background: #f9fafb;
border-bottom: 1px solid #e5e7eb;
cursor: grab;
user-select: none;
}

.header:active {
cursor: grabbing;
}

.header-left {
Expand Down
31 changes: 31 additions & 0 deletions public/bubble-decrypt.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

let port = null;
let currentPlaintext = '';
let dragging = false;

// DOM Elements
const plaintextEl = document.getElementById('plaintext');
Expand Down Expand Up @@ -105,3 +106,33 @@ document.addEventListener('keydown', (e) => {
port.postMessage({ type: 'close' });
}
});

/**
* Drag support - header is the drag handle
*/
const header = document.querySelector('.header');

header?.addEventListener('mousedown', () => {
dragging = true;
if (port) {
port.postMessage({ type: 'drag-start' });
}
});

window.addEventListener('mouseup', () => {
if (dragging) {
dragging = false;
if (port) {
port.postMessage({ type: 'drag-end' });
}
}
});

window.addEventListener('mousemove', (e) => {
if (!dragging || !port) return;
port.postMessage({
type: 'drag-move',
deltaX: e.movementX,
deltaY: e.movementY,
});
});
2 changes: 1 addition & 1 deletion public/manifest.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"manifest_version": 3,
"name": "Quack - Universal Web Encryption",
"name": "Quack!",
"version": "0.1.0",
"description": "Encrypt your messages anywhere on the web with post-quantum cryptography",
"icons": {
Expand Down
245 changes: 153 additions & 92 deletions public/overlay-encrypt.html
Original file line number Diff line number Diff line change
@@ -1,175 +1,236 @@
<!doctype html>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Quack Encrypt</title>
<style>
:root { color-scheme: light; }
* { box-sizing: border-box; }
body {
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}

body {
font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
background: transparent;
overflow: hidden;
}

.bubble {
position: relative;
width: 340px;
max-height: 420px;
background: #ffffff;
color: #111827;
border-radius: 12px;
box-shadow: 0 16px 36px rgba(0, 0, 0, 0.16);
box-shadow: 0 4px 20px rgba(0, 0, 0, 0.15);
overflow: hidden;
display: none;
flex-direction: column;
border: none;
max-height: 520px;
}

.header {
display: flex;
align-items: center;
justify-content: space-between;
padding: 6px 10px;
background: linear-gradient(120deg, #f7b267, #f79d65);
color: #0b0c0f;
padding: 10px 12px;
background: #f9fafb;
border-bottom: 1px solid #e5e7eb;
cursor: grab;
user-select: none;
min-height: 32px;
}

.header:active {
cursor: grabbing;
}

.header-left {
display: flex;
align-items: center;
gap: 8px;
}

.duck-icon {
font-size: 18px;
}

.title {
font-weight: 700;
font-size: 13px;
letter-spacing: 0.01em;
font-size: 12px;
color: #6b7280;
font-weight: 600;
}

.close-btn {
background: none;
border: none;
background: rgba(0, 0, 0, 0.08);
width: 24px;
height: 24px;
border-radius: 7px;
cursor: pointer;
font-weight: 700;
color: #111827;
padding: 4px;
border-radius: 4px;
color: #6b7280;
font-size: 16px;
line-height: 1;
display: inline-flex;
align-items: center;
justify-content: center;
transition: background 0.15s, color 0.15s;
}
.close-btn:hover { background: rgba(0, 0, 0, 0.14); }

.section {
padding: 10px;

.close-btn:hover {
background: #e5e7eb;
color: #374151;
}

.content {
flex: 1;
padding: 12px;
display: flex;
flex-direction: column;
gap: 8px;
overflow: auto;
max-height: 380px;
gap: 10px;
overflow-y: auto;
}

.textarea {
width: 100%;
min-height: 110px;
min-height: 80px;
resize: vertical;
border-radius: 10px;
border-radius: 8px;
border: 1px solid #e5e7eb;
padding: 10px;
font-size: 14px;
line-height: 1.5;
font-family: inherit;
color: #111827;
outline: none;
transition: border-color 0.15s, box-shadow 0.15s;
}

.textarea:focus {
border-color: #f79d65;
box-shadow: 0 0 0 2px rgba(247, 157, 101, 0.24);
border-color: #ea711a;
box-shadow: 0 0 0 2px rgba(234, 113, 26, 0.15);
}
.row {

.textarea:read-only {
background: #f9fafb;
color: #374151;
cursor: default;
resize: none;
}

.key-row {
display: flex;
align-items: center;
gap: 8px;
}
.label {

.key-label {
font-size: 12px;
font-weight: 700;
font-weight: 600;
color: #6b7280;
letter-spacing: 0.02em;
text-transform: uppercase;
white-space: nowrap;
}
select {

.key-select {
flex: 1;
border-radius: 10px;
border-radius: 6px;
border: 1px solid #e5e7eb;
padding: 8px 10px;
font-size: 14px;
padding: 6px 8px;
font-size: 13px;
font-family: inherit;
color: #111827;
outline: none;
background: #ffffff;
transition: border-color 0.15s, box-shadow 0.15s;
}

.key-select:focus {
border-color: #ea711a;
box-shadow: 0 0 0 2px rgba(234, 113, 26, 0.15);
}

.status {
font-size: 11px;
color: #6b7280;
text-align: center;
display: none;
}
select:focus {
border-color: #f79d65;
box-shadow: 0 0 0 2px rgba(247, 157, 101, 0.24);

.status.visible {
display: block;
}
.buttons {

.status.error {
color: #ef4444;
}

.status.success {
color: #10b981;
}

.footer {
padding: 8px 12px;
border-top: 1px solid #e5e7eb;
display: flex;
align-items: center;
gap: 8px;
margin-top: 4px;
background: #f9fafb;
}

.btn {
border: 1px solid transparent;
border-radius: 10px;
padding: 10px 12px;
font-weight: 700;
border: none;
border-radius: 8px;
padding: 10px 14px;
cursor: pointer;
font-size: 14px;
font-size: 13px;
font-weight: 700;
transition: background 0.2s, transform 0.1s;
flex: 1;
transition: background 150ms ease, color 150ms ease, border-color 150ms ease, box-shadow 150ms ease;
text-align: center;
}

.btn:active {
transform: scale(0.98);
}

.btn-primary {
background: #ea711a;
color: #fff;
box-shadow: 0 12px 24px rgba(234, 113, 26, 0.22);
color: #ffffff;
}

.btn-primary:hover {
background: #db5810;
}
.btn-primary:hover { background: #db5810; }

.btn-primary.copied {
background: #10b981;
}

.btn-secondary {
background: #fff;
background: #e5e7eb;
color: #1f2937;
border-color: #e5e7eb;
}

.btn-secondary:hover {
background: #f9fafb;
border-color: #f79d65;
}
.status {
font-size: 12px;
color: #6b7280;
margin-top: -2px;
}
.status.error { color: #b91c1c; }
.cipher-box {
background: #f9fafb;
border-radius: 10px;
padding: 8px 10px;
font-size: 13px;
background: #d1d5db;
color: #111827;
min-height: 32px;
box-shadow: inset 0 0 0 1px #e5e7eb;
word-break: break-word;
}
</style>
</head>
<body>
<div class="bubble" id="bubble">
<div class="header" id="drag-handle">
<div class="title" id="bubble-title">Quack</div>
<button class="close-btn" id="close-btn" aria-label="Close">×</button>
<div class="header-left">
<span class="duck-icon">🦆</span>
<span class="title" id="bubble-title">Encrypt</span>
</div>
<button class="close-btn" id="close-btn" aria-label="Close">✕</button>
</div>
<div class="section">
<div class="content">
<textarea class="textarea" id="encrypt-text" placeholder="Type your message..."></textarea>
<div class="row">
<div class="label">Key</div>
<select id="encrypt-key"></select>
</div>
<div class="buttons">
<button class="btn btn-primary" id="encrypt-submit">Duck it</button>
<button class="btn btn-secondary" id="encrypt-cancel">Dismiss</button>
<div class="status" id="encrypt-status"></div>
<div class="key-row" id="key-row">
<span class="key-label">Group</span>
<select class="key-select" id="encrypt-key"></select>
</div>
</div>
<div class="footer" id="footer">
<button class="btn btn-primary" id="encrypt-submit">🦆 Duck it</button>
<button class="btn btn-secondary" id="encrypt-cancel">Dismiss</button>
</div>
</div>

<script src="overlay-encrypt.js"></script>
Expand Down
Loading