nessa: publish the Terms of Use the app links at /terms (FRE-194)

The Nessa app's Settings › Legal "Terms of Service" row had no Nessa-owned
document to resolve to: it linked another product's terms, and
nessa.freno.me/terms was a 404. Nessa sells an auto-renewing subscription, so
App Review 3.1.2 requires the app to link terms of use as well as a privacy
policy — the row has to land on a real document.

- src/routes/nessa/terms.tsx: the page, in the privacy.tsx house template
  (EdgeCacheHeaders, site-aware PageHead, SubdomainHeader, subdomain-relative
  internal links). Sections cover acceptance, the service and its limits,
  accounts, community content and acceptable use, auto-renewable
  subscriptions (payment, renewal, the 24-hour cancel window, managing it in
  the App Store, trials, refunds, price changes), the Apple third-party
  acknowledgements, IP, disclaimers and liability, termination, changes, and
  contact.
- src/lib/sitemap-routes.ts: add /terms to the Nessa set, and update the
  count assertion in sitemap-routes.test.ts to match.

Health and safety: Nessa is not a medical device, so section 2(c) says so
explicitly — the previous app-side link pointed at another product's terms,
which said nothing about Nessa's training features.

Deliberately left out, for Mike to decide rather than have me guess:
 - No legal entity name and no governing-law clause. No Nessa page states
   either today; the privacy policy speaks only as "we".
 - No NAV_CONFIG entry, so the nav link-set matrix tests are untouched. The
   route serves through the existing catch-all host rewrite in vercel.json;
   adding a nav item is a one-line change plus a matrix update if wanted.
This commit is contained in:
2026-11-07 21:36:44 +00:00
committed by fixture
parent a0e6ff1044
commit 97755042cb
3 changed files with 450 additions and 2 deletions

View File

