7 Commits

Author SHA1 Message Date
98d76e3a35 0.3.4
All checks were successful
Deploy to Production / deploy (push) Successful in 13s
2026-02-27 04:44:34 +00:00
cc7e80a807 feat: improve mobile layout for Password Generator button 2026-02-27 04:43:58 +00:00
1f5500f7d7 0.3.3
All checks were successful
Deploy to Production / deploy (push) Successful in 13s
2026-02-27 04:37:29 +00:00
d404370027 fix: adjust layout for Password Generator and Clipboard Sniffer on smaller screens 2026-02-27 04:37:21 +00:00
8fb3ee1069 refactor: align privacy policy layout with app design
All checks were successful
Deploy to Production / deploy (push) Successful in 7s
2026-02-27 04:20:29 +00:00
348c78612d 0.3.2
All checks were successful
Deploy to Production / deploy (push) Successful in 13s
2026-02-27 04:16:17 +00:00
dc99dce485 fix: restore dark mode styles and scope privacy policy styles 2026-02-27 04:16:01 +00:00
5 changed files with 125 additions and 89 deletions

4
package-lock.json generated
View File

@@ -1,12 +1,12 @@
{ {
"name": "tools-app", "name": "tools-app",
"version": "0.3.1", "version": "0.3.4",
"lockfileVersion": 3, "lockfileVersion": 3,
"requires": true, "requires": true,
"packages": { "packages": {
"": { "": {
"name": "tools-app", "name": "tools-app",
"version": "0.3.1", "version": "0.3.4",
"dependencies": { "dependencies": {
"lucide-vue-next": "^0.575.0", "lucide-vue-next": "^0.575.0",
"vue": "^3.5.25", "vue": "^3.5.25",

View File

@@ -1,7 +1,7 @@
{ {
"name": "tools-app", "name": "tools-app",
"private": true, "private": true,
"version": "0.3.1", "version": "0.3.4",
"type": "module", "type": "module",
"scripts": { "scripts": {
"dev": "vite", "dev": "vite",

View File

@@ -224,7 +224,6 @@ onUnmounted(() => {
v-model="clipboardContent" v-model="clipboardContent"
class="tool-textarea" class="tool-textarea"
placeholder="Clipboard content will appear here line by line..." placeholder="Clipboard content will appear here line by line..."
readonly
></textarea> ></textarea>
</div> </div>
</div> </div>

View File

@@ -75,7 +75,7 @@ const generatePasswords = () => {
<div class="tool-panel"> <div class="tool-panel">
<div class="panel-header"> <div class="panel-header">
<h2 class="tool-title">Bulk Passwords Generator</h2> <h2 class="tool-title">Bulk Passwords Generator</h2>
<div class="action-area"> <div class="action-area desktop-only">
<button class="btn-neon generate-btn" @click="generatePasswords" v-ripple> <button class="btn-neon generate-btn" @click="generatePasswords" v-ripple>
Generate Generate
</button> </button>
@@ -131,6 +131,12 @@ const generatePasswords = () => {
</div> </div>
</div> </div>
<div class="mobile-only" style="margin-top: 1rem; width: 100%;">
<button class="btn-neon generate-btn" @click="generatePasswords" v-ripple style="width: 100%;">
Generate
</button>
</div>
<div class="result-area" :style="{ height: textareaHeight }"> <div class="result-area" :style="{ height: textareaHeight }">
<textarea <textarea
class="tool-textarea" class="tool-textarea"
@@ -189,9 +195,10 @@ const generatePasswords = () => {
.inputs-group { .inputs-group {
display: flex; display: flex;
gap: 2rem; gap: 1rem;
flex: 1; flex: 1;
min-width: 300px; min-width: 200px;
flex-wrap: wrap;
} }
.input-wrapper { .input-wrapper {
@@ -199,6 +206,7 @@ const generatePasswords = () => {
flex-direction: column; flex-direction: column;
gap: 0.5rem; gap: 0.5rem;
flex: 1; flex: 1;
min-width: 140px;
} }
.checkbox-label { .checkbox-label {
@@ -351,6 +359,14 @@ const generatePasswords = () => {
letter-spacing: 1px; letter-spacing: 1px;
} }
.desktop-only {
display: block;
}
.mobile-only {
display: none;
}
@media (max-width: 768px) { @media (max-width: 768px) {
.options-grid { .options-grid {
flex-direction: column; flex-direction: column;
@@ -370,5 +386,13 @@ const generatePasswords = () => {
.generate-btn { .generate-btn {
width: 100%; width: 100%;
} }
.desktop-only {
display: none;
}
.mobile-only {
display: block !important;
}
} }
</style> </style>

View File

@@ -3,8 +3,8 @@ import { ArrowLeft } from 'lucide-vue-next'
</script> </script>
<template> <template>
<div class="privacy-container"> <div class="tool-container">
<div class="privacy-content"> <div class="tool-panel privacy-panel">
<header class="privacy-header"> <header class="privacy-header">
<router-link to="/" class="back-link"> <router-link to="/" class="back-link">
<ArrowLeft size="20" /> <ArrowLeft size="20" />
@@ -14,96 +14,102 @@ import { ArrowLeft } from 'lucide-vue-next'
<p class="last-updated">Last Updated: February 27, 2026</p> <p class="last-updated">Last Updated: February 27, 2026</p>
</header> </header>
<section> <div class="privacy-body">
<h2>1. Introduction</h2> <section>
<p> <h2>1. Introduction</h2>
Welcome to Tools App ("we," "our," or "us"). We are committed to protecting your privacy. <p>
This Privacy Policy explains how our Chrome Extension ("Tools App Extension") handles your data. Welcome to Tools App ("we," "our," or "us"). We are committed to protecting your privacy.
</p> This Privacy Policy explains how our Chrome Extension ("Tools App Extension") handles your data.
</section> </p>
</section>
<section> <section>
<h2>2. Data Collection and Usage</h2> <h2>2. Data Collection and Usage</h2>
<p> <p>
The Tools App Extension is designed with privacy as a priority. The Tools App Extension is designed with privacy as a priority.
<strong>We do not collect, store, or transmit any of your personal data to external servers.</strong> <strong>We do not collect, store, or transmit any of your personal data to external servers.</strong>
</p> </p>
<h3>Clipboard Data</h3>
<p>
The extension requires the <code>clipboardRead</code> permission to function.
It reads text from your clipboard <strong>only</strong> when you explicitly enable the "Clipboard Sniffer" tool in the Tools App web interface.
</p>
<ul>
<li>Clipboard data is processed locally within your browser.</li>
<li>Data is sent directly from the extension to the open Tools App tab via a secure local communication channel.</li>
<li>Once you close the tab or stop the tool, the extension stops monitoring the clipboard immediately.</li>
<li>We do not have access to your clipboard history, and it is never uploaded to any cloud storage or third-party service.</li>
</ul>
</section>
<section> <h3>Clipboard Data</h3>
<h2>3. Permissions</h2> <p>
<p>The extension requests the following permissions for specific functional purposes:</p> The extension requires the <code>clipboardRead</code> permission to function.
<ul> It reads text from your clipboard <strong>only</strong> when you explicitly enable the "Clipboard Sniffer" tool in the Tools App web interface.
<li><strong>clipboardRead:</strong> To detect copied text when the Sniffer tool is active.</li> </p>
<li><strong>scripting:</strong> To communicate with the Tools App web page.</li> <ul>
<li><strong>storage:</strong> To save local user preferences (e.g., sound settings).</li> <li>Clipboard data is processed locally within your browser.</li>
<li><strong>alarms:</strong> To maintain the background process active during monitoring sessions.</li> <li>Data is sent directly from the extension to the open Tools App tab via a secure local communication channel.</li>
</ul> <li>Once you close the tab or stop the tool, the extension stops monitoring the clipboard immediately.</li>
</section> <li>We do not have access to your clipboard history, and it is never uploaded to any cloud storage or third-party service.</li>
</ul>
</section>
<section> <section>
<h2>4. Third-Party Services</h2> <h2>3. Permissions</h2>
<p> <p>The extension requests the following permissions for specific functional purposes:</p>
Our extension operates independently and does not use any third-party analytics, tracking scripts, or advertising networks. <ul>
</p> <li><strong>clipboardRead:</strong> To detect copied text when the Sniffer tool is active.</li>
</section> <li><strong>scripting:</strong> To communicate with the Tools App web page.</li>
<li><strong>storage:</strong> To save local user preferences (e.g., sound settings).</li>
<li><strong>alarms:</strong> To maintain the background process active during monitoring sessions.</li>
</ul>
</section>
<section> <section>
<h2>5. Changes to This Policy</h2> <h2>4. Third-Party Services</h2>
<p> <p>
We may update our Privacy Policy from time to time. We will notify you of any changes by posting the new Privacy Policy on this page. Our extension operates independently and does not use any third-party analytics, tracking scripts, or advertising networks.
</p> </p>
</section> </section>
<section> <section>
<h2>6. Contact Us</h2> <h2>5. Changes to This Policy</h2>
<p> <p>
If you have any questions about this Privacy Policy, please contact us via the repository or support channels provided in the Chrome Web Store listing. We may update our Privacy Policy from time to time. We will notify you of any changes by posting the new Privacy Policy on this page.
</p> </p>
</section> </section>
<section>
<h2>6. Contact Us</h2>
<p>
If you have any questions about this Privacy Policy, please contact us via the repository or support channels provided in the Chrome Web Store listing.
</p>
</section>
</div>
</div> </div>
</div> </div>
</template> </template>
<style scoped> <style scoped>
.privacy-container { .privacy-panel {
min-height: 100vh; max-width: 900px; /* Slightly wider for reading */
width: 100%; margin: 0 auto;
display: flex;
justify-content: center;
padding: 2rem;
background: var(--bg-gradient);
color: var(--text-color);
} }
.privacy-content { .privacy-body {
width: 100%; overflow-y: auto;
max-width: 800px; padding-right: 0.5rem;
background: var(--glass-bg); }
backdrop-filter: blur(12px);
-webkit-backdrop-filter: blur(12px); /* Custom scrollbar for privacy body */
border: 1px solid var(--glass-border); .privacy-body::-webkit-scrollbar {
border-radius: 16px; width: 8px;
padding: 3rem; }
box-shadow: var(--glass-shadow);
.privacy-body::-webkit-scrollbar-track {
background: rgba(0, 0, 0, 0.1);
border-radius: 4px;
}
.privacy-body::-webkit-scrollbar-thumb {
background: rgba(255, 255, 255, 0.2);
border-radius: 4px;
} }
.privacy-header { .privacy-header {
margin-bottom: 3rem; margin-bottom: 2rem;
border-bottom: 1px solid var(--glass-border); border-bottom: 1px solid var(--glass-border);
padding-bottom: 2rem; padding-bottom: 1.5rem;
flex-shrink: 0;
} }
.back-link { .back-link {
@@ -128,6 +134,7 @@ h1 {
-webkit-background-clip: text; -webkit-background-clip: text;
background-clip: text; background-clip: text;
color: transparent; color: transparent;
width: fit-content;
} }
.last-updated { .last-updated {
@@ -168,29 +175,35 @@ li {
color: var(--text-color); color: var(--text-color);
} }
strong {
color: var(--text-strong);
font-weight: 600;
}
code { code {
background: rgba(0, 0, 0, 0.1); background: rgba(255, 255, 255, 0.1);
padding: 0.2rem 0.4rem; padding: 0.2rem 0.4rem;
border-radius: 4px; border-radius: 4px;
font-family: monospace; font-family: monospace;
font-size: 0.9em; font-size: 0.9em;
color: var(--text-strong);
} }
:global(:root[data-theme="dark"]) code { :global(html[data-theme="light"]) code {
background: rgba(255, 255, 255, 0.1); background: rgba(0, 0, 0, 0.1);
} }
@media (max-width: 768px) { @media (max-width: 768px) {
.privacy-container { .privacy-container {
padding: 1rem; padding: 1rem;
} }
.privacy-content { .privacy-content {
padding: 1.5rem; padding: 1.5rem;
} }
h1 { h1 {
font-size: 2rem; font-size: 2rem;
} }
} }
</style> </style>