/* global React, Common, I18n */
const { Eyebrow } = Common;
const { useT, useI18n } = I18n;
const { useEffect, useState } = React;

// =============================================================
// Terms of Service / End-User Agreement.
// Reflects the actual product:
//  - Source code under AGPL-3.0.
//  - Free tier (compile from source, BYOK).
//  - Pro tier (Stripe-backed subscription, signed binary, auto-update).
//  - Lifetime tier (one-time payment, 3 years of releases from purchase).
//  - 30-day refund, cancel anytime, students 40% off.
//  - License system: Ed25519-signed activation, Worker at license.dimmy.app.
//  - BYOK: cloud STT/LLM providers are billed and governed by the user.
// =============================================================

const COPY = {
  lastUpdated: { en: "Last updated: 2026-05-11", it: "Ultimo aggiornamento: 11 maggio 2026" },
  eyebrow: { en: "terms of service", it: "termini di servizio" },
  title: {
    en: ["The fine print.", "Plain English."],
    it: ["I dettagli.", "In italiano leggibile."],
  },
  lead: {
    en: "These are the terms that govern your use of Dimmy. They follow what the code actually does: source is open under AGPL-3.0, the binary distribution is paid, your API keys are yours, and we never charge anything we did not advertise.",
    it: "Questi sono i termini che regolano l'uso di Dimmy. Seguono ciò che il codice fa davvero: il sorgente è aperto sotto AGPL-3.0, la distribuzione del binario è a pagamento, le tue API key sono tue, e non addebitiamo mai nulla che non sia stato comunicato.",
  },
  disclaimer: {
    en: "Plain-English version below. The legally binding text is the same wording, written without lawyer ornaments. If something is unclear, write to konrad.dalla@gmail.com before clicking accept.",
    it: "Versione in italiano comprensibile qui sotto. Il testo legalmente vincolante è lo stesso, scritto senza ornamenti da avvocato. Se qualcosa non è chiaro, scrivi a konrad.dalla@gmail.com prima di accettare.",
  },

  tocTitle: { en: "On this page", it: "In questa pagina" },
  toc: [
    { id: "tldr",          en: "TL;DR",                   it: "In breve" },
    { id: "definitions",   en: "Definitions",             it: "Definizioni" },
    { id: "source",        en: "Source code license",     it: "Licenza del codice sorgente" },
    { id: "binary",        en: "Binary license",          it: "Licenza del binario" },
    { id: "plans",         en: "Plans and pricing",       it: "Piani e prezzi" },
    { id: "billing",       en: "Billing and renewals",    it: "Fatturazione e rinnovi" },
    { id: "refunds",       en: "Refunds",                 it: "Rimborsi" },
    { id: "cancellation",  en: "Cancellation",            it: "Cancellazione" },
    { id: "byok",          en: "BYOK and third parties",  it: "BYOK e terze parti" },
    { id: "use",           en: "Acceptable use",          it: "Uso accettabile" },
    { id: "warranty",      en: "No warranty",             it: "Nessuna garanzia" },
    { id: "liability",     en: "Limitation of liability", it: "Limitazione di responsabilità" },
    { id: "termination",   en: "Termination",             it: "Cessazione" },
    { id: "changes",       en: "Changes to these terms",  it: "Modifiche ai termini" },
    { id: "law",           en: "Governing law",           it: "Legge applicabile" },
    { id: "contact",       en: "Contact",                 it: "Contatti" },
  ],

  tldrTitle: { en: "TL;DR", it: "In breve" },
  tldrPoints: {
    en: [
      "The full source code is open under AGPL-3.0. You can read it, fork it, modify it, and run your own build for free.",
      "We sell distribution, not the software. The signed pre-built binary, in-app auto-update, and email support are the paid product.",
      "You can pay monthly (€4.99), annually (€39, saves 35%), or once (€99 Lifetime, every release for 3 years from purchase). Students get 40% off.",
      "30-day refund, no questions asked. Cancel anytime, takes effect at end of the current period.",
      "Cloud STT and LLM providers are your account and your bill. We never see or proxy your API keys.",
      "Software is provided as-is. No warranties, no SLAs, no medical / safety-critical usage.",
    ],
    it: [
      "Il codice sorgente completo è aperto sotto AGPL-3.0. Puoi leggerlo, forkarlo, modificarlo ed eseguire la tua build gratis.",
      "Vendiamo la distribuzione, non il software. Il binario firmato e pre-compilato, l'auto-update integrato e il supporto via email sono il prodotto a pagamento.",
      "Puoi pagare mensilmente (€4.99), annualmente (€39, risparmi il 35%), oppure una sola volta (€99 Lifetime, tutti i rilasci per 3 anni dall'acquisto). Sconto studenti del 40%.",
      "Rimborso entro 30 giorni, senza domande. Puoi cancellare in qualsiasi momento, l'effetto si applica a fine periodo corrente.",
      "I provider cloud STT e LLM sono il tuo account e il tuo costo. Non vediamo né proxy le tue API key.",
      "Il software è fornito \"così com'è\". Nessuna garanzia, nessuno SLA, nessun uso medico o safety-critical.",
    ],
  },

  // Definitions
  definitionsTitle: { en: "Definitions", it: "Definizioni" },
  definitions: [
    {
      term: { en: "\"Dimmy\", \"the app\", \"the software\"", it: "\"Dimmy\", \"l'app\", \"il software\"" },
      def: {
        en: "The desktop voice-dictation application maintained at github.com/KonradDallaOrg/dimmy, including the Rust core, the WinUI 3 Windows frontend, the SwiftUI macOS frontend, and the GTK4 Linux frontend.",
        it: "L'applicazione desktop di dettatura vocale mantenuta su github.com/KonradDallaOrg/dimmy, incluso il core Rust, il frontend Windows WinUI 3, il frontend macOS SwiftUI e il frontend Linux GTK4.",
      },
    },
    {
      term: { en: "\"We\", \"us\", \"Dimmy team\"", it: "\"Noi\", \"il team Dimmy\"" },
      def: {
        en: "Konrad Dalla, sole maintainer and operator of the project, based in Milano, Italy. Contact at konrad.dalla@gmail.com.",
        it: "Konrad Dalla, unico maintainer e operatore del progetto, con sede a Milano. Contatto: konrad.dalla@gmail.com.",
      },
    },
    {
      term: { en: "\"You\", \"the user\"", it: "\"Tu\", \"l'utente\"" },
      def: {
        en: "Any individual or organization that installs, builds, runs, or pays for Dimmy.",
        it: "Qualsiasi individuo o organizzazione che installi, compili, esegua o paghi Dimmy.",
      },
    },
    {
      term: { en: "\"BYOK\"", it: "\"BYOK\"" },
      def: {
        en: "Bring Your Own Key. Dimmy itself does not include or proxy any cloud STT or LLM credentials. You sign up with the provider directly (Groq, OpenAI, Anthropic, Google, Deepgram, OpenRouter, or a custom OpenAI-compatible endpoint), and Dimmy uses the key locally on your device.",
        it: "Bring Your Own Key. Dimmy in sé non include né fa da proxy a credenziali cloud STT o LLM. Ti registri direttamente con il provider (Groq, OpenAI, Anthropic, Google, Deepgram, OpenRouter, o un endpoint custom compatibile OpenAI) e Dimmy usa la chiave localmente sul tuo dispositivo.",
      },
    },
  ],

  // Source license
  sourceTitle: { en: "Source code license", it: "Licenza del codice sorgente" },
  sourceBody: {
    en: "All Dimmy source code is licensed under the GNU Affero General Public License version 3 (AGPL-3.0). You can read, modify, run, and redistribute it. If you offer a modified version as a network service, AGPL Section 13 requires you to make the modified source available to users of that service. The full text of the license is in the LICENSE file at the root of the repository.",
    it: "Tutto il codice sorgente di Dimmy è rilasciato sotto GNU Affero General Public License versione 3 (AGPL-3.0). Puoi leggerlo, modificarlo, eseguirlo e ridistribuirlo. Se offri una versione modificata come servizio di rete, la Sezione 13 della AGPL impone di rendere disponibile il sorgente modificato agli utenti di quel servizio. Il testo integrale della licenza è nel file LICENSE alla radice del repository.",
  },
  sourceClarification: {
    en: "Building Dimmy from source, for any purpose, is and will remain free. No registration, no key, no telemetry beacon, no \"call home\" check.",
    it: "Compilare Dimmy dal sorgente, per qualsiasi scopo, è e resterà gratis. Nessuna registrazione, nessuna key, nessun beacon di telemetria, nessun \"call home\".",
  },

  // Binary license
  binaryTitle: { en: "Binary license", it: "Licenza del binario" },
  binaryBody: {
    en: "Pre-built binaries we distribute under \"Free\", \"Pro\", and \"Lifetime\" plans are the same software, identically licensed under AGPL-3.0 in source form. What the plans differ on is distribution: we sign, notarize, package, and host the binaries, and we ship an in-app auto-updater. The \"Pro\" and \"Lifetime\" plans grant you a personal, non-exclusive, non-transferable right to use the signed binary and the included update channel for as long as your plan is active. The \"Free\" plan invites you to build the same binary yourself.",
    it: "I binari pre-compilati distribuiti nei piani \"Free\", \"Pro\" e \"Lifetime\" sono lo stesso software, identicamente licenziato sotto AGPL-3.0 nella forma sorgente. I piani si differenziano sulla distribuzione: noi firmiamo, notarizziamo, impacchettiamo e ospitiamo i binari, e includiamo un auto-updater. I piani \"Pro\" e \"Lifetime\" ti concedono il diritto personale, non esclusivo e non trasferibile di usare il binario firmato e il canale di update incluso fino a quando il piano è attivo. Il piano \"Free\" ti invita a compilare lo stesso binario per conto tuo.",
  },
  binaryActivation: {
    en: "Pro and Lifetime activate by entering an activation code (sent to you by email after purchase) into Settings → Account. The activation flow contacts our license server at license.dimmy.app and stores an Ed25519-signed license token locally on the device. The token can run offline for up to 7 days between online refreshes. No personal data beyond the activation code and a per-device random ID is sent during activation.",
    it: "Pro e Lifetime si attivano inserendo un codice di attivazione (inviato via email dopo l'acquisto) in Impostazioni → Account. Il flusso di attivazione contatta il nostro license server su license.dimmy.app e salva un token di licenza firmato Ed25519 localmente sul dispositivo. Il token può funzionare offline fino a 7 giorni tra un refresh online e l'altro. Durante l'attivazione non vengono inviati dati personali oltre al codice di attivazione e a un ID dispositivo casuale.",
  },

  // Plans
  plansTitle: { en: "Plans and pricing", it: "Piani e prezzi" },
  plansLead: {
    en: "Three plans. Prices are in euro, VAT excluded for B2B customers in the EU and applicable VAT inclusive for consumers per VAT-OSS rules.",
    it: "Tre piani. Prezzi in euro, IVA esclusa per clienti B2B in UE e IVA inclusa per consumatori secondo le regole VAT-OSS.",
  },
  plans: [
    {
      name: "Free",
      price: { en: "€0 forever", it: "€0 per sempre" },
      who: {
        en: "Anyone willing to clone, compile, and self-host the binary. Same code as Pro, no feature gates.",
        it: "Chiunque sia disposto a clonare, compilare e firmarsi il binario. Stesso codice del Pro, nessuna feature gate.",
      },
    },
    {
      name: "Pro",
      price: { en: "€4.99/month or €39/year", it: "€4.99/mese oppure €39/anno" },
      who: {
        en: "Pre-built signed binary, in-app auto-update, early access to beta builds, vote on the public roadmap, human email support within 24h, 30-day refund, cancel anytime.",
        it: "Binario pre-compilato e firmato, auto-update in-app, accesso anticipato alle beta, voto sulla roadmap pubblica, supporto via email entro 24h, rimborso 30 giorni, cancellazione in qualsiasi momento.",
      },
    },
    {
      name: "Lifetime",
      price: { en: "€99 once", it: "€99 una sola volta" },
      who: {
        en: "Everything in Pro plus every release for 3 years from purchase, on all platforms, with priority email support. One-time payment, no renewals.",
        it: "Tutto del Pro più ogni release per 3 anni dall'acquisto, su tutte le piattaforme, con supporto email prioritario. Pagamento unico, nessun rinnovo.",
      },
    },
  ],
  plansFooter: {
    en: "Students get a 40% discount on any plan with a valid .edu or equivalent verification. Education-verified pricing is fulfilled manually by us, write to konrad.dalla@gmail.com from the educational email.",
    it: "Gli studenti hanno il 40% di sconto su qualsiasi piano con una verifica .edu o equivalente. Il prezzo verificato per istruzione è gestito manualmente, scrivi a konrad.dalla@gmail.com dall'email accademica.",
  },

  // Billing
  billingTitle: { en: "Billing and renewals", it: "Fatturazione e rinnovi" },
  billingBody: {
    en: "Payments are processed by Stripe Payments Europe, Ltd. Subscriptions (Pro monthly, Pro annual) renew automatically at the end of each billing period using the payment method on file. Lifetime is a single charge with no renewals. Receipts are emailed at checkout and accessible any time through the customer portal.",
    it: "I pagamenti sono gestiti da Stripe Payments Europe, Ltd. Gli abbonamenti (Pro mensile, Pro annuale) si rinnovano automaticamente alla fine di ogni periodo di fatturazione usando il metodo di pagamento registrato. Lifetime è un addebito unico senza rinnovi. Le ricevute vengono inviate via email al checkout e sono sempre accessibili dal customer portal.",
  },
  billingVat: {
    en: "VAT is calculated by Stripe Tax according to your country of residence (B2C) or your VAT ID (B2B reverse charge for EU businesses outside Italy). Italian B2B customers are charged Italian VAT.",
    it: "L'IVA è calcolata da Stripe Tax in base al paese di residenza (B2C) o al numero di partita IVA (reverse charge B2B per aziende UE fuori dall'Italia). I clienti B2B italiani sono soggetti a IVA italiana.",
  },
  billingPortal: {
    en: "You can update your payment method, change plan, see invoices, and cancel from Settings → Account → Manage subscription, which opens the Stripe customer portal in your browser.",
    it: "Puoi aggiornare il metodo di pagamento, cambiare piano, visualizzare le fatture e cancellare da Impostazioni → Account → Gestisci abbonamento, che apre il customer portal Stripe nel browser.",
  },

  // Refunds
  refundsTitle: { en: "Refunds", it: "Rimborsi" },
  refundsBody: {
    en: "Within 30 days of purchase, write to konrad.dalla@gmail.com from the address you used at checkout, ask for a refund, and we issue it. No forms, no friction. After 30 days, refunds are at our discretion and usually granted unless the request looks abusive (e.g. asking for a refund after a full year of active use).",
    it: "Entro 30 giorni dall'acquisto, scrivi a konrad.dalla@gmail.com dall'indirizzo usato al checkout e chiedi il rimborso: te lo emettiamo. Niente moduli, niente attriti. Dopo 30 giorni i rimborsi sono a nostra discrezione e di solito vengono concessi salvo casi che appaiano abusivi (es. rimborso dopo un anno di uso attivo).",
  },
  refundsConsumer: {
    en: "EU consumers retain all statutory rights, including the 14-day right of withdrawal under Directive 2011/83/EU. The 30-day window above is in addition to, not in place of, any statutory right.",
    it: "I consumatori UE mantengono tutti i diritti di legge, incluso il diritto di recesso di 14 giorni ai sensi della Direttiva 2011/83/UE. La finestra di 30 giorni qui sopra si aggiunge ai diritti di legge, non li sostituisce.",
  },

  // Cancellation
  cancellationTitle: { en: "Cancellation", it: "Cancellazione" },
  cancellationBody: {
    en: "Cancel a Pro subscription from Settings → Account → Manage subscription or by writing to us. Cancellation takes effect at the end of the current billing period. You keep access to the signed binary, auto-update, and support until that date.",
    it: "Cancella un abbonamento Pro da Impostazioni → Account → Gestisci abbonamento oppure scrivendoci. La cancellazione ha effetto alla fine del periodo di fatturazione corrente. Mantieni l'accesso a binario firmato, auto-update e supporto fino a quella data.",
  },
  cancellationFree: {
    en: "After the access window expires, the app falls back to a \"Free\" mode: you can still use the binary you already downloaded, but you will no longer receive automatic updates and your license token will refuse to refresh. You can always rebuild from source and run that, or buy a new period.",
    it: "Quando la finestra di accesso scade, l'app passa in modalità \"Free\": puoi continuare a usare il binario già scaricato, ma non riceverai più gli update automatici e il token di licenza non si rinnoverà più. Puoi sempre ricompilare dal sorgente ed eseguire quello, oppure acquistare un nuovo periodo.",
  },

  // BYOK
  byokTitle: { en: "BYOK and third-party services", it: "BYOK e servizi di terze parti" },
  byokBody: {
    en: "Dimmy is bring-your-own-key for any cloud transcription or LLM use. You sign up directly with the provider, you store the API key locally (AES-256-GCM with a machine-bound KDF), and the network calls go from your device to the provider, not through any Dimmy server.",
    it: "Dimmy è bring-your-own-key per qualsiasi uso cloud di trascrizione o LLM. Ti registri direttamente con il provider, salvi la API key localmente (AES-256-GCM con KDF legato alla macchina), e le chiamate di rete vanno dal tuo dispositivo al provider, non attraverso server Dimmy.",
  },
  byokProviders: {
    en: "Provider relationships are entirely between you and the provider. We do not bill on their behalf, do not see your usage, and do not endorse any specific provider. The list of providers Dimmy currently supports is Groq, OpenAI, Anthropic, Google (Gemini), Deepgram, OpenRouter, and any OpenAI-compatible HTTPS endpoint you configure.",
    it: "Il rapporto con i provider è esclusivamente tra te e il provider. Non fatturiamo per loro, non vediamo il tuo utilizzo e non promuoviamo provider specifici. La lista dei provider attualmente supportati da Dimmy è: Groq, OpenAI, Anthropic, Google (Gemini), Deepgram, OpenRouter, e qualsiasi endpoint HTTPS compatibile OpenAI che configuri.",
  },
  byokOther: {
    en: "Other third-party services we rely on for our own operation: Stripe (payments and customer portal), PostHog EU (anonymous analytics), Sentry EU (crash reporting), Resend (transactional email), Cloudflare (license server, website, file hosting), GitHub (source hosting and releases). Each has its own terms and privacy policy.",
    it: "Altri servizi di terze parti che usiamo per la nostra operatività: Stripe (pagamenti e customer portal), PostHog EU (analytics anonimi), Sentry EU (crash report), Resend (email transazionali), Cloudflare (license server, sito, file hosting), GitHub (hosting sorgente e release). Ognuno ha i suoi termini e la sua privacy policy.",
  },

  // Acceptable use
  useTitle: { en: "Acceptable use", it: "Uso accettabile" },
  useIntro: {
    en: "Dimmy is a local tool. We do not see what you transcribe. That said, do not use Dimmy for:",
    it: "Dimmy è uno strumento locale. Non vediamo cosa trascrivi. Detto questo, non usare Dimmy per:",
  },
  useItems: {
    en: [
      "Recording or transcribing other people without consent in jurisdictions that require it.",
      "Generating or storing CSAM or any content illegal in your or our jurisdiction.",
      "Reverse-engineering the activation system or distributing license tokens, activation codes, or signed binaries you did not buy.",
      "Re-selling pre-built Dimmy binaries you obtained from us, with or without modifications, in a way that competes with our distribution.",
      "Stress-testing, scraping, or denial-of-service against license.dimmy.app, posthog, sentry, or any infrastructure we run.",
    ],
    it: [
      "Registrare o trascrivere altre persone senza consenso nelle giurisdizioni che lo richiedono.",
      "Generare o conservare CSAM o qualsiasi contenuto illegale nella tua o nella nostra giurisdizione.",
      "Fare reverse engineering del sistema di attivazione o distribuire token di licenza, codici di attivazione o binari firmati che non hai acquistato.",
      "Rivendere binari Dimmy pre-compilati ottenuti da noi, con o senza modifiche, in modo da competere con la nostra distribuzione.",
      "Stress-test, scraping o denial-of-service contro license.dimmy.app, posthog, sentry o qualsiasi infrastruttura che gestiamo.",
    ],
  },
  useNote: {
    en: "Forking and self-hosting the source under AGPL-3.0 is not on this list and never will be. That is the whole point of the license.",
    it: "Forkare e self-hostare il sorgente sotto AGPL-3.0 non è in questa lista e non lo sarà mai. È esattamente lo scopo della licenza.",
  },

  // Warranty
  warrantyTitle: { en: "No warranty", it: "Nessuna garanzia" },
  warrantyBody: {
    en: "Dimmy is provided as-is, without warranty of any kind, express or implied, including merchantability, fitness for a particular purpose, accuracy, or non-infringement. Transcription quality depends on your microphone, environment, the model you pick, the cloud provider you connect, and the language you speak. We do not guarantee any specific accuracy, speed, or uptime.",
    it: "Dimmy è fornito \"così com'è\", senza garanzie di alcun tipo, esplicite o implicite, incluse commerciabilità, idoneità a uno scopo specifico, accuratezza o non violazione di diritti. La qualità della trascrizione dipende dal tuo microfono, dall'ambiente, dal modello scelto, dal provider cloud e dalla lingua parlata. Non garantiamo accuratezza, velocità o uptime specifici.",
  },
  warrantySafety: {
    en: "Do not use Dimmy in safety-critical, medical, legal-record, or accessibility-mandated contexts where a transcription error could cause material harm.",
    it: "Non usare Dimmy in contesti safety-critical, medici, di verbale legale o in contesti di accessibilità obbligatoria dove un errore di trascrizione possa causare un danno materiale.",
  },

  // Liability
  liabilityTitle: { en: "Limitation of liability", it: "Limitazione di responsabilità" },
  liabilityBody: {
    en: "To the maximum extent permitted by law, our total liability arising out of or related to Dimmy is capped at the amount you actually paid us in the 12 months preceding the event giving rise to the claim. We are not liable for indirect, incidental, special, consequential, or punitive damages, lost profits, lost data, or business interruption.",
    it: "Nei limiti massimi consentiti dalla legge, la nostra responsabilità totale derivante o correlata a Dimmy è limitata all'importo effettivamente pagato a noi nei 12 mesi precedenti l'evento che ha originato la richiesta. Non siamo responsabili per danni indiretti, incidentali, speciali, consequenziali o punitivi, perdita di profitti, perdita di dati o interruzione di attività.",
  },
  liabilityConsumer: {
    en: "Nothing in these terms limits liability for death, personal injury caused by negligence, fraud, or anything else that cannot be limited under applicable law (including, for EU consumers, statutory consumer protection rights).",
    it: "Nulla in questi termini limita la responsabilità per decesso, danni personali causati da negligenza, frode o qualsiasi altra cosa che non possa essere limitata dalla legge applicabile (inclusi, per i consumatori UE, i diritti di tutela del consumatore previsti per legge).",
  },

  // Termination
  terminationTitle: { en: "Termination", it: "Cessazione" },
  terminationBody: {
    en: "You can stop using Dimmy at any time by uninstalling it. We can suspend or terminate a paid license if you breach these terms (most commonly: charge-back fraud, reselling activation codes, abuse of the license server). On termination, your activation token stops refreshing and you fall back to the same position as a \"Free\" user.",
    it: "Puoi smettere di usare Dimmy in qualsiasi momento disinstallandolo. Possiamo sospendere o cessare una licenza a pagamento se violi questi termini (più comunemente: frode con chargeback, rivendita di codici di attivazione, abuso del license server). Alla cessazione il token di attivazione smette di rinnovarsi e torni nella stessa posizione di un utente \"Free\".",
  },

  // Changes
  changesTitle: { en: "Changes to these terms", it: "Modifiche ai termini" },
  changesBody: {
    en: "We can update these terms. Material changes are announced in the release notes and on the website. The current text is the one displayed on this page, and the change history is in the website Git repository.",
    it: "Possiamo aggiornare questi termini. Le modifiche sostanziali sono annunciate nelle note di rilascio e sul sito. Il testo corrente è quello visualizzato su questa pagina, lo storico delle modifiche è nel repository Git del sito.",
  },
  changesNotice: {
    en: "If a change materially reduces your rights as a paying user, we will email active Pro and Lifetime customers at least 30 days before it takes effect.",
    it: "Se una modifica riduce materialmente i tuoi diritti come utente pagante, manderemo una email agli utenti Pro e Lifetime attivi almeno 30 giorni prima dell'entrata in vigore.",
  },

  // Law
  lawTitle: { en: "Governing law and forum", it: "Legge applicabile e foro" },
  lawBody: {
    en: "These terms are governed by Italian law. The forum of Milano has exclusive jurisdiction over disputes, except where mandatory consumer protection law in your country of residence gives you the right to sue or be sued elsewhere.",
    it: "Questi termini sono regolati dalla legge italiana. Il foro di Milano ha giurisdizione esclusiva sulle controversie, salvo i casi in cui la legge imperativa di tutela del consumatore del tuo paese di residenza ti consenta di agire o essere convenuto altrove.",
  },

  // Contact
  contactTitle: { en: "Contact", it: "Contatti" },
  contactBody: {
    en: "Anything legal, billing, or just a question: konrad.dalla@gmail.com. Security issues: security@dimmy.app. We are a single human in Milano, replies are typically within a day.",
    it: "Qualsiasi cosa legale, fatturazione, o anche solo una domanda: konrad.dalla@gmail.com. Problemi di sicurezza: security@dimmy.app. Siamo un singolo umano a Milano, le risposte arrivano in genere entro un giorno.",
  },
};

