/* =========================================================================
 *  CTWCAD — Privacy Policy (gated)
 *  -----------------------------------------------------------------------
 *  Reachable at /legal/privacy. GATED: visitors must be Google-signed-in
 *  AND on /access/config.allowedEmails (or be the owner) before they can
 *  read this page. This is unusual — most privacy policies are public —
 *  but it matches the rest of the private-beta posture: only allowlisted
 *  users see anything.
 *
 *  Client-side gate is UX, not security. The policy text itself is just
 *  a JSX literal embedded here, so a determined visitor could still read
 *  it by inspecting the bundle. That's fine — there's nothing secret in
 *  the policy. The gate stops casual visitors from seeing a "we collect
 *  your CAD data" disclosure with no context, which would be confusing.
 *
 *  Version is hard-coded as POLICY_VERSION below; bump it when material
 *  changes ship. The Fusion 360 consent flow records the version a user
 *  agreed to so we can re-prompt for re-authorization on a bump.
 * =======================================================================*/

// Top-level React destructure — same pattern admin.jsx + account.jsx use.
// Avoids a class of "React.something is undefined" failures when Babel-
// standalone wraps each text/babel script in a way that doesn't expose
// React.* shorthand inside JSX expressions.
const { useState, useEffect } = React;

const POLICY_VERSION = "1.0";
const POLICY_EFFECTIVE = "2026-05-04";

/* ---------- Per-component error boundary for the policy markup ------
   Catches render-time exceptions inside the long policy JSX (or the
   gate logic above it) and renders a graceful card instead of a white
   screen. Sits INSIDE LegalPrivacyView's shell so the user still sees
   the page chrome and a link to the static fallback at /privacy.txt. */
class PrivacyErrorBoundary extends React.Component {
  constructor(props) {
    super(props);
    this.state = { error: null };
  }
  static getDerivedStateFromError(error) { return { error }; }
  componentDidCatch(error, info) {
    console.error("[CTWCAD] privacy policy render error:", error, info);
  }
  render() {
    if (!this.state.error) return this.props.children;
    return (
      <div className="ct-legal-gate" style={{ textAlign: "left" }}>
        <h1>Couldn't render the policy here.</h1>
        <p className="ct-dim">
          The page hit a render error before it could finish drawing the
          policy. The text is still available — open the plain-text
          version below, or email{" "}
          <a href="mailto:sethbenricks@gmail.com">sethbenricks@gmail.com</a>.
        </p>
        <div style={{ display: "flex", gap: 8, marginTop: 16, flexWrap: "wrap" }}>
          <a className="ct-btn ct-btn-primary" href="/privacy.txt" target="_blank" rel="noopener">
            Open /privacy.txt
          </a>
          <button className="ct-btn ct-btn-ghost" onClick={() => window.location.reload()}>
            Reload
          </button>
        </div>
        {this.state.error && this.state.error.message && (
          <details style={{ marginTop: 14 }}>
            <summary className="ct-mono ct-dim" style={{ fontSize: 11, cursor: "pointer" }}>
              error detail
            </summary>
            <pre className="ct-mono ct-dim" style={{ fontSize: 11, whiteSpace: "pre-wrap", marginTop: 6 }}>
              {String(this.state.error.message)}
              {this.state.error.stack ? "\n\n" + String(this.state.error.stack) : ""}
            </pre>
          </details>
        )}
      </div>
    );
  }
}

const TOC = [
  { id: "1",     label: "Introduction" },
  { id: "2",     label: "Who we are" },
  { id: "3",     label: "Information we collect" },
  { id: "3.1",   label: "Account information",            sub: true },
  { id: "3.2",   label: "Files & CAD data",               sub: true },
  { id: "3.3",   label: "Fusion 360 plugin data",         sub: true },
  { id: "3.4",   label: "Diagnostic bundles",             sub: true },
  { id: "3.5",   label: "Usage, device & cookies",        sub: true },
  { id: "3.6",   label: "Third-party data",               sub: true },
  { id: "4",     label: "How we use your information" },
  { id: "4.1",   label: "Operating the Service",          sub: true },
  { id: "4.2",   label: "Communicating with you",         sub: true },
  { id: "4.3",   label: "Improving & training AI",        sub: true },
  { id: "4.4",   label: "Security & abuse prevention",    sub: true },
  { id: "4.5",   label: "Legal compliance",               sub: true },
  { id: "5",     label: "How we share your information" },
  { id: "6",     label: "Your rights & choices" },
  { id: "7",     label: "Data retention" },
  { id: "8",     label: "Security" },
  { id: "9",     label: "International users" },
  { id: "10",    label: "Children's privacy" },
  { id: "11",    label: "California (CCPA / CPRA)" },
  { id: "12",    label: "Europe / UK (GDPR)" },
  { id: "13",    label: "Changes to this Policy" },
  { id: "14",    label: "Contact us" },
];

