feat(privacy): migrate privacy policies to product subdomains
Consolidate privacy policies per-subdomain: - Migrate Gaze and Life and Lineage privacy policies verbatim from the legacy /privacy-policy/* routes to their subdomain paths (gaze.freno.me/privacy, lineage.freno.me/privacy), and replace the old routes with 308 permanent redirects to preserve SEO equity and stable link resolution. - Add net-new privacy policies for the InputHalo and Nessa subdomains. - Update the contact page link to point at the Lineage subdomain privacy policy.
This commit is contained in:
@@ -331,7 +331,7 @@ export default function ContactPage() {
|
|||||||
<div class="pb-2">
|
<div class="pb-2">
|
||||||
You can find the entire privacy policy{" "}
|
You can find the entire privacy policy{" "}
|
||||||
<A
|
<A
|
||||||
href="/privacy-policy/life-and-lineage"
|
href="https://lineage.freno.me/privacy"
|
||||||
class="text-blue underline-offset-4 hover:underline"
|
class="text-blue underline-offset-4 hover:underline"
|
||||||
>
|
>
|
||||||
here
|
here
|
||||||
|
|||||||
125
src/routes/gaze/privacy.tsx
Normal file
125
src/routes/gaze/privacy.tsx
Normal file
@@ -0,0 +1,125 @@
|
|||||||
|
/**
|
||||||
|
* Gaze privacy policy — `gaze.freno.me/privacy` (task 10).
|
||||||
|
*
|
||||||
|
* Migrated verbatim from the legacy `src/routes/privacy-policy/gaze.tsx`
|
||||||
|
* route so there is zero content loss; the old route now 308-redirects here
|
||||||
|
* (see `src/routes/privacy-policy/gaze.tsx`). PageHead is site-aware (task 02)
|
||||||
|
* so the Gaze `titleSuffix` (` | Gaze`), canonical
|
||||||
|
* (`https://gaze.freno.me/privacy`), and OG image derive automatically — we
|
||||||
|
* only pass the base title.
|
||||||
|
*
|
||||||
|
* Internal links use the **public subdomain-relative paths** (`/contact`),
|
||||||
|
* which vercel.json rewrites to the internal `/gaze/contact` route prefix
|
||||||
|
* while leaving the browser URL clean — consistent with nav-config.ts and
|
||||||
|
* the canonical rule in page-head-meta.ts.
|
||||||
|
*/
|
||||||
|
import { A } from "@solidjs/router";
|
||||||
|
import { PageHead } from "~/components/PageHead";
|
||||||
|
|
||||||
|
export default function GazePrivacyPolicy() {
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<PageHead
|
||||||
|
title="Privacy Policy"
|
||||||
|
description="Privacy policy for Gaze, a macOS eye health reminder app."
|
||||||
|
/>
|
||||||
|
<div class="min-h-screen px-[8vw] py-[10vh]">
|
||||||
|
<div class="py-4 text-xl">Gaze's Privacy Policy</div>
|
||||||
|
<div class="py-2">Last Updated: February 9, 2026</div>
|
||||||
|
<div class="py-2">
|
||||||
|
Welcome to Gaze ('We', 'Us', 'Our').
|
||||||
|
Your privacy is important to us. This privacy policy will help you
|
||||||
|
understand our policies and procedures related to the collection, use,
|
||||||
|
and storage of personal information from our users.
|
||||||
|
</div>
|
||||||
|
<ol>
|
||||||
|
<div class="py-2">
|
||||||
|
<div class="pb-2 text-lg">
|
||||||
|
<span class="-ml-4 pr-2">1.</span> Personal Information
|
||||||
|
</div>
|
||||||
|
<div class="pl-4">
|
||||||
|
<div class="pb-2">
|
||||||
|
<div class="-ml-6">(a) Collection of Personal Data:</div> Gaze
|
||||||
|
is designed with privacy as a core principle. We currently do
|
||||||
|
not collect, store, or share any personal information from our
|
||||||
|
users. The app runs entirely on your device and does not require
|
||||||
|
any account creation or data transmission to external servers.
|
||||||
|
</div>
|
||||||
|
<div class="pb-2">
|
||||||
|
<div class="-ml-6">(b) Future Data Collection:</div> We may in
|
||||||
|
the future implement optional features such as analytics or
|
||||||
|
crash reporting. If we do, we will clearly inform users through
|
||||||
|
a privacy policy update and obtain explicit consent before
|
||||||
|
collecting any data.
|
||||||
|
</div>
|
||||||
|
<div class="pb-2">
|
||||||
|
<div class="-ml-6">(c) Data Removal:</div> Since we do not
|
||||||
|
collect any personal information, there is no data to remove. If
|
||||||
|
you have any concerns about our practices, please contact{" "}
|
||||||
|
<A href="/contact" class="text-blue hover-underline-animation">
|
||||||
|
here
|
||||||
|
</A>
|
||||||
|
.
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="py-2">
|
||||||
|
<div class="pb-2 text-lg">
|
||||||
|
<span class="-ml-4 pr-2">2.</span> Third-Party Access
|
||||||
|
</div>
|
||||||
|
<div class="pb-2 pl-4">
|
||||||
|
<div class="-ml-6">(a) No Third-Party Sharing:</div> We do not
|
||||||
|
share, sell, or transfer any personal information to third
|
||||||
|
parties. Currently, Gaze does not utilize any third-party services
|
||||||
|
that would collect user data. Any future third-party services we
|
||||||
|
may use will be transparently disclosed in our privacy policy.
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="py-2">
|
||||||
|
<div class="pb-2 text-lg">
|
||||||
|
<span class="-ml-4 pr-2">3.</span> Security
|
||||||
|
</div>
|
||||||
|
<div class="pb-2 pl-4">
|
||||||
|
<div class="-ml-6">(a) Data Protection:</div> Because Gaze does
|
||||||
|
not collect or store any personal information, there is minimal
|
||||||
|
data security risk. The app runs locally on your device using
|
||||||
|
standard macOS security practices. Any configuration data stored
|
||||||
|
locally on your device is encrypted using system-provided
|
||||||
|
mechanisms.
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="py-2">
|
||||||
|
<div class="pb-2 text-lg">
|
||||||
|
<span class="-ml-4 pr-2">4.</span> Changes to the Privacy Policy
|
||||||
|
</div>
|
||||||
|
<div class="pb-2 pl-4">
|
||||||
|
<div class="-ml-6">(a) Updates:</div> We may update this privacy
|
||||||
|
policy periodically, especially if we introduce new features that
|
||||||
|
involve data collection. Any changes to this privacy policy will
|
||||||
|
be posted on this page. We encourage users to review this policy
|
||||||
|
regularly to stay informed about how we protect their information.
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="py-2">
|
||||||
|
<div class="pb-2 text-lg">
|
||||||
|
<span class="-ml-4 pr-2">5.</span> Contact Us
|
||||||
|
</div>
|
||||||
|
<div class="pb-2 pl-4">
|
||||||
|
<div class="-ml-6">(a) Reaching Out:</div> If there are any
|
||||||
|
questions or comments regarding this privacy policy, you can
|
||||||
|
contact us{" "}
|
||||||
|
<A href="/contact" class="text-blue hover-underline-animation">
|
||||||
|
here
|
||||||
|
</A>
|
||||||
|
.
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</ol>
|
||||||
|
</div>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
}
|
||||||
159
src/routes/inputhalo/privacy.tsx
Normal file
159
src/routes/inputhalo/privacy.tsx
Normal file
@@ -0,0 +1,159 @@
|
|||||||
|
/**
|
||||||
|
* InputHalo privacy policy — `inputhalo.freno.me/privacy` (task 10).
|
||||||
|
*
|
||||||
|
* Net-new privacy policy for the InputHalo subdomain. InputHalo is a macOS
|
||||||
|
* menu bar application (`LSUIElement: true`,
|
||||||
|
* `LSApplicationCategoryType: public.app-category.productivity`) — a
|
||||||
|
* productivity utility that lives in the system menu bar. Following the task
|
||||||
|
* notes, Gaze's privacy policy is the template for macOS menu bar apps
|
||||||
|
* (both are local-only menu bar utilities), so this policy mirrors Gaze's
|
||||||
|
* structure and language while describing InputHalo's own practices.
|
||||||
|
*
|
||||||
|
* Data practices stated here reflect InputHalo as shipped:
|
||||||
|
* - No account is required and none is created.
|
||||||
|
* - The app runs entirely on your device; no personal information is
|
||||||
|
* collected, stored, or transmitted to external servers.
|
||||||
|
* - Settings and any cached state are stored locally using standard
|
||||||
|
* macOS mechanisms and are never sent off-device.
|
||||||
|
*
|
||||||
|
* PageHead is site-aware (task 02): only the base title is supplied; the
|
||||||
|
* ` | InputHalo` suffix, `https://inputhalo.freno.me/privacy` canonical, and
|
||||||
|
* OG image are derived automatically. Internal links use public
|
||||||
|
* subdomain-relative paths (`/contact`) consistent with nav-config.ts and
|
||||||
|
* page-head-meta.ts.
|
||||||
|
*/
|
||||||
|
import { A } from "@solidjs/router";
|
||||||
|
import { PageHead } from "~/components/PageHead";
|
||||||
|
|
||||||
|
export default function InputHaloPrivacyPolicy() {
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<PageHead
|
||||||
|
title="Privacy Policy"
|
||||||
|
description="Privacy policy for InputHalo, a macOS menu bar productivity app."
|
||||||
|
/>
|
||||||
|
<div class="min-h-screen px-[8vw] py-[10vh]">
|
||||||
|
<div class="py-4 text-xl">InputHalo's Privacy Policy</div>
|
||||||
|
<div class="py-2">Last Updated: February 9, 2026</div>
|
||||||
|
<div class="py-2">
|
||||||
|
Welcome to InputHalo ('We', 'Us',
|
||||||
|
'Our'). Your privacy is important to us. This privacy
|
||||||
|
policy will help you understand our policies and procedures related
|
||||||
|
to the collection, use, and storage of personal information from our
|
||||||
|
users.
|
||||||
|
</div>
|
||||||
|
<ol>
|
||||||
|
<div class="py-2">
|
||||||
|
<div class="pb-2 text-lg">
|
||||||
|
<span class="-ml-4 pr-2">1.</span> Personal Information
|
||||||
|
</div>
|
||||||
|
<div class="pl-4">
|
||||||
|
<div class="pb-2">
|
||||||
|
<div class="-ml-6">(a) Collection of Personal Data:</div>{" "}
|
||||||
|
InputHalo is designed with privacy as a core principle. We
|
||||||
|
currently do not collect, store, or share any personal
|
||||||
|
information from our users. The app runs entirely on your
|
||||||
|
device as a menu bar utility and does not require any account
|
||||||
|
creation or data transmission to external servers.
|
||||||
|
</div>
|
||||||
|
<div class="pb-2">
|
||||||
|
<div class="-ml-6">(b) Local-Only Settings:</div> Any
|
||||||
|
preferences, configuration, or cached state InputHalo maintains
|
||||||
|
is stored locally on your device using standard macOS
|
||||||
|
mechanisms (such as the user defaults system). This data never
|
||||||
|
leaves your device and is not transmitted to us or to any
|
||||||
|
third-party service.
|
||||||
|
</div>
|
||||||
|
<div class="pb-2">
|
||||||
|
<div class="-ml-6">(c) Future Data Collection:</div> We may in
|
||||||
|
the future implement optional features such as usage analytics
|
||||||
|
or crash reporting. If we do, we will clearly inform users
|
||||||
|
through a privacy policy update and obtain explicit consent
|
||||||
|
before collecting any data. Until then, no data of any kind is
|
||||||
|
transmitted off your device.
|
||||||
|
</div>
|
||||||
|
<div class="pb-2">
|
||||||
|
<div class="-ml-6">(d) Data Removal:</div> Since we do not
|
||||||
|
collect any personal information, there is no server-side data
|
||||||
|
to remove. To clear InputHalo's local data at any time, you
|
||||||
|
can remove the app from your Mac, which deletes the locally
|
||||||
|
stored settings alongside it. If you have any concerns about our
|
||||||
|
practices, please contact{" "}
|
||||||
|
<A href="/contact" class="text-blue hover-underline-animation">
|
||||||
|
here
|
||||||
|
</A>
|
||||||
|
.
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="py-2">
|
||||||
|
<div class="pb-2 text-lg">
|
||||||
|
<span class="-ml-4 pr-2">2.</span> Third-Party Access
|
||||||
|
</div>
|
||||||
|
<div class="pl-4">
|
||||||
|
<div class="pb-2">
|
||||||
|
<div class="-ml-6">(a) No Third-Party Sharing:</div> We do not
|
||||||
|
share, sell, or transfer any personal information to third
|
||||||
|
parties. Currently, InputHalo does not utilize any third-party
|
||||||
|
services that would collect user data. Any future third-party
|
||||||
|
services we may use will be transparently disclosed in our
|
||||||
|
privacy policy.
|
||||||
|
</div>
|
||||||
|
<div class="pb-2">
|
||||||
|
<div class="-ml-6">(b) No Network Telemetry:</div> InputHalo
|
||||||
|
does not phone home. The app does not make network requests to
|
||||||
|
our servers or to any analytics, advertising, or tracking
|
||||||
|
endpoint as part of its normal operation. The only network
|
||||||
|
activity the app performs is whatever you explicitly initiate
|
||||||
|
through its features.
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="py-2">
|
||||||
|
<div class="pb-2 text-lg">
|
||||||
|
<span class="-ml-4 pr-2">3.</span> Security
|
||||||
|
</div>
|
||||||
|
<div class="pb-2 pl-4">
|
||||||
|
<div class="-ml-6">(a) Data Protection:</div> Because InputHalo
|
||||||
|
does not collect or store any personal information, there is
|
||||||
|
minimal data security risk. The app runs locally on your device
|
||||||
|
using standard macOS security practices. Any configuration data
|
||||||
|
stored locally on your device is managed using system-provided
|
||||||
|
mechanisms and is not transmitted off your device.
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="py-2">
|
||||||
|
<div class="pb-2 text-lg">
|
||||||
|
<span class="-ml-4 pr-2">4.</span> Changes to the Privacy Policy
|
||||||
|
</div>
|
||||||
|
<div class="pb-2 pl-4">
|
||||||
|
<div class="-ml-6">(a) Updates:</div> We may update this privacy
|
||||||
|
policy periodically, especially if we introduce new features that
|
||||||
|
involve data collection. Any changes to this privacy policy will
|
||||||
|
be posted on this page. We encourage users to review this policy
|
||||||
|
regularly to stay informed about how we protect their information.
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="py-2">
|
||||||
|
<div class="pb-2 text-lg">
|
||||||
|
<span class="-ml-4 pr-2">5.</span> Contact Us
|
||||||
|
</div>
|
||||||
|
<div class="pb-2 pl-4">
|
||||||
|
<div class="-ml-6">(a) Reaching Out:</div> If there are any
|
||||||
|
questions or comments regarding this privacy policy, you can
|
||||||
|
contact us{" "}
|
||||||
|
<A href="/contact" class="text-blue hover-underline-animation">
|
||||||
|
here
|
||||||
|
</A>
|
||||||
|
.
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</ol>
|
||||||
|
</div>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
}
|
||||||
123
src/routes/lineage/privacy.tsx
Normal file
123
src/routes/lineage/privacy.tsx
Normal file
@@ -0,0 +1,123 @@
|
|||||||
|
/**
|
||||||
|
* Life and Lineage privacy policy — `lineage.freno.me/privacy` (task 10).
|
||||||
|
*
|
||||||
|
* Migrated verbatim from the legacy
|
||||||
|
* `src/routes/privacy-policy/life-and-lineage.tsx` route so there is zero
|
||||||
|
* content loss; the old route now 308-redirects here (see
|
||||||
|
* `src/routes/privacy-policy/life-and-lineage.tsx`). PageHead is site-aware
|
||||||
|
* (task 02) so the Lineage `titleSuffix` (` | Life and Lineage`), canonical
|
||||||
|
* (`https://lineage.freno.me/privacy`), and OG image derive automatically —
|
||||||
|
* we only pass the base title.
|
||||||
|
*
|
||||||
|
* Per task instructions, the account-deletion reference now points at the
|
||||||
|
* Lineage subdomain's deletion flow, served at the **public subdomain-relative
|
||||||
|
* path** `/deletion` (vercel.json rewrites to `/lineage/deletion`). The
|
||||||
|
* contact link similarly uses `/contact` (public subdomain path), consistent
|
||||||
|
* with nav-config.ts and the canonical rule in page-head-meta.ts.
|
||||||
|
*/
|
||||||
|
import { A } from "@solidjs/router";
|
||||||
|
import { PageHead } from "~/components/PageHead";
|
||||||
|
|
||||||
|
export default function LineagePrivacyPolicy() {
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<PageHead
|
||||||
|
title="Privacy Policy"
|
||||||
|
description="Privacy policy for Life and Lineage mobile game, outlining data collection, usage, and user rights."
|
||||||
|
/>
|
||||||
|
<div class="min-h-screen px-[8vw] py-[10vh]">
|
||||||
|
<div class="py-4 text-xl">Life and Lineage's Privacy Policy</div>
|
||||||
|
<div class="py-2">Last Updated: October 22, 2024</div>
|
||||||
|
<div class="py-2">
|
||||||
|
Welcome to Life and Lineage ('We', 'Us',
|
||||||
|
'Our'). Your privacy is important to us. This privacy policy
|
||||||
|
will help you understand our policies and procedures related to the
|
||||||
|
collection, use, and storage of personal information from our users.
|
||||||
|
</div>
|
||||||
|
<ol>
|
||||||
|
<div class="py-2">
|
||||||
|
<div class="pb-2 text-lg">
|
||||||
|
<span class="-ml-4 pr-2">1.</span> Personal Information
|
||||||
|
</div>
|
||||||
|
<div class="pl-4">
|
||||||
|
<div class="pb-2">
|
||||||
|
<div class="-ml-6">(a) Collection of Personal Data:</div> Life
|
||||||
|
and Lineage collects and stores personal data only if users opt
|
||||||
|
to use the remote saving feature. The information collected
|
||||||
|
includes email address, and if using an OAuth provider - first
|
||||||
|
name, and last name. This information is used solely for the
|
||||||
|
purpose of providing and managing the remote saving feature. It
|
||||||
|
is and never will be shared with a third party.
|
||||||
|
</div>
|
||||||
|
<div class="pb-2">
|
||||||
|
<div class="-ml-6">(b) Data Removal:</div> Users can request the
|
||||||
|
removal of all information related to them by visiting{" "}
|
||||||
|
<A
|
||||||
|
href="/deletion"
|
||||||
|
class="text-blue hover-underline-animation"
|
||||||
|
>
|
||||||
|
this page
|
||||||
|
</A>{" "}
|
||||||
|
and filling out the provided form.
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="py-2">
|
||||||
|
<div class="pb-2 text-lg">
|
||||||
|
<span class="-ml-4 pr-2">2.</span> Third-Party Access
|
||||||
|
</div>
|
||||||
|
<div class="pb-2 pl-4">
|
||||||
|
<div class="-ml-6">(a) Limited Third-Party Access:</div> We do not
|
||||||
|
share or sell user information to third parties. However, we do
|
||||||
|
utilize third-party services for crash reporting and performance
|
||||||
|
profiling. These services do not have access to personal user
|
||||||
|
information and only receive anonymized data related to app
|
||||||
|
performance and stability.
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="py-2">
|
||||||
|
<div class="pb-2 text-lg">
|
||||||
|
<span class="-ml-4 pr-2">3.</span> Security
|
||||||
|
</div>
|
||||||
|
<div class="pb-2 pl-4">
|
||||||
|
<div class="-ml-6">(a) Data Protection:</div>Life and Lineage
|
||||||
|
takes appropriate measures to protect the personal information of
|
||||||
|
users who opt for the remote saving feature. We implement
|
||||||
|
industry-standard security protocols to prevent unauthorized
|
||||||
|
access, disclosure, alteration, or destruction of user data.
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="py-2">
|
||||||
|
<div class="pb-2 text-lg">
|
||||||
|
<span class="-ml-4 pr-2">4.</span> Changes to the Privacy Policy
|
||||||
|
</div>
|
||||||
|
<div class="pb-2 pl-4">
|
||||||
|
<div class="-ml-6">(a) Updates:</div> We may update this privacy
|
||||||
|
policy periodically. Any changes to this privacy policy will be
|
||||||
|
posted on this page. We encourage users to review this policy
|
||||||
|
regularly to stay informed about how we protect their information.
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="py-2">
|
||||||
|
<div class="pb-2 text-lg">
|
||||||
|
<span class="-ml-4 pr-2">5.</span> Contact Us
|
||||||
|
</div>
|
||||||
|
<div class="pb-2 pl-4">
|
||||||
|
<div class="-ml-6">(a) Reaching Out:</div> If there are any
|
||||||
|
questions or comments regarding this privacy policy, you can
|
||||||
|
contact us{" "}
|
||||||
|
<A href="/contact" class="text-blue hover-underline-animation">
|
||||||
|
here
|
||||||
|
</A>
|
||||||
|
.
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</ol>
|
||||||
|
</div>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
}
|
||||||
192
src/routes/nessa/privacy.tsx
Normal file
192
src/routes/nessa/privacy.tsx
Normal file
@@ -0,0 +1,192 @@
|
|||||||
|
/**
|
||||||
|
* Nessa privacy policy — `nessa.freno.me/privacy` (task 10).
|
||||||
|
*
|
||||||
|
* Net-new privacy policy for the Nessa subdomain. Modeled on the Life and
|
||||||
|
* Lineage policy (the template for products with user accounts, per the task
|
||||||
|
* notes) but scoped to Nessa's real data practices:
|
||||||
|
*
|
||||||
|
* - Authentication: user accounts are managed by Clerk
|
||||||
|
* (`src/server/nessa-auth.ts` verifies Clerk session JWTs via the Clerk
|
||||||
|
* Backend JWKS endpoint). Nessa itself does not store passwords — Clerk is
|
||||||
|
* the identity provider.
|
||||||
|
* - Community content: clubs, club challenges, club posts, post likes, and
|
||||||
|
* post comments (see `src/server/api/routers/nessa-community.ts`,
|
||||||
|
* `clubMemberships`, `clubChallenges`, `clubChallengeParticipations`,
|
||||||
|
* `clubPosts`, `clubPostLikes`, `clubPostComments`).
|
||||||
|
* - Storage: the Nessa data lives in a dedicated Turso (libSQL) database
|
||||||
|
* (`NessaConnectionFactory` in `src/server/db-connections.ts`), separate
|
||||||
|
* from the freno.me main DB and the Lineage DB.
|
||||||
|
*
|
||||||
|
* PageHead is site-aware (task 02): only the base title is supplied; the
|
||||||
|
* ` | Nessa` suffix, `https://nessa.freno.me/privacy` canonical, and OG image
|
||||||
|
* are derived automatically. Internal links use public subdomain-relative
|
||||||
|
* paths (`/contact`) consistent with nav-config.ts and page-head-meta.ts.
|
||||||
|
*
|
||||||
|
* Nessa does not yet ship a dedicated account-deletion form route; per the
|
||||||
|
* task notes ("reference the deletion flow if Nessa has user accounts"),
|
||||||
|
* account/data deletion is initiated by contacting us — Clerk user records
|
||||||
|
* and the associated Nessa community content are then purged manually until a
|
||||||
|
* self-serve flow is built.
|
||||||
|
*/
|
||||||
|
import { A } from "@solidjs/router";
|
||||||
|
import { PageHead } from "~/components/PageHead";
|
||||||
|
|
||||||
|
export default function NessaPrivacyPolicy() {
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<PageHead
|
||||||
|
title="Privacy Policy"
|
||||||
|
description="Privacy policy for Nessa, a community platform for clubs, challenges, and social features."
|
||||||
|
/>
|
||||||
|
<div class="min-h-screen px-[8vw] py-[10vh]">
|
||||||
|
<div class="py-4 text-xl">Nessa's Privacy Policy</div>
|
||||||
|
<div class="py-2">Last Updated: February 9, 2026</div>
|
||||||
|
<div class="py-2">
|
||||||
|
Welcome to Nessa ('We', 'Us', 'Our').
|
||||||
|
Your privacy is important to us. This privacy policy will help you
|
||||||
|
understand our policies and procedures related to the collection, use,
|
||||||
|
and storage of personal information from our users.
|
||||||
|
</div>
|
||||||
|
<ol>
|
||||||
|
<div class="py-2">
|
||||||
|
<div class="pb-2 text-lg">
|
||||||
|
<span class="-ml-4 pr-2">1.</span> Personal Information
|
||||||
|
</div>
|
||||||
|
<div class="pl-4">
|
||||||
|
<div class="pb-2">
|
||||||
|
<div class="-ml-6">(a) Collection of Personal Data:</div> Nessa
|
||||||
|
authenticates users through Clerk, our third-party identity
|
||||||
|
provider. When you create or sign in to your Nessa account, the
|
||||||
|
information you provide to Clerk (such as your email address,
|
||||||
|
and depending on the sign-in method you choose, your name or
|
||||||
|
OAuth profile details) is processed by Clerk to establish and
|
||||||
|
maintain your account. Nessa stores only the Clerk user id
|
||||||
|
needed to associate your account with the content you create —
|
||||||
|
we do not receive or store your Clerk password.
|
||||||
|
</div>
|
||||||
|
<div class="pb-2">
|
||||||
|
<div class="-ml-6">(b) Community Content:</div> When you use
|
||||||
|
Nessa's community features — creating or joining clubs,
|
||||||
|
participating in challenges, posting, commenting, or liking
|
||||||
|
posts — the content you submit is stored in our database and
|
||||||
|
associated with your account. This includes club names,
|
||||||
|
descriptions, and rules you author, challenge progress and
|
||||||
|
completion data, and any posts, comments, or likes you create.
|
||||||
|
This content is visible to other members according to the
|
||||||
|
privacy settings of the club it belongs to.
|
||||||
|
</div>
|
||||||
|
<div class="pb-2">
|
||||||
|
<div class="-ml-6">(c) Data Storage:</div> Nessa's data is
|
||||||
|
stored in a dedicated Turso (libSQL) database that is separate
|
||||||
|
from the freno.me main database and the Life and Lineage
|
||||||
|
database. Your Nessa community content is never shared with or
|
||||||
|
accessible through those other products.
|
||||||
|
</div>
|
||||||
|
<div class="pb-2">
|
||||||
|
<div class="-ml-6">(d) Data Removal:</div> You can request the
|
||||||
|
removal of your Nessa account and all associated content by
|
||||||
|
contacting us{" "}
|
||||||
|
<A
|
||||||
|
href="/contact"
|
||||||
|
class="text-blue hover-underline-animation"
|
||||||
|
>
|
||||||
|
here
|
||||||
|
</A>
|
||||||
|
. On receipt of your request we will remove your account
|
||||||
|
record, your club memberships, your challenges and
|
||||||
|
participation data, and your posts, comments, and likes from the
|
||||||
|
Nessa database, and we will request that Clerk delete the
|
||||||
|
corresponding user record. A short grace period may apply while
|
||||||
|
the deletion is processed.
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="py-2">
|
||||||
|
<div class="pb-2 text-lg">
|
||||||
|
<span class="-ml-4 pr-2">2.</span> Third-Party Access
|
||||||
|
</div>
|
||||||
|
<div class="pl-4">
|
||||||
|
<div class="pb-2">
|
||||||
|
<div class="-ml-6">(a) Limited Third-Party Access:</div> We do
|
||||||
|
not sell or rent your personal information. We share data with
|
||||||
|
third parties only as necessary to operate Nessa: Clerk
|
||||||
|
processes your authentication credentials and account metadata,
|
||||||
|
and Turso hosts the database in which your community content is
|
||||||
|
stored. We may also use third-party services for crash reporting
|
||||||
|
and performance profiling; these services receive only
|
||||||
|
anonymized data related to app performance and stability, never
|
||||||
|
personal user content.
|
||||||
|
</div>
|
||||||
|
<div class="pb-2">
|
||||||
|
<div class="-ml-6">(b) Clerk as Identity Provider:</div> Your
|
||||||
|
authentication credentials (such as your password, if you use
|
||||||
|
an email/password sign-in) are handled exclusively by Clerk
|
||||||
|
under Clerk's own privacy policy. Nessa never receives,
|
||||||
|
stores, or transmits your password. When you sign in, Nessa
|
||||||
|
receives a session token from Clerk that lets us identify you;
|
||||||
|
this token is verified on each request and is not persisted in
|
||||||
|
our database.
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="py-2">
|
||||||
|
<div class="pb-2 text-lg">
|
||||||
|
<span class="-ml-4 pr-2">3.</span> Security
|
||||||
|
</div>
|
||||||
|
<div class="pl-4">
|
||||||
|
<div class="pb-2">
|
||||||
|
<div class="-ml-6">(a) Data Protection:</div> Nessa takes
|
||||||
|
appropriate measures to protect your account and the content you
|
||||||
|
create. Authentication is delegated to Clerk, which maintains
|
||||||
|
industry-standard security for credentials and session tokens.
|
||||||
|
Your community content is stored in the Nessa Turso database,
|
||||||
|
access to which is restricted to authenticated, authorized API
|
||||||
|
requests. We implement standard security protocols to prevent
|
||||||
|
unauthorized access, disclosure, alteration, or destruction of
|
||||||
|
user data.
|
||||||
|
</div>
|
||||||
|
<div class="pb-2">
|
||||||
|
<div class="-ml-6">(b) Club-Level Visibility:</div> Community
|
||||||
|
content you author is shared with other Nessa members only
|
||||||
|
according to the visibility rules of the club it belongs to.
|
||||||
|
Public clubs expose their content to any signed-in Nessa member;
|
||||||
|
private clubs restrict content to their members. You are
|
||||||
|
responsible for the content you choose to post.
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="py-2">
|
||||||
|
<div class="pb-2 text-lg">
|
||||||
|
<span class="-ml-4 pr-2">4.</span> Changes to the Privacy Policy
|
||||||
|
</div>
|
||||||
|
<div class="pb-2 pl-4">
|
||||||
|
<div class="-ml-6">(a) Updates:</div> We may update this privacy
|
||||||
|
policy periodically, especially if we introduce new features that
|
||||||
|
involve data collection. Any changes to this privacy policy will
|
||||||
|
be posted on this page. We encourage users to review this policy
|
||||||
|
regularly to stay informed about how we protect their information.
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="py-2">
|
||||||
|
<div class="pb-2 text-lg">
|
||||||
|
<span class="-ml-4 pr-2">5.</span> Contact Us
|
||||||
|
</div>
|
||||||
|
<div class="pb-2 pl-4">
|
||||||
|
<div class="-ml-6">(a) Reaching Out:</div> If there are any
|
||||||
|
questions or comments regarding this privacy policy, you can
|
||||||
|
contact us{" "}
|
||||||
|
<A href="/contact" class="text-blue hover-underline-animation">
|
||||||
|
here
|
||||||
|
</A>
|
||||||
|
.
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</ol>
|
||||||
|
</div>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -1,110 +1,25 @@
|
|||||||
import { A } from "@solidjs/router";
|
/**
|
||||||
import { PageHead } from "~/components/PageHead";
|
* Legacy Gaze privacy policy route — now a 308 permanent redirect to the Gaze
|
||||||
|
* subdomain (task 10).
|
||||||
export default function PrivacyPolicy() {
|
*
|
||||||
return (
|
* The privacy policy content has been migrated to
|
||||||
<>
|
* `src/routes/gaze/privacy.tsx`, served at `gaze.freno.me/privacy`
|
||||||
<PageHead
|
* (vercel.json host rewrites map the Gaze subdomain to the internal
|
||||||
title="Privacy Policy - Gaze"
|
* `/gaze/*` prefix). Keeping this route as a permanent (308) server-side
|
||||||
description="Privacy policy for Gaze, a macOS eye health reminder app."
|
* redirect — rather than a client `<Navigate>` — preserves SEO equity and
|
||||||
/>
|
* gives installed / linked URLs a stable resolution path, mirroring how the
|
||||||
<div class="min-h-screen px-[8vw] py-[10vh]">
|
* legacy Life and Lineage marketing page was redirected in task 08.
|
||||||
<div class="py-4 text-xl">Gaze's Privacy Policy</div>
|
*
|
||||||
<div class="py-2">Last Updated: February 9, 2026</div>
|
* Implemented as a SolidStart API route (`GET` handler returning a Response)
|
||||||
<div class="py-2">
|
* so the redirect happens before any rendering; the route no longer ships a
|
||||||
Welcome to Gaze ('We', 'Us', 'Our').
|
* page component.
|
||||||
Your privacy is important to us. This privacy policy will help you
|
*/
|
||||||
understand our policies and procedures related to the collection, use,
|
export function GET() {
|
||||||
and storage of personal information from our users.
|
return new Response(null, {
|
||||||
</div>
|
status: 308,
|
||||||
<ol>
|
headers: {
|
||||||
<div class="py-2">
|
Location: "https://gaze.freno.me/privacy",
|
||||||
<div class="pb-2 text-lg">
|
"Cache-Control": "public, max-age=0, must-revalidate"
|
||||||
<span class="-ml-4 pr-2">1.</span> Personal Information
|
}
|
||||||
</div>
|
});
|
||||||
<div class="pl-4">
|
|
||||||
<div class="pb-2">
|
|
||||||
<div class="-ml-6">(a) Collection of Personal Data:</div> Gaze
|
|
||||||
is designed with privacy as a core principle. We currently do
|
|
||||||
not collect, store, or share any personal information from our
|
|
||||||
users. The app runs entirely on your device and does not require
|
|
||||||
any account creation or data transmission to external servers.
|
|
||||||
</div>
|
|
||||||
<div class="pb-2">
|
|
||||||
<div class="-ml-6">(b) Future Data Collection:</div> We may in
|
|
||||||
the future implement optional features such as analytics or
|
|
||||||
crash reporting. If we do, we will clearly inform users through
|
|
||||||
a privacy policy update and obtain explicit consent before
|
|
||||||
collecting any data.
|
|
||||||
</div>
|
|
||||||
<div class="pb-2">
|
|
||||||
<div class="-ml-6">(c) Data Removal:</div> Since we do not
|
|
||||||
collect any personal information, there is no data to remove. If
|
|
||||||
you have any concerns about our practices, please contact{" "}
|
|
||||||
<A href="/contact" class="text-blue hover-underline-animation">
|
|
||||||
here
|
|
||||||
</A>
|
|
||||||
.
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="py-2">
|
|
||||||
<div class="pb-2 text-lg">
|
|
||||||
<span class="-ml-4 pr-2">2.</span> Third-Party Access
|
|
||||||
</div>
|
|
||||||
<div class="pb-2 pl-4">
|
|
||||||
<div class="-ml-6">(a) No Third-Party Sharing:</div> We do not
|
|
||||||
share, sell, or transfer any personal information to third
|
|
||||||
parties. Currently, Gaze does not utilize any third-party services
|
|
||||||
that would collect user data. Any future third-party services we
|
|
||||||
may use will be transparently disclosed in our privacy policy.
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="py-2">
|
|
||||||
<div class="pb-2 text-lg">
|
|
||||||
<span class="-ml-4 pr-2">3.</span> Security
|
|
||||||
</div>
|
|
||||||
<div class="pb-2 pl-4">
|
|
||||||
<div class="-ml-6">(a) Data Protection:</div> Because Gaze does
|
|
||||||
not collect or store any personal information, there is minimal
|
|
||||||
data security risk. The app runs locally on your device using
|
|
||||||
standard macOS security practices. Any configuration data stored
|
|
||||||
locally on your device is encrypted using system-provided
|
|
||||||
mechanisms.
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="py-2">
|
|
||||||
<div class="pb-2 text-lg">
|
|
||||||
<span class="-ml-4 pr-2">4.</span> Changes to the Privacy Policy
|
|
||||||
</div>
|
|
||||||
<div class="pb-2 pl-4">
|
|
||||||
<div class="-ml-6">(a) Updates:</div> We may update this privacy
|
|
||||||
policy periodically, especially if we introduce new features that
|
|
||||||
involve data collection. Any changes to this privacy policy will
|
|
||||||
be posted on this page. We encourage users to review this policy
|
|
||||||
regularly to stay informed about how we protect their information.
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="py-2">
|
|
||||||
<div class="pb-2 text-lg">
|
|
||||||
<span class="-ml-4 pr-2">5.</span> Contact Us
|
|
||||||
</div>
|
|
||||||
<div class="pb-2 pl-4">
|
|
||||||
<div class="-ml-6">(a) Reaching Out:</div> If there are any
|
|
||||||
questions or comments regarding this privacy policy, you can
|
|
||||||
contact us{" "}
|
|
||||||
<A href="/contact" class="text-blue hover-underline-animation">
|
|
||||||
here
|
|
||||||
</A>
|
|
||||||
.
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</ol>
|
|
||||||
</div>
|
|
||||||
</>
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,106 +1,25 @@
|
|||||||
import { A } from "@solidjs/router";
|
/**
|
||||||
import { PageHead } from "~/components/PageHead";
|
* Legacy Life and Lineage privacy policy route — now a 308 permanent redirect
|
||||||
|
* to the Lineage subdomain (task 10).
|
||||||
export default function PrivacyPolicy() {
|
*
|
||||||
return (
|
* The privacy policy content has been migrated to
|
||||||
<>
|
* `src/routes/lineage/privacy.tsx`, served at `lineage.freno.me/privacy`
|
||||||
<PageHead
|
* (vercel.json host rewrites map the Lineage subdomain to the internal
|
||||||
title="Privacy Policy - Life and Lineage"
|
* `/lineage/*` prefix). Keeping this route as a permanent (308) server-side
|
||||||
description="Privacy policy for Life and Lineage mobile game, outlining data collection, usage, and user rights."
|
* redirect — rather than a client `<Navigate>` — preserves SEO equity and
|
||||||
/>
|
* gives installed / linked URLs a stable resolution path, mirroring how the
|
||||||
<div class="min-h-screen px-[8vw] py-[10vh]">
|
* legacy Life and Lineage marketing page was redirected in task 08.
|
||||||
<div class="py-4 text-xl">Life and Lineage's Privacy Policy</div>
|
*
|
||||||
<div class="py-2">Last Updated: October 22, 2024</div>
|
* Implemented as a SolidStart API route (`GET` handler returning a Response)
|
||||||
<div class="py-2">
|
* so the redirect happens before any rendering; the route no longer ships a
|
||||||
Welcome to Life and Lineage ('We', 'Us',
|
* page component.
|
||||||
'Our'). Your privacy is important to us. This privacy policy
|
*/
|
||||||
will help you understand our policies and procedures related to the
|
export function GET() {
|
||||||
collection, use, and storage of personal information from our users.
|
return new Response(null, {
|
||||||
</div>
|
status: 308,
|
||||||
<ol>
|
headers: {
|
||||||
<div class="py-2">
|
Location: "https://lineage.freno.me/privacy",
|
||||||
<div class="pb-2 text-lg">
|
"Cache-Control": "public, max-age=0, must-revalidate"
|
||||||
<span class="-ml-4 pr-2">1.</span> Personal Information
|
}
|
||||||
</div>
|
});
|
||||||
<div class="pl-4">
|
|
||||||
<div class="pb-2">
|
|
||||||
<div class="-ml-6">(a) Collection of Personal Data:</div> Life
|
|
||||||
and Lineage collects and stores personal data only if users opt
|
|
||||||
to use the remote saving feature. The information collected
|
|
||||||
includes email address, and if using an OAuth provider - first
|
|
||||||
name, and last name. This information is used solely for the
|
|
||||||
purpose of providing and managing the remote saving feature. It
|
|
||||||
is and never will be shared with a third party.
|
|
||||||
</div>
|
|
||||||
<div class="pb-2">
|
|
||||||
<div class="-ml-6">(b) Data Removal:</div> Users can request the
|
|
||||||
removal of all information related to them by visiting{" "}
|
|
||||||
<A
|
|
||||||
href="/deletion/life-and-lineage"
|
|
||||||
class="text-blue hover-underline-animation"
|
|
||||||
>
|
|
||||||
this page
|
|
||||||
</A>{" "}
|
|
||||||
and filling out the provided form.
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="py-2">
|
|
||||||
<div class="pb-2 text-lg">
|
|
||||||
<span class="-ml-4 pr-2">2.</span> Third-Party Access
|
|
||||||
</div>
|
|
||||||
<div class="pb-2 pl-4">
|
|
||||||
<div class="-ml-6">(a) Limited Third-Party Access:</div> We do not
|
|
||||||
share or sell user information to third parties. However, we do
|
|
||||||
utilize third-party services for crash reporting and performance
|
|
||||||
profiling. These services do not have access to personal user
|
|
||||||
information and only receive anonymized data related to app
|
|
||||||
performance and stability.
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="py-2">
|
|
||||||
<div class="pb-2 text-lg">
|
|
||||||
<span class="-ml-4 pr-2">3.</span> Security
|
|
||||||
</div>
|
|
||||||
<div class="pb-2 pl-4">
|
|
||||||
<div class="-ml-6">(a) Data Protection:</div>Life and Lineage
|
|
||||||
takes appropriate measures to protect the personal information of
|
|
||||||
users who opt for the remote saving feature. We implement
|
|
||||||
industry-standard security protocols to prevent unauthorized
|
|
||||||
access, disclosure, alteration, or destruction of user data.
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="py-2">
|
|
||||||
<div class="pb-2 text-lg">
|
|
||||||
<span class="-ml-4 pr-2">4.</span> Changes to the Privacy Policy
|
|
||||||
</div>
|
|
||||||
<div class="pb-2 pl-4">
|
|
||||||
<div class="-ml-6">(a) Updates:</div> We may update this privacy
|
|
||||||
policy periodically. Any changes to this privacy policy will be
|
|
||||||
posted on this page. We encourage users to review this policy
|
|
||||||
regularly to stay informed about how we protect their information.
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="py-2">
|
|
||||||
<div class="pb-2 text-lg">
|
|
||||||
<span class="-ml-4 pr-2">5.</span> Contact Us
|
|
||||||
</div>
|
|
||||||
<div class="pb-2 pl-4">
|
|
||||||
<div class="-ml-6">(a) Reaching Out:</div> If there are any
|
|
||||||
questions or comments regarding this privacy policy, you can
|
|
||||||
contact us{" "}
|
|
||||||
<A href="/contact" class="text-blue hover-underline-animation">
|
|
||||||
here
|
|
||||||
</A>
|
|
||||||
.
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</ol>
|
|
||||||
</div>
|
|
||||||
</>
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user