function TermsHero() {
  const lead = useT(COPY.lead);
  const lastUpdated = useT(COPY.lastUpdated);
  const [a, b] = useT(COPY.title);
  return (
    <section style={{
      position: "relative",
      padding: "120px 32px 64px",
      overflow: "hidden",
    }}>
      <div className="bg-grid" style={{
        position: "absolute", inset: 0,
        maskImage: "radial-gradient(ellipse 70% 50% at 50% 30%, black, transparent 70%)",
        WebkitMaskImage: "radial-gradient(ellipse 70% 50% at 50% 30%, black, transparent 70%)",
        pointerEvents: "none",
      }}/>
      <div style={{
        position: "absolute", top: -180, left: "50%",
        transform: "translateX(-50%)",
        width: 900, height: 500,
        background: "radial-gradient(circle, rgba(167,139,250,0.16), transparent 60%), radial-gradient(circle at 70% 60%, rgba(56,189,248,0.12), transparent 60%)",
        filter: "blur(60px)",
        pointerEvents: "none",
      }}/>
      <div className="container-narrow" style={{ position: "relative", textAlign: "center" }}>
        <Eyebrow color="#A78BFA">{useT(COPY.eyebrow)}</Eyebrow>
        <div style={{ height: 18 }}/>
        <h1 className="reveal" style={{
          fontFamily: "var(--font-display)",
          fontSize: "clamp(40px, 7vw, 80px)",
          fontWeight: 700,
          letterSpacing: "-0.03em",
          lineHeight: 1.02,
          margin: 0,
          color: "var(--fg)",
          textWrap: "balance",
        }}>
          {a}<br/>
          <span className="grad-text">{b}</span>
        </h1>
        <p className="reveal" style={{
          marginTop: 22,
          fontSize: 19, lineHeight: 1.55,
          color: "var(--fg-muted)",
          maxWidth: 660, marginInline: "auto",
          textWrap: "pretty",
        }}>{lead}</p>
        <p className="reveal" style={{
          marginTop: 12,
          fontSize: 13, lineHeight: 1.55,
          color: "var(--fg-faint)",
          maxWidth: 620, marginInline: "auto",
          textWrap: "pretty", fontStyle: "italic",
        }}>{useT(COPY.disclaimer)}</p>
        <div className="reveal" style={{
          marginTop: 24, fontFamily: "var(--font-mono)", fontSize: 11,
          color: "var(--fg-faint)", letterSpacing: "0.06em",
        }}>{lastUpdated}</div>
      </div>
    </section>
  );
}

