{% extends "public_base.html" %}
{% block title %}{{ BRAND_NAME }} &middot; Privacy{% endblock %}

{% block main %}

<section class="public-section">
  <h1 class="public-section__head">Privacy notice</h1>
  <p style="color: var(--muted); font-size: 13px;">
    Last updated: 2026-05-24. The operator (data controller) is
    {{ LEGAL_OPERATOR }}, {{ OPERATOR_JURISDICTION }}. Registered with
    the UK Information Commissioner&rsquo;s Office under reference
    <strong>ZC098928</strong>. Questions:
    <a href="mailto:{{ OPERATOR_EMAIL }}">{{ OPERATOR_EMAIL }}</a>.
  </p>
  <p>
    This page describes exactly what we collect, what we don&rsquo;t,
    where it lives, and how long we keep it. It is written from the code,
    not from a template &mdash; every claim corresponds to an explicit
    code path we&rsquo;re happy to point a reviewer at.
  </p>
</section>

<section class="public-section">
  <h2 class="public-section__head">What we collect</h2>
  <ul>
    <li>
      <strong>Your email address</strong>, when you sign in. We use it
      only to send one-time login codes.
    </li>
    <li>
      <strong>An argon2 hash of each login code</strong>, plus expiry
      and attempt counts. The plaintext code is sent to your inbox and
      never written to disk on our side.
    </li>
    <li>
      <strong>A signed session cookie</strong> after you verify a code.
      It contains your user id only and is signed so we can detect
      tampering. Cookie is marked Secure and HttpOnly.
    </li>
    {# Cloud sync + server-side per-ticker aggregate union are flag-gated off.
       See docs/read-markets-compliance-changes.md and app/config.py
       (PORTFOLIO_SYNC_ENABLED, TICKER_UNIVERSE_AGGREGATE_ENABLED). #}
    <li>
      <strong>Anonymised cost ledger</strong> of AI calls (model, tokens,
      cost). No portfolio or personal data is attached to ledger rows.
    </li>
    <li>
      <strong>Referral linkage</strong>: if you signed up via an invite
      link, we record which existing user&rsquo;s code you used so we can
      apply the agreed referral credit later.
    </li>
    <li>
      <strong>Job-run telemetry</strong>: success/failure timestamps for
      the scheduled jobs that fetch market data and generate AI reads.
      No user identifiers are attached.
    </li>
  </ul>
</section>

<section class="public-section">
  <h2 class="public-section__head">What we don&rsquo;t collect</h2>
  <ul>
    <li>
      <strong>Your portfolio holdings, in any form, on the server.</strong>
      The portfolio feature is a browser-only composition viewer:
      uploaded CSVs are parsed and returned to your browser, kept in
      <code>localStorage</code>, and never sent back to or stored on
      the server. The server records no per-ticker aggregate of what
      anyone holds.
    </li>
    <li>
      <strong>Third-party analytics or ad cookies.</strong> No Google
      Analytics, no Hotjar, no Segment, no Facebook pixel, no LinkedIn
      tag. (You can verify by viewing-source on any page.)
    </li>
    <li>
      <strong>Browser fingerprints.</strong>
    </li>
    <li>
      <strong>IP-address joins to your user identity.</strong> IP
      addresses are processed transiently by the reverse proxy for
      security and access logging, retained for up to 30 days, and not
      linked to your account record.
    </li>
  </ul>
</section>

<section class="public-section">
  <h2 class="public-section__head">Lawful basis (UK-GDPR Art. 6)</h2>
  <p>We rely on the following lawful bases:</p>
  <ul>
    <li>
      <strong>Performance of a contract</strong> (Art. 6(1)(b)) &mdash; for
      operating your account, the sign-in flow, and any paid features.
    </li>
    <li>
      <strong>Legitimate interests</strong> (Art. 6(1)(f)) &mdash; for the
      anonymised cost ledger, job-run telemetry, and reverse-proxy access
      logs. Our interest is the secure, abuse-resistant, cost-controlled
      operation of a free public service, balanced against the minimal
      and de-identified nature of the data.
    </li>
  </ul>
</section>

<section class="public-section">
  <h2 class="public-section__head">Automated decisions and profiling</h2>
  <p>
    The Service does not make decisions about you that produce legal or
    similarly significant effects in an automated way (UK-GDPR Art. 22).
    The strategic log and indicator summaries are general editorial
    commentary on public market data, not personalised assessments of
    you, and you remain the sole decision-maker about anything in your
    account.
  </p>
</section>

<section class="public-section">
  <h2 class="public-section__head">Cookies and local storage</h2>
  <ul>
    <li>
      <strong>Session cookie</strong> &mdash; strictly necessary for keeping
      you signed in (PECR reg. 6(4)). No prior consent required.
    </li>
    <li>
      <strong>Local preferences</strong> &mdash; your chosen theme (light /
      dark) and reading level (Novice / Intermediate) are stored in
      <code>localStorage</code> on your device. They never leave the
      browser.
    </li>
    <li>
      <strong>Local portfolio</strong> &mdash; parsed pies live in
      <code>localStorage</code> on your device. They are not sent to
      or stored on the server.
    </li>
  </ul>
</section>

<section class="public-section">
  <h2 class="public-section__head">Where the data lives, and international transfers</h2>
  <p>
    The server runs in {{ OPERATOR_JURISDICTION }}. Data is stored in a
    MariaDB database on the same host, backed up locally.
  </p>
  <p>
    Two flows can take personal data outside the UK:
  </p>
  <ul>
    <li>
      <strong>SMTP</strong> for sending one-time login codes. Operator-hosted,
      currently inside the UK; if that changes we will update this notice.
    </li>
    <li>
      <strong>AI provider calls</strong> for the strategic log and
      indicator summaries. Where the provider sits outside the UK, we
      rely on the UK International Data Transfer Agreement (IDTA) / the
      UK Addendum to the EU Standard Contractual Clauses where no
      adequacy decision applies. Each outbound request carries an
      explicit no-training opt-out header
      (<code>X-OR-Allow-Training: false</code> on OpenRouter); see the
      Third parties section below for the caveats. None of these
      outbound requests contain user holdings or other portfolio data.
    </li>
  </ul>
</section>

<section class="public-section">
  <h2 class="public-section__head">Retention</h2>
  <ul>
    <li>
      <strong>Login codes</strong>: expire after a few minutes; row
      remains briefly to enforce single-use, then is purged.
    </li>
    <li>
      <strong>Session cookies</strong>: expire automatically; you can
      sign out at any time to revoke.
    </li>
    <li>
      <strong>Account</strong>: held until you ask us to delete it.
      Email <a href="mailto:{{ OPERATOR_EMAIL }}">{{ OPERATOR_EMAIL }}</a>.
    </li>
    <li>
      <strong>Cost ledger and job telemetry</strong>: retained for
      operational accounting; no personal data attached.
    </li>
  </ul>
</section>

<section class="public-section">
  <h2 class="public-section__head">Third parties</h2>
  <ul>
    <li>
      <strong>SMTP provider</strong>: an operator-hosted Mailu server
      sends the one-time login codes. The provider sees your email
      address and the code body (the code itself).
    </li>
    <li>
      <strong>AI provider(s)</strong>: DeepSeek (primary) with OpenRouter
      as a fallback. They see the prompt for the strategic log and the
      indicator summaries. These prompts contain public market data and
      headlines &mdash; never any user holdings or portfolio data.
      <br>
      <strong>No-training opt-out.</strong> Every OpenRouter request
      carries the <code>X-OR-Allow-Training: false</code> header, which
      signals to OpenRouter and any compatible upstream that the prompt
      must not be used to train or improve models. DeepSeek does not
      currently expose a per-request opt-out. We do not control
      retention or training policies on the provider side beyond the
      headers we set &mdash; the provider&rsquo;s own published data policy is
      the binding statement on that point.
    </li>
    <li>
      <strong>Market-data sources</strong>: Yahoo Finance and a small set
      of public RSS feeds. We request prices and headlines; we don&rsquo;t
      send them any user identifier.
    </li>
  </ul>
</section>

<section class="public-section">
  <h2 class="public-section__head">Your rights (UK-GDPR)</h2>
  <p>You have the right to:</p>
  <ul>
    <li>Ask what personal data we hold about you (Art. 15, right of access).</li>
    <li>Have inaccurate data corrected (Art. 16, rectification).</li>
    <li>Have your account and associated data deleted (Art. 17, erasure).</li>
    <li>Export the data you can recognise (Art. 20, portability): your
        email and your referral linkage.</li>
    <li>Restrict processing (Art. 18).</li>
    <li>Object specifically to processing carried out on the basis of
        legitimate interests (Art. 21), including any direct marketing.</li>
    <li>Withdraw consent at any time where processing is based on
        consent (Art. 7(3)), e.g. by disabling cloud sync.</li>
    <li>Lodge a complaint with the
      <a href="https://ico.org.uk/" target="_blank" rel="noopener">Information Commissioner&rsquo;s Office</a>
      if you think we&rsquo;re mishandling your data.</li>
  </ul>
  <p>
    Email <a href="mailto:{{ OPERATOR_EMAIL }}">{{ OPERATOR_EMAIL }}</a> to
    exercise any of these.
  </p>
</section>

<section class="public-section">
  <h2 class="public-section__head">Children</h2>
  <p>
    The Service is not directed at, and is not intended for use by,
    anyone under 18. Do not create an account if you are under 18. If
    you believe a child has provided personal data to us, contact
    <a href="mailto:{{ OPERATOR_EMAIL }}">{{ OPERATOR_EMAIL }}</a> and we
    will delete it.
  </p>
</section>

<section class="public-section">
  <h2 class="public-section__head">Security incidents</h2>
  <p>
    If we discover a personal-data breach likely to result in a risk to
    your rights and freedoms, we will notify the ICO within 72 hours of
    becoming aware of it, as required by UK-GDPR Art. 33, and notify
    affected users without undue delay where Art. 34 requires.
  </p>
</section>

<section class="public-section">
  <h2 class="public-section__head">Changes to this notice</h2>
  <p>
    Material changes will be flagged in-app and dated above. Trivial
    edits (grammar, restructuring) won&rsquo;t.
  </p>
</section>

{% endblock %}
