Decisions log
2026-08-02 — Migration into the skill-suite structure (phase-1 test run)
- This project predates the current website-builder suite: the repo root IS the old flat site
(index.html, styles.css, script.js) deployed to silvia-jayet-reflexologie-preview.pages.dev.
- Decision: adopt the suite structure alongside the legacy files (content/, brand/, build/,
deploy/ added; legacy files untouched at root so the existing preview deploy keeps working).
The future site/ build will replace the root deploy at publish time.
- No Google Places entry exists → GBP setup kit generated (deploy/gbp-setup.md) instead of a dossier;
identity.md curated from the site itself + its source files.
- Category: reflexology (manual — no Places types available). Single-page layout kept as a
deliberate deviation from the spec sitemap for now (see category-mapping.md).
- Brand DNA: extracted from the preview site (extracted-palette.json, computed styles, screenshots).
The site publishes its tokens as CSS custom properties — adopted as the basis for design-tokens.json.
- Distinctiveness note: the current palette/pairing (cream + sage, Cormorant Garamond + Inter) is
close to the suite's known convergence style. Kept faithful in v1 tokens (source-site fidelity);
the styleguide flags the terracotta + deep-green pill CTA as the distinctive anchors and lists
review options for Pat at the styleguide gate.
2026-08-02 — Styleguide gate: v2 "sharpened" identity proposed
- Pat: no fixed identity exists yet — agent to propose one for the practice.
- Proposal: keep Silvia's palette and calm structure; promote terracotta to lead accent,
demote sage to details, body font Inter → Karla; deep-green pill CTA and Cormorant stay.
- Tokens bumped to 2.0.0; styleguide updated; v2 preview deployed for review (see deploy/cloudflare.md).
- Fonts to be self-hosted at build time (nDSG — legal-pages.md).
2026-08-02 — Phase 2 draft-first: full draft site live on v2
- Copy deck migrated mechanically from the old site's i18n dictionaries (fidelity guaranteed;
minor copy fixes: FR reflexP1/history typos cleaned, t1 price display normalized to EN pattern).
- Astro build on tokens v2: single-page FR at /, EN at /en/, legal pages both locales,
HealthAndBeautyBusiness schema (hours carried from the old site's own schema — to confirm),
llms.txt, self-hosted fonts, hreflang, sitemap. check-tokens: 0 violations.
- Draft markers: photos + legal entity as [TBD:]; ribbon bottom-left after a nav-collision fix.
- /_styleguide/ + /dossier/ preserved on the deployed site.
2026-08-02 — Suite v0.9.0 applied (specs 121–126)
- /dossier/ transparency surface: regenerated from TODO/identity/decisions on every build,
linked from the draft ribbon; mechanically removed at DRAFT=false (preflight-enforced).
- Branded OG image (og.png, from tokens) + twitter card; bilingual branded 404.
- Whole project folder now in the private repo (pajai/silvia-jayet-reflexologie);
legacy flat site moved to content/sources/legacy-site/ (its deploy untouched, rule 118).
2026-08-02 — Dossier v2: working-copy surface (suite spec 127)
- All 16 project docs published under the obfuscated /dossier-a74c98/ (kits, copy deck, notes),
cross-linked; TODO items carry stable [T1..T30] IDs; answer box (mailto to Pat until a
Web3Forms key exists). Reply pattern: "T4 done, T2: …" → agent edits files → rebuild.
2026-08-10 — Content pass: testimonials, hero photo, trigger points, disclaimer
- Testimonials section added to home (both locales), two quotes (Éleonore, Victoria) — [T28].
Consent is NOT yet on file for either; tracked in content/reviews.md, blocker before go-live.
- Hero placeholder replaced with a real photo of Silvia (content/assets/photos/silvia-hero.jpg),
served via astro:assets → responsive webp (56–289 kB vs 337 kB original). Casual outdoor
shot, kept deliberately after review. placeholderNature → heroPhotoAlt; placeholderStream
still [TBD:], so T24 stays open.
- triggerText rewritten (points gâchette / douleurs projetées) in both decks; EN translated
to match. Earlier edit had landed in content/sources/ (an extraction archive) — reverted
there; sources/ is a snapshot and is never hand-edited.
- Medical disclaimer removed from indicationsLead in both locales (was "Sans jamais remplacer
un suivi médical," / "Without ever replacing medical care,") — Silvia's call, 2026-08-10.
reflexP2 still carries "ne remplace pas un suivi médical" in both locales; left in place.
If Silvia registers with ASCA/RME, recheck their advertising wording rules against this.
2026-08-10 — Silvia's fact answers (T1–T10) + naming/pricing decisions
- Silvia answered the full facts list via Pat; facts recorded in content/identity.md, TODO T1–T9
closed, T10 partially (hero done; cabinet photos not possible for now → deferred).
- Pricing presentation (Pat): CHF 70 framed as "offre de lancement" with CHF 110 visible as the
regular price — expectation management for when the offer ends. Silvia ties the offer's end to
ASCA recognition, so no printed end date ("valable jusqu'à nouvel avis"); removal trigger
moved into T29. Note: Silvia's own wording could read as "all sessions CHF 70"; Pat decided to
keep the launch-offer framing.
- Display name (Pat, after Silvia asked what it means): "Réflexologie Silvia Jayet" —
service-first French convention, é accent kept, must be identical on GBP / header / signage /
impressum. Header currently "Silvia Jayet — Réflexologie · Lausanne" → align (T19.7).
- Impressum: Silvia has no legal structure → raison individuelle. Text: "Réflexologie Silvia
Jayet · Silvia Jayet, Chemin de Bérée 22b, 1010 Lausanne". "Entreprise individuelle" label
dropped as implied (Pat) — the visible personal name + address satisfy the requirement.
- ASCA/RME: not yet; no insurance reimbursement — site continues to claim nothing.
- Copy-deck application of all of the above: consolidated 9-point list under T19, owner Alexia,
folds into T23 (rebuild + preview recheck).
2026-08-10 — T19 applied: Silvia's facts into both copy decks
- Hours 14:30–18:30 in
metaHours+contactHoursValue(both locales) and in the
HealthAndBeautyBusiness schema (was Tu-Fr 13:00-19:30, inherited from the old site).
- TWINT added wherever payment is stated —
treatmentsFine,policy1,faq6A(T19 named only
treatmentsFine; the other two would have contradicted it).
- New contact keys:
contactLanguagesLabel/Value(FR/EN/DE/SP) andcontactAccessNote
(wheelchair access possible but difficult) — rendered in the contact list.
- Offer reframed "réouverture" → "lancement" across offer section, treatments lead and the
banner; reopening date 01.09.2026 and "valable jusqu'à nouvel avis" in offerSubtitle;
no printed end date per Silvia. CHF 110 already visible as the regular price.
- Display name "Réflexologie Silvia Jayet" (T8) now single-sourced from
SITE_NAMEin
config.mjs → header, meta titles, schema name, legal-page titles, impressum, privacy.
brandTag demoted to "Réflexologie thérapeutique · Lausanne" to avoid repeating the name.
- Impressum + privacy legal-entity
[TBD:]filled in both locales (raison individuelle, no
UID line — Silvia is not in the commercial register, T9). Privacy still has two open
[TBD:]: e-mail retention period and go-live date — neither is decided yet.
- Certifications aligned with Silvia's own wording: "Réflexologie thérapeutique · Certificat B2",
"The Bayly School of Reflexology" (was "École Bayly"), "Ecovie Sàrl" (was "Ecovie").
- Fixed along the way: EN
expectLeadclaimed a one-hour first appointment, contradicting the
confirmed ~1h30 with anamnesis; footer note still announced placeholder imagery.
2026-08-10 — Image licence cleared + privacy retention decided
nature-stones.jpgswapped for a licensed image of the same subject and identical dimensions
(1280×717), so the 16/9 crop and layout are unchanged. Licence confirmed held by Alexia — [T31]
closed. The licence reference itself is not recorded; SOURCES.md flags that gap.
- E-mail retention set to 12 months (Alexia). Enquiries to a reflexology practice can reveal
health concerns, i.e. sensitive personal data under nDSG art. 5 — a stated, bounded retention
is the point, and 12 months is short enough to be defensible while covering a season of
follow-up. What matters now is that the mailbox is actually emptied on that cadence.
- Privacy "Dernière mise à jour" set to 2026-08-10. It is the notice's revision date, not the
go-live date — the [TBD:] label misnamed it. Bump it whenever the privacy text changes;
it does not need to wait for publication. No [TBD:] left anywhere in the copy deck.
2026-08-10 — aiwww.ch webcheck (84/100) → round-1 fixes [T32]
Scores: Tempo 98, Cookies 100, Links 100, Technik 88, Recht 88, Google 89 — top finding
("noindex") is our deliberate draft setting; ribbon contrast + sitemap findings likewise
draft artifacts that resolve at go-live.
- Checker false positives (verified against deployed HTML): (1) "structured data lacks business
info" — the JSON-LD already carries name/address/phone/hours/priceRange; checker apparently
only recognizes literal LocalBusiness/Organization, not the valid HealthAndBeautyBusiness
subtype. Kept the more specific type. (2) "privacy unspecific" — deck already names hosting,
logs, retention, contact; checker hit the pre-deploy cache. → both worth reporting to Martin.
- Implemented: tap targets ≥44px on .text-link / contact & footer links / lang-switch /
skip-link / faq summary via padding-block + negative margin (hit area grows, layout pixel-
identical — verified 48–51px in browser, typography unchanged); public/_headers with HSTS,
X-Frame-Options SAMEORIGIN, Permissions-Policy, nosniff, referrer-policy and 1-year immutable
caching for hashed /_astro/* assets; FAQ questions now real <h3> inside <summary> (font:
inherit → identical look) + FAQPage JSON-LD from the same deck strings (schema.mjs policy:
FAQs are visible page text).
- Deliberately NOT done: CSP (info-only site, zero external scripts; revisit with forms),
e-mail obfuscation (moot once T17 brings a domain address), SPF/DMARC/DNSSEC/CAA (impossible
on pages.dev — folded into T17/T26 go-live checklist).
2026-08-10 — Suite spec 162 ported: brand favicon
- The favicon fix (suite 943c4c9, spec 162 — motivated by this very site's blank tab icon)
ported by re-syncing site/scripts/generate-tokens.mjs from the starter template (only diff).
- tokens meta.brand updated "Silvia Jayet Réflexologie" → "Réflexologie Silvia Jayet" (T8:
name identical everywhere); favicon generates as "R" in Cormorant on primary #2a302a.
- File carries the generated-from-design-tokens marker — dropping in a real logo mark later
is safe (the tokens step never touches a file without the marker).
2026-08-11 — Kit drift fixed + suite spec 165 (fact-propagation sweep)
- Pat noticed the dossier's GBP tutorial still showed pre-answer facts. Root cause: deploy kits
are generated once and never regenerate on build — Silvia's T1–T10 answers reached decks and
schema (T19) but not the kits. Swept: gbp-setup.md + listings-kit.md now carry hours
14:30–18:30, espèces/TWINT, FR/EN/DE/ES, wheelchair attribute «non», opening 01.09.2026,
launch-offer wording, and the T8 name (also fixed in README/TODO/styleguide titles).
- Suite fix (spec 165, v0.13.1): fact answers are now an explicit change-request type with a
mandatory propagation sweep; publish-preflight warns on leftover intake markers in deploy/*.md.
2026-08-11 — Logo integrated (header lockup + favicon)
- The real artwork is
brand/logo-adasil-source.png(1254², green tree of life in a circle,
"adasil" in script). brand/logo-adasil-sketch.svg — blobby circles + Cormorant text — is a
rough sketch of the same idea, NOT the logo; kept only for reference, nothing renders it.
- Source was white-backed with no alpha.
brand/logo-adasil.pngis the working master:
white knocked out to alpha with a soft ramp (>=246 fully clear, 200–246 ramped, so the
anti-aliased edges leave no halo on the cream header) and trimmed to content (737×882).
- The lockup is vertical and its wordmark is ~9% of the height, i.e. ~5px at header size.
So the header uses a horizontal recomposition built from two crops of the master —
site/src/assets/logo-mark.png (circle, 737×796) and logo-word.png (script, 394×72) —
laid out side by side, served through astro:assets as responsive webp (mark 2 kB at 1x).
- Favicon rebuilt from the real mark, embedded as a base64 PNG inside
favicon.svg(28 kB).
Its placeholder marker is deliberately absent so the tokens step no longer rewrites it.
Caution: that generator matches the marker as a plain substring, so the file must not
contain it even inside a comment — a first attempt was silently overwritten that way.
color.logo-greenadded to design-tokens.json as #53772a, measured as the mean of the
opaque pixels of the real artwork. (An earlier #3f6b52 came from the sketch and was wrong.)
It sits outside the existing palette — sage #93a08a, terracotta #8a5e48, ink #2a302a.
- Accessibility: the brand link is labelled with SITE_NAME, the mark is
alt=""(decorative
next to the wordmark) and the wordmark carries alt="adasil".
- Open conflict — see [T33]. The header now reads "adasil" while <title>, schema name,
impressum, privacy and the GBP kit all still read "Réflexologie Silvia Jayet" (T8, Pat,
2026-08-10). SITE_NAME was deliberately NOT changed: renaming would rewrite the impressum's
trading name and the Google listing kits, which is Pat's and Silvia's call, not a styling
change. The site currently presents two brands; that has to be resolved before go-live.
2026-08-11 — Copy pass from Silvia's corrections (via Alexia)
- Applied to both decks. Structural: indications 11 → 13 (torticolis/lombalgies/hernies, and
burnout/dépression), session steps 4 → 5 (integration & possible reactions), "Bon à savoir"
4 → 6 items. Home.astro now maps these lists instead of hard-coding indices, and the steps
grid switched to auto-fit (a fixed repeat(4) stranded the fifth step alone on a row).
- Hours changed to 14:30–19:00 in the decks, the schema and identity.md. Note this
contradicts [T1], where Silvia confirmed 14:30–18:30 through Pat on 2026-08-10. Applied on
Alexia's instruction; Pat should confirm which is right before the GBP is created (T11),
since the kit carries the old figure.
- Italian added to the languages line. [T7] recorded FR/EN/DE/SP as confirmed by Silvia on
2026-08-10; Italian is new and equally needs confirming before it reaches GBP attributes.
- reflexP1 reverted to "les capacités naturelles du corps d'autoguérison" at Silvia's request.
This is the wording the 2026-08-10 pass had corrected (it parses as "the body of
self-healing"); her phrasing wins, noted here so it is not "fixed" again by mistake.
- Wording: banner + offer label "la séance" / "La séance"; mailBtn → "Contact par mail";
footerRole → "Réflexothérapeute"; aboutEyebrow → "Qui suis-je ?"; trigger-points closing
sentence dropped; trustLine and training6 now credit Prana Formation.
- EN deck follows the FR meaning but the translations are the agent's, not Silvia's — worth a
native pass before go-live, especially reflexP1/P2 and the new step 5.
2026-08-12 — Medical disclaimers removed site-wide (Silvia, via Alexia)
- Every "reflexology does not replace medical care" statement is gone from both locales:
reflexP2's closing sentence, the last "Bon à savoir" bullet (policy6), the FAQ answer on
pregnancy/medical follow-up (faq4A), and the italic line on both impressum pages. The
indicationsLead disclaimer had already been dropped on 2026-08-10.
- Reason given: "les gens le savent". The concern was raised twice (2026-08-10 and
2026-08-11) and the instruction was reaffirmed each time — recorded here as the client's
decision, not an oversight.
- What remains, and is not a disclaimer: faq4Q/faq4A still ask clients to flag a pregnancy,
medical follow-up or ongoing treatment when booking, and the "Bon à savoir" list still
asks for the reason for the visit. Those are intake questions, deliberately kept.
- Worth re-examining if Silvia registers with ASCA/RME: their advertising rules generally
expect complementary-therapy wording, and the site now carries none.
2026-08-11 — Kit sweep for the hours correction + Italian
- Alexia's session corrected hours to 14:30–19:00 and added Italian; decks/schema/identity were
updated but the deploy kits drifted again (18:30, no italien). Swept per change-requests.md
fact-propagation rule (suite spec 165); both kits now match identity.md.
2026-08-11 — WhatsApp becomes the primary booking channel
- Pat's decision (options A+B1+C1 from the proposal): every primary CTA (hero, contact section,
sticky mobile bar) is now "Prendre rendez-vous sur WhatsApp" → wa.me/41765457586 with a
locale-specific pre-filled message ("Bonjour, je souhaite prendre rendez-vous…" / EN).
Brand-pill styling with an inline WhatsApp glyph (currentColor — token discipline holds).
- Phone and email stepped down to the contact list (tap-to-call + mailto, WhatsApp listed first);
hero secondary button now anchors to the contact section.
- identity.md booking section + GBP kit swept (description, appointment-link step = wa.me,
enable profile WhatsApp chat). ⚠️ Open: Silvia to confirm the number runs WhatsApp
(WhatsApp Business app suggested).
2026-08-12 — Go-live staged, then paused on the brand conflict (T34)
- Go-live mechanics completed: DRAFT + SITE_URL now env-driven (defaults stay draft-safe),
13 token waivers annotated, draft-ribbon CSS moved behind the DRAFT flag, _redirects
generated, publish-preflight fully green. Production Pages project
silvia-jayet-reflexologie deployed (canonical https://reflexologie.com, 6 routes 200).
- Domain NOT attached — twice blocked: domain-attach needs a scoped API token (wrangler
OAuth insufficient), and Pat filed the adasil-vs-"Réflexologie Silvia Jayet" brand conflict
as a go-live blocker mid-deploy (now [T34]; was a duplicate [T33]). reflexologie.com serves
nothing yet; the staged build is only on the pages.dev URL.
- Resolution paths per T34: (a) header reverts to the T8 name (logo mark only) — small change,
go-live can proceed same day; (b) rename to "adasil" — reopens T8, impressum, GBP/listings
kits, schema, privacy; days not hours.
2026-08-12 — T34 resolved: the brand is "Adasil" — go-live unblocked
- Pat: impressum name becomes Adasil → full consistency sweep so the site doesn't ship two brands:
impressum + privacy ("Adasil · Silvia Jayet, …" — the person stays, an unregistered trade name
alone would not satisfy the impressum identification requirement), SITE_NAME → "Adasil"
(header aria, legal-page headers), schema name, meta titles now "Adasil | Réflexologie
thérapeutique à Lausanne" (descriptive tail keeps the SEO term + her name in content),
GBP + listings kits (NAP name + duplicate-check search links). T8 superseded.
- Kept: "Silvia Jayet" as the human name throughout content, footer copyright, testimonial
context; hero/about copy unchanged (they speak about Silvia, correctly).
2026-08-12 — Post-launch webcheck round (prod scored 89/100)
- Draft-era footer note ("Aperçu — contenu fondé sur les documents fournis") had shipped to
production and failed contrast — now DRAFT-gated (draft surface keeps it). robots.txt Sitemap
line made absolute (https://reflexologie.com/sitemap-index.xml).
- Flagged to Pat (dashboard-side): Cloudflare AI Crawl Control blocks Claude/Gemini/Apple on the
new zone — must be allowed (repo robots.txt already welcomes them); SPF/DMARC/CAA/DNSSEC +
email routing pending; schema sameAs waits on T11–T15 profiles.
2026-08-12 — go-live orchestrator retro-fit (suite spec 182) + www cutover
deploy/production.jsoncreated (domain reflexologie.com, project silvia-jayet-reflexologie,
canonical apex) — the machine-readable production config go-live.mjs runs from.
- www.reflexologie.com cutover completed: the zone import had kept a stale proxied
A www → 94.130.154.187 (Hetzner — Silvia's pre-suite site "Réflexologie Silvia Adamez",
HTTP-only; also explains the "adasil" brand: ADAmez SILvia). domain-attach's safety gate
caught it; record deleted deliberately (rollback: recreate that A record), www attached to
the Pages project — HTTP 525 on www is gone.
- Pending: canonical 301 www→apex as a zone Single Redirect rule — token needs
Zone | Dynamic Redirect | Edit (Pages _redirects cannot match hosts; a briefly-shipped
full-URL _redirects line was removed as ineffective). Until then www serves the site
directly with correct canonical tags — harmless, not ideal.
- DNSSEC verified end-to-end this session: DS live at Joker, chain validates.
2026-08-15 — T35: brand reverted to "Réflexologie Silvia Jayet", header wordmark becomes text
- Pat reversed T34 (2026-08-12, "Adasil"): the practice trades under the practitioner's own
name again — T8's name, restored. The trigger was the header still reading "adasil" in
production while everything the client says about herself carries her name.
- The header lockup no longer uses wordmark artwork.
src/assets/logo-word.pngis unreferenced
(the file is kept, and brand/logo-adasil.png remains its source); the name renders as live
text in --font-headline (Cormorant Garamond), body size on mobile → h3 size at ≥560px, and
wraps to two lines against the mark on very narrow screens. The circular tree mark is
unchanged and still supplies the favicon — the Adasil origin (ADAmez SILvia) leaves the words
but not the mark.
- Renamed with it: SITE_NAME, schema
name(both locales), meta titles, impressum, privacy,
identity.md, gbp-setup.md, listings-kit.md. The legal-page and 404 titles had hardcoded the
name in six places despite the config comment claiming a single source — they now interpolate
SITE_NAME, so the next rename really is one line.
- Meta-title tails changed: "…| Réflexologie thérapeutique à Lausanne" → "…| Réflexologue à
Lausanne" (EN: "…| Reflexologist in Lausanne"). The old tail repeated "Réflexologie" straight
after the new name — bad in a SERP, and the local keyword survives either way. The header
tagline still carries the old wording and still stutters; left as a copy decision (T35 sub-item).
- No external cleanup: no GBP entry and no directory listing was ever created under "Adasil",
so the rename costs nothing outside the repo. Both kits' duplicate checks now search both
names, since a stray entry under the old name would still get the new one suspended.
- Also fixed in passing: the listings-kit NAP block still advertised the retired preview URL
(silvia-jayet-reflexologie-preview.pages.dev) as the website to paste into local.ch and
search.ch — now https://reflexologie.com.
2026-08-15 — T36: scroll reveal + price count-up (the site's first JavaScript)
- Reveal: 43 blocks carry
data-reveal— section headings, cards, the five steps, testimonials,
FAQ rows, and both columns of every two-col section. One IntersectionObserver, one-shot
(unobserve on reveal), threshold 0.15 with an -8% bottom rootMargin so the motion reads as
the page arriving rather than catching up. Only opacity and transform animate, so no CLS.
- The hero is deliberately NOT revealed: it is the LCP element and starting it at opacity 0
would push LCP out for a block that is on screen from the first paint anyway.
- Stagger is limited to
.card-rowand.two-col, whose children enter together. Vertical
lists (steps, FAQ, testimonials) already arrive one at a time; a delay there reads as lag.
- Count-up rides the *lead* price only. On the launch card
.offer-firstdeliberately demotes
the regular CHF 110 and promotes the CHF 70 actually charged, so the counter sits on the
<b>, not the <strong> — animating the price nobody pays would have been backwards.
- Three failure modes drove the shape of the code, all found while testing:
- No JS. The hiding lives entirely behind a
.jsclass set by an inline<head>script.
No class, nothing hidden — and being inline in <head> means no flash of revealed-then-
hidden content. Every price is real text in the HTML, so the no-JS page is the old page.
- Observer never reports. A working observer reports on every element right after
observe(), intersecting or not; if nothing comes back within 2.5s the script reveals
everything. Losing the animation is cosmetic, leaving the page blank is not.
- Hidden tab.
requestAnimationFramefreezes while the page is hidden but the observer
still fires, which stranded prices at "CHF 4" mid-count in testing. The count now settles
to the real number instead of animating whenever document.hidden — a correct price beats
an animation nobody is watching. Every exit path goes through one settle().
- The element's own text is the source of truth: the script parses the first digit run, counts
to it, then restores the original string verbatim, so currency, spacing and any later copy
edit survive. Width is frozen (tabular figures + a measured min-width) so climbing digits
cannot reflow the line.
- Durations live in brand/design-tokens.json like every other design value and the script reads
the token rather than keeping a second copy — mind the unit, getComputedStyle normalises
"900ms" to ".9s" and a bare parseFloat gives 0.9 (caught in testing).
prefers-reduced-motion: reduceshort-circuits both: everything is shown immediately and the
prices are never touched.