function Toc() {
  const tocTitle = useT(COPY.tocTitle);
  const { lang } = useI18n();
  const [activeId, setActiveId] = useState("");
  useEffect(() => {
    const ids = COPY.toc.map((t) => t.id);
    const observers = ids.map((id) => {
      const el = document.getElementById(id);
      if (!el) return null;
      const io = new IntersectionObserver(
        (entries) => {
          entries.forEach((e) => {
            if (e.isIntersecting) setActiveId(id);
          });
        },
        { rootMargin: "-30% 0px -55% 0px", threshold: 0 }
      );
      io.observe(el);
      return io;
    });
    return () => observers.forEach((io) => io && io.disconnect());
  }, []);
  return (
    <aside className="terms-toc" style={{
      position: "sticky", top: 96,
      alignSelf: "start",
      padding: 20,
      borderLeft: "1px solid var(--line)",
      fontFamily: "var(--font-sans)",
      fontSize: 13,
      maxHeight: "calc(100vh - 96px)",
      overflowY: "auto",
    }}>
      <div style={{
        fontFamily: "var(--font-mono)", fontSize: 10,
        color: "var(--fg-faint)", letterSpacing: "0.10em",
        textTransform: "uppercase", marginBottom: 14,
      }}>{tocTitle}</div>
      <ol style={{ listStyle: "none", padding: 0, margin: 0, display: "flex", flexDirection: "column", gap: 4 }}>
        {COPY.toc.map((t, i) => {
          const isActive = activeId === t.id;
          return (
            <li key={t.id}>
              <a href={`#${t.id}`} style={{
                display: "flex", alignItems: "baseline", gap: 8,
                padding: "4px 0",
                color: isActive ? "var(--fg)" : "var(--fg-muted)",
                textDecoration: "none",
                borderLeft: `2px solid ${isActive ? "var(--fg)" : "transparent"}`,
                paddingLeft: 10,
                marginLeft: -12,
                transition: "color 180ms, border-color 180ms",
              }}>
                <span style={{
                  fontFamily: "var(--font-mono)", fontSize: 10,
                  color: "var(--fg-faint)",
                  minWidth: 16,
                }}>{String(i + 1).padStart(2, "0")}</span>
                <span>{t[lang]}</span>
              </a>
            </li>
          );
        })}
      </ol>
    </aside>
  );
}