function LegalPrivacyView({ user, signedIn, onSignIn }) {
  // No gate — the privacy policy is public. Anyone (signed-in or not)
  // can read it. The previous client-side gate kept causing white-
  // screens for users whose allowlist cache was stale, and gating a
  // privacy policy was unusual to begin with: the standard for any
  // service is that this document is reachable BEFORE the user
  // decides whether to sign in. Static text, no PII, nothing to gate.

  const goHome = (e) => {
    if (e) e.preventDefault();
    if (typeof window.CTWCAD_NAV === "function") window.CTWCAD_NAV("/");
    else window.location.assign("/");
  };

  return (
    <div className="ct-legal-page">
      <div className="ct-legal-bar">
        <button className="ct-btn ct-btn-ghost" onClick={goHome}>← Back to CTWCAD</button>
        <span className="ct-mono ct-dim">Privacy Policy v{POLICY_VERSION} · Effective {POLICY_EFFECTIVE}</span>
      </div>
      <PrivacyErrorBoundary>
      <div className="ct-legal-shell">
        <aside className="ct-legal-toc" aria-label="Table of contents">
          <div className="ct-eyebrow ct-mono">CONTENTS</div>
          {TOC.map(t => (
            <a key={t.id} href={`#sec-${t.id}`}
               className={"ct-legal-toc-link" + (t.sub ? " is-sub" : "")}>
              <span className="ct-mono ct-dim">{t.id}</span>
              <span>{t.label}</span>
            </a>
          ))}
        </aside>
        <article className="ct-legal-content">
          <h1>CTWCAD Privacy Policy</h1>
          <div className="ct-legal-meta ct-mono ct-dim">
            Effective: {POLICY_EFFECTIVE} · Version {POLICY_VERSION}
          </div>

          <p>
            This Privacy Policy explains how CTWCAD ("CTWCAD," "we," "us")
            collects, uses, shares, and protects information when you use our
            website at ctwcad.com, the CTWCAD desktop application, the CTWCAD
            mobile application, the CTWCAD Fusion 360 plugin, and any related
            services (together, the "Service"). It also describes the rights
            you have over your information and how to exercise those rights.
          </p>
          <p>
            Read this policy alongside our Terms of Service, which govern your
            use of the Service.
          </p>
          <p>
            This policy applies to information about CTWCAD users. It does
            not cover the practices of third-party services that operate
            independently of CTWCAD, even when those services integrate with
            the Service — notably Google's Fusion 360, your Google Account,
            and any other third-party design tool you use. Their practices
            are governed by their own privacy policies.
          </p>

          <h2 id="sec-1">1. Introduction</h2>
          <p>
            CTWCAD is a CAD environment that pairs a local design experience
            with cloud sync, collaboration, and AI-assisted design tools. The
            Service is in private beta, available by invitation. This Policy
            describes what information the Service collects from you, how we
            use that information, who we share it with, how long we keep it,
            and what choices you have.
          </p>
          <p>
            We have written this Policy to be readable. Where a section uses
            defined legal terms, we explain them in plain language afterwards.
          </p>
          <p>
            By creating an account, signing in, or otherwise using the
            Service, you confirm you have read this Policy. Specific features
            of the Service — including the CTWCAD Fusion 360 plugin —
            require an additional, explicit authorization step that
            references this Policy by version. You can revoke that
            authorization at any time. See §6.4.
          </p>

          <h2 id="sec-2">2. Who we are</h2>
          <p>
            CTWCAD is operated by Seth Ricks ("the operator"), at the email
            address listed in §14. CTWCAD is a private-beta service and does
            not currently operate as an incorporated entity; references in
            this Policy to "CTWCAD," "we," "our," or "us" should be read as
            references to the operator and any contractors operating under
            the operator's direction.
          </p>
          <p>
            If CTWCAD reorganizes or incorporates, we will update §2 and
            §13.3 with the new operating entity. Material changes are
            governed by §13.
          </p>

          <h2 id="sec-3">3. Information we collect</h2>
          <h3 id="sec-3.1">3.1 Account information.</h3>
          <p>
            When you sign in to CTWCAD with Google, we receive your Google
            account identifier, email address, display name, and (where you
            have set one) profile photo. We use these to create and maintain
            your CTWCAD account. We do not receive your Google password.
          </p>
          <p>
            We also store your role in CTWCAD (member, admin, or owner), the
            allowlist entry that authorized your access, an avatar color we
            generate from your email, your storage limit, and the timestamps
            for account creation, last update, and most recent sign-in.
          </p>

          <h3 id="sec-3.2">3.2 Files and CAD data you upload to ctwcad.com.</h3>
          <p>
            When you upload files through the website, the desktop app, or
            the mobile app, we store the file content (CAD geometry, document
            data, images, PDFs, and any other format you upload), the file's
            name, size, content type, your specified folder and project, the
            version history you create, your share settings (private, link,
            public-read), any tags or comments you attach, and your editing
            timestamps.
          </p>
          <p>
            We also store a small amount of generated metadata: a thumbnail
            seed used to render previews, the inferred file kind (e.g.
            "step", "stl", "image"), and a download URL token from Firebase
            Storage so the website and apps can fetch the file.
          </p>

          <h3 id="sec-3.3">3.3 Fusion 360 plugin data.</h3>
          <p>
            If you install and authorize the CTWCAD Fusion 360 plugin, the
            plugin transmits the data described in §3.3.1 and §3.3.2 to our
            servers. Authorization is explicit: the plugin opens this website
            and asks you to agree to this Policy before any data is
            transmitted. You can revoke the authorization at any time
            (§6.4); revocation stops further data transmission.
          </p>
          <h4>3.3.1 Geometry, parameters, sketches.</h4>
          <p>
            For each Fusion 360 document you save while the plugin is active,
            the plugin transmits the document's three-dimensional geometry,
            its parametric feature tree (the ordered sequence of features
            such as extrudes, fillets, holes, patterns, and assemblies), the
            sketches you have constructed including their geometric and
            dimensional constraints, every parameter and the relationships
            you have defined between parameters, the document and project
            names, and the timestamps for document creation and last save.
          </p>
          <p>
            We have full access to this data once it reaches our servers.
            We process it as described in §4.
          </p>
          <h4>3.3.2 Edit history and workflow signals.</h4>
          <p>
            Where Fusion 360 exposes the data and you have not turned off
            edit history transmission, the plugin also transmits the order
            in which you constructed your features, modifications and undos
            you performed, the sequence in which you defined parameters and
            assigned constraints, and the time you spent on each feature.
            We refer to this collectively as "workflow signals."
          </p>
          <p>
            Workflow signals are the primary input to the AI models
            described in §4.3. Geometry alone does not tell us how an
            engineer thinks; the sequence of decisions does.
          </p>
          <h4>3.3.3 What the plugin does not transmit.</h4>
          <p>
            The plugin does not transmit your Fusion 360 account credentials
            (we authenticate you via Google OAuth, not Autodesk), Fusion 360
            documents that you opened but did not save while the plugin was
            active, files or data outside Fusion 360 (other applications,
            your operating system, your filesystem outside the plugin's
            working directories), or add-in data unrelated to the CAD
            workspace.
          </p>
          <p>
            The plugin does not screenshot your display, keylog your input,
            or transmit any data while you are not actively saving a Fusion
            360 document.
          </p>

          <h3 id="sec-3.4">3.4 Desktop application diagnostic bundles.</h3>
          <p>
            The CTWCAD Windows desktop app, when configured to do so, uploads
            a session diagnostic bundle to the cloud at the close of each
            session. The bundle contains structured logs from your session:
            which features you used, which files you opened, errors and
            warnings the app encountered, and crash reports if any occurred.
            The bundle is uploaded to a per-user, owner-readable Storage
            location.
          </p>
          <p>
            You — and only you — can read your own diagnostic bundles via
            the "My Diagnostics" page on the website. Other users, including
            users with admin role, cannot read your diagnostics. The CTWCAD
            operator can read diagnostics through the Firebase console for
            the purposes of investigating issues you report; we will tell you
            when we do.
          </p>

          <h3 id="sec-3.5">3.5 Usage data, device data, and cookies.</h3>
          <p>
            When you visit ctwcad.com or use the apps, we automatically
            collect information about how you use the Service: the pages
            you visit, the features you click, the projects and folders
            you open, the duration of your sessions, and aggregate
            performance metrics like page load time and animation frame
            rate. This information is associated with your account when
            you are signed in.
          </p>
          <p>
            We collect device information including operating system and
            version, browser name and version, screen size and pixel
            density, and a generated device identifier we use to recognize
            your sign-in across the desktop app, the mobile app, and the
            website.
          </p>
          <p>
            We use cookies, local storage, and equivalent browser storage
            technologies to keep you signed in, remember your theme
            preference, remember which folders you had open, cache portions
            of your CTWCAD data so the app loads quickly, and for similar
            quality-of-life purposes. We do not use third-party analytics
            cookies.
          </p>

          <h3 id="sec-3.6">3.6 Information from third parties.</h3>
          <p>
            When you sign in with Google, we receive the information
            described in §3.1 from Google. When you upload files, the
            underlying storage service (Firebase Storage / Google Cloud
            Storage) processes them on our behalf and provides us with
            usage and access metadata.
          </p>
          <p>
            When you connect a desktop or mobile device, we may receive a
            Firebase Cloud Messaging registration token associated with that
            device so we can deliver push notifications you have opted in
            to receive (for example, the desktop sign-in approval push from
            your phone).
          </p>

          <h2 id="sec-4">4. How we use your information</h2>
          <h3 id="sec-4.1">4.1 Operating and maintaining the Service.</h3>
          <p>
            We use your information to provide the Service: to authenticate
            you, serve your files, render your projects and folders, run
            searches you initiate, sync between your devices, deliver email
            and push notifications you have opted in to, enforce your
            storage quota, and operate every feature you interact with.
          </p>

          <h3 id="sec-4.2">4.2 Communicating with you.</h3>
          <p>
            We use your contact information to send you transactional emails
            (account confirmations, security alerts, sign-in approvals,
            password or session resets), respond to support requests, and
            notify you of material changes to this Policy or our Terms of
            Service.
          </p>
          <p>
            We do not currently send marketing email. If we begin sending
            marketing email, you will be able to opt out via an unsubscribe
            link in every such message.
          </p>

          <h3 id="sec-4.3">4.3 Improving the Service and training AI models.</h3>
          <p>
            CTWCAD includes AI-assisted design tools that propose features,
            parameters, and construction sequences as you work. To make
            these tools useful, we train and refine machine learning models
            using data collected through the Service. The Fusion 360 plugin
            data described in §3.3 is the primary input to that training;
            the website-uploaded files described in §3.2 may also be used
            for training where you have not opted out (§6.5).
          </p>
          <h4>4.3.1 What "training on workflow patterns" means.</h4>
          <p>
            We extract aggregated, anonymized signals from your workflow
            data — which features tend to follow which other features,
            common sketch construction patterns, parameter naming
            conventions, the shape of dependency graphs in parametric
            models, and similar patterns. These signals feed machine
            learning models that power CTWCAD's design assistant, similar
            features, and search.
          </p>
          <h4>4.3.2 How we anonymize and aggregate.</h4>
          <p>
            Before workflow signals enter a training run, an anonymization
            pipeline strips file names, project names, parameter names that
            contain identifying strings, and any user-identifying metadata.
            Models train on patterns that recur across many users; no model
            is trained from a single user's data alone, and no training
            output is keyed to a specific user's identity.
          </p>
          <p>
            We retain the un-anonymized source data so we can re-run
            anonymization when we improve the pipeline, and so you can
            exercise your access and deletion rights against the original
            data (§6.1, §6.3).
          </p>
          <h4>4.3.3 What we will not train on.</h4>
          <p>
            We do not train models to reproduce, replicate, or
            reverse-engineer your specific designs. We do not use the
            geometry or visual appearance of your CAD work as a training
            output. The product of training is a model that understands
            engineering process, not a model that knows what you have built.
          </p>
          <p>
            If you opt out of training (§6.5), data we collected from you
            after the opt-out date is excluded from training datasets going
            forward. Models that were trained on data we collected before
            the opt-out cannot be retroactively un-trained — that is a
            limitation of how machine learning models work — but we will
            exclude you from future training runs.
          </p>

          <h3 id="sec-4.4">4.4 Security, abuse prevention, and incident response.</h3>
          <p>
            We use your information to detect and prevent fraud, abuse,
            and security incidents; to enforce our Terms of Service; and
            to defend the Service. This may include analyzing usage
            patterns to identify unauthorized access attempts, inspecting
            reported content, and preserving evidence in connection with
            a security incident.
          </p>

          <h3 id="sec-4.5">4.5 Legal compliance.</h3>
          <p>
            We use your information to comply with applicable law and
            regulation, including responding to lawful subpoenas and
            court orders (§5.4).
          </p>

          <h2 id="sec-5">5. How we share your information</h2>
          <h3>5.1 Service providers and infrastructure.</h3>
          <p>
            We host the Service on Google Cloud Platform via Firebase:
            Firestore for structured data, Cloud Storage for file blobs,
            Cloud Functions for server-side logic, Firebase Authentication,
            and Firebase Cloud Messaging. Google processes your data on our
            behalf as a data processor; Google's Cloud Data Processing
            Addendum governs that processing.
          </p>
          <p>
            We do not currently use other third-party processors. If we add
            a processor, we will update §5.1 with their identity, the
            purpose of the processing, and (where applicable) the
            contractual safeguards in place.
          </p>
          <h3>5.2 Collaborators you choose.</h3>
          <p>
            When you share a project, folder, or file with another user —
            by adding them as a member, by sharing a link, or by enabling
            public-read on a specific file — that user gets the access
            level you chose. We do not share your data with collaborators
            you have not selected.
          </p>
          <h3>5.3 Aggregated and de-identified disclosures.</h3>
          <p>
            We may publish or share aggregated and de-identified information
            that does not identify you (for example, total user count, total
            file count by file type, average parameters per parametric
            model). Such disclosures do not constitute sharing of your
            personal information.
          </p>
          <h3>5.4 Legal requests and protective disclosures.</h3>
          <p>
            We may disclose your information when required to do so by law,
            including in response to a subpoena, court order, or other legal
            process. We may also disclose your information when we have a
            good-faith belief that disclosure is necessary to protect the
            safety of any person, to address fraud or security issues, to
            enforce our Terms of Service, or to protect our legal rights.
          </p>
          <p>
            If we receive a legal request for your data, we will (where
            permitted) attempt to notify you so that you can exercise your
            rights.
          </p>
          <h3>5.5 Business transitions.</h3>
          <p>
            If CTWCAD is sold, merges with another entity, restructures,
            files for bankruptcy, or otherwise undergoes a business
            transition, your information may be transferred to the new
            entity. The new entity will be bound by this Policy or a
            successor policy that protects your information at least as
            much. We will notify you of the transition in advance where
            reasonably possible.
          </p>
          <h3>5.6 We do not sell personal information.</h3>
          <p>
            We do not sell your personal information for monetary
            consideration. We do not currently engage in "sharing" your
            personal information for cross-context behavioral advertising
            as that term is defined under California law. See §11.4 for
            the formal CCPA / CPRA notice.
          </p>

          <h2 id="sec-6">6. Your rights and choices</h2>
          <h3>6.1 Accessing and downloading your data.</h3>
          <p>
            You can view all of the personal information CTWCAD holds about
            you through your account on the website. You can download your
            files individually via the file drawer's Download button, in
            bulk via a project's Export-as-ZIP, and in raw form by emailing
            us a request under §14.
          </p>
          <h3>6.2 Correcting your data.</h3>
          <p>
            You can update your name, profile photo, and email through your
            Google Account; the Service automatically reflects those
            changes. You can rename your files, folders, and projects from
            the website.
          </p>
          <p>
            If you discover an error in CTWCAD's records that you cannot
            correct yourself, contact us under §14 and we will correct it
            within 30 days.
          </p>
          <h3>6.3 Deleting your data.</h3>
          <p>
            You can move individual files to Trash, permanently delete
            trashed files, and delete entire projects through the website.
            You can revoke the Fusion 360 plugin authorization at any time
            (§6.4) and request deletion of all data the plugin has uploaded
            by emailing us under §14.
          </p>
          <p>
            You can request that we close your account and delete all of
            your data. We will complete the deletion within 30 days of your
            request, subject to the retention exceptions in §7.
          </p>
          <h3>6.4 Revoking the Fusion 360 authorization.</h3>
          <p>
            The Fusion 360 plugin authorization is revocable at any time.
            To revoke, visit ctwcad.com/settings → Connected apps & training,
            and click "Revoke Fusion 360 authorization." Once revoked:
          </p>
          <ul>
            <li>The plugin stops transmitting data on its next sync attempt.</li>
            <li>Your previously-transmitted data is excluded from new training runs going forward.</li>
            <li>Models that were trained before revocation are not affected, as described in §4.3.3.</li>
          </ul>
          <p>
            You can re-authorize the plugin at any time by signing in to
            the plugin again. Re-authorization references the version of
            this Policy in effect at the time and will require you to
            agree to that version.
          </p>
          <h3>6.5 Opting out of training.</h3>
          <p>
            You can opt out of having your data — both Fusion 360 plugin
            data and ctwcad.com files — used to train models. To opt out,
            email us under §14 with the subject line "OPT OUT OF
            TRAINING." Your opt-out takes effect within seven days. Data
            we collect from you after the opt-out date is excluded from
            training datasets going forward; see §4.3.3 for the
            limitation on retroactive opt-out.
          </p>
          <h3>6.6 Closing your account.</h3>
          <p>
            You can request that we close your CTWCAD account by emailing
            us under §14 with the subject line "CLOSE MY ACCOUNT." We will
            close the account, delete your stored files, and delete your
            account information within 30 days. We will retain audit logs
            and de-identified analytics as described in §7.
          </p>

          <h2 id="sec-7">7. Data retention</h2>
          <h3>7.1 Active account data.</h3>
          <p>
            We retain account information, files, and metadata for as long
            as your account is active. If you do not sign in for twelve
            consecutive months, we may notify you that your account will
            be closed for inactivity and proceed with closure 30 days
            after notice.
          </p>
          <h3>7.2 Trashed files.</h3>
          <p>
            Files you move to Trash remain recoverable for 30 days, after
            which they are permanently deleted. You can permanently delete
            a trashed file before the 30-day period elapses.
          </p>
          <h3>7.3 Diagnostic bundles and audit logs.</h3>
          <p>
            Session diagnostic bundles uploaded by the desktop app (§3.4)
            are retained for 90 days, after which they are automatically
            deleted unless you have specifically asked us to preserve a
            bundle for issue investigation. Audit logs of administrative
            actions are retained for two years for security and compliance
            purposes.
          </p>
          <h3>7.4 Training datasets and trained models.</h3>
          <p>
            Anonymized workflow signals used in training datasets are
            retained for the lifetime of the model trained on them, plus
            seven years. Trained models are retained indefinitely. Both
            are subject to your opt-out (§6.5) for going-forward training;
            the retroactive limitations described in §4.3.3 apply.
          </p>

          <h2 id="sec-8">8. Security</h2>
          <h3>8.1 Encryption in transit and at rest.</h3>
          <p>
            All connections to the Service use TLS 1.2 or higher. Data
            stored in Firebase Storage is encrypted at rest under
            Google-managed encryption keys. Data stored in Firestore is
            encrypted at rest under Google-managed encryption keys.
          </p>
          <h3>8.2 Access controls.</h3>
          <p>
            Access to your data is controlled by Firebase Security Rules
            configured to enforce the access boundaries described in this
            Policy: non-owner admins cannot read other users' diagnostic
            bundles, the Fusion 360 plugin can only write to your own
            data, and other rules specific to each collection. Rules are
            versioned in our source control and reviewed before each
            deploy.
          </p>
          <p>
            The CTWCAD operator has administrative access to the underlying
            Firebase project for the purposes described in §3.4 and §4.
            The operator does not access your CAD geometry or design
            content as a matter of routine.
          </p>
          <h3>8.3 Incident notification.</h3>
          <p>
            If we discover a security incident affecting your personal
            information, we will notify you within 72 hours of discovery
            (or as soon as reasonably possible, where 72 hours is not
            feasible) by email. The notification will describe the nature
            of the incident, the information involved, the steps we are
            taking, and what you can do.
          </p>

          <h2 id="sec-9">9. International users and cross-border transfers</h2>
          <p>
            The Service is operated from the United States. If you access
            the Service from outside the United States, your information
            will be transferred to and processed in the United States. By
            using the Service, you consent to that transfer.
          </p>
          <p>
            For users in the European Economic Area, the United Kingdom,
            and Switzerland, see §12 for the legal bases and protections
            that apply to your data.
          </p>

          <h2 id="sec-10">10. Children's privacy</h2>
          <p>
            The Service is not directed to children under the age of 16,
            and we do not knowingly collect information from children under
            16. If you believe we have collected information from a child
            under 16, contact us under §14 and we will delete the
            information promptly.
          </p>

          <h2 id="sec-11">11. Notice for California residents (CCPA / CPRA)</h2>
          <p>
            This section provides additional disclosures required for
            California residents under the California Consumer Privacy Act,
            as amended by the California Privacy Rights Act.
          </p>
          <h3>11.1 Categories of personal information we collect.</h3>
          <p>
            In the past 12 months, we have collected the following
            categories of personal information from California residents:
            identifiers (name, email, Google account ID, IP address, device
            identifier); customer records information (account profile
            data); commercial information (account creation date, sign-in
            history); internet activity (usage data, cookies as described
            in §3.5); geolocation data (only the country derived from IP);
            professional information (CAD designs and related work product
            as described in §3.2 and §3.3); and inferences drawn from the
            above (the workflow signals described in §3.3.2).
          </p>
          <h3>11.2 Sources, purposes, and disclosures.</h3>
          <p>
            We collect personal information from the sources described in
            §3. We use it for the purposes described in §4. We disclose
            it to the recipients described in §5. We do not sell or share
            personal information.
          </p>
          <h3>11.3 Your CCPA / CPRA rights.</h3>
          <p>
            You have the right to know what personal information we have
            collected about you (§6.1), correct inaccurate information
            (§6.2), delete your information (§6.3 / §6.6), opt out of the
            sale or sharing of your information (we do not sell or share,
            but the right exists), limit our use of sensitive personal
            information, and not be discriminated against for exercising
            any of these rights.
          </p>
          <p>
            To exercise these rights, email us under §14. We will respond
            within 45 days. We may need to verify your identity before
            responding; we will not ask you for more information than
            necessary to do so.
          </p>
          <h3>11.4 We do not sell or share personal information.</h3>
          <p>
            We have not sold or shared the personal information of
            California residents in the past 12 months.
          </p>

          <h2 id="sec-12">12. Notice for European, UK, and Swiss residents (GDPR)</h2>
          <h3>12.1 Roles.</h3>
          <p>
            For the purposes of the General Data Protection Regulation,
            the UK GDPR, and the Swiss Federal Act on Data Protection,
            CTWCAD is the data controller for personal information
            collected through the Service. Google (as Firebase) acts as
            a data processor on our behalf.
          </p>
          <h3>12.2 Legal bases for processing.</h3>
          <p>
            We process your personal information on the following legal
            bases:
          </p>
          <ul>
            <li><strong>Contract</strong> (Article 6(1)(b)): processing necessary to provide the Service you have requested.</li>
            <li><strong>Legitimate interests</strong> (Article 6(1)(f)): processing necessary for our legitimate interests in operating, improving, and securing the Service, where those interests are not overridden by your rights and freedoms. We use this basis for the security and abuse-prevention processing in §4.4.</li>
            <li><strong>Consent</strong> (Article 6(1)(a)): the Fusion 360 plugin authorization in §3.3 and §6.4 is processed under your explicit consent. Training-data use under §4.3 is processed under consent for plugin data and under legitimate interests for non-plugin data, subject to your opt-out (§6.5).</li>
            <li><strong>Legal obligation</strong> (Article 6(1)(c)): for the legal-compliance processing in §4.5 and §5.4.</li>
          </ul>
          <h3>12.3 Your rights under GDPR.</h3>
          <p>
            You have the right to access your data, rectify inaccuracies,
            request erasure, restrict processing, object to processing
            based on legitimate interests, and request data portability.
            To exercise any of these rights, email us under §14.
          </p>
          <h3>12.4 Right to lodge a complaint.</h3>
          <p>
            You have the right to lodge a complaint with a supervisory
            authority in the EU/EEA member state of your habitual
            residence, place of work, or place of the alleged infringement.
            In the United Kingdom, the supervisory authority is the
            Information Commissioner's Office (ico.org.uk).
          </p>
          <h3>12.5 Data Protection Officer.</h3>
          <p>
            CTWCAD has not appointed a designated Data Protection Officer
            because our processing does not meet the threshold for
            mandatory appointment under Article 37 of the GDPR. Privacy
            questions should be addressed to the contact in §14, with the
            subject line "PRIVACY QUESTION."
          </p>

          <h2 id="sec-13">13. Changes to this Policy</h2>
          <h3>13.1 How we communicate changes.</h3>
          <p>
            We will post any changes to this Policy at
            ctwcad.com/legal/privacy with a new effective date and an
            updated version number.
          </p>
          <h3>13.2 Material changes and re-authorization.</h3>
          <p>
            If a change to this Policy materially affects how we handle
            your information — for example, if we expand the categories
            of data we collect, add a new category of recipients, or
            change the purposes for which we use your data — we will (a)
            notify you by email, and (b) for the Fusion 360 plugin
            authorization, require you to re-authorize the plugin under
            the new version. Existing authorizations remain valid under
            the version of the Policy in effect at the time they were
            granted.
          </p>
          <h3>13.3 Version history.</h3>
          <ul>
            <li><strong>v1.0</strong> ({POLICY_EFFECTIVE}) — Initial publication.</li>
          </ul>

          <h2 id="sec-14">14. How to contact us</h2>
          <p>
            For privacy questions, requests under §6, or any other inquiry
            related to this Policy, contact:
          </p>
          <p className="ct-mono">
            Seth Ricks<br/>
            Email: <a href="mailto:sethbenricks@gmail.com">sethbenricks@gmail.com</a><br/>
            Subject line: PRIVACY (followed by your specific request)
          </p>
          <p>
            We will acknowledge your inquiry within seven days and respond
            substantively within the timelines specified in §6 and §11.
          </p>

          <hr/>
          <p className="ct-mono ct-dim" style={{textAlign:"center",fontSize:11.5,marginTop:32}}>
            End of CTWCAD Privacy Policy v{POLICY_VERSION}.
          </p>
        </article>
      </div>
      </PrivacyErrorBoundary>
    </div>
  );
}

