{point.title}
-{point.text}
- +{step.title}
+{step.text}
+diff --git a/docs/app/footer.css b/docs/app/footer.css index 074edb6..7eadcc6 100644 --- a/docs/app/footer.css +++ b/docs/app/footer.css @@ -1,72 +1,36 @@ .site-footer { - padding-top: 75px; + padding-top: 42px; background: var(--paper); } -.footer-main { - display: grid; - grid-template-columns: 1fr auto; - gap: 60px; - padding-bottom: 70px; -} - -.footer-brand { +.footer-inner { display: flex; - align-items: flex-start; - gap: 15px; + align-items: center; + justify-content: space-between; + gap: 40px; + padding-bottom: 38px; } -.footer-mark { - display: grid; - width: 48px; - height: 48px; - flex: 0 0 auto; - place-items: center; - border: 1px solid var(--line); - border-radius: 14px; - background: white; -} - -.footer-mark img { - width: 32px; - height: 32px; -} - -.footer-brand p { - margin-bottom: 0; - color: var(--ink-muted); - font-size: 13px; -} - -.footer-brand .footer-name { - margin-bottom: 3px; +.footer-identity { + display: inline-flex; + align-items: center; + gap: 7px; color: var(--ink); font-family: var(--font-display); - font-size: 21px; + font-size: 18px; font-weight: 750; letter-spacing: -0.04em; } +.footer-identity img { + width: 38px; + height: 38px; +} + .footer-links { - display: grid; - grid-template-columns: repeat(2, minmax(140px, 1fr)); - gap: 70px; -} - -.footer-links > div { display: flex; - flex-direction: column; - gap: 9px; -} - -.footer-links .footer-label { - margin-bottom: 7px; - color: var(--ink-muted); - font-family: var(--font-mono); - font-size: 10px; - font-weight: 800; - letter-spacing: 0.1em; - text-transform: uppercase; + align-items: center; + gap: 24px; } .footer-links a { @@ -74,8 +38,8 @@ align-items: center; gap: 6px; color: var(--ink-soft); - font-size: 13px; - font-weight: 600; + font-size: 12px; + font-weight: 620; } .footer-links a:hover { @@ -83,15 +47,15 @@ } .footer-links svg { - width: 13px; + width: 14px; } .footer-bottom { display: flex; align-items: center; justify-content: space-between; - padding-top: 22px; - padding-bottom: 28px; + padding-top: 20px; + padding-bottom: 26px; border-top: 1px solid var(--line); color: var(--ink-muted); font-size: 11px; diff --git a/docs/app/home.css b/docs/app/home.css index 55d1bea..57e8c02 100644 --- a/docs/app/home.css +++ b/docs/app/home.css @@ -97,7 +97,7 @@ } .hero-lead { - max-width: 610px; + max-width: 590px; margin-bottom: 30px; color: var(--ink-soft); font-size: 18px; @@ -138,157 +138,69 @@ } .hero-platforms li { - padding: 4px 8px; + display: grid; + width: 36px; + height: 36px; + place-items: center; border: 1px solid var(--line); - border-radius: 7px; - background: rgba(255, 255, 255, 0.65); + border-radius: 10px; + background: rgba(255, 255, 255, 0.78); + box-shadow: 0 7px 18px rgba(55, 35, 63, 0.055); } +.hero-platforms .platform-glyph { + width: 20px; + height: 20px; +} + +.platform-glyph[data-platform="android"] { color: #2fbf71; } +.platform-glyph[data-platform="ios"] { color: #201c23; } +.platform-glyph[data-platform="macos"] { color: #1687f8; } +.platform-glyph[data-platform="windows"] { color: #008de5; } + .hero-art-reveal { min-width: 0; } -.trust-section { +.hero-app-preview { position: relative; - z-index: 3; - margin-top: -32px; + width: min(112%, 850px); + margin: 0 0 0 -3%; + isolation: isolate; } -.trust-grid { - display: grid; - grid-template-columns: repeat(3, 1fr); - overflow: hidden; - border: 1px solid var(--line); - border-radius: 23px; - background: rgba(255, 255, 255, 0.94); - box-shadow: var(--shadow-lg); - backdrop-filter: blur(12px); +.hero-app-preview::before { + position: absolute; + z-index: -1; + inset: 14% 8% 8% 10%; + border-radius: 48%; + background: rgba(168, 85, 247, 0.2); + filter: blur(70px); + content: ""; } -.trust-item { - display: flex; - min-height: 124px; - align-items: center; - gap: 19px; - padding: 24px 28px; -} - -.trust-item + .trust-item { - border-left: 1px solid var(--line); -} - -.trust-number { - color: var(--brand-500); - font-family: var(--font-mono); - font-size: 11px; - font-weight: 800; -} - -.trust-item strong { +.hero-app-preview-image { display: block; - margin-bottom: 3px; - font-family: var(--font-display); - font-size: 18px; - letter-spacing: -0.025em; + width: 100%; + height: auto; + filter: drop-shadow(0 28px 42px rgba(36, 24, 42, 0.2)); } -.trust-item p { - margin: 0; - color: var(--ink-muted); - font-size: 13px; - line-height: 1.45; +.simple-section { + padding: 124px 0; } -.word-stream { - overflow: hidden; - padding: 92px 0 28px; - color: #ebe5ee; - font-family: var(--font-display); - font-size: clamp(3.5rem, 7vw, 7.6rem); - font-weight: 800; - letter-spacing: -0.055em; - line-height: 1; - white-space: nowrap; -} - -.word-stream > div { - display: flex; - width: max-content; - align-items: center; - gap: 35px; - animation: word-stream 36s linear infinite; -} - -.word-stream i { - color: var(--brand-300); - font-size: 0.18em; - font-style: normal; -} - -.section { - position: relative; - padding: 132px 0; -} - -.section-heading { - margin-bottom: 64px; -} - -.section-heading h2, -.privacy-intro h2, -.network-copy h2, -.platforms-copy h2, -.final-cta h2, -.approval-copy h2 { - margin-bottom: 20px; - font-size: clamp(2.7rem, 4.4vw, 4.8rem); - font-weight: 740; - letter-spacing: -0.06em; - line-height: 1.02; -} - -.section-heading p, -.section-lead { - color: var(--ink-soft); - font-size: 17px; - line-height: 1.72; -} - -.section-heading-centered { - max-width: 810px; - margin-right: auto; - margin-left: auto; - text-align: center; -} - -.section-heading-centered p { - max-width: 620px; - margin-right: auto; - margin-bottom: 0; - margin-left: auto; -} - -.section-heading-split { - display: grid; - grid-template-columns: 1.1fr 0.72fr; - align-items: end; - gap: 90px; -} - -.section-heading-split h2 { - margin-bottom: 0; -} - -.section-heading-split p { - margin-bottom: 6px; +.simple-heading { + max-width: 760px; + margin-bottom: 58px; } .kicker { display: inline-block; - margin-bottom: 18px; + margin-bottom: 17px; color: var(--brand-600); font-family: var(--font-mono); - font-size: 11px; + font-size: 10px; font-weight: 800; letter-spacing: 0.13em; } @@ -297,405 +209,150 @@ color: #d89bff; } -.flow-section { - padding-top: 105px; +.simple-heading h2, +.trust-summary-copy h2 { + margin-bottom: 18px; + font-size: clamp(2.6rem, 4.2vw, 4.6rem); + font-weight: 740; + letter-spacing: -0.06em; + line-height: 1.02; } -.invitation-section { - overflow: hidden; - background: var(--paper-warm); -} - -.approval-section { - padding: 150px 0; -} - -.approval-layout { - display: grid; - grid-template-columns: minmax(0, 0.86fr) minmax(480px, 1.14fr); - align-items: center; - gap: 100px; -} - -.approval-copy h2 { - max-width: 620px; -} - -.approval-copy .section-lead { - max-width: 570px; - margin-bottom: 27px; -} - -.check-list { - display: grid; - gap: 13px; - margin: 0 0 25px; - padding: 0; - list-style: none; -} - -.check-list li { - display: flex; - align-items: center; - gap: 11px; - color: #3c3540; - font-size: 14px; - font-weight: 600; -} - -.check-list svg { - width: 20px; - height: 20px; - padding: 4px; - border-radius: 50%; - background: var(--brand-100); - color: var(--brand-600); - stroke-width: 2.5; -} - -.approval-note { - max-width: 555px; +.simple-heading p { + max-width: 650px; margin: 0; - padding: 15px 17px; - border: 1px solid #eadff0; - border-radius: 12px; - background: #faf7fb; - color: var(--ink-muted); - font-size: 12px; - line-height: 1.55; + color: var(--ink-soft); + font-size: 17px; + line-height: 1.7; } -.approval-demo-wrap { - position: relative; -} - -.demo-hint { - position: absolute; - right: 22px; - bottom: -45px; - display: inline-flex; - align-items: center; - gap: 7px; - color: var(--brand-600); - font-family: var(--font-mono); - font-size: 10px; - font-weight: 800; - letter-spacing: 0.07em; - transform: rotate(-2deg); -} - -.demo-hint svg { - width: 15px; -} - -.privacy-principles-section { - position: relative; - overflow: hidden; - padding: 145px 0 135px; - background: - radial-gradient(circle at 90% 8%, rgba(168, 85, 247, 0.18), transparent 25%), - radial-gradient(circle at 5% 90%, rgba(124, 42, 239, 0.12), transparent 25%), - var(--dark); - color: white; -} - -.privacy-principles-section::after { - position: absolute; - inset: 0; - background-image: radial-gradient(rgba(255, 255, 255, 0.12) 0.7px, transparent 0.7px); - background-size: 22px 22px; - content: ""; - opacity: 0.13; - pointer-events: none; -} - -.privacy-principles-section .page-shell { - position: relative; - z-index: 1; -} - -.privacy-intro { - max-width: 890px; - margin-bottom: 65px; -} - -.privacy-intro h2 { - max-width: 840px; -} - -.privacy-intro > p { - max-width: 700px; - margin-bottom: 0; - color: #bdb4c2; - font-size: 18px; - line-height: 1.72; -} - -.privacy-point-grid { +.simple-steps { display: grid; - grid-template-columns: repeat(4, 1fr); - gap: 12px; + grid-template-columns: repeat(3, 1fr); + border-top: 1px solid var(--line); + border-bottom: 1px solid var(--line); } -.privacy-point { - min-height: 275px; - padding: 24px; - border: 1px solid var(--dark-line); - border-radius: 20px; - background: rgba(255, 255, 255, 0.035); - transition: border-color 200ms ease, transform 200ms ease, background 200ms ease; +.simple-step { + min-height: 235px; + padding: 30px 30px 36px; } -.privacy-point:hover { - transform: translateY(-5px); - border-color: rgba(192, 132, 252, 0.45); - background: rgba(255, 255, 255, 0.055); +.simple-step + .simple-step { + border-left: 1px solid var(--line); } -.privacy-point-top { +.simple-step-top { display: flex; align-items: center; justify-content: space-between; - margin-bottom: 43px; + margin-bottom: 46px; } -.privacy-point-top > span { - display: grid; - width: 44px; - height: 44px; - place-items: center; - border: 1px solid rgba(192, 132, 252, 0.28); - border-radius: 12px; - background: rgba(168, 85, 247, 0.1); - color: var(--brand-400); -} - -.privacy-point-top svg { - width: 22px; -} - -.privacy-point-top small { - color: #706775; +.simple-step-top span { + color: var(--brand-600); font-family: var(--font-mono); - font-size: 10px; + font-size: 11px; + font-weight: 800; } -.privacy-point h3 { +.simple-step-top svg { + width: 24px; + height: 24px; + color: var(--brand-500); +} + +.simple-step h3 { margin-bottom: 10px; - font-size: 19px; - letter-spacing: -0.025em; + font-size: 22px; + letter-spacing: -0.035em; } -.privacy-point p { - margin-bottom: 0; - color: #a99fac; - font-size: 13px; +.simple-step p { + max-width: 310px; + margin: 0; + color: var(--ink-muted); + font-size: 14px; line-height: 1.65; } -.privacy-policy-link { - display: flex; +.trust-summary-section { + padding: 112px 0; + background: #171319; + color: white; +} + +.trust-summary { + display: grid; + grid-template-columns: minmax(0, 0.82fr) minmax(0, 1.18fr); + align-items: start; + gap: 100px; +} + +.trust-summary-copy { + max-width: 520px; +} + +.trust-summary-copy p { + margin-bottom: 28px; + color: #b7adb9; + font-size: 16px; + line-height: 1.72; +} + +.simple-text-link { + display: inline-flex; align-items: center; - justify-content: space-between; - gap: 30px; - margin-top: 38px; - padding-top: 27px; + gap: 9px; + color: #ddaaff; + font-size: 14px; + font-weight: 720; +} + +.simple-text-link svg { + width: 17px; +} + +.simple-text-link:hover { + color: white; +} + +.trust-summary-list { border-top: 1px solid var(--dark-line); } -.privacy-policy-link p { +.trust-summary-item { + display: grid; + grid-template-columns: 44px 1fr; + gap: 18px; + padding: 24px 0; + border-bottom: 1px solid var(--dark-line); +} + +.trust-summary-item > span { + display: grid; + width: 42px; + height: 42px; + place-items: center; + border: 1px solid rgba(192, 132, 252, 0.24); + border-radius: 12px; + color: var(--brand-400); +} + +.trust-summary-item svg { + width: 21px; +} + +.trust-summary-item h3 { + margin-bottom: 6px; + font-size: 18px; + letter-spacing: -0.025em; +} + +.trust-summary-item p { + max-width: 530px; margin: 0; color: #a99fac; font-size: 13px; + line-height: 1.62; } - -.privacy-policy-link a { - display: inline-flex; - align-items: center; - gap: 10px; - color: #dca7ff; - font-size: 14px; - font-weight: 750; -} - -.privacy-policy-link svg { - width: 18px; - transition: transform 180ms ease; -} - -.privacy-policy-link a:hover svg { - transform: translateX(4px); -} - -.network-section { - padding: 150px 0; - background: #0f0c11; - color: white; -} - -.network-layout { - display: grid; - grid-template-columns: minmax(0, 0.78fr) minmax(580px, 1.22fr); - align-items: center; - gap: 75px; -} - -.network-copy h2 { - font-size: clamp(2.6rem, 4vw, 4.2rem); -} - -.network-copy > p { - margin-bottom: 35px; - color: #aaa0ae; - font-size: 16px; - line-height: 1.75; -} - -.network-copy blockquote { - position: relative; - margin: 0; - padding: 20px 0 20px 25px; - border-left: 2px solid var(--brand-500); - color: #f0e9f3; - font-family: var(--font-display); - font-size: 20px; - font-weight: 630; - line-height: 1.45; -} - -.network-copy blockquote span { - position: absolute; - top: -14px; - left: 12px; - color: var(--brand-500); - font-family: Georgia, serif; - font-size: 44px; - opacity: 0.55; -} - -.platforms-section { - overflow: hidden; - padding: 155px 0; -} - -.platforms-layout { - display: grid; - grid-template-columns: minmax(0, 0.86fr) minmax(520px, 1.14fr); - align-items: center; - gap: 75px; -} - -.platforms-copy .section-lead { - max-width: 570px; - margin-bottom: 29px; -} - -.platform-feature-list { - display: flex; - flex-wrap: wrap; - gap: 8px; -} - -.platform-feature-list span { - display: inline-flex; - align-items: center; - gap: 8px; - padding: 8px 11px; - border: 1px solid var(--line); - border-radius: 9px; - background: white; - color: var(--ink-soft); - font-size: 12px; - font-weight: 620; -} - -.platform-feature-list svg { - width: 16px; - color: var(--brand-600); -} - -.orbit-wrap { - min-width: 0; -} - -.final-cta-section { - padding: 0 0 40px; -} - -.final-cta { - position: relative; - overflow: hidden; - padding: 100px 50px; - border-radius: 31px; - background: - linear-gradient(125deg, rgba(255, 255, 255, 0.06), transparent 40%), - linear-gradient(135deg, #25172f, #171019 55%, #28143a); - color: white; - text-align: center; -} - -.final-cta::after { - position: absolute; - inset: 0; - border: 1px solid rgba(255, 255, 255, 0.1); - border-radius: inherit; - content: ""; - pointer-events: none; -} - -.final-cta h2 { - position: relative; - z-index: 1; - max-width: 850px; - margin-right: auto; - margin-left: auto; - font-size: clamp(2.8rem, 5vw, 5.4rem); -} - -.final-cta > p { - position: relative; - z-index: 1; - max-width: 600px; - margin: 0 auto 31px; - color: #bfb4c4; - font-size: 16px; -} - -.final-cta > .kicker { - position: relative; - z-index: 1; -} - -.final-cta-actions { - position: relative; - z-index: 1; - display: flex; - flex-wrap: wrap; - justify-content: center; - gap: 10px; -} - -.final-cta-orb { - position: absolute; - border-radius: 50%; - background: var(--brand-500); - filter: blur(90px); - opacity: 0.18; -} - -.final-cta-orb-one { - top: -140px; - left: -70px; - width: 380px; - height: 380px; - animation: cta-orb 12s ease-in-out infinite alternate; -} - -.final-cta-orb-two { - right: -80px; - bottom: -200px; - width: 430px; - height: 430px; - animation: cta-orb 15s ease-in-out -4s infinite alternate-reverse; -} - diff --git a/docs/app/layout.tsx b/docs/app/layout.tsx index 443c678..93fe3aa 100644 --- a/docs/app/layout.tsx +++ b/docs/app/layout.tsx @@ -7,16 +7,8 @@ import "../components/header.css"; import "./home.css"; import "./footer.css"; import "./privacy/privacy-document.css"; -import "../components/hero-scene.css"; -import "../components/hero-device.css"; -import "../components/transfer-flow.css"; -import "../components/invitation-scene.css"; -import "../components/approval-scene.css"; -import "../components/network-scene.css"; -import "../components/platform-scene.css"; import "./responsive.css"; import "./privacy/privacy-responsive.css"; -import "../components/illustration-motion.css"; export const metadata: Metadata = { title: { diff --git a/docs/app/page.tsx b/docs/app/page.tsx index a5eb2ef..93ab9b2 100644 --- a/docs/app/page.tsx +++ b/docs/app/page.tsx @@ -1,48 +1,54 @@ +import Image from "next/image"; import Link from "next/link"; -import { ApprovalDemo } from "@/components/approval-demo"; -import { HeroIllustration } from "@/components/hero-illustration"; import { Icon, type IconName } from "@/components/icons"; -import { InvitationShowcase } from "@/components/invitation-showcase"; -import { NetworkIllustration } from "@/components/network-illustration"; -import { PlatformOrbit } from "@/components/platform-orbit"; +import { PlatformIcon, supportedPlatforms } from "@/components/platform-icon"; import { Reveal } from "@/components/reveal"; -import { TransferFlow } from "@/components/transfer-flow"; -const trustItems = [ - { value: "No account", detail: "Open the app and start sharing" }, - { value: "No hosted copy", detail: "Your transfer is not parked in our cloud" }, - { value: "No silent overwrite", detail: "Existing files stay untouched" }, -]; - -const privacyPoints: Array<{ +const steps: Array<{ icon: IconName; number: string; title: string; text: string; }> = [ { - icon: "lock", + icon: "folder", number: "01", - title: "Encrypted in transit", - text: "Each connection is authenticated and end-to-end encrypted, including through a relay.", + title: "Choose what to send", + text: "Pick files, a batch, or a complete folder. VniDrop preserves the folder structure.", + }, + { + icon: "qr", + number: "02", + title: "Share an invitation", + text: "Introduce the devices with a QR code, NFC tap, or portable .vnd invitation.", }, { icon: "shield", - number: "02", - title: "Approval by default", - text: "An invitation helps devices meet. It is not automatic permission to download.", + number: "03", + title: "Approve and transfer", + text: "The receiver asks first. Once approved, the files move over an authenticated encrypted connection.", + }, +]; + +const trustItems: Array<{ + icon: IconName; + title: string; + text: string; +}> = [ + { + icon: "devices", + title: "Direct when possible", + text: "Devices connect directly when they can. An encrypted relay forwards traffic when they cannot.", + }, + { + icon: "lock", + title: "No hosted copy", + text: "A relay is a route, not storage. Your transfer is never turned into a cloud download.", }, { icon: "verified", - number: "03", title: "Verified on arrival", - text: "Content addressing checks that incoming bytes match exactly what was offered.", - }, - { - icon: "stop", - number: "04", - title: "Revocable access", - text: "Stop a share at any time and the invitation can no longer be used.", + text: "Content addressing checks that the received bytes match exactly what you sent.", }, ]; @@ -67,224 +73,95 @@ export default function HomePage() { between devices.
- Send files and folders directly when possible, with an end-to-end encrypted relay - when needed. No account. No hosted transfer copy. You decide who receives them. + Send files and folders across your devices—direct when possible, private by design, + and always under your control.
{item.detail}
-- VniDrop keeps the transfer understandable from first selection to final verified file. + Choose the files, introduce the devices, and approve the handoff. VniDrop handles the + secure route.
- The invitation is small enough to scan, tap, or send. Your files stay where they are - until a receiver connects and you allow the transfer. -
-- Every new receiver knocks by default. Approve people you recognize, refuse the rest, - and follow progress for each device. -
-- Need an open handoff? An optional “Anyone with this transfer” mode is available for - non-sensitive files. -
-- VniDrop coordinates a secure handoff. It does not turn your transfer into a hosted - download sitting on someone else’s storage. -
-{point.text}
- +{step.text}
+Diagnostics are optional and exclude invitations, file paths, and transfer contents.
- - Read the full privacy policy ++ The transfer happens between devices. These are the details that matter when you + decide what to share and who can receive it. +
+ + Read the privacy policy- VniDrop tries to connect devices directly—even across home routers and mobile - networks. If that path is not available, a relay forwards the same encrypted - connection without becoming a file store. -
-- “ - The relay can move the envelope. It cannot open it. --
- Android, iOS, macOS, Windows, and Linux share one clear transfer experience while each - platform keeps control of its own file picker and save destination. -
-- VniDrop is in early development. Explore the code, build the app, and help shape a - more direct way to share. -
-{item.text}
+- This policy explains what moves between devices, what stays local, and what is sent - only when you choose to share diagnostics or a bug report. -
-+ This policy explains what moves between devices, what stays local, and what is sent + only when you choose to share diagnostics or a bug report. +
+Effective July 16, 2026 · Version 1.0
- VniDrop has no user accounts and does not upload your transfer to a VniDrop file - store. Files travel over an authenticated, end-to-end encrypted connection. - Product diagnostics are opt-in; a bug report is sent only when you submit one. -
-+ VniDrop has no user accounts and does not upload your transfer to a VniDrop file + store. Files travel over an authenticated, end-to-end encrypted connection. + Product diagnostics are opt-in; a bug report is sent only when you submit one. +
This policy covers the official VniDrop website, the VniDrop applications for @@ -132,7 +76,6 @@ export default function PrivacyPage() {
@@ -159,7 +102,6 @@ export default function PrivacyPage() { encrypted transfer contents.
Approval is required by default. If the sender selects “Anyone with this transfer,”
anyone holding the invitation may receive the files until sharing stops.
@@ -168,7 +110,6 @@ export default function PrivacyPage() {
VniDrop stores the information needed to operate the app locally, including:
@@ -217,7 +157,6 @@ export default function PrivacyPage() {
This website is a static product site. It does not provide an account, contact form,
@@ -235,14 +174,25 @@ export default function PrivacyPage() {
Choose what to send and where received files are saved. Scan a QR invitation when you choose that receive method. Read or write an invitation through a compatible NFC tag. Connect peers and alert you to background receiver requests.
VniDrop requests a platform permission only for the related feature. On Android, QR
scanning may be provided through Google Play services Code Scanner. Platform-level
@@ -251,54 +201,100 @@ export default function PrivacyPage() {
Device discovery, connection establishment, and encrypted relay fallback. Relays process connection metadata but cannot decrypt transfer contents. The project’s diagnostics design uses Cloudflare Workers, D1, and R2. Cloudflare also processes source IPs for request delivery and abuse controls. May provide the QR code scanner on supported Android devices when you choose to scan an invitation. Hosts the source repository, issue tracker, and external pages linked from this site. GitHub’s own privacy terms apply after you follow those links.
- Provider policies: {" "}
- Iroh, {" "}
- Cloudflare, {" "}
- Google, and {" "}
- GitHub.
+ Provider policies:{" "}
+
+ Iroh
+
+ ,{" "}
+
+ Cloudflare
+
+ ,{" "}
+
+ Google
+
+ , and{" "}
+
+ GitHub
+
+ .
Operational backups, provider logs, and deletion backlogs may persist briefly beyond
@@ -309,14 +305,22 @@ export default function PrivacyPage() {
Depending on where you live, privacy law may provide rights to access, correct,
@@ -328,7 +332,6 @@ export default function PrivacyPage() {
VniDrop uses authenticated end-to-end encrypted connections, content verification,
@@ -338,13 +341,19 @@ export default function PrivacyPage() {
updated, and stop sharing when a transfer is finished.
- Please report a suspected vulnerability through the private process in the {" "}
- VniDrop security policy, not in a public issue.
+ Please report a suspected vulnerability through the private process in the{" "}
+
+ VniDrop security policy
+
+ , not in a public issue.
VniDrop is in early development. Features and data practices may change. When this
@@ -355,7 +364,6 @@ export default function PrivacyPage() {
VniDrop is currently maintained as an open-source project and does not yet publish a
@@ -364,13 +372,12 @@ export default function PrivacyPage() {
credentials, or other sensitive information in a public issue.
Information kept on your device
@@ -187,7 +128,6 @@ export default function PrivacyPage() {
Optional diagnostics and bug reports
Automatic product diagnostics
The VniDrop website
Device permissions
-
+
Infrastructure and external services
-
Retention and deletion
-
+
+
+
+
+ Data
+ Typical retention
+
+
+ Transfer history and settings
+ Until you delete them, clear app data, or uninstall
+
+
+ Pending local crash reports
+ Up to 30 days and 20 reports; deleted when diagnostics is disabled
+
+
+ Server diagnostics and bug reports
+ The current project configuration is 90 days, with scheduled deletion
+
+
+
+ Downloaded files
+ Until you delete them through your operating system
+ Your choices and rights
Security
Changes to this policy
Contact