function SectionBlock({ id, title, children }) {
  return (
    <section id={id} style={{
      padding: "48px 0",
      borderTop: "1px solid var(--line)",
      scrollMarginTop: 96,
    }}>
      <h2 className="reveal" style={{
        fontFamily: "var(--font-display)", fontSize: "clamp(26px, 3vw, 36px)",
        fontWeight: 700, letterSpacing: "-0.02em",
        lineHeight: 1.1, margin: 0, color: "var(--fg)",
      }}>{title}</h2>
      <div style={{ marginTop: 22 }}>{children}</div>
    </section>
  );
}

function Para({ children }) {
  return (
    <p style={{
      margin: "0 0 14px",
      fontSize: 16, lineHeight: 1.62,
      color: "var(--fg-muted)",
      textWrap: "pretty",
    }}>{children}</p>
  );
}

function Tldr() {
  const points = useT(COPY.tldrPoints);
  return (
    <SectionBlock id="tldr" title={useT(COPY.tldrTitle)}>
      <ul style={{
        listStyle: "none", padding: 0, margin: 0,
        display: "flex", flexDirection: "column", gap: 12,
      }}>
        {points.map((p, i) => (
          <li key={i} className="reveal" style={{
            display: "flex", gap: 14, alignItems: "flex-start",
            padding: "14px 16px",
            background: "linear-gradient(180deg, var(--bg-elev), transparent)",
            border: "1px solid var(--line)",
            borderRadius: 12,
            fontSize: 15, lineHeight: 1.55,
            color: "var(--fg)",
          }}>
            <span aria-hidden="true" style={{
              width: 6, height: 6, borderRadius: 99,
              background: "#A78BFA", boxShadow: "0 0 8px #A78BFA",
              marginTop: 8, flexShrink: 0,
            }}/>
            <span>{p}</span>
          </li>
        ))}
      </ul>
    </SectionBlock>
  );
}

