Compare commits

..

7 commits

Author SHA1 Message Date
ClaraCrazy
633d9c9b29
[Chore]: Stop making a fool out of myself 2025-12-29 17:57:09 +01:00
ClaraCrazy
8ce7476227
[Chore]: Fix Expiry Color
This time fr
2025-12-29 17:54:33 +01:00
ClaraCrazy
4d74eacb23
[Chore]: Fix Expiry CSS 2025-12-29 17:43:57 +01:00
ClaraCrazy
8ebf22430b
[Chore]: SEO Updates 2025-12-29 17:39:56 +01:00
ClaraCrazy
6d3a2da214
[AI][Feat]: Add QR-Code Button next to email on inbox
Using local and unminified qrcode.js for auditability <3
2025-12-29 16:54:32 +01:00
ClaraCrazy
9798cd47e9
[Chore]: Modify "Expired" timer to show accent-color
Someone really hates themselves today
2025-12-29 16:34:01 +01:00
ClaraCrazy
f35df3cbc7
[Chore]: Refactor CSS 2025-12-29 16:33:24 +01:00
8 changed files with 1558 additions and 141 deletions

File diff suppressed because it is too large Load diff

View file

@ -30,7 +30,14 @@ document.addEventListener('DOMContentLoaded', () => {
let diff = Math.floor((expiry - now) / 1000); let diff = Math.floor((expiry - now) / 1000);
if (diff <= 0) { if (diff <= 0) {
el.textContent = 'Expired'; el.textContent = 'Expired';
el.style.color = '#b00'; // why am I doing this to myself?
try {
const trojan = document.querySelector('body');
const horse = getComputedStyle(trojan);
el.style.color = horse.getPropertyValue('accent-color').trim();
} catch (_) {
el.style.color = '#b00';
}
return; return;
} }
const hours = Math.floor(diff / 3600); const hours = Math.floor(diff / 3600);
@ -231,10 +238,54 @@ document.addEventListener('DOMContentLoaded', () => {
}); });
} }
function initQrModal() {
const qrBtn = document.getElementById('qrCodeBtn');
const qrModal = document.getElementById('qrModal');
const closeQr = document.getElementById('closeQr');
const qrContainer = document.getElementById('qrcode');
const copyAddress = document.getElementById('copyAddress');
if (!qrBtn || !qrModal || !qrContainer) return;
let qrGenerated = false;
qrBtn.onclick = function() {
qrModal.style.display = 'block';
// Generate QR code only once
if (!qrGenerated && copyAddress) {
const address = copyAddress.textContent.trim();
qrContainer.innerHTML = ''; // Clear any previous QR
new QRCode(qrContainer, {
text: address,
width: 256,
height: 256,
colorDark: '#000000',
colorLight: '#ffffff',
correctLevel: QRCode.CorrectLevel.H
});
qrGenerated = true;
}
};
if (closeQr) {
closeQr.onclick = function() {
qrModal.style.display = 'none';
};
}
window.addEventListener('click', function(e) {
if (e.target === qrModal) {
qrModal.style.display = 'none';
}
});
}
// Expose utilities and run them // Expose utilities and run them
window.utils = { formatEmailDates, formatMailDate, initLockModals, initCopyAddress, initExpiryTimers }; window.utils = { formatEmailDates, formatMailDate, initLockModals, initCopyAddress, initExpiryTimers, initQrModal };
formatEmailDates(); formatEmailDates();
formatMailDate(); formatMailDate();
initLockModals(); initLockModals();
initCopyAddress(); initCopyAddress();
initQrModal();
}); });

View file

@ -0,0 +1,8 @@
# 48hr.email - Temporary Email Service
User-agent: *
Allow: /
Disallow: /inbox/
Disallow: /lock/
Sitemap: https://48hr.email/sitemap.xml

View file

@ -0,0 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
<url>
<loc>https://48hr.email/</loc>
<lastmod>2025-12-29</lastmod>
<changefreq>daily</changefreq>
<priority>1.0</priority>
</url>
</urlset>

View file

