# Plego Spring newsletter, change record

Current build: **v6, 3 September 2026**. Confirm what is live at
`https://news.myvermeiren.com/plegospring/version.json` before sending anything to a country.

Every email file carries its build in the comment at the top, and every copy deck on line two.

If a country has already pasted an earlier build into Mailchimp, it has to be replaced. The copy
changed in v5, so anything older carries wrong specification text. Netherlands and Belgium should
take the Dutch file again from v6, which is the 900px version.

## Pack revision, 30 October 2026

_the eight email files are unchanged. This is the day out post, the Poland notice and the AI
disclosure_

**The day out post is live in all eight markets.** The coastal promenade card is now a post like
any other: its eyebrow and headline are translated into the eight languages, a country can type
over them, and the three formats download. It was rebuilt for this, in Montserrat, with a textless
plate per format, so the page draws the copy and never touches the picture.

**The city post was dropped** in the same decision, and stays a preview.

**Why only one of the two.** Both frames were checked against the hand cut studio plates first,
and neither showed the real chair. Both put a mark on the upper link where the real product carries
none, SPRING on the promenade and illegible lettering on the city, and the drive wheel, the pivot
disc, the controller and the footplate differed as well. The finding, with the crops it is based
on, is in `Social/_verify-2026-10-30/`, and it is repeated in every sidecar of the card and on the
post in the handover page, where a country reads it before scheduling. The card is a campaign
picture and not a product reference, and the page says so in those words.

**A correction to that check, made the same day.** It first reported that the generated frames drew
the PLEGO mark wrongly, filling in the O where the real one is an open ring. At higher magnification
the real mark is a gold ring with a **dark** centre, which is exactly what the frames show. The
PLEGO mark is reproduced correctly and that line was wrong; it is corrected in the verification, in
the sidecars and here. The SPRING decal on the upper link is the real discrepancy and it stands.

## The city post, same day, on a new frame

Carlos generated four new frames in Higgsfield on 30 October and picked the plaza for post 09, so
**the city post is live in all eight markets too**, built the same way as the day out one: its own
crop per format, textless plates, eight translations, the disclosure in the language of the post.

The new frames are a long way closer to the real product than the September set: the drive wheel,
the hub, the six bolt circle and the PLEGO mark all match the studio plates now. **The SPRING decal
on the upper link does not**, and this is the fourth generation in a row to carry it, across two
tools and two months, including runs whose prompt ordered the model to keep the marks identical to
the reference. Either every generator is inheriting it from the reveal video, which carries the
same invention, or the production chair has a decal the March studio shoot did not show. That is a
question for engineering or the Marketing Database, and it is the one open point on both cards.

**The crop on the city square was lifted three hundredths**, from 0.560 to 0.535, because at 0.560
the SPRING half of the PLEGO lockup crossed the rider's hair. A square crop of a 3:4 frame uses the
full width, so there is no horizontal room to move her, and the kit's framing rule says to move the
copy rather than crop tighter. Moving the lockup down to sit with the copy was tried and is worse:
it lands on the front wheel. Lifting the crop clears her head, keeps the whole chair in the picture
and leaves the lockup where it is on every other card in the campaign. The same value is used for
all three formats, so the post is one crop and not three. The renderer keeps a `wordmark_pos`
setting for a frame where no crop can clear that corner; nothing uses it today.

**Nothing in the post rail is a preview any anymore.** The callout above the rail now says what the
two generated pictures are rather than why they cannot be used, and the car boot option, which was
never rendered on the page, stays out of it.

**The AI disclosure is now in the language of the post.** It used to be one English line burned
into the artwork for everybody. It is still not a field, there is no switch and nothing a market
types reaches it: the page looks the line up from the market it is set to and prints it on the
strip under the picture. It is one line that does not wrap, so the type steps down to fit, which
French and Italian both need. The English is still burned into the master that ships in the pack.

**The Poland notice is a black plate with white type.** Vermeiren changed it on 21 September, and
`pl_legal.py` was updated the same day; nothing downstream followed, so until now the 32 Poland
files in the pack were still the white plate of 9 September and the handover page still drew white.
All **35** Poland files are re-rendered, the page matches the renderer, and both carry the colours
in the sidecar so the next batch is checkable rather than re-measurable. The height rule, the type
size, the line break and the centring are untouched: only the two colours changed. Every file was
verified again, 10.00% of the surface or better and flatness 0.997 or better.

On a Poland day out card the two notices stack and read as what they each are: the picture, then
the white strip with the AI disclosure in Polish, then the black bar with the medical device
sentence.