function Definitions() {
  const { lang } = useI18n();
  return (
    <SectionBlock id="definitions" title={useT(COPY.definitionsTitle)}>
      <dl style={{
        margin: 0, padding: 0,
        display: "grid", gridTemplateColumns: "1fr", gap: 14,
      }}>
        {COPY.definitions.map((d, i) => (
          <div key={i} className="reveal" style={{
            padding: "18px 20px",
            border: "1px solid var(--line)",
            borderRadius: 12,
            background: "linear-gradient(180deg, var(--bg-elev), transparent)",
          }}>
            <dt style={{
              fontFamily: "var(--font-mono)", fontSize: 13,
              color: "#A78BFA",
              letterSpacing: "0.02em",
              marginBottom: 6,
              fontWeight: 600,
            }}>{d.term[lang]}</dt>
            <dd style={{
              margin: 0,
              fontSize: 14.5, lineHeight: 1.6, color: "var(--fg-muted)",
            }}>{d.def[lang]}</dd>
          </div>
        ))}
      </dl>
    </SectionBlock>
  );
}

function SourceLicense() {
  return (
    <SectionBlock id="source" title={useT(COPY.sourceTitle)}>
      <Para>{useT(COPY.sourceBody)}</Para>
      <div className="reveal" style={{
        padding: "14px 16px",
        background: "rgba(74,222,128,0.06)",
        border: "1px solid rgba(74,222,128,0.22)",
        borderRadius: 10,
        fontSize: 14.5, lineHeight: 1.55,
        color: "var(--fg)",
      }}>{useT(COPY.sourceClarification)}</div>
    </SectionBlock>
  );
}

