diff --git a/README.md b/README.md
index d819051..59166fd 100644
--- a/README.md
+++ b/README.md
@@ -48,11 +48,13 @@ pnpm run check:external # outside links; weekly in CI, not
| What | Pin | Refresh |
|---|---|---|
-| Product groups and EU acts from `dpp-core` | `site/dpp-landing/core-source.json` | `pnpm --filter dpp-landing run sync:core` |
+| Product groups and EU acts from `dpp-core`, with a copy of the acts in `site/dpp-docs/src/data/instruments` for the docs | `site/dpp-landing/core-source.json` | `pnpm --filter dpp-landing run sync:core` |
| API spec from `dpp-engine` | `site/dpp-docs/openapi-source.json` | `pnpm run sync:openapi`, or the nightly workflow |
Never edit the vendored files by hand; bump the pin and sync.
+Never type a passport date into a page either. The docs write ``, landing pages call `passportDateOf("")`, and copy in `site/dpp-landing/src/data` writes `{passport:}`. All three read the vendored acts and fail the build when an act records no date. Other regulatory dates are written beside the article that sets them.
+
## Releasing
`main` is what Cloudflare publishes. Its ruleset matches `dpp-core` and `dpp-engine`: pull request required, squash only, `build` must pass on an up-to-date branch, no force-push, no deletion, no bypass.
diff --git a/site/dpp-docs/src/components/PassportDate.astro b/site/dpp-docs/src/components/PassportDate.astro
new file mode 100644
index 0000000..cacd788
--- /dev/null
+++ b/site/dpp-docs/src/components/PassportDate.astro
@@ -0,0 +1,14 @@
+---
+// PassportDate.astro — the date an act's passport becomes mandatory, from the
+// vendored dpp-core instrument records. See src/lib/acts.ts.
+import { passportDate } from '../lib/acts';
+
+interface Props {
+ act: string;
+ short?: boolean;
+}
+
+const { act, short = false } = Astro.props;
+---
+
+{passportDate(act, short ? 'short' : 'long')}
diff --git a/site/dpp-docs/src/content/docs/regulatory/acts-and-standards.mdx b/site/dpp-docs/src/content/docs/regulatory/acts-and-standards.mdx
index 4540012..6a41672 100644
--- a/site/dpp-docs/src/content/docs/regulatory/acts-and-standards.mdx
+++ b/site/dpp-docs/src/content/docs/regulatory/acts-and-standards.mdx
@@ -4,6 +4,7 @@ description: Every EU act and standard the Odal Node code relies on, the article
---
import { Aside } from "@astrojs/starlight/components";
+import PassportDate from "../../../components/PassportDate.astro";
This is the reference behind the website's [regulations page](https://odal-node.io/regulations): every EU act and standard the code cites, grouped by what the software does with it, with the articles it relies on, and then the acts it does not apply yet but is preparing for.
@@ -17,12 +18,12 @@ These are records in the core library's instrument catalog, and the website's re
| Act | Passport provision the catalog rests on |
|---|---|
-| Batteries Regulation (EU) 2023/1542 | Art. 77(1), from 18 February 2027; access by Art. 77(2) and Annex XIII |
+| Batteries Regulation (EU) 2023/1542 | Art. 77(1), from ; access by Art. 77(2) and Annex XIII |
| Ecodesign for Sustainable Products Regulation (EU) 2024/1781 | Art. 9(1), dated act by act through delegated acts; access by Art. 11(b) |
| Construction Products Regulation (EU) 2024/3110 | Art. 22(7): 18 months after the Art. 75(1) delegated act, not yet adopted |
-| Detergents Regulation (EU) 2026/405 | Art. 21(1), applying from 23 September 2029 (Art. 37); transition in Art. 36(2) |
-| Toy Safety Regulation (EU) 2025/2509 | Art. 19(1), applying from 1 August 2030 (Art. 59) |
-| End-of-Life Vehicles Regulation (EU) 2026/1738 | Art. 13(1): a vehicle passport from 1 September 2032 |
+| Detergents Regulation (EU) 2026/405 | Art. 21(1), applying from (Art. 37); transition in Art. 36(2) |
+| Toy Safety Regulation (EU) 2025/2509 | Art. 19(1), applying from (Art. 59) |
+| End-of-Life Vehicles Regulation (EU) 2026/1738 | Art. 13(1): a vehicle passport from |
| Delegated Regulation (EU) 2026/296 and Implementing Regulation (EU) 2026/2 | No passport: the unsold-goods destruction derogations and disclosure format |
| Regulations (EU) 2023/1670 and 2023/1669 | No passport: product information goes to EPREL |
| Packaging and Packaging Waste Regulation (EU) 2025/40 | No passport: a shared data carrier only |
diff --git a/site/dpp-docs/src/content/docs/regulatory/battery.mdx b/site/dpp-docs/src/content/docs/regulatory/battery.mdx
index fa9bcc9..e87a90d 100644
--- a/site/dpp-docs/src/content/docs/regulatory/battery.mdx
+++ b/site/dpp-docs/src/content/docs/regulatory/battery.mdx
@@ -3,11 +3,13 @@ title: Battery DPP
description: The EU Battery Regulation (EU 2023/1542), what a battery passport carries under Annex XIII, the supply-chain due-diligence record, and which checks are binding today.
---
+import PassportDate from "../../../components/PassportDate.astro";
+
The Battery Regulation (EU 2023/1542) is the first product-group regulation to require a Digital Product Passport in production. Article 1(3) applies it to five categories of battery, and only five: portable, starting-lighting-ignition (SLI), light means of transport (LMT), electric vehicle (EV) and industrial. The list is closed on purpose: where a battery could fall under more than one category, the strictest requirements apply, and that rule only works over a closed list. Stationary energy-storage systems are not a sixth category; the Regulation places them under industrial. The regulation is already in force, and some of its staged dates have already passed.
## Which batteries need a passport
-Not all five. **Art. 77(1)**: from 18 February 2027, each LMT battery, each industrial battery with a capacity greater than 2 kWh and each electric-vehicle battery placed on the market or put into service must have a battery passport. Portable and SLI batteries, and industrial batteries of 2 kWh or less, do not. Under **Art. 77(8)** the passport ceases to exist once the battery has been recycled.
+Not all five. **Art. 77(1)**: from , each LMT battery, each industrial battery with a capacity greater than 2 kWh and each electric-vehicle battery placed on the market or put into service must have a battery passport. Portable and SLI batteries, and industrial batteries of 2 kWh or less, do not. Under **Art. 77(8)** the passport ceases to exist once the battery has been recycled.
## What the regulation requires
@@ -31,7 +33,7 @@ The Battery Regulation is in force, but its requirements start in stages, and Od
- **Declared now, binding later**: the minimum recycled-content shares for cobalt, lithium, nickel and lead, set by Art. 8(2) and 8(3) and cross-referenced to Annex VIII. (Annex X is the due-diligence raw-materials list and has nothing to do with recycled content.) These are final law but only take effect in 2031, rising again in 2036, so today they are shown as advisory rather than as a pass or fail.
- **Waiting for a delegated act**: minimum electrochemical performance and durability values, empowered by Art. 10(5), and the carbon-footprint performance class under Art. 7(2). Art. 7(2) requires the label to declare a class but leaves the classes themselves to an act that has not been adopted, and requires the scale to be revised every three years. Neither the classes nor how many there will be is settled, and we do not guess.
-The passport itself becomes mandatory on **18 February 2027**. As each later requirement takes effect, the battery checks are extended to cover it, and passports already issued stay valid. Every product group follows the same approach of giving a binding verdict only where the law applies; see [ESPR Overview](/regulatory/espr).
+The passport itself becomes mandatory on ****. As each later requirement takes effect, the battery checks are extended to cover it, and passports already issued stay valid. Every product group follows the same approach of giving a binding verdict only where the law applies; see [ESPR Overview](/regulatory/espr).
## Who may read which part
diff --git a/site/dpp-docs/src/content/docs/regulatory/detergents.mdx b/site/dpp-docs/src/content/docs/regulatory/detergents.mdx
index 99ffd64..212ea1f 100644
--- a/site/dpp-docs/src/content/docs/regulatory/detergents.mdx
+++ b/site/dpp-docs/src/content/docs/regulatory/detergents.mdx
@@ -4,12 +4,13 @@ description: What the Detergents Regulation (EU) 2026/405 requires of a detergen
---
import { Aside } from "@astrojs/starlight/components";
+import PassportDate from "../../../components/PassportDate.astro";
The Detergents Regulation (EU) 2026/405 creates a passport for detergents and end-user surfactants. It replaces Regulation (EC) No 648/2004 and is built on the same passport regime as the [toy passport](/regulatory/toys).
## When
-- **The passport applies from 23 September 2029**, when the Regulation applies (Art. 37; only Art. 4(3) and (4) apply earlier).
+- **The passport applies from **, when the Regulation applies (Art. 37; only Art. 4(3) and (4) apply earlier).
- **Transition** (Art. 36):
- Products that meet the old Regulation and are placed on the market **before** 23 September 2029 may continue to be made available indefinitely.
- Products that meet the old Regulation and are placed on the market **between 23 September 2029 and 22 September 2030** may be made available until 23 September 2030. For that year, a detergent can be placed on the market without a passport.
diff --git a/site/dpp-docs/src/content/docs/regulatory/espr.mdx b/site/dpp-docs/src/content/docs/regulatory/espr.mdx
index 47f4d0c..54a2b89 100644
--- a/site/dpp-docs/src/content/docs/regulatory/espr.mdx
+++ b/site/dpp-docs/src/content/docs/regulatory/espr.mdx
@@ -4,8 +4,9 @@ description: The Ecodesign for Sustainable Products Regulation, what it requires
---
import { Aside } from "@astrojs/starlight/components";
+import PassportDate from "../../../components/PassportDate.astro";
-The Ecodesign for Sustainable Products Regulation (ESPR, EU 2024/1781) is the framework regulation that sets up the Digital Product Passport requirement across the European Union. It entered into force in 2024. **No delegated act under Article 4 has yet been adopted for any product group**, so ESPR itself obliges nobody to issue a passport today: the framework is in force, but the obligations that depend on it are not. The passport obligations that do have dates come from other acts: the Battery Regulation from 18 February 2027, the Detergents Regulation from 23 September 2029 and the Toy Safety Regulation from 1 August 2030. The Construction Products Regulation requires a passport too, but Art. 22(7) dates it 18 months after the Commission's delegated act setting up the construction passport system (Art. 75(1)), and that act has not been adopted.
+The Ecodesign for Sustainable Products Regulation (ESPR, EU 2024/1781) is the framework regulation that sets up the Digital Product Passport requirement across the European Union. It entered into force in 2024. **No delegated act under Article 4 has yet been adopted for any product group**, so ESPR itself obliges nobody to issue a passport today: the framework is in force, but the obligations that depend on it are not. The passport obligations that do have dates come from other acts: the Battery Regulation from , the Detergents Regulation from and the Toy Safety Regulation from . The Construction Products Regulation requires a passport too, but Art. 22(7) dates it 18 months after the Commission's delegated act setting up the construction passport system (Art. 75(1)), and that act has not been adopted.
## What ESPR requires
@@ -45,15 +46,15 @@ ESPR is a framework. The binding detail comes in delegated acts for each product
| Product group | Regulatory basis | Status today |
|---|---|---|
-| [**Batteries**](/regulatory/battery) | Regulation (EU) 2023/1542 | Passport required from 18 Feb 2027 for EV, LMT and industrial batteries over 2 kWh; substance limits enforced now |
+| [**Batteries**](/regulatory/battery) | Regulation (EU) 2023/1542 | Passport required from for EV, LMT and industrial batteries over 2 kWh; substance limits enforced now |
| [**Textiles**](/regulatory/textile) | ESPR | No delegated act; indicative adoption 2027. Structural validation only |
| **Iron and steel** | ESPR | No delegated act; first in the working plan, indicative adoption 2026 |
| **Aluminium** | ESPR | No delegated act; indicative adoption 2027. Carbon checks use reference values as warnings only |
| **Tyres** | ESPR; Tyre Labelling Regulation (EU) 2020/740 | No delegated act; indicative adoption 2027. Label classes in force |
| **Furniture** · **Mattresses** | ESPR | No delegated act; indicative adoption 2028 and 2029 |
| [**Phones and tablets**](/regulatory/phones) | Regulations (EU) 2023/1670 and 2023/1669 (ecodesign and energy labelling, not ESPR) | In force since 20 Jun 2025; no passport, product information goes to EPREL |
-| [**Toys**](/regulatory/toys) | Regulation (EU) 2025/2509 | Passport required from 1 Aug 2030, a date set by the Toy Safety Regulation itself |
-| [**Detergents**](/regulatory/detergents) | Regulation (EU) 2026/405 | Passport required from 23 Sep 2029, with a one-year transition for products meeting the old rules |
+| [**Toys**](/regulatory/toys) | Regulation (EU) 2025/2509 | Passport required from , a date set by the Toy Safety Regulation itself |
+| [**Detergents**](/regulatory/detergents) | Regulation (EU) 2026/405 | Passport required from , with a one-year transition for products meeting the old rules |
| [**Construction products**](/regulatory/construction) | Regulation (EU) 2024/3110 | Passport owed 18 months after the Commission's delegated act setting up the construction passport system (Art. 22(7), Art. 75(1)), not yet adopted. Operator owes 10 years of availability, the passport *system* 25 |
Each linked group has its own page, [Vehicle passport](/regulatory/vehicles) covers the separate regime for vehicles, and [Acts and standards](/regulatory/acts-and-standards) lists every act the code relies on.
diff --git a/site/dpp-docs/src/content/docs/regulatory/toys.mdx b/site/dpp-docs/src/content/docs/regulatory/toys.mdx
index 6f4df34..c62de5f 100644
--- a/site/dpp-docs/src/content/docs/regulatory/toys.mdx
+++ b/site/dpp-docs/src/content/docs/regulatory/toys.mdx
@@ -4,13 +4,14 @@ description: What the Toy Safety Regulation (EU) 2025/2509 requires of a toy pas
---
import { Aside } from "@astrojs/starlight/components";
+import PassportDate from "../../../components/PassportDate.astro";
The Toy Safety Regulation (EU) 2025/2509 creates a passport for every toy placed on the EU market. Its date is set by the Regulation itself, not by a later act.
## When
- **In force** since 1 January 2026. Articles 28 to 44 and 49 to 55 already apply, including the Commission's power to set the passport's technical requirements (Art. 49).
-- **The passport applies from 1 August 2030**, when the rest of the Regulation applies (Art. 59).
+- **The passport applies from **, when the rest of the Regulation applies (Art. 59).
- Toys placed on the market under the Toy Safety Directive 2009/48/EC before that date may still be made available afterwards (Art. 57(1)).
## What it requires
diff --git a/site/dpp-docs/src/data/instruments/battery-reg-2023-1542.json b/site/dpp-docs/src/data/instruments/battery-reg-2023-1542.json
new file mode 100644
index 0000000..ac94b95
--- /dev/null
+++ b/site/dpp-docs/src/data/instruments/battery-reg-2023-1542.json
@@ -0,0 +1,27 @@
+{
+ "id": "battery-reg-2023-1542",
+ "title": "Batteries Regulation (EU) 2023/1542",
+ "celex": "32023R1542",
+ "kind": "direct",
+ "status": "adopted",
+ "currency": { "state": "consolidated", "asOf": "02023R1542-20260813", "checkedOn": "2026-09-11" },
+ "passport": {
+ "obligation": "required",
+ "from": { "date": "2027-02-18", "basis": "sourced" }
+ },
+ "retentionYears": 10,
+ "retentionYearsBasis": "assumed",
+ "productGroups": [
+ {
+ "productGroup": "battery",
+ "status": "in_force",
+ "legalBasis": [
+ "Regulation (EU) 2023/1542 Art. 77(1)",
+ "Regulation (EU) 2023/1542 Art. 9",
+ "Regulation (EU) 2025/1561"
+ ],
+ "notes": "In force and determinable today even though the passport is future-dated: the Art. 9 mercury and cadmium prohibitions have applied since 2008, carried forward from Directive 2006/66/EC. Scope of the passport obligation is EV, LMT and industrial batteries over 2 kWh. Reg. (EU) 2025/1561 moved the Art. 48(1) due-diligence trigger to 2027-08-18 and the Art. 48(5) Commission guidelines deadline to 2026-07-26. Major obligations remain future-dated: Art. 10(2) minimum performance values from 2027-08-18, Art. 8(1) recycled-content declaration from 2028-08-18, Art. 8(2) minimum shares from 2031-08-18. retentionYears is assumed, not sourced: the Regulation's 10-year figures are documentation retention — technical documentation, EU declaration of conformity, audit reports — not passport availability, which sits with Art. 77 and the unadopted Art. 77(9) implementing act."
+ }
+ ],
+ "notes": "The clearest case for separating instrument status from binding status, and passport date from determinability: the act is adopted, its obligations bind now, and its passport is owed from 2027-02-18. retentionYears is assumed, not sourced — the Regulation's 10-year figures are documentation retention (technical documentation, EU declaration of conformity, audit reports), not passport availability, which sits with Art. 77 and the unadopted Art. 77(9) implementing act. Granularity is deliberately unset: the EU registry treats batteries as item-level, but that is the registry's operational position from its user guide, not a level fixed by an adopted act."
+}
diff --git a/site/dpp-docs/src/data/instruments/cpr-2024-3110.json b/site/dpp-docs/src/data/instruments/cpr-2024-3110.json
new file mode 100644
index 0000000..eb2df53
--- /dev/null
+++ b/site/dpp-docs/src/data/instruments/cpr-2024-3110.json
@@ -0,0 +1,20 @@
+{
+ "id": "cpr-2024-3110",
+ "title": "Construction Products Regulation (EU) 2024/3110",
+ "celex": "32024R3110",
+ "kind": "direct",
+ "status": "adopted",
+ "currency": { "state": "inForce", "checkedOn": "2026-09-11" },
+ "passport": { "obligation": "required" },
+ "productGroups": [
+ {
+ "productGroup": "construction",
+ "status": "provisional",
+ "legalBasis": ["Regulation (EU) 2024/3110 Art. 75"],
+ "retentionYears": 10,
+ "retentionYearsBasis": "sourced",
+ "notes": "retentionYears is sourced: the Regulation imposes 10 years on the economic operator. In force since 2025-01-07 and applicable in stages from 2026-01-08, but the per-product duty depends on harmonised technical specifications plus delegated and implementing acts, so nothing is determinable. The 18 months is Art. 22(7), counted from the delegated act that sets up the passport system; the expectation that the system is in place in principle by end 2027 is secondary-sourced, and no delegated act exists, which is why the instrument carries no passport date. WRONG AXIS, to be re-homed: the CPR uses 'product group' zero times and defines product family, then product category, then product type, with its own Annex VII family list. This binding keeps the existing catalog key so nothing breaks; re-homing it is a later step and needs CPR Annex VII read first."
+ }
+ ],
+ "notes": "A real passport instrument, unlike the electronics pair — Art. 75 creates a construction DPP outright. Its first expected product families are rebar, cement, doors and windows with their hardware, and thermal insulation, of which our existing product-category list carries only cement. The passport is undated because the text dates it against an act that does not exist yet. Art. 22(7): 'By 18 months after the entry into force of the delegated act referred to in Article 75(1) the manufacturer shall make available a digital product passport referred to in Article 76'. Art. 75(1) leaves that delegated act, which sets up the construction DPP system, to the Commission, and none has been adopted. Once it is, the date is its entry into force plus 18 months, sourced from both articles. Two dates that are not the passport date. 8 January 2026 is Art. 96's general application date: Arts. 75 and 76 apply from that day, but Art. 22(7) is what says when a manufacturer owes a passport, and it points past Art. 96; this record carried 2026-01-08 as a sourced passport date until that was found. And 8 January 2027 is Art. 96's date for Art. 92, which is Penalties."
+}
diff --git a/site/dpp-docs/src/data/instruments/detergents-2026-405.json b/site/dpp-docs/src/data/instruments/detergents-2026-405.json
new file mode 100644
index 0000000..4d7f0c3
--- /dev/null
+++ b/site/dpp-docs/src/data/instruments/detergents-2026-405.json
@@ -0,0 +1,23 @@
+{
+ "id": "detergents-2026-405",
+ "title": "Detergents Regulation (EU) 2026/405",
+ "celex": "32026R0405",
+ "kind": "direct",
+ "status": "adopted",
+ "currency": { "state": "inForce", "checkedOn": "2026-09-11" },
+ "passport": {
+ "obligation": "required",
+ "from": { "date": "2029-09-23", "basis": "sourced" }
+ },
+ "productGroups": [
+ {
+ "productGroup": "detergent",
+ "status": "provisional",
+ "legalBasis": ["Regulation (EU) 2026/405"],
+ "retentionYears": 10,
+ "retentionYearsBasis": "sourced",
+ "notes": "Adopted 2026-02-11, published in the OJ 2026-03-02. Nothing determinable yet. retentionYears is sourced: the Regulation requires 10 years after placing on the market, including in cases of insolvency."
+ }
+ ],
+ "notes": "Two things worth keeping straight. First, the passport date is sourced: Art. 21(1), 'Before placing a detergent or end-user surfactant on the market, the manufacturer shall create a digital product passport for that product', applies from 23 September 2029 under Art. 37, which excepts only Art. 4(3) and (4). Two limits the date does not show. Art. 36(2) lets detergents and surfactants that comply with Regulation (EC) No 648/2004 be placed on the market until 22 September 2030 and made available until 23 September 2030, so the first year is a transition. And Art. 21(10) leaves the passport's technical requirements to an implementing act whose date of application may not be earlier than 18 months after its entry into force, except where the act sets an earlier date in duly justified cases relating to the whole act or certain provisions of it, or on its partial repeal or amendment, so an act that enters into force after 23 March 2028 cannot apply by the passport date unless it invokes one of those exceptions. Second, detergents is a direct instrument, not an ESPR delegated act — it appears in the ESPR Art. 18 statutory priority list but was NOT selected into the 2025-2030 working plan, so no ESPR act is coming for it and this Regulation is the whole of its passport obligation. Consequential difference from every other instrument here: under this Regulation the passport replaces the EU declaration of conformity as the primary means of demonstrating compliance, so a defective passport costs an operator its conformity route rather than one disclosure among several."
+}
diff --git a/site/dpp-docs/src/data/instruments/ecodesign-energy-labelling-mobile.json b/site/dpp-docs/src/data/instruments/ecodesign-energy-labelling-mobile.json
new file mode 100644
index 0000000..2fe991c
--- /dev/null
+++ b/site/dpp-docs/src/data/instruments/ecodesign-energy-labelling-mobile.json
@@ -0,0 +1,27 @@
+{
+ "id": "ecodesign-energy-labelling-mobile",
+ "title": "Ecodesign and energy labelling for smartphones, mobile phones and tablets — Regulations (EU) 2023/1670 and 2023/1669",
+ "celex": "32023R1670",
+ "kind": "adjacent",
+ "status": "adopted",
+ "currency": { "state": "consolidated", "asOf": "02023R1670-20250620", "checkedOn": "2026-09-11" },
+ "passport": {
+ "obligation": "displacedBy",
+ "system": "EPREL",
+ "basis": "ESPR Art. 9(4)(b)"
+ },
+ "productGroups": [
+ {
+ "productGroup": "electronics",
+ "status": "in_force",
+ "legalBasis": [
+ "Regulation (EU) 2023/1670 Art. 1(1)",
+ "Regulation (EU) 2023/1669"
+ ],
+ "retentionYears": 10,
+ "retentionYearsBasis": "assumed",
+ "notes": "retentionYears is assumed: neither Regulation has been checked for a retention figure, and since neither imposes a passport there may be no such figure to find. Binding since 2025-06-20 for smartphones, other mobile phones, cordless phones and slate tablets — repairability class A-E, durability, seven-year spare parts, OS updates. Those obligations are real and determinable. What does not exist is a passport obligation: neither Regulation contains the phrase 'digital product passport', and their information mechanism is EPREL."
+ }
+ ],
+ "notes": "The record that the previous model could not hold. Its predecessor entry carried status in_force together with dppAppliesFrom 2025-06-20 — but 2025-06-20 is Reg. 2023/1670's *ecodesign* application date under Directive 2009/125/EC, relabelled as a passport date, and no passport obligation exists to date. Because in_force was the gate for binding determinations, a node could assert compliance against an obligation that is not there. Here the two facts are recorded separately and both stay true: the binding is in_force, and the passport is displaced. ESPR Art. 9(4)(b) lets the Commission exempt a product group where other Union law provides an equivalent digital system, and the 2025-2030 working plan states the position in terms: every product covered by ecodesign measures will have a passport 'except if there is an alternative digital system providing equivalent information, for example the EPREL database'. EPREL is the alternative to a passport, not a form of one, and we do not model it."
+}
diff --git a/site/dpp-docs/src/data/instruments/elv-2026-1738.json b/site/dpp-docs/src/data/instruments/elv-2026-1738.json
new file mode 100644
index 0000000..5648fb7
--- /dev/null
+++ b/site/dpp-docs/src/data/instruments/elv-2026-1738.json
@@ -0,0 +1,14 @@
+{
+ "id": "elv-2026-1738",
+ "title": "End-of-Life Vehicles Regulation (EU) 2026/1738",
+ "celex": "32026R1738",
+ "kind": "direct",
+ "status": "adopted",
+ "currency": { "state": "inForce", "checkedOn": "2026-09-11" },
+ "passport": {
+ "obligation": "required",
+ "from": { "date": "2032-09-01", "basis": "sourced" }
+ },
+ "productGroups": [],
+ "notes": "Recorded with no bindings, deliberately: the act exists and creates a Digital Circularity Vehicle Passport, and we hold no vehicle product group to bind it to. An instrument that reaches nothing we model is still worth holding — it is how the catalog stops the act being rediscovered as new, and it is the shape a horizontal act takes before its groups are known. Full requirements cover passenger cars and light commercial vans, with a reduced end-of-life-treatment set for heavy-duty vehicles, motorcycles and special-purpose vehicles. The passport date is now sourced, read from the OJ text: Art. 13(1) — 'From 1 September 2032, each vehicle placed on the market shall have a Digital Circularity Vehicle Passport'. An earlier secondary source gave 'two years after entry into force', i.e. around August 2028; that is the Regulation's general application date under Art. 59(2) and not the passport date, which is four years later. The manifest previously recorded no date at all rather than an unsourced one, which was the right call. Note also that 'digital product passport' appears zero times in this Regulation — the Digital Circularity Vehicle Passport is a differently-named instrument, not an ESPR DPP, though Art. 13(1) requires it to be aligned and interoperable with the Art. 77 battery passport and with passports established under Regulation (EU) 2024/1781. This Regulation amends four acts, not two: its title names Regulations (EU) No 168/2013, (EU) 2018/858, (EU) 2019/1020 and (EU) 2023/1542 — Art. 53 amends the Batteries Regulation (applies 13 Aug 2026), Art. 54 amends 2019/1020 (applies 1 Sep 2028), Art. 55 amends 2018/858 and 168/2013 (applies 1 Sep 2032). Scope is staged if a vehicle group is ever modelled: Art. 2(1) takes M1 and N1 first, special-purpose M1/N1 from 1 Sep 2029, and M2, M3, N2, N3, O and L-category from 1 Sep 2031. Note the relationship with ESPR: Art. 1(2)(h) excludes vehicles only in respect of aspects already regulated by sector-specific acts, so the exclusion is partial and aspect-scoped, and this Regulation is the automotive passport route."
+}
diff --git a/site/dpp-docs/src/data/instruments/espr-horizontal-eee-recyclability.json b/site/dpp-docs/src/data/instruments/espr-horizontal-eee-recyclability.json
new file mode 100644
index 0000000..59c95ed
--- /dev/null
+++ b/site/dpp-docs/src/data/instruments/espr-horizontal-eee-recyclability.json
@@ -0,0 +1,17 @@
+{
+ "id": "espr-horizontal-eee-recyclability",
+ "title": "ESPR horizontal requirements on recycled content and recyclability of electrical and electronic equipment",
+ "kind": "delegated",
+ "status": "anticipated",
+ "parent": "espr",
+ "passport": { "obligation": "required" },
+ "productGroups": [
+ {
+ "productGroup": "lmt",
+ "status": "provisional",
+ "legalBasis": [],
+ "notes": "Light means of transport — monowheels, e-scooters, e-bikes and e-mopeds up to L2e under Regulation (EU) 168/2013. Source is the JRC priorities study's recyclability coverage table, which is a preparatory technical study, NOT law and not a Commission position by its own disclaimer. Recorded because it is the case this catalog exists to represent, not because it binds anything: the study states that the horizontal requirements' product sets include product groups that were never shortlisted as candidates for priority action, naming LMT. There is no product-group manifest for this key and there may never be one."
+ }
+ ],
+ "notes": "The second horizontal act from the 2025-2030 working plan, anticipated with no adoption year stated. It carries the binding that proves the model: a product group reached by an act while having no manifest, no schema and no place on any priority list. Nothing derives from a product group here — the reach is recorded on the act, which is the only place it can be written down. Every value is provisional or anticipated and none of it may be presented as sourced."
+}
diff --git a/site/dpp-docs/src/data/instruments/espr-horizontal-repairability.json b/site/dpp-docs/src/data/instruments/espr-horizontal-repairability.json
new file mode 100644
index 0000000..5e6e279
--- /dev/null
+++ b/site/dpp-docs/src/data/instruments/espr-horizontal-repairability.json
@@ -0,0 +1,10 @@
+{
+ "id": "espr-horizontal-repairability",
+ "title": "ESPR horizontal requirements on repairability, including a repairability score",
+ "kind": "delegated",
+ "status": "anticipated",
+ "parent": "espr",
+ "passport": { "obligation": "required" },
+ "productGroups": [],
+ "notes": "One of the two horizontal acts the 2025-2030 working plan selects, with indicative adoption years of 2027 and 2029. Anticipated, so no CELEX and no text: nothing derived from it may be presented as sourced. Recorded with NO product groups on purpose. The working plan says its scope 'could include products such as consumer electronics and small household appliances' and is 'to be refined during the preparatory study' — that is a candidate scope, and binding a product group to it would be exactly the class of invention this catalog exists to prevent. The passport obligation follows from ESPR Art. 9(1) applying to products covered by ecodesign measures rather than from any text of this act; it is undated, and every future binding will be provisional until the act is adopted."
+}
diff --git a/site/dpp-docs/src/data/instruments/espr.json b/site/dpp-docs/src/data/instruments/espr.json
new file mode 100644
index 0000000..59de9b6
--- /dev/null
+++ b/site/dpp-docs/src/data/instruments/espr.json
@@ -0,0 +1,61 @@
+{
+ "id": "espr",
+ "title": "Ecodesign for Sustainable Products Regulation (EU) 2024/1781",
+ "celex": "32024R1781",
+ "kind": "framework",
+ "status": "adopted",
+ "currency": { "state": "consolidated", "asOf": "02024R1781-20240628", "checkedOn": "2026-09-11" },
+ "passport": { "obligation": "required" },
+ "retentionYears": 10,
+ "retentionYearsBasis": "assumed",
+ "productGroups": [
+ {
+ "productGroup": "textile",
+ "status": "provisional",
+ "legalBasis": ["Regulation (EU) 2024/1781 Art. 18"],
+ "notes": "Art. 18 statutory priority list ('textiles, in particular garments and footwear'); selected as a final product in the 2025-2030 working plan with an indicative delegated-act adoption year of 2027. No delegated act exists, so nothing is determinable and no CN range is knowable."
+ },
+ {
+ "productGroup": "furniture",
+ "status": "provisional",
+ "legalBasis": ["Regulation (EU) 2024/1781 Art. 18"],
+ "notes": "Art. 18 lists 'furniture, including mattresses'; the working plan then selects Furniture and Mattresses separately, with different rankings and indicative adoption years of 2028 and 2029 respectively. Mattresses is bound separately below and must not be carried as a category here."
+ },
+ {
+ "productGroup": "mattress",
+ "status": "provisional",
+ "legalBasis": ["Regulation (EU) 2024/1781 Art. 18"],
+ "notes": "Selected in the 2025-2030 working plan as a final product distinct from Furniture, ranked fourth among final products, indicative adoption 2029. The Regulation groups it under furniture and the working plan splits it out — which is why product group cannot be a fixed taxonomy: the grouping changed between the framework and its own working plan."
+ },
+ {
+ "productGroup": "tyre",
+ "status": "provisional",
+ "legalBasis": ["Regulation (EU) 2024/1781 Art. 18"],
+ "notes": "Art. 18 priority list; working plan final product, indicative adoption 2027. Already regulated in part by the Tyre Labelling Regulation (EU) 2020/740, which is a labelling instrument and not a passport one."
+ },
+ {
+ "productGroup": "steel",
+ "status": "provisional",
+ "legalBasis": ["Regulation (EU) 2024/1781 Art. 18"],
+ "notes": "Art. 18 'iron and steel'; working plan intermediate product, ranked first, indicative adoption 2026. The JRC priorities study indicates a scope of CN chapters 72 and 73 — an indication from a preparatory study, not a legal scope: ESPR Art. 8(a) puts the commodity codes in the delegated act, and none exists."
+ },
+ {
+ "productGroup": "aluminium",
+ "status": "provisional",
+ "legalBasis": ["Regulation (EU) 2024/1781 Art. 18"],
+ "notes": "Art. 18 priority list; working plan intermediate product, indicative adoption 2027. Intermediate products may have their delegated acts reach final products containing them, which is one of the ways one product accumulates several instruments."
+ },
+ {
+ "productGroup": "unsold-goods",
+ "status": "in_force",
+ "legalBasis": [
+ "Regulation (EU) 2024/1781 Art. 24",
+ "Regulation (EU) 2024/1781 Art. 25",
+ "Regulation (EU) 2024/1781 Annex VII"
+ ],
+ "passport": { "obligation": "notRequired" },
+ "notes": "Binding today and determinable: the Art. 25(1) destruction prohibition for Annex VII goods has applied since 2026-07-19, and the Art. 24 disclosure duty is live for large operators, with medium-sized operators brought in from 2030-07-19 and micro and small enterprises exempt. There is no passport anywhere in Arts. 24-25 — the subject is an operator over a financial year, disclosed on its own website, not a product placed on the market. This is why the obligation binds while requiring no passport: the two questions are separate and this binding answers them differently. The 2026-07-19 date is the destruction ban's, and it must never be recorded as a passport date."
+ }
+ ],
+ "notes": "The framework itself. Art. 9(1) requires 'a digital product passport ... in accordance with the applicable delegated acts' — singular passport, plural acts — so the obligation is real but undated until a delegated act fixes it. Art. 5(7) lets one act cover many product groups and lets a group-specific act supplement a horizontal one, and no precedence rule exists anywhere in the Regulation: overlapping acts accumulate. retentionYears is assumed, not sourced, and applies to every group below: Art. 9(2)(i) sets no figure — it requires availability for at least the expected lifetime of the product, delegated per product group, and no delegated act has been adopted for any of them. As of 2026-08-24 that is true of every ESPR product group without exception."
+}
diff --git a/site/dpp-docs/src/data/instruments/ppwr-2025-40.json b/site/dpp-docs/src/data/instruments/ppwr-2025-40.json
new file mode 100644
index 0000000..810b485
--- /dev/null
+++ b/site/dpp-docs/src/data/instruments/ppwr-2025-40.json
@@ -0,0 +1,11 @@
+{
+ "id": "ppwr-2025-40",
+ "title": "Packaging and Packaging Waste Regulation (EU) 2025/40",
+ "celex": "32025R0040",
+ "kind": "adjacent",
+ "status": "adopted",
+ "currency": { "state": "inForce", "checkedOn": "2026-09-11" },
+ "passport": { "obligation": "notRequired" },
+ "productGroups": [],
+ "notes": "Held as a record specifically so it is not mistaken for a passport instrument again. The word 'passport' appears twice in the entire Regulation and both occurrences point outward: where the packaged product is covered by Regulation (EU) 2024/1781 or other Union law requiring a digital product passport, THAT passport should also carry the information required here. So there is no packaging passport, and a packaging product group would have nothing to dispatch on — no passport, no schema derived from law, no determination possible. What the Regulation does require is labelling, and a QR code or other standardised open data carrier on reusable packaging carrying re-use system and trip data, which is a data-carrier obligation. A trade-press claim that this created a packaging passport from 2028-08-12 was recorded once and refuted by reading the primary text. Deliberately unbound and parked pending a decision to revisit."
+}
diff --git a/site/dpp-docs/src/data/instruments/toy-safety-2025-2509.json b/site/dpp-docs/src/data/instruments/toy-safety-2025-2509.json
new file mode 100644
index 0000000..e75b44e
--- /dev/null
+++ b/site/dpp-docs/src/data/instruments/toy-safety-2025-2509.json
@@ -0,0 +1,23 @@
+{
+ "id": "toy-safety-2025-2509",
+ "title": "Toy Safety Regulation (EU) 2025/2509",
+ "celex": "32025R2509",
+ "kind": "direct",
+ "status": "adopted",
+ "currency": { "state": "inForce", "checkedOn": "2026-09-11" },
+ "passport": {
+ "obligation": "required",
+ "from": { "date": "2030-08-01", "basis": "sourced" }
+ },
+ "retentionYears": 10,
+ "retentionYearsBasis": "sourced",
+ "productGroups": [
+ {
+ "productGroup": "toy",
+ "status": "provisional",
+ "legalBasis": ["Regulation (EU) 2025/2509"],
+ "notes": "retentionYears is sourced: the Regulation requires 10 years after placing on the market, including in cases of insolvency. Adopted 2025-12-12 and in force since 2026-01-01, but fully applicable only from 2030-08-01 after a 54-month transition, so nothing is bindingly determinable yet. The implementing acts defining the technical and procedural passport requirements are not published, so a conformant toy data carrier cannot be generated today."
+ }
+ ],
+ "notes": "A direct instrument with a firm passport date, which is rarer than it looks — most of the catalog is undated. Its identifier-sharing provision is one of the two proofs that a product bears one passport however many instruments apply: the unique product identifier, operator identifier and registration identifier 'shall be the same' as those used under other Union law."
+}
diff --git a/site/dpp-docs/src/data/instruments/unsold-goods-derogations-2026-296.json b/site/dpp-docs/src/data/instruments/unsold-goods-derogations-2026-296.json
new file mode 100644
index 0000000..c3ea921
--- /dev/null
+++ b/site/dpp-docs/src/data/instruments/unsold-goods-derogations-2026-296.json
@@ -0,0 +1,25 @@
+{
+ "id": "unsold-goods-derogations-2026-296",
+ "title": "Derogations from the prohibition of destruction of unsold consumer products — Commission Delegated Regulation (EU) 2026/296",
+ "celex": "32026R0296",
+ "kind": "delegated",
+ "status": "adopted",
+ "currency": { "state": "inForce", "checkedOn": "2026-09-11" },
+ "parent": "espr",
+ "passport": { "obligation": "notRequired" },
+ "retentionYears": 5,
+ "retentionYearsBasis": "sourced",
+ "productGroups": [
+ {
+ "productGroup": "unsold-goods",
+ "status": "in_force",
+ "legalBasis": [
+ "Commission Delegated Regulation (EU) 2026/296 Art. 2",
+ "Commission Delegated Regulation (EU) 2026/296 Art. 3",
+ "Regulation (EU) 2024/1781 Art. 25(5)"
+ ],
+ "notes": "Adopted 2026-02-09, OJ 2026-04-22. Art. 2 is a CLOSED list of ten derogations, points (a) to (j), under which an Annex VII good may lawfully be destroyed. Point (h) — offered for donation and not accepted — is subordinate: it applies 'only where none of the circumstances referred to in points (a) to (g) are applicable', which is a condition over the whole set of reasons claimed for a category and cannot be checked on one line alone. Impl. Reg. (EU) 2026/2 Annex I note (h) makes this list the reason vocabulary of the disclosure, so the two acts interlock."
+ }
+ ],
+ "notes": "retentionYears is sourced and is NOT a passport retention figure: Art. 3 requires the economic operator to keep per-derogation documentation for five years after destruction, in electronic form, and produce it to a competent authority within 30 days of a request. It is evidence of a lawful destruction, not availability of a product record, and must not be folded into a passport availability period. Neither this act nor its implementing sibling creates a passport."
+}
diff --git a/site/dpp-docs/src/data/instruments/unsold-goods-format-2026-2.json b/site/dpp-docs/src/data/instruments/unsold-goods-format-2026-2.json
new file mode 100644
index 0000000..0aeed34
--- /dev/null
+++ b/site/dpp-docs/src/data/instruments/unsold-goods-format-2026-2.json
@@ -0,0 +1,24 @@
+{
+ "id": "unsold-goods-format-2026-2",
+ "title": "Format for the disclosure of information on discarded unsold consumer products — Commission Implementing Regulation (EU) 2026/2",
+ "celex": "32026R0002",
+ "kind": "implementing",
+ "status": "adopted",
+ "currency": { "state": "inForce", "checkedOn": "2026-09-11" },
+ "parent": "espr",
+ "passport": { "obligation": "notRequired" },
+ "productGroups": [
+ {
+ "productGroup": "unsold-goods",
+ "status": "in_force",
+ "legalBasis": [
+ "Commission Implementing Regulation (EU) 2026/2 Art. 2(1)",
+ "Commission Implementing Regulation (EU) 2026/2 Art. 3",
+ "Commission Implementing Regulation (EU) 2026/2 Annex I",
+ "Regulation (EU) 2024/1781 Art. 24(3)"
+ ],
+ "notes": "Adopted 2026-02-09, OJ 2026-02-10. Creates no duty of its own — it prescribes the format of the disclosure ESPR Art. 24 already requires, which is why it is an implementing act and carries no passport obligation. Art. 2(1) binds the visual presentation and content to Annex I. Art. 3 delimits categories on the first two digits of the CN code, except for the products of its Annex II, which take four. Art. 1 scopes the duty to each financial year from the first full financial year after the date of application, disclosed within 12 months of that year's end; Art. 2(2) lets an operator publishing sustainability reporting under Directive 2013/34/EU Arts. 19a or 29a link to it instead of disclosing on its website directly. Annex I note (h) points the reason vocabulary at the derogations of the delegated act under Art. 25(5), which is Del. Reg. (EU) 2026/296 — the two acts interlock and neither is complete alone."
+ }
+ ],
+ "notes": "Scope worth keeping straight: this implements Art. 24's DISCLOSURE duty, which reaches discarded unsold consumer products generally, and is therefore much wider than Art. 25's destruction prohibition over the Annex VII goods. Its own Annex II runs to 45 CN headings from soap and tyres to refrigerators and toys, none of which are in ESPR Annex VII. Treating Annex VII as the scope of the disclosure drops every category outside apparel and footwear from a report required to carry them."
+}
diff --git a/site/dpp-docs/src/lib/acts.ts b/site/dpp-docs/src/lib/acts.ts
new file mode 100644
index 0000000..97b4d04
--- /dev/null
+++ b/site/dpp-docs/src/lib/acts.ts
@@ -0,0 +1,37 @@
+// acts.ts — passport dates, read from the instrument records vendored from
+// dpp-core (site/dpp-landing/core-source.json pins the commit; check:core holds
+// this copy to it).
+//
+// A regulatory page writes instead of a date, so the
+// docs, the landing site and the software cannot disagree about one. An act
+// with no passport date the core records as read from the text fails the build:
+// a blank or guessed date on a regulatory page is worse than no page.
+type Instrument = {
+ id: string;
+ passport: { obligation: string; from?: { date: string; basis: 'sourced' | 'assumed' } };
+};
+
+const modules = import.meta.glob('../data/instruments/*.json', { eager: true });
+const byId = new Map(
+ Object.values(modules).map((m: any) => {
+ const i = (m.default ?? m) as Instrument;
+ return [i.id, i];
+ }),
+);
+
+const LONG = ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'];
+// Spelled out rather than left to Intl, whose en-GB short form for September
+// is "Sept" in current ICU data and "Sep" in older.
+const SHORT = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'];
+
+/** "18 February 2027", or "18 Feb 2027" in tables. */
+export function passportDate(act: string, form: 'long' | 'short' = 'long'): string {
+ const instrument = byId.get(act);
+ if (!instrument) throw new Error(`PassportDate: no vendored instrument "${act}".`);
+ const from = instrument.passport.from;
+ if (!from || from.basis !== 'sourced') {
+ throw new Error(`PassportDate: "${act}" records no passport date read from the text.`);
+ }
+ const [year, month, day] = from.date.split('-').map(Number);
+ return `${day} ${(form === 'short' ? SHORT : LONG)[month - 1]} ${year}`;
+}
diff --git a/site/dpp-landing/core-source.json b/site/dpp-landing/core-source.json
index e50d85b..a47fcf2 100644
--- a/site/dpp-landing/core-source.json
+++ b/site/dpp-landing/core-source.json
@@ -11,7 +11,12 @@
"instruments": {
"path": "crates/dpp-domain/instruments",
"dest": "src/data/instruments",
- "_note": "The legal acts, as typed records: CELEX id, status, passport obligation and date with its basis, and the product groups each act reaches. The only source of any regulatory date on the /regulations pages."
+ "_note": "The legal acts, as typed records: CELEX id, status, passport obligation and date with its basis, and the product groups each act reaches. The only source of any passport date on this site."
+ },
+ "instruments-for-docs": {
+ "path": "crates/dpp-domain/instruments",
+ "dest": "../dpp-docs/src/data/instruments",
+ "_note": "The same acts for docs.odal-node.io, where renders every passport date from them. A copy inside the docs folder, so a pin bump changes files the docs deploy watches. Both copies come from this one commit, and check:core fails if either drifts."
}
}
}
diff --git a/site/dpp-landing/src/data/faq.json b/site/dpp-landing/src/data/faq.json
index cd5eee1..12357ed 100644
--- a/site/dpp-landing/src/data/faq.json
+++ b/site/dpp-landing/src/data/faq.json
@@ -15,7 +15,7 @@
{
"q": "Do my products need one, and from when?",
"a": [
- "It depends on the product group. Electric-vehicle, light-transport and larger industrial batteries need one from 18 February 2027, detergents from 23 September 2029 and toys from 1 August 2030. New vehicles need their own vehicle passport from 1 September 2032. Most other product groups get their date from a Commission act that has not been adopted yet.",
+ "It depends on the product group. Electric-vehicle, light-transport and larger industrial batteries need one from {passport:battery-reg-2023-1542}, detergents from {passport:detergents-2026-405} and toys from {passport:toy-safety-2025-2509}. New vehicles need their own vehicle passport from {passport:elv-2026-1738}. Most other product groups get their date from a Commission act that has not been adopted yet.",
"The regulations page lists every act the software tracks and where each date comes from. It is a summary, not legal advice."
],
"link": { "href": "/regulations", "label": "See every act and its date" }
diff --git a/site/dpp-landing/src/data/glossary.json b/site/dpp-landing/src/data/glossary.json
index acb5bf9..c581af6 100644
--- a/site/dpp-landing/src/data/glossary.json
+++ b/site/dpp-landing/src/data/glossary.json
@@ -18,7 +18,7 @@
},
{
"term": "Battery passport",
- "definition": "The passport the Batteries Regulation requires from 18 February 2027 for electric-vehicle batteries, light-transport batteries and industrial batteries over 2 kWh.",
+ "definition": "The passport the Batteries Regulation requires from {passport:battery-reg-2023-1542} for electric-vehicle batteries, light-transport batteries and industrial batteries over 2 kWh.",
"link": { "href": "/regulations/battery-reg-2023-1542", "label": "The Batteries Regulation" }
},
{
diff --git a/site/dpp-landing/src/lib/regulations.ts b/site/dpp-landing/src/lib/regulations.ts
index cb0079c..0fafc21 100644
--- a/site/dpp-landing/src/lib/regulations.ts
+++ b/site/dpp-landing/src/lib/regulations.ts
@@ -107,6 +107,36 @@ export const formatDate = (iso: string) =>
timeZone: "UTC",
});
+/**
+ * The date an act's passport becomes mandatory, as the core records it from the
+ * act's text: "18 February 2027", or "February 2027". Pages write this instead
+ * of a date. An act with no such date fails the build, so a page cannot print a
+ * blank or a stale one.
+ */
+export function passportDateOf(id: string, form: "day" | "month" = "day"): string {
+ const act = byId.get(id);
+ if (!act) throw new Error(`passportDateOf: no vendored instrument "${id}".`);
+ const from = act.passport.obligation === "required" ? act.passport.from : undefined;
+ if (!from || from.basis !== "sourced") {
+ throw new Error(`passportDateOf: "${id}" records no passport date read from the text.`);
+ }
+ const day = formatDate(from.date);
+ return form === "month" ? day.replace(/^\d+ /, "") : day;
+}
+
+/**
+ * Copy in src/data writes `{passport:}` or `{passport-month:}` where a
+ * passport date goes; this fills it from passportDateOf. A token it cannot read
+ * fails the build rather than reaching the page.
+ */
+export function withPassportDates(text: string): string {
+ const filled = text.replace(/\{passport(-month)?:([a-z0-9-]+)\}/g, (_, month, id) =>
+ passportDateOf(id, month ? "month" : "day"),
+ );
+ if (filled.includes("{passport")) throw new Error(`withPassportDates: unreadable token in "${text}"`);
+ return filled;
+}
+
// ── the passport line ────────────────────────────────────────────────────────
export type PassportView = {
diff --git a/site/dpp-landing/src/pages/example-passport.astro b/site/dpp-landing/src/pages/example-passport.astro
index 1491548..a451325 100644
--- a/site/dpp-landing/src/pages/example-passport.astro
+++ b/site/dpp-landing/src/pages/example-passport.astro
@@ -6,6 +6,7 @@ import Base from "../layouts/Base.astro";
import Section from "../components/Section.astro";
import { fieldLabel } from "../lib/product-groups";
import { buckets, flat, isObj, scalar, shown } from "../lib/example-passport";
+import { passportDateOf } from "../lib/regulations";
const title = "Example battery passport | Odal Node";
const description =
@@ -49,7 +50,7 @@ const SECTIONS = [
signed, sorted the way a node shows it to each reader.
- Some public values are placeholders. For passports from February 2027,
+ Some public values are placeholders. For passports from {passportDateOf("battery-reg-2023-1542", "month")},
the Commission's guidance says to leave the carbon footprint and the
shares of recycled cobalt, lithium, nickel and lead empty until the rules
for calculating and showing them apply. The software still asks for
diff --git a/site/dpp-landing/src/pages/faq.astro b/site/dpp-landing/src/pages/faq.astro
index 9cbb8ad..f34b811 100644
--- a/site/dpp-landing/src/pages/faq.astro
+++ b/site/dpp-landing/src/pages/faq.astro
@@ -10,10 +10,14 @@ import Base from "../layouts/Base.astro";
import Section from "../components/Section.astro";
import ExternalArrow from "../components/ExternalArrow.astro";
import faq from "../data/faq.json";
+import { withPassportDates } from "../lib/regulations";
type Item = { q: string; a: string[]; link?: { href: string; label: string } };
type Group = { title: string; items: Item[] };
-const groups = faq.groups as Group[];
+const groups = (faq.groups as Group[]).map((g) => ({
+ ...g,
+ items: g.items.map((it) => ({ ...it, a: it.a.map(withPassportDates) })),
+}));
const title = "FAQ: Digital Product Passports and Odal Node | Odal Node";
const description =
diff --git a/site/dpp-landing/src/pages/glossary.astro b/site/dpp-landing/src/pages/glossary.astro
index 79fa7a2..ece7070 100644
--- a/site/dpp-landing/src/pages/glossary.astro
+++ b/site/dpp-landing/src/pages/glossary.astro
@@ -6,9 +6,10 @@ import Base from "../layouts/Base.astro";
import Section from "../components/Section.astro";
import ExternalArrow from "../components/ExternalArrow.astro";
import glossary from "../data/glossary.json";
+import { withPassportDates } from "../lib/regulations";
type Term = { term: string; definition: string; link?: { href: string; label: string } };
-const terms = glossary.terms as Term[];
+const terms = (glossary.terms as Term[]).map((t) => ({ ...t, definition: withPassportDates(t.definition) }));
const title = "Glossary: Digital Product Passport terms | Odal Node";
const description =
diff --git a/site/dpp-landing/src/pages/lifecycle.astro b/site/dpp-landing/src/pages/lifecycle.astro
index 3b0146c..4024fec 100644
--- a/site/dpp-landing/src/pages/lifecycle.astro
+++ b/site/dpp-landing/src/pages/lifecycle.astro
@@ -9,6 +9,7 @@
import Base from "../layouts/Base.astro";
import Section from "../components/Section.astro";
import stations from "../data/stations.json";
+import { passportDateOf } from "../lib/regulations";
const title = "Lifecycle: one passport, eight stations | Odal Node";
const description =
@@ -81,7 +82,7 @@ const afterSale = stations.stations.filter((s) => s.n >= 6);
All eight stations exist in the software today. Nobody is running
it in production: no customers, no pilots, no live deployments.
- The battery passport obligation begins on 18 February 2027, and we would
+ The battery passport obligation begins on {passportDateOf("battery-reg-2023-1542")}, and we would
rather be correct when it arrives than early and wrong.
diff --git a/site/dpp-landing/src/pages/repairers-and-recyclers.astro b/site/dpp-landing/src/pages/repairers-and-recyclers.astro
index dde9f2b..3461167 100644
--- a/site/dpp-landing/src/pages/repairers-and-recyclers.astro
+++ b/site/dpp-landing/src/pages/repairers-and-recyclers.astro
@@ -13,6 +13,7 @@ import Base from "../layouts/Base.astro";
import Section from "../components/Section.astro";
import Button from "../components/Button.astro";
import access from "../data/access.json";
+import { passportDateOf } from "../lib/regulations";
const title = "For repairers and recyclers: reading a Digital Product Passport | Odal Node";
const description =
@@ -36,7 +37,7 @@ const mailto = `mailto:contact@odal-node.io?subject=${encodeURIComponent("Readin
This page covers the battery passport, the first one the law requires,
- from 18 February 2027. For other product groups, no act sets these
+ from {passportDateOf("battery-reg-2023-1542")}. For other product groups, no act sets these
access rights yet.
diff --git a/site/dpp-landing/src/pages/roadmap.astro b/site/dpp-landing/src/pages/roadmap.astro
index 45b4c84..d5809c2 100644
--- a/site/dpp-landing/src/pages/roadmap.astro
+++ b/site/dpp-landing/src/pages/roadmap.astro
@@ -10,6 +10,7 @@
import Base from "../layouts/Base.astro";
import Section from "../components/Section.astro";
import OurRoadmap from "../components/Roadmap.astro";
+import { passportDateOf } from "../lib/regulations";
const title = "Roadmap: what is built, waiting and next | Odal Node";
const description =
@@ -24,7 +25,7 @@ const description =
Nobody is running this in production. No customers, no
pilots, no live deployments, and nothing below should be read as evidence
- of any. The battery passport obligation begins on 18 February 2027, and we
+ of any. The battery passport obligation begins on {passportDateOf("battery-reg-2023-1542")}, and we
would rather be correct when it arrives than early and wrong.
diff --git a/site/dpp-landing/src/pages/timeline.astro b/site/dpp-landing/src/pages/timeline.astro
index 1a2195e..3aa29f8 100644
--- a/site/dpp-landing/src/pages/timeline.astro
+++ b/site/dpp-landing/src/pages/timeline.astro
@@ -8,7 +8,7 @@ import Base from "../layouts/Base.astro";
import Section from "../components/Section.astro";
import BasisMark from "../components/BasisMark.astro";
import { years, undated, planSource } from "../lib/timeline";
-import { basisLabel, formatDate } from "../lib/regulations";
+import { basisLabel, formatDate, passportDateOf } from "../lib/regulations";
const title = "Timeline: when Digital Product Passports arrive | Odal Node";
const description =
@@ -26,7 +26,7 @@ const marked = years.some(({ year, entries }) => year === thisYear && entries.so
- Batteries come first, in February 2027. Detergents, toys and vehicles
+ Batteries come first, in {passportDateOf("battery-reg-2023-1542", "month")}. Detergents, toys and vehicles
follow on dates their own laws set, and the Commission plans acts for more
product groups, each of which will set its own passport date.