**A plate can now pin the top of the band as well as the bottom.** On a studio card the copy sits
on flat white, so a short translation setting itself larger than the English costs nothing. On the
situational card it sits on a scrim shaped for one cap, and type that grows climbs out of the dark
into pale sky. The plate carries `capMaxPx` for that, the page honours it where it is there, and
`check_lang.py` solves the same way. All eight markets land on the same cap as the English on this
card, so nothing moves today; the ceiling is there for the wording that has not been written yet.

Tests: **116 of 116**.

## Handover page revision, 17 September 2026

_the eight email files are unchanged, this is the social text in all eight languages_

**The campaign ships translated.** Every eyebrow, every headline and every caption is now in all
eight languages in the pack and in the page, so a market opens its own words rather than the
English. Eight people were otherwise going to do the same job at different times, and the first one
to do it would have had nothing to check it against.

The terminology is not new writing. It is lifted from the newsletter copy for that market, which is
the same approved draft the email ships, so the two channels cannot drift apart: *fauteuil roulant
electrique*, *Elektrorollstuhl*, *wozek inwalidzki elektryczny*, and the same for the suspension.
**Plego Spring is never translated**, in any string, in any language.

**Three states, and the page keeps them apart.** *Master* is the English the card was built with
and it stays under every field. *Supplied* is our translation, the default for that market.
*Own* is what the country typed, and it is the only one that counts as an edit, so the pip in the
market rail still means somebody here wrote this rather than this is not English. Reset puts the
supplied translation back, not the English. Every field says which of the three you are looking at.

Three things a native reader notices immediately, and which are handled rather than left to chance:

* **The product's gender differs by language.** Masculine in French, Dutch, German and Polish,
  feminine in Italian and Spanish, so the family cards read *Le plus leger* against *La piu
  leggera*. Switzerland is the odd one out: the Swiss newsletter treats the name itself as neuter,
  *das Plego Spring*, so its family cards read *Das leichteste*.
* **Swiss German has no sharp s.** Germany gets *Strasse* with the sharp s, Switzerland without it,
  which is what the newsletter already does.
* **Accents are real characters here.** The eight email files ship as pure ASCII with numeric
  entities, because a mail server can mangle a charset. These strings are drawn onto a canvas
  instead, so they carry their own accents, Polish included.

**A longer translation costs type size, so it is measured rather than discovered.** The band is
fixed by the plate and the page steps the cap down to fit, which is what stops a carousel jumping
on the swipe. `check_lang.py` solves every string the way the page does and reports the cap against
the English on the same plate, so wording that would shrink a card is caught while it is still
wording. Two were, and were tightened: the Italian *Potenza su entrambe le ruote* and the French
*Se plie en quelques secondes* each cost a fifth of the type size and now do not. One card is
accepted as it is and says so in the checker: no language matches the three one syllable words of
*Fold. Roll. Go.*, and the rhythm is worth more than the cap.

It also measures the headline against the index number in the bottom right corner, which sits on
the headline's own row on the carousel cards. The English master is already tight there, so the
test is an absolute floor rather than a comparison with the English, and nothing overlaps.

**`social/text/`, eight sheets.** The same strings as plain text, one file per market, with the
English under each line. For reviewing a translation in a mail or beside the newsletter copy rather
than on screen. They are written from the same file the page reads, so the two cannot drift.

## Handover page revision, 9 September 2026

_the eight email files are unchanged, this is the social channel, the Poland notice and the face_

**The social card text is now the market's own.** A country cannot translate a headline that is
baked into a JPEG, so the renderer writes each card twice: once finished, for the pack, and once
**with no copy on it at all**, beside the numbers that placed the copy. The page draws the eyebrow
and the headline onto that textless plate, in the market's words, and hands back a finished JPEG.
Social follows the eight language chips now, where before it was English only.

The split is because of the shadow. It is not drawn: it is the darker part of the original studio
frame, composited back under the isolated product with a Multiply pass, the way Carlos does it in
Photoshop. A browser re-rendering the product would lose it. A browser drawing only type cannot
touch it. `social/r2/shadow_check.py` now measures the penumbra population of the product zone on
every card and holds a per file baseline, so a later build that drops a Multiply layer fails
instead of shipping a floating chair. All 32 cards pass, before and after the re-render.