function BinaryLicense() {
  return (
    <SectionBlock id="binary" title={useT(COPY.binaryTitle)}>
      <Para>{useT(COPY.binaryBody)}</Para>
      <Para>{useT(COPY.binaryActivation)}</Para>
    </SectionBlock>
  );
}

function Plans() {
  const { lang } = useI18n();
  return (
    <SectionBlock id="plans" title={useT(COPY.plansTitle)}>
      <Para>{useT(COPY.plansLead)}</Para>
      <div className="reveal terms-plans" style={{
        display: "grid", gridTemplateColumns: "repeat(3, 1fr)", gap: 14,
      }}>
        {COPY.plans.map((p, i) => (
          <div key={i} style={{
            padding: "20px 22px",
            border: "1px solid var(--line)",
            borderRadius: 14,
            background: "linear-gradient(180deg, var(--bg-elev), transparent)",
            display: "flex", flexDirection: "column", gap: 10,
          }}>
            <div style={{
              fontFamily: "var(--font-display)", fontSize: 20, fontWeight: 700,
              letterSpacing: "-0.01em", color: "var(--fg)",
            }}>{p.name}</div>
            <div style={{
              fontFamily: "var(--font-mono)", fontSize: 12,
              color: "#38BDF8", letterSpacing: "0.02em",
            }}>{p.price[lang]}</div>
            <p style={{
              margin: 0,
              fontSize: 14, lineHeight: 1.55,
              color: "var(--fg-muted)",
            }}>{p.who[lang]}</p>
          </div>
        ))}
      </div>
      <p style={{
        marginTop: 16, fontSize: 13, lineHeight: 1.55,
        color: "var(--fg-faint)", fontStyle: "italic",
      }}>{useT(COPY.plansFooter)}</p>
      <style>{`
        @media (max-width: 760px) {
          .terms-plans { grid-template-columns: 1fr !important; }
        }
      `}</style>
    </SectionBlock>
  );
}

function Billing() {
  return (
    <SectionBlock id="billing" title={useT(COPY.billingTitle)}>
      <Para>{useT(COPY.billingBody)}</Para>
      <Para>{useT(COPY.billingVat)}</Para>
      <Para>{useT(COPY.billingPortal)}</Para>
    </SectionBlock>
  );
}

function Refunds() {
  return (
    <SectionBlock id="refunds" title={useT(COPY.refundsTitle)}>
      <Para>{useT(COPY.refundsBody)}</Para>
      <Para>{useT(COPY.refundsConsumer)}</Para>
    </SectionBlock>
  );
}

function Cancellation() {
  return (
    <SectionBlock id="cancellation" title={useT(COPY.cancellationTitle)}>
      <Para>{useT(COPY.cancellationBody)}</Para>
      <Para>{useT(COPY.cancellationFree)}</Para>
    </SectionBlock>
  );
}

function Byok() {
  return (
    <SectionBlock id="byok" title={useT(COPY.byokTitle)}>
      <Para>{useT(COPY.byokBody)}</Para>
      <Para>{useT(COPY.byokProviders)}</Para>
      <Para>{useT(COPY.byokOther)}</Para>
    </SectionBlock>
  );
}

function AcceptableUse() {
  const items = useT(COPY.useItems);
  return (
    <SectionBlock id="use" title={useT(COPY.useTitle)}>
      <Para>{useT(COPY.useIntro)}</Para>
      <ul className="reveal" style={{
        listStyle: "none", padding: 0, margin: 0,
        display: "flex", flexDirection: "column", gap: 10,
      }}>
        {items.map((it, i) => (
          <li key={i} style={{
            display: "flex", alignItems: "flex-start", gap: 12,
            padding: "12px 14px",
            background: "rgba(239,68,68,0.05)",
            border: "1px solid rgba(239,68,68,0.20)",
            borderRadius: 10,
            fontSize: 14.5, lineHeight: 1.55, color: "var(--fg)",
          }}>
            <span aria-hidden="true" style={{
              width: 18, height: 18, borderRadius: 99,
              background: "rgba(239,68,68,0.12)",
              border: "1px solid rgba(239,68,68,0.30)",
              color: "#F87171",
              display: "inline-flex", alignItems: "center", justifyContent: "center",
              flexShrink: 0, marginTop: 1,
              fontSize: 12, fontWeight: 700, fontFamily: "var(--font-mono)",
            }}>✕</span>
            <span>{it}</span>
          </li>
        ))}
      </ul>
      <p style={{
        marginTop: 18, fontSize: 14, lineHeight: 1.55,
        color: "var(--fg-faint)", fontStyle: "italic",
      }}>{useT(COPY.useNote)}</p>
    </SectionBlock>
  );
}

function Warranty() {
  return (
    <SectionBlock id="warranty" title={useT(COPY.warrantyTitle)}>
      <Para>{useT(COPY.warrantyBody)}</Para>
      <div className="reveal" style={{
        padding: "14px 16px",
        background: "rgba(251,146,60,0.06)",
        border: "1px solid rgba(251,146,60,0.25)",
        borderRadius: 10,
        fontSize: 14.5, lineHeight: 1.55,
        color: "var(--fg)",
      }}>{useT(COPY.warrantySafety)}</div>
    </SectionBlock>
  );
}

function Liability() {
  return (
    <SectionBlock id="liability" title={useT(COPY.liabilityTitle)}>
      <Para>{useT(COPY.liabilityBody)}</Para>
      <Para>{useT(COPY.liabilityConsumer)}</Para>
    </SectionBlock>
  );
}

function Termination() {
  return (
    <SectionBlock id="termination" title={useT(COPY.terminationTitle)}>
      <Para>{useT(COPY.terminationBody)}</Para>
    </SectionBlock>
  );
}

function Changes() {
  return (
    <SectionBlock id="changes" title={useT(COPY.changesTitle)}>
      <Para>{useT(COPY.changesBody)}</Para>
      <Para>{useT(COPY.changesNotice)}</Para>
    </SectionBlock>
  );
}

function Law() {
  return (
    <SectionBlock id="law" title={useT(COPY.lawTitle)}>
      <Para>{useT(COPY.lawBody)}</Para>
    </SectionBlock>
  );
}

function Contact() {
  return (
    <SectionBlock id="contact" title={useT(COPY.contactTitle)}>
      <Para>{useT(COPY.contactBody)}</Para>
    </SectionBlock>
  );
}

function Terms() {
  return (
    <>
      <TermsHero/>
      <div className="container-narrow terms-layout" style={{
        position: "relative",
        display: "grid",
        gridTemplateColumns: "1fr 220px",
        gap: 48,
        paddingBottom: 96,
      }}>
        <main>
          <Tldr/>
          <Definitions/>
          <SourceLicense/>
          <BinaryLicense/>
          <Plans/>
          <Billing/>
          <Refunds/>
          <Cancellation/>
          <Byok/>
          <AcceptableUse/>
          <Warranty/>
          <Liability/>
          <Termination/>
          <Changes/>
          <Law/>
          <Contact/>
        </main>
        <Toc/>
      </div>
      <style>{`
        @media (max-width: 960px) {
          .terms-layout { grid-template-columns: 1fr !important; }
          .terms-toc { display: none !important; }
        }
      `}</style>
    </>
  );
}

window.TermsPage = Terms;