/* =========================================================================
 *  PolicyAcceptanceView — required acceptance gate after sign-in
 *  -----------------------------------------------------------------------
 *  Sits BETWEEN the existing sign-in / allowlist gates and the routed
 *  app shell. Every signed-in + allowlisted user must accept the
 *  privacy policy once before they see any product surface. Re-prompts
 *  on a future POLICY_VERSION bump because the comparison is by
 *  version string. Skipped for /legal/privacy itself, /install, and
 *  the connect flow — those aren't part of the regular gated app.
 *
 *  Acceptance is mirrored to localStorage (`ctwcad.policyAccepted.{v}`)
 *  so subsequent loads don't need a Firestore round-trip. The Firestore
 *  field is the load-bearing record (cross-device coherency); localStorage
 *  is just a fast-path.
 * =======================================================================*/
function PolicyAcceptanceView({ user, onAccepted, onSignOut }) {
  const [ticked, setTicked] = useState(false);
  const [busy, setBusy] = useState(false);
  const [error, setError] = useState(null);
  const goPolicy = (e) => {
    e?.preventDefault();
    window.open("/legal/privacy/", "_blank", "noopener,noreferrer");
  };
  const accept = async () => {
    if (!ticked || busy) return;
    setBusy(true);
    setError(null);
    try {
      await window.api.setPolicyAcceptance(POLICY_VERSION);
      onAccepted?.({ version: POLICY_VERSION });
    } catch (err) {
      console.warn("[CTWCAD] setPolicyAcceptance failed:", err);
      // Surface the actual Firebase error code so the user (and Seth)
      // can debug from the UI instead of squinting at the console.
      const code = err?.code || err?.cause?.code;
      const msg = err?.message || err?.cause?.message;
      const detail = code ? `(${code})` : "";
      setError(
        code === "permission-denied"
          ? `Couldn't save your acceptance ${detail}. Sign out and sign back in, then try again. If it persists, email sethbenricks@gmail.com.`
          : (msg ? `Couldn't save acceptance: ${msg}` : "Couldn't save acceptance — try again.")
      );
    } finally {
      setBusy(false);
    }
  };
  const firstName = (user?.name || user?.email || "").split(" ")[0] || (user?.email || "");
  return (
    <div className="ct-legal-page">
      <div className="ct-policy-accept-card">
        <div className="ct-eyebrow ct-mono">CTWCAD — privacy notice</div>
        <h1>Welcome{firstName ? `, ${firstName}` : ""}.</h1>
        <p style={{ fontSize: 14.5, lineHeight: 1.6, margin: "10px 0 8px" }}>
          Before you start, take a quick look at our Privacy Policy. It
          covers what data CTWCAD collects across the website, the
          desktop app, the mobile app, and the Fusion 360 plugin — what
          we use it for, how long we keep it, and how to manage it.
        </p>
        <p style={{ fontSize: 14.5, lineHeight: 1.6, margin: "0 0 14px" }}>
          Your work stays yours. We use anonymized patterns from how
          engineers build to improve CTWCAD's tools — not your designs
          themselves.
        </p>
        <div style={{ margin: "10px 0 14px" }}>
          <a href="/legal/privacy" onClick={goPolicy}
             style={{ color: "var(--ct-accent)", fontSize: 14, textDecoration: "underline" }}>
            Read the full Privacy Policy →
          </a>
        </div>
        <label style={{
          display: "flex", alignItems: "flex-start", gap: 10,
          padding: "10px 12px", marginTop: 8,
          border: "1px solid var(--ct-border-soft, rgba(255,255,255,0.08))",
          borderRadius: 8, cursor: "pointer",
          background: ticked ? "rgba(91,157,249,0.06)" : "transparent",
        }}>
          <input
            type="checkbox"
            checked={ticked}
            onChange={(e) => setTicked(e.target.checked)}
            style={{ marginTop: 3 }}
          />
          <span style={{ fontSize: 13.5, lineHeight: 1.5 }}>
            I've read and agree to the Privacy Policy (v{POLICY_VERSION}).
          </span>
        </label>
        {error && (
          <div className="ct-mono" style={{ color: "var(--ct-danger)", fontSize: 12, marginTop: 8 }}>
            {error}
          </div>
        )}
        <div style={{ display: "flex", gap: 10, marginTop: 18, flexWrap: "wrap" }}>
          <button
            className="ct-btn ct-btn-primary ct-btn-lg"
            onClick={accept}
            disabled={!ticked || busy}>
            {busy ? "Saving…" : "Accept and continue"}
          </button>
          <button
            className="ct-btn ct-btn-ghost"
            onClick={onSignOut}
            disabled={busy}>
            Sign out
          </button>
        </div>
        <div className="ct-mono ct-dim" style={{ fontSize: 11, marginTop: 16 }}>
          Signed in as {user?.email}. You can revoke or update preferences
          anytime in Settings.
        </div>
      </div>
    </div>
  );
}

window.LegalPrivacyView = LegalPrivacyView;
window.PolicyAcceptanceView = PolicyAcceptanceView;
window.POLICY_VERSION = POLICY_VERSION;
window.POLICY_EFFECTIVE = POLICY_EFFECTIVE;