**The band is fixed, the type moves.** The headline band keeps the height the renderer gave it, so
a longer translation steps the type down rather than growing the band and pushing the product. That
is what keeps a carousel from jumping on the swipe, and it means the layout the kit's check measured
does not move when a market edits. The page reproduces the renderer's own wrap, sentence end first
then balanced, so English comes out line for line identical: the test compares the page's line count
and cap against every master sidecar and all nine posts match.

**Poland: every card carries the medical device notice, and no other market carries one.** The bar
is appended below the artwork, never painted over it, because these cards put the headline at the
bottom of the canvas. Its height comes from the surface rule in Dz.U. 2023 poz. 817: `bar >= H / 9`,
and the floor is used, so 120px on a square, 150 on the portrait, 134 on a 1200 carousel card and
214 on the story. Every card in a carousel gets its own. Both numbers were verified on all 32
files rather than assumed: 10.00% of the surface or better, flatness 0.997 or better against the
kit's 0.97 floor, measured with the glyphs masked out (counting white pixels naively reports 0.88
and reads as a failure, because the type is legitimately dark). The set is in `social/poland/` and
the page adds it automatically on the Polski chip.

**The face is Montserrat Medium.** It was Futura Medium, because a Mac system Futura happened to be
reachable in the build folder. That could not continue once the page had to draw type in a browser:
embedding an Apple system font is redistributing it. Montserrat is the closest freely available
match to the brand sans, carries the Polish diacritics the notice needs, and is already the face the
newsletter and the Altima social build settled on. Medium and not SemiBold: SemiBold reads visibly
heavier at a 54px cap and the reveal headline goes from airy to crowding its own margin. Python and
the browser now use the same file off the same cap height maths. The previous set is kept in
`social/_futura/` so the decision is reversible.

**The banner channel is down to three.** Carlos took the sage, the amber and the deep navy campaign
banners out, leaving the signature pair and 1d airy. They are **not deleted from the drive**: the
exports and `Plego Spring Signature.psd` are untouched in `Plego Spring/Mail banner/`, and any of
them comes back with one entry in `_build/banners.py` and a rerun. `mkbanners.py` now copies only
the banners that are in the channel, rather than everything in the source folder, because a folder
is a list too and a country will use what is in front of it: leaving three withdrawn banners in
`banners/` would have undone the decision. The test checks the page carries no trace of them, by
name and by filename.

That left the campaign family in an odd place, since the two that went were the two with clean copy
and the one left was the one flagged, so **1d was corrected the same day** and all three banners are
now usable.

**Banner 1d, corrected.** It had no PLEGO SPRING lockup at all, only a `NEW - THE FAMILY GROWS`
pill repeating the headline underneath it, so on its own it did not say which product it was about;
and its sub line joined its halves with a long dash. The lockup is now on it at the same 60px ink
height and position 1a and 1b used, and the dash is a comma.

There is **no layered file** for the campaign banners, only the flattened exports, so the correction
was made on the export, in one specific way: **nothing photographic was touched.** The product and
the shadow it was photographed with come through byte for byte, and only the left hand text column
was rebuilt. The field there is a purely horizontal gradient, so it was reconstructed exactly by
sampling one clean row above every element, rather than cloned or healed. `mkbanner1d.py` prints the
maximum channel difference in the untouched half and it is 0.

Two things that fell out of it. The **whole text column** was re-set rather than only the sub line,
because one line in a new face under a headline in the old one reads as a mistake, and the headline
takes Bold: measured at a 48px cap the original's stems are 11 to 12px, where Montserrat Medium
gives 7. And the **button moved right**, from x858 to x1150, because Montserrat is a wider face and
the same sub line at the same cap runs 983px instead of 707, which would have put "comfort every
mile." under the button. Shrinking the line to fit would have meant a 16px cap; the banner is 2176
wide with 570px of empty field between the text and the product, so sliding the button cost nothing.

The pre-correction exports are kept in the source folder as `-uncorrected.jpg` and are filtered out
of the pack, where a country would read them as another option.

**The interface follows the Altima handover.** Montserrat and Hanken Grotesk, the green and amber
palette, the market rail with a state pip per market, and the social channel rebuilt as a post rail
into a single post view: the card on a canvas, the swipe strip when a post has more than one card,
the fields beside it with the English master under each one, the measured numbers under the card,
a review sheet, and a download.

Three things worth knowing for next time:

* **`mkplates.py` runs before `mkpage.py`**, and `mkbanners.py` before both. The page inlines what
  they write. The plates are 3.3 MB and take the page to 5.2 MB, which is the cost of the download
  being the real file rather than a preview.
