Files
v-iole-t--tab-harbor/privacy.html
T
2026-07-13 12:34:04 +08:00

602 lines
20 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Tab Harbor Privacy Policy</title>
<meta name="description" content="Privacy Policy for Tab Harbor, a calmer Chrome new tab workspace for tabs, quick links, saved reads, and lightweight todos.">
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Libre+Caslon+Display&family=Public+Sans:wght@400;500;600;700&display=swap" rel="stylesheet">
<style>
:root {
--ink: #1a1613;
--paper: #f8f5f0;
--card: #fffdf9;
--warm-gray: #e8e2da;
--muted: #80776f;
--accent: #8a653f;
--accent-soft: #f2e7db;
--accent-border: #d4b396;
--shadow: 0 18px 42px rgba(26, 22, 19, 0.08);
--line: rgba(212, 179, 150, 0.24);
}
* {
box-sizing: border-box;
}
body {
margin: 0;
font-family: "Public Sans", sans-serif;
color: var(--ink);
background:
radial-gradient(circle at top left, rgba(242, 231, 219, 0.8), transparent 34%),
radial-gradient(circle at top right, rgba(232, 226, 218, 0.55), transparent 28%),
var(--paper);
line-height: 1.7;
}
body::before {
content: "";
position: fixed;
inset: 0;
pointer-events: none;
opacity: 0.04;
background-image: url("data:image/svg+xml,%3Csvg viewBox='0 0 256 256' xmlns='http://www.w3.org/2000/svg'%3E%3Cfilter id='noise'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='4' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23noise)'/%3E%3C/svg%3E");
}
.page {
width: min(920px, calc(100vw - 32px));
margin: 0 auto;
padding: 36px 0 72px;
position: relative;
z-index: 1;
}
.topbar {
display: flex;
align-items: center;
justify-content: space-between;
gap: 16px;
margin-bottom: 28px;
padding: 0 2px 12px;
border-bottom: 1px solid var(--line);
}
.brandmark {
display: inline-flex;
align-items: center;
gap: 10px;
min-width: 0;
color: var(--ink);
text-decoration: none;
}
.brandmark-badge {
width: 38px;
height: 38px;
border-radius: 12px;
background: color-mix(in srgb, var(--accent-soft) 72%, var(--card) 28%);
border: 1px solid color-mix(in srgb, var(--accent-border) 74%, var(--card) 26%);
display: inline-flex;
align-items: center;
justify-content: center;
box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.5);
flex-shrink: 0;
overflow: hidden;
}
.brandmark-badge img {
width: 24px;
height: 24px;
display: block;
}
.brandmark-text {
display: flex;
flex-direction: column;
min-width: 0;
}
.brandmark-title {
font-size: 13px;
font-weight: 700;
letter-spacing: 0.01em;
}
.brandmark-meta {
font-size: 11px;
color: var(--muted);
}
.topbar-links {
display: flex;
flex-wrap: wrap;
gap: 10px 14px;
justify-content: flex-end;
}
.topbar-link {
display: inline-flex;
align-items: center;
color: var(--accent);
text-decoration: none;
font-size: 12px;
font-weight: 600;
letter-spacing: 0.01em;
}
.topbar-link + .topbar-link::before {
content: "/";
margin-right: 14px;
color: color-mix(in srgb, var(--muted) 76%, var(--paper) 24%);
}
.hero {
padding: 6px 2px 28px;
}
.eyebrow {
margin: 0 0 14px;
font-size: 11px;
letter-spacing: 0.18em;
text-transform: uppercase;
color: var(--muted);
font-weight: 700;
}
h1 {
margin: 0;
font-family: "Libre Caslon Display", serif;
font-size: clamp(42px, 7vw, 64px);
line-height: 0.95;
font-weight: 400;
letter-spacing: -0.03em;
}
.subtitle {
margin: 18px 0 0;
max-width: 60ch;
font-size: 16px;
color: color-mix(in srgb, var(--ink) 78%, var(--muted) 22%);
}
.meta {
display: flex;
flex-wrap: wrap;
gap: 8px 12px;
margin-top: 18px;
color: var(--muted);
font-size: 12px;
letter-spacing: 0.01em;
}
.meta-item {
display: inline-flex;
align-items: center;
gap: 12px;
}
.meta-item + .meta-item::before {
content: "";
width: 18px;
height: 1px;
background: rgba(212, 179, 150, 0.45);
transform: translateY(-1px);
}
.layout {
display: grid;
grid-template-columns: minmax(0, 1fr) 244px;
gap: 18px;
align-items: start;
}
.card {
background: rgba(255, 253, 249, 0.9);
border: 1px solid rgba(212, 179, 150, 0.35);
border-radius: 24px;
box-shadow: var(--shadow);
padding: 28px 28px 12px;
backdrop-filter: blur(10px);
}
.toc-card {
position: sticky;
top: 18px;
padding: 18px 18px 8px;
}
.toc-title {
margin: 0 0 12px;
font-size: 11px;
letter-spacing: 0.16em;
text-transform: uppercase;
color: var(--muted);
font-weight: 700;
}
.toc {
display: grid;
gap: 10px;
}
.toc a {
color: var(--accent);
text-decoration: none;
font-size: 13px;
font-weight: 600;
line-height: 1.45;
}
.toc a:hover,
.toc a:focus-visible {
text-decoration: underline;
text-underline-offset: 3px;
}
section {
padding-bottom: 18px;
margin-bottom: 8px;
border-bottom: 1px solid rgba(212, 179, 150, 0.18);
}
section:last-of-type {
border-bottom: none;
}
h2 {
margin: 0 0 12px;
font-size: 22px;
line-height: 1.2;
font-weight: 600;
color: var(--ink);
}
.legal-note {
margin: 0 0 20px;
padding: 16px 18px;
border-radius: 18px;
border: 1px solid rgba(212, 179, 150, 0.24);
background: linear-gradient(180deg, rgba(242, 231, 219, 0.54), rgba(255, 253, 249, 0.78));
}
.legal-note-title {
margin: 0 0 8px;
font-size: 12px;
font-weight: 700;
letter-spacing: 0.08em;
text-transform: uppercase;
color: var(--accent);
}
.legal-note p:last-child {
margin-bottom: 0;
}
p {
margin: 0 0 14px;
}
ul {
margin: 0 0 16px;
padding-left: 20px;
}
li {
margin-bottom: 8px;
}
code {
font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
font-size: 0.95em;
background: rgba(232, 226, 218, 0.6);
padding: 2px 6px;
border-radius: 6px;
}
.contact {
margin-top: 10px;
padding: 18px 20px;
border-radius: 18px;
background: color-mix(in srgb, var(--accent-soft) 58%, var(--card) 42%);
border: 1px solid rgba(212, 179, 150, 0.28);
}
.footer {
display: grid;
grid-template-columns: minmax(0, 1fr) auto;
gap: 14px 20px;
margin-top: 26px;
padding: 16px 4px 0;
border-top: 1px solid rgba(212, 179, 150, 0.2);
color: var(--muted);
font-size: 12px;
}
.footer-brand {
display: flex;
flex-direction: column;
gap: 4px;
min-width: 0;
}
.footer-title {
color: var(--ink);
font-size: 12px;
font-weight: 700;
letter-spacing: 0.04em;
text-transform: uppercase;
}
.footer-links {
display: flex;
flex-wrap: wrap;
gap: 10px 14px;
justify-content: flex-end;
}
a {
color: var(--accent);
}
a:hover,
a:focus-visible {
text-underline-offset: 3px;
}
@media (max-width: 900px) {
.layout {
grid-template-columns: 1fr;
}
.toc-card {
position: static;
order: -1;
}
.toc {
grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
gap: 10px 16px;
}
}
@media (max-width: 720px) {
.page {
width: min(100vw - 24px, 920px);
padding: 22px 0 42px;
}
.card {
padding: 22px 20px 8px;
border-radius: 20px;
}
.subtitle {
font-size: 15px;
}
.topbar {
padding-bottom: 12px;
align-items: flex-start;
flex-direction: column;
}
.topbar-links {
justify-content: flex-start;
}
.footer {
grid-template-columns: 1fr;
}
.footer-links {
justify-content: flex-start;
}
}
</style>
</head>
<body>
<main class="page">
<div class="topbar">
<a class="brandmark" href="https://github.com/V-IOLE-T/tab-harbor" target="_blank" rel="noreferrer">
<span class="brandmark-badge" aria-hidden="true">
<img src="extension/icons/icon128.png" alt="">
</span>
<span class="brandmark-text">
<span class="brandmark-title">Tab Harbor</span>
<span class="brandmark-meta">Chrome extension privacy page</span>
</span>
</a>
<div class="topbar-links">
<a class="topbar-link" href="https://github.com/V-IOLE-T/tab-harbor" target="_blank" rel="noreferrer">Back to project home</a>
<a class="topbar-link" href="#contact">Contact</a>
<a class="topbar-link" href="https://github.com/V-IOLE-T/tab-harbor/blob/main/PRIVACY.md" target="_blank" rel="noreferrer">Markdown</a>
</div>
</div>
<header class="hero">
<p class="eyebrow">Tab Harbor</p>
<h1>Privacy Policy</h1>
<p class="subtitle">
Tab Harbor is a calmer Chrome new tab workspace for open tabs, quick links, saved reads, and lightweight todos.
This page explains what data the extension accesses, why it needs that data, and how that data is handled.
</p>
<div class="meta" aria-label="Policy metadata">
<span class="meta-item">Last updated: 2026-05-27</span>
<span class="meta-item">Local-first by default</span>
<span class="meta-item">No remote code</span>
</div>
</header>
<div class="layout">
<article class="card">
<div class="legal-note">
<p class="legal-note-title">Privacy Snapshot</p>
<p>Tab Harbor is a local-first Chrome extension. It organizes tabs, quick links, saved reads, and lightweight todos inside the new tab page. It does not require an account, does not sell user data, and does not use remote code.</p>
</div>
<section id="summary">
<h2>1. Summary</h2>
<p>Tab Harbor is designed to work locally in the browser.</p>
<ul>
<li>It does not require a user account.</li>
<li>It does not sell user data.</li>
<li>It does not use remote code.</li>
<li>It does not send workspace data to a developer-controlled backend.</li>
</ul>
<p>Most extension data is stored locally through Chrome extension storage APIs.</p>
</section>
<section id="data-accessed">
<h2>2. Information the extension accesses</h2>
<p>To provide its core features, Tab Harbor may access the following categories of data:</p>
<ul>
<li>Open tab metadata, including tab titles, URLs, and tab state</li>
<li>Quick links created by the user</li>
<li>Saved read-later items created by the user</li>
<li>Todo items created by the user</li>
<li>Theme, transparency, layout, and ordering preferences selected by the user</li>
<li>Clipboard image or SVG content, but only when the user explicitly pastes a custom shortcut icon</li>
</ul>
<p>Tab Harbor does not intentionally collect sensitive categories such as health data, financial account credentials, or personal communications.</p>
</section>
<section id="data-use">
<h2>3. How the data is used</h2>
<p>Tab Harbor uses the accessed data only to provide the extensions single purpose:</p>
<ul>
<li>Show and organize the users current browser session in the new tab page</li>
<li>Help the user review, group, focus, close, deduplicate, save, and restore tabs</li>
<li>Let the user manage quick links, saved reads, and lightweight todos in one workspace</li>
<li>Restore user preferences and layout state when the new tab page is opened again</li>
<li>Let the user paste a custom icon into a shortcut when they explicitly choose to do so</li>
</ul>
<p>Tab Harbor does not use this data for advertising, profiling, creditworthiness, or unrelated analytics.</p>
</section>
<section id="permissions">
<h2>4. Chrome permissions and why they are needed</h2>
<p>Tab Harbor requests the following Chrome permissions:</p>
<p><strong><code>tabs</code></strong></p>
<ul>
<li>display open tabs in the workspace</li>
<li>group tabs by site or workflow</li>
<li>focus a selected tab</li>
<li>close or deduplicate tabs at the users request</li>
<li>save or restore tabs as part of the read-later workflow</li>
</ul>
<p><strong><code>storage</code></strong></p>
<ul>
<li>save quick links, saved reads, todos, theme settings, layout order, and other local workspace preferences</li>
</ul>
<p><strong><code>search</code></strong></p>
<ul>
<li>let the user submit searches from the built-in search field through the browsers default search engine</li>
</ul>
<p><strong><code>clipboardRead</code></strong></p>
<ul>
<li>let the user explicitly paste an image or SVG into the shortcut editor for a custom shortcut icon</li>
</ul>
<p><strong><code>tabGroups</code></strong></p>
<ul>
<li>read existing native Chrome tab groups</li>
<li>create or update Chrome tab groups to match the workspace</li>
<li>keep group titles, colors, and collapsed state aligned with the users chosen organization</li>
<li>respond when Chrome tab groups change outside the Tab Harbor page</li>
</ul>
<p><strong><code>favicon</code></strong></p>
<ul>
<li>request and display site icons for tabs, saved sessions, and quick shortcuts more reliably</li>
<li>use Chromes packaged favicon endpoint, a sites own <code>favicon.ico</code>, or a fallback favicon service when no better icon is available</li>
</ul>
</section>
<section id="storage">
<h2>5. Data storage and retention</h2>
<p>Tab Harbor stores extension data locally using Chrome extension storage APIs, primarily <code>chrome.storage.local</code>.</p>
<p>This includes items such as quick links, saved reads, todos, theme preferences, and layout state.</p>
<p>This data remains in the browser profile until the user removes it through the extension UI, clears extension storage, or uninstalls the extension.</p>
</section>
<section id="sharing">
<h2>6. Data sharing</h2>
<p>Tab Harbor does not sell user data.</p>
<p>Tab Harbor does not transfer user data to third parties except where necessary to perform a user-requested browser action, such as opening a page chosen by the user, submitting a search through the browsers default search engine, or requesting favicon resources needed to display site icons in the workspace.</p>
<p>Aside from those normal browser actions initiated by the user, Tab Harbor does not send workspace data to a developer-controlled remote service.</p>
</section>
<section id="remote-code">
<h2>7. Remote code</h2>
<p>Tab Harbor does not use remote code.</p>
<p>All JavaScript and extension assets required to run the extension are packaged with the extension bundle. Tab Harbor does not download and execute external JavaScript or WebAssembly at runtime.</p>
</section>
<section id="third-party">
<h2>8. Third-party services</h2>
<p>Tab Harbor relies on Chromes extension platform APIs to function.</p>
<p>When a user opens a webpage or submits a search through the extension, the browser may connect to the destination website or the configured default search engine as part of the users explicit action.</p>
<p>To render site icons, Tab Harbor may also request favicon resources from a pages origin or a fallback favicon service based on the page URLs already visible in the workspace.</p>
</section>
<section id="choices">
<h2>9. User choices and controls</h2>
<p>Users can control their data by editing or deleting quick links, deleting saved reads or todos, changing theme and layout preferences, uninstalling the extension, or clearing extension storage through browser settings.</p>
<p>If you do not want Tab Harbor to access your open tabs, do not use the extension.</p>
</section>
<section id="children">
<h2>10. Childrens privacy</h2>
<p>Tab Harbor is not directed to children under 13, and the developer does not knowingly collect personal information from children.</p>
</section>
<section id="changes">
<h2>11. Changes to this policy</h2>
<p>This Privacy Policy may be updated from time to time to reflect product changes, permission changes, or legal requirements.</p>
<p>The latest version will be published at the public URL associated with the extension listing.</p>
</section>
<section id="contact">
<h2>12. Contact</h2>
<div class="contact">
<p>If you have questions about this Privacy Policy or Tab Harbor, you may contact:</p>
<p><strong>Publisher contact email:</strong> <a href="mailto:lunatic.halle@gmail.com">lunatic.halle@gmail.com</a></p>
</div>
</section>
</article>
<aside class="card toc-card">
<p class="toc-title">Contents</p>
<nav class="toc" aria-label="Table of contents">
<a href="#summary">1. Summary</a>
<a href="#data-accessed">2. Information the extension accesses</a>
<a href="#data-use">3. How the data is used</a>
<a href="#permissions">4. Chrome permissions</a>
<a href="#storage">5. Data storage and retention</a>
<a href="#sharing">6. Data sharing</a>
<a href="#remote-code">7. Remote code</a>
<a href="#third-party">8. Third-party services</a>
<a href="#choices">9. User choices and controls</a>
<a href="#children">10. Childrens privacy</a>
<a href="#changes">11. Changes to this policy</a>
<a href="#contact">12. Contact</a>
</nav>
</aside>
</div>
<footer class="footer">
<div class="footer-brand">
<span class="footer-title">Tab Harbor</span>
<span>Privacy page for Chrome Web Store review and public reference.</span>
<span>Copyright © 2026 Tab Harbor. All rights reserved.</span>
</div>
<div class="footer-links">
<a href="https://github.com/V-IOLE-T/tab-harbor" target="_blank" rel="noreferrer">GitHub repository</a>
<a href="https://github.com/V-IOLE-T/tab-harbor/blob/main/PRIVACY.md" target="_blank" rel="noreferrer">Source markdown</a>
</div>
</footer>
</main>
</body>
</html>