Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions docs/ROADMAP.md
Original file line number Diff line number Diff line change
Expand Up @@ -1651,9 +1651,9 @@ Sequencing: realistically wants to happen before live Stripe mode activates (Str
| Feature | Size | Description |
|---------|------|-------------|
| About page (/about) | M | _Shipped early, ahead of v1.42._ Honest first-person voice matching the Pricing page. Covers: what Campable does, why it exists, who's behind it, how it's funded, where data comes from, what's coming. Trust signal for fence-sitters on /pricing. |
| Privacy Policy (/privacy) | S | Hand-written in Campable voice (not Termly — see Architecture Decisions). Honest disclosure of every third party that touches user data (Supabase, Stripe, PostHog, Mapbox, Visual Crossing, Cloudflare, Fly), retention policy, and GDPR/CCPA rights. |
| Privacy Policy (/privacy) | S | Hand-written in Campable voice. See Architecture Decisions for why Termly was rejected. Honest disclosure of every third party that touches user data (Supabase, Stripe, PostHog, Mapbox, Visual Crossing, Cloudflare, Fly), retention policy, and GDPR/CCPA rights. |
| Terms of Service (/terms) | S | Hand-written. $5/mo subscription terms, explicit 30-day refund policy (per Stripe's preference), liability limit, governing law (Washington), right to terminate abusive accounts. Linked from /pricing. |
| Footer component | S | New `<Footer>` rendered site-wide outside `<Routes>`. Links: About, Pricing, Privacy, Terms, Contact (mailto). © year only — version dropped (continuously deployed, package.json is 0.0.0, no semver discipline to display). |
| Footer component | S | New `<Footer>` rendered site-wide outside `<Routes>`. Links: About, Pricing, Privacy, Terms, Contact (mailto). © year only. Version dropped because package.json is 0.0.0 and the site is continuously deployed. |
| Contact email | XS | `hello@palouselabs.com` already wired. Mailto in footer and on Privacy/Terms contact sections. |
| Stripe Business profile config | XS | Paste Privacy + ToS URLs into Stripe Dashboard → Settings → Public details. Required for live-mode review. |
| Stripe Customer Portal links | XS | Customer Portal config page → add Terms + Privacy URLs so the cancel/manage flow shows them. |
Expand Down
83 changes: 43 additions & 40 deletions web/src/pages/About.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
/**
* About page (/about) v1.42.
* About page (/about) for v1.42.
*
* Trust signal for fence-sitters on /pricing. Same first-person, no-marketing
* voice as the Pricing page. Built to be skimmed top-to-bottom in 60 seconds
* by someone deciding whether to give a $5/mo subscription to a stranger on
* the internet. Concrete facts (data sources, funding model) carry more
* weight than "we're committed to quality" copy ever would.
* Trust signal for fence-sitters on /pricing. Same first-person,
* no-marketing voice as the Pricing page. Built to be skimmed
* top-to-bottom in 60 seconds by someone deciding whether to give
* a $5/mo subscription to a stranger on the internet. Concrete facts
* (data sources, funding model) carry more weight than "we're committed
* to quality" copy ever would.
*/

import { Helmet } from "react-helmet-async";
Expand All @@ -28,39 +29,40 @@ export default function About() {
<p className="about-lede">
Campable aggregates real-time campsite availability across
Recreation.gov, Washington State Parks, and Oregon State Parks so
you can answer &ldquo;what&rsquo;s actually open this weekend within
driving distance?&rdquo; without bouncing between five booking
sites.
you can answer &ldquo;what&rsquo;s actually open this weekend
within driving distance?&rdquo; without bouncing between five
booking sites.
</p>
</header>

<section className="about-section" aria-labelledby="why-heading">
<h2 id="why-heading">Why this exists</h2>
<p>
Finding a campsite shouldn&rsquo;t require fifteen browser tabs and
a spreadsheet. The booking sites are designed for people who already
know the campground they want. They&rsquo;re not designed for
&ldquo;anywhere quiet and pretty within three hours of
Finding a campsite shouldn&rsquo;t require fifteen browser tabs
and a spreadsheet. The booking sites are designed for people who
already know the campground they want. They&rsquo;re not designed
for &ldquo;anywhere quiet and pretty within three hours of
Seattle&rdquo; or &ldquo;any lakeside spot that opened up this
week.&rdquo;
</p>
<p>
Campable does the cross-source aggregation, the date filtering, the
drive-time math, and the trail / lake / old-growth tagging &mdash;
so you can do less searching and more camping.
Campable does the cross-source aggregation, the date filtering,
the drive-time math, and the trail / lake / old-growth tagging,
so you can spend less time searching and more time camping.
</p>
</section>

<section className="about-section" aria-labelledby="who-heading">
<h2 id="who-heading">Who&rsquo;s behind it</h2>
<p>
Built and maintained by one person. The kind of person who has
watched availability flip from open to gone in fifteen minutes and
decided the booking layer needed a search engine on top.
watched availability flip from open to gone in fifteen minutes
and decided the booking layer needed a search engine on top.
</p>
<p>
If something&rsquo;s broken or could be better, send a note &mdash;
feedback goes to a real human, not a support queue.
If something&rsquo;s broken or could be better, email{" "}
<a href="mailto:hello@palouselabs.com">hello@palouselabs.com</a>.
Replies come from a real human.
</p>
</section>

Expand All @@ -69,45 +71,46 @@ export default function About() {
<p>
Free for search, three watches, and shareable links.{" "}
<Link to="/pricing">Pro</Link> ($5/month) unlocks unlimited
watches, 5-minute polling instead of 15-minute, more trip planner
sessions, and anomaly-based deal alerts. Pro subscriptions cover
the polling infrastructure and let the free tier stay genuinely
free for the next person who just needs to find a tent site.
watches, 5-minute polling instead of 15-minute, more trip
planner sessions, and anomaly-based deal alerts. Pro
subscriptions cover the polling infrastructure and let the free
tier stay genuinely free for the next person who just needs to
find a tent site.
</p>
<p>
No ads, ever. No selling your data. No &ldquo;free trial that
auto-converts&rdquo; &mdash; Pro is opt-in and one-click cancel via
the Stripe portal.
No ads. We don&rsquo;t sell your data. Pro never auto-converts
from a trial; it&rsquo;s opt-in, and you can cancel in one click
from the Stripe portal.
</p>
</section>

<section className="about-section" aria-labelledby="data-heading">
<h2 id="data-heading">Where the data comes from</h2>
<ul className="about-list">
<li>
<strong>Recreation.gov</strong> &mdash; federal campgrounds via
the official RIDB metadata API and per-day availability endpoint
<strong>Recreation.gov:</strong> federal campgrounds via the
official RIDB metadata API and per-day availability endpoint.
</li>
<li>
<strong>Washington State Parks</strong> &mdash; via the
GoingToCamp public API
<strong>Washington State Parks:</strong> via the GoingToCamp
public API.
</li>
<li>
<strong>Oregon State Parks</strong> &mdash; via ReserveAmerica
<strong>Oregon State Parks:</strong> via ReserveAmerica.
</li>
<li>
<strong>Mapbox</strong> &mdash; actual drive-time routing, not
just straight-line distance
<strong>Mapbox:</strong> real drive-time routing for the
distance estimates, rather than straight-line distance.
</li>
<li>
<strong>Visual Crossing</strong> &mdash; typical climate normals
shown on result cards so you know what to pack
<strong>Visual Crossing:</strong> typical climate normals shown
on result cards so you know what to pack.
</li>
</ul>
<p>
When you click &ldquo;Book&rdquo; on a result, you go directly to
the booking site for that campground. Campable doesn&rsquo;t process
bookings or take a cut &mdash; payments go to whoever runs the
the booking site for that campground. Campable doesn&rsquo;t
process bookings or take a cut. Payments go to whoever runs the
campground.
</p>
</section>
Expand All @@ -119,8 +122,8 @@ export default function About() {
monetization is validated on the web). Predictive availability
(&ldquo;typically frees up X days before&rdquo;) once polling
history is deep enough to make confidence bands meaningful
(~Q1 2027). Continued registry expansion as state park APIs become
accessible.
(around Q1 2027). Continued registry expansion as state park APIs
become accessible.
</p>
</section>
</main>
Expand Down
103 changes: 51 additions & 52 deletions web/src/pages/Privacy.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ export default function Privacy() {
<title>Privacy · Campable</title>
<meta
name="description"
content="What Campable collects, the third parties that touch your data, retention, and how to exercise your access and deletion rights."
content="What Campable collects, the third parties that handle any of it, retention, and how to exercise your access and deletion rights."
/>
</Helmet>

Expand All @@ -16,41 +16,40 @@ export default function Privacy() {
<h1>Privacy Policy</h1>
<p className="legal-meta">Last updated: 2026-05-31</p>
<p className="about-lede">
Campable is a campsite discovery tool. To run search, watches, and
billing we collect the minimum data needed and route it through a
short list of specific third parties &mdash; named below, not
described as &ldquo;service providers.&rdquo; No ads, no selling, no
cross-site tracking pixels.
Campable is a campsite discovery tool. We collect the minimum data
needed to run search, watches, and billing. Every third party that
handles any of it is listed below by name. We don&rsquo;t run ads,
sell data, or use cross-site tracking pixels.
</p>
</header>

<section className="legal-section" aria-labelledby="collect-heading">
<h2 id="collect-heading">What we collect</h2>
<ul className="about-list">
<li>
<strong>Account</strong> &mdash; email, a password (hashed and
stored by Supabase, never seen in plaintext on our servers), and
an optional display name.
<strong>Account:</strong> email, a password (hashed and stored by
Supabase, never seen in plaintext on our servers), and an
optional display name.
</li>
<li>
<strong>Product data</strong> &mdash; the watches, trips, and
search history you create. Stored against your account so they
persist across devices.
<strong>Product data:</strong> the watches, trips, and search
history you create. Stored against your account so they persist
across devices.
</li>
<li>
<strong>Billing</strong> &mdash; Stripe customer ID and
subscription status. We never see your card number; Stripe handles
card data directly.
<strong>Billing:</strong> Stripe customer ID and subscription
status. We never see your card number; Stripe handles card data
directly.
</li>
<li>
<strong>Analytics</strong> &mdash; page views, button clicks,
<strong>Analytics:</strong> page views, button clicks, and
search parameters. Analytics requests are reverse-proxied
through campable.co so your IP isn&rsquo;t forwarded to the
analytics vendor.
</li>
<li>
<strong>Server logs</strong> &mdash; standard HTTP request
metadata for debugging and abuse prevention. Retained 30 days.
<strong>Server logs:</strong> standard HTTP request metadata for
debugging and abuse prevention. Retained 30 days.
</li>
</ul>
</section>
Expand All @@ -59,60 +58,60 @@ export default function Privacy() {
<h2 id="parties-heading">Third parties that touch your data</h2>
<ul className="about-list">
<li>
<strong>Supabase</strong> &mdash; authentication and our primary
<strong>Supabase:</strong> authentication and our primary
database. US-hosted. Sees your email, hashed password, and all
account-tied data.
</li>
<li>
<strong>Stripe</strong> &mdash; payment processing. Sees your
billing details directly; we receive only a customer ID and
subscription status.
<strong>Stripe:</strong> payment processing. Sees your billing
details directly; we receive only a customer ID and subscription
status.
</li>
<li>
<strong>PostHog</strong> &mdash; product analytics, EU-hosted
<strong>PostHog:</strong> product analytics, EU-hosted
(eu.posthog.com). Sees clicks and page views tied to a session
ID. Requests are reverse-proxied through campable.co so your
IP isn&rsquo;t forwarded.
ID. Requests are reverse-proxied through campable.co so your IP
isn&rsquo;t forwarded.
</li>
<li>
<strong>Mapbox</strong> &mdash; drive-time geocoding. Sees the
origin and destination coordinates required to compute a route.
Does not see your account.
<strong>Mapbox:</strong> drive-time geocoding. Sees the origin
and destination coordinates required to compute a route. Does
not see your account.
</li>
<li>
<strong>Visual Crossing</strong> &mdash; weather climate normals.
<strong>Visual Crossing:</strong> weather climate normals.
Called server-side with campground coordinates only. Never sees
user identity.
</li>
<li>
<strong>Cloudflare</strong> &mdash; DNS and TLS termination. Sees
<strong>Cloudflare:</strong> DNS and TLS termination. Sees
standard HTTP request metadata.
</li>
<li>
<strong>Fly.io</strong> &mdash; application hosting. Holds the
running application and its database.
<strong>Fly.io:</strong> application hosting. Holds the running
application and its database.
</li>
</ul>
</section>

<section className="legal-section" aria-labelledby="dont-heading">
<h2 id="dont-heading">What we don&rsquo;t do</h2>
<p>
No advertising network integrations. No selling or renting of your
data. No cross-site tracking pixels. No third-party social-login
providers wired in yet (when Google/Apple sign-in lands, this
section will be updated to disclose what each provider sees).
We don&rsquo;t run advertising integrations or cross-site tracking
pixels, and we don&rsquo;t sell or rent your data to anyone.
Social login providers (Google, Apple) are not wired in yet. When
that lands, this section will list what each provider sees.
</p>
</section>

<section className="legal-section" aria-labelledby="retention-heading">
<h2 id="retention-heading">Retention</h2>
<p>
Account data lives until you delete your account, at which point
it&rsquo;s removed from our database within 7 days. Billing records
are retained per Stripe&rsquo;s tax and audit requirements (up to
7 years). Analytics events are retained 12 months in aggregate
form. Server logs are retained 30 days.
it&rsquo;s removed from our database within 7 days. Billing
records are retained per Stripe&rsquo;s tax and audit requirements
(up to 7 years). Analytics events are retained 12 months in
aggregate form. Server logs are retained 30 days.
</p>
</section>

Expand All @@ -123,38 +122,38 @@ export default function Privacy() {
access, correct, delete, or export your data, and to object to
certain processing. Email{" "}
<a href="mailto:hello@palouselabs.com">hello@palouselabs.com</a>{" "}
and we&rsquo;ll act on it within 30 days. Account deletion is also
available directly in the user menu.
and we&rsquo;ll act on it within 30 days. Account deletion is
also available directly in the user menu.
</p>
</section>

<section className="legal-section" aria-labelledby="cookies-heading">
<h2 id="cookies-heading">Cookies and analytics</h2>
<p>
We use first-party cookies for session login and a first-party
analytics cookie for PostHog. No third-party advertising cookies.
We have not yet implemented an EU consent banner; we plan to add
one once EU traffic exceeds 5% of total. If you&rsquo;re in the EU
and want to opt out before then, email us and we&rsquo;ll exclude
your account from analytics.
analytics cookie for PostHog, and no third-party advertising
cookies. An EU consent banner is not yet implemented; we plan to
add one once EU traffic exceeds 5% of total. If you&rsquo;re in
the EU and want to opt out before then, email us and we&rsquo;ll
exclude your account from analytics.
</p>
</section>

<section className="legal-section" aria-labelledby="children-heading">
<h2 id="children-heading">Children</h2>
<p>
Campable is not directed at people under 13 and we do not knowingly
collect their data.
Campable is not directed at people under 13, and we do not
knowingly collect their data.
</p>
</section>

<section className="legal-section" aria-labelledby="changes-heading">
<h2 id="changes-heading">Changes</h2>
<p>
Material changes to this policy will be announced in-app and by
email to active subscribers. Minor edits (wording, clarifications)
are made silently and reflected in the &ldquo;Last updated&rdquo;
date at the top.
email to active subscribers. Minor edits (wording,
clarifications) are made silently and reflected in the
&ldquo;Last updated&rdquo; date at the top.
</p>
</section>

Expand Down
Loading
Loading