* **The card text has to be measured in the real face or every line breaks in the wrong place.** The
  build sandbox cannot reach Google Fonts, so `test_page.py` registers the local Montserrat files
  under the same family before the page runs. Without that the layout comparison is meaningless.
* **A page that draws its own file cannot hand it over with a link.** The artifact viewer's sandbox
  makes `<a download>` inert, blob URLs included, so the download goes through the `downloads`
  capability with the canvas blob.

## Handover page revision, 8 September 2026

_the eight email files are unchanged, this is the page and the pack folder_

**All four channels are now on the handover page, and in one folder.** Carlos asked for one place to
hand over: banners, newsletter, WhatsApp message, and the social pack with every post. That is what
the page and this folder now are.

**Banners, new channel.** Six banners from `Plego Spring/Mail banner/`, in two families:

* the **signature pair**, 2a dark and 2c light, 22 July, masters 1920 x 364 and 1924 x 368, exports
  at 540, 560 and 600. Their copy already matches the reference: "Front fork suspension for a
  smoother ride." on 2a, no hyphen. **2c has no 600px export**: the source file named `2c-600px` is
  the 1924px master, which is why the card says so rather than the page linking a wrong size;
* the **campaign banners**, 1a to 1d, 8 July, masters 2176 x 412, exports at 600. **1b and 1c are
  clean. 1a and 1d are not**: 1a reads "front-fork" with a hyphen, against the v6 wording that the
  email, the WhatsApp template and every social card were corrected to, and 1d joins its sub line
  with a long dash and carries no PLEGO SPRING lockup at all. Neither is fixable in a flattened
  JPEG, so both are flagged on their card with the exact pass they need. Same discipline as the
  pending social cards: nothing ships quietly with superseded copy.

The page builds the **Outlook signature HTML** per banner and per width. It takes the market page
from step 3, so the country sets one link and the email, the WhatsApp button and the banner all
follow it. The banner image prefix is derived from the email image prefix rather than typed twice, so
a country that rehosts the images does not end up with banners pointing at the old server.

The per language banner table under the cards is **not a new translation**: every string in it is
that language's own newsletter copy. PLEGO SPRING is never translated and never set upright.

**Social, now the whole pack rather than a preview.** Each of the nine posts lists every file it
ships in, by name, with the folder it is in. 40 files across the nine, and the split is stated: **32
cleared in `social/`, 8 not cleared in `social/pending/`**. The post 05 AI option is listed under
the pending folder as well, not beside the cleared files, because that is where it is.

**The folder is the pack.** `banners/` and `social/` join `images/` and `whatsapp/` and the eight
language folders, and `banners/BANNERS.md` and `social/README.md` say what is in each and what is
not ready. `index.html` and `README.md` describe four channels. The image URLs did not move, so
nothing that was already published breaks.

`test_page.py` goes from 46 checks to 60. The new ones cover the six banner cards, that only the two
that need a pass are flagged, that the snippet carries the market link and a real export at its
stated size and width and height attributes that match it, that changing the width changes all three,
that the per language table covers eight languages with its accents intact, and that every generated
social file is listed under the pending folder and none under the cleared one.

Two things caught in the process, both worth knowing:

* `mkbanners.py` has to run **before** `mkpage.py`, because the page inlines the previews it writes.
  The rebuild list in `README.md` is in that order now.
* Playwright's `inner_text` applies `text-transform`, so a test that counted an uppercased label
  found nothing. Read `textContent` when a CSS transform is in play.

## v6, 3 September 2026

_current, send this one_

**The Dutch newsletter is now 900px wide.** Every other language stays on the 680px design artboard.
Dutch has the longest headline and the longest card bodies of the eight, and 900px is the room it
needed. Everything inside is derived from the container, so nothing was stretched by hand:

* **The white card behind the hero is gone.** The product photograph is flattened onto the same
  `#F5F5F3` as the band it sits on, and its cell carries that colour too, so there is no white
  square any more. This one applies to all eight languages, not only Dutch.
* Gutter 60px, content width 780px. The four benefit cards are 318px each, the three family cards
  244px each.
* Display type back to the full size, 58 / 42 / 30. Dutch had been stepped down to 50 / 36 / 26 only
  because the copy did not fit the narrower container.
* The family card bodies drop from a measured 174px to 124px, because the wider card wraps the same
  copy in fewer lines. That is what closed the empty gap under the Dutch card text.
* The hero shows at 520px and the suspension photograph at 390px, both from new 2x files
  (`plego-hero-spring-wide.jpg`, `plego-suspension-wide.jpg`). Seventeen hosted images now, 692 KB.
  Each email loads only the files its own width uses.
* Centred copy keeps a readable measure rather than filling the width: intro 620px, section titles
  600px, family intro 580px, the dark panel body 620px.
* The mobile breakpoint for Dutch moves to 920px so a desktop client shows the desktop layout.
  Verified no horizontal overflow from 320px to 1400px, in all eight languages.

**The other seven files change only in the build stamp and the hero background.** The hero fix is
visible, so every country should take its file again from v6.

## Handover page revision, 8 September 2026

_the eight email files are unchanged, nothing to re-paste in Mailchimp_

* **The handover now holds all three channels.** A social media section sits below the WhatsApp
  steps: nine posts in the order the plan runs them, each with its finished artwork, an editable
  caption, a field for the day it goes out and one for who posts it. The key features post and the
  range post show their carousel cards together, so a carousel reads as one post rather than as
  loose squares.
* Social is **English only, from the group account**, so that section does not change with the
  language chips. The newsletter and the WhatsApp template still do.
* **Two of the nine are marked NOT READY TO SCHEDULE**, in amber, with the reason on the card.
  They are built on AI generated frames with the product in them, they carry the EU AI Act
  disclosure line, and the brand kit does not allow them to ship until the product plate fidelity
  check has been run against the real studio photograph and a named approver has signed it. They
  are in the handover so a country can see the whole plan, not so it can schedule them.
* Undo my edits now also resets the social captions and clears the dates.

## Handover page, same date

_page and WhatsApp only, no change to the email layout beyond v6 above_

* The internal list of build corrections is off the page. It was never meant for the countries and it
  lives here in this record instead.
* Keep my work now works on the hosted copy. It used to offer Save for the team and then report that
  saving was not available, because republishing the shared page only works from the Claude link. The
  hosted copy keeps your edits in your own browser instead, so they are still there when you come
  back, and the button says which of the two it is doing.
* Undo my edits clears that browser copy as well, so one click really does put the original back.
* The English WhatsApp body said electric wheelchairs and front-fork suspension. It now says powered
  wheelchairs and front fork suspension, the same as the email. Resubmit the EN template if it was
  already sent for approval. The other seven languages were already correct, they use their own
  local term.

## v5, 2 September 2026

_superseded by v6_

* Spec strip tile 2 now reads 2 x 250 W over Dual motors. It used to read 500 W over 2 x 250 W motors, which was the old text.
* English is back to powered wheelchair and front fork suspension. A previous pass had changed these to electric and front-fork from an older design file.
* The word Spring is set in italic wherever it appears in running copy, the way the wordmark sets it.
* Standard features fill row-wise, so the left column is items 1, 3, 5, 7, 9 and the right column is 2, 4, 6, 8, 10.
* The hero product sits on a white card inside the grey band.
* The hosted handover page now carries its own charset, which is what was turning the French accents into mojibake.
* Undo my edits on the handover page also resets the image prefix.

## v4, 1 September 2026, evening

_superseded_

* Newsletter widened from 600px to 680px with a 54px gutter, the design artboard 1:1, so every column has the room the design intended.
* The handover page previews desktop only, the phone toggle was removed.
* Three overflow bugs fixed that the wider layout exposed: the spec strip, the card grids and the feature image each had a fixed width with no mobile release.

## v3, 1 September 2026, afternoon

_superseded_

* Every product photo recut from the approved design assets. The hero and the three family shots had come from a different photo series.
* Photographs re-encoded as JPEG quality 90 instead of 256 colour PNG, which was banding the tyre and the frame.
* Images repointed at news.myvermeiren.com, so nothing needs uploading to Mailchimp Content Studio.
* WhatsApp campaign added: a header image and a template per language, with the Polish medical device notice in both the message and the image.
* Cards in a row now end level, the suspension crop was recomposed, family card rules aligned.
* Soft hyphens added per language so long German compounds stop breaking the layout.

## v2, 1 September 2026, morning

_superseded_

* Images given hosted URLs. Every src had pointed at a relative path, so nothing rendered in any email client.
* Bulletproof buttons added. Both calls to action had been plain styled anchors, invisible as buttons in Outlook.
* Vermeiren Group postal address added to the footer, required on a commercial mailing.
* Polish medical device notice added above the footer in the PL version.
* Outlook scaling fix, preheader fix, duplicate check marks removed from the standard features list, copyright moved to 2026.

## v1, 31 August 2026

_the original eight language zip_

* First delivery.