@@ -67,7 +67,8 @@ describe("generateSitemap", () => {
expect(locs).toContain("https://nessa.freno.me/");
expect(locs).toContain("https://nessa.freno.me/contact");
expect(locs).toContain("https://nessa.freno.me/privacy");
expect(locs.length).toBe(3);
expect(locs).toContain("https://nessa.freno.me/terms");
expect(locs.length).toBe(4);
for (const loc of locs) {
expect(loc).not.toContain("://freno.me/");

View File

@@ -57,7 +57,8 @@ export const SITEMAP_ROUTES: Record<SiteId, SitemapEntry[]> = {
nessa: [
{ path: "/", changefreq: "weekly", priority: 1.0 },
{ path: "/contact", changefreq: "monthly", priority: 0.6 },
{ path: "/privacy", changefreq: "yearly", priority: 0.4 }
{ path: "/privacy", changefreq: "yearly", priority: 0.4 },
{ path: "/terms", changefreq: "yearly", priority: 0.4 }
],
lineage: [

446
src/routes/nessa/terms.tsx Normal file
View File

@@ -0,0 +1,446 @@
/**
* Nessa terms of use — `nessa.freno.me/terms`.
*
* The document behind the `Terms of Service` row in the Nessa app
* (`Nessa/Models/AppSettings.swift`, Settings › Legal). Before this page the
* row had no Nessa-owned document to resolve to: the app linked another
* product's terms, and `nessa.freno.me/terms` was a 404 (FRE-194).
*
* Nessa sells an auto-renewing subscription through the App Store, so App
* Review 3.1.2 requires the app to link a privacy policy **and** terms of
* use. Section 5 (subscriptions) and section 6 (Apple acknowledgements) are
* the clauses that requirement is read against, so keep them when editing.
*
* House voice follows `privacy.tsx`: "we" / "Nessa", no legal entity name,
* and no governing-law clause — the Nessa pages have never stated either, and
* naming an entity or a jurisdiction is a decision to make deliberately, not
* to introduce as a side effect of a link fix.
*
* PageHead is site-aware: only the base title is supplied; the ` | Nessa`
* suffix, the `https://nessa.freno.me/terms` canonical and the OG image are
* derived automatically. Internal links use public subdomain-relative paths
* (`/privacy`, `/deletion`, `/contact`) per nav-config.ts and
* page-head-meta.ts.
*/
import { A } from "@solidjs/router";
import { PageHead } from "~/components/PageHead";
import { EdgeCacheHeaders } from "~/components/EdgeCacheHeaders";
import SubdomainHeader from "~/components/SubdomainHeader";
export default function NessaTermsOfUse() {
return (
<>
<EdgeCacheHeaders maxAge={300} />
<PageHead
title="Terms of Use"
description="Terms of use for Nessa, a fitness app for tracking workouts and training with clubs, challenges, and friends."
/>
<SubdomainHeader />
<div class="min-h-screen px-[8vw] py-[10vh]">
<div class="py-4 text-xl">Nessa&apos;s Terms of Use</div>
<div class="py-2">Last Updated: November 7, 2026</div>
<div class="py-2">
Welcome to Nessa (&apos;We&apos;, &apos;Us&apos;, &apos;Our&apos;).
These terms of use govern your access to and use of the Nessa app and
its related services. By using Nessa you agree to these terms. Our{" "}
<A href="/privacy" class="text-blue hover-underline-animation">
privacy policy
</A>{" "}
explains how we handle your data, and it forms part of these terms.
</div>
<ol>
<div class="py-2">
<div class="pb-2 text-lg">
<span class="-ml-4 pr-2">1.</span> Acceptance of These Terms
</div>
<div class="pl-4">
<div class="pb-2">
<div class="-ml-6">(a) Agreement:</div> By creating an account,
downloading, or otherwise using Nessa you agree to these terms.
If you do not agree to them, do not use Nessa.
</div>
<div class="pb-2">
<div class="-ml-6">(b) Eligibility:</div> You must be at least
the age of digital consent in your country to use Nessa. If you
are using Nessa with a parent&apos;s or guardian&apos;s
account, they are responsible for your compliance with these
terms.
</div>
<div class="pb-2">
<div class="-ml-6">(c) Where these terms apply:</div> These
terms are between you and us. Where you obtained Nessa through
a third party such as the Apple App Store, that
party&apos;s own terms apply to your relationship with them as
well.
</div>
</div>
</div>
<div class="py-2">
<div class="pb-2 text-lg">
<span class="-ml-4 pr-2">2.</span> The Service
</div>
<div class="pl-4">
<div class="pb-2">
<div class="-ml-6">(a) What Nessa is:</div> Nessa is a fitness
application for iOS, with an Apple Watch companion, that lets
you record workouts and routes, review your training history,
and take part in community features — clubs, club challenges,
posts, comments, and leaderboards. Some features are free and
some require a paid subscription (see section 5).
</div>
<div class="pb-2">
<div class="-ml-6">(b) Changes and availability:</div> We are
continually improving Nessa, so features may change, move
between tiers, or be withdrawn. We do not guarantee that Nessa
will be available at all times, and we may suspend or discontinue
part or all of the service. Where a change materially affects a
paid feature you have subscribed to, we will tell you on the
subscription management page or by contact.
</div>
<div class="pb-2">
<div class="-ml-6">(c) Not medical advice:</div> Nessa is not a
medical device and is not intended to diagnose, treat, cure, or
prevent any condition. Workout data, heart-rate and other
health readings, training plans, and estimates you see in Nessa
are for general information and motivation only. Consult a
qualified professional before starting or changing a training
programme, especially if you have a health condition. Never
ignore professional advice, or delay seeking it, because of
something you read in Nessa.
</div>
<div class="pb-2">
<div class="-ml-6">(d) Your surroundings:</div> You are
responsible for your own safety while using Nessa, including
when recording an activity. Follow local laws and do not use
Nessa in a way that distracts you from driving or other
activities that require your full attention.
</div>
</div>
</div>
<div class="py-2">
<div class="pb-2 text-lg">
<span class="-ml-4 pr-2">3.</span> Your Account
</div>
<div class="pl-4">
<div class="pb-2">
<div class="-ml-6">(a) Sign-in:</div> Nessa accounts are
authenticated through Clerk, our identity provider. You are
responsible for keeping the credentials you use to sign in
secure, and you are responsible for the activity that happens
under your account.
</div>
<div class="pb-2">
<div class="-ml-6">(b) Notify us:</div> Tell us promptly, using
the contact details in section 11, if you believe someone else
has used or may use your account without your permission.
</div>
<div class="pb-2">
<div class="-ml-6">(c) One account:</div> Keep to one account,
and give us accurate information so we can keep your training
history and your place in the community correct. Do not create
accounts to evade a moderation decision or to gain a fair
advantage in challenges or leaderboards.
</div>
</div>
</div>
<div class="py-2">
<div class="pb-2 text-lg">
<span class="-ml-4 pr-2">4.</span> Community Content and Acceptable
Use
</div>
<div class="pl-4">
<div class="pb-2">
<div class="-ml-6">(a) You keep your content:</div> You own what
you post. By posting to a club, challenge, or other shared area
of Nessa you grant us a limited, non-exclusive licence to store,
reproduce, and display that content inside Nessa so that the
feature you used can work — for example, showing your post to
the members of your club. That licence ends when your content is
removed from our systems. We handle your content as described in
our{" "}
<A href="/privacy" class="text-blue hover-underline-animation">
privacy policy
</A>
; we do not sell it.
</div>
<div class="pb-2">
<div class="-ml-6">(b) What you are responsible for:</div> You
are responsible for the content you post and the data you record
in Nessa, and for who you share it with. Use the privacy
settings on your profile and the privacy rules of the clubs you
join before sharing anything you would not want others to see.
</div>
<div class="pb-2">
<div class="-ml-6">(c) Do not:</div> (i) post anything unlawful,
harassing, hateful, threatening, or sexually explicit involving
minors; (ii) post content you do not have the right to share, or
that infringes someone else&apos;s intellectual property;
(iii) falsify activity data, spoof a location, or otherwise
cheat a challenge, leaderboard, or competition; (iv) scrape,
bulk-download, or access Nessa through automated means we have
not authorised; (v) interfere with, overload, or probe Nessa for
vulnerabilities, or attempt to access another user&apos;s
account or data; (vi) resell, sublicense, or offer Nessa to
others as your own service.
</div>
<div class="pb-2">
<div class="-ml-6">(d) Moderation:</div> We may remove or
restrict content, disqualify an entry from a challenge, or
suspend or close an account that breaks these terms. We are not
obliged to pre-monitor content. You can report content or a user
to us at any time using the contact details in section 11.
</div>
</div>
</div>
<div class="py-2">
<div class="pb-2 text-lg">
<span class="-ml-4 pr-2">5.</span> Subscriptions and Payments
</div>
<div class="pl-4">
<div class="pb-2">
<div class="-ml-6">(a) Paid tiers:</div> Nessa offers paid
subscription tiers, Nessa Plus and Nessa Pro, which unlock
features described in the app. Subscriptions are sold as
auto-renewing subscriptions through the Apple App Store and are
billed to your Apple Account.
</div>
<div class="pb-2">
<div class="-ml-6">(b) Payment:</div> Payment is charged to your
Apple Account at confirmation of purchase. The price of your
plan is shown in the app before you buy, and it is the price on
your App Store purchase receipt.
</div>
<div class="pb-2">
<div class="-ml-6">(c) Auto-renewal:</div> Unless you cancel at
least 24 hours before the end of the current period, your
subscription renews automatically. Your account is charged for
renewal within 24 hours before the end of the current period, at
the price of the plan you selected.
</div>
<div class="pb-2">
<div class="-ml-6">(d) Managing your subscription:</div> You can
turn off auto-renewal, or cancel, at any time in your App Store
account settings after purchase. Changes made there take effect
at the end of the current period, and you keep access to the
paid features you have already paid for until then.
</div>
<div class="pb-2">
<div class="-ml-6">(e) Trials:</div> If we offer a free trial,
any unused portion of it is forfeited when you purchase a
subscription, and the trial converts to a paid auto-renewing
subscription unless you cancel it before it ends.
</div>
<div class="pb-2">
<div class="-ml-6">(f) Refunds:</div> Purchases made through the
App Store are refunded according to Apple&apos;s refund policy
and, where applicable law gives you a right to a refund,
according to that law. Tell us using the contact details in
section 11 and we will do what we can.
</div>
<div class="pb-2">
<div class="-ml-6">(g) Price changes:</div> We may change our
prices. A price change does not apply to a period you have
already paid for; it applies from your next renewal, and we give
notice where the law requires it.
</div>
<div class="pb-2">
<div class="-ml-6">(h) Downgrade:</div> When a subscription
lapses or is cancelled you keep the free features, and anything
you created that belongs to a paid feature (such as a custom
route) is kept but is not editable or usable until you
subscribe again.
</div>
</div>
</div>
<div class="py-2">
<div class="pb-2 text-lg">
<span class="-ml-4 pr-2">6.</span> Apple and Other Third Parties
</div>
<div class="pl-4">
<div class="pb-2">
<div class="-ml-6">(a) Not Apple&apos;s terms:</div> These terms
are between you and us, not with Apple Inc. Apple is not
responsible for Nessa or its content, and your use of Nessa must
comply with the Apple App Store Terms of Service.
</div>
<div class="pb-2">
<div class="-ml-6">(b) No Apple support:</div> Apple has no
obligation to furnish maintenance and support services for
Nessa. If Nessa fails, you may notify Apple, but Apple has no
further support obligation, and support and any warranties
relating to Nessa are ours to provide as described in these
terms.
</div>
<div class="pb-2">
<div class="-ml-6">(c) Apple is not responsible for claims:</div>{" "}
Apple is not responsible for product liability claims,
intellectual property infringement claims, or any other claims
relating to Nessa or your possession and use of it. We, not
Apple, are responsible for addressing any such claims and for
any claims that you may have relating to Nessa.
</div>
<div class="pb-2">
<div class="-ml-6">(d) Compliance:</div> You confirm that you
are not located in a country subject to an embargo of the United
States or listed by the United States government as a
terrorist-supporting country, and that you are not listed on any
United States government list of prohibited or restricted
parties.
</div>
<div class="pb-2">
<div class="-ml-6">(e) Third-party services:</div> Nessa depends
on third-party services — Clerk for authentication, Apple
HealthKit for health and workout data, Apple&apos;s In-App
Purchase system for subscriptions, and our own hosting — each
governed by its own terms. Where those terms affect how you may
use the feature they power, they apply alongside these terms.
</div>
</div>
</div>
<div class="py-2">
<div class="pb-2 text-lg">
<span class="-ml-4 pr-2">7.</span> Intellectual Property
</div>
<div class="pl-4">
<div class="pb-2">
<div class="-ml-6">(a) Our rights:</div> The Nessa software, its
design, text, icons, and branding are owned by us or our
licensors and are protected by copyright and other laws. We
grant you a personal, non-exclusive, non-transferable, revocable
licence to use Nessa for your own personal, non-commercial
purposes.
</div>
<div class="pb-2">
<div class="-ml-6">(b) Restrictions:</div> You may not copy,
modify, translate, distribute, sell, lease, sublicense, or
create derivative works from Nessa, and you may not reverse
engineer, decompile, or attempt to obtain its source code,
except to the extent applicable law allows this despite a
restriction.
</div>
</div>
</div>
<div class="py-2">
<div class="pb-2 text-lg">
<span class="-ml-4 pr-2">8.</span> Disclaimers and Limitation of
Liability
</div>
<div class="pl-4">
<div class="pb-2">
<div class="-ml-6">(a) As is:</div> Nessa is provided &quot;as
is&quot; and &quot;as available&quot; to the fullest extent
permitted by applicable law. We do not warrant that Nessa will
be uninterrupted, secure, error-free, or that recorded data will
be accurate — GPS-derived distance, pace, elevation, and
estimates can be wrong, and device and sensor limits apply.
</div>
<div class="pb-2">
<div class="-ml-6">(b) Your data:</div> You are responsible for
backing up the data you store on your device. We keep
Nessa&apos;s service data as described in the{" "}
<A href="/privacy" class="text-blue hover-underline-animation">
privacy policy
</A>{" "}
and{" "}
<A href="/deletion" class="text-blue hover-underline-animation">
deletion page
</A>
, but no service is a substitute for your own backup.
</div>
<div class="pb-2">
<div class="-ml-6">(c) Liability:</div> To the fullest extent
permitted by law, we are not liable for indirect, incidental,
special, consequential, or punitive damages, or for lost data,
lost profits, or loss of training records, arising out of your
use of, or inability to use, Nessa. Where a court would not
allow that exclusion, our liability for claims arising from your
use of Nessa is limited to the greater of the subscription fees
you paid us in the twelve months before the event giving rise to
the claim, or the minimum the applicable law requires. Nothing
in these terms limits liability that cannot lawfully be limited,
including for fraud or for death or personal injury caused by
our negligence.
</div>
</div>
</div>
<div class="py-2">
<div class="pb-2 text-lg">
<span class="-ml-4 pr-2">9.</span> Ending Your Use
</div>
<div class="pl-4">
<div class="pb-2">
<div class="-ml-6">(a) You can leave:</div> You can stop using
Nessa at any time. You can delete your account and the content
associated with it through our{" "}
<A href="/deletion" class="text-blue hover-underline-animation">
account deletion page
</A>
. Deleting your account does not cancel a subscription that is
still in its paid period; cancel that in your App Store account
settings as described in section 5.
</div>
<div class="pb-2">
<div class="-ml-6">(b) We may end access:</div> We may suspend
or close your access to Nessa if you break these terms, if we
are required to by law, or if we reasonably believe your account
has been compromised. Where we can, we will tell you why.
</div>
<div class="pb-2">
<div class="-ml-6">(c) On termination:</div> Your licence to use
Nessa ends, and sections 4(a), 6, 7, 8, 10, and 11 continue to
apply.
</div>
</div>
</div>
<div class="py-2">
<div class="pb-2 text-lg">
<span class="-ml-4 pr-2">10.</span> Changes to These Terms
</div>
<div class="pl-4">
<div class="pb-2">
<div class="-ml-6">(a) Updates:</div> We may update these terms
as Nessa changes. The current version is always the one at{" "}
<A href="/terms" class="text-blue hover-underline-animation">
nessa.freno.me/terms
</A>
, and the &quot;Last Updated&quot; date at the top of this page
shows when it last changed.
</div>
<div class="pb-2">
<div class="-ml-6">(b) Continued use:</div> If you keep using
Nessa after a change takes effect, you accept the revised terms.
For changes that materially reduce your rights or your paid
features, we will give notice in the app or by contact before
they take effect.
</div>
</div>
</div>
<div class="py-2">
<div class="pb-2 text-lg">
<span class="-ml-4 pr-2">11.</span> Contact Us
</div>
<div class="pb-2 pl-4">
<div class="-ml-6">(a) Reaching Out:</div> If you have any
questions or comments about these terms, want to report content,
or need help with a subscription, you can contact us{" "}
<A href="/contact" class="text-blue hover-underline-animation">
here
</A>
.
</div>
</div>
</ol>
</div>
</>
);
}