@ -1,13 +1,68 @@
:root {
/* Base colors */
--color-bg-dark: #131516;
--color-bg-medium: #2F2B36;
--color-text-primary: #cccccc;
--color-text-light: #e0e0e0;
--color-text-dim: #888;
--color-text-dimmer: #666;
--color-text-gray: #999;
--color-text-white: #ffffff;
--color-text-white-alt: #fff;
/* Accent colors */
--color-accent-purple: #9b4dca;
--color-accent-purple-alt: #9b4cda;
--color-accent-purple-light: #b366e6;
--color-accent-purple-bright: #6c5ce7;
--color-accent-orange: #ca5414;
--color-warning: #ff8c00;
--color-danger: #e74c3c;
--color-error: #b00;
/* UI colors */
--color-border-dark: #444;
--color-button-cancel: #555;
/* Transparent overlays */
--overlay-white-15: rgba(255, 255, 255, 0.15);
--overlay-white-12: rgba(255, 255, 255, 0.12);
--overlay-white-10: rgba(255, 255, 255, 0.1);
--overlay-white-08: rgba(255, 255, 255, 0.08);
--overlay-white-06: rgba(255, 255, 255, 0.06);
--overlay-white-05: rgba(255, 255, 255, 0.05);
--overlay-white-04: rgba(255, 255, 255, 0.04);
--overlay-white-03: rgba(255, 255, 255, 0.03);
--overlay-white-02: rgba(255, 255, 255, 0.02);
--overlay-black-80: rgba(0, 0, 0, 0.8);
--overlay-black-45: rgba(0, 0, 0, 0.45);
--overlay-black-40: rgba(0, 0, 0, 0.4);
--overlay-black-35: rgba(0, 0, 0, 0.35);
--overlay-black-30: rgba(0, 0, 0, 0.3);
/* Purple overlays */
--overlay-purple-50: rgba(155, 77, 202, 0.5);
--overlay-purple-40: rgba(155, 77, 202, 0.4);
--overlay-purple-35: rgba(155, 77, 202, 0.35);
--overlay-purple-30: rgba(155, 77, 202, 0.3);
--overlay-purple-25: rgba(155, 77, 202, 0.25);
--overlay-purple-20: rgba(155, 77, 202, 0.2);
--overlay-purple-15: rgba(155, 77, 202, 0.15);
--overlay-purple-12: rgba(155, 77, 202, 0.12);
--overlay-purple-10: rgba(155, 77, 202, 0.1);
--overlay-purple-08: rgba(155, 77, 202, 0.08);
--overlay-purple-04: rgba(155, 77, 202, 0.04);
/* Warning overlay */
--overlay-warning-10: rgba(255, 140, 0, 0.1);
}
body { body {
margin: 0; margin: 0;
min-height: 100vh; min-height: 100vh;
padding: 20px; padding: 20px;
display: flex; display: flex;
flex-direction: column; flex-direction: column;
background: linear-gradient( 135deg, rgba(255, 255, 255, 0.08), rgba(255, 255, 255, 0.02)), #131516; accent-color: var(--color-accent-purple-alt);
color: #cccccc; background: linear-gradient( 135deg, var(--overlay-white-08), var(--overlay-white-02)), var(--color-bg-dark);
border: 1px solid rgba(255, 255, 255, 0.12); color: var(--color-text-primary);
box-shadow: 0 10px 30px rgba(0, 0, 0, 0.45), inset 0 1px 0 rgba(255, 255, 255, 0.06); border: 1px solid var(--overlay-white-12);
box-shadow: 0 10px 30px var(--overlay-black-45), inset 0 1px 0 var(--overlay-white-06);
} }
body::-webkit-scrollbar { body::-webkit-scrollbar {
@ -27,12 +82,19 @@ main {
} }
a { a {
color: #cccccc; color: var(--color-text-primary);
}
a:hover,
.action-links a:hover,
.email-link,
.attachment-link,
.attachment-link:hover {
text-decoration: none;
} }
a:hover { a:hover {
color: #9b4cda; color: var(--color-accent-purple-alt);
text-decoration: none;
} }
h1 { h1 {
@ -44,7 +106,7 @@ h3 {
} }
a.no-link-color { a.no-link-color {
color: #cccccc; color: var(--color-text-primary);
} }
p { p {
@ -53,7 +115,7 @@ p {
.email:hover { .email:hover {
color: black; color: black;
background-color: #9b4cda; background-color: var(--color-accent-purple-alt);
} }
iframe { iframe {
@ -69,11 +131,11 @@ iframe {
} }
blockquote { blockquote {
border-left: .3rem solid #9b4dca; border-left: .3rem solid var(--color-accent-purple);
} }
blockquote.warning { blockquote.warning {
border-left: .3rem solid #ca5414; border-left: .3rem solid var(--color-accent-orange);
} }
text-muted { text-muted {
@ -107,11 +169,11 @@ text-muted {
text-transform: uppercase; text-transform: uppercase;
letter-spacing: 0.5px; letter-spacing: 0.5px;
transition: all 0.3s ease; transition: all 0.3s ease;
border: 1px solid rgba(255, 255, 255, 0.15); border: 1px solid var(--overlay-white-15);
position: relative; position: relative;
overflow: hidden; overflow: hidden;
text-decoration: none; text-decoration: none;
color: #e0e0e0; color: var(--color-text-light);
} }
.action-links a::before { .action-links a::before {
@ -121,7 +183,7 @@ text-muted {
left: -100%; left: -100%;
width: 100%; width: 100%;
height: 100%; height: 100%;
background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.1), transparent); background: linear-gradient(90deg, transparent, var(--overlay-white-10), transparent);
transition: left 0.5s; transition: left 0.5s;
} }
@ -131,10 +193,9 @@ text-muted {
.action-links a:hover { .action-links a:hover {
transform: translateY(-3px); transform: translateY(-3px);
box-shadow: 0 8px 25px rgba(155, 77, 202, 0.4); box-shadow: 0 8px 25px var(--overlay-purple-40);
border-color: rgba(155, 77, 202, 0.3); border-color: var(--overlay-purple-30);
text-decoration: none; color: var(--color-text-white);
color: #ffffff;
} }
@ -159,11 +220,11 @@ select:hover {
flex-direction: column; flex-direction: column;
max-width: 600px; max-width: 600px;
margin: auto; margin: auto;
background: linear-gradient( 135deg, rgba(155, 77, 202, 0.12), rgba(155, 77, 202, 0.04)), rgba(255, 255, 255, 0.04); background: linear-gradient( 135deg, var(--overlay-purple-12), var(--overlay-purple-04)), var(--overlay-white-04);
border-radius: 22px; border-radius: 22px;
border: 1px solid rgba(155, 77, 202, 0.25); border: 1px solid var(--overlay-purple-25);
padding: 40px 36px; padding: 40px 36px;
box-shadow: 0 20px 50px rgba(0, 0, 0, 0.5), 0 0 0 1px rgba(155, 77, 202, 0.08) inset; box-shadow: 0 20px 50px var(--overlay-black-40), 0 0 0 1px var(--overlay-purple-08) inset;
} }
#login h1, #login h1,
@ -188,14 +249,14 @@ select:hover {
line-height: 1; line-height: 1;
padding: 0 6px; padding: 0 6px;
font-size: 1.4rem; font-size: 1.4rem;
background: #2F2B36; background: var(--color-bg-medium);
z-index: 999; z-index: 999;
} }
#login input[type="text"], #login input[type="text"],
#login select { #login select {
border-radius: 0.4rem; border-radius: 0.4rem;
color: #cccccc; color: var(--color-text-primary);
font-size: 1.6rem; font-size: 1.6rem;
height: 4.2rem; height: 4.2rem;
padding: 0 1.4rem; padding: 0 1.4rem;
@ -203,8 +264,8 @@ select:hover {
} }
#login select option { #login select option {
background-color: #131516; background-color: var(--color-bg-dark);
color: #cccccc; color: var(--color-text-primary);
} }
#login .dropdown { #login .dropdown {
@ -228,22 +289,28 @@ select:hover {
margin-top: 1.5rem; margin-top: 1.5rem;
} }
#login .buttons>*,
#copyAddress,
.close,
.raw-tab-button {
cursor: pointer;
}
#login .buttons>* { #login .buttons>* {
flex: 1 1 auto; flex: 1 1 auto;
min-width: 120px; min-width: 120px;
border-radius: 20px; border-radius: 20px;
color: #fff; color: var(--color-text-white-alt);
background: rgba(155, 77, 202, 0.2); background: var(--overlay-purple-20);
border: 1px solid rgba(155, 77, 202, 0.35); border: 1px solid var(--overlay-purple-35);
box-shadow: 0 8px 20px rgba(155, 77, 202, 0.25), inset 0 1px 0 rgba(255, 255, 255, 0.08); box-shadow: 0 8px 20px var(--overlay-purple-25), inset 0 1px 0 var(--overlay-white-08);
cursor: pointer;
transition: transform 0.2s ease, background 0.2s ease, box-shadow 0.2s ease; transition: transform 0.2s ease, background 0.2s ease, box-shadow 0.2s ease;
} }
#login .buttons>*:hover { #login .buttons>*:hover {
background: rgba(155, 77, 202, 0.3); background: var(--overlay-purple-30);
transform: translateY(-2px); transform: translateY(-2px);
box-shadow: 0 12px 25px rgba(155, 77, 202, 0.35), inset 0 1px 0 rgba(255, 255, 255, 0.12); box-shadow: 0 12px 25px var(--overlay-purple-35), inset 0 1px 0 var(--overlay-white-12);
} }
.mail_attachments { .mail_attachments {
@ -258,27 +325,36 @@ label {
/* Modern Inbox Styles */ /* Modern Inbox Styles */
.inbox-container { .inbox-container,
.mail-container,
.raw-container {
min-width: 75%; min-width: 75%;
max-width: 1500px; max-width: 1500px;
margin: 0 auto; margin: 0 auto;
}
.inbox-container {
padding: 0 20px; padding: 0 20px;
} }
.inbox-header { .inbox-header {
text-align: center; text-align: center;
margin-bottom: 30px; margin-bottom: 30px;
display: flex;
align-items: center;
justify-content: center;
gap: 12px;
} }
.inbox-title { .inbox-title {
background: linear-gradient(135deg, #9b4dca, #b366e6, #6c5ce7); background: linear-gradient(135deg, var(--color-accent-purple), var(--color-accent-purple-light), var(--color-accent-purple-bright));
font-size: 2.8rem; font-size: 2.8rem;
font-weight: 300; font-weight: 300;
-webkit-background-clip: text; -webkit-background-clip: text;
-webkit-text-fill-color: transparent; -webkit-text-fill-color: transparent;
background-clip: text; background-clip: text;
margin: 0; margin-bottom: 10px;
text-shadow: 0 2px 10px rgba(155, 77, 202, 0.3); text-shadow: 0 2px 10px var(--overlay-purple-30);
} }
.emails-container { .emails-container {
@ -290,7 +366,7 @@ label {
overflow-y: auto; overflow-y: auto;
overflow-x: hidden; overflow-x: hidden;
background: transparent; background: transparent;
border: 2px solid rgba(155, 77, 202, 0.3); border: 2px solid var(--overlay-purple-30);
border-radius: 15px; border-radius: 15px;
padding: 20px; padding: 20px;
/* Hide scrollbar */ /* Hide scrollbar */
@ -303,7 +379,6 @@ label {
} }
.email-link { .email-link {
text-decoration: none;
transition: all 0.3s ease; transition: all 0.3s ease;
display: block; display: block;
} }
@ -312,12 +387,17 @@ label {
transform: translateY(-4px); transform: translateY(-4px);
} }
.email-card { .email-card,
.mail-content,
.mail-attachments {
border-radius: 18px; border-radius: 18px;
border: 1px solid rgba(255, 255, 255, 0.08); border: 1px solid var(--overlay-white-08);
box-shadow: 0 8px 30px var(--overlay-black-30);
}
.email-card {
padding: 24px; padding: 24px;
transition: all 0.4s ease; transition: all 0.4s ease;
box-shadow: 0 8px 30px rgba(0, 0, 0, 0.3);
position: relative; position: relative;
overflow: hidden; overflow: hidden;
} }
@ -338,7 +418,7 @@ label {
} }
.email-card:hover { .email-card:hover {
box-shadow: 0 15px 50px rgba(155, 77, 202, 0.15); box-shadow: 0 15px 50px var(--overlay-purple-15);
transform: translateY(-2px); transform: translateY(-2px);
} }
@ -358,29 +438,38 @@ label {
.sender-name { .sender-name {
font-weight: 600; font-weight: 600;
font-size: 1.35rem; font-size: 1.35rem;
color: #ffffff; color: var(--color-text-white);
line-height: 1.2; line-height: 1.2;
} }
.sender-email,
.mail-date {
opacity: 0.8;
}
.sender-email { .sender-email {
font-size: 1rem; font-size: 1rem;
color: #888; color: var(--color-text-dim);
opacity: 0.8;
} }
.email-date, .email-date,
.email-expiry { .email-expiry {
font-size: 0.85rem; font-size: 0.85rem;
color: #666; color: var(--color-text-dimmer);
white-space: nowrap; white-space: nowrap;
opacity: 0.7; opacity: 0.7;
} }
.email-subject,
.empty-card h3,
.mail-attachments h4 {
font-weight: 400;
}
.email-subject { .email-subject {
font-size: 1.25rem; font-size: 1.25rem;
color: #e0e0e0; color: var(--color-text-light);
line-height: 1.5; line-height: 1.5;
font-weight: 400;
} }
@ -394,7 +483,7 @@ label {
} }
.email-date { .email-date {
color: #666; color: var(--color-text-dimmer);
margin-left: auto; margin-left: auto;
text-align: right; text-align: right;
white-space: nowrap; white-space: nowrap;
@ -407,25 +496,28 @@ label {
min-height: 400px; min-height: 400px;
} }
.empty-card { .empty-card,
background: rgba(255, 255, 255, 0.03); .mail-header {
background: var(--overlay-white-03);
border-radius: 20px; border-radius: 20px;
border: 1px solid rgba(255, 255, 255, 0.08); border: 1px solid var(--overlay-white-08);
}
.empty-card {
padding: 50px; padding: 50px;
text-align: center; text-align: center;
box-shadow: 0 12px 40px rgba(0, 0, 0, 0.3); box-shadow: 0 12px 40px var(--overlay-black-30);
max-width: 400px; max-width: 400px;
} }
.empty-card h3 { .empty-card h3 {
color: #9b4dca; color: var(--color-accent-purple);
margin-bottom: 20px; margin-bottom: 20px;
font-weight: 400;
font-size: 2.2rem; font-size: 2.2rem;
} }
.empty-card p { .empty-card p {
color: #888; color: var(--color-text-dim);
font-size: 1.3rem; font-size: 1.3rem;
opacity: 0.9; opacity: 0.9;
line-height: 1.5; line-height: 1.5;
@ -434,59 +526,52 @@ label {
/* Modern Mail View Styles */ /* Modern Mail View Styles */
.mail-container {
min-width: 75%;
max-width: 1500px;
margin: 0 auto;
}
.mail-header { .mail-header {
background: rgba(255, 255, 255, 0.03);
border-radius: 20px;
border: 1px solid rgba(255, 255, 255, 0.08);
padding: 30px; padding: 30px;
margin-bottom: 30px; margin-bottom: 30px;
box-shadow: 0 12px 40px rgba(0, 0, 0, 0.4); box-shadow: 0 12px 40px var(--overlay-black-40);
} }
.mail-subject { .mail-subject {
font-size: 2.2rem; font-size: 2.2rem;
font-weight: 300; font-weight: 300;
margin: 0 0 20px 0; margin: 0 0 20px 0;
color: #ffffff; color: var(--color-text-white);
line-height: 1.3; line-height: 1.3;
} }
.mail-from { .mail-from {
font-size: 1.5rem; font-size: 1.5rem;
color: #b366e6; color: var(--color-accent-purple-light);
font-weight: 500; font-weight: 500;
} }
.mail-date { .mail-date {
font-size: 1.4rem; font-size: 1.4rem;
color: #888; color: var(--color-text-dim);
opacity: 0.8;
} }
.mail-content { .mail-content {
background: rgba(255, 255, 255, 0.02); background: var(--overlay-white-02);
border-radius: 18px; border: 1px solid var(--overlay-white-06);
border: 1px solid rgba(255, 255, 255, 0.06);
padding: 30px; padding: 30px;
box-shadow: 0 8px 30px rgba(0, 0, 0, 0.3);
margin-bottom: 30px; margin-bottom: 30px;
} }
.mail-html-content iframe { .mail-html-content iframe,
.attachment-link,
.raw-mail {
border-radius: 12px; border-radius: 12px;
border: 1px solid rgba(255, 255, 255, 0.1); }
.mail-html-content iframe {
border: 1px solid var(--overlay-white-10);
width: 100%; width: 100%;
min-height: 40vh; min-height: 40vh;
} }
.mail-text-content { .mail-text-content {
color: #e0e0e0; color: var(--color-text-light);
line-height: 1.6; line-height: 1.6;
font-size: 1rem; font-size: 1rem;
white-space: pre-wrap; white-space: pre-wrap;
@ -495,23 +580,19 @@ label {
.mail-empty-content { .mail-empty-content {
text-align: center; text-align: center;
color: #888; color: var(--color-text-dim);
font-style: italic; font-style: italic;
padding: 40px; padding: 40px;
} }
.mail-attachments { .mail-attachments {
background: rgba(255, 255, 255, 0.03); background: var(--overlay-white-03);
border-radius: 18px;
border: 1px solid rgba(255, 255, 255, 0.08);
padding: 25px; padding: 25px;
box-shadow: 0 8px 30px rgba(0, 0, 0, 0.3);
} }
.mail-attachments h4 { .mail-attachments h4 {
color: #9b4dca; color: var(--color-accent-purple);
margin: 0 0 20px 0; margin: 0 0 20px 0;
font-weight: 400;
font-size: 1.4rem; font-size: 1.4rem;
} }
@ -523,22 +604,19 @@ label {
} }
.attachment-link { .attachment-link {
color: #b366e6; color: var(--color-accent-purple-light);
text-decoration: none;
padding: 12px 16px; padding: 12px 16px;
border-radius: 12px; background: var(--overlay-purple-10);
background: rgba(155, 77, 202, 0.1); border: 1px solid var(--overlay-purple-20);
border: 1px solid rgba(155, 77, 202, 0.2);
transition: all 0.3s ease; transition: all 0.3s ease;
display: inline-block; display: inline-block;
max-width: fit-content; max-width: fit-content;
} }
.attachment-link:hover { .attachment-link:hover {
background: rgba(155, 77, 202, 0.15); background: var(--overlay-purple-15);
border-color: rgba(155, 77, 202, 0.3); border-color: var(--overlay-purple-30);
transform: translateX(5px); transform: translateX(5px);
text-decoration: none;
} }
@ -553,27 +631,27 @@ label {
width: 100%; width: 100%;
height: 100%; height: 100%;
overflow: auto; overflow: auto;
background-color: rgba(0, 0, 0, 0.8); background-color: var(--overlay-black-80);
} }
.modal-content { .modal-content {
background-color: #131516; background-color: var(--color-bg-dark);
margin: 10% auto; margin: 10% auto;
padding: 2rem; padding: 2rem;
border: 1px solid #9b4dca; border: 1px solid var(--color-accent-purple);
border-radius: 0.4rem; border-radius: 0.4rem;
width: 90%; width: 90%;
max-width: 400px; max-width: 400px;
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.3); box-shadow: 0 4px 6px var(--overlay-black-30);
} }
.modal-content h3 { .modal-content h3 {
margin-top: 0; margin-top: 0;
color: #cccccc; color: var(--color-text-primary);
} }
.modal-description { .modal-description {
color: #999; color: var(--color-text-gray);
margin-bottom: 1.5rem; margin-bottom: 1.5rem;
font-size: 1.4rem; font-size: 1.4rem;
} }
@ -582,15 +660,14 @@ label {
float: right; float: right;
font-size: 2.8rem; font-size: 2.8rem;
font-weight: bold; font-weight: bold;
cursor: pointer; color: var(--color-text-primary);
color: #cccccc;
line-height: 20px; line-height: 20px;
transition: color 0.3s; transition: color 0.3s;
} }
.close:hover, .close:hover,
.close:focus { .close:focus {
color: #9b4dca; color: var(--color-accent-purple);
} }
.floating-label { .floating-label {
@ -601,89 +678,82 @@ label {
line-height: 1; line-height: 1;
padding: 0 6px; padding: 0 6px;
font-size: 1.4rem; font-size: 1.4rem;
background-color: #131516; background-color: var(--color-bg-dark);
z-index: 999; z-index: 999;
color: #cccccc; color: var(--color-text-primary);
} }
.modal-input { .modal-input {
border-radius: 0.4rem; border-radius: 0.4rem;
color: #cccccc; color: var(--color-text-primary);
font-size: 1.6rem; font-size: 1.6rem;
height: 4.2rem; height: 4.2rem;
padding: 0 1.4rem; padding: 0 1.4rem;
margin-bottom: 1rem; margin-bottom: 1rem;
background-color: transparent; background-color: transparent;
border: 1px solid #444; border: 1px solid var(--color-border-dark);
width: 100%; width: 100%;
} }
.modal-input:focus { .modal-input:focus {
border-color: #9b4dca; border-color: var(--color-accent-purple);
outline: none; outline: none;
} }
.modal-button { .modal-button {
width: 100%; width: 100%;
margin-top: 1rem; margin-top: 1rem;
background-color: #9b4dca; background-color: var(--color-accent-purple);
} }
/* Lock Error Messages */ /* Lock Error Messages */
.unlock-error { .unlock-error {
color: #ff8c00; color: var(--color-warning);
margin-bottom: 1rem; margin-bottom: 1rem;
padding: 0.8rem; padding: 0.8rem;
background: rgba(255, 140, 0, 0.1); background: var(--overlay-warning-10);
border-left: 3px solid #ff8c00; border-left: 3px solid var(--color-warning);
} }
/* Remove Lock Button Styles */ /* Remove Lock Button Styles */
.modal-button-danger { .modal-button-danger {
background-color: #e74c3c; background-color: var(--color-danger);
} }
.modal-button-cancel { .modal-button-cancel {
background-color: #555; background-color: var(--color-button-cancel);
} }
/* Copy address feedback */ /* Copy address feedback */
#copyAddress {
cursor: pointer;
}
#copyFeedback { #copyFeedback {
display: none; display: none;
color: #9b4cda; color: var(--color-accent-purple-alt);
font-size: 0.9em; font-size: 0.9em;
margin-left: 10px; margin-left: 10px;
} }
.email-expiry .expiry-timer[style*="color: #b00"] { .email-expiry .expiry-timer[style*="color: #b00"] {
color: #b00 !important; color: var(--color-error) !important;
} }
/* Raw mail view */ /* Raw mail view */
.raw-container { .raw-container,
max-width: 1500px; .raw-mail {
margin: 0 auto;
padding: 20px; padding: 20px;
} }
.raw-mail { .raw-mail {
background: rgba(0, 0, 0, 0.35); background: var(--overlay-black-35);
color: #e0e0e0; color: var(--color-text-light);
padding: 20px; border: 1px solid var(--overlay-white-08);
border-radius: 12px;
border: 1px solid rgba(255, 255, 255, 0.08);
white-space: pre-wrap; white-space: pre-wrap;
word-break: break-word; word-break: break-word;
overflow-x: auto; overflow-x: auto;
@ -700,21 +770,20 @@ label {
.raw-tab-button { .raw-tab-button {
padding: 8px 14px; padding: 8px 14px;
border-radius: 10px; border-radius: 10px;
border: 1px solid rgba(255, 255, 255, 0.12); border: 1px solid var(--overlay-white-12);
background: rgba(255, 255, 255, 0.05); background: var(--overlay-white-05);
color: #e0e0e0; color: var(--color-text-light);
cursor: pointer;
transition: all 0.2s ease; transition: all 0.2s ease;
} }
.raw-tab-button.active { .raw-tab-button.active {
background: rgba(155, 77, 202, 0.25); background: var(--overlay-purple-25);
border-color: rgba(155, 77, 202, 0.4); border-color: var(--overlay-purple-40);
color: #fff; color: var(--color-text-white-alt);
} }
.raw-tab-button:hover { .raw-tab-button:hover {
border-color: rgba(155, 77, 202, 0.5); border-color: var(--overlay-purple-50);
} }
.raw-panels { .raw-panels {
@ -724,3 +793,64 @@ label {
.raw-mail.hidden { .raw-mail.hidden {
display: none; display: none;
} }
/* QR Code Button and Modal */
.qr-icon-btn {
background: var(--overlay-purple-20);
border: 1px solid var(--overlay-purple-30);
border-radius: 12px;
padding: 10px;
color: var(--color-accent-purple-light);
display: flex;
align-items: center;
justify-content: center;
transition: all 0.3s ease;
}
.qr-icon-btn:hover {
background: var(--overlay-purple-30);
border-color: var(--overlay-purple-40);
transform: translateY(-2px);
box-shadow: 0 8px 20px var(--overlay-purple-25);
}
.qr-icon-btn svg {
width: 24px;
height: 24px;
}
.qr-icon {
fill: none;
stroke: currentColor;
stroke-width: 2;
stroke-linecap: round;
stroke-linejoin: round;
}
.qr-modal-content {
max-width: 400px;
text-align: center;
}
.qr-modal-content h3 {
margin-bottom: 24px;
}
.qr-code-container {
background: white;
padding: 20px;
border-radius: 12px;
display: inline-block;
margin: 0 auto 20px;
border: 2px solid var(--color-accent-purple);
box-shadow: 0 8px 25px var(--overlay-purple-25);
}
.qr-address-label {
color: var(--color-text-light);
font-size: 1.2rem;
margin: 0;
word-break: break-all;
}

View file

@ -21,11 +21,20 @@
{% endblock %} {% endblock %}
{% block body %} {% block body %}
<script src="/javascripts/qrcode.js"></script>
<script src="/javascripts/utils.js" defer></script> <script src="/javascripts/utils.js" defer></script>
<script src="/javascripts/inbox-init.js" defer data-address="{{ address }}" data-expiry-time="{{ expiryTime }}" data-expiry-unit="{{ expiryUnit }}"></script> <script src="/javascripts/inbox-init.js" defer data-address="{{ address }}" data-expiry-time="{{ expiryTime }}" data-expiry-unit="{{ expiryUnit }}"></script>
<div class="inbox-container"> <div class="inbox-container">
<div class="inbox-header"> <div class="inbox-header">
<h1 class="inbox-title" id="copyAddress" title="Click to copy address">{{ address }}</h1> <h1 class="inbox-title" id="copyAddress" title="Click to copy address">{{ address }}</h1>
<button id="qrCodeBtn" class="qr-icon-btn" title="Show QR Code" aria-label="Show QR Code">
<svg class="qr-icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
<rect x="3" y="3" width="7" height="7"/>
<rect x="14" y="3" width="7" height="7"/>
<rect x="14" y="14" width="7" height="7"/>
<rect x="3" y="14" width="7" height="7"/>
</svg>
</button>
<span id="copyFeedback">Copied!</span> <span id="copyFeedback">Copied!</span>
</div> </div>
@ -136,4 +145,14 @@
{# JS handled in /javascripts/lock-modals.js #} {# JS handled in /javascripts/lock-modals.js #}
{% endif %} {% endif %}
<!-- QR Code Modal -->
<div id="qrModal" class="modal">
<div class="modal-content qr-modal-content">
<span class="close" id="closeQr">&times;</span>
<h3>Scan Email Address</h3>
<div id="qrcode" class="qr-code-container"></div>
<p class="qr-address-label">{{ address }}</p>
</div>
</div>
{% endblock %} {% endblock %}

View file

@ -1,17 +1,76 @@
<!DOCTYPE html> <!DOCTYPE html>
<html> <html lang="en">
<head> <head>
<title>{{ title }}</title>
<meta charset="UTF-8"> <meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, minimal-ui"> <meta name="viewport" content="width=device-width, initial-scale=1.0, minimal-ui">
<meta name="darkreader-lock"> <meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="description" content="Dont give shady companies your real email. Use 48hr.email to protect your privacy!">
<meta property="og:image" content="/images/logo.png">
<title>{{ title }}</title>
<!-- SEO Meta Tags -->
<meta name="description" content="Your temporary Inbox. Create instant throwaway email addresses to protect your privacy. No registration required. Emails auto-delete after 48 hours.">
<meta name="keywords" content="temporary email, disposable email, throwaway email, fake email, temp mail, anonymous email, 48hr email, privacy protection, burner email">
<meta name="author" content="CrazyCo">
<meta name="robots" content="index, follow">
<meta name="googlebot" content="index, follow">
<link rel="canonical" href="https://48hr.email/">
<!-- Open Graph / Facebook -->
<meta property="og:type" content="website">
<meta property="og:url" content="https://48hr.email/">
<meta property="og:title" content="48hr.email - Your temporary Inbox">
<meta property="og:description" content="Protect your privacy with free temporary email addresses. No registration required. Emails auto-delete after 48 hours.">
<meta property="og:image" content="https://48hr.email/images/logo.png">
<meta property="og:site_name" content="48hr.email">
<!-- Twitter Card -->
<meta name="twitter:card" content="summary">
<meta name="twitter:url" content="https://48hr.email/">
<meta name="twitter:title" content="48hr.email - Your temporary Inbox">
<meta name="twitter:description" content="Free temporary email service. Protect your privacy with disposable email addresses.">
<meta name="twitter:image" content="https://48hr.email/images/logo.png">
<!-- Additional Meta Tags -->
<meta name="theme-color" content="#9b4dca">
<meta name="darkreader-lock">
<meta name="mobile-web-app-capable" content="yes">
<meta name="apple-mobile-web-app-capable" content="yes">
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent">
<meta name="apple-mobile-web-app-title" content="48hr.email">
<!-- Favicon -->
<link rel="icon" type="image/x-icon" href="/images/logo.ico">
<link rel="shortcut icon" href="/images/logo.ico"> <link rel="shortcut icon" href="/images/logo.ico">
<link rel="apple-touch-icon" href="/images/logo.png">
<!-- Stylesheets -->
<link rel='stylesheet' href='/dependencies/milligram.css' /> <link rel='stylesheet' href='/dependencies/milligram.css' />
<link rel='stylesheet' href='/stylesheets/custom.css' /> <link rel='stylesheet' href='/stylesheets/custom.css' />
<!-- Structured Data for SEO -->
<script type="application/ld+json">
{
"@context": "https://schema.org",
"@type": "WebApplication",
"name": "48hr.email",
"url": "https://48hr.email",
"description": "Your temporary Inbox service for privacy protection",
"applicationCategory": "UtilitiesApplication",
"operatingSystem": "Any",
"offers": {
"@type": "Offer",
"price": "0",
"priceCurrency": "USD"
},
"author": {
"@type": "Organization",
"name": "CrazyCo",
"url": "https://crazyco.xyz"
}
}
</script>
<!-- Scripts -->
<script src="/socket.io/socket.io.js" defer="true"></script> <script src="/socket.io/socket.io.js" defer="true"></script>
<script src="/javascripts/notifications.js" defer="true"></script> <script src="/javascripts/notifications.js" defer="true"></script>

View file

@ -1,6 +1,6 @@
{ {
"name": "48hr.email", "name": "48hr.email",
"version": "1.7.0", "version": "1.7.2",
"private": false, "private": false,
"description": "48hr.email is your favorite open-source tempmail client.", "description": "48hr.email is your favorite open-source tempmail client.",
"keywords": [ "keywords": [