diff --git a/.env.example b/.env.example
index c0660ea..17a8d22 100644
--- a/.env.example
+++ b/.env.example
@@ -4,7 +4,7 @@ APP_KEY=
APP_DEBUG=true
APP_URL=http://localhost
-APP_LOCALE=en
+APP_LOCALE=nl
APP_FALLBACK_LOCALE=en
APP_FAKER_LOCALE=en_US
@@ -63,3 +63,6 @@ AWS_BUCKET=
AWS_USE_PATH_STYLE_ENDPOINT=false
VITE_APP_NAME="${APP_NAME}"
+
+TURNSTILE_SITE_KEY=
+TURNSTILE_SECRET_KEY=
diff --git a/app/Http/Controllers/CertificatePreviewController.php b/app/Http/Controllers/CertificatePreviewController.php
new file mode 100644
index 0000000..19af1ee
--- /dev/null
+++ b/app/Http/Controllers/CertificatePreviewController.php
@@ -0,0 +1,22 @@
+file_path) && Storage::disk('local')->exists($certificate->file_path), 404);
+
+ return Storage::disk('local')->response($certificate->file_path);
+ }
+}
diff --git a/app/Http/Controllers/MarketingController.php b/app/Http/Controllers/MarketingController.php
index 5c8cea1..1133e12 100644
--- a/app/Http/Controllers/MarketingController.php
+++ b/app/Http/Controllers/MarketingController.php
@@ -20,4 +20,19 @@ class MarketingController extends Controller
{
return view('marketing.pricing');
}
+
+ public function terms(): View
+ {
+ return view('marketing.terms');
+ }
+
+ public function privacy(): View
+ {
+ return view('marketing.privacy');
+ }
+
+ public function dpa(): View
+ {
+ return view('marketing.dpa');
+ }
}
diff --git a/app/Http/Controllers/VerifyController.php b/app/Http/Controllers/VerifyController.php
new file mode 100644
index 0000000..fb8371e
--- /dev/null
+++ b/app/Http/Controllers/VerifyController.php
@@ -0,0 +1,48 @@
+ Session::get('verify.result')]);
+ }
+
+ public function check(Request $request): RedirectResponse
+ {
+ $validated = $request->validate([
+ 'certificate_number' => ['required', 'string', 'max:255'],
+ 'holder_last_name' => ['required', 'string', 'max:255'],
+ 'cf-turnstile-response' => [new Turnstile],
+ ]);
+
+ $isValid = Certificate::query()
+ // Verification checks across every account's certificates, not
+ // just the caller's — bypass the owner scope explicitly since a
+ // staff member checking a certificate may be logged in too.
+ ->withoutGlobalScope(OwnedByUserScope::class)
+ ->whereRaw('LOWER(certificate_number) = ?', [Str::lower(trim($validated['certificate_number']))])
+ ->whereRaw('LOWER(holder_last_name) = ?', [Str::lower(trim($validated['holder_last_name']))])
+ ->where('expires_at', '>=', today())
+ ->exists();
+
+ return redirect()->route('verify.show')
+ ->with('verify.result', $isValid ? 'valid' : 'invalid');
+ }
+}
diff --git a/app/Models/Certificate.php b/app/Models/Certificate.php
index 3d24453..8e39b92 100644
--- a/app/Models/Certificate.php
+++ b/app/Models/Certificate.php
@@ -20,6 +20,7 @@ use Illuminate\Support\Carbon;
* @property string $title
* @property string|null $issuer
* @property string|null $certificate_number
+ * @property string|null $holder_last_name
* @property Carbon|null $issued_at
* @property string|null $file_path
* @property Carbon $expires_at
@@ -27,7 +28,7 @@ use Illuminate\Support\Carbon;
* @property Carbon|null $created_at
* @property Carbon|null $updated_at
*/
-#[Fillable(['title', 'category_id', 'issuer', 'certificate_number', 'issued_at', 'file_path', 'expires_at', 'notes'])]
+#[Fillable(['title', 'category_id', 'issuer', 'certificate_number', 'holder_last_name', 'issued_at', 'file_path', 'expires_at', 'notes'])]
#[ScopedBy(OwnedByUserScope::class)]
class Certificate extends Model
{
diff --git a/app/Models/User.php b/app/Models/User.php
index 2a76c52..8eab6dd 100644
--- a/app/Models/User.php
+++ b/app/Models/User.php
@@ -46,7 +46,7 @@ class User extends Authenticatable implements PasskeyUser
protected $attributes = [
'reminder_months_before' => 1,
'ocr_provider' => 'none',
- 'locale' => 'en',
+ 'locale' => 'nl',
];
/**
diff --git a/app/Rules/Turnstile.php b/app/Rules/Turnstile.php
new file mode 100644
index 0000000..a47934b
--- /dev/null
+++ b/app/Rules/Turnstile.php
@@ -0,0 +1,41 @@
+post('https://challenges.cloudflare.com/turnstile/v0/siteverify', [
+ 'secret' => $secret,
+ 'response' => $value,
+ 'remoteip' => Request::ip(),
+ ]);
+
+ if (! $response->json('success', false)) {
+ $fail(__('The verification challenge failed. Please try again.'));
+ }
+ }
+}
diff --git a/config/services.php b/config/services.php
index ec226a4..462c906 100644
--- a/config/services.php
+++ b/config/services.php
@@ -35,4 +35,13 @@ return [
],
],
+ // Cloudflare Turnstile, used to gate the public certificate verification
+ // form. Left unconfigured, the CAPTCHA check is skipped (see
+ // App\Rules\Turnstile) so local development and CI need no keys — set
+ // both before exposing /verify in production.
+ 'turnstile' => [
+ 'site_key' => env('TURNSTILE_SITE_KEY'),
+ 'secret_key' => env('TURNSTILE_SECRET_KEY'),
+ ],
+
];
diff --git a/database/factories/CertificateFactory.php b/database/factories/CertificateFactory.php
index 8abd36e..5b0554b 100644
--- a/database/factories/CertificateFactory.php
+++ b/database/factories/CertificateFactory.php
@@ -22,6 +22,7 @@ class CertificateFactory extends Factory
'title' => fake()->sentence(3),
'issuer' => fake()->company(),
'certificate_number' => fake()->bothify('CERT-####-????'),
+ 'holder_last_name' => fake()->lastName(),
'issued_at' => fake()->dateTimeBetween('-2 years', '-1 month'),
'file_path' => null,
'expires_at' => fake()->dateTimeBetween('+2 months', '+2 years'),
diff --git a/database/factories/UserFactory.php b/database/factories/UserFactory.php
index 98825c8..5f81f83 100644
--- a/database/factories/UserFactory.php
+++ b/database/factories/UserFactory.php
@@ -30,6 +30,10 @@ class UserFactory extends Factory
'email_verified_at' => now(),
'password' => static::$password ??= Hash::make('password'),
'remember_token' => Str::random(10),
+ // Keeps existing assertions of English copy stable regardless of
+ // the app's production locale default; tests that care about
+ // Dutch rendering override this explicitly via create(['locale' => 'nl']).
+ 'locale' => 'en',
'two_factor_secret' => null,
'two_factor_recovery_codes' => null,
'two_factor_confirmed_at' => null,
diff --git a/database/migrations/2026_08_04_000001_add_holder_last_name_to_certificates_table.php b/database/migrations/2026_08_04_000001_add_holder_last_name_to_certificates_table.php
new file mode 100644
index 0000000..e5208ad
--- /dev/null
+++ b/database/migrations/2026_08_04_000001_add_holder_last_name_to_certificates_table.php
@@ -0,0 +1,25 @@
+string('holder_last_name')->nullable()->after('certificate_number');
+
+ $table->index(['certificate_number', 'holder_last_name']);
+ });
+ }
+
+ public function down(): void
+ {
+ Schema::table('certificates', function (Blueprint $table) {
+ $table->dropIndex(['certificate_number', 'holder_last_name']);
+ $table->dropColumn('holder_last_name');
+ });
+ }
+};
diff --git a/lang/en.json b/lang/en.json
new file mode 100644
index 0000000..665d3e7
--- /dev/null
+++ b/lang/en.json
@@ -0,0 +1,395 @@
+{
+ "\"AVG\"/\"GDPR\"": "\"GDPR\"",
+ "\"Dienst\" betekent Certified: het platform waarmee je je eigen certificaten, diploma's en vergelijkbare documenten beheert, inclusief automatische OCR-herkenning, reminders en veilig delen.": "\"Service\" means Certified: the platform on which you manage your own certificates, diplomas, and similar documents, including automatic OCR recognition, reminders, and secure sharing.",
+ "\"Gebruiker\" of \"je\"/\"jij\" betekent de natuurlijke persoon die een account aanmaakt en de Dienst gebruikt.": "\"User\" or \"you\" means the natural person who creates an account and uses the Service.",
+ "\"Inbreuk in verband met persoonsgegevens\"": "\"Personal data breach\"",
+ "\"Inhoud\" betekent alle certificaten, documenten, gegevens en bestanden die je naar de Dienst uploadt.": "\"Content\" means all certificates, documents, data, and files you upload to the Service.",
+ "\"Overeenkomst\" betekent deze Gebruiksvoorwaarden, samen met onze Privacyverklaring en, indien van toepassing, de Verwerkersovereenkomst.": "\"Agreement\" means these Terms of Service, together with our Privacy Policy and, where applicable, the Data Processing Agreement.",
+ "\"Persoonsgegevens\"": "\"Personal data\"",
+ "\"Sub-verwerker\"": "\"Sub-processor\"",
+ "\"Verwerker\"": "\"Processor\"",
+ "\"Verwerkingsverantwoordelijke\"": "\"Controller\"",
+ "1 maand van tevoren": "1 month ahead",
+ "100% Europese hosting": "100% European hosting",
+ "100% Europese hosting, onder Europees recht": "100% European hosting, under European law",
+ "2 maanden van tevoren": "2 months ahead",
+ "4.1 De verwerker erkent dat Certified mede bedoeld is voor het opslaan van documenten die bijzondere persoonsgegevens kunnen bevatten in de zin van artikel 9 en 10 AVG, zoals gegevens over het strafrechtelijk verleden bij een Verklaring Omtrent het Gedrag (VOG). De verwerkingsverantwoordelijke is zelf verantwoordelijk voor het hebben van een geldige rechtsgrond wanneer hij dergelijke gegevens van anderen dan zichzelf verwerkt.": "4.1 The processor acknowledges that Certified is partly intended for storing documents that may contain special category personal data within the meaning of articles 9 and 10 GDPR, such as data on criminal history in a Certificate of Conduct (VOG). The controller is responsible for having a valid legal basis when processing such data on behalf of anyone other than themselves.",
+ "AES-256 versleuteld": "AES-256 encrypted",
+ "AES-256 versleuteld delen": "AES-256 encrypted sharing",
+ "AES-256 versleutelde ZIP met een apart verstuurd wachtwoord": "AES-256 encrypted ZIP with a separately sent password",
+ "AES-256 versleutelde ZIP-export": "AES-256 encrypted ZIP export",
+ "AES-256 versleutelde ZIP-exports": "AES-256 encrypted ZIP exports",
+ "AVG / GDPR-proof": "GDPR-proof",
+ "Aan": "To",
+ "Aan de slag": "Get started",
+ "Aanbieder": "Provider",
+ "Aansprakelijkheid wordt geregeld conform artikel 82 AVG en de aansprakelijkheidsbepaling in de Gebruiksvoorwaarden. Op deze overeenkomst is Nederlands recht van toepassing; geschillen worden voorgelegd aan de bevoegde rechtbank te Arnhem.": "Liability is governed by article 82 GDPR and the liability clause in the Terms of Service. This agreement is governed by Dutch law; disputes are submitted to the competent court in Arnhem.",
+ "Account en authenticatie": "Account and authentication",
+ "Afhankelijk van hoe de verwerkingsverantwoordelijke Certified gebruikt, kunnen de volgende gegevens worden verwerkt: naam, contactgegevens, certificaatgegevens (titel, uitgever, geldigheidsdata) en het geüploade document zelf.": "Depending on how the controller uses Certified, the following data may be processed: name, contact details, certificate data (title, issuer, validity dates), and the uploaded document itself.",
+ "Al je certificaten op één plek.": "All your certificates in one place.",
+ "Al je certificaten op één plek. Nooit meer verlopen.": "All your certificates in one place. Never expired again.",
+ "Al je data in EU-datacenters, volledig AVG-proof.": "All your data in EU data centers, fully GDPR-proof.",
+ "Al je data staat in Europese datacenters, onder Europees recht. Geen Amerikaanse cloud, geen CLOUD Act, volledig AVG/GDPR-compliant.": "All your data is stored in European data centers, under European law. No American cloud, no CLOUD Act, fully GDPR compliant.",
+ "Algemene voorwaarden": "Terms of Service",
+ "Alle applicatie- en documentdata staat in Europese datacenters. We gebruiken bewust geen Amerikaanse hyperscalers: je data valt daardoor niet onder de Amerikaanse CLOUD Act en blijft volledig binnen de reikwijdte van de AVG/GDPR. Back-ups worden versleuteld opgeslagen, eveneens binnen de EU.": "All application and document data is stored in European data centers. We deliberately avoid American hyperscalers: your data therefore does not fall under the American CLOUD Act and remains fully within the scope of the GDPR. Backups are stored encrypted, also within the EU.",
+ "Alle prijzen zijn per jaar en exclusief btw. Start gratis — upgraden kan altijd, opzeggen ook.": "All prices are per year and exclude VAT. Start for free — you can upgrade or cancel at any time.",
+ "Alle rechten voorbehouden.": "All rights reserved.",
+ "Alleen jij, vanuit je eigen account. De scheiding tussen accounts wordt op databaseniveau afgedwongen. Onze eigen medewerkers hebben geen toegang tot documentinhoud, behalve wanneer jij daar bij een supportverzoek expliciet toestemming voor geeft.": "Only you, from your own account. The separation between accounts is enforced at the database level. Our own staff have no access to document content, except when you explicitly grant permission for a support request.",
+ "Alles over facturering, opzeggen en overstappen.": "Everything about billing, cancelling, and switching plans.",
+ "Applicatiehosting, bestandsopslag en databases": "Application hosting, file storage, and databases",
+ "Artikel 1 — Definities": "Article 1 — Definitions",
+ "Artikel 1 — Partijen en definities": "Article 1 — Parties and definitions",
+ "Artikel 10 — Opzeggen en verwijdering van je data": "Article 10 — Cancelling and deletion of your data",
+ "Artikel 10 — Rechten van betrokkenen": "Article 10 — Rights of data subjects",
+ "Artikel 11 — Verwijdering en teruggave": "Article 11 — Deletion and return",
+ "Artikel 11 — Wijzigingen van deze voorwaarden": "Article 11 — Changes to these terms",
+ "Artikel 12 — Auditrechten": "Article 12 — Audit rights",
+ "Artikel 12 — Toepasselijk recht en bevoegde rechter": "Article 12 — Governing law and jurisdiction",
+ "Artikel 13 — Aansprakelijkheid en toepasselijk recht": "Article 13 — Liability and governing law",
+ "Artikel 2 — Acceptatie en geschiktheid": "Article 2 — Acceptance and eligibility",
+ "Artikel 2 — Onderwerp, aard en doel": "Article 2 — Subject matter, nature, and purpose",
+ "Artikel 3 — Looptijd": "Article 3 — Duration",
+ "Artikel 3 — Toegang en accountverplichtingen": "Article 3 — Access and account obligations",
+ "Artikel 4 — Aanvaardbaar gebruik": "Article 4 — Acceptable use",
+ "Artikel 4 — Persoonsgegevens en betrokkenen": "Article 4 — Personal data and data subjects",
+ "Artikel 5 — Abonnementen en betaling": "Article 5 — Subscriptions and payment",
+ "Artikel 5 — Verplichtingen van de verwerker": "Article 5 — Obligations of the processor",
+ "Artikel 6 — Intellectueel eigendom": "Article 6 — Intellectual property",
+ "Artikel 6 — Sub-verwerkers": "Article 6 — Sub-processors",
+ "Artikel 7 — Beschikbaarheid en wijzigingen van de Dienst": "Article 7 — Availability and changes to the Service",
+ "Artikel 7 — Internationale doorgiften": "Article 7 — International transfers",
+ "Artikel 8 — Beveiligingsmaatregelen": "Article 8 — Security measures",
+ "Artikel 8 — Gegevens, privacy en OCR-verwerking": "Article 8 — Data, privacy, and OCR processing",
+ "Artikel 9 — Aansprakelijkheid": "Article 9 — Liability",
+ "Artikel 9 — Meldplicht datalekken": "Article 9 — Data breach notification",
+ "Automatische OCR": "Automatic OCR",
+ "Automatische OCR-scan": "Automatic OCR scan",
+ "Automatische tekstherkenning (OCR) vindt alleen plaats als jij dit zelf inschakelt, via een door jou gekozen Europese provider. Je kunt OCR ook uitschakelen en velden handmatig invullen.": "Automatic text recognition (OCR) only takes place if you enable it yourself, via a European provider of your choice. You can also disable OCR and fill in fields manually.",
+ "Bckstage exploiteert Certified, een persoonlijke certificatenmanager waarmee je zelf je certificaten, diploma's en documenten zoals een VOG bijhoudt. Deze verklaring legt uit welke persoonsgegevens we verzamelen, waarom, hoe lang we ze bewaren en wat je rechten zijn onder de AVG/GDPR.": "Bckstage operates Certified, a personal certificate manager that lets you keep track of your own certificates, diplomas, and documents such as a Certificate of Conduct (VOG). This policy explains what personal data we collect, why, how long we keep it, and what rights you have under the GDPR.",
+ "Bckstage is verwerkingsverantwoordelijke voor alle persoonsgegevens die worden verwerkt om je Certified te leveren: je accountgegevens en de certificaatgegevens en documenten die je zelf uploadt.": "Bckstage is the controller for all personal data processed to provide you with Certified: your account data and the certificate data and documents you upload yourself.",
+ "Bckstage, die persoonsgegevens verwerkt namens de verwerkingsverantwoordelijke.": "Bckstage, which processes personal data on behalf of the controller.",
+ "Bekijk de prijzen": "View pricing",
+ "Bekijk de verwerkersovereenkomst": "View the Data Processing Agreement",
+ "Betaalde pakketten worden één keer per jaar gefactureerd: €12,50 per jaar voor Starter, €45 per jaar voor Onbeperkt, beide exclusief btw. Je ontvangt een factuur die je direct in je administratie kunt verwerken.": "Paid plans are billed once a year: €12.50 per year for Starter, €45 per year for Unlimited, both excluding VAT. You receive an invoice you can process directly in your own bookkeeping.",
+ "Beveiliging": "Security",
+ "Beveiligingslogboeken": "Security logs",
+ "Bezorging van reminders en accountmeldingen": "Delivery of reminders and account notifications",
+ "Bij beëindiging van het abonnement verwijdert de verwerker, naar keuze van de verwerkingsverantwoordelijke, alle persoonsgegevens of geeft deze terug in een machineleesbaar formaat. Zonder tijdige instructie verwijdert de verwerker alle gegevens binnen 30 dagen na beëindiging, inclusief back-ups binnen maximaal 90 dagen vanwege back-uprotatieschema's.": "Upon termination of the subscription, the processor will, at the controller's choice, delete all personal data or return it in a machine-readable format. Without timely instructions, the processor deletes all data within 30 days of termination, including backups within a maximum of 90 days due to backup rotation schedules.",
+ "Bijlage blijft voor altijd in inboxen en op mailservers staan": "The attachment stays in inboxes and on mail servers forever",
+ "Bijstand": "Assistance",
+ "Binnen tien minuten staan je eerste certificaten in Certified — inclusief automatische reminders. Start gratis met maximaal 5 certificaten.": "Within ten minutes your first certificates are in Certified — including automatic reminders. Start for free with up to 5 certificates.",
+ "Categorieën": "Categories",
+ "Certificaat": "Certificate",
+ "Certificaat herkend en ingevuld — klaar om op te slaan": "Certificate recognized and filled in — ready to save",
+ "Certificaatgegevens": "Certificate data",
+ "Certificaten": "Certificates",
+ "Certificaten die je deelt worden verpakt in een AES-256 versleutelde ZIP. Links zijn ondertekend en verlopen automatisch na 48 uur.": "Certificates you share are packaged into an AES-256 encrypted ZIP. Links are signed and automatically expire after 48 hours.",
+ "Certified bewaakt de geldigheid van al je certificaten. Automatische OCR, slimme reminders en AVG-proof delen — 100% Europese hosting.": "Certified watches over the validity of all your certificates. Automatic OCR, smart reminders, and GDPR-proof sharing — 100% European hosting.",
+ "Certified bewaart documenten met bijzondere persoonsgegevens — je VOG en andere gevoelige diploma's en certificaten. Op deze pagina lees je precies hoe we die gegevens beschermen.": "Certified stores documents containing special category personal data — your Certificate of Conduct (VOG) and other sensitive diplomas and certificates. This page explains exactly how we protect that data.",
+ "Certified controleert dagelijks alle vervaldatums en stuurt automatisch reminders — ruim op tijd om een certificaat te verlengen. Verloopt er toch iets? Dan krijg je direct een urgente melding, zodat het nooit onopgemerkt blijft.": "Certified checks all expiry dates daily and automatically sends reminders — well in time to renew a certificate. Does something expire anyway? You get an urgent notification right away, so it never goes unnoticed.",
+ "Certified gebruikt uitsluitend strikt noodzakelijke cookies: een sessiecookie om je ingelogd te houden, een CSRF-tokencookie ter beveiliging, en een voorkeurscookie voor je taal en weergave (licht/donker). We gebruiken geen reclamecookies, trackingpixels of analyses van derden. Er is geen cookiebanner nodig omdat we uitsluitend strikt noodzakelijke cookies plaatsen.": "Certified uses only strictly necessary cookies: a session cookie to keep you signed in, a CSRF token cookie for security, and a preference cookie for your language and appearance (light/dark). We do not use advertising cookies, tracking pixels, or third-party analytics. No cookie banner is required because we only place strictly necessary cookies.",
+ "Certified herinnert je opnieuw zolang het niet is verlengd.": "Certified reminds you again as long as it hasn't been renewed.",
+ "Certified is bedoeld voor het beheren van je eigen certificaten en documenten door jou als individu — niet voor het op grote schaal beheren van certificaten van andere personen namens een bedrijf of organisatie.": "Certified is intended for managing your own certificates and documents as an individual — not for managing certificates of other people on a large scale on behalf of a company or organization.",
+ "Certified is een hulpmiddel om je certificaten te overzien en je te herinneren aan vervaldatums — geen garantie dat je nooit een deadline mist. De Dienst wordt geleverd \"zoals het is\".": "Certified is a tool to help you keep an overview of your certificates and remind you of expiry dates — not a guarantee that you'll never miss a deadline. The Service is provided \"as is\".",
+ "Certified is gebouwd voor persoonlijk gebruik: jij beheert je eigen VOG, diploma's en certificaten. In dat geval ben je zelf geen verwerkingsverantwoordelijke in de zin van de AVG en heb je deze overeenkomst niet nodig.": "Certified is built for personal use: you manage your own Certificate of Conduct (VOG), diplomas, and certificates. In that case, you are not a controller within the meaning of the GDPR and you don't need this agreement.",
+ "Certified is niet bedoeld voor gebruik door personen jonger dan 16 jaar. Vermoed je dat we onbedoeld gegevens van een minderjarige hebben verzameld, neem dan contact met ons op zodat we deze kunnen verwijderen.": "Certified is not intended for use by people under the age of 16. If you suspect we have unintentionally collected data from a minor, please contact us so we can delete it.",
+ "Certified kent een gratis pakket en de betaalde abonnementen Starter en Onbeperkt, zoals beschreven op onze prijzenpagina. Betaalde abonnementen worden jaarlijks vooraf gefactureerd, exclusief btw.": "Certified has a free plan and the paid subscriptions Starter and Unlimited, as described on our pricing page. Paid subscriptions are billed annually in advance, excluding VAT.",
+ "Certified scant je VOG, diploma's en certificaten automatisch in, bewaakt elke vervaldatum en deelt ze alleen versleuteld — zonder Excel-lijstjes, losse mapjes of kwetsbare e-mailbijlagen.": "Certified automatically scans your Certificate of Conduct (VOG), diplomas, and certificates, watches every expiry date, and only shares them encrypted — no spreadsheets, loose folders, or vulnerable email attachments.",
+ "Certified — home": "Certified — home",
+ "Contact": "Contact",
+ "Cookies": "Cookies",
+ "Cryptografisch ondertekende deel-URL's": "Cryptographically signed sharing URLs",
+ "Data-isolatie afgedwongen op databaseniveau": "Data isolation enforced at the database level",
+ "Datacenters in de EU, data verlaat Europa nooit": "Data centers in the EU, data never leaves Europe",
+ "De Dienst gebruikt uitsluitend strikt noodzakelijke functionele cookies — geen reclame- of trackingcookies.": "The Service uses only strictly necessary functional cookies — no advertising or tracking cookies.",
+ "De gebruiksvoorwaarden voor het gebruik van Certified.": "The terms of service for using Certified.",
+ "De klant": "The customer",
+ "De natuurlijke persoon die een account aanmaakt bij Certified om zijn eigen certificaten, diploma's en documenten te beheren.": "The natural person who creates an account with Certified to manage their own certificates, diplomas, and documents.",
+ "De standaard verwerkersovereenkomst (DPA) van Certified, beschikbaar voor zzp'ers en eenmanszaken die er één nodig hebben.": "Certified's standard Data Processing Agreement (DPA), available for freelancers and sole proprietors who need one.",
+ "De veilige plek waar je zelf al je certificaten, diploma's en VOG's beheert. Gebouwd en gehost in Europa.": "The secure place where you manage all your own certificates, diplomas, and Certificates of Conduct. Built and hosted in Europe.",
+ "De verwerker geeft geen persoonsgegevens door aan derde landen buiten de EER, behalve aan Resend (Verenigde Staten) voor het bezorgen van reminders, op basis van passende waarborgen conform Hoofdstuk V AVG. Alle overige sub-verwerkers zijn gevestigd binnen de EU.": "The processor does not transfer personal data to third countries outside the EEA, except to Resend (United States) for delivering reminders, based on appropriate safeguards under Chapter V GDPR. All other sub-processors are located within the EU.",
+ "De verwerker handelt uitsluitend op gedocumenteerde instructies van de verwerkingsverantwoordelijke, tenzij Unierecht of nationale wetgeving anders vereist.": "The processor acts only on documented instructions from the controller, unless required otherwise by Union or national law.",
+ "De verwerker helpt de verwerkingsverantwoordelijke bij het beantwoorden van verzoeken van betrokkenen (inzage, rectificatie, verwijdering, beperking, overdraagbaarheid, bezwaar) en stuurt verzoeken die rechtstreeks bij de verwerker binnenkomen binnen 5 werkdagen door.": "The processor helps the controller respond to data subject requests (access, rectification, erasure, restriction, portability, objection) and forwards any request it receives directly within 5 business days.",
+ "De verwerker stelt de verwerkingsverantwoordelijke zonder onredelijke vertraging, en in elk geval binnen 72 uur nadat hij kennis heeft gekregen van een inbreuk in verband met persoonsgegevens, hiervan op de hoogte — met een beschrijving van de aard, de waarschijnlijke gevolgen en de genomen maatregelen.": "The processor notifies the controller without undue delay, and in any case within 72 hours of becoming aware of a personal data breach — with a description of the nature, likely consequences, and measures taken.",
+ "De verwerker verstrekt de informatie die redelijkerwijs nodig is om naleving van artikel 28 AVG aan te tonen. Auditverzoeken worden schriftelijk ingediend met ten minste 30 dagen vooraankondiging en mogen de beveiliging van gegevens van andere klanten niet in gevaar brengen.": "The processor provides the information reasonably necessary to demonstrate compliance with article 28 GDPR. Audit requests must be submitted in writing with at least 30 days' notice and may not jeopardize the security of other customers' data.",
+ "De verwerker verwerkt persoonsgegevens niet voor eigen doeleinden, reclame, profilering of enig ander doel dan het leveren en verbeteren van Certified.": "The processor does not process personal data for its own purposes, advertising, profiling, or any purpose other than providing and improving Certified.",
+ "De verwerker verwerkt persoonsgegevens uitsluitend om Certified te leveren aan de verwerkingsverantwoordelijke: opslag, OCR-herkenning, het bewaken van vervaldatums en het veilig delen van certificaten.": "The processor processes personal data solely to provide Certified to the controller: storage, OCR recognition, monitoring expiry dates, and securely sharing certificates.",
+ "De vragen die we het vaakst krijgen over privacy en gegevensbescherming.": "The questions we get asked most often about privacy and data protection.",
+ "De zzp'er of eenmanszaak die Certified gebruikt en zelf certificaatgegevens van anderen verwerkt.": "The freelancer or sole proprietor who uses Certified and processes certificate data of others themselves.",
+ "Delen met": "Sharing with",
+ "Derden en internationale doorgiften": "Third parties and international transfers",
+ "Deze overeenkomst blijft van kracht gedurende de looptijd van het abonnement en eindigt automatisch bij beëindiging daarvan, onder voorbehoud van artikel 11 (Verwijdering en teruggave).": "This agreement remains in effect for the duration of the subscription and automatically ends upon its termination, subject to article 11 (Deletion and return).",
+ "Deze overeenkomst wordt geacht te zijn aanvaard bij eerste gebruik van Certified in de context van je eigen bedrijfsvoering. Voor een getekende kopie voor je eigen archief mail je ons via": "This agreement is deemed accepted upon first use of Certified in the context of your own business. For a signed copy for your own records, email us at",
+ "Diploma's & getuigschriften": "Diplomas & certificates of completion",
+ "Direct een urgente melding in je inbox": "An urgent notification straight to your inbox",
+ "Document scannen…": "Scanning document…",
+ "Documenten uploaden die niet van jou zijn, zonder toestemming van de rechthebbende": "Uploading documents that are not yours without permission from the rights holder",
+ "Documenten zoals een VOG bevatten bijzondere persoonsgegevens. Daarom is Certified vanaf de eerste regel code gebouwd op privacy-by-design — en blijft je data binnen de EU.": "Documents such as a Certificate of Conduct contain special category personal data. That's why Certified was built on privacy-by-design from the very first line of code — and your data stays within the EU.",
+ "Doel": "Purpose",
+ "Door deze overeenkomst aan te gaan geeft de verwerkingsverantwoordelijke algemene toestemming aan de verwerker om de volgende sub-verwerkers in te schakelen:": "By entering into this agreement, the controller gives general authorization to the processor to engage the following sub-processors:",
+ "Door een account aan te maken of de Dienst te gebruiken, ga je akkoord met deze Overeenkomst. Ga je hier niet mee akkoord, dan mag je de Dienst niet gebruiken.": "By creating an account or using the Service, you agree to this Agreement. If you do not agree, you may not use the Service.",
+ "Doorverkoop of sublicentiëring van toegang tot de Dienst zonder onze voorafgaande schriftelijke toestemming": "Reselling or sublicensing access to the Service without our prior written consent",
+ "Downgraden of opzeggen van een betaald abonnement gaat in op de eerstvolgende verlengingsdatum. Reeds betaalde bedragen worden niet naar rato terugbetaald.": "Downgrading or cancelling a paid subscription takes effect on the next renewal date. Amounts already paid are not refunded pro rata.",
+ "Drie pijlers die samen je hele certificatenbeheer afdekken — zonder handwerk.": "Three pillars that together cover your entire certificate management — without manual work.",
+ "E-mail op het moment dat jij instelt, plus urgente meldingen.": "Email at the time you set, plus urgent notifications.",
+ "E-mailbijlage": "Email attachment",
+ "EHBO & BHV": "First aid & emergency response",
+ "EU (Nederland)": "EU (Netherlands)",
+ "Een volledig overzicht van onze beveiligingsmaatregelen vind je op onze security-pagina.": "A full overview of our security measures can be found on our security page.",
+ "Eerlijke prijzen voor je eigen certificaatbeheer. Start gratis met maximaal 5 certificaten — inclusief OCR, slimme reminders en AVG-proof delen.": "Fair pricing for managing your own certificates. Start for free with up to 5 certificates — including OCR, smart reminders, and GDPR-proof sharing.",
+ "Eerlijke prijzen, geen verrassingen": "Fair pricing, no surprises",
+ "Eigen infrastructuur": "Own infrastructure",
+ "Elk gebruik dat in strijd is met toepasselijk recht of rechten van derden": "Any use that violates applicable law or the rights of third parties",
+ "Europese OCR-providers": "European OCR providers",
+ "Europese hosting": "European hosting",
+ "Europese privacy & security": "European privacy & security",
+ "Eén vast bedrag, jaarlijks gefactureerd": "One fixed price, billed annually",
+ "Eén verlopen certificaat kost je al snel meer dan een jaar Certified. Start gratis en betaal pas als je meer certificaten beheert.": "One expired certificate can easily cost you more than a year of Certified. Start for free and only pay once you manage more certificates.",
+ "Facturering (betaalde abonnementen)": "Billing (paid subscriptions)",
+ "Facturering van betaalde abonnementen": "Billing of paid subscriptions",
+ "Features": "Features",
+ "Frankrijk (EU)": "France (EU)",
+ "Geautomatiseerd scrapen, crawlen of op grote schaal gegevens onttrekken aan de Dienst": "Automated scraping, crawling, or large-scale data extraction from the Service",
+ "Gebruik je Certified puur voor je eigen certificaten? Dan heb je geen verwerkersovereenkomst nodig — je bent geen verwerkingsverantwoordelijke in de zin van de AVG. Werk je als zzp'er of eenmanszaak en wil je er toch één voor je eigen administratie, dan kun je die downloaden op onze DPA-pagina.": "Do you use Certified purely for your own certificates? Then you don't need a Data Processing Agreement — you are not a controller within the meaning of the GDPR. If you work as a freelancer or sole proprietor and want one for your own records anyway, you can download it on our DPA page.",
+ "Gebruik je Certified voor je eigen certificaten, dan heb je geen verwerkersovereenkomst nodig — je bent zelf geen verwerkingsverantwoordelijke onder de AVG. Werk je als zzp'er of eenmanszaak en wil je er voor je eigen administratie toch één, dan staat de standaard verwerkersovereenkomst voor je klaar.": "If you use Certified for your own certificates, you don't need a Data Processing Agreement — you are not a controller under the GDPR. If you work as a freelancer or sole proprietor and want one for your own records anyway, the standard agreement is ready for you.",
+ "Gebruiker": "User",
+ "Gedeelde documenten alleen bereikbaar via cryptografisch ondertekende, automatisch verlopende links": "Shared documents only accessible via cryptographically signed links that expire automatically",
+ "Geen Amerikaanse cloudproviders in de keten": "No American cloud providers in the chain",
+ "Geen controle: doorsturen, kopiëren en lekken kan ongemerkt": "No control: forwarding, copying, and leaks can go unnoticed",
+ "Geen creditcard nodig": "No credit card required",
+ "Geldig": "Valid",
+ "Gemaakt in Nederland": "Made in the Netherlands",
+ "Geschillen worden voorgelegd aan de bevoegde rechtbank te Arnhem, Nederland, tenzij dwingend consumentenrecht in jouw woonland anders bepaalt.": "Disputes are submitted to the competent court in Arnhem, the Netherlands, unless mandatory consumer law in your country of residence provides otherwise.",
+ "Gevoelige gegevens verdienen Europese waarborgen": "Sensitive data deserves European safeguards",
+ "Gratis": "Free",
+ "Gratis tot 5 certificaten": "Free up to 5 certificates",
+ "Heb ik een verwerkersovereenkomst nodig bij een betaald pakket?": "Do I need a Data Processing Agreement with a paid plan?",
+ "Heb ik een verwerkersovereenkomst nodig?": "Do I need a Data Processing Agreement?",
+ "Heb je deze wel nodig?": "Do you actually need this?",
+ "Herinnering": "Reminder",
+ "Herkent titel, uitgever en vervaldatum in seconden": "Recognizes title, issuer, and expiry date in seconds",
+ "Het document wordt via een beveiligde verbinding naar de door jou gekozen Europese provider (Klippa of Mistral AI) gestuurd, die er tekst uit herkent en het resultaat teruggeeft. Wil je dit niet, dan zet je OCR uit en vul je de velden handmatig in.": "The document is sent over a secure connection to the European provider you chose (Klippa or Mistral AI), which recognizes text in it and returns the result. If you don't want this, turn off OCR and fill in the fields manually.",
+ "Het volgende is niet toegestaan:": "The following is not allowed:",
+ "Hoe Certified je certificaten beschermt: 100% Europese hosting, AES-256 versleuteld delen en keuze uit Europese OCR-providers. Volledig AVG/GDPR-compliant.": "How Certified protects your certificates: 100% European hosting, AES-256 encrypted sharing, and a choice of European OCR providers. Fully GDPR compliant.",
+ "Hoe Certified omgaat met je persoonsgegevens: welke gegevens we verzamelen, waarom, en welke rechten je hebt.": "How Certified handles your personal data: what data we collect, why, and what rights you have.",
+ "Hoe lang blijft een gedeelde link geldig?": "How long does a shared link stay valid?",
+ "Hoe we met je persoonsgegevens omgaan staat beschreven in onze Privacyverklaring, die integraal onderdeel uitmaakt van deze Overeenkomst.": "How we handle your personal data is described in our Privacy Policy, which forms an integral part of this Agreement.",
+ "Hoe werkt de automatische OCR-scan?": "How does the automatic OCR scan work?",
+ "Hoe werkt de facturering?": "How does billing work?",
+ "Hoofdnavigatie": "Main navigation",
+ "Hosting & jurisdictie": "Hosting & jurisdiction",
+ "IP-adres, browser- en apparaatinformatie en inloggebeurtenissen, gebruikt om misbruik te detecteren en beveiligingsincidenten te onderzoeken.": "IP address, browser and device information, and login events, used to detect abuse and investigate security incidents.",
+ "Inbegrepen bij elk pakket": "Included in every plan",
+ "Instellingen": "Settings",
+ "Is Certified geschikt voor gevoelige documenten, zoals een VOG?": "Is Certified suitable for sensitive documents, such as a Certificate of Conduct?",
+ "Is het Gratis-pakket echt gratis?": "Is the Free plan really free?",
+ "Ja, daar is Certified juist voor gebouwd. Je documenten staan versleuteld op Europese servers, worden nooit als open bijlage gedeeld en zijn alleen toegankelijk met jouw account. Delen met anderen gebeurt via een tijdelijke ondertekende link of een AES-256 versleutelde ZIP.": "Yes, that's exactly what Certified is built for. Your documents are stored encrypted on European servers, are never shared as an open attachment, and are only accessible with your account. Sharing with others happens via a temporary signed link or an AES-256 encrypted ZIP.",
+ "Ja, voor altijd. Je beheert er tot 5 certificaten mee, inclusief OCR-scan, reminders en veilig delen. Geen creditcard, geen verborgen kosten — pas als je meer dan 5 certificaten wilt bewaken, stap je over op een betaald pakket.": "Yes, forever. You can manage up to 5 certificates with it, including OCR scanning, reminders, and secure sharing. No credit card, no hidden costs — you only switch to a paid plan once you want to track more than 5 certificates.",
+ "Ja. Je kunt op elk moment al je certificaten en metadata exporteren. Zeg je op, dan verwijderen we je data — inclusief back-ups — binnen 30 dagen definitief, conform de AVG.": "Yes. You can export all your certificates and metadata at any time. If you cancel, we permanently delete your data — including backups — within 30 days, in accordance with the GDPR.",
+ "Je BHV-diploma verloopt over 2 maanden": "Your emergency response certificate expires in 2 months",
+ "Je VOG of diploma als onbeveiligde bijlage naar een nieuwe werkgever of instantie mailen is vragen om problemen. Certified deelt je documenten alleen versleuteld en tijdelijk.": "Emailing your Certificate of Conduct or diploma as an unsecured attachment to a new employer or authority is asking for trouble. Certified only shares your documents encrypted and temporarily.",
+ "Je account is persoonlijk; het delen van je inloggegevens met anderen is niet toegestaan.": "Your account is personal; sharing your login details with others is not allowed.",
+ "Je bent verantwoordelijk voor het geheimhouden van je wachtwoord of passkey en meldt vermoed onbevoegd gebruik direct aan ons.": "You are responsible for keeping your password or passkey confidential and for reporting any suspected unauthorized use to us immediately.",
+ "Je bent zelf verantwoordelijk voor het geven van juiste en actuele gegevens bij registratie, en voor het up-to-date houden daarvan.": "You are responsible for providing accurate and up-to-date information when registering, and for keeping it up to date.",
+ "Je certificaten en accountgegevens worden opgeslagen in datacenters binnen de Europese Unie. We gebruiken geen Amerikaanse cloudproviders voor hosting, waardoor je gegevens niet onder de Amerikaanse CLOUD Act vallen.": "Your certificates and account data are stored in data centers within the European Union. We do not use American cloud providers for hosting, so your data does not fall under the American CLOUD Act.",
+ "Je documenten worden versleuteld opgeslagen en al het verkeer loopt via TLS. Deel je een certificaat met iemand anders, dan gebeurt dat via een AES-256 versleutelde ZIP met een apart verstuurd wachtwoord, of via een ondertekende link die na 48 uur automatisch onbruikbaar wordt. API-sleutels van OCR-providers slaan we versleuteld op.": "Your documents are stored encrypted and all traffic runs over TLS. If you share a certificate with someone else, this happens via an AES-256 encrypted ZIP with a separately sent password, or via a signed link that automatically becomes unusable after 48 hours. We store OCR provider API keys encrypted.",
+ "Je kunt je account op elk moment opzeggen vanuit je instellingen. Je kunt daarvoor al je certificaten en gegevens exporteren. Na opzegging verwijderen we je gegevens, inclusief back-ups, definitief binnen 30 dagen. Wij kunnen je account opschorten of beëindigen bij een wezenlijke schending van artikel 4.": "You can cancel your account at any time from your settings. Before doing so, you can export all your certificates and data. After cancellation, we permanently delete your data, including backups, within 30 days. We may suspend or terminate your account for a material breach of article 4.",
+ "Je uploadt een PDF of foto van je certificaat. Onze OCR-engine herkent automatisch de titel, uitgever en vervaldatum en vult die voor je in. Jij controleert en slaat op — dat is alles. Je kiest zelf welke Europese provider (Klippa of Mistral AI) de verwerking doet.": "You upload a PDF or photo of your certificate. Our OCR engine automatically recognizes the title, issuer, and expiry date and fills them in for you. You check and save — that's it. You choose which European provider (Klippa or Mistral AI) does the processing.",
+ "Je verklaart dat je ten minste 16 jaar oud bent.": "You declare that you are at least 16 years old.",
+ "Jij": "You",
+ "Jij behoudt alle rechten op je eigen Inhoud. Je geeft ons een beperkte licentie om je Inhoud op te slaan, te verwerken en te verzenden, uitsluitend voor zover nodig om de Dienst aan jou te leveren.": "You retain all rights to your own Content. You grant us a limited license to store, process, and transmit your Content, solely to the extent necessary to provide the Service to you.",
+ "Jij bepaalt zelf hoeveel maanden van tevoren je gewaarschuwd wilt worden.": "You decide for yourself how many months in advance you want to be warned.",
+ "Jij kiest welke Europese partij je documenten leest": "You choose which European party reads your documents",
+ "Jij ziet uitsluitend je eigen certificaten — afgedwongen op databaseniveau, niet alleen in de interface. Inloggen kan met wachtwoord of passkeys, en documenten die je deelt zijn alleen bereikbaar via cryptografisch ondertekende URL's die niet te raden of te vervalsen zijn.": "You only ever see your own certificates — enforced at the database level, not just in the interface. You can sign in with a password or passkeys, and documents you share are only reachable via cryptographically signed URLs that cannot be guessed or forged.",
+ "Jouw rechten": "Your rights",
+ "Juridisch": "Legal",
+ "Kan ik Certified eerst vrijblijvend proberen?": "Can I try Certified first without obligation?",
+ "Kan ik al mijn data exporteren of laten verwijderen?": "Can I export or delete all my data?",
+ "Kan ik tussentijds upgraden, downgraden of opzeggen?": "Can I upgrade, downgrade, or cancel in the middle of the term?",
+ "Keuze uit Europese providers: Klippa of Mistral AI": "Choice of European providers: Klippa or Mistral AI",
+ "Kies zelf wie je documenten leest: Klippa (Nederland) of Mistral AI (Frankrijk). Je documenten verlaten Europa nooit — jij houdt de regie.": "Choose for yourself who reads your documents: Klippa (Netherlands) or Mistral AI (France). Your documents never leave Europe — you stay in control.",
+ "Klippa: Nederlandse document-AI specialist": "Klippa: Dutch document AI specialist",
+ "Lees alles over security & privacy": "Read all about security & privacy",
+ "Locatie": "Location",
+ "Login": "Login",
+ "Malware, virussen of schadelijke code uploaden of verspreiden via de Dienst": "Uploading or spreading malware, viruses, or harmful code via the Service",
+ "Maximaal 20 certificaten": "Up to 20 certificates",
+ "Maximaal 48 uur. Daarna is de ondertekende URL cryptografisch ongeldig en kan niemand het document meer openen — ook niet met de oude link. Versleutelde ZIP-exports blijven beveiligd met AES-256 en het apart verstuurde wachtwoord.": "A maximum of 48 hours. After that, the signed URL is cryptographically invalid and no one can open the document anymore — not even with the old link. Encrypted ZIP exports remain protected with AES-256 and the separately sent password.",
+ "Maximaal 5 certificaten": "Up to 5 certificates",
+ "Meest gekozen": "Most popular",
+ "Meestal niet — gebruik je Certified voor jezelf, dan ben je geen verwerkingsverantwoordelijke. Wil je er als zzp'er of eenmanszaak toch één voor je administratie, dan staat de standaard verwerkersovereenkomst gratis voor je klaar op de DPA-pagina.": "Usually not — if you use Certified for yourself, you are not a controller. If you're a freelancer or sole proprietor and want one for your own records anyway, the standard Data Processing Agreement is available for free on our DPA page.",
+ "Menu openen": "Open menu",
+ "Mijn VOG — zie bijlage": "My Certificate of Conduct — see attachment",
+ "Minderjarigen": "Minors",
+ "Mistral AI: Frans AI-bedrijf, EU-gehost": "Mistral AI: French AI company, EU-hosted",
+ "Naam, e-mailadres, gehasht wachtwoord of passkey, taalvoorkeur en sessiegegevens.": "Name, email address, hashed password or passkey, language preference, and session data.",
+ "Naam, factuuradres en e-mailadres voor facturering. Betalingsgegevens worden niet door Bckstage zelf opgeslagen.": "Name, billing address, and email address for invoicing. Payment details are not stored by Bckstage itself.",
+ "Nederland": "The Netherlands",
+ "Nederland (EU)": "Netherlands (EU)",
+ "Nederlands recht, EU-hosting": "Dutch law, EU hosting",
+ "Nee. Certified draait uitsluitend op Europese infrastructuur van Europese leveranciers. Er is geen Amerikaanse partij in de hostingketen, dus de CLOUD Act is niet van toepassing op jouw data.": "No. Certified runs exclusively on European infrastructure from European providers. There is no American party in the hosting chain, so the CLOUD Act does not apply to your data.",
+ "Nee. OCR-scans zitten bij elk pakket inbegrepen — ook bij Gratis. Je betaalt nooit per scan.": "No. OCR scans are included in every plan — even the Free one. You never pay per scan.",
+ "Neem contact met ons op via": "Contact us at",
+ "Niets ergs — je data blijft gewoon staan. We sturen een melding en je kunt eenvoudig upgraden naar het volgende pakket. We verwijderen nooit certificaten omdat je over een limiet heen bent.": "Nothing bad — your data simply stays put. We send a notification and you can easily upgrade to the next plan. We never delete certificates because you've gone over a limit.",
+ "Niets in deze Overeenkomst beperkt aansprakelijkheid voor overlijden of persoonlijk letsel door onze nalatigheid, fraude, of andere aansprakelijkheid die niet kan worden uitgesloten onder Nederlands recht.": "Nothing in this Agreement limits liability for death or personal injury caused by our negligence, fraud, or any other liability that cannot be excluded under Dutch law.",
+ "Nog geen nieuw certificaat geüpload": "No new certificate uploaded yet",
+ "Nooit meer per ongeluk verlopen.": "Never accidentally expired again.",
+ "OCR volledig uitschakelbaar per account": "OCR fully switchable off per account",
+ "OCR-herkenning — alleen als jij dit inschakelt": "OCR recognition — only if you enable it",
+ "OCR-herkenning — alleen indien geactiveerd": "OCR recognition — only if activated",
+ "OCR-verwerking": "OCR processing",
+ "OCR-verwerking (optioneel)": "OCR processing (optional)",
+ "Onbeperkt": "Unlimited",
+ "Onbeperkt certificaten": "Unlimited certificates",
+ "Onbeveiligd verstuurd — een onnodig risico op misbruik van je gegevens": "Sent unsecured — an unnecessary risk of misuse of your data",
+ "Onder de AVG heb je recht op inzage, rectificatie, verwijdering, beperking van de verwerking, gegevensoverdraagbaarheid en bezwaar. Je kunt je certificaten en gegevens grotendeels zelf inzien en exporteren vanuit je account; voor andere verzoeken mail je ons. We reageren binnen één maand. Je hebt ook het recht een klacht in te dienen bij de Autoriteit Persoonsgegevens.": "Under the GDPR you have the right to access, rectification, erasure, restriction of processing, data portability, and objection. You can view and export most of your certificates and data yourself from your account; for other requests, email us. We respond within one month. You also have the right to lodge a complaint with the Dutch Data Protection Authority.",
+ "Ondersteuning voor passkeys (phishing-bestendig inloggen)": "Passkey support (phishing-resistant sign-in)",
+ "Ondersteuning voor phishing-bestendige authenticatie via passkeys": "Support for phishing-resistant authentication via passkeys",
+ "Ondertekende deel-links met een maximale geldigheid van 48 uur": "Signed sharing links valid for a maximum of 48 hours",
+ "Ondertekende links (48u) en AES-256 versleutelde ZIP's.": "Signed links (48h) and AES-256 encrypted ZIPs.",
+ "Ondertekening": "Signing",
+ "Ontdek hoe het werkt": "See how it works",
+ "Op deze Overeenkomst is Nederlands recht van toepassing.": "This Agreement is governed by Dutch law.",
+ "Op tijd gewaarschuwd, elke keer weer": "Warned in time, every single time",
+ "Opzeggen wanneer je wilt": "Cancel whenever you want",
+ "Overzicht hoeft niet duur te zijn": "A clear overview doesn't have to be expensive",
+ "Partij": "Party",
+ "Pricing": "Pricing",
+ "Prijzen": "Pricing",
+ "Prioriteit support": "Priority support",
+ "Privacy-by-design, gebouwd in Europa": "Privacy-by-design, built in Europe",
+ "Privacyverklaring": "Privacy Policy",
+ "Privacyvriendelijk: geen kopieën die ergens blijven rondslingeren": "Privacy-friendly: no copies left lying around anywhere",
+ "Probeer de demo-scan": "Try the demo scan",
+ "Proberen onbevoegde toegang te krijgen tot enig onderdeel van de Dienst of gegevens van andere gebruikers": "Attempting to gain unauthorized access to any part of the Service or other users' data",
+ "Rechtsgrond: gerechtvaardigd belang (art. 6 lid 1 sub f AVG) · Bewaartermijn: 90 dagen": "Legal basis: legitimate interest (art. 6(1)(f) GDPR) · Retention: 90 days",
+ "Rechtsgrond: overeenkomst (art. 6 lid 1 sub b AVG) · Bewaartermijn: 90 dagen in maillogboeken": "Legal basis: contract (art. 6(1)(b) GDPR) · Retention: 90 days in mail logs",
+ "Rechtsgrond: overeenkomst (art. 6 lid 1 sub b AVG) · Bewaartermijn: tot accountverwijdering + 30 dagen": "Legal basis: contract (art. 6(1)(b) GDPR) · Retention: until account deletion + 30 days",
+ "Rechtsgrond: overeenkomst (art. 6 lid 1 sub b AVG) · Bewaartermijn: tot verwijdering door jou, of tot 30 dagen na accountopzegging": "Legal basis: contract (art. 6(1)(b) GDPR) · Retention: until deleted by you, or up to 30 days after account cancellation",
+ "Rechtsgrond: toestemming (art. 6 lid 1 sub a AVG) · Bewaartermijn: niet permanent opgeslagen bij de provider": "Legal basis: consent (art. 6(1)(a) GDPR) · Retention: not permanently stored by the provider",
+ "Rechtsgrond: wettelijke verplichting (art. 6 lid 1 sub c AVG) · Bewaartermijn: 7 jaar (Nederlandse belastingwet)": "Legal basis: legal obligation (art. 6(1)(c) GDPR) · Retention: 7 years (Dutch tax law)",
+ "Regel het vandaag nog. Niet pas als het te laat is.": "Sort it out today. Not once it's too late.",
+ "Regelmatige geautomatiseerde back-ups": "Regular automated backups",
+ "Reminder": "Reminder",
+ "Reminders": "Reminders",
+ "Reverse-engineeren, decompileren of afgeleide werken maken van de Dienst": "Reverse-engineering, decompiling, or creating derivative works of the Service",
+ "Rustig de tijd om een herhalingscursus in te plannen.": "Plenty of time to schedule a refresher course.",
+ "Scan opnieuw": "Scan again",
+ "Schakel je automatische tekstherkenning in, dan wordt het document dat je op dat moment uploadt gestuurd naar de Europese provider die jij zelf kiest: Klippa (Nederland) of Mistral AI (Frankrijk). Zonder deze instelling gebeurt dit niet.": "If you enable automatic text recognition, the document you upload at that moment is sent to the European provider you choose: Klippa (Netherlands) or Mistral AI (France). Without this setting, this does not happen.",
+ "Security": "Security",
+ "Security & privacy": "Security & privacy",
+ "Security & privacy als fundament,": "Security & privacy as a foundation,",
+ "Servicecommunicatie": "Service communication",
+ "Sleep je certificaat in Certified en de OCR-engine herkent automatisch de titel, uitgever en vervaldatum. Geen overtypwerk, geen tikfouten in vervaldatums — en jij kiest zelf welke Europese OCR-provider je document verwerkt.": "Drag your certificate into Certified and the OCR engine automatically recognizes the title, issuer, and expiry date. No retyping, no typos in expiry dates — and you choose which European OCR provider processes your document.",
+ "Slimme e-mailreminders": "Smart email reminders",
+ "Slimme reminders": "Smart reminders",
+ "Soorten certificaten": "Types of certificates",
+ "Staat je vraag er niet tussen? Mail ons via support@certified.eu.": "Don't see your question? Email us at support@certified.eu.",
+ "Standaard ontvang je twee maanden van tevoren een e-mail, en daarna opnieuw zolang je het certificaat niet hebt verlengd. Verloopt een certificaat vandaag, dan krijg je direct een urgente melding. Het aantal maanden stel je zelf in bij je instellingen.": "By default you receive an email two months in advance, and again as long as you haven't renewed the certificate. If a certificate expires today, you get an urgent notification immediately. You set the number of months yourself in your settings.",
+ "Start gratis": "Start for free",
+ "Start gratis en groei mee wanneer je meer certificaten beheert. Elk pakket bevat OCR, reminders en veilig delen.": "Start for free and grow along as you manage more certificates. Every plan includes OCR, reminders, and secure sharing.",
+ "Start met Onbeperkt": "Start with Unlimited",
+ "Start met Starter": "Start with Starter",
+ "Status": "Status",
+ "Stop met certificaten mailen als losse bijlage": "Stop emailing certificates as loose attachments",
+ "Strikte scheiding tussen accounts": "Strict separation between accounts",
+ "Sub-verwerker": "Sub-processor",
+ "Sub-verwerkers": "Sub-processors",
+ "TLS voor al het verkeer, versleutelde opslag van API-sleutels": "TLS for all traffic, encrypted storage of API keys",
+ "Tijdelijke ondertekende URL die na 48 uur automatisch verloopt": "Temporary signed URL that automatically expires after 48 hours",
+ "Titel": "Title",
+ "Titel, uitgever en vervaldatum automatisch herkend.": "Title, issuer, and expiry date recognized automatically.",
+ "Titel, uitgever, certificaatnummer, uitgifte- en vervaldatum, notities en het geüploade document zelf — soms bijzondere persoonsgegevens, zoals gegevens over het strafrechtelijk verleden bij een VOG.": "Title, issuer, certificate number, issue and expiry date, notes, and the uploaded document itself — sometimes special category personal data, such as data on criminal history in a Certificate of Conduct.",
+ "Toegang & isolatie": "Access & isolation",
+ "Toegangsscheiding per account, afgedwongen op databaseniveau": "Access separation per account, enforced at the database level",
+ "Uitgever": "Issuer",
+ "Uitsluitend in Europese datacenters, onder Europees recht. We gebruiken geen Amerikaanse cloudproviders, waardoor je data niet onder de Amerikaanse CLOUD Act valt. Zo voldoe je aantoonbaar aan de AVG.": "Exclusively in European data centers, under European law. We do not use American cloud providers, so your data does not fall under the American CLOUD Act. This way you can demonstrably comply with the GDPR.",
+ "Upgraden kan op elk moment; je betaalt alleen het verschil voor de rest van het jaar. Downgraden of opzeggen gaat in bij de volgende verlengingsdatum. Na opzegging kun je al je data exporteren; daarna verwijderen we alles definitief binnen 30 dagen.": "You can upgrade at any time; you only pay the difference for the rest of the year. Downgrading or cancelling takes effect on the next renewal date. After cancelling you can export all your data; after that we permanently delete everything within 30 days.",
+ "Upgraden kan op elk moment; je betaalt dan alleen het verschil voor de resterende looptijd.": "You can upgrade at any time; you then only pay the difference for the remaining term.",
+ "Upload een foto of PDF, wij vullen de rest in": "Upload a photo or PDF, we fill in the rest",
+ "Urgent": "Urgent",
+ "VCA & veiligheidscertificaten": "Safety & workplace certificates",
+ "VOG": "Certificate of Conduct",
+ "Vakdiploma's (Code 95, ADR, heftruck)": "Professional certificates (driver training, hazmat, forklift)",
+ "Valt mijn data onder de Amerikaanse CLOUD Act?": "Does my data fall under the American CLOUD Act?",
+ "Van scan tot reminder tot veilig delen": "From scan to reminder to secure sharing",
+ "Vandaag verlopen": "Expired today",
+ "Veelgestelde vragen": "Frequently asked questions",
+ "Veilig delen": "Secure sharing",
+ "Veilig delen via signed URL": "Secure sharing via signed URL",
+ "Velden invullen…": "Filling in fields…",
+ "Verenigde Staten": "United States",
+ "Verify a certificate": "Verify a certificate",
+ "Verloopt": "Expires",
+ "Verloopt bijna": "Expiring soon",
+ "Verloopt over 48 uur": "Expires in 48 hours",
+ "Verlopen": "Expired",
+ "Verordening (EU) 2016/679, zoals geïmplementeerd in Nederlands recht via de Uitvoeringswet AVG.": "Regulation (EU) 2016/679, as implemented in Dutch law via the GDPR Implementation Act.",
+ "Versie 1.0 · augustus 2026": "Version 1.0 · August 2026",
+ "Versie 1.0 · augustus 2026 · AVG/GDPR": "Version 1.0 · August 2026 · GDPR",
+ "Versie 1.0 · augustus 2026 · AVG/GDPR art. 28": "Version 1.0 · August 2026 · GDPR art. 28",
+ "Versleuteld in rust, onderweg en bij het delen": "Encrypted at rest, in transit, and when sharing",
+ "Versleutelde back-ups binnen de EU": "Encrypted backups within the EU",
+ "Versleuteling": "Encryption",
+ "Versleuteling van persoonsgegevens tijdens verzending (TLS) en in rust (AES-256)": "Encryption of personal data in transit (TLS) and at rest (AES-256)",
+ "Vertrouwelijkheid": "Confidentiality",
+ "Vervaldatum": "Expiry date",
+ "Verwerker": "Processor",
+ "Verwerkersovereenkomst": "Data Processing Agreement",
+ "Verwerkersovereenkomst op aanvraag": "Data Processing Agreement on request",
+ "Verwerkingsverantwoordelijke": "Controller",
+ "Voor Resend (doorgifte naar de Verenigde Staten) steunen we op Standaardcontractuele Clausules op grond van Hoofdstuk V AVG. De verwerker legt elke sub-verwerker gelijkwaardige gegevensbeschermingsverplichtingen op als in deze overeenkomst.": "For Resend (transfer to the United States) we rely on Standard Contractual Clauses under Chapter V GDPR. The processor imposes data protection obligations on every sub-processor equivalent to those in this agreement.",
+ "Voor altijd gratis, geen creditcard nodig": "Free forever, no credit card required",
+ "Voor de automatische tekstherkenning kies je zelf een verwerker: Klippa (Nederland) of Mistral AI (Frankrijk) — beide Europese bedrijven onder Europese jurisdictie. Wil je helemaal geen externe verwerking? Zet OCR dan simpelweg uit en vul velden handmatig in. Jouw data, jouw keuze.": "For automatic text recognition, you choose the processor yourself: Klippa (Netherlands) or Mistral AI (France) — both European companies under European jurisdiction. Don't want any external processing at all? Simply turn off OCR and fill in fields manually. Your data, your choice.",
+ "Voor de doorgifte aan Resend (Verenigde Staten) steunen we op Standaardcontractuele Clausules op grond van Hoofdstuk V AVG. Klippa, Mistral AI en Moneybird zijn allen binnen de EU gevestigd.": "For the transfer to Resend (United States) we rely on Standard Contractual Clauses under Chapter V GDPR. Klippa, Mistral AI, and Moneybird are all located within the EU.",
+ "Voor elk certificaat dat je zelf bijhoudt": "For every certificate you keep track of yourself",
+ "Voor iedereen die zijn eigen certificaten, diploma's en VOG's wil bijhouden": "For anyone who wants to keep track of their own certificates, diplomas, and Certificates of Conduct",
+ "Voor wie Certified wil proberen of maar een handvol certificaten beheert.": "For anyone who wants to try Certified or only manages a handful of certificates.",
+ "Voor wie al zijn diploma's, VOG's en certificaten voorgoed op één plek wil bewaken.": "For anyone who wants to keep all their diplomas, Certificates of Conduct, and certificates safe in one place for good.",
+ "Voor wie meer dan een handvol eigen certificaten en diploma's bijhoudt.": "For anyone who keeps track of more than a handful of their own certificates and diplomas.",
+ "Voor zover wettelijk toegestaan zijn wij niet aansprakelijk voor indirecte schade of gevolgschade. Onze totale aansprakelijkheid is beperkt tot het bedrag dat je in de twaalf maanden voorafgaand aan de schadeveroorzakende gebeurtenis aan ons hebt betaald.": "To the extent permitted by law, we are not liable for indirect or consequential damages. Our total liability is limited to the amount you paid us in the twelve months preceding the event that caused the damage.",
+ "Voorbeeld van de reminder-tijdlijn": "Example of the reminder timeline",
+ "Vraag een getekend exemplaar aan": "Request a signed copy",
+ "Vragen over deze verklaring of je gegevens? Mail ons via": "Questions about this policy or your data? Email us at",
+ "Vragen over deze voorwaarden?": "Questions about these terms?",
+ "Vragen over prijzen": "Questions about pricing",
+ "Vragen over security": "Questions about security",
+ "Waar je gegevens worden opgeslagen": "Where your data is stored",
+ "Waar wordt mijn data opgeslagen?": "Where is my data stored?",
+ "Wachtwoorden opgeslagen als hash, nooit in leesbare tekst": "Passwords stored as a hash, never in readable text",
+ "Wanneer krijg ik een reminder als een certificaat bijna verloopt?": "When do I get a reminder when a certificate is about to expire?",
+ "Wat gebeurt er als ik over mijn certificatenlimiet ga?": "What happens if I go over my certificate limit?",
+ "Wat gebeurt er met een document tijdens de OCR-scan?": "What happens to a document during the OCR scan?",
+ "We behouden ons het recht voor om toegang op te schorten zonder voorafgaande kennisgeving wanneer we een schending van dit artikel constateren of vermoeden.": "We reserve the right to suspend access without prior notice when we detect or suspect a violation of this article.",
+ "We kunnen deze verklaring van tijd tot tijd bijwerken. Bij wezenlijke wijzigingen informeren we je per e-mail, ten minste 14 dagen voordat de wijziging ingaat.": "We may update this policy from time to time. For material changes, we will notify you by email at least 14 days before the change takes effect.",
+ "We kunnen deze voorwaarden wijzigen door een bijgewerkte versie op deze pagina te plaatsen. Bij ingrijpende wijzigingen informeren we je per e-mail, ten minste 30 dagen voordat de wijziging ingaat. Voortgezet gebruik na die datum geldt als acceptatie.": "We may change these terms by posting an updated version on this page. For significant changes, we will notify you by email at least 30 days before the change takes effect. Continued use after that date constitutes acceptance.",
+ "We kunnen onze prijzen aanpassen met een schriftelijke kennisgeving van ten minste 30 dagen vooraf. Ga je niet akkoord met de nieuwe prijs, dan kun je opzeggen voordat de wijziging ingaat.": "We may adjust our prices with at least 30 days' written notice in advance. If you do not agree with the new price, you can cancel before the change takes effect.",
+ "We mogen geanonimiseerde, geaggregeerde gegevens die niet tot jou herleidbaar zijn gebruiken om de Dienst te verbeteren.": "We may use anonymized, aggregated data that cannot be traced back to you to improve the Service.",
+ "We streven naar een betrouwbaar beschikbare Dienst, maar garanderen geen ononderbroken of foutloze toegang. We kunnen de Dienst van tijd tot tijd aanpassen; ingrijpende wijzigingen kondigen we vooraf aan.": "We strive to keep the Service reliably available, but do not guarantee uninterrupted or error-free access. We may adjust the Service from time to time; we announce significant changes in advance.",
+ "We verkopen, verhuren of verhandelen je persoonsgegevens nooit aan derden. We delen gegevens uitsluitend met de volgende partijen, voor zover van toepassing op jouw gebruik:": "We never sell, rent, or trade your personal data to third parties. We only share data with the following parties, to the extent applicable to your use:",
+ "We versleutelen documenten in rust en tijdens verzending (TLS), scheiden accounts op databaseniveau en ondersteunen phishing-bestendige aanmelding via passkeys. Gedeelde documenten zijn alleen bereikbaar via cryptografisch ondertekende links die automatisch verlopen. Meer details vind je op onze security-pagina. Mochten we een datalek ontdekken met waarschijnlijk hoog risico voor jouw rechten, dan informeren we je zonder onredelijke vertraging conform artikel 34 AVG.": "We encrypt documents at rest and in transit (TLS), separate accounts at the database level, and support phishing-resistant sign-in via passkeys. Shared documents are only reachable via cryptographically signed links that expire automatically. More details can be found on our security page. Should we discover a data breach likely to pose a high risk to your rights, we will inform you without undue delay in accordance with article 34 GDPR.",
+ "We versturen reminders en accountmeldingen via Resend (Verenigde Staten). Open- en kliktracking staat uit; Resend verwerkt alleen het ontvangeradres en de berichtinhoud.": "We send reminders and account notifications via Resend (United States). Open and click tracking is disabled; Resend only processes the recipient address and message content.",
+ "Welke gegevens we verzamelen en waarom": "What data we collect and why",
+ "Werk je als zzp'er of eenmanszaak en beheer je via Certified ook certificaten van anderen (bijvoorbeeld van jezelf als ondernemer richting een opdrachtgever), dan kun je de onderstaande standaardovereenkomst gebruiken — zonder extra kosten.": "If you work as a freelancer or sole proprietor and also manage certificates of others through Certified (for example your own, as a business owner, toward a client), you can use the standard agreement below — at no extra cost.",
+ "Werkt met PDF, JPG en PNG — ook met scans en foto's": "Works with PDF, JPG, and PNG — including scans and photos",
+ "Wie kan er bij mijn certificaten?": "Who can access my certificates?",
+ "Wie wij zijn": "Who we are",
+ "Wij behouden alle intellectuele eigendomsrechten op de Dienst zelf, waaronder de broncode, het ontwerp en onze merken.": "We retain all intellectual property rights to the Service itself, including the source code, design, and our trademarks.",
+ "Wijzigingen": "Changes",
+ "Wissel tussen licht en donker thema": "Switch between light and dark theme",
+ "Zeker. Het Gratis-pakket is voor altijd gratis en laat je tot 5 certificaten beheren — zonder creditcard. Groei je eruit, dan upgrade je eenvoudig naar Starter (20 certificaten) of Onbeperkt.": "Sure. The Free plan is free forever and lets you manage up to 5 certificates — no credit card. If you outgrow it, you can easily upgrade to Starter (20 certificates) or Unlimited.",
+ "Zijn er kosten per OCR-scan?": "Are there costs per OCR scan?",
+ "Zo mis je nooit de deadline om het op tijd te verlengen.": "That way you never miss the deadline to renew it in time.",
+ "Zolang je deze Overeenkomst naleeft, verleent de Aanbieder je een beperkt, niet-overdraagbaar recht om de Dienst te gebruiken.": "As long as you comply with this Agreement, the Provider grants you a limited, non-transferable right to use the Service.",
+ "alle informatie als gedefinieerd in artikel 4 lid 1 AVG.": "all information as defined in article 4(1) GDPR.",
+ "de klant, die de doeleinden en middelen van de verwerking bepaalt.": "the customer, who determines the purposes and means of the processing.",
+ "de verwerker helpt bij verzoeken van betrokkenen en bij naleving van de artikelen 32–36 AVG.": "the processor assists with data subject requests and with compliance with articles 32–36 GDPR.",
+ "de verwerker schakelt geen nieuwe sub-verwerkers in zonder de verwerkingsverantwoordelijke hierover ten minste 14 dagen vooraf te informeren.": "the processor does not engage new sub-processors without informing the controller at least 14 days in advance.",
+ "een beveiligingsincident zoals gedefinieerd in artikel 4 lid 12 AVG.": "a security incident as defined in article 4(12) GDPR.",
+ "een derde partij die door de verwerker wordt ingeschakeld om specifieke verwerkingsactiviteiten uit te voeren.": "a third party engaged by the processor to carry out specific processing activities.",
+ "jaar": "year",
+ "niet als bijzaak": "not an afterthought",
+ "oude manier": "old way",
+ "passende technische en organisatorische maatregelen, zoals beschreven in artikel 8.": "appropriate technical and organizational measures, as described in article 8.",
+ "personen die persoonsgegevens verwerken zijn gebonden aan geheimhouding.": "individuals who process personal data are bound by confidentiality."
+}
diff --git a/lang/nl.json b/lang/nl.json
index 3742cf3..7ddc9b3 100644
--- a/lang/nl.json
+++ b/lang/nl.json
@@ -31,6 +31,7 @@
"Authenticating...": "Bezig met authenticeren...",
"Authentication code": "Authenticatiecode",
"Back": "Terug",
+ "Back to certificates": "Terug naar certificaten",
"By category": "Per categorie",
"Cancel": "Annuleren",
"Categories": "Categorieën",
@@ -38,7 +39,9 @@
"Category created.": "Categorie aangemaakt.",
"Category deleted. Its certificates are now uncategorized.": "Categorie verwijderd. De certificaten zijn nu ongecategoriseerd.",
"Certificate added.": "Certificaat toegevoegd.",
+ "Certificate authenticity check powered by :app.": "Certificaatcontrole aangeboden door :app.",
"Certificate deleted.": "Certificaat verwijderd.",
+ "Certificate details": "Certificaatgegevens",
"Certificate expires today: :title": "Certificaat verloopt vandaag: :title",
"Certificate expiring soon: :title": "Certificaat verloopt binnenkort: :title",
"Certificate number": "Certificaatnummer",
@@ -46,6 +49,7 @@
"Certificate updated.": "Certificaat bijgewerkt.",
"Certificates": "Certificaten",
"Certificates shared with you": "Certificaten met je gedeeld",
+ "Check certificate": "Certificaat controleren",
"Choose the language used throughout the application": "Kies de taal die in de hele applicatie wordt gebruikt",
"Click here to re-send the verification email.": "Klik hier om de verificatie-e-mail opnieuw te versturen.",
"Close": "Sluiten",
@@ -94,6 +98,7 @@
"Ensure your account is using a long, random password to stay secure": "Zorg dat je account een lang, willekeurig wachtwoord gebruikt om veilig te blijven",
"Enter the 6-digit code from your authenticator app.": "Voer de 6-cijferige code uit je authenticator-app in.",
"Enter the authentication code provided by your authenticator application.": "Voer de authenticatiecode in die door je authenticator-app wordt gegeven.",
+ "Enter the certificate number and the last name of the certificate holder to check whether it is genuine and currently valid.": "Voer het certificaatnummer en de achternaam van de certificaathouder in om te controleren of het certificaat echt en nog geldig is.",
"Enter the password you received from the sender to view the shared certificates.": "Voer het wachtwoord in dat je van de afzender hebt ontvangen om de gedeelde certificaten te bekijken.",
"Enter your API key": "Voer je API-sleutel in",
"Enter your details below to create your account": "Vul hieronder je gegevens in om je account aan te maken",
@@ -111,7 +116,9 @@
"Hello :name,": "Hallo :name,",
"Here is the status of your certificates.": "Dit is de status van je certificaten.",
"Hide recovery codes": "Herstelcodes verbergen",
+ "Holder last name": "Achternaam certificaathouder",
"If you did not expect this email, you can safely ignore it.": "Als je deze e-mail niet verwachtte, kun je hem veilig negeren.",
+ "Invalid": "Ongeldig",
"Issue date": "Uitgiftedatum",
"Issuing authority": "Uitgevende instantie",
"Language": "Taal",
@@ -141,6 +148,8 @@
"No certificates found": "Geen certificaten gevonden",
"No certificates in this category. Try another filter.": "Geen certificaten in deze categorie. Probeer een ander filter.",
"No certificates yet": "Nog geen certificaten",
+ "No currently valid certificate matches that certificate number and last name.": "Er is geen geldig certificaat dat overeenkomt met dit certificaatnummer en deze achternaam.",
+ "No document was uploaded for this certificate.": "Er is geen document geüpload voor dit certificaat.",
"No passkeys yet": "Nog geen passkeys",
"No shares yet": "Nog niets gedeeld",
"None (manual entry)": "Geen (handmatig invoeren)",
@@ -163,6 +172,7 @@
"Password": "Wachtwoord",
"Password updated.": "Wachtwoord bijgewerkt.",
"PDF or image, up to 10 MB.": "PDF of afbeelding, tot 10 MB.",
+ "Please complete the verification challenge.": "Voltooi de verificatiecontrole.",
"Please confirm access to your account by entering one of your emergency recovery codes.": "Bevestig toegang tot je account door een van je noodherstelcodes in te voeren.",
"Please enter your new password below": "Voer hieronder je nieuwe wachtwoord in",
"Please renew it in good time to stay compliant.": "Verleng het op tijd om compliant te blijven.",
@@ -225,7 +235,9 @@
"The recipient can view and download the certificates on this page:": "De ontvanger kan de certificaten bekijken en downloaden op deze pagina:",
"The selected certificates have no files to share.": "De geselecteerde certificaten hebben geen bestanden om te delen.",
"The ZIP archive is encrypted with the same password you used to open this page.": "Het ZIP-archief is versleuteld met hetzelfde wachtwoord waarmee je deze pagina hebt geopend.",
+ "The verification challenge failed. Please try again.": "De verificatiecontrole is mislukt. Probeer het opnieuw.",
"There are no files available in this share anymore.": "Er zijn geen bestanden meer beschikbaar op deze pagina.",
+ "This certificate number and last name match a currently valid certificate.": "Dit certificaatnummer en deze achternaam komen overeen met een geldig certificaat.",
"This is a secure area of the application. Please confirm your password before continuing.": "Dit is een beveiligd gedeelte van de applicatie. Bevestig je wachtwoord voordat je verdergaat.",
"This page is available until :date, after which it will stop working.": "Deze pagina is beschikbaar tot :date, daarna werkt deze niet meer.",
"This share is no longer available": "Deze gedeelde pagina is niet meer beschikbaar",
@@ -247,7 +259,9 @@
"Upload a document to preview it, then confirm the details — pre-filled automatically if scanning is enabled.": "Upload een document om het te bekijken en bevestig daarna de gegevens — automatisch ingevuld als scannen is ingeschakeld.",
"Upload your first certificate to start tracking issue dates, expiry, and reminders.": "Upload je eerste certificaat om uitgiftedatums, vervaldatums en herinneringen bij te houden.",
"Uploading…": "Uploaden…",
+ "Used by the public verification page.": "Wordt gebruikt op de openbare verificatiepagina.",
"Valid": "Geldig",
+ "Verify a certificate": "Certificaat verifiëren",
"Verify authentication code": "Authenticatiecode verifiëren",
"View all": "Alles bekijken",
"View recovery codes": "Herstelcodes bekijken",
diff --git a/phpunit.xml b/phpunit.xml
index e7f0a48..1a4a5c0 100644
--- a/phpunit.xml
+++ b/phpunit.xml
@@ -19,6 +19,7 @@
+
diff --git a/resources/views/marketing/dpa.blade.php b/resources/views/marketing/dpa.blade.php
new file mode 100644
index 0000000..67df402
--- /dev/null
+++ b/resources/views/marketing/dpa.blade.php
@@ -0,0 +1,212 @@
+@extends('marketing.layout')
+
+@section('title', __('Verwerkersovereenkomst').' — Certified')
+@section('description', __('De standaard verwerkersovereenkomst (DPA) van Certified, beschikbaar voor zzp\'ers en eenmanszaken die er één nodig hebben.'))
+
+@section('content')
+
+@include('marketing.partials.legal-header', ['title' => __('Verwerkersovereenkomst'), 'updated' => __('Versie 1.0 · augustus 2026 · AVG/GDPR art. 28')])
+
+
+
+
{{ __('Heb je deze wel nodig?') }}
+
+ {{ __("Certified is gebouwd voor persoonlijk gebruik: jij beheert je eigen VOG, diploma's en certificaten. In dat geval ben je zelf geen verwerkingsverantwoordelijke in de zin van de AVG en heb je deze overeenkomst niet nodig.") }}
+
+
+ {{ __('Werk je als zzp\'er of eenmanszaak en beheer je via Certified ook certificaten van anderen (bijvoorbeeld van jezelf als ondernemer richting een opdrachtgever), dan kun je de onderstaande standaardovereenkomst gebruiken — zonder extra kosten.') }}
+
+ {{ __('De zzp\'er of eenmanszaak die Certified gebruikt en zelf certificaatgegevens van anderen verwerkt.') }}
+
+
+
+
+
+
+
+
+
{{ __('Artikel 1 — Definities') }}
+
+
{{ __('"AVG"/"GDPR"') }} — {{ __('Verordening (EU) 2016/679, zoals geïmplementeerd in Nederlands recht via de Uitvoeringswet AVG.') }}
+
{{ __('"Persoonsgegevens"') }} — {{ __('alle informatie als gedefinieerd in artikel 4 lid 1 AVG.') }}
+
{{ __('"Verwerkingsverantwoordelijke"') }} — {{ __('de klant, die de doeleinden en middelen van de verwerking bepaalt.') }}
+
{{ __('"Verwerker"') }} — {{ __('Bckstage, die persoonsgegevens verwerkt namens de verwerkingsverantwoordelijke.') }}
+
{{ __('"Sub-verwerker"') }} — {{ __('een derde partij die door de verwerker wordt ingeschakeld om specifieke verwerkingsactiviteiten uit te voeren.') }}
+
{{ __('"Inbreuk in verband met persoonsgegevens"') }} — {{ __('een beveiligingsincident zoals gedefinieerd in artikel 4 lid 12 AVG.') }}
+
+
+
+
+
{{ __('Artikel 2 — Onderwerp, aard en doel') }}
+
+
2.1 {{ __('De verwerker verwerkt persoonsgegevens uitsluitend om Certified te leveren aan de verwerkingsverantwoordelijke: opslag, OCR-herkenning, het bewaken van vervaldatums en het veilig delen van certificaten.') }}
+
2.2 {{ __('De verwerker verwerkt persoonsgegevens niet voor eigen doeleinden, reclame, profilering of enig ander doel dan het leveren en verbeteren van Certified.') }}
+
2.3 {{ __('De verwerker handelt uitsluitend op gedocumenteerde instructies van de verwerkingsverantwoordelijke, tenzij Unierecht of nationale wetgeving anders vereist.') }}
+
+
+
+
+
{{ __('Artikel 3 — Looptijd') }}
+
+ {{ __('Deze overeenkomst blijft van kracht gedurende de looptijd van het abonnement en eindigt automatisch bij beëindiging daarvan, onder voorbehoud van artikel 11 (Verwijdering en teruggave).') }}
+
+
+
+
+
{{ __('Artikel 4 — Persoonsgegevens en betrokkenen') }}
+
+ {{ __('Afhankelijk van hoe de verwerkingsverantwoordelijke Certified gebruikt, kunnen de volgende gegevens worden verwerkt: naam, contactgegevens, certificaatgegevens (titel, uitgever, geldigheidsdata) en het geüploade document zelf.') }}
+
+
+ {{ __('4.1 De verwerker erkent dat Certified mede bedoeld is voor het opslaan van documenten die bijzondere persoonsgegevens kunnen bevatten in de zin van artikel 9 en 10 AVG, zoals gegevens over het strafrechtelijk verleden bij een Verklaring Omtrent het Gedrag (VOG). De verwerkingsverantwoordelijke is zelf verantwoordelijk voor het hebben van een geldige rechtsgrond wanneer hij dergelijke gegevens van anderen dan zichzelf verwerkt.') }}
+
+
+
+
+
{{ __('Artikel 5 — Verplichtingen van de verwerker') }}
+
+
{{ __('Vertrouwelijkheid') }} — {{ __('personen die persoonsgegevens verwerken zijn gebonden aan geheimhouding.') }}
+
{{ __('Beveiliging') }} — {{ __('passende technische en organisatorische maatregelen, zoals beschreven in artikel 8.') }}
+
{{ __('Sub-verwerkers') }} — {{ __('de verwerker schakelt geen nieuwe sub-verwerkers in zonder de verwerkingsverantwoordelijke hierover ten minste 14 dagen vooraf te informeren.') }}
+
{{ __('Bijstand') }} — {{ __('de verwerker helpt bij verzoeken van betrokkenen en bij naleving van de artikelen 32–36 AVG.') }}
+
+
+
+
+
{{ __('Artikel 6 — Sub-verwerkers') }}
+
+ {{ __('Door deze overeenkomst aan te gaan geeft de verwerkingsverantwoordelijke algemene toestemming aan de verwerker om de volgende sub-verwerkers in te schakelen:') }}
+
+
+
+
+
+
{{ __('Sub-verwerker') }}
+
{{ __('Locatie') }}
+
{{ __('Doel') }}
+
+
+
+
+
{{ __('Eigen infrastructuur') }}
+
{{ __('EU (Nederland)') }}
+
{{ __('Applicatiehosting, bestandsopslag en databases') }}
+
+
+
Resend
+
{{ __('Verenigde Staten') }}
+
{{ __('Bezorging van reminders en accountmeldingen') }}
+
+
+
Klippa
+
{{ __('Nederland (EU)') }}
+
{{ __('OCR-herkenning — alleen indien geactiveerd') }}
+
+
+
Mistral AI
+
{{ __('Frankrijk (EU)') }}
+
{{ __('OCR-herkenning — alleen indien geactiveerd') }}
+
+
+
Moneybird
+
{{ __('Nederland (EU)') }}
+
{{ __('Facturering van betaalde abonnementen') }}
+
+
+
+
+
+ {{ __('Voor Resend (doorgifte naar de Verenigde Staten) steunen we op Standaardcontractuele Clausules op grond van Hoofdstuk V AVG. De verwerker legt elke sub-verwerker gelijkwaardige gegevensbeschermingsverplichtingen op als in deze overeenkomst.') }}
+
+
+
+
+
{{ __('Artikel 7 — Internationale doorgiften') }}
+
+ {{ __('De verwerker geeft geen persoonsgegevens door aan derde landen buiten de EER, behalve aan Resend (Verenigde Staten) voor het bezorgen van reminders, op basis van passende waarborgen conform Hoofdstuk V AVG. Alle overige sub-verwerkers zijn gevestigd binnen de EU.') }}
+
+
+
+
+
{{ __('Artikel 8 — Beveiligingsmaatregelen') }}
+
+ @foreach ([
+ __('Versleuteling van persoonsgegevens tijdens verzending (TLS) en in rust (AES-256)'),
+ __('Wachtwoorden opgeslagen als hash, nooit in leesbare tekst'),
+ __('Toegangsscheiding per account, afgedwongen op databaseniveau'),
+ __('Ondersteuning voor phishing-bestendige authenticatie via passkeys'),
+ __('Gedeelde documenten alleen bereikbaar via cryptografisch ondertekende, automatisch verlopende links'),
+ __('Regelmatige geautomatiseerde back-ups'),
+ ] as $measure)
+
+
+ {{ $measure }}
+
+ @endforeach
+
+
+ {{ __('Een volledig overzicht van onze beveiligingsmaatregelen vind je op onze security-pagina.') }}
+
+
+
+
+
{{ __('Artikel 9 — Meldplicht datalekken') }}
+
+ {{ __('De verwerker stelt de verwerkingsverantwoordelijke zonder onredelijke vertraging, en in elk geval binnen 72 uur nadat hij kennis heeft gekregen van een inbreuk in verband met persoonsgegevens, hiervan op de hoogte — met een beschrijving van de aard, de waarschijnlijke gevolgen en de genomen maatregelen.') }}
+
+
+
+
+
{{ __('Artikel 10 — Rechten van betrokkenen') }}
+
+ {{ __('De verwerker helpt de verwerkingsverantwoordelijke bij het beantwoorden van verzoeken van betrokkenen (inzage, rectificatie, verwijdering, beperking, overdraagbaarheid, bezwaar) en stuurt verzoeken die rechtstreeks bij de verwerker binnenkomen binnen 5 werkdagen door.') }}
+
+
+
+
+
{{ __('Artikel 11 — Verwijdering en teruggave') }}
+
+ {{ __('Bij beëindiging van het abonnement verwijdert de verwerker, naar keuze van de verwerkingsverantwoordelijke, alle persoonsgegevens of geeft deze terug in een machineleesbaar formaat. Zonder tijdige instructie verwijdert de verwerker alle gegevens binnen 30 dagen na beëindiging, inclusief back-ups binnen maximaal 90 dagen vanwege back-uprotatieschema\'s.') }}
+
+
+
+
+
{{ __('Artikel 12 — Auditrechten') }}
+
+ {{ __('De verwerker verstrekt de informatie die redelijkerwijs nodig is om naleving van artikel 28 AVG aan te tonen. Auditverzoeken worden schriftelijk ingediend met ten minste 30 dagen vooraankondiging en mogen de beveiliging van gegevens van andere klanten niet in gevaar brengen.') }}
+
+
+
+
+
{{ __('Artikel 13 — Aansprakelijkheid en toepasselijk recht') }}
+
+ {{ __('Aansprakelijkheid wordt geregeld conform artikel 82 AVG en de aansprakelijkheidsbepaling in de Gebruiksvoorwaarden. Op deze overeenkomst is Nederlands recht van toepassing; geschillen worden voorgelegd aan de bevoegde rechtbank te Arnhem.') }}
+
+
+
+
+
{{ __('Ondertekening') }}
+
+ {{ __('Deze overeenkomst wordt geacht te zijn aanvaard bij eerste gebruik van Certified in de context van je eigen bedrijfsvoering. Voor een getekende kopie voor je eigen archief mail je ons via') }} privacy@bckstage.cloud.
+
+
+
+
+
+@endsection
diff --git a/resources/views/marketing/home.blade.php b/resources/views/marketing/home.blade.php
index 0f20b8c..e546bdd 100644
--- a/resources/views/marketing/home.blade.php
+++ b/resources/views/marketing/home.blade.php
@@ -1,6 +1,6 @@
@extends('marketing.layout')
-@section('title', 'Certified — Nooit meer verlopen certificaten. Volledig AVG-proof.')
+@section('title', 'Certified — '.__('Al je certificaten op één plek. Nooit meer verlopen.'))
@section('content')
@@ -17,16 +17,16 @@
- Gebouwd voor organisaties die met VOG's en persoonsgegevens werken
+ {{ __("Voor iedereen die zijn eigen certificaten, diploma's en VOG's wil bijhouden") }}
- Nooit meer verlopen certificaten.
- Volledig AVG-proof.
+ {{ __('Al je certificaten op één plek.') }}
+ {{ __('Nooit meer per ongeluk verlopen.') }}
- Certified scant je certificaten automatisch in, bewaakt elke vervaldatum en deelt documenten alleen versleuteld. Zo blijft je organisatie aantoonbaar compliant — zonder Excel-lijstjes en losse e-mailbijlagen.
+ {{ __("Certified scant je VOG, diploma's en certificaten automatisch in, bewaakt elke vervaldatum en deelt ze alleen versleuteld — zonder Excel-lijstjes, losse mapjes of kwetsbare e-mailbijlagen.") }}
- Van scan tot reminder tot veilig delen
+ {{ __('Van scan tot reminder tot veilig delen') }}
- Drie pijlers die samen je volledige certificaatbeheer afdekken — zonder handwerk.
+ {{ __('Drie pijlers die samen je hele certificatenbeheer afdekken — zonder handwerk.') }}
- Upload een PDF, wij vullen de rest in
+ {{ __('Upload een foto of PDF, wij vullen de rest in') }}
- Sleep een certificaat in Certified en de OCR-engine herkent automatisch de titel, uitgever en vervaldatum. Geen overtypwerk, geen tikfouten in vervaldatums — en jij kiest zelf welke Europese OCR-provider je data verwerkt.
+ {{ __('Sleep je certificaat in Certified en de OCR-engine herkent automatisch de titel, uitgever en vervaldatum. Geen overtypwerk, geen tikfouten in vervaldatums — en jij kiest zelf welke Europese OCR-provider je document verwerkt.') }}
@foreach ([
- 'Herkent titel, uitgever en vervaldatum in seconden',
- 'Keuze uit Europese providers: Klippa of Mistral AI',
- 'Werkt met PDF, JPG en PNG — ook met scans en foto\'s',
+ __('Herkent titel, uitgever en vervaldatum in seconden'),
+ __('Keuze uit Europese providers: Klippa of Mistral AI'),
+ __("Werkt met PDF, JPG en PNG — ook met scans en foto's"),
] as $point)
- Certificaat herkend en ingevuld — klaar om op te slaan
+ {{ __('Certificaat herkend en ingevuld — klaar om op te slaan') }}
@@ -273,21 +273,21 @@
- Slimme reminders
+ {{ __('Slimme reminders') }}
- Op tijd gewaarschuwd, elke keer weer
+ {{ __('Op tijd gewaarschuwd, elke keer weer') }}
- Certified controleert dagelijks alle vervaldatums en stuurt automatisch reminders — ruim op tijd om een certificaat te verlengen. Verloopt er toch iets? Dan krijg je direct een urgente melding, zodat het nooit onopgemerkt blijft.
+ {{ __('Certified controleert dagelijks alle vervaldatums en stuurt automatisch reminders — ruim op tijd om een certificaat te verlengen. Verloopt er toch iets? Dan krijg je direct een urgente melding, zodat het nooit onopgemerkt blijft.') }}
- Jij bepaalt zelf hoeveel maanden van tevoren je gewaarschuwd wilt worden.
+ {{ __('Jij bepaalt zelf hoeveel maanden van tevoren je gewaarschuwd wilt worden.') }}
{{-- Timeline visual --}}
-
+
@@ -298,11 +298,11 @@
-
2 maanden van tevoren
- Reminder
+
{{ __('2 maanden van tevoren') }}
+ {{ __('Reminder') }}
-
“BHV Diploma — A. Bakker” verloopt over 2 maanden
-
Rustig de tijd om een herhalingscursus in te plannen.
+
{{ __('Je BHV-diploma verloopt over 2 maanden') }}
+
{{ __('Rustig de tijd om een herhalingscursus in te plannen.') }}
@@ -313,11 +313,11 @@
-
1 maand van tevoren
- Herinnering
+
{{ __('1 maand van tevoren') }}
+ {{ __('Herinnering') }}
-
Nog geen nieuw certificaat geüpload
-
Certified herinnert je opnieuw zolang het niet is verlengd.
+
{{ __('Nog geen nieuw certificaat geüpload') }}
+
{{ __('Certified herinnert je opnieuw zolang het niet is verlengd.') }}
@@ -328,11 +328,11 @@
-
Vandaag verlopen
- Urgent
+
{{ __('Vandaag verlopen') }}
+ {{ __('Urgent') }}
-
Direct een urgente melding in je inbox
-
Zo weet je meteen welke medewerker niet meer inzetbaar is.
+
{{ __('Direct een urgente melding in je inbox') }}
+
{{ __('Zo mis je nooit de deadline om het op tijd te verlengen.') }}
@@ -344,13 +344,13 @@
- Secure sharing
+ {{ __('Veilig delen') }}
- Stop met certificaten mailen als losse bijlage
+ {{ __('Stop met certificaten mailen als losse bijlage') }}
- Een VOG met BSN als onbeveiligde bijlage rondsturen is een datalek dat wacht om te gebeuren. Certified deelt documenten alleen versleuteld en tijdelijk.
+ {{ __('Je VOG of diploma als onbeveiligde bijlage naar een nieuwe werkgever of instantie mailen is vragen om problemen. Certified deelt je documenten alleen versleuteld en tijdelijk.') }}
@foreach ([
- 'Bijlage blijft voor altijd in inboxen en op mailservers staan',
- 'Geen controle: doorsturen, kopiëren en lekken kan ongemerkt',
- 'BSN onversleuteld verstuurd — een meldplichtig datalek onder de AVG',
+ __('Bijlage blijft voor altijd in inboxen en op mailservers staan'),
+ __('Geen controle: doorsturen, kopiëren en lekken kan ongemerkt'),
+ __('Onbeveiligd verstuurd — een onnodig risico op misbruik van je gegevens'),
] as $risk)
@foreach ([
- 'AES-256 versleutelde ZIP met een apart verstuurd wachtwoord',
- 'Tijdelijke ondertekende URL die na 48 uur automatisch verloopt',
- 'Volledig AVG-proof: geen kopieën die blijven rondslingeren',
+ __('AES-256 versleutelde ZIP met een apart verstuurd wachtwoord'),
+ __('Tijdelijke ondertekende URL die na 48 uur automatisch verloopt'),
+ __('Privacyvriendelijk: geen kopieën die ergens blijven rondslingeren'),
] as $benefit)
@@ -436,12 +436,12 @@
-
Europese privacy & security
+
{{ __('Europese privacy & security') }}
- Gevoelige gegevens verdienen Europese waarborgen
+ {{ __('Gevoelige gegevens verdienen Europese waarborgen') }}
- VOG's en BSN-nummers zijn bijzondere persoonsgegevens. Daarom is Certified vanaf de eerste regel code gebouwd op privacy-by-design — en blijft je data binnen de EU.
+ {{ __("Documenten zoals een VOG bevatten bijzondere persoonsgegevens. Daarom is Certified vanaf de eerste regel code gebouwd op privacy-by-design — en blijft je data binnen de EU.") }}
@@ -449,18 +449,18 @@
@foreach ([
[
'icon' => 'M12 21a9.004 9.004 0 0 0 8.716-6.747M12 21a9.004 9.004 0 0 1-8.716-6.747M12 21c2.485 0 4.5-4.03 4.5-9S14.485 3 12 3m0 18c-2.485 0-4.5-4.03-4.5-9S9.515 3 12 3m0 0a8.997 8.997 0 0 1 7.843 4.582M12 3a8.997 8.997 0 0 0-7.843 4.582m15.686 0A11.953 11.953 0 0 1 12 10.5c-2.998 0-5.74-1.1-7.843-2.918m15.686 0A8.959 8.959 0 0 1 21 12c0 .778-.099 1.533-.284 2.253m0 0A17.919 17.919 0 0 1 12 16.5c-3.162 0-6.133-.815-8.716-2.247m0 0A9.015 9.015 0 0 1 3 12c0-1.605.42-3.113 1.157-4.418',
- 'title' => '100% Europese hosting',
- 'body' => 'Alle data staat in Europese datacenters, onder Europees recht. Geen Amerikaanse cloud, geen CLOUD Act, volledig AVG/GDPR-compliant.',
+ 'title' => __('100% Europese hosting'),
+ 'body' => __('Al je data staat in Europese datacenters, onder Europees recht. Geen Amerikaanse cloud, geen CLOUD Act, volledig AVG/GDPR-compliant.'),
],
[
'icon' => 'M16.5 10.5V6.75a4.5 4.5 0 1 0-9 0v3.75m-.75 11.25h10.5a2.25 2.25 0 0 0 2.25-2.25v-6.75a2.25 2.25 0 0 0-2.25-2.25H6.75a2.25 2.25 0 0 0-2.25 2.25v6.75a2.25 2.25 0 0 0 2.25 2.25Z',
- 'title' => 'AES-256 versleuteld delen',
- 'body' => 'Gedeelde certificaten worden verpakt in een AES-256 versleutelde ZIP. Links zijn ondertekend en verlopen automatisch na 48 uur.',
+ 'title' => __('AES-256 versleuteld delen'),
+ 'body' => __('Certificaten die je deelt worden verpakt in een AES-256 versleutelde ZIP. Links zijn ondertekend en verlopen automatisch na 48 uur.'),
],
[
'icon' => 'M7.5 3.75H6A2.25 2.25 0 0 0 3.75 6v1.5M16.5 3.75H18A2.25 2.25 0 0 1 20.25 6v1.5m0 9V18A2.25 2.25 0 0 1 18 20.25h-1.5m-9 0H6A2.25 2.25 0 0 1 3.75 18v-1.5M15 12a3 3 0 1 1-6 0 3 3 0 0 1 6 0Z',
- 'title' => 'Europese OCR-providers',
- 'body' => 'Kies zelf wie je documenten leest: Klippa (Nederland) of Mistral AI (Frankrijk). Je documenten verlaten Europa nooit — jij houdt de regie.',
+ 'title' => __('Europese OCR-providers'),
+ 'body' => __('Kies zelf wie je documenten leest: Klippa (Nederland) of Mistral AI (Frankrijk). Je documenten verlaten Europa nooit — jij houdt de regie.'),
],
] as $card)
@@ -478,7 +478,7 @@
href="{{ route('marketing.security') }}"
class="group inline-flex items-center gap-2 text-base font-semibold text-emerald-400 transition-colors hover:text-emerald-300"
>
- Lees alles over security & privacy
+ {{ __('Lees alles over security & privacy') }}
→
- Eerlijke prijzen, geen verrassingen
+ {{ __('Eerlijke prijzen, geen verrassingen') }}
- Start gratis en groei mee wanneer je meer certificaten beheert. Elk pakket bevat OCR, reminders en veilig delen.
+ {{ __('Start gratis en groei mee wanneer je meer certificaten beheert. Elk pakket bevat OCR, reminders en veilig delen.') }}
@@ -504,12 +504,12 @@
{{-- ============ FAQ ============ --}}
@include('marketing.partials.faq', ['faqs' => [
- ['q' => 'Is Certified geschikt voor documenten met BSN-nummers, zoals een VOG?', 'a' => 'Ja, daar is Certified juist voor gebouwd. Documenten staan versleuteld op Europese servers, worden nooit als open bijlage gedeeld en zijn alleen toegankelijk voor geautoriseerde gebruikers. Delen gebeurt via een tijdelijke ondertekende link of een AES-256 versleutelde ZIP.'],
- ['q' => 'Hoe werkt de automatische OCR-scan?', 'a' => 'Je uploadt een PDF of foto van het certificaat. Onze OCR-engine herkent automatisch de titel, uitgever en vervaldatum en vult die voor je in. Jij controleert en slaat op — dat is alles. Je kiest zelf welke Europese provider (Klippa of Mistral AI) de verwerking doet.'],
- ['q' => 'Wanneer krijg ik een reminder als een certificaat bijna verloopt?', 'a' => 'Standaard ontvang je twee maanden van tevoren een e-mail, en daarna opnieuw zolang het certificaat niet verlengd is. Verloopt een certificaat vandaag, dan krijg je direct een urgente melding. Het aantal maanden stel je zelf in per account.'],
- ['q' => 'Waar wordt mijn data opgeslagen?', 'a' => 'Uitsluitend in Europese datacenters, onder Europees recht. We gebruiken geen Amerikaanse cloudproviders, waardoor je data niet onder de Amerikaanse CLOUD Act valt. Zo voldoe je aantoonbaar aan de AVG.'],
- ['q' => 'Kan ik Certified eerst vrijblijvend proberen?', 'a' => 'Zeker. Het Gratis-pakket is voor altijd gratis en laat je tot 5 certificaten beheren — zonder creditcard. Groei je eruit, dan upgrade je eenvoudig naar Starter (20 certificaten) of Onbeperkt.'],
- ['q' => 'Sluiten jullie een verwerkersovereenkomst af?', 'a' => 'Ja. Voor alle betaalde abonnementen bieden we een standaard verwerkersovereenkomst aan, inclusief afspraken over dataretentie en de door jou gekozen OCR-provider.'],
+ ['q' => __('Is Certified geschikt voor gevoelige documenten, zoals een VOG?'), 'a' => __('Ja, daar is Certified juist voor gebouwd. Je documenten staan versleuteld op Europese servers, worden nooit als open bijlage gedeeld en zijn alleen toegankelijk met jouw account. Delen met anderen gebeurt via een tijdelijke ondertekende link of een AES-256 versleutelde ZIP.')],
+ ['q' => __('Hoe werkt de automatische OCR-scan?'), 'a' => __('Je uploadt een PDF of foto van je certificaat. Onze OCR-engine herkent automatisch de titel, uitgever en vervaldatum en vult die voor je in. Jij controleert en slaat op — dat is alles. Je kiest zelf welke Europese provider (Klippa of Mistral AI) de verwerking doet.')],
+ ['q' => __('Wanneer krijg ik een reminder als een certificaat bijna verloopt?'), 'a' => __('Standaard ontvang je twee maanden van tevoren een e-mail, en daarna opnieuw zolang je het certificaat niet hebt verlengd. Verloopt een certificaat vandaag, dan krijg je direct een urgente melding. Het aantal maanden stel je zelf in bij je instellingen.')],
+ ['q' => __('Waar wordt mijn data opgeslagen?'), 'a' => __('Uitsluitend in Europese datacenters, onder Europees recht. We gebruiken geen Amerikaanse cloudproviders, waardoor je data niet onder de Amerikaanse CLOUD Act valt. Zo voldoe je aantoonbaar aan de AVG.')],
+ ['q' => __('Kan ik Certified eerst vrijblijvend proberen?'), 'a' => __('Zeker. Het Gratis-pakket is voor altijd gratis en laat je tot 5 certificaten beheren — zonder creditcard. Groei je eruit, dan upgrade je eenvoudig naar Starter (20 certificaten) of Onbeperkt.')],
+ ['q' => __('Heb ik een verwerkersovereenkomst nodig?'), 'a' => __('Gebruik je Certified puur voor je eigen certificaten? Dan heb je geen verwerkersovereenkomst nodig — je bent geen verwerkingsverantwoordelijke in de zin van de AVG. Werk je als zzp\'er of eenmanszaak en wil je er toch één voor je eigen administratie, dan kun je die downloaden op onze DPA-pagina.')],
]])
{{-- ============ BOTTOM CTA ============ --}}
diff --git a/resources/views/marketing/layout.blade.php b/resources/views/marketing/layout.blade.php
index cd19083..f6821cc 100644
--- a/resources/views/marketing/layout.blade.php
+++ b/resources/views/marketing/layout.blade.php
@@ -1,11 +1,11 @@
-
+
- @yield('title', 'Certified — Nooit meer verlopen certificaten')
-
+ @yield('title', 'Certified — '.__('Al je certificaten op één plek. Nooit meer verlopen.'))
+
diff --git a/resources/views/marketing/partials/cta.blade.php b/resources/views/marketing/partials/cta.blade.php
index aed420b..4684025 100644
--- a/resources/views/marketing/partials/cta.blade.php
+++ b/resources/views/marketing/partials/cta.blade.php
@@ -1,26 +1,26 @@
-
+
- Regel je compliance vandaag nog. Niet pas na de audit.
+ {{ __('Regel het vandaag nog. Niet pas als het te laat is.') }}
- Binnen tien minuten staan je eerste certificaten in Certified — inclusief automatische reminders. Start gratis met maximaal 5 certificaten.
+ {{ __('Binnen tien minuten staan je eerste certificaten in Certified — inclusief automatische reminders. Start gratis met maximaal 5 certificaten.') }}
- {{ $faqSubtitle ?? 'Staat je vraag er niet tussen? Mail ons via support@certified.eu.' }}
+ {{ $faqSubtitle ?? __('Staat je vraag er niet tussen? Mail ons via support@certified.eu.') }}
- De veilige certificaatmanager voor organisaties die met gevoelige persoonsgegevens werken. Gebouwd en gehost in Europa.
+ {{ __("De veilige plek waar je zelf al je certificaten, diploma's en VOG's beheert. Gebouwd en gehost in Europa.") }}
- Alle prijzen zijn per jaar en exclusief btw. Start gratis — upgraden kan altijd, opzeggen ook.
+ {{ __('Alle prijzen zijn per jaar en exclusief btw. Start gratis — upgraden kan altijd, opzeggen ook.') }}
diff --git a/resources/views/marketing/pricing.blade.php b/resources/views/marketing/pricing.blade.php
index 47eaf20..2295b53 100644
--- a/resources/views/marketing/pricing.blade.php
+++ b/resources/views/marketing/pricing.blade.php
@@ -1,7 +1,7 @@
@extends('marketing.layout')
@section('title', 'Pricing — Certified')
-@section('description', 'Eerlijke prijzen voor veilig certificaatbeheer. Start gratis met maximaal 5 certificaten — inclusief OCR, slimme reminders en AVG-proof delen.')
+@section('description', __('Eerlijke prijzen voor je eigen certificaatbeheer. Start gratis met maximaal 5 certificaten — inclusief OCR, slimme reminders en AVG-proof delen.'))
@section('content')
@@ -14,10 +14,10 @@
Pricing
- Compliance hoeft niet duur te zijn
+ {{ __('Overzicht hoeft niet duur te zijn') }}
- Eén verlopen certificaat kost al snel meer dan een jaar Certified. Start gratis en betaal pas als je meer certificaten beheert.
+ {{ __('Eén verlopen certificaat kost je al snel meer dan een jaar Certified. Start gratis en betaal pas als je meer certificaten beheert.') }}
@foreach ([
- ['title' => 'Europese hosting', 'body' => 'Alle data in EU-datacenters, volledig AVG-proof.'],
- ['title' => 'Automatische OCR', 'body' => 'Titel, uitgever en vervaldatum automatisch herkend.'],
- ['title' => 'Slimme reminders', 'body' => 'E-mail op het moment dat jij instelt, plus urgente meldingen.'],
- ['title' => 'Veilig delen', 'body' => 'Ondertekende links (48u) en AES-256 versleutelde ZIP\'s.'],
+ ['title' => __('Europese hosting'), 'body' => __('Al je data in EU-datacenters, volledig AVG-proof.')],
+ ['title' => __('Automatische OCR'), 'body' => __('Titel, uitgever en vervaldatum automatisch herkend.')],
+ ['title' => __('Slimme reminders'), 'body' => __('E-mail op het moment dat jij instelt, plus urgente meldingen.')],
+ ['title' => __('Veilig delen'), 'body' => __("Ondertekende links (48u) en AES-256 versleutelde ZIP's.")],
] as $item)
@@ -52,15 +52,15 @@
{{-- ============ FAQ ============ --}}
@include('marketing.partials.faq', [
- 'faqTitle' => 'Vragen over prijzen',
- 'faqSubtitle' => 'Alles over facturering, opzeggen en overstappen.',
+ 'faqTitle' => __('Vragen over prijzen'),
+ 'faqSubtitle' => __('Alles over facturering, opzeggen en overstappen.'),
'faqs' => [
- ['q' => 'Is het Gratis-pakket echt gratis?', 'a' => 'Ja, voor altijd. Je beheert er tot 5 certificaten mee, inclusief OCR-scan, reminders en veilig delen. Geen creditcard, geen verborgen kosten — pas als je meer dan 5 certificaten wilt bewaken, stap je over op een betaald pakket.'],
- ['q' => 'Hoe werkt de facturering?', 'a' => 'Betaalde pakketten worden één keer per jaar gefactureerd: €12,50 per jaar voor Starter, €45 per jaar voor Onbeperkt, beide exclusief btw. Je ontvangt een factuur die je direct in je administratie kunt verwerken.'],
- ['q' => 'Wat gebeurt er als ik over mijn certificatenlimiet ga?', 'a' => 'Niets ergs — je data blijft gewoon staan. We sturen een melding en je kunt eenvoudig upgraden naar het volgende pakket. We verwijderen nooit certificaten omdat je over een limiet heen bent.'],
- ['q' => 'Kan ik tussentijds upgraden, downgraden of opzeggen?', 'a' => 'Upgraden kan op elk moment; je betaalt alleen het verschil voor de rest van het jaar. Downgraden of opzeggen gaat in bij de volgende verlengingsdatum. Na opzegging kun je al je data exporteren; daarna verwijderen we alles definitief binnen 30 dagen.'],
- ['q' => 'Zit de verwerkersovereenkomst bij de prijs in?', 'a' => 'Ja, bij de betaalde pakketten leveren we een standaard verwerkersovereenkomst zonder extra kosten.'],
- ['q' => 'Zijn er kosten per OCR-scan?', 'a' => 'Nee. OCR-scans zitten bij elk pakket inbegrepen — ook bij Gratis. Je betaalt nooit per scan.'],
+ ['q' => __('Is het Gratis-pakket echt gratis?'), 'a' => __('Ja, voor altijd. Je beheert er tot 5 certificaten mee, inclusief OCR-scan, reminders en veilig delen. Geen creditcard, geen verborgen kosten — pas als je meer dan 5 certificaten wilt bewaken, stap je over op een betaald pakket.')],
+ ['q' => __('Hoe werkt de facturering?'), 'a' => __('Betaalde pakketten worden één keer per jaar gefactureerd: €12,50 per jaar voor Starter, €45 per jaar voor Onbeperkt, beide exclusief btw. Je ontvangt een factuur die je direct in je administratie kunt verwerken.')],
+ ['q' => __('Wat gebeurt er als ik over mijn certificatenlimiet ga?'), 'a' => __('Niets ergs — je data blijft gewoon staan. We sturen een melding en je kunt eenvoudig upgraden naar het volgende pakket. We verwijderen nooit certificaten omdat je over een limiet heen bent.')],
+ ['q' => __('Kan ik tussentijds upgraden, downgraden of opzeggen?'), 'a' => __('Upgraden kan op elk moment; je betaalt alleen het verschil voor de rest van het jaar. Downgraden of opzeggen gaat in bij de volgende verlengingsdatum. Na opzegging kun je al je data exporteren; daarna verwijderen we alles definitief binnen 30 dagen.')],
+ ['q' => __('Heb ik een verwerkersovereenkomst nodig bij een betaald pakket?'), 'a' => __('Meestal niet — gebruik je Certified voor jezelf, dan ben je geen verwerkingsverantwoordelijke. Wil je er als zzp\'er of eenmanszaak toch één voor je administratie, dan staat de standaard verwerkersovereenkomst gratis voor je klaar op de DPA-pagina.')],
+ ['q' => __('Zijn er kosten per OCR-scan?'), 'a' => __('Nee. OCR-scans zitten bij elk pakket inbegrepen — ook bij Gratis. Je betaalt nooit per scan.')],
],
])
diff --git a/resources/views/marketing/privacy.blade.php b/resources/views/marketing/privacy.blade.php
new file mode 100644
index 0000000..959668e
--- /dev/null
+++ b/resources/views/marketing/privacy.blade.php
@@ -0,0 +1,161 @@
+@extends('marketing.layout')
+
+@section('title', __('Privacyverklaring').' — Certified')
+@section('description', __('Hoe Certified omgaat met je persoonsgegevens: welke gegevens we verzamelen, waarom, en welke rechten je hebt.'))
+
+@section('content')
+
+@include('marketing.partials.legal-header', ['title' => __('Privacyverklaring'), 'updated' => __('Versie 1.0 · augustus 2026 · AVG/GDPR')])
+
+
+
+ {{ __('Bckstage exploiteert Certified, een persoonlijke certificatenmanager waarmee je zelf je certificaten, diploma\'s en documenten zoals een VOG bijhoudt. Deze verklaring legt uit welke persoonsgegevens we verzamelen, waarom, hoe lang we ze bewaren en wat je rechten zijn onder de AVG/GDPR.') }}
+
+
+ {{ __('Bckstage is verwerkingsverantwoordelijke voor alle persoonsgegevens die worden verwerkt om je Certified te leveren: je accountgegevens en de certificaatgegevens en documenten die je zelf uploadt.') }}
+
+
+
+
+
2. {{ __('Welke gegevens we verzamelen en waarom') }}
+
+
+
+
{{ __('Account en authenticatie') }}
+
{{ __('Naam, e-mailadres, gehasht wachtwoord of passkey, taalvoorkeur en sessiegegevens.') }}
+
{{ __('Rechtsgrond: overeenkomst (art. 6 lid 1 sub b AVG) · Bewaartermijn: tot accountverwijdering + 30 dagen') }}
+
+
+
+
{{ __('Certificaatgegevens') }}
+
{{ __("Titel, uitgever, certificaatnummer, uitgifte- en vervaldatum, notities en het geüploade document zelf — soms bijzondere persoonsgegevens, zoals gegevens over het strafrechtelijk verleden bij een VOG.") }}
+
{{ __('Rechtsgrond: overeenkomst (art. 6 lid 1 sub b AVG) · Bewaartermijn: tot verwijdering door jou, of tot 30 dagen na accountopzegging') }}
+
+
+
+
{{ __('Beveiligingslogboeken') }}
+
{{ __('IP-adres, browser- en apparaatinformatie en inloggebeurtenissen, gebruikt om misbruik te detecteren en beveiligingsincidenten te onderzoeken.') }}
+
{{ __('Rechtsgrond: gerechtvaardigd belang (art. 6 lid 1 sub f AVG) · Bewaartermijn: 90 dagen') }}
+
+
+
+
{{ __('OCR-verwerking (optioneel)') }}
+
{{ __('Schakel je automatische tekstherkenning in, dan wordt het document dat je op dat moment uploadt gestuurd naar de Europese provider die jij zelf kiest: Klippa (Nederland) of Mistral AI (Frankrijk). Zonder deze instelling gebeurt dit niet.') }}
+
{{ __('Rechtsgrond: toestemming (art. 6 lid 1 sub a AVG) · Bewaartermijn: niet permanent opgeslagen bij de provider') }}
+
+
+
+
{{ __('Servicecommunicatie') }}
+
{{ __('We versturen reminders en accountmeldingen via Resend (Verenigde Staten). Open- en kliktracking staat uit; Resend verwerkt alleen het ontvangeradres en de berichtinhoud.') }}
+
{{ __('Rechtsgrond: overeenkomst (art. 6 lid 1 sub b AVG) · Bewaartermijn: 90 dagen in maillogboeken') }}
+
+
+
+
{{ __('Facturering (betaalde abonnementen)') }}
+
{{ __('Naam, factuuradres en e-mailadres voor facturering. Betalingsgegevens worden niet door Bckstage zelf opgeslagen.') }}
+
{{ __('Rechtsgrond: wettelijke verplichting (art. 6 lid 1 sub c AVG) · Bewaartermijn: 7 jaar (Nederlandse belastingwet)') }}
+
+
+
+
+
+
3. {{ __('Cookies') }}
+
+ {{ __('Certified gebruikt uitsluitend strikt noodzakelijke cookies: een sessiecookie om je ingelogd te houden, een CSRF-tokencookie ter beveiliging, en een voorkeurscookie voor je taal en weergave (licht/donker). We gebruiken geen reclamecookies, trackingpixels of analyses van derden. Er is geen cookiebanner nodig omdat we uitsluitend strikt noodzakelijke cookies plaatsen.') }}
+
+
+
+
+
4. {{ __('Derden en internationale doorgiften') }}
+
+ {{ __('We verkopen, verhuren of verhandelen je persoonsgegevens nooit aan derden. We delen gegevens uitsluitend met de volgende partijen, voor zover van toepassing op jouw gebruik:') }}
+
+
+
+
+
+
{{ __('Partij') }}
+
{{ __('Locatie') }}
+
{{ __('Doel') }}
+
+
+
+
+
Resend
+
{{ __('Verenigde Staten') }}
+
{{ __('Bezorging van reminders en accountmeldingen') }}
+
+
+
Klippa
+
{{ __('Nederland (EU)') }}
+
{{ __('OCR-herkenning — alleen als jij dit inschakelt') }}
+
+
+
Mistral AI
+
{{ __('Frankrijk (EU)') }}
+
{{ __('OCR-herkenning — alleen als jij dit inschakelt') }}
+
+
+
Moneybird
+
{{ __('Nederland (EU)') }}
+
{{ __('Facturering van betaalde abonnementen') }}
+
+
+
+
+
+ {{ __('Voor de doorgifte aan Resend (Verenigde Staten) steunen we op Standaardcontractuele Clausules op grond van Hoofdstuk V AVG. Klippa, Mistral AI en Moneybird zijn allen binnen de EU gevestigd.') }}
+
+
+
+
+
5. {{ __('Waar je gegevens worden opgeslagen') }}
+
+ {{ __('Je certificaten en accountgegevens worden opgeslagen in datacenters binnen de Europese Unie. We gebruiken geen Amerikaanse cloudproviders voor hosting, waardoor je gegevens niet onder de Amerikaanse CLOUD Act vallen.') }}
+
+
+
+
+
6. {{ __('Beveiliging') }}
+
+ {{ __('We versleutelen documenten in rust en tijdens verzending (TLS), scheiden accounts op databaseniveau en ondersteunen phishing-bestendige aanmelding via passkeys. Gedeelde documenten zijn alleen bereikbaar via cryptografisch ondertekende links die automatisch verlopen. Meer details vind je op onze security-pagina. Mochten we een datalek ontdekken met waarschijnlijk hoog risico voor jouw rechten, dan informeren we je zonder onredelijke vertraging conform artikel 34 AVG.') }}
+
+
+
+
+
7. {{ __('Jouw rechten') }}
+
+ {{ __('Onder de AVG heb je recht op inzage, rectificatie, verwijdering, beperking van de verwerking, gegevensoverdraagbaarheid en bezwaar. Je kunt je certificaten en gegevens grotendeels zelf inzien en exporteren vanuit je account; voor andere verzoeken mail je ons. We reageren binnen één maand. Je hebt ook het recht een klacht in te dienen bij de Autoriteit Persoonsgegevens.') }}
+
+
+
+
+
8. {{ __('Minderjarigen') }}
+
+ {{ __('Certified is niet bedoeld voor gebruik door personen jonger dan 16 jaar. Vermoed je dat we onbedoeld gegevens van een minderjarige hebben verzameld, neem dan contact met ons op zodat we deze kunnen verwijderen.') }}
+
+
+
+
+
9. {{ __('Wijzigingen') }}
+
+ {{ __('We kunnen deze verklaring van tijd tot tijd bijwerken. Bij wezenlijke wijzigingen informeren we je per e-mail, ten minste 14 dagen voordat de wijziging ingaat.') }}
+
+
+
+
+
10. {{ __('Contact') }}
+
+ {{ __('Vragen over deze verklaring of je gegevens? Mail ons via') }} privacy@bckstage.cloud.
+
+
+
+
+
+@endsection
diff --git a/resources/views/marketing/security.blade.php b/resources/views/marketing/security.blade.php
index 70289c1..8a0ccdd 100644
--- a/resources/views/marketing/security.blade.php
+++ b/resources/views/marketing/security.blade.php
@@ -1,7 +1,7 @@
@extends('marketing.layout')
-@section('title', 'Security & privacy — Certified')
-@section('description', 'Hoe Certified gevoelige certificaten beschermt: 100% Europese hosting, AES-256 versleuteld delen en keuze uit Europese OCR-providers. Volledig AVG/GDPR-compliant.')
+@section('title', __('Security & privacy').' — Certified')
+@section('description', __("Hoe Certified je certificaten beschermt: 100% Europese hosting, AES-256 versleuteld delen en keuze uit Europese OCR-providers. Volledig AVG/GDPR-compliant."))
@section('content')
@@ -12,13 +12,13 @@
- 🇪🇺 Privacy-by-design, gebouwd in Europa
+ 🇪🇺 {{ __('Privacy-by-design, gebouwd in Europa') }}
- Security & privacy als fundament, niet als bijzaak
+ {{ __('Security & privacy als fundament,') }} {{ __('niet als bijzaak') }}
- Certified beheert documenten met bijzondere persoonsgegevens — VOG's, diploma's, BSN-nummers. Op deze pagina lees je precies hoe we die gegevens beschermen.
+ {{ __("Certified bewaart documenten met bijzondere persoonsgegevens — je VOG en andere gevoelige diploma's en certificaten. Op deze pagina lees je precies hoe we die gegevens beschermen.") }}
@@ -27,28 +27,28 @@
@foreach ([
[
- 'kicker' => '01 — Hosting & jurisdictie',
- 'title' => '100% Europese hosting, onder Europees recht',
- 'body' => 'Alle applicatie- en documentdata staat in Europese datacenters. We gebruiken bewust geen Amerikaanse hyperscalers: je data valt daardoor niet onder de Amerikaanse CLOUD Act en blijft volledig binnen de reikwijdte van de AVG/GDPR. Back-ups worden versleuteld opgeslagen, eveneens binnen de EU.',
- 'points' => ['Datacenters in de EU, data verlaat Europa nooit', 'Geen Amerikaanse cloudproviders in de keten', 'Versleutelde back-ups binnen de EU'],
+ 'kicker' => '01 — '.__('Hosting & jurisdictie'),
+ 'title' => __('100% Europese hosting, onder Europees recht'),
+ 'body' => __('Alle applicatie- en documentdata staat in Europese datacenters. We gebruiken bewust geen Amerikaanse hyperscalers: je data valt daardoor niet onder de Amerikaanse CLOUD Act en blijft volledig binnen de reikwijdte van de AVG/GDPR. Back-ups worden versleuteld opgeslagen, eveneens binnen de EU.'),
+ 'points' => [__('Datacenters in de EU, data verlaat Europa nooit'), __('Geen Amerikaanse cloudproviders in de keten'), __('Versleutelde back-ups binnen de EU')],
],
[
- 'kicker' => '02 — Versleuteling',
- 'title' => 'Versleuteld in rust, onderweg en bij het delen',
- 'body' => 'Documenten worden versleuteld opgeslagen en al het verkeer loopt via TLS. Deel je een certificaat met een externe partij, dan gebeurt dat via een AES-256 versleutelde ZIP met een apart verstuurd wachtwoord, of via een ondertekende link die na 48 uur automatisch onbruikbaar wordt. API-sleutels van OCR-providers slaan we versleuteld op.',
- 'points' => ['AES-256 versleutelde ZIP-exports', 'Ondertekende deel-links met een maximale geldigheid van 48 uur', 'TLS voor al het verkeer, versleutelde opslag van API-sleutels'],
+ 'kicker' => '02 — '.__('Versleuteling'),
+ 'title' => __('Versleuteld in rust, onderweg en bij het delen'),
+ 'body' => __('Je documenten worden versleuteld opgeslagen en al het verkeer loopt via TLS. Deel je een certificaat met iemand anders, dan gebeurt dat via een AES-256 versleutelde ZIP met een apart verstuurd wachtwoord, of via een ondertekende link die na 48 uur automatisch onbruikbaar wordt. API-sleutels van OCR-providers slaan we versleuteld op.'),
+ 'points' => [__('AES-256 versleutelde ZIP-exports'), __('Ondertekende deel-links met een maximale geldigheid van 48 uur'), __('TLS voor al het verkeer, versleutelde opslag van API-sleutels')],
],
[
- 'kicker' => '03 — OCR-verwerking',
- 'title' => 'Jij kiest welke Europese partij je documenten leest',
- 'body' => 'Voor de automatische tekstherkenning kies je zelf een verwerker: Klippa (Nederland) of Mistral AI (Frankrijk) — beide Europese bedrijven onder Europese jurisdictie. Wil je helemaal geen externe verwerking? Zet OCR dan simpelweg uit en vul velden handmatig in. Jouw data, jouw keuze.',
- 'points' => ['Klippa: Nederlandse document-AI specialist', 'Mistral AI: Frans AI-bedrijf, EU-gehost', 'OCR volledig uitschakelbaar per account'],
+ 'kicker' => '03 — '.__('OCR-verwerking'),
+ 'title' => __('Jij kiest welke Europese partij je documenten leest'),
+ 'body' => __('Voor de automatische tekstherkenning kies je zelf een verwerker: Klippa (Nederland) of Mistral AI (Frankrijk) — beide Europese bedrijven onder Europese jurisdictie. Wil je helemaal geen externe verwerking? Zet OCR dan simpelweg uit en vul velden handmatig in. Jouw data, jouw keuze.'),
+ 'points' => [__('Klippa: Nederlandse document-AI specialist'), __('Mistral AI: Frans AI-bedrijf, EU-gehost'), __('OCR volledig uitschakelbaar per account')],
],
[
- 'kicker' => '04 — Toegang & isolatie',
- 'title' => 'Strikte scheiding tussen organisaties en gebruikers',
- 'body' => 'Elke gebruiker ziet uitsluitend de eigen certificaten — afgedwongen op databaseniveau, niet alleen in de interface. Inloggen kan met wachtwoord of passkeys, en gedeelde documenten zijn alleen bereikbaar via cryptografisch ondertekende URL\'s die niet te raden of te vervalsen zijn.',
- 'points' => ['Data-isolatie afgedwongen op databaseniveau', 'Ondersteuning voor passkeys (phishing-bestendig inloggen)', 'Cryptografisch ondertekende deel-URL\'s'],
+ 'kicker' => '04 — '.__('Toegang & isolatie'),
+ 'title' => __('Strikte scheiding tussen accounts'),
+ 'body' => __("Jij ziet uitsluitend je eigen certificaten — afgedwongen op databaseniveau, niet alleen in de interface. Inloggen kan met wachtwoord of passkeys, en documenten die je deelt zijn alleen bereikbaar via cryptografisch ondertekende URL's die niet te raden of te vervalsen zijn."),
+ 'points' => [__('Data-isolatie afgedwongen op databaseniveau'), __('Ondersteuning voor passkeys (phishing-bestendig inloggen)'), __("Cryptografisch ondertekende deel-URL's")],
],
] as $block)
@@ -74,24 +74,31 @@
- Verwerkersovereenkomst inbegrepen
+ {{ __('Verwerkersovereenkomst op aanvraag') }}
- Als jouw organisatie certificaten van medewerkers beheert, ben jij verwerkingsverantwoordelijke en zijn wij verwerker. Daarom leveren we bij elk betaald abonnement een heldere verwerkersovereenkomst — zodat je richting de Autoriteit Persoonsgegevens direct kunt aantonen dat het geregeld is.
+ {{ __('Gebruik je Certified voor je eigen certificaten, dan heb je geen verwerkersovereenkomst nodig — je bent zelf geen verwerkingsverantwoordelijke onder de AVG. Werk je als zzp\'er of eenmanszaak en wil je er voor je eigen administratie toch één, dan staat de standaard verwerkersovereenkomst voor je klaar.') }}
{{-- ============ FAQ ============ --}}
@include('marketing.partials.faq', [
- 'faqTitle' => 'Vragen over security',
- 'faqSubtitle' => 'De vragen die privacy officers en functionarissen gegevensbescherming ons het vaakst stellen.',
+ 'faqTitle' => __('Vragen over security'),
+ 'faqSubtitle' => __('De vragen die we het vaakst krijgen over privacy en gegevensbescherming.'),
'faqs' => [
- ['q' => 'Valt mijn data onder de Amerikaanse CLOUD Act?', 'a' => 'Nee. Certified draait uitsluitend op Europese infrastructuur van Europese leveranciers. Er is geen Amerikaanse partij in de hostingketen, dus de CLOUD Act is niet van toepassing op jouw data.'],
- ['q' => 'Wat gebeurt er met een document tijdens de OCR-scan?', 'a' => 'Het document wordt via een beveiligde verbinding naar de door jou gekozen Europese provider (Klippa of Mistral AI) gestuurd, die er tekst uit herkent en het resultaat teruggeeft. Wil je dit niet, dan zet je OCR uit en vul je de velden handmatig in.'],
- ['q' => 'Hoe lang blijft een gedeelde link geldig?', 'a' => 'Maximaal 48 uur. Daarna is de ondertekende URL cryptografisch ongeldig en kan niemand het document meer openen — ook niet met de oude link. Versleutelde ZIP-exports blijven beveiligd met AES-256 en het apart verstuurde wachtwoord.'],
- ['q' => 'Wie kan er bij de certificaten van mijn organisatie?', 'a' => 'Alleen de gebruikers van jouw eigen account. De scheiding tussen gebruikers wordt op databaseniveau afgedwongen. Onze eigen medewerkers hebben geen toegang tot documentinhoud, behalve wanneer jij daar bij een supportverzoek expliciet toestemming voor geeft.'],
- ['q' => 'Kan ik al mijn data exporteren of laten verwijderen?', 'a' => 'Ja. Je kunt op elk moment al je certificaten en metadata exporteren. Zeg je op, dan verwijderen we je data — inclusief back-ups — binnen 30 dagen definitief, conform de AVG.'],
+ ['q' => __('Valt mijn data onder de Amerikaanse CLOUD Act?'), 'a' => __('Nee. Certified draait uitsluitend op Europese infrastructuur van Europese leveranciers. Er is geen Amerikaanse partij in de hostingketen, dus de CLOUD Act is niet van toepassing op jouw data.')],
+ ['q' => __('Wat gebeurt er met een document tijdens de OCR-scan?'), 'a' => __('Het document wordt via een beveiligde verbinding naar de door jou gekozen Europese provider (Klippa of Mistral AI) gestuurd, die er tekst uit herkent en het resultaat teruggeeft. Wil je dit niet, dan zet je OCR uit en vul je de velden handmatig in.')],
+ ['q' => __('Hoe lang blijft een gedeelde link geldig?'), 'a' => __('Maximaal 48 uur. Daarna is de ondertekende URL cryptografisch ongeldig en kan niemand het document meer openen — ook niet met de oude link. Versleutelde ZIP-exports blijven beveiligd met AES-256 en het apart verstuurde wachtwoord.')],
+ ['q' => __('Wie kan er bij mijn certificaten?'), 'a' => __('Alleen jij, vanuit je eigen account. De scheiding tussen accounts wordt op databaseniveau afgedwongen. Onze eigen medewerkers hebben geen toegang tot documentinhoud, behalve wanneer jij daar bij een supportverzoek expliciet toestemming voor geeft.')],
+ ['q' => __('Kan ik al mijn data exporteren of laten verwijderen?'), 'a' => __('Ja. Je kunt op elk moment al je certificaten en metadata exporteren. Zeg je op, dan verwijderen we je data — inclusief back-ups — binnen 30 dagen definitief, conform de AVG.')],
],
])
diff --git a/resources/views/marketing/terms.blade.php b/resources/views/marketing/terms.blade.php
new file mode 100644
index 0000000..1dd3f8d
--- /dev/null
+++ b/resources/views/marketing/terms.blade.php
@@ -0,0 +1,154 @@
+@extends('marketing.layout')
+
+@section('title', __('Algemene voorwaarden').' — Certified')
+@section('description', __('De gebruiksvoorwaarden voor het gebruik van Certified.'))
+
+@section('content')
+
+@include('marketing.partials.legal-header', ['title' => __('Algemene voorwaarden'), 'updated' => __('Versie 1.0 · augustus 2026')])
+
+
+
+ {{ __('De natuurlijke persoon die een account aanmaakt bij Certified om zijn eigen certificaten, diploma\'s en documenten te beheren.') }}
+
+
+
+
+
+
1.1 {{ __('"Overeenkomst" betekent deze Gebruiksvoorwaarden, samen met onze Privacyverklaring en, indien van toepassing, de Verwerkersovereenkomst.') }}
+
1.2 {{ __('"Dienst" betekent Certified: het platform waarmee je je eigen certificaten, diploma\'s en vergelijkbare documenten beheert, inclusief automatische OCR-herkenning, reminders en veilig delen.') }}
+
1.3 {{ __('"Gebruiker" of "je"/"jij" betekent de natuurlijke persoon die een account aanmaakt en de Dienst gebruikt.') }}
+
1.4 {{ __('"Inhoud" betekent alle certificaten, documenten, gegevens en bestanden die je naar de Dienst uploadt.') }}
+
+
+
+
+
{{ __('Artikel 2 — Acceptatie en geschiktheid') }}
+
+
2.1 {{ __('Door een account aan te maken of de Dienst te gebruiken, ga je akkoord met deze Overeenkomst. Ga je hier niet mee akkoord, dan mag je de Dienst niet gebruiken.') }}
+
2.2 {{ __('Je verklaart dat je ten minste 16 jaar oud bent.') }}
+
2.3 {{ __('Je bent zelf verantwoordelijk voor het geven van juiste en actuele gegevens bij registratie, en voor het up-to-date houden daarvan.') }}
+
+
+
+
+
{{ __('Artikel 3 — Toegang en accountverplichtingen') }}
+
+
3.1 {{ __('Zolang je deze Overeenkomst naleeft, verleent de Aanbieder je een beperkt, niet-overdraagbaar recht om de Dienst te gebruiken.') }}
+
3.2 {{ __('Je account is persoonlijk; het delen van je inloggegevens met anderen is niet toegestaan.') }}
+
3.3 {{ __('Je bent verantwoordelijk voor het geheimhouden van je wachtwoord of passkey en meldt vermoed onbevoegd gebruik direct aan ons.') }}
+
+
+
+
+
{{ __('Artikel 4 — Aanvaardbaar gebruik') }}
+
+ {{ __('Certified is bedoeld voor het beheren van je eigen certificaten en documenten door jou als individu — niet voor het op grote schaal beheren van certificaten van andere personen namens een bedrijf of organisatie.') }}
+
+
{{ __('Het volgende is niet toegestaan:') }}
+
+ @foreach ([
+ __('Proberen onbevoegde toegang te krijgen tot enig onderdeel van de Dienst of gegevens van andere gebruikers'),
+ __('Reverse-engineeren, decompileren of afgeleide werken maken van de Dienst'),
+ __('Malware, virussen of schadelijke code uploaden of verspreiden via de Dienst'),
+ __('Documenten uploaden die niet van jou zijn, zonder toestemming van de rechthebbende'),
+ __('Doorverkoop of sublicentiëring van toegang tot de Dienst zonder onze voorafgaande schriftelijke toestemming'),
+ __('Geautomatiseerd scrapen, crawlen of op grote schaal gegevens onttrekken aan de Dienst'),
+ __('Elk gebruik dat in strijd is met toepasselijk recht of rechten van derden'),
+ ] as $item)
+
+
+ {{ $item }}
+
+ @endforeach
+
+
+ {{ __('We behouden ons het recht voor om toegang op te schorten zonder voorafgaande kennisgeving wanneer we een schending van dit artikel constateren of vermoeden.') }}
+
+
+
+
+
{{ __('Artikel 5 — Abonnementen en betaling') }}
+
+
5.1 {{ __('Certified kent een gratis pakket en de betaalde abonnementen Starter en Onbeperkt, zoals beschreven op onze prijzenpagina. Betaalde abonnementen worden jaarlijks vooraf gefactureerd, exclusief btw.') }}
+
5.2 {{ __('Upgraden kan op elk moment; je betaalt dan alleen het verschil voor de resterende looptijd.') }}
+
5.3 {{ __('Downgraden of opzeggen van een betaald abonnement gaat in op de eerstvolgende verlengingsdatum. Reeds betaalde bedragen worden niet naar rato terugbetaald.') }}
+
5.4 {{ __('We kunnen onze prijzen aanpassen met een schriftelijke kennisgeving van ten minste 30 dagen vooraf. Ga je niet akkoord met de nieuwe prijs, dan kun je opzeggen voordat de wijziging ingaat.') }}
+
+
+
+
+
{{ __('Artikel 6 — Intellectueel eigendom') }}
+
+
6.1 {{ __('Wij behouden alle intellectuele eigendomsrechten op de Dienst zelf, waaronder de broncode, het ontwerp en onze merken.') }}
+
6.2 {{ __('Jij behoudt alle rechten op je eigen Inhoud. Je geeft ons een beperkte licentie om je Inhoud op te slaan, te verwerken en te verzenden, uitsluitend voor zover nodig om de Dienst aan jou te leveren.') }}
+
6.3 {{ __('We mogen geanonimiseerde, geaggregeerde gegevens die niet tot jou herleidbaar zijn gebruiken om de Dienst te verbeteren.') }}
+
+
+
+
+
{{ __('Artikel 7 — Beschikbaarheid en wijzigingen van de Dienst') }}
+
+ {{ __('We streven naar een betrouwbaar beschikbare Dienst, maar garanderen geen ononderbroken of foutloze toegang. We kunnen de Dienst van tijd tot tijd aanpassen; ingrijpende wijzigingen kondigen we vooraf aan.') }}
+
+
+
+
+
{{ __('Artikel 8 — Gegevens, privacy en OCR-verwerking') }}
+
+
8.1 {{ __('Hoe we met je persoonsgegevens omgaan staat beschreven in onze Privacyverklaring, die integraal onderdeel uitmaakt van deze Overeenkomst.') }}
+
8.2 {{ __('Automatische tekstherkenning (OCR) vindt alleen plaats als jij dit zelf inschakelt, via een door jou gekozen Europese provider. Je kunt OCR ook uitschakelen en velden handmatig invullen.') }}
+
8.3 {{ __('De Dienst gebruikt uitsluitend strikt noodzakelijke functionele cookies — geen reclame- of trackingcookies.') }}
+
+
+
+
+
{{ __('Artikel 9 — Aansprakelijkheid') }}
+
+
9.1 {{ __('Certified is een hulpmiddel om je certificaten te overzien en je te herinneren aan vervaldatums — geen garantie dat je nooit een deadline mist. De Dienst wordt geleverd "zoals het is".') }}
+
9.2 {{ __('Voor zover wettelijk toegestaan zijn wij niet aansprakelijk voor indirecte schade of gevolgschade. Onze totale aansprakelijkheid is beperkt tot het bedrag dat je in de twaalf maanden voorafgaand aan de schadeveroorzakende gebeurtenis aan ons hebt betaald.') }}
+
9.3 {{ __('Niets in deze Overeenkomst beperkt aansprakelijkheid voor overlijden of persoonlijk letsel door onze nalatigheid, fraude, of andere aansprakelijkheid die niet kan worden uitgesloten onder Nederlands recht.') }}
+
+
+
+
+
{{ __('Artikel 10 — Opzeggen en verwijdering van je data') }}
+
+ {{ __('Je kunt je account op elk moment opzeggen vanuit je instellingen. Je kunt daarvoor al je certificaten en gegevens exporteren. Na opzegging verwijderen we je gegevens, inclusief back-ups, definitief binnen 30 dagen. Wij kunnen je account opschorten of beëindigen bij een wezenlijke schending van artikel 4.') }}
+
+
+
+
+
{{ __('Artikel 11 — Wijzigingen van deze voorwaarden') }}
+
+ {{ __('We kunnen deze voorwaarden wijzigen door een bijgewerkte versie op deze pagina te plaatsen. Bij ingrijpende wijzigingen informeren we je per e-mail, ten minste 30 dagen voordat de wijziging ingaat. Voortgezet gebruik na die datum geldt als acceptatie.') }}
+
+
+
+
+
{{ __('Artikel 12 — Toepasselijk recht en bevoegde rechter') }}
+
+
12.1 {{ __('Op deze Overeenkomst is Nederlands recht van toepassing.') }}
+
12.2 {{ __('Geschillen worden voorgelegd aan de bevoegde rechtbank te Arnhem, Nederland, tenzij dwingend consumentenrecht in jouw woonland anders bepaalt.') }}
+ {{ __('Verify a certificate') }}
+
+ {{ __('Enter the certificate number and the last name of the certificate holder to check whether it is genuine and currently valid.') }}
+
+
+
+ @if ($result === 'valid')
+
+ {{ __('This certificate number and last name match a currently valid certificate.') }}
+
+ @elseif ($result === 'invalid')
+
+ {{ __('No currently valid certificate matches that certificate number and last name.') }}
+
+ @endif
+
+
+
+@endsection
diff --git a/routes/web.php b/routes/web.php
index f496e0b..9fa8e5f 100644
--- a/routes/web.php
+++ b/routes/web.php
@@ -1,25 +1,37 @@
name('home');
Route::get('/security', [MarketingController::class, 'security'])->name('marketing.security');
Route::get('/pricing', [MarketingController::class, 'pricing'])->name('marketing.pricing');
+Route::get('/terms', [MarketingController::class, 'terms'])->name('marketing.terms');
+Route::get('/privacy', [MarketingController::class, 'privacy'])->name('marketing.privacy');
+Route::get('/dpa', [MarketingController::class, 'dpa'])->name('marketing.dpa');
// Available to guests and authenticated users alike.
Route::get('language/{locale}', LanguageController::class)->name('language.switch');
+// Public certificate authenticity check. No auth — anyone with a
+// certificate number and the holder's last name can confirm it's valid.
+Route::get('verify', [VerifyController::class, 'show'])->name('verify.show');
+Route::post('verify', [VerifyController::class, 'check'])->middleware('throttle:10,1')->name('verify.check');
+
Route::middleware(['auth', 'verified'])->group(function () {
Route::livewire('dashboard', 'pages::dashboard')->name('dashboard');
Route::livewire('certificates', 'pages::certificates.index')->name('certificates.index');
Route::livewire('certificates/create', 'pages::certificates.create')->name('certificates.create');
+ Route::livewire('certificates/{certificate}', 'pages::certificates.show')->name('certificates.show');
Route::livewire('certificates/{certificate}/edit', 'pages::certificates.edit')->name('certificates.edit');
Route::get('certificates/{certificate}/download', CertificateDownloadController::class)->name('certificates.download');
+ Route::get('certificates/{certificate}/preview', CertificatePreviewController::class)->name('certificates.preview');
Route::livewire('categories', 'pages::categories.index')->name('categories.index');
diff --git a/tests/Feature/Verify/CheckCertificateTest.php b/tests/Feature/Verify/CheckCertificateTest.php
new file mode 100644
index 0000000..b321ecc
--- /dev/null
+++ b/tests/Feature/Verify/CheckCertificateTest.php
@@ -0,0 +1,91 @@
+get(route('verify.show'))
+ ->assertOk()
+ ->assertSee(__('Verify a certificate'));
+});
+
+test('a matching certificate number and last name is reported valid', function () {
+ Certificate::factory()->for(User::factory())->create([
+ 'certificate_number' => 'CERT-1234-ABCD',
+ 'holder_last_name' => 'Jansen',
+ 'expires_at' => now()->addYear(),
+ ]);
+
+ $this->post(route('verify.check'), [
+ 'certificate_number' => 'cert-1234-abcd',
+ 'holder_last_name' => 'jansen',
+ ])->assertRedirect(route('verify.show'));
+
+ $this->get(route('verify.show'))
+ ->assertSee(__('Valid'));
+});
+
+test('a mismatched last name is reported invalid', function () {
+ Certificate::factory()->for(User::factory())->create([
+ 'certificate_number' => 'CERT-1234-ABCD',
+ 'holder_last_name' => 'Jansen',
+ 'expires_at' => now()->addYear(),
+ ]);
+
+ $this->post(route('verify.check'), [
+ 'certificate_number' => 'CERT-1234-ABCD',
+ 'holder_last_name' => 'Bakker',
+ ])->assertRedirect(route('verify.show'));
+
+ $this->get(route('verify.show'))
+ ->assertSee(__('Invalid'));
+});
+
+test('an unknown certificate number is reported invalid', function () {
+ $this->post(route('verify.check'), [
+ 'certificate_number' => 'DOES-NOT-EXIST',
+ 'holder_last_name' => 'Bakker',
+ ])->assertRedirect(route('verify.show'));
+
+ $this->get(route('verify.show'))
+ ->assertSee(__('Invalid'));
+});
+
+test('an expired certificate is reported invalid', function () {
+ Certificate::factory()->for(User::factory())->create([
+ 'certificate_number' => 'CERT-1234-ABCD',
+ 'holder_last_name' => 'Jansen',
+ 'expires_at' => now()->subDay(),
+ ]);
+
+ $this->post(route('verify.check'), [
+ 'certificate_number' => 'CERT-1234-ABCD',
+ 'holder_last_name' => 'Jansen',
+ ])->assertRedirect(route('verify.show'));
+
+ $this->get(route('verify.show'))
+ ->assertSee(__('Invalid'));
+});
+
+test('certificates belonging to any account can be verified, not just the authenticated user\'s own', function () {
+ Certificate::factory()->for(User::factory())->create([
+ 'certificate_number' => 'CERT-1234-ABCD',
+ 'holder_last_name' => 'Jansen',
+ 'expires_at' => now()->addYear(),
+ ]);
+
+ $this->actingAs(User::factory()->create());
+
+ $this->post(route('verify.check'), [
+ 'certificate_number' => 'CERT-1234-ABCD',
+ 'holder_last_name' => 'Jansen',
+ ])->assertRedirect(route('verify.show'));
+
+ $this->get(route('verify.show'))
+ ->assertSee(__('Valid'));
+});
+
+test('certificate number and last name are required', function () {
+ $this->post(route('verify.check'), [])
+ ->assertSessionHasErrors(['certificate_number', 'holder_last_name']);
+});