/* TRAX [ai] site stylesheet: one file, one cascade (WP-A merged brand-test.css into it, 26/10).
   Regions are marked "@name" below, in this order: @tokens @base @buttons @header @footer @close @motion @home-sections @hero @turtle @swap @rings @demo @intl-globe @services @finder @about @approach @forms @contact-join @dev-panel.
   Inside a region: base rules, then wider-screen @media blocks, then phone (max-width) blocks, then hover / reduced-motion.
   Where two rules of equal specificity can hit the same element, their original order is kept, and a comment says so. */

/* ==================== @tokens : colour, size and layout tokens (one :root) ==================== */
:root {
  /* V2 palette */
  --brown: #674c3f; --choco: #472f24; --beige: #f9e8d4; --blue: #8cb5c7;
  /* 08/11, ASSETS/Couleurs_Trax.pdf : le brun clair passe de #6a4e41 a #674c3f, et un beige clair
     secondaire entre dans la palette. Les quatre primaires et l'orange sont inchanges. */
  --light-beige: #fef0de;
  /* 30/10 (Sam): the two browns are used by role, never by name. --frame is what wraps the site (top bar, closing
     band, footer, buttons), --surface is what sits inside it (hero, world map, demo frames, value card, finder).
     The ?edit palette button swaps the two, so the choice can be seen both ways on a real page. The -rgb pairs are
     for the rgba() masks of the phone hero, which have to be the same colour as the hero behind them. */
  --title-gap: clamp(18px, 2.2vw, 28px); /* titre de page -> sa sous-ligne, sur les quatre pages */
  --orange: #e77f4b; /* 08/11 (the owner): the designer's orange, only for a few touches: the small step numbers, the menu underline on hover, the map routes */
  --frame: var(--choco);   --frame-rgb: 71, 47, 36;
  --surface: var(--brown); --surface-rgb: 103, 76, 63;
  --ink: #141414; --body: #4a4540; --muted: #6b645d; --line: #e0cbb2;
  --cream: #fdf6ec; --page-bg: var(--light-beige);
  /* 08/11, ASSETS/Typo_Trax.pdf : trois fontes, chacune a son emploi.
     --font-1 Google Sans : l'identite principale. Titres, textes courants, navigation, boutons. Par defaut partout.
     --font-2 Inter Tight : ce qui doit etre compact et precis. Labels, chiffres et donnees, annotations, numeros.
     --font-3 Comico     : la tortue, et rien d'autre. Ses bulles et ses annotations.
     Google Sans ne monte qu'a 700 : les regles a 800 sont ramenees a 700 par le navigateur. */
  --font-1: "Google Sans", "TRAX Fallback", system-ui, -apple-system, "Segoe UI", sans-serif;
  --font-2: "Inter Tight", "TRAX Fallback", system-ui, -apple-system, "Segoe UI", sans-serif;
  --font-3: "Comico", "Comic Sans MS", "TRAX Fallback", system-ui, sans-serif;
  /* layout */
  --header-h: 68px; --maxw: 1180px; --gutter: clamp(20px, 5vw, 56px);
  --brown-hover: #4a3328; --cream-muted: #e6d3bd;
}

/* ==================== @base : reset, type, links, focus, layout helpers ==================== */
*, *::before, *::after { box-sizing: border-box; }
html { scroll-behavior: smooth; -webkit-text-size-adjust: 100%; scroll-padding-top: calc(var(--header-h) + 16px); }
body { margin: 0; font-family: var(--font-1); font-weight: 400; font-size: 1.0625rem; line-height: 1.7; color: var(--body); background: var(--page-bg); position: relative; }
img { max-width: 100%; display: block; }
a { color: var(--brown); }
a:hover { color: var(--brown-hover); }
/* WP-B (P1-10): one ring, brown on light backgrounds and beige where the background is brown or choco (>= 3:1 everywhere) */
:focus-visible { outline: 3px solid var(--brown); outline-offset: 3px; border-radius: 3px; }
.skip:focus-visible, .site-header :focus-visible, .on-dark :focus-visible, .close :focus-visible, .finder :focus-visible { outline-color: var(--beige); }
.finder .rc :focus-visible { outline-color: var(--brown); }
/* the floating pill sits in its own shadow over any background: brown ring with a beige gap, so it reads on light and dark */
.finder-pill:focus-visible { outline: 3px solid var(--brown); outline-offset: 3px; box-shadow: 0 0 0 3px var(--beige), 0 8px 22px rgba(0,0,0,.28); }
.skip { position: absolute; left: 12px; top: -60px; z-index: 100; background: var(--ink); color: #fff; padding: 10px 16px; border-radius: 999px; text-decoration: none; }
.skip:focus { top: 12px; }
/* WP-B (P2-12): viewport-fit=cover, so keep content out of the notch and rounded corners in landscape */
.wrap { width: 100%; margin: 0 auto; padding: 0 var(--gutter); padding-left: max(var(--gutter), env(safe-area-inset-left)); padding-right: max(var(--gutter), env(safe-area-inset-right)); max-width: 1280px; }
h1, h2 { color: var(--choco); font-weight: 800; line-height: 1.06; letter-spacing: -0.025em; margin: 0; } /* 29/10 (Sam): the dark brown of the guideline rather than black. Headings on a dark ground keep their own beige. */
h3 { color: var(--ink); margin: 0; font-size: clamp(1.15rem, 2vw, 1.4rem); font-weight: 700; line-height: 1.25; letter-spacing: -0.015em; }
h2 { font-size: clamp(2rem, 5vw, 3.6rem); overflow-wrap: anywhere; } /* a long word ("internationale,") breaks at 195 px or 200 % text instead of pushing the page sideways */
/* WP-B (P2-8): one title size for the inner pages (About, Services, Contact, Join) */
/* 30/10 (Sam) : les quatre pages s'ouvraient avec quatre reglages differents — 77 / 0 / 77 / 64 px au-dessus du
   titre, une sous-ligne a 20, 24 ou 40 px dessous, et deux echelles pour elle (24 px sur 30 caracteres a
   l'Approche, 22,4 px sur 46 ailleurs). Le titre, lui, faisait deja 73,6 px partout. Une seule ouverture
   maintenant : meme retrait, meme ecart, meme echelle. L'Approche garde sa photo, qui est son identite, mais plus
   son propre bareme. */
.page-title { font-size: clamp(2.4rem, 6vw, 4.6rem); max-width: 16ch; overflow-wrap: anywhere; }
.page-title + .lead, .page-title + .svc-top { margin-top: var(--title-gap); }
p { margin: 0 0 1.1em; }
/* 28/10 (Sam): never a lone word on the last line of a heading or a paragraph (a browser that does not know text-wrap keeps its usual wrapping) */
h1, h2, h3 { text-wrap: balance; }
p, li, summary { text-wrap: pretty; }
/* 28/10 (Sam, confirmed by the owner): no italic accent words in headings, one colour per heading */
em.accent, .hero-line1 em { font-style: normal; color: inherit; }
.lead { font-size: clamp(1.15rem, 2vw, 1.4rem); line-height: 1.55; color: var(--ink); font-weight: 500; max-width: 46ch; }
.small { font-size: .85rem; color: var(--muted); }
/* WP-K: a text link that stands alone on its line is a touch target of its own, so it is 44 px high (the text keeps its place: the paragraph's top margin is smaller by the same amount) */
.more-link { display: inline-flex; align-items: center; min-height: 44px; }
.sec { padding: clamp(44px, 6vw, 88px) 0; }
.two { display: grid; gap: clamp(28px, 6vw, 96px); grid-template-columns: minmax(0, 1fr); }
.two--tight { gap: clamp(20px, 3vw, 48px); }
@media (min-width: 900px) {
  .two { grid-template-columns: minmax(0, 5fr) minmax(0, 7fr); align-items: start; }
  .two > div + div .lead { margin-top: .35em; } /* 29/10 (Sam): sits on the title's first line, like the map block */
}
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
}

/* ==================== @buttons : .btn and variants ==================== */
.btn { display: inline-flex; align-items: center; min-height: 48px; padding: 12px 28px; border-radius: 999px; font: inherit; font-weight: 700; text-decoration: none; border: 2px solid transparent; --btn-line: var(--brown); transition: color .2s; cursor: pointer; }
.on-dark .btn:hover { --btn-bg: #fff; --btn-line: #fff; color: var(--brown); }
.btn--ghost { --btn-bg: transparent; color: var(--ink); --btn-line: var(--line); }
.btn--demo { --btn-bg: #8cb5c7; --btn-line: #8cb5c7; color: #2b1f18; margin-top: 4px; }
.btn { --btn-bg: var(--frame); --btn-line: var(--frame); color: var(--beige); }
/* 08/11 (the owner): every call to action takes the designer's hand-drawn button (Drive ASSETS/CTA, tools/make_brand_art.py).
   The colours stay Sam's: the rules above set --btn-bg (the fill) and --btn-line (the edge) instead of painting the box.
   The shape is a layer behind the text (so the focus ring is never clipped), cut in three: two hand-drawn ends, each
   half the button's height wide (--btn-h), and a middle that stretches with the label. Ghost buttons get the outline. */
.btn { position: relative; isolation: isolate; background: transparent; border-color: transparent; --btn-h: 57px; }
.btn::before, .btn::after, .finder-pill::before { content: ""; position: absolute; inset: -2px; z-index: -1; pointer-events: none; transition: background-color .2s;
  -webkit-mask-repeat: no-repeat; mask-repeat: no-repeat;
  -webkit-mask-position: left center, right center, center; mask-position: left center, right center, center;
  -webkit-mask-size: calc(var(--btn-h) / 2) 100%, calc(var(--btn-h) / 2) 100%, calc(100% - var(--btn-h) + 2px) 100%;
  mask-size: calc(var(--btn-h) / 2) 100%, calc(var(--btn-h) / 2) 100%, calc(100% - var(--btn-h) + 2px) 100%; }
.btn::before, .finder-pill::before { background-color: var(--btn-bg, transparent);
  -webkit-mask-image: url(../img/btn-shape-l.svg), url(../img/btn-shape-r.svg), url(../img/btn-shape-m.svg);
  mask-image: url(../img/btn-shape-l.svg), url(../img/btn-shape-r.svg), url(../img/btn-shape-m.svg); }
.btn--ghost::before { inset: 2px; }
.btn--ghost::after { background-color: var(--btn-line, transparent);
  -webkit-mask-image: url(../img/btn-line-l.svg), url(../img/btn-line-r.svg), url(../img/btn-line-m.svg);
  mask-image: url(../img/btn-line-l.svg), url(../img/btn-line-r.svg), url(../img/btn-line-m.svg); }
.finder-form .btn { --btn-h: 44px; }
/* the floating assistant pill (bottom right) takes the same hand-drawn shape; its shadow follows the drawing */
.finder-pill { --btn-bg: var(--surface); --btn-h: 46px; isolation: isolate; filter: drop-shadow(0 6px 12px rgba(0,0,0,.26)); } /* paint: see the @finder .finder-pill rule */
.finder-main > .btn, .finder-main a.btn { --btn-h: 40px; }
.finder .rc .btn, .finder-reply .btn { --btn-h: 38px; }
@media (prefers-reduced-motion: reduce) {
  .btn, .btn::before, .btn::after { transition: none; }
}

/* ==================== @header : site header, nav, phone menu ==================== */
.site-header { position: sticky; top: 0; z-index: 50; background: var(--frame); border-bottom: 0; }
.site-header .wrap { display: flex; align-items: center; justify-content: space-between; height: var(--header-h); gap: 16px; }
.logo { font-weight: 800; font-size: 1.3rem; letter-spacing: -.02em; color: var(--ink); text-decoration: none; }
.nav { display: flex; align-items: center; gap: 30px; }
.nav a { color: var(--ink); text-decoration: none; font-weight: 600; font-size: .96rem; padding: 6px 0; border-bottom: 2px solid transparent; }
.nav a:hover { color: var(--brown); }
.lang { display: inline-flex; border: 1.5px solid var(--line); border-radius: 999px; overflow: hidden; }
.nav .lang a { padding: 5px 12px; font-size: .78rem; font-weight: 700; border: 0; letter-spacing: .06em; color: var(--muted); }
.nav .lang a[aria-current="true"] { background: var(--ink); color: #fff; }
.menu-btn { display: none; border: 1.5px solid var(--line); border-radius: 999px; padding: 8px 16px; font: inherit; font-weight: 700; cursor: pointer; min-height: 44px; color: var(--beige); border-color: rgba(249,232,212,.6); background: transparent; }
html body.page-home .site-header { transition: opacity .35s ease, background .3s, border-color .3s; }
.logo-img { display: block; width: auto; height: 30px; }
.site-header .logo { display: flex; align-items: center; min-height: 44px; }
.site-header .nav a { color: var(--beige); }
.site-header .nav a:hover { border-bottom-color: var(--orange); } /* WP-K: the text stays beige (6.3:1); blue text on the brown bar was 3.4:1 */
.site-header .nav a[aria-current="page"] { border-bottom-color: var(--blue); }
.site-header .lang { background: var(--surface); border-color: var(--surface); }
.site-header .nav .lang a { color: var(--beige); }
.site-header .nav .lang a[aria-current="true"] { background: var(--beige); color: var(--frame); }
.site-header .nav .lang a:not([aria-current="true"]):hover { background: rgba(249,232,212,.18); } /* the pill has no underline to show a hover, so it gets a faint beige fill */
/* WP-B (P0-3, P1-1): on desktop the Home bar is fixed in every state, so the hero starts at y = 0 and nothing jumps.
   Over the top of the hero it is only faded out (no visibility:hidden), so Tab still reaches it and :focus-within shows it. */
@media (min-width: 761px) {
  html body.page-home .site-header { opacity: 1; visibility: visible; pointer-events: auto; background: var(--frame); position: fixed; left: 0; right: 0; top: 0; }
  .page-home .site-header:not(.solid) .logo-img { filter: none; }
  /* 08/11 (the owner): on arrival the bar is there but transparent over the hero; it turns brown once the hero is behind it
     (.solid, site.js). A faint shade from the top keeps the beige links readable over the light photo. The small logo waits
     until the bar is solid: the hero already shows the big one (Tab still reaches it and shows it). */
  html body.page-home .site-header:not(.solid) { background: linear-gradient(rgba(var(--frame-rgb), .55), rgba(var(--frame-rgb), 0)); }
  /* 08/11 : sur ordinateur le hero n'a plus de grand logo (maquette d'Audrey), donc celui de la barre
     reste visible des l'arrivee. Il est beige : il se lit sur la photo comme sur le bandeau brun. */
  .page-home .site-header .logo { transition: opacity .3s; }
}
@media (max-width: 760px) {
  .menu-btn { display: inline-flex; align-items: center; }
  .nav { display: none; position: absolute; left: 0; right: 0; top: 100%; background: #fff; border-bottom: 1px solid var(--line); flex-direction: column; align-items: flex-start; gap: 4px; padding: 12px var(--gutter) 24px; }
  .nav.open { display: flex; }
  .nav a { padding: 12px 0; font-size: 1.1rem; }
  .nav .lang { margin-top: 8px; }
  .page-home .site-header { position: fixed; left: 0; right: 0; top: 0; background: transparent; border-bottom-color: transparent; transition: background .3s, border-color .3s; }
  /* WP-B (P1-1, P1-11): at the top of Home the bar is transparent and the logo hidden, but the Menu button shows from the first paint.
     The open menu is keyed on a .menu-open class set by site.js (no relational selector), so iOS < 15.4 gets the same brown panel. */
  .page-home .site-header:not(.solid):not(.menu-open) .logo-img { filter: brightness(0) invert(1); }
  .page-home .site-header:not(.solid):not(.menu-open) .menu-btn { color: #fff; background: rgba(20,14,10,.42); border-color: rgba(255,255,255,.8); }
  .page-home .site-header.solid, .page-home .site-header.menu-open { background: var(--frame); border-bottom-color: transparent; }
  .page-home .site-header:not(.solid):not(.menu-open) .logo { opacity: 0; pointer-events: none; }
  .page-home .site-header:not(.solid):not(.menu-open) .logo:focus-visible { opacity: 1; }
  .page-home .site-header .logo { transition: opacity .3s; }
  html body .site-header.menu-open, html body.page-home .site-header.menu-open { background: var(--frame); border-bottom-color: transparent; }
}
html body .site-header, html body.page-home .site-header.solid { background: var(--frame); border-bottom-color: transparent; }
@media (max-width: 760px) {
  html body .site-header.menu-open .nav { background: var(--frame); border-bottom: 0; padding-bottom: 32px; gap: 2px; }
  html body .site-header.menu-open .nav a { color: var(--beige); font-size: 1.7rem; font-weight: 800; letter-spacing: -.02em; padding: 10px 0; border-bottom: 0; }
  html body .site-header.menu-open .nav a[aria-current="page"] { color: var(--blue); }
  html body .site-header.menu-open .logo-img { filter: brightness(0) invert(1); }
  html body .site-header.menu-open .menu-btn { color: var(--beige); border-color: var(--beige); background: transparent; }
  html body .site-header.menu-open .nav .lang { border-color: var(--beige); margin-top: 14px; }
  html body .site-header.menu-open .nav .lang a { display: flex; align-items: center; min-height: 44px; color: var(--beige); font-size: .9rem; font-weight: 700; letter-spacing: .06em; padding: 0 16px; } /* WP-K: 44 px touch target (it was 38.5) */
  html body .site-header.menu-open .nav .lang a[aria-current="true"] { background: var(--beige); color: var(--frame); }
  html body.page-home .site-header:not(.solid):not(.menu-open) { background: transparent; }
}
/* WP-B (P1-10): the FR/EN pill clips its links (overflow:hidden), so their ring is drawn inside them */
.site-header .lang a:focus-visible { outline-offset: -5px; }
.site-header .lang a[aria-current="true"]:focus-visible { outline-color: var(--choco); }
@media (prefers-reduced-motion: reduce) {
  html body.page-home .site-header, html body.page-home .site-header.at-top:not(:focus-within) { transition: none; }
}

/* ==================== @footer : site footer ==================== */
.site-footer { padding: 44px 0 40px; font-size: .95rem; border-top: 1px solid rgba(242,233,216,.18); background: var(--frame); color: var(--cream-muted); } /* 29/10 (Sam): header, closing block and footer now share the dark choco; on it the brand blue is 5.62:1, so the footer may carry blue again */
/* 10/11 (Sam) : plus de rognage ici. Le selecteur de langue s'ouvre vers le haut, a 110 px
   au-dessus du bord du pied : overflow:hidden en coupait tout sauf la derniere ligne, et on ne
   voyait qu'un bout de « NL ». Le rognage servait a la grande tortue du fond, qui depuis le 08/11
   est ajustee a la hauteur du pied (top et bottom a 16 px, object-fit: contain) : elle ne deborde
   plus, ni en hauteur ni en largeur. Mesure : scrollWidth et scrollHeight egaux aux clientWidth
   et clientHeight une fois le rognage enleve. */
.site-footer { position: relative; }
/* 29/10 (Sam): a big turtle lying in the back on the right, as on the client-hub card. Decorative, so it is
   faint enough to stay behind the links and it never takes a click. */
/* 08/11 (the owner: "the turtle is being cut at the bottom"): the whole turtle, fitted to the footer's height */
.foot-turtle { position: absolute; right: 3%; top: 16px; bottom: 16px; height: calc(100% - 32px); max-height: 260px; width: auto; max-width: 60%; object-fit: contain; object-position: right center; opacity: .13; pointer-events: none; user-select: none; }
.site-footer .wrap { position: relative; z-index: 1; display: flex; flex-wrap: wrap; gap: 24px 48px; justify-content: space-between; }
.site-footer .logo { color: var(--beige); display: block; margin-bottom: 8px; }
.site-footer ul { list-style: none; padding: 0; margin: 0; display: flex; gap: 0 22px; flex-wrap: wrap; }
.site-footer .logo-img { width: auto; height: 70px; margin-bottom: 14px; }
/* 29/10 (Sam): the line of the guideline was written nowhere on the site. It signs the footer, next to the turtle. */
.site-footer a { color: var(--beige); }
/* WP-B (P2-5): 44 px tap targets (the links were 26 px tall) */
.site-footer ul a { display: inline-block; padding: 10px 0; }

/* ==================== @close : closing CTA block ==================== */
/* WP-B (P2-7): flat V2 block (the rounded top showed white wedges over the page) and a CTA sized to its text */
.close { color: var(--cream-muted); padding: clamp(48px, 7vw, 96px) 0; margin-top: -1px; background: var(--frame); } /* 29/10 (Sam): dark choco, not the brown of the content bands — the blue slogan on brown measured 3.44:1 */
.page-home section[aria-labelledby="w-h"] + .close { border-top: 1px solid rgba(249,232,212,.18); } /* the globe block above is brown too */
.close .btn { justify-self: start; }
.close h2 { max-width: 16ch; color: var(--beige); overflow-wrap: anywhere; }
/* 29/10 (Sam, option A2): the slogan sits above the closing heading, on every page, where the call is asked for */
.close-slogan { margin: 0 0 14px; color: var(--blue); font-weight: 800; font-size: clamp(1rem, 1.6vw, 1.15rem); letter-spacing: -.01em; }
.close .wrap { display: grid; gap: 32px; grid-template-columns: 1fr; align-items: end; }
.signature { font-weight: 800; margin: 0 0 16px; color: var(--blue); } /* 04/11 (Sam) : plus d'italique nulle part */
.close .lead { color: var(--beige); margin-bottom: 0; }
@media (min-width: 860px) {
  .close .wrap { grid-template-columns: auto auto; justify-content: start; gap: clamp(32px, 5vw, 72px); } /* 29/10 (Sam): the two halves were pushed to opposite edges */
}

/* ==================== @motion : .fx reveals ==================== */
/* WP-B (P0-1, P2-2): the background morph, the progress bar and the hero parallax are gone. One light reveal is left:
   headings and figure groups rise 14 px and fade in once (site.js section 11 adds .fx; never under reduced motion or .still). */
.fx { opacity: 0; transform: translateY(14px); transition: opacity .55s ease, transform .6s cubic-bezier(.2,.7,.2,1); }
.fx.fx-in { opacity: 1; transform: none; }
html:not(.js) .fx, .still .fx { opacity: 1; transform: none; }
@media (prefers-reduced-motion: reduce) {
  .fx { opacity: 1; transform: none; transition: none; }
}

/* ==================== @home-sections : Home section colour blocks ==================== */
.lines { border-top: 1px solid var(--ink); }
.line { display: grid; grid-template-columns: 1fr; gap: 6px 36px; padding: clamp(24px, 3.2vw, 40px) 0; border-bottom: 1px solid var(--line); }
.line .n { font-weight: 800; font-size: .95rem; letter-spacing: .06em; }
.line p { margin: 0; }
.cities { display: flex; flex-wrap: wrap; gap: 4px 28px; list-style: none; padding: 0; margin: 32px 0 0; font-weight: 800; font-size: clamp(1.6rem, 4vw, 3rem); letter-spacing: -.025em; color: var(--ink); line-height: 1.2; }
/* @services rule placed before its region: it must stay before the equal-specificity rule below (cascade order); its selector matches nothing on any page today */
.case h3 { font-size: 1.2rem; }
.intro { font-size: clamp(1.4rem, 3vw, 2.2rem); font-weight: 700; letter-spacing: -.02em; line-height: 1.28; color: var(--ink); max-width: 40ch; margin: 0; }
.lines .line:last-child { border-bottom: 1px solid var(--ink); }
.sec--tint::before, .sec--tint::after { content: ""; position: absolute; left: 0; right: 0; height: clamp(70px, 10vw, 140px); pointer-events: none; z-index: 1; display: none; }
.sec--tint::before { top: 0; background: linear-gradient(to bottom, #fff, rgba(255,255,255,0)); }
.sec--tint::after { bottom: 0; background: linear-gradient(to top, #fff, rgba(255,255,255,0)); }
.sec--tint { position: relative; background: var(--beige); }
.cities li:nth-child(even) { color: var(--brown); }
.page-home section#e-h-sec { background: var(--beige); }
/* WP-B (P0-2): ink only for the heading and the lead; the "p" of this selector used to beat ".cubes .cube p" (ink on brown cards, 2.3:1) */
.page-home section#e-h-sec h2 { color: var(--choco); }
.page-home section#e-h-sec .two p { color: var(--ink); }
/* WP-B (P0-1): every Home block paints its own colour; the page under them is brown for overscroll and the area behind the fixed bar */
body.page-home { background: var(--surface); }
.page-home section[aria-labelledby="s-h"] { background: var(--beige); } /* 29/10 (Sam): was #fdf6ec, a second background that is in no guideline */
.page-home section[aria-labelledby="s-h"] h2 { color: var(--choco); }
.page-home section[aria-labelledby="s-h"] p, .page-home section[aria-labelledby="s-h"] li, .page-home section[aria-labelledby="s-h"] .small { color: var(--ink); }
.page-home section[aria-labelledby="s-h"] a { color: var(--brown); }
/* 29/10 (Sam): his key message 2 and the four figures that prove it, as an inset card on the beige rather than a full-width band —
   a card reads as an object, so it breaks the long beige run without becoming a second brown section beside the map.
   29/10 later (Sam): the lighter brown, like every other surface inside the site — the dark choco is the frame's colour.
   The figures' blue reads 3.44:1 here, which clears the 3:1 the 44px bold asks for; the eyebrow above each figure
   is the one thing the lighter ground costs: at .62 it measured 3.52:1, so it goes to .88.
   The turtle behind the figures lightens the ground it sits on, so the worst case is there, not on the flat brown:
   .88 over the watermark is 4.61:1, 5.34:1 off it. The watermark itself drops to .09 — the blue shows more on the lighter brown. */
.page-home section.sec--value { background: var(--beige); }
.value-card { position: relative; overflow: hidden; border-radius: clamp(18px, 2.2vw, 28px); background: var(--surface); color: var(--beige);
  padding: clamp(28px, 4vw, 64px); display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, .92fr); gap: clamp(26px, 4vw, 60px); align-items: start; }
.value-card > div { position: relative; z-index: 1; }
.value-card h2 { color: var(--beige); max-width: 18ch; }
.value-card .lead { color: #efe0cc; margin: 18px 0 0; max-width: 46ch; }
.value-turtle { position: absolute; right: -6%; bottom: -26%; width: min(44%, 500px); height: auto; opacity: .09; z-index: 0; pointer-events: none; user-select: none; }
/* 05/11 (Sam) : en trois colonnes chaque chiffre n'avait que 140 px, et "188 400 €" se coupait des qu'on
   l'agrandissait. Empiles, ils ont toute la largeur de la colonne : ils tiennent sur une ligne, ils peuvent etre
   deux fois plus gros, et ils se suivent de haut en bas — ce qui est aussi le sens dans lequel ils apparaissent. */
/* 10/11 (Sam) : le filet au-dessus des chiffres disparait, ici comme sur Interventions. L'espace
   reste : ce qui separe les chiffres du texte, c'est le blanc, plus un trait. */
.value-figs { display: grid; grid-template-columns: minmax(0, 1fr); gap: clamp(16px, 2.2vw, 24px);
  padding-top: clamp(18px, 2.4vw, 26px); }
.value-figs .fig { padding: 0; border-bottom: 0; }
/* "188 400 €" ne doit jamais se couper entre deux chiffres : l'espace des milliers est insecable et
   overflow-wrap:normal le respecte ; white-space:nowrap garde en plus l'unite collee au nombre */
.value-figs .fig b { color: var(--blue); font-size: clamp(2.1rem, 3.4vw, 3.4rem); overflow-wrap: normal;
  white-space: nowrap; }
/* 05/11 (Sam) : chaque chiffre monte et apparait a son tour. .figs-anim est pose par site.js, donc sans script
   — ou en mouvement reduit — les chiffres restent simplement la, a leur valeur finale. */
.value-figs.figs-anim .fig { opacity: 0; transform: translateY(16px);
  transition: opacity .6s cubic-bezier(.2,.8,.2,1), transform .6s cubic-bezier(.2,.8,.2,1); }
.value-figs.figs-anim .fig.on { opacity: 1; transform: none; }
html.still .value-figs.figs-anim .fig { opacity: 1; transform: none; transition: none; }
.value-figs .fig > span { color: #e8d7c2; max-width: 26ch; margin-top: 6px; }
@media (max-width: 900px) {
  .value-card { grid-template-columns: minmax(0, 1fr); }
  .value-turtle { bottom: -16%; width: min(58%, 300px); }
}
@media (max-width: 520px) { .value-figs { grid-template-columns: minmax(0, 1fr); } }
.page-home section[aria-labelledby="w-h"] { background: var(--surface); position: relative; }
/* 28/10 (Sam): the beige block above fades into this brown over its own bottom padding (same height as the padding, so nothing sits under the band) */
.page-home section#e-h-sec { padding-bottom: clamp(72px, 11vw, 128px); }
.page-home section[aria-labelledby="w-h"] h2, .page-home section[aria-labelledby="w-h"] p, .page-home section[aria-labelledby="w-h"] li, .page-home section[aria-labelledby="w-h"] .lead { color: var(--beige); }
.page-home section[aria-labelledby="w-h"] * { border-color: rgba(249,232,212,.25); }
.sec--tint a { color: var(--brown); }
@media (min-width: 820px) {
  .line { grid-template-columns: 70px minmax(0, 1fr) minmax(0, 1.2fr); align-items: baseline; }
}
@media (min-width: 900px) {
  .line h3 { font-size: 1.6rem; }
}

/* ==================== @hero : hero layout, photo, headline ==================== */
.hero { position: relative; overflow: hidden; min-height: calc(86vh - var(--header-h)); min-height: calc(86svh - var(--header-h)); display: flex; padding: clamp(28px, 4vw, 56px) 0 0; flex-direction: column; justify-content: flex-end; align-items: stretch; background: linear-gradient(to bottom, #fff 0%, #fff 48%, var(--beige) 100%); padding-bottom: clamp(24px, 4vw, 56px); }
.hero-bg { position: absolute; inset: 0; z-index: 0; }
.hero-bg img { position: absolute; right: 0; top: 0; width: min(64%, 1100px); height: 100%; object-fit: cover; opacity: .55; -webkit-mask-composite: source-in; mask-composite: intersect; -webkit-mask-image: linear-gradient(to right, transparent 0, #000 30%), linear-gradient(to bottom, #000 45%, transparent 92%); mask-image: linear-gradient(to right, transparent 0, #000 30%), linear-gradient(to bottom, #000 45%, transparent 92%); filter: blur(var(--hero-blur, 0px)); transform: scale(var(--hero-scale, 1)); transform-origin: 60% 30%; object-position: 50% 35%; }
.hero .wrap { position: relative; z-index: 1; flex: 1; display: flex; flex-direction: column; justify-content: space-between; gap: clamp(36px, 8vh, 96px); }
.hl { display: block; overflow: hidden; padding-bottom: .12em; }
.hl > span { display: block; }
.hero-line1 { font-weight: 800; line-height: 1.08; letter-spacing: -.025em; color: var(--ink); margin: 0; font-size: clamp(1.9rem, 4.6vw, 3.8rem); max-width: 30ch; text-wrap: initial; }
.rv .hl > span { transform: translateY(110%); }
.hero-brand { display: flex; align-items: flex-end; gap: clamp(14px, 2vw, 28px); }
.hero-wm { width: clamp(150px, 17vw, 250px); height: auto; }
.hero-line1 .ln { display: block; text-wrap: balance; }
.page-home .hero { background: var(--surface); }
.page-home .hero h1, .page-home .hero .hero-line1 { color: var(--beige); }
.page-home .hero-bg::before, .page-home .hero-bg::after { background: none; }
/* Phones held in landscape (height <= 500) get the two-column hero too: the stacked phone layout has no room there. */
@media (min-width: 761px), (orientation: landscape) and (max-height: 500px) {
  .hero { min-height: calc(100vh - var(--header-h)); min-height: calc(100svh - var(--header-h)); }
  .hero-line1 { font-size: clamp(2rem, 4.4vw, 4rem); max-width: 52vw; }
  .hero-bg img { left: auto; right: 0; top: 0; max-width: none; height: 100%; aspect-ratio: auto; object-fit: cover; opacity: 1; -webkit-mask-composite: source-in; mask-composite: intersect; object-position: 50% 12%; width: 50%; -webkit-mask-image: linear-gradient(to right, transparent 0, #000 12%), linear-gradient(to bottom, #000 70%, transparent 100%); mask-image: linear-gradient(to right, transparent 0, #000 12%), linear-gradient(to bottom, #000 70%, transparent 100%); }
  .page-home .hero .wrap { justify-content: center; gap: clamp(28px, 6vh, 64px); margin: 0 0 0 max(0px, calc((100vw - var(--maxw)) / 2)); width: calc(50vw - max(0px, calc((100vw - var(--maxw)) / 2))); max-width: none; padding: 0 24px 0 var(--hero-pad); position: absolute; left: 0; top: 50%; transform: translateY(-50%); margin-left: max(0px, calc((100vw - var(--maxw)) / 2)); flex: none; }
  .page-home .hero-line1 { font-size: clamp(1.6rem, 2.3vw, 2.9rem); font-weight: 700; line-height: 1.12; letter-spacing: -.02em; max-width: none; }
  .page-home .hero { background: var(--surface); align-items: center; padding: 0; justify-content: flex-start; display: block; position: relative; min-height: 100vh; min-height: 100svh; }
  .page-home .hero-bg img { -webkit-mask-image: linear-gradient(to right, transparent 0, #000 28%), linear-gradient(to bottom, #000 80%, transparent 100%); mask-image: linear-gradient(to right, transparent 0, #000 28%), linear-gradient(to bottom, #000 80%, transparent 100%); -webkit-mask-composite: source-in; mask-composite: intersect; } /* 28/10 (Sam): no hard line under the photo */
  .page-home .hero .hero-line1 .ln { display: block; }
  .page-home .hero .hero-line1 .ln + .ln { font-weight: 600; color: var(--beige); opacity: .92; font-size: .8em; margin-top: .3em; letter-spacing: -.005em; }
  .page-home .hero .hero-line1 { max-width: none; font-size: clamp(1.5rem, 2.3vw, 2.3rem); line-height: 1.12; }
  .page-home .hero .hero-brand { display: flex; margin: 0 0 clamp(22px, 3vw, 40px); }
  .page-home .hero .hero-wm { width: clamp(220px, 22vw, 340px); }
  .page-home .hero { --hero-m: max(0px, calc((100vw - var(--maxw)) / 2)); --hero-pad: max(var(--gutter), env(safe-area-inset-left)); }
}
@media (max-width: 760px) and (orientation: portrait), (max-width: 760px) and (min-height: 501px) {
  .hero .wrap { gap: 0; display: contents; }
  .hero-wm { width: 156px; }
  .hero-line1 { text-wrap: balance; line-height: 1.12; max-width: 100%; grid-row: 2; grid-column: 1; order: 0; align-self: end; margin: 0; padding: 0 var(--gutter) 22px; color: #fff; font-size: 1.75rem; padding-bottom: 0; text-shadow: 0 1px 2px rgba(0,0,0,.22), 0 2px 18px rgba(0,0,0,.32); }
  .hero-brand { padding: 0 var(--gutter); grid-row: 1; grid-column: 1; order: 0; }
  .hero-bg img { opacity: 1; position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; object-position: 50% 40%; -webkit-mask-image: linear-gradient(to bottom, #000 62%, transparent 100%); mask-image: linear-gradient(to bottom, #000 62%, transparent 100%); }
  .hero { grid-template-columns: 100%; grid-template-rows: auto auto auto; align-content: start; position: relative; display: flex; flex-direction: column; justify-content: space-between; margin-top: 0; padding: calc(var(--header-h) + 20px) 0 28px; overflow: hidden; border-radius: 0; background: var(--beige); min-height: calc(84vh - var(--header-h)); min-height: calc(84svh - var(--header-h)); padding-bottom: 84px; }
  .hero-bg { grid-row: 2; grid-column: 1; order: 0; position: absolute; inset: 0; height: auto; aspect-ratio: auto; margin: 0; z-index: 0; }
  .hero-bg::after { content: ""; position: absolute; left: 0; right: 0; bottom: 0; pointer-events: none; height: 38%; background: linear-gradient(to bottom, rgba(251,243,232,0) 0%, rgba(251,243,232,.7) 70%, var(--beige) 100%); }
  .hero-bg::before { content: ""; position: absolute; left: 0; right: 0; top: 0; height: 34%; background: linear-gradient(to bottom, rgba(14,10,7,.62), rgba(14,10,7,0)); z-index: 1; pointer-events: none; display: none; }
  .hero-brand, .hero-line1 { z-index: 2; position: relative; }
  .hero-brand::before { content: ""; position: absolute; z-index: -1; pointer-events: none; left: -60px; top: -80px; width: 340px; height: 250px; background: radial-gradient(closest-side at 40% 45%, rgba(18,12,8,.30) 0%, rgba(18,12,8,.22) 30%, rgba(18,12,8,.10) 60%, rgba(18,12,8,.03) 85%, rgba(18,12,8,0) 100%); filter: blur(12px); }
  .hero-line1::before { content: ""; position: absolute; z-index: -1; pointer-events: none; left: -50px; bottom: -60px; width: calc(100% + 100px); height: calc(100% + 170px); background: radial-gradient(closest-side at 45% 60%, rgba(18,12,8,.42) 0%, rgba(18,12,8,.32) 28%, rgba(18,12,8,.17) 58%, rgba(18,12,8,.05) 84%, rgba(18,12,8,0) 100%); filter: blur(14px); }
  .page-home .hero-bg::after { height: 38%; background: linear-gradient(to bottom, rgba(249,232,212,0) 0%, rgba(249,232,212,.7) 70%, var(--beige) 100%); }
  .page-home .hero .hero-wm { width: clamp(168px, 46vw, 200px); }
  html body.page-home .hero-bg { position: absolute; inset: 0; aspect-ratio: auto; margin: 0; }
  html body.page-home .hero-bg img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; object-position: 50% 22%; -webkit-mask-image: none; mask-image: none; }
  html body.page-home .hero-bg::after { content: ""; position: absolute; left: 0; right: 0; bottom: 0; top: auto; pointer-events: none; height: 58%; background: linear-gradient(to bottom, rgba(var(--surface-rgb),0) 0%, rgba(var(--surface-rgb),.42) 30%, rgba(var(--surface-rgb),.9) 50%, rgba(var(--surface-rgb),.95) 62%, rgba(var(--surface-rgb),.96) 100%); }
  html body.page-home .hero-line1::before, html body.page-home .hero-brand::before { display: none; }
  html body.page-home .hero .hero-line1 { text-shadow: none; font-size: clamp(2rem, 9vw, 2.8rem); line-height: 1.04; margin: 0; justify-self: start; align-self: end; width: 100%; max-width: none; padding: 0 var(--gutter); }
  .hero-brand img { filter: none !important; }
  html body.page-home .hero-bg::before { display: block; content: ""; position: absolute; left: 0; right: 0; top: 0; height: 36%; z-index: 1; background: linear-gradient(to right, rgba(var(--surface-rgb),.78) 0%, rgba(var(--surface-rgb),.74) 52%, rgba(var(--surface-rgb),.3) 82%, rgba(var(--surface-rgb),.18) 100%); -webkit-mask-image: linear-gradient(to bottom, #000 42%, transparent 100%); mask-image: linear-gradient(to bottom, #000 42%, transparent 100%); pointer-events: none; }
  html body.page-home .hero { min-height: 100vh; min-height: 100svh; padding-top: calc(env(safe-area-inset-top) + 18px); padding-bottom: calc(env(safe-area-inset-bottom) + 60px); }
  html body.page-home .hero .hero-line1 .ln { display: block; }
  html body.page-home .hero .hero-line1 .ln + .ln { font-size: .5em; font-weight: 600; line-height: 1.3; margin-top: .7em; max-width: 24ch; opacity: .95; letter-spacing: -.005em; }
  html body.page-home .hero .hero-line1 .ln:first-child { max-width: 12ch; }
}
@media (orientation: landscape) and (max-height: 500px) {
  /* the text column is back in the flow, so the hero grows with it instead of clipping it; it still fills the screen */
  .page-home .hero { display: flex; flex-direction: column; justify-content: center; align-items: flex-start; padding: 24px 0; }
  .page-home .hero .wrap { position: relative; top: auto; transform: none; gap: 18px; }
  .page-home .hero .hero-wm { width: 200px; }
}
@media (orientation: landscape) and (max-height: 500px) and (max-width: 760px) {
  /* the phone Menu button floats at the top right: the photo column starts below it, the tags follow the photo */
  .page-home .hero-bg img { top: var(--header-h); height: calc(100% - var(--header-h)); }
}

/* 08/11 (Sam, d'apres la maquette d'Audrey) : sur ordinateur la photo du canape tient tout le cadre,
   un voile brun la calme, et la phrase est posee au centre en beige, ses deux lignes de la meme taille
   (c'est ce que Sam reprochait a l'ancien hero : une ligne plus grosse que l'autre). Le grand logo du
   hero disparait, la barre en porte un en haut a gauche. Pas d'appel a l'action ici, Sam y tient.
   Sur telephone rien ne change : la photo verticale de l'escalier, masquee comme avant, et le grand logo.
   Les regles du dessus sont ecrites en ".page-home .hero ..." : il faut au moins autant de poids pour les reprendre. */
@media (min-width: 761px) {
  html body.page-home .hero { background: var(--choco); display: flex; flex-direction: column;
    align-items: center; justify-content: center; padding: 0; min-height: 100vh; min-height: 100svh; }
  html body.page-home .hero-bg img { position: absolute; inset: 0; left: 0; right: 0; top: 0;
    width: 100%; height: 100%; max-width: none; object-fit: cover; object-position: 50% 38%; opacity: 1;
    -webkit-mask-image: none; mask-image: none; }
  /* le voile : plus dense en haut pour que la barre et ses liens beiges tiennent, et au bas sous la phrase */
  html body.page-home .hero-bg::before { display: none; }
  html body.page-home .hero-bg::after { content: ""; position: absolute; inset: 0; top: 0; height: auto;
    pointer-events: none; z-index: 1;
    background: linear-gradient(to bottom, rgba(var(--frame-rgb), .66) 0, rgba(var(--frame-rgb), .34) 26%,
                                           rgba(var(--frame-rgb), .50) 60%, rgba(var(--frame-rgb), .72) 100%); }
  html body.page-home .hero .wrap { position: relative; left: auto; top: auto; transform: none;
    width: 100%; max-width: var(--maxw); margin: 0 auto; flex: none;
    display: flex; flex-direction: column; align-items: center; justify-content: flex-end; text-align: center; gap: 0;
    /* 08/11 (Sam) : la phrase descend dans le tiers bas au lieu d'etre au milieu */
    padding: 0 var(--gutter) clamp(90px, 16vh, 180px); min-height: 100%; }
  html body.page-home .hero .hero-brand { display: none; }
  html body.page-home .hero .hero-line1 { color: var(--beige); font-weight: 400; letter-spacing: -.012em;
    font-size: clamp(2rem, 3.4vw, 3.3rem); line-height: 1.16; max-width: 26ch; margin: 0 auto; text-align: center; }
  html body.page-home .hero .hero-line1 .ln + .ln { font-size: 1em; font-weight: 400; opacity: 1;
    margin-top: 0; color: var(--beige); letter-spacing: -.012em; }
}

/* ==================== @turtle : walking turtle ==================== */
/* .turtle = the brand turtle rig (body + four legs), shared with the Services finder.
   .walker = the one that wanders the Home: since 08/11 the designer's brown turtle with the blue outline. It lives in .roam, a layer the size of <main>, and
   site.js section 6 walks it to the free spots of each block. Hidden without JS, set down and still under reduced motion. */
.turtle img { position: absolute; display: block; pointer-events: none; }
.turtle .t-body { left: 0; top: 0; width: 100%; height: 100%; }
.turtle .t-leg { will-change: transform; transform-origin: inherit; z-index: 0; }
.turtle .t-body { z-index: 1; } /* 08/11: the legs swing behind the body (tools/make_turtle.py), so no outline shows at the joints */
.turtle { aspect-ratio: 500 / 302; width: auto; display: block; height: 28px; position: relative; isolation: isolate; }
.page-home main { position: relative; }
.roam { position: absolute; inset: 0; z-index: 3; pointer-events: none; overflow: hidden; }
.roam .walker { position: absolute; left: 0; top: 0; height: 44px; will-change: transform; pointer-events: none; transform-origin: 50% 50%; opacity: 0; transition: opacity .28s ease-out; }
/* 11/11 (Sam) : « le fondu assez vite et smooth ». Il durait 1,8 s en linéaire : on la voyait se
   matérialiser lentement, ce qui n'est pas une arrivée mais une apparition. 0,55 s sur la courbe
   d'entrée de la charte — elle arrive, et c'est fait. */
.roam.in .walker { opacity: 1; }
/* 11/11 (Sam) : « elle n'apparaît pas assez bien ». Mesure sur la page rendue : elle ne faisait que
   42 x 27 px sur un écran de 1440, soit 0,09 % de la surface — le contraste, lui, était bon (3,9 à 4,1:1).
   C'était donc une question de taille, pas de couleur. 28 px -> 44 px coûte 12 % des places libres et
   ne prive aucun bloc supplémentaire de place (mesure a 1024).
   Sur telephone elle reste a 22 px : mesure a 390, passer a 30 px prive un bloc de plus de toute
   place (de 916 places sur 5 blocs a 764 sur 4). */
@media (max-width: 760px) { .roam .walker { height: 22px; } } /* plus petite : la colonne d'un téléphone est étroite */
.still .roam .walker { transition: none; }
html:not(.js) .roam { display: none; }
@media (prefers-reduced-motion: reduce) {
  .turtle .t-leg { animation: none; }
}

/* ==================== @swap : sticky word swap ==================== */
/* Pacing: 70vh of scroll per word plus a 30vh tail on the last word, on top of the pinned screen itself.
   site.js §2 reads --per and --tail. Words sit in one grid cell, so a long word can wrap (200 % zoom). */
.swap { --per: 70; --tail: 30; position: relative; height: calc((var(--n) * var(--per) + var(--tail)) * 1vh + 100vh - var(--header-h)); height: calc((var(--n) * var(--per) + var(--tail)) * 1vh + 100svh - var(--header-h)); background: var(--beige); }
/* 28/10 (Sam): where the brown hero meets the beige block the colour fades over a short band, no hard line. The band is the top of the swap block, above its text. */
.page-home .swap { --seam-from: var(--surface); }
/* 29/10 (the owner): the colour changes of the Home follow the scroll instead of being strips of gradient. A block that comes up arrives in the colour of the one before and takes its own
   as it rises: --p goes from 0 (its top edge at the bottom of the screen) to 1 (risen to 40 % from the top), set by site.js section 16, and a layer in the old colour fades out over it.
   Its content comes up once the colour is nearly its own (the swap's and the globe block's from p .85 to .99: no text on a half-way colour, small grey text needs a nearly final background to reach 4.5:1). Without JavaScript or under reduced motion --p stays 1: the block has its colour, plain edge. */
.page-home [data-arrive] { position: relative; }
.page-home [data-arrive]::before { content: ""; display: block; position: absolute; z-index: 0; left: 0; right: 0; top: 0; height: 100vh; height: 100svh; pointer-events: none; background: var(--arrive-from); opacity: calc(1 - var(--p, 1)); }
.page-home [data-arrive] > .wrap, .page-home .swap-pin { position: relative; z-index: 1; }
.page-home .swap-pin { position: sticky; }
.page-home .swap { --arrive-from: var(--seam-from); }
.page-home section[aria-labelledby="s-h"] { --arrive-from: var(--beige); }
.page-home #e-h-sec { --arrive-from: var(--beige); }
.page-home section[aria-labelledby="w-h"] { --arrive-from: var(--beige); }
.page-home .swap-pin { opacity: clamp(0, calc((var(--p, 1) - .85) * 7), 1); }
.page-home section[aria-labelledby="w-h"] > .wrap { opacity: clamp(0, calc((var(--p, 1) - .85) * 7), 1); }
.swap-pin { position: sticky; top: var(--header-h); height: calc(100vh - var(--header-h)); height: calc(100svh - var(--header-h)); display: flex; flex-direction: column; justify-content: center; z-index: 2; }
/* 29/10 (the owner): the words do not rotate away, they stay and make a small text that shows the order: the lead line, then one line per step, each rising in as the scroll reaches it.
   The lead sentence is on one line (its size follows the width of the column, see .swap-col), every step has its own line; the steps already shown go lighter, the current one is full ink. */
/* 29/10 (Sam): the section is titled like the two that follow it, at the same size, and the title stays while the steps run. */
.swap-head { margin: 0 auto clamp(14px, 2.2vw, 28px); flex: none; }
.swap-col { container-type: inline-size; min-width: 0; }
.swap-line { margin: 0; font-weight: 800; color: var(--choco); } /* 29/10 (Sam): the dark brown of the guideline carries the text */
.swap-slot { margin: 0; font-weight: 800; color: var(--choco); } /* 28/10: same colour as the line above it, no italic */
/* 29/10 (Sam): the step being read is the brand blue, the ones already read and the ones still to come are the dark brown. */
.swap-slot span.on { color: var(--blue); }
.swap-slot span { display: block; opacity: 0; transform: translateY(.5em); transition: transform .9s cubic-bezier(.22,.61,.36,1) .1s, opacity .7s ease .1s; will-change: transform, opacity; }
.swap-texts { display: grid; margin-top: clamp(10px, 1.6vw, 20px); max-width: 46ch; } /* 28/10 (Sam): less space between the word and its line */
.swap-texts p { grid-area: 1 / 1; margin: 0; opacity: 0; line-height: 1.55; color: var(--body); font-size: clamp(1.15rem, 2vw, 1.4rem); transform: translateY(8px); transition: opacity .8s ease .2s, transform .9s cubic-bezier(.22,.61,.36,1) .2s; }
.swap-texts p.on { opacity: 1; transform: none; }
.swap-texts b { display: block; color: var(--ink); font-weight: 800; margin-bottom: 4px; }
.swap-count { margin-top: 14px; font-size: .78rem; font-weight: 700; letter-spacing: .12em; color: var(--orange); font-variant-numeric: tabular-nums; }
/* .swap-alt: the three statements as text. Screen readers get it while the swap runs (visually hidden);
   it is the visible list without JS, with reduced motion and when site.js sets .flat on .swap (the pinned content is taller than
   the pin: a short or sideways phone, a short window, 200 % text), so nothing spills out of the pin over the hero. */
.swap-alt { position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0; border: 0; overflow: hidden; clip: rect(0 0 0 0); clip-path: inset(50%); white-space: nowrap; }
.swap-alt p { max-width: 52ch; }
html:not(.js) .swap, .still .swap, .swap.flat { height: auto; }
html:not(.js) .swap-pin, .still .swap-pin, .swap.flat .swap-pin { position: static; height: auto; padding: 24px 0; }
html:not(.js) .swap-slot, .still .swap-slot, .swap.flat .swap-slot { display: block; }
html:not(.js) .swap-slot span, .still .swap-slot span, .swap.flat .swap-slot span { display: block; opacity: 1; transform: none; margin-bottom: 18px; transition: none; }
html:not(.js) .swap-texts, .still .swap-texts, .swap.flat .swap-texts { display: none; }
html:not(.js) .swap-count, .still .swap-count, .swap.flat .swap-count { display: none; }
html:not(.js) .swap-alt, .still .swap-alt, .swap.flat .swap-alt { position: static; width: auto; height: auto; margin: 0; overflow: visible; clip: auto; clip-path: none; white-space: normal; }
.swap-grid { display: grid; gap: clamp(24px, 4vw, 64px); grid-template-columns: 1fr; align-items: center; }
/* 29/10 (Sam: the page is not consistent between a phone and a computer). One rank below the section titles and, like them,
   measured against the viewport: 46.1 px against 57.6 px at 1280, 25.6 px against 32 px at 375 — the same ratio at both ends.
   Sized against its own column it crossed over the titles between 508 and 899 px and halved at 900 px, where the grid splits. */
.swap-line, .swap-slot { font-size: clamp(1.6rem, 3.6vw, 2.6rem); line-height: 1.12; letter-spacing: -.03em; }
.swap-slot span.on { transform: none; opacity: 1; }
.swap-slot span.past { transform: none; opacity: 1; transition-delay: 0s; transition-duration: .9s, .6s; } /* 29/10 (Sam: "this grey is random"): the fade turned the ink into a grey that is in no guideline */
.swap-texts p:not(.on) { transition-delay: 0s; transition-duration: .4s; }
@media (min-width: 900px) {
  .swap-grid { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); align-items: start; }
  .swap-head { max-width: calc(var(--maxw) + 2 * var(--gutter)); } /* the title sits over its own column, not the full page */
}
@media (max-width: 760px) {
  .swap-pin { padding-top: 24px; }
}
/* a phone about 660 px high (an iPhone in Safari): the same layout with a tighter vertical rhythm, so the pinned swap still fits */
@media (max-width: 760px) and (max-height: 720px) {
  .swap-pin { padding-top: 12px; }
  .swap-grid { gap: 8px; }
  .swap-texts { margin-top: 12px; }
  .swap-texts p { font-size: 1rem; line-height: 1.5; }
  .swap-count { display: none; } /* the lines that stay already show where we are; the room goes to the drawing (the stack is three lines taller than the single word it replaced) */
}
@media (prefers-reduced-motion: reduce) {
  .swap-slot span, .swap-texts p { transition: none; }
}

/* ==================== @rings : human + tools rings ==================== */
/* Chips sit at fixed angles (tools/make_rings.py): nothing orbits. The motion here is the ring highlight that follows
   the word swap (site.js §2), plus one logo cross-fade every 4 s while the rings are on screen (site.js §4b).
   The SVG scales with its column, so text sizes step with the width: captions and ring labels render at 12 CSS px or more. */
.rings { width: 100%; max-width: 640px; justify-self: center; display: block; overflow: visible; }
/* 28/10 (Sam picked "Zoom arrière"): the drawing zooms out with the words. At the first word the human is alone and big, at the second the systems circle
   appears, at the third the tools circle. site.js section 2 sets data-step (1-3) and drops it in the static list; without JS or with reduced motion the whole drawing shows.
   While zoomed the svg clips at its own box, so the hidden outer circles cannot widen the page. */
/* 02/11 (Sam) : "Planning" et "Stockage" etaient coupes a l'arrivee. Le overflow:hidden sert au zoom des etapes 1 et 2 ;
   le dessin a donc 50 unites de marge de chaque cote dans son viewBox (-50 0 660 560), ce qui le reduit de 3 % et le fait
   tenir entier. L'origine passe en 50% 50% : elle reste le centre du dessin quel que soit le point de depart du viewBox. */
.rings .world { transform-box: view-box; transform-origin: 50% 50%; }
.rings .zs, .rings .zt { transition: opacity .7s ease .15s; }
.js:not(.still) .rings[data-step] { overflow: hidden; }
.js:not(.still) .rings[data-step] .world { transition: transform 1s cubic-bezier(.22, .61, .36, 1); }
.js:not(.still) .rings[data-step="1"] .world { transform: scale(2.15); }
.js:not(.still) .rings[data-step="2"] .world { transform: scale(1.3); }
.js:not(.still) .rings[data-step="1"] .zs, .js:not(.still) .rings[data-step="1"] .zt, .js:not(.still) .rings[data-step="2"] .zt { opacity: 0; }
@media (prefers-reduced-motion: reduce) { .rings .world, .rings .zs, .rings .zt { transition: none; } }
/* 29/10 (Sam: "il faut que les outils tournent, littéralement"). site.js pauses the SVG animations when the visitor
   asks for less motion; SMIL cannot be stopped from CSS. */
/* active ring: brown line and a cream band (beige would match the section and make the band look erased) */
.rings .ring { fill: #fff; stroke: var(--line); stroke-width: 2; transition: fill .5s, stroke .5s; }
.rings .ring.on { fill: var(--cream); stroke: var(--brown); }
.rings .human path { fill: none; stroke: var(--ink); stroke-width: 3.2; stroke-linecap: round; stroke-linejoin: round; transition: stroke .5s; }
.rings .human.on path { stroke: var(--brown); }
.rings .node .bg { fill: #fff; stroke: var(--line); stroke-width: 2; transition: stroke .5s; }
.rings .node.on .bg { stroke: var(--brown); }
.rings .node .ic { fill: currentColor; }
/* text halo in cream: it hides ring lines behind the letters and is near-invisible on white, cream and the beige page */
/* 29/10 (Sam): HUMAIN, SYSTEMES and OUTILS in the dark brown of the guideline, not a grey */
.rings .rl { font-family: var(--font-2); font-weight: 800; font-size: 13px; letter-spacing: .16em; text-anchor: middle; fill: var(--choco); text-transform: uppercase; paint-order: stroke; stroke: var(--beige); stroke-width: 5px; stroke-linejoin: round; transition: fill .5s; }
.rings .rl.on { fill: var(--choco); }
.rings .cap { font-family: var(--font-1); font-weight: 600; font-size: 13.5px; letter-spacing: .02em; fill: var(--ink); paint-order: stroke; stroke: var(--cream); stroke-width: 4px; stroke-linejoin: round; }
html:not(.js) .rings .ring, .still .rings .ring { fill: var(--cream); }
@media (min-width: 900px) and (max-width: 1199.98px) {
  .rings .cap, .rings .rl { font-size: 15.5px; }
}
@media (min-width: 900px) and (max-width: 1023.98px) {
  .rings .cap, .rings .rl { font-size: 17.5px; }
}
@media (max-width: 899px) {
  .rings { max-width: var(--rings-w, 340px); } /* 30/10 (the owner): site.js §2 lowers --rings-w on a short phone so the pinned swap still fits */
  .rings .cap, .rings .rl { font-size: 21.2px; }
}

/* --- 11/11 (Sam) : le contexte avant la demo de l'accueil ------------------------------------
   « d'abord un texte qui explique rapidement le contexte, pour que chaque personne comprenne le
   vrai probleme ». La demo montrait la solution a des gens qui n'avaient pas le probleme en tete.
   Trois paragraphes, la largeur d'une colonne de lecture, et la demo juste apres. */
.demo-intro { margin-top: clamp(28px, 4vw, 48px); max-width: 68ch;
  display: grid; gap: clamp(12px, 1.4vw, 18px); }
.demo-intro-k { font-family: var(--font-2); font-weight: 800; font-size: .72rem; letter-spacing: .15em;
  text-transform: uppercase; color: var(--brown); margin: 0; }
.demo-intro p { margin: 0; font-size: clamp(1.02rem, 1.25vw, 1.15rem); line-height: 1.65; color: var(--body); }
.demo-intro p:last-child { color: var(--ink); font-weight: 500; }

/* ==================== @demo : demo frames and demo modal ==================== */
.demo { border: 1px solid var(--line); border-radius: 6px; overflow: hidden; background: #fff; }
.demo iframe { display: block; width: 100%; height: clamp(520px, 78vh, 760px); border: 0; background: #fff; }
.demo-bar { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 8px 16px; padding: 10px 14px; border-top: 1px solid var(--line); font-size: .85rem; color: var(--muted); }
.demo-bar a { font-weight: 700; }
/* ---- WP-E: the placeholder has the final iframe height (same formula as .demo iframe), so mounting moves nothing ---- */
.demo-ph { display: grid; place-items: center; height: clamp(520px, 78vh, 760px); color: var(--muted); font-weight: 600; background: var(--beige); }
/* Phones and touch screens: the demo never loads in the page. A poster (still + result line + play label) takes the placeholder's place and opens the full-screen window.
   Still: 2:1, at most 168 px tall. Result bar: 64 px. The placeholder has the same height, so swapping them moves nothing. */
@media (max-width: 760px), (pointer: coarse) { .demo[data-auto] { max-width: 464px; } .demo-ph { height: calc(min(168px, (100vw - 2 * clamp(20px, 5vw, 56px) - 2px) / 2) + 64px); } }
.demo--poster { overflow: visible; border: 0; border-radius: 0; background: none; } /* the poster card is the frame: its focus ring must not be clipped by .demo */
.demo-poster { position: relative; display: block; width: 100%; padding: 0; border: 1px solid var(--line); border-radius: 6px; background: var(--surface); color: var(--beige); font: inherit; text-align: left; cursor: pointer; overflow: hidden; -webkit-tap-highlight-color: transparent; }
.demo-still { position: relative; display: block; }
.demo-still img { display: block; width: 100%; height: auto; max-height: 168px; object-fit: cover; object-position: 50% 0; }
.demo-play { position: absolute; left: 50%; top: 78%; transform: translate(-50%, -50%); display: inline-flex; align-items: center; gap: 9px; min-height: 40px; padding: 0 18px 0 14px; border-radius: 999px; background: var(--surface); color: var(--beige); font-weight: 700; font-size: .95rem; white-space: nowrap; box-shadow: 0 6px 18px rgba(71, 47, 36, .35); transition: transform .15s ease; }
.demo-play svg { flex: none; color: var(--blue); }
.demo-poster:active .demo-play { transform: translate(-50%, -50%) scale(.97); }
.demo-poster:focus-visible { outline: 3px solid var(--brown); outline-offset: 3px; }
@media (prefers-reduced-motion: reduce) { .demo-play { transition: none; } }
.case .demo-btn { margin-top: 16px; }
.case .demo { margin-top: 14px; }
/* Full-screen demo window (window.TRAX.openDemoModal): brown title bar, 44 px close button, nothing behind it can scroll */
html.modal-open { overflow: hidden; }
.demo-modal { position: fixed; inset: 0; z-index: 100; display: grid; place-items: center; padding: 16px; background: rgba(71, 47, 36, .82); overscroll-behavior: contain; }
.dm { display: flex; flex-direction: column; width: min(1100px, 100%); height: min(90vh, 820px); height: min(90svh, 820px); background: var(--surface); border-radius: 16px; overflow: hidden; box-shadow: 0 24px 64px rgba(0, 0, 0, .35); }
.dm-head { flex: none; display: flex; align-items: center; justify-content: space-between; gap: 8px; min-height: 52px; padding: 4px 4px 4px 18px; background: var(--surface); color: var(--beige); }
.dm-title { display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2; overflow: hidden; font-size: .95rem; font-weight: 700; line-height: 1.25; }
.dm-x { flex: none; display: grid; place-items: center; width: 44px; height: 44px; padding: 0; border: 0; border-radius: 50%; background: transparent; color: var(--beige); cursor: pointer; }
.dm-x:hover { background: rgba(249, 232, 212, .14); }
.dm-x:focus-visible { outline: 2px solid var(--beige); outline-offset: -4px; }
.dm iframe { flex: 1; width: 100%; min-height: 0; border: 0; background: #fff; }
@media (max-width: 760px), (pointer: coarse), (max-height: 500px) { /* phones, touch screens, and a phone turned sideways: the whole screen */
  .demo-modal { display: block; padding: 0; }
  .dm { width: 100%; height: 100%; border-radius: 0; box-shadow: none; padding: env(safe-area-inset-top) env(safe-area-inset-right) env(safe-area-inset-bottom) env(safe-area-inset-left); }
}
@media (max-height: 500px) { .dm-head { min-height: 44px; padding-top: 0; padding-bottom: 0; } }

/* ==================== @intl-globe : international block and map ==================== */
/* @services rule placed before its region: it must stay before the equal-specificity rule below (cascade order); its selector matches nothing on any page today */
.situation > h2 { font-size: clamp(1.6rem, 3.4vw, 2.5rem); max-width: 26ch; margin-bottom: 28px; }
.presence { display: grid; gap: clamp(28px, 4.4vw, 56px); grid-template-columns: minmax(0, 1fr); align-items: start; }
.presence-text .lead { margin: clamp(20px, 3vw, 32px) 0 0; }
@media (min-width: 960px) {
  .presence-text { display: grid; grid-template-columns: minmax(0, 5fr) minmax(0, 7fr); gap: clamp(32px, 5vw, 80px); align-items: start; }
  .presence-text .lead { margin-top: .35em; }
}
/* 29/10 (the owner): the old flat dot map is back ("restore the old flat map"), the whole width of the block: beige dots, the blue links from Paris drawing themselves when it comes on
   screen (site.js section 12) with a dot travelling along each, the cities pulsing. The names are in the SVG (hidden under 700 px, where they would be too small: the paragraph names them). */
.map-wrap { position: relative; width: 100%; }
.map { width: 100%; height: auto; display: block; overflow: visible; }
.map-land { fill: none; stroke: rgba(249,232,212,.45); stroke-width: 4.4; stroke-linecap: round; }
.map-arc { fill: none; stroke: var(--orange); stroke-width: 1.8; /* 08/11 (the owner): the routes in orange */  stroke-dasharray: 1; stroke-dashoffset: 1; }
.map.in .map-arc, html:not(.js) .map-arc, .still .map-arc { stroke-dashoffset: 0; }
.map.in .map-arc { animation: arc-draw 1.8s cubic-bezier(.3,.1,.2,1) var(--d) both; }
@keyframes arc-draw { from { stroke-dashoffset: 1; } to { stroke-dashoffset: 0; } }
.map-trav { fill: var(--beige); opacity: 0; offset-distance: 0%; }
.map.live .map-trav { animation: trav 4.5s linear var(--d) infinite; }
@keyframes trav { 0% { offset-distance: 0%; opacity: 0; } 10% { opacity: 1; } 90% { opacity: 1; } 100% { offset-distance: 100%; opacity: 0; } }
.city .pt { fill: var(--blue); stroke: var(--brown); stroke-width: 2; }
.city .pulse { fill: var(--blue); opacity: .3; transform-box: fill-box; transform-origin: center; }
.map.live .city .pulse { animation: pulse 2.8s ease-out infinite; }
.city--hub .pt, .city--hub .pulse { fill: var(--beige); }
@keyframes pulse { 0% { transform: scale(1); opacity: .4; } 100% { transform: scale(4.2); opacity: 0; } }
.map-lbl { font: 800 22px var(--font-2); fill: var(--beige); }
/* 29/10 (Sam): every city reads the same; Paris stays the head office through its marker, not its label. */
.map-lbl--ams { transform: translateY(-9px); }
.map-lbl--anv { transform: translateY(11px); }
/* 29/10 (Sam: "on iPhone we cannot see the cities"). They were hidden here because 22 px of a 1050-wide viewBox
   lands at about 7 px once the map is 335 px across. They are back in type that survives the scale, and Paris,
   Amsterdam and Antwerp are pulled apart so the bigger words do not sit on top of each other. */
@media (max-width: 700px) {
  .map-lbl { font-size: 40px; }
  .map-lbl--ams { transform: translateY(-40px); }
  .map-lbl--anv { transform: translateY(38px); }
}
@media (prefers-reduced-motion: reduce) { .map-trav, .city .pulse { animation: none !important; opacity: 0; } .map-arc { animation: none !important; stroke-dashoffset: 0; } }

/* ==================== @services : Services tree ==================== */
.fig { padding: 28px 20px 28px 0; border-bottom: 1px solid var(--line); }
.fig b { display: block; font-size: clamp(2.4rem, 8vw, 6rem); overflow-wrap: anywhere; font-weight: 800; line-height: 1; letter-spacing: -.04em; font-variant-numeric: tabular-nums; }
.fig b small { font-size: .4em; letter-spacing: 0; margin-left: .15em; }
/* WP-K (CLS): the number's real text is always its final value, so the box never changes size. While it counts (site.js §3) the
   real text is transparent and the count is painted over it by ::after, which is out of the flow: the unit beside it cannot move. */
.fig b .cnt { position: relative; display: inline-block; }
.fig b .cnt.counting { color: transparent; }
/* 05/11 : la couleur etait ecrite en dur en brun. Sur la carte de valeur, ou le chiffre est bleu sur fond brun,
   le compte en cours etait donc invisible — on ne voyait que l'unite et la legende pendant une seconde. */
.fig b .cnt.counting::after { content: attr(data-now); position: absolute; left: 0; top: 0; color: inherit; }
.fig > span { display: block; margin-top: 10px; font-size: .92rem; line-height: 1.4; color: var(--body); max-width: 22ch; } /* direct children only: the number's .cnt span must not take these */
.situation { padding: clamp(36px, 5vw, 64px) 0 0; }
.sit-n { display: block; margin-bottom: 10px; font-size: .72rem; font-weight: 800; letter-spacing: .12em; text-transform: uppercase; }
.case { padding: 0; border-top: 1px solid var(--line); position: relative; border-radius: 14px; background: #fbf3e8; }
.case p { margin: 0; }
.case [hidden] { display: none; }
.tree-hint { margin: 0 0 18px; font-weight: 600; color: var(--muted); max-width: 52ch; }
.tree { position: relative; display: grid; grid-template-columns: minmax(0, 1fr); gap: 12px; }
details > summary { list-style: none; cursor: pointer; }
details > summary::-webkit-details-marker { display: none; }
.sit { position: relative; border: 1.5px solid var(--line); border-radius: 18px; background: #fff; transition: border-color .2s; }
.sit > summary { display: grid; grid-template-columns: 22px 1fr 22px; gap: 14px; align-items: center; min-height: 68px; padding: 14px 16px; }
.sit .node { width: 18px; height: 18px; border-radius: 50%; border: 3px solid var(--brown); background: #fff; }
.sit[open] .node { background: var(--surface); }
.sit-lab { display: grid; gap: 2px; min-width: 0; }
.sit-t { overflow-wrap: anywhere; font-weight: 800; font-size: clamp(1.05rem, 2.2vw, 1.4rem); line-height: 1.25; color: var(--ink); letter-spacing: -.01em; }
.chev { width: 12px; height: 12px; border-right: 2.5px solid var(--ink); border-bottom: 2.5px solid var(--ink); transform: rotate(45deg); transition: transform .25s; justify-self: center; margin-top: -4px; }
details[open] > summary .chev { transform: rotate(-135deg); margin-top: 4px; }
.branches { --branch: #8cb5c7; position: relative; margin: 0 16px 14px 25px; padding-left: 20px; border-left: 2.5px solid var(--branch); display: grid; grid-template-columns: minmax(0, 1fr); gap: 8px; } /* WP-F, P1-10: the tree lines have their own token, so links and focus rings in the tree keep the page colours */
.case::before { content: ""; position: absolute; left: -22px; top: 28px; width: 20px; height: 2.5px; background: var(--branch); }
.case > summary { display: grid; grid-template-columns: 1fr 22px; gap: 4px 12px; align-items: center; min-height: 56px; padding: 12px 14px; }
.case .dot { display: none; }
.case-t { grid-column: 1; min-width: 0; overflow-wrap: anywhere; font-weight: 700; line-height: 1.3; color: var(--ink); }
.case > summary .chev { grid-column: 2; grid-row: 1 / span 2; }
.case-body { padding: 4px 14px 16px; overflow-wrap: anywhere; } /* long words break instead of widening the page at 200 % text */
.case-body p { margin: 0 0 14px; }
/* 29/10 (Sam's documents): who an example is about, its detailed description (before / after / the role of AI / result), the tagline of a situation */
.case-body .case-who { margin: 0 0 8px; font-size: .9rem; font-weight: 700; color: var(--muted); }
.case-body .case-more { margin-top: 14px; }
.case-detail { margin: 6px 0 0; }
.case-detail dt { margin-top: 14px; font-size: .78rem; font-weight: 800; letter-spacing: .1em; text-transform: uppercase; color: var(--brown); }
.case-detail dd { margin: 4px 0 0; }
.case-detail dd p:last-child { margin-bottom: 0; }
.case-body .case-ai { margin: 16px 0 0; padding-top: 12px; border-top: 1px solid var(--line); font-weight: 700; color: var(--ink); }
.sit-tag { margin: 0 0 2px; font-weight: 600; color: var(--muted); }
/* 28/10 (Sam): the short text of the Services page is a list of the sectors of the examples */
.more { margin-top: 20px; }
.more > summary { display: inline-flex; align-items: center; gap: 10px; min-height: 44px; font-weight: 800; color: var(--ink); }
.more > summary::after { content: ""; width: 10px; height: 10px; border-right: 2.5px solid var(--ink); border-bottom: 2.5px solid var(--ink); transform: rotate(45deg); transition: transform .25s; margin-top: -4px; }
.more[open] > summary::after { transform: rotate(-135deg); margin-top: 4px; }
.fig b, .sit-n { color: var(--brown); }
/* ==================== Interventions : les onze demos se voient ====================
   30/10 (Sam) : la liste depliante a trois etages cachait les demos derriere trois clics. La page montre
   maintenant les cinq situations en cartes, puis chaque exemple par la vignette de sa propre demo.
   Deux fonds seulement, comme partout : le beige du haut, puis du blanc. Le choco reste la couleur du cadre
   (barre, bande de fin, pied de page) et ne sert pas dans le corps. */

/* le haut : titre, phrase, puis les cinq situations */
.sv-top { padding-bottom: clamp(26px, 3.4vw, 40px); }
.bbx { margin-top: clamp(26px, 3.4vw, 40px); }
.bbx-k { margin: 0 0 clamp(14px, 1.8vw, 18px); font-size: .7rem; font-weight: 800; letter-spacing: .15em;
  text-transform: uppercase; color: var(--brown); }
.bbx-g { display: grid; grid-template-columns: minmax(0, 1fr); gap: 12px; }
/* cartes blanches et non beiges : le haut de page est deja beige, des cartes beiges y disparaitraient */
.bb { position: relative; overflow: hidden; display: flex; flex-direction: column; gap: 9px;
  padding: clamp(18px, 2.2vw, 24px); text-decoration: none; color: inherit; border-radius: 12px;
  background: #fff; border: 1px solid var(--line); transition: border-color .2s, transform .2s; }
.bb:hover { border-color: var(--brown); transform: translateY(-3px); }
/* 02/11 (Sam) : le chiffre fantome faisait 4.4rem et tenait toute la hauteur de la carte. C'est un reperage, pas un
   decor : petit, brun, lisible, en haut a droite. */
.bb-n { position: absolute; right: 14px; top: 13px; font-size: 1.3rem; font-weight: 800; letter-spacing: -.02em;
  color: var(--orange); line-height: 1; font-variant-numeric: tabular-nums; } /* 08/11: orange (was brown at .75) */
/* 03/11 (Sam) : sur telephone le titre passe a deux lignes et venait buter sous le chiffre. On lui reserve la
   place du chiffre au lieu de l'y laisser passer. */
.bb-t { position: relative; padding-right: 46px; font-size: .98rem; font-weight: 800; letter-spacing: -.015em; line-height: 1.24; color: var(--choco); }
.bb-c { position: relative; margin-top: auto; font-size: .74rem; font-weight: 700; color: var(--brown); }
.bb-c i { font-style: normal; display: inline-block; transition: transform .2s; }
.bb:hover .bb-c i { transform: translateX(4px); }

/* une section par situation.
   02/11 (Sam) : en descendant dans une situation on perdait son titre, et un "175 h" lu sans la situation qui le
   motive ne veut plus rien dire — sur telephone la situation sortait de l'ecran des la premiere carte. Le titre reste
   donc colle sous la barre et celui de la situation suivante vient le pousser. Tout le creux entre deux situations
   est au-dessous (padding-bottom du .wrap, plus rien sur la section) : le titre suivant est ainsi deja en place a
   l'instant ou le precedent s'en va, sans blanc entre les deux. Meme procede que .ap-fig sur la page Approche. */
.sv-s { background: var(--light-beige); scroll-margin-top: var(--header-h); }
.sv-s > .wrap { padding-bottom: clamp(40px, 5.5vw, 80px); }
.sv-s > .wrap > h2 { position: sticky; top: var(--header-h); z-index: 4; background: var(--light-beige);
  display: grid; grid-template-columns: auto minmax(0, 1fr); gap: clamp(12px, 2vw, 20px);
  align-items: baseline; font-size: clamp(1.5rem, 3.1vw, 2.3rem); line-height: 1.12; letter-spacing: -.028em;
  margin: 0 0 clamp(22px, 3vw, 34px); padding: clamp(14px, 2vw, 22px) 0 clamp(14px, 2vw, 20px);
  border-bottom: 2px solid var(--choco); }
.sv-s > .wrap > h2 span { font-size: .46em; font-weight: 800; letter-spacing: .14em; color: var(--brown); }
/* le texte qui defile dessous se coupait net une lettre sous le filet. Meme fondu que .ap-fig sur Approche. */
.sv-s > .wrap > h2::after { content: ""; position: absolute; left: 0; right: 0; top: calc(100% + 2px); height: 18px;
  pointer-events: none; background: linear-gradient(to bottom, var(--light-beige), rgba(254, 240, 222, 0)); }
.sv-g { display: grid; grid-template-columns: minmax(0, 1fr); gap: clamp(26px, 3.4vw, 42px); align-items: start; }
.sv-c { min-width: 0; scroll-margin-top: calc(var(--header-h) + var(--sv-h, 96px) + 10px); } /* le titre colle est au-dessus : --sv-h est sa hauteur, mesuree (site.js, 17) */

/* la vignette EST le bouton qui ouvre la demo (son intitule vit dans .demo-lab, site.js) */
.sv-shot { position: relative; display: block; width: 100%; padding: 0; border-radius: 13px; overflow: hidden;
  border: 1px solid var(--line); background: var(--beige); cursor: pointer; color: inherit; font: inherit;
  box-shadow: 0 16px 36px -24px rgba(71, 47, 36, .55);
  transition: transform .35s cubic-bezier(.2, .8, .2, 1), box-shadow .35s, border-color .2s; }
.sv-shot img { display: block; width: 100%; height: auto; }
.sv-shot:hover { transform: translateY(-5px); box-shadow: 0 26px 50px -24px rgba(71, 47, 36, .6); border-color: var(--brown); }
.sv-shot:focus-visible { outline: 3px solid var(--choco); outline-offset: 3px; }
.sv-play { position: absolute; left: 50%; top: 50%; width: 54px; height: 54px; margin: -27px 0 0 -27px;
  border-radius: 50%; background: var(--choco); opacity: 0; transition: opacity .3s, transform .3s cubic-bezier(.2, .8, .2, 1); }
/* le triangle, dessine plutot qu'ecrit, pour qu'aucune police n'en decide la forme */
.sv-play::after { content: ""; position: absolute; left: 21px; top: 17px; border: 10px solid transparent;
  border-left: 16px solid var(--beige); border-right: 0; }
.sv-shot:hover .sv-play, .sv-shot:focus-visible .sv-play { opacity: 1; transform: scale(1.08); }
/* l'intitule porte le nom accessible du bouton ; il se voit au survol, avec le triangle */
.sv-lab { position: absolute; left: 0; right: 0; bottom: 0; padding: 26px 14px 11px; text-align: center;
  font-size: .8rem; font-weight: 700; color: var(--beige); opacity: 0; transition: opacity .3s;
  background: linear-gradient(to top, rgba(71, 47, 36, .92), rgba(71, 47, 36, 0)); }
.sv-shot:hover .sv-lab, .sv-shot:focus-visible .sv-lab { opacity: 1; }

.sv-t { margin: 16px 0 0; font-size: clamp(1.2rem, 2.1vw, 1.48rem); font-weight: 800; letter-spacing: -.02em;
  line-height: 1.24; color: var(--choco); max-width: 28ch; }
.sv-c .demo { margin-top: 14px; }

/* 02/11 (Sam) : "Le detail" ne disait pas ce qui s'ouvre, et le triangle d'un <details> sous une carte n'invite a rien.
   C'est maintenant une ligne nommee ("Comment nous l'avons fait"), qui ouvre un panneau par-dessus la page (site.js §16).
   Le balisage reste un <details> : sans JavaScript il s'ouvre sur place, et le texte reste lisible. */
.sv-more { margin-top: 10px; }
.sv-more > summary { display: inline-flex; align-items: center; gap: 8px; min-height: 44px; cursor: pointer;
  font-size: .85rem; font-weight: 700; color: var(--brown); list-style: none; }
.sv-more > summary::-webkit-details-marker { display: none; }
.sv-more > summary > span { border-bottom: 1.5px solid transparent; transition: border-color .2s; }
.sv-more > summary:hover > span, .sv-more > summary:focus-visible > span { border-bottom-color: var(--brown); }
.sv-more > summary i { font-style: normal; display: inline-block; transition: transform .2s; }
.sv-more > summary:hover i { transform: translateX(4px); }
.sv-more-in { padding-top: 6px; }

/* le panneau lui-meme. Quatre couleurs : fond blanc, titre chocolat, etiquette brune, voile chocolat derriere. */
.sheet { width: min(720px, calc(100vw - 28px)); max-height: 86vh; padding: 0; border: 0; border-radius: 16px;
  background: #fff; color: var(--body); overflow: hidden; box-shadow: 0 40px 90px -40px rgba(71, 47, 36, .62); }
.sheet::backdrop { background: rgba(71, 47, 36, .62); }
.sheet-in { display: flex; flex-direction: column; max-height: 86vh; }
.sheet-h { position: relative; flex: none; padding: clamp(20px, 3vw, 28px) 64px 16px clamp(20px, 3vw, 32px);
  border-bottom: 1px solid var(--line); }
.sheet-k { display: block; font-size: .68rem; font-weight: 800; letter-spacing: .14em; text-transform: uppercase; color: var(--brown); }
.sheet-h h2 { margin: 7px 0 0; font-size: clamp(1.12rem, 2.4vw, 1.45rem); line-height: 1.22; letter-spacing: -.02em;
  color: var(--choco); max-width: 30ch; }
.sheet-x { position: absolute; right: clamp(12px, 1.6vw, 18px); top: clamp(14px, 1.8vw, 20px);
  width: 40px; height: 40px; display: grid; place-items: center; border-radius: 999px; border: 1px solid var(--line);
  background: #fff; color: var(--choco); font: 700 1.15rem/1 inherit; cursor: pointer; transition: background .2s, border-color .2s; }
.sheet-x:hover { background: var(--beige); border-color: var(--brown); }
.sheet-b { overflow-y: auto; overscroll-behavior: contain; padding: clamp(18px, 2.6vw, 26px) clamp(20px, 3vw, 32px) clamp(26px, 3.4vw, 34px); }
@media (max-width: 640px) {
  .sheet { width: 100vw; max-width: none; height: 100dvh; max-height: 100dvh; border-radius: 0; margin: 0; }
  .sheet-in { max-height: 100dvh; height: 100dvh; }
}
.case-lead { margin: 0 0 1.1em; font-weight: 500; color: var(--ink); }
.sv-figs { background: var(--beige); }
/* 02/11 (Sam : "pas aussi classe que sur la homepage"). Le bloc de fin avait son propre habillage, des filets sur du
   beige. Il reprend la carte de la home — la meme regle, pas une imitation : meme .value-card, meme tortue en
   filigrane, memes chiffres bleus. Sans le texte de gauche, la carte n'a plus qu'une colonne. */
.value-card--figs { grid-template-columns: minmax(0, 1fr); gap: clamp(16px, 2.2vw, 24px); }
.value-card--figs .value-figs { border-top: 0; padding-top: 0; }
.value-note { position: relative; z-index: 1; margin: 0; padding-top: clamp(14px, 2vw, 18px);
  border-top: 1px solid rgba(249, 232, 212, .26); font-size: .82rem; line-height: 1.45; color: rgba(249, 232, 212, .72); }

@media (min-width: 900px) { .sv-g { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (min-width: 1040px) { .bbx-g { grid-template-columns: repeat(5, minmax(0, 1fr)); } }
@media (min-width: 1280px) { .sv-g { grid-template-columns: repeat(3, minmax(0, 1fr)); gap: clamp(24px, 2.6vw, 34px); } }
/* sans survol (telephone, tablette) l'intitule et le triangle restent visibles : sinon rien ne dit que la vignette s'ouvre */
@media (hover: none) { .sv-lab, .sv-play { opacity: 1; } }

/* 29/10 (the owner): the four figures of the Services page are at the top, two over two (a square), beside the intro on a computer */
.svc-top { display: grid; grid-template-columns: minmax(0, 1fr); gap: clamp(28px, 4vw, 56px); margin-top: var(--title-gap); align-items: start; }
.svc-top > .lead { margin: 0; }
@media (min-width: 900px) { .svc-top { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); } }
.sit[open] { border-color: var(--brown); }
.chev, .more > summary::after { border-color: var(--brown); }
.demo-bar a { color: var(--brown); } /* WP-F, P1-12: was blue on white (about 2.2:1); brown on white is 7.6:1 */
@media (min-width: 900px) {
  .figs { grid-template-columns: repeat(4, 1fr); }
  .tree { gap: 14px; }
  .sit > summary { padding: 18px 22px; grid-template-columns: 26px 1fr 22px; }
  .branches { margin: 0 22px 18px 33px; }
}
@media (max-width: 760px) {
  /* WP-F, P2-9: the text column of an example is at least 290 px at 390 (it was 257); the tick keeps joining the line to the card (left = -padding - 2px) */
  .branches { margin: 0 8px 12px 8px; padding-left: 12px; }
  .case::before { left: -14px; width: 12px; }
  .case-body { padding: 4px 12px 16px; }
}

/* ==================== @finder : turtle assistant (pill and box) on Home, About and Services ==================== */
.finder-pill { position: fixed; right: 14px; right: max(14px, env(safe-area-inset-right)); bottom: 10px; bottom: calc(10px + env(safe-area-inset-bottom)); z-index: 88; display: flex; align-items: center; gap: 8px; border-radius: 999px; border: 0; background: transparent; color: #f9e8d4; font: inherit; font-weight: 800; cursor: pointer; box-shadow: none; /* 08/11: the hand-drawn shape is its ::before (@buttons) */ min-height: 44px; padding: 4px 14px 4px 8px; font-size: .78rem; transition: opacity .2s, transform .4s cubic-bezier(.2, .7, .2, 1); }
.finder-pill.is-away:not(:focus-visible) { opacity: 0; pointer-events: none; transform: translateY(100vh); transition: opacity .2s, transform 0s .2s; } /* WP-F: fades out, then waits a screen below while the closing call to action or the footer is on screen (a keyboard focus brings it back) */
.pill-turtle { position: relative; display: block; width: 38px; height: 23px; }
/* 28/10 (Sam: the chatbot from the first page; owner: not over the hero text): on Home the pill waits out of sight while the hero is on screen, then arrives like a notification */
.finder-pill.is-wait:not(:focus-visible) { opacity: 0; pointer-events: none; transform: translateY(18px); }
.finder-pill.is-wait .t-leg { animation-play-state: paused; } /* the legs start to swing when it arrives */
.pill-dot { position: absolute; top: -2px; right: -2px; width: 13px; height: 13px; border-radius: 50%; background: var(--blue); border: 2px solid var(--surface); }
.finder-pill.seen .pill-dot { display: none; }
/* WP-F: on a phone the label made the pill 254 px wide on a 375 px screen, so while scrolling it sat over two thirds of a line.
   It already steps aside for the closing call to action and the footer, but not for the body text. Below 760 px it keeps the turtle
   alone: the name stays in the accessible tree, the target stays 52 px, and it covers the corner instead of the words. */
@media (max-width: 760px) {
  .finder-pill { width: 52px; height: 52px; padding: 0; gap: 0; justify-content: center; --btn-h: 52px; } /* the two hand-drawn ends meet: a round pebble */
  .finder-pill::before { inset: 0; -webkit-mask-size: 50% 100%, 50% 100%, 0 0; mask-size: 50% 100%, 50% 100%, 0 0; } /* no middle slice at this size */
  .finder-pill .pill-dot { top: 3px; right: 3px; } /* on the pebble's edge, not beside it */
  .pill-label { position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0; border: 0; overflow: hidden; clip: rect(0 0 0 0); clip-path: inset(50%); white-space: nowrap; }
}
.finder-pill[hidden], .finder[hidden] { display: none; }
.finder [hidden] { display: none !important; } /* WP-F, P0-5: author display rules (.finder-form, .finder-chips, .finder-link) were overriding the hidden attribute */
.finder { position: fixed; right: 14px; right: max(14px, env(safe-area-inset-right)); bottom: 10px; bottom: calc(10px + env(safe-area-inset-bottom)); z-index: 89; max-height: min(50vh, 440px); max-height: min(50svh, 440px); overflow: auto; overscroll-behavior: contain; background: var(--surface); color: #f9e8d4; box-shadow: 0 18px 48px rgba(20,10,4,.45); animation: finder-in .32s cubic-bezier(.2,.8,.2,1); width: min(352px, calc(100vw - 24px)); padding: 12px 14px; border-radius: 20px; }
.finder-bar { display: flow-root; position: sticky; top: 0; height: 0; z-index: 2; } /* WP-F: zero-height strip that holds the close button, so it stays in view when the box scrolls */
.finder-x { position: absolute; border: 0; background: rgba(var(--surface-rgb),.92); border-radius: 50%; line-height: 1; color: #f9e8d4; cursor: pointer; z-index: 2; right: -14px; top: -12px; width: 44px; height: 44px; min-height: 44px; font-size: 1.5rem; opacity: .9; box-shadow: 0 1px 6px rgba(20,10,4,.3); }
.finder-top { position: relative; display: flex; align-items: flex-end; padding-right: 0; margin-top: 32px; gap: 10px; }
.finder-turtle { position: relative; flex: none; margin: 0 0 2px; width: 52px; height: 32px; margin-bottom: 0; }
.finder-turtle .turtle { position: absolute; left: 0; top: 0; height: 32px; }
.finder .t-leg, .finder-pill .t-leg { animation: 1.7s ease-in-out infinite alternate; }
.finder .t-a, .finder-pill .t-a { animation-name: fstep-a; }
.finder .t-b, .finder-pill .t-b { animation-name: fstep-b; }
/* WCAG 2.2.2: the pill's legs swing four and a half times (7.65 s), end upright, then stand still. The open panel's turtle follows the visitor's own action and keeps going. */
.finder-pill .t-leg { animation-iteration-count: 4.5; }
.finder.talking .t-leg { animation-duration: .5s; }
.finder.talking .finder-turtle { animation: nod .5s ease-in-out infinite alternate; }
@keyframes fstep-a { from { transform: rotate(-14deg); } to { transform: rotate(14deg); } }
@keyframes fstep-b { from { transform: rotate(14deg); } to { transform: rotate(-14deg); } }
@keyframes nod { from { transform: translateY(0); } to { transform: translateY(-3px); } }
.finder-form { display: grid; grid-template-columns: 1fr auto; margin-top: 12px; gap: 8px; }
.finder-form input { min-width: 0; padding: 8px 14px; border: 2px solid transparent; font: inherit; color: var(--ink); background: #fff; min-height: 44px; font-size: 16px; border-radius: 12px; } /* 16 px: iOS does not zoom the page on focus */
.finder-form input:focus { outline: 3px solid #8cb5c7; border-color: #fff; }
.finder-chips { display: flex; flex-wrap: wrap; margin: 0; gap: 6px; }
.chip { border-radius: 999px; border: 1.5px solid rgba(249,232,212,.4); background: transparent; color: #f9e8d4; font: inherit; font-weight: 600; cursor: pointer; transition: background .2s; border-color: rgba(249,232,212,.3); min-height: 44px; padding: 5px 11px; font-size: .76rem; line-height: 1.2; text-align: left; }
.chip:hover { background: rgba(249,232,212,.16); }
.rc { padding: 14px; border-radius: 16px; background: #fff; color: var(--ink); display: grid; gap: 6px; }
.rc b { line-height: 1.3; }
.rc-row { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 6px; }
.finder .btn--ghost { --btn-bg: transparent; color: var(--ink); --btn-line: #cdbfae; }
/* @buttons rule kept after ".finder .btn--ghost": equal specificity, the cascade order must not change */
.btn--ghost:hover { --btn-bg: var(--beige); color: var(--ink); --btn-line: var(--brown); }
.finder .rc .btn--ghost:hover { --btn-bg: var(--beige); }
@keyframes finder-in { from { opacity: 0; transform: translateY(14px) scale(.98); } to { opacity: 1; transform: none; } }
.finder-x:hover { opacity: 1; }
/* 08/11: no filter on the assistant's turtle any more: its parts are the designer's brown turtle with the beige outline (tools/make_turtle.py) */
.say { position: relative; flex: 1; min-width: 0; margin: 0; background: #fff; color: var(--ink); display: grid; gap: 3px; box-shadow: none; padding: 9px 12px; border-radius: 14px; }
.say::before { content: ""; position: absolute; background: #fff; border-radius: 3px; transform: rotate(45deg); width: 11px; height: 11px; bottom: 11px; left: -5px; }
.finder-title { font-weight: 800; letter-spacing: -.01em; font-size: .9rem; line-height: 1.2; }
.finder-form .btn { border-radius: 14px; min-height: 44px; padding: 6px 14px; font-size: .85rem; }
.finder .finder-go { --btn-bg: var(--beige); color: var(--choco); --btn-line: var(--beige); } /* WP-F, P0-5: was brown on the brown panel; text 10:1, edge 6:1 */
.finder .finder-go:hover { --btn-bg: #fff; color: var(--choco); --btn-line: #fff; }
html.has-finder { scroll-padding-bottom: 72px; } /* WP-F: keyboard focus is not scrolled under the pill */
.finder-sub { margin: 8px 2px 0; font-size: .78rem; color: #e5d3bc; font-weight: 500; line-height: 1.35; }
.finder-main { margin-top: 8px; }
.chip--wide { border-radius: 12px; max-width: 100%; }
.finder-link { display: inline-block; margin-top: 8px; padding: 4px 2px; background: none; border: 0; color: #e5d3bc; font: inherit; font-weight: 600; font-size: .78rem; text-decoration: underline; text-underline-offset: 3px; cursor: pointer; }
.finder-main .finder-form { margin-top: 10px; }
.finder-main .res-t { margin: 0 0 8px; font-weight: 800; font-size: .92rem; color: #f9e8d4; }
.finder-label { margin: 10px 0 5px; font-size: .68rem; font-weight: 800; letter-spacing: .1em; text-transform: uppercase; color: var(--beige); } /* WP-K: #cdbba3 was 4.04:1 on the brown panel at 10.9 px; beige is 6.3:1 */
.finder .rc { padding: 11px 12px; gap: 4px; border-radius: 14px; font-size: .84rem; line-height: 1.4; }
.finder .rc b { font-size: .9rem; }
.finder .rc .btn { min-height: 38px; padding: 6px 14px; font-size: .82rem; }
.finder-actions { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 12px; }
.finder-reply { margin-top: 10px; font-size: .84rem; line-height: 1.45; color: #f9e8d4; }
.finder-reply:empty { display: none; }
.finder-reply p { margin: 0 0 8px; }
.finder-reply .btn { min-height: 38px; font-size: .82rem; }
.finder-main > .btn, .finder-main a.btn { margin-top: 6px; --btn-bg: #f9e8d4; color: #3a2a21; --btn-line: #f9e8d4; min-height: 40px; font-size: .85rem; }
/* @buttons rule kept after ".finder-main > .btn": equal specificity, the cascade order must not change */
.btn:hover { color: #fff; }
/* @buttons rule kept after ".finder-form .btn": equal specificity, the cascade order must not change */
.btn--demo:hover { --btn-bg: #6f9db1; --btn-line: #6f9db1; color: #14181a; }
/* @buttons rule kept after ".finder-form .btn": equal specificity, the cascade order must not change */
.on-dark .btn { --btn-bg: #f9e8d4; --btn-line: #f9e8d4; color: #3a2a21; }
/* @buttons rule kept after ".finder-main > .btn": equal specificity, the cascade order must not change */
.btn:hover { --btn-bg: var(--surface); --btn-line: var(--surface); }
@media (pointer: coarse) {
  .finder-link { display: inline-flex; align-items: center; min-height: 44px; }
}
@media (max-width: 760px) {
  .finder-pill { right: 10px; right: max(10px, env(safe-area-inset-right)); }
  .finder { right: 10px; right: max(10px, env(safe-area-inset-right)); width: calc(100vw - 20px); }
  .has-finder .site-footer { padding-bottom: 84px; } /* WP-F: the pill never sits on the last footer links */
}
@media (prefers-reduced-motion: reduce) {
  .finder { animation: none; }
  .finder .t-leg, .finder-pill .t-leg, .finder.talking .finder-turtle { animation: none; }
  .finder-pill, .finder-pill.is-away:not(:focus-visible), .chip { transition: none; }
}

/* ==================== @about : About page ==================== */
/* owner (27/10, D15): the About text sections sit on beige and the three people on a white band; Services, Contact and Join stay white */
body.page-about, body.page-services, body.page-approach { --page-bg: var(--beige); } /* Services: 28/10 (Sam), everything on that page can be beige */
.sec--team { padding-top: 0; padding-bottom: 0; }   /* 09/11 : .team porte deja son propre padding, les deux se cumulaient */
.people { background: transparent; } /* 08/11 (the owner): no white band any more, the three people sit on the page beige too */
.photo { margin: 0; }
.photo img { width: 100%; height: auto; border-radius: 4px; }
.quote { font-size: clamp(1.6rem, 3.6vw, 2.6rem); font-weight: 700; line-height: 1.22; letter-spacing: -.02em; color: var(--ink); max-width: 26ch; margin: 0 0 22px; }
/* 29/10 (the owner): the story of the two founders in two rows, one photo each, on alternating sides; the title spans the page */
.story-h { max-width: 24em; text-wrap: balance; overflow-wrap: anywhere; }
.story-row { display: grid; grid-template-columns: minmax(0, 1fr); gap: clamp(22px, 4vw, 32px); margin-top: clamp(32px, 5vw, 72px); align-items: start; }
.story-text { min-width: 0; }
.story-text > p { max-width: 60ch; }
.story-text > p:last-child { margin-bottom: 0; }
.story-text > .quote { margin: clamp(20px, 3vw, 32px) 0 clamp(16px, 2vw, 24px); }
.story-photo img { display: block; width: 100%; height: auto; aspect-ratio: 1 / 1; object-fit: cover; border-radius: 10px; box-shadow: 0 22px 46px rgba(71, 47, 36, .16); }
/* 10/11 (Sam) : la photo de la terrasse remplace celle des chaises. Elle est en 3:2 et non carree :
   la forcer au carre coupait un tiers de sa largeur, donc les deux hommes par les bords. Elle garde
   presque tout son cadre (4:3 sur ordinateur, 3:2 entier sur telephone). */
.story-photo--a img { aspect-ratio: 4 / 3; object-position: 50% 50%; }
@media (max-width: 899px) { .story-row--flip .story-venn { order: -1; } }
.story-venn .venn-wrap { margin-top: 0; }
@media (min-width: 900px) {
  .story-row { grid-template-columns: minmax(0, 5fr) minmax(0, 6fr); gap: clamp(48px, 8vw, 128px); align-items: center; }
  .story-row--flip { grid-template-columns: minmax(0, 6fr) minmax(0, 5fr); }
  .story-photo img { aspect-ratio: 4 / 5; }
  .story-photo--a img { aspect-ratio: 3 / 2; object-position: 50% 50%; }
  .story-venn .venn-wrap { margin-top: 0; }
}
/* 29/10 (Sam picked option B for the band): Qui on est was the only page whose title had nothing beside it, while
   Contact and Nous rejoindre both carry a picture on the right. The brand turtle fills that space. Purely decorative,
   so it is hidden from screen readers, and it steps aside on a phone, where there is no empty space to fill. */
.about-top { display: grid; grid-template-columns: minmax(0, 1fr); gap: clamp(20px, 3vw, 40px); align-items: start; }
.about-turtle { align-self: center; }
.about-turtle { display: none; width: min(300px, 32vw); height: auto; justify-self: end; }
@media (min-width: 860px) {
  .about-top { grid-template-columns: minmax(0, 1fr) auto; }
  .about-turtle { display: block; }
}

/* 29/10 (Sam picked option B, replacing the 28/10 tabs and the 29/10 pair): one person per row, the portrait on one
   side and the text on the other, alternating, Samuel first. Side by side, the two bios differed by a paragraph and it
   showed; stacked, each gets one comfortable column and the difference disappears. Rafi closes, smaller. */
.team { padding: clamp(26px, 3.2vw, 44px) 0 clamp(40px, 6vw, 80px); }
.member { display: flex; flex-direction: column; gap: clamp(18px, 2.5vw, 28px); margin-bottom: clamp(44px, 6vw, 80px); }
.member:last-child { margin-bottom: 0; }
.member .face { display: block; width: clamp(150px, 18vw, 190px); aspect-ratio: 1; border-radius: 50%; overflow: hidden; background: var(--beige); flex: none; }
.member .face img { display: block; width: 100%; height: 100%; object-fit: cover; }
.member-txt { max-width: 62ch; min-width: 0; }
.member h2 { font-size: clamp(1.3rem, 2.2vw, 1.7rem); margin-bottom: 2px; }
.member .role { color: var(--brown); font-weight: 700; margin: 0 0 14px; }
.member-txt > :last-child { margin-bottom: 0; }
/* Rafi closes the row of three: a smaller portrait, a lighter text, set apart by a rule */
/* 09/11 (Sam) : Rafi au meme format que les deux autres. Le filet reste, il separe ; ce n'est plus une hierarchie de taille. */
.member--minor { margin-top: clamp(20px, 3vw, 32px); padding-top: clamp(24px, 3vw, 40px); border-top: 2px solid var(--line); }
@media (min-width: 820px) {
  .member { flex-direction: row; align-items: flex-start; gap: clamp(32px, 4.5vw, 72px); }
  .member--flip { flex-direction: row-reverse; }
}

/* ==================== @approach : Approche page ==================== */
/* 29/10 (Sam): the page kept only the approach — "Notre expertise" and "Notre expérience" are off it. The three rings
   come alongside the three dimensions and stay in view while they are read, opening one ring at a time (site.js 4d).
   Below 1040 px there is no room for a second column: the drawing goes above the text and stops following. */
/* 30/10 (Sam) : le dessin suit la lecture aux deux largeurs. Sous 1040 px il n'y a pas de deuxieme colonne, donc la
   rangee passe en flux normal et le dessin se colle en haut de l'ecran : le texte defile dessous et le zoom suit la
   section lue, comme sur un ordinateur. Il est donc place avant le texte dans le HTML, et remis a droite plus bas. */
.ap-spine { display: block; }
.ap-fig { position: sticky; top: var(--header-h); z-index: 3; padding: 12px 0 14px;
  background: var(--light-beige); }          /* franc derriere le dessin : le texte doit passer dessous, pas au travers */
.ap-fig::after { content: ""; position: absolute; left: 0; right: 0; top: 100%; height: 20px; pointer-events: none;
  background: linear-gradient(to bottom, var(--light-beige), rgba(254, 240, 222, 0)); }   /* le fondu est sous la boite, pas dedans */
.ap-fig .rings { margin: 0 auto; display: block; max-width: clamp(150px, 42vw, 230px); }
@media (min-width: 1040px) {
  .ap-spine { display: grid; grid-template-columns: minmax(0, 1fr) minmax(360px, 440px); gap: clamp(40px, 5vw, 88px); align-items: start; }
  .ap-col { order: -1; }                      /* le texte reprend la premiere colonne, le dessin la seconde */
  .ap-fig { top: calc(var(--header-h) + 40px); padding: 0; background: none; }
  .ap-fig::after { display: none; }
  .ap-fig .rings { max-width: 420px; }
  .ap-spine .ap { grid-template-columns: minmax(0, 1fr); gap: 12px; }
  /* 29/10 (Sam): the title stays at the top while its own text passes under it, as it did before the two columns. */
  /* 30/10 (Sam): the titles used to be sticky, each with a backdrop that was meant to hide its own paragraph passing
     underneath. It never worked — a two-line title outgrew its backdrop and the text showed through the words. The
     index below says which dimension is being read, which is what the sticky titles were for, so they scroll normally. */
  /* Between 900 and 1039 px the title sits in its own left column beside its text, where sticky is harmless and
     useful. From 1040 the second column holds the rings, .ap goes back to one column and the title stacks above
     its own paragraph — sticky there pinned it on top of the text, with nothing behind it. The index replaces it. */
  .ap-spine .ap-h { position: static; }
  .ap-spine .ap h2 { max-width: 22ch; }
}
/* 28/10 (the owner, after Sam's call): the master document's approach and expertise texts. Two columns on a computer (number and title on the left, the text on the right),
   one column on a phone. The five situations at the end are links into the Services list. */
.ap { display: grid; gap: 14px 56px; grid-template-columns: minmax(0, 1fr); padding: clamp(32px, 5vw, 60px) 0; border-top: 1px solid var(--line); }
.ap-h { display: grid; gap: 8px; align-content: start; min-width: 0; }
/* 30/10 (Sam) : sur telephone, le titre de la section lue reste lui aussi a l'ecran, juste sous le dessin colle.
   Il se cale sur --fig-h, la hauteur reelle du dessin, que site.js §4e mesure et pose sur .ap-spine. Chaque titre
   ne colle que dans les limites de sa propre section, donc c'est toujours le titre de ce qu'on lit. Fond franc et
   fondu rejete dessous, sinon le paragraphe repasserait au travers des lettres. */
@media (max-width: 1039.98px) {
  .ap-spine .ap-h { position: sticky; top: calc(var(--header-h) + var(--fig-h, 200px)); z-index: 2;
    background: var(--light-beige); padding-bottom: 10px; }
  .ap-spine .ap-h::after { content: ""; position: absolute; left: 0; right: 0; top: 100%; height: 16px;
    pointer-events: none; background: linear-gradient(to bottom, var(--light-beige), rgba(254, 240, 222, 0)); }
}
.ap-n { font-size: .78rem; font-weight: 800; letter-spacing: .12em; color: var(--orange); }
.ap h2, .ap h3 { font-size: clamp(1.5rem, 3vw, 2.2rem); line-height: 1.12; max-width: 16ch; overflow-wrap: anywhere; }
.ap-t { min-width: 0; }
.ap-t p { max-width: 64ch; }
.ap-t p:last-child { margin-bottom: 0; }
/* 30/10 (Sam) : la page ouvre sur une photo, comme l'accueil et A propos — c'etait la seule page du site a ouvrir
   sur un mur de texte (85 mots, contre 8 a 16 ailleurs). Il ne reste en haut que le titre et la phrase ; le
   paragraphe de these descend juste au-dessus des trois dimensions, ou il annonce ce qu'on va lire. */
.ap-hero { position: relative; display: grid; align-items: end; overflow: hidden;
  min-height: clamp(380px, 50vw, 620px); background: var(--brown); }
.ap-hero > img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; object-position: 50% 42%; }
.ap-hero::after { content: ""; position: absolute; inset: 0; pointer-events: none;
  background: linear-gradient(to bottom, rgba(71,47,36,.08) 0%, rgba(71,47,36,.16) 38%, rgba(71,47,36,.66) 56%, rgba(71,47,36,.94) 70%, rgba(71,47,36,.98) 100%); }
  /* 30/10 (Sam) : le voile descend du haut vers le bas, il ne balaie plus de gauche a droite. En biais il noyait
     l'homme de gauche, qui est du cote sombre ; de haut en bas il laisse les deux visages dans la partie claire et
     ne fonce que la bande basse, celle qui porte le texte.
     Le voile est le brun clair de la charte, pas un brun invente : c'est la couleur du heros de l'accueil, donc les
     deux pages s'ouvrent sur le meme fond. Il est plus clair qu'un noir brun, donc les alphas du bas sont montes
     pour compenser ; les valeurs sont reglees sur le point le plus clair mesure sous le texte, pas a l'oeil. */
.ap-hero .wrap { position: relative; z-index: 1;
  padding-top: clamp(60px, 10vw, 150px); padding-bottom: clamp(20px, 2.8vw, 34px); }
.ap-hero .page-title { color: var(--beige); }
.ap-craft { font-size: clamp(1.15rem, 2vw, 1.4rem); line-height: 1.55; font-weight: 500; color: var(--beige);
  max-width: 46ch; margin: var(--title-gap) 0 0; }
/* la these, seule, juste avant les trois dimensions */
.ap-these { font-size: clamp(1.05rem, 1.7vw, 1.22rem); line-height: 1.6; font-weight: 500; color: var(--body);
  max-width: 58ch; margin: 0 0 clamp(26px, 4vw, 48px); }
.ap-band { background: var(--light-beige); }
/* 30/10 (Sam): the index of the three dimensions (catalogue "Scrollspy index"). It sits above the rings in the second
   column: the words say where you are, the drawing shows it. Hidden below 1040 px, where there is no second column and
   the three sections follow each other anyway. The marker's top and height come from site.js §21, because the three
   titles wrap to different heights and a pure-CSS marker would need them equal. */
.ap-idx { display: none; margin: 0 0 clamp(26px, 3vw, 40px); }
.ap-idx ol { list-style: none; margin: 0; padding: 0 0 0 20px; display: grid; gap: 2px; position: relative; border-left: 2px solid var(--line); }
.ap-idx ol::before { content: ""; position: absolute; left: -2px; width: 2px; border-radius: 2px; background: var(--brown);
  top: var(--mt, 0px); height: var(--mh, 0px); transition: top .45s cubic-bezier(.2, .8, .2, 1), height .45s cubic-bezier(.2, .8, .2, 1); }
.ap-idx a { display: grid; grid-template-columns: auto minmax(0, 1fr); gap: 12px; align-items: baseline; padding: 10px 0;
  text-decoration: none; color: var(--muted); font-size: .95rem; line-height: 1.35; transition: color .25s; }
.ap-idx a span { font-size: .72rem; font-weight: 800; letter-spacing: .12em; color: var(--orange); } /* 08/11: the small numbers in orange */
.ap-idx a:hover { color: var(--brown); }
.ap-idx a[aria-current="true"] { color: var(--choco); font-weight: 700; }
.ap-idx a:focus-visible { outline: 2px solid var(--brown); outline-offset: 3px; border-radius: 3px; }
html.still .ap-idx ol::before { transition: none; }
@media (min-width: 1040px) { .ap-idx { display: block; } }
.ap-title { font-size: clamp(1.8rem, 4vw, 3rem); overflow-wrap: anywhere; }

/* 30/10 (Sam) : les pages juridiques — conditions generales et confidentialite. Texte long, une seule colonne de
   lecture, pas de fioriture : on vient y chercher une clause, pas une experience. Le corps vient de copy/legal/,
   exporte des documents Drive ; la mise en forme est ici, le texte n'est jamais reecrit. */
.legal { max-width: 68ch; }
.legal-h1 { font-size: clamp(1.9rem, 4vw, 3rem); max-width: 22ch; margin-bottom: clamp(22px, 3vw, 34px); }
.legal h2 { font-size: clamp(1.14rem, 1.9vw, 1.36rem); line-height: 1.3; color: var(--choco);
  margin: clamp(30px, 4vw, 46px) 0 clamp(10px, 1.4vw, 14px); }
.legal h3 { font-size: 1rem; line-height: 1.35; color: var(--brown); font-weight: 800;
  margin: clamp(20px, 2.6vw, 28px) 0 clamp(8px, 1vw, 10px); }
.legal p { max-width: none; margin: 0 0 clamp(12px, 1.6vw, 16px); }
.legal ul { margin: 0 0 clamp(14px, 1.8vw, 18px); padding-left: 1.15em; }
.legal li { margin-bottom: 8px; }
.legal li:last-child { margin-bottom: 0; }
.legal-def { list-style: none; padding-left: 0; }
.legal-def li { padding-left: 14px; border-left: 2px solid var(--line); }
.legal-def strong { color: var(--choco); }
.legal .cta-row { margin-top: clamp(34px, 5vw, 56px); padding-top: clamp(22px, 3vw, 32px); border-top: 1px solid var(--line); }
/* 29/10 (the owner): the three circles of "Notre expertise" (Home, in place of the three cards; Approche; About, small): they overlap, and where all three cross, TRAX.
   They form with the scroll: --vf goes from 0 (three small circles apart) to 1 (formed), set by site.js section 14; the shared zone, the titles and the wordmark come in at the end. */
.venn-wrap { margin-top: clamp(20px, 3vw, 40px); }
.venn { --vf: 1; position: relative; width: min(100%, 720px); margin: 0 auto; container-type: inline-size; }
.venn-svg { display: block; width: 100%; height: 100%; overflow: visible; }
.vc, .vr { transform-box: fill-box; transform-origin: 50% 50%; }
.vc1, .vr1 { transform: translate(calc((1 - var(--vf, 1)) * -123px), calc((1 - var(--vf, 1)) * -118px)) scale(calc(.62 + .38 * var(--vf, 1))); }
.vc2, .vr2 { transform: translate(calc((1 - var(--vf, 1)) * 123px), calc((1 - var(--vf, 1)) * -118px)) scale(calc(.62 + .38 * var(--vf, 1))); }
.vc3, .vr3 { transform: translate(0, calc((1 - var(--vf, 1)) * 118px)) scale(calc(.62 + .38 * var(--vf, 1))); }
.vc { fill: var(--brown); fill-opacity: .16; transition: fill-opacity .4s; }
.vc2 { fill: var(--blue); fill-opacity: .42; }
.vc3 { fill: #fff; fill-opacity: .6; }
.venn-core { fill: var(--brown); opacity: clamp(0, calc((var(--vf, 1) - .8) * 5), 1); }
.vr { fill: none; stroke: var(--brown); stroke-width: 2px; vector-effect: non-scaling-stroke; pointer-events: none; transition: stroke-width .3s; }
.venn[data-on="1"] .vc1 { fill-opacity: .4; }
.venn[data-on="2"] .vc2 { fill-opacity: .8; }
.venn[data-on="3"] .vc3 { fill-opacity: 1; }
.venn[data-on="1"] .vr1, .venn[data-on="2"] .vr2, .venn[data-on="3"] .vr3 { stroke-width: 4px; }
.venn-l { position: absolute; width: 27%; transform: translate(-50%, -50%); display: grid; justify-items: center; gap: .35em; text-align: center; color: var(--ink); pointer-events: none; opacity: clamp(0, calc((var(--vf, 1) - .7) * 3.4), 1); }
.venn-ic { display: block; width: clamp(18px, 4.8cqw, 38px); height: clamp(18px, 4.8cqw, 38px); }
.venn-ic svg { width: 100%; height: 100%; display: block; fill: none; stroke: var(--brown); stroke-width: 2.4; stroke-linecap: round; stroke-linejoin: round; }
.venn-t { font-weight: 800; letter-spacing: -.01em; line-height: 1.12; font-size: 12px; font-size: clamp(11.5px, 3.2cqw, 26px); text-wrap: balance; overflow-wrap: anywhere; }
.venn-trax { position: absolute; width: 26%; height: auto; transform: translate(-50%, -50%); pointer-events: none; opacity: clamp(0, calc((var(--vf, 1) - .88) * 8), 1); }
@container (max-width: 260px) { .venn-t { display: none; } }
.venn--small { width: min(100%, 440px); }
.sit-links { list-style: none; margin: clamp(20px, 3vw, 32px) 0 0; padding: 0; display: grid; gap: 10px; max-width: 46rem; }
.sit-links li { min-width: 0; }
.sit-links a span { min-width: 0; overflow-wrap: anywhere; }
.sit-links a { display: flex; align-items: center; justify-content: space-between; gap: 16px; min-height: 56px; padding: 10px 20px; border: 1px solid var(--line); border-radius: 16px; background: #fff; color: var(--ink); font-weight: 700; line-height: 1.3; text-decoration: none; }
.sit-links a::after { content: "→"; flex: none; color: var(--brown); font-weight: 800; }
.sit-links a:hover { border-color: var(--brown); }
@media (min-width: 900px) {
  .ap { grid-template-columns: 340px minmax(0, 1fr); }
  .ap-h { position: sticky; top: calc(var(--header-h) + 24px); align-self: start; }
}
.cta-row { margin: clamp(20px, 3vw, 32px) 0 0; text-align: center; } /* 29/10 (Sam): centred on the circles above it */
.cta-row .btn { color: var(--beige); } /* the link colour of the beige blocks (.sec--tint a) is brown: on the brown button it was invisible */

/* ==================== @forms : Contact / Join forms ==================== */
.join-form { display: grid; gap: 18px; margin-top: 36px; max-width: 520px; }
.join-form .field { display: grid; gap: 6px; }
.join-form label { font-weight: 700; font-size: .95rem; line-height: 1.3; color: var(--ink); }
/* WP-H: brown border on white = 7.6:1 (the old --line border was 1.6:1, below the 3:1 a field edge needs) */
.join-form input, .join-form textarea { font: inherit; padding: 14px 16px; border: 1px solid var(--brown); border-radius: 12px; background: #fff; color: var(--ink); width: 100%; -webkit-appearance: none; appearance: none; }
.join-form textarea { resize: vertical; }
.join-form select { font: inherit; padding: 14px 44px 14px 16px; border: 1px solid var(--brown); border-radius: 12px; background: #fff; color: var(--ink); width: 100%; -webkit-appearance: none; appearance: none; background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='14' height='9' viewBox='0 0 14 9'%3E%3Cpath d='M1 1l6 6 6-6' fill='none' stroke='%236a4e41' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E"); background-repeat: no-repeat; background-position: right 16px center; }
.join-form select:focus { outline: 2px solid var(--brown); outline-offset: 2px; }
.join-form select:invalid { color: var(--muted); } /* the "choose a situation" line reads as a placeholder until one is picked */
.join-form ::placeholder { color: var(--muted); opacity: 1; }
.join-form input:focus, .join-form textarea:focus { outline: 2px solid var(--brown); outline-offset: 2px; }
.join-form .form-actions { display: flex; flex-direction: column; align-items: flex-start; }
/* the status line (role=status) is always in the page, empty, so screen readers announce what site.js writes into it; empty it takes no room */
.join-form .form-status { margin: 0; font-size: .95rem; line-height: 1.5; color: var(--ink); scroll-margin: calc(var(--header-h) + 24px) 0 24px; }
.join-form .form-status:not(:empty) { margin-top: 14px; padding: 2px 0 2px 14px; border-left: 3px solid var(--brown); }
.join-form .form-status a { color: var(--brown); font-weight: 700; overflow-wrap: anywhere; }

/* ==================== @contact-join : Contact and Join page layouts ==================== */
.join { display: grid; grid-template-columns: 1.05fr .95fr; gap: clamp(28px,5vw,72px); align-items: center; }
.join-ph { margin: 0; }
.join-ph img { width: 100%; height: auto; border-radius: 20px; display: block; }
.eyebrow { text-transform: uppercase; letter-spacing: .14em; font-size: .78rem; font-weight: 700; color: var(--brown); margin: 0 0 14px; }
/* 29/10 (Sam, option B2 without the 1-2-3 steps): one column of five fields, so nothing has to be written in prose.
   The two columns and the sticky heading of the old split layout are gone with it, and so is the photo it shared with About. */
.contact-head { background: var(--beige); padding: clamp(44px, 6vw, 88px) 0 clamp(28px, 4vw, 54px); }
.contact-head .wrap { display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: clamp(24px, 4vw, 56px); align-items: start; }
.contact-turtle { align-self: center; }
.contact-turtle { width: min(250px, 25vw); height: auto; }
.contact-box { max-width: 680px; }
.contact-box h2 { font-size: clamp(1.55rem, 3.2vw, 2.3rem); margin-bottom: clamp(20px, 3vw, 30px); }
.contact-box .join-form { margin-top: 0; max-width: none; }
.contact-ways { background: var(--beige); padding: clamp(30px, 4.5vw, 62px) 0; }
.contact-ways .wrap { display: grid; grid-template-columns: 1fr 1fr; gap: clamp(22px, 4vw, 56px); }
.contact-ways h3 { margin-bottom: 6px; }
.contact-ways p { margin: 0 0 .5em; }
/* WP-H: minmax(0, 1fr) so a long word cannot widen the single column (was 1fr = minmax(auto, 1fr): 2 px of sideways scroll at a 200 % zoom) */
.join-txt h1 { overflow-wrap: anywhere; }
@media (max-width: 760px) {
  .join { grid-template-columns: minmax(0, 1fr); }
  .join-ph { order: -1; }
  .contact-head .wrap, .contact-ways .wrap { grid-template-columns: minmax(0, 1fr); }
  .contact-turtle { display: none; }
}


/* ==================== @typo-roles : qui porte quelle fonte (ASSETS/Typo_Trax.pdf, 08/11) ====================
   Google Sans est la fonte du site : elle est posee sur body et tout en herite. Les deux regions ci-dessous
   ne font que les exceptions que la charte demande, et rien d'autre : aucune taille, aucune couleur. */

/* Inter Tight — « labels et petites informations, chiffres et donnees, annotations, numeros de section ».
   Elle est plus etroite et plus serree que Google Sans : c'est ce qui donne du contraste et du rythme. */
.eyebrow, .sit-n, .bbx-k, .sheet-k, .panel-sub,
.swap-count, .bb-n, .ap-n, .ap-idx a span,
.fig b, .value-figs .fig b,
.sv-s > .wrap > h2 span { font-family: var(--font-2); }

/* Comico — la voix de la tortue, et rien d'autre. Elle n'a qu'une graisse : on retire les 800 qui
   trainent, sinon le navigateur fabrique un faux gras et le dessin se salit. Son oeil est petit,
   d'ou le demi-point de plus. */
.finder-pill, .finder-title, .finder-sub, .pill-dot + span {
  font-family: var(--font-3); font-weight: 400; letter-spacing: .01em;
}
.finder-pill { font-size: .84rem; }
.finder-title { font-size: .98rem; font-weight: 400; }

/* ==================== @systeme : le parti pris du 08/11 ====================
   Sam : « propose-moi toi-meme comment appliquer les choses, comment on utilise l'orange,
   comment on rend les pages plus interessantes. » Voici la regle, et ce qu'elle donne.

   L'ORANGE. Mesure : il echoue comme texte sur fond clair (2,79:1 sur blanc, 2,33:1 sur beige)
   mais il passe largement comme APLAT (5,74:1 avec une encre brun fonce). Donc la regle est :
   l'orange ne porte jamais de texte sur fond clair — il remplit, il souligne, il trace.
   C'est ce qui lui permet d'etre plus present qu'avant sans rien rendre illisible.

   LE BLEU reste le signal de lecture : l'etape en cours, la tortue qu'on croise en haut.
   LES DEUX BRUNS restent la structure. Le beige porte les pages. */

/* --- 1. Le titre de l'accueil : meme graisse sur ordinateur et sur telephone (Sam) --- */
@media (max-width: 760px) and (orientation: portrait), (max-width: 760px) and (min-height: 501px) {
  html body.page-home .hero .hero-line1 { font-weight: 400; letter-spacing: -.012em; line-height: 1.16;
    font-size: clamp(1.75rem, 7.6vw, 2.3rem); max-width: 20ch; }
  html body.page-home .hero .hero-line1 .ln:first-child { max-width: none; }
  html body.page-home .hero .hero-line1 .ln + .ln { font-size: 1em; font-weight: 400; opacity: 1;
    margin-top: .18em; line-height: 1.16; max-width: none; letter-spacing: -.012em; }
}

/* --- 2. L'action principale : beige sur le sombre, brun fonce sur le clair --- */
/* 08/11 (Sam, apres la planche) : le bouton du bas passe au beige, comme dans la maquette d'Audrey.
   Sur le bandeau brun fonce il donne 13,36:1 d'encre et 10,31:1 de bord — c'est le meilleur des cinq.
   Mais le beige ne vaut que la : sur un fond clair son bord tombe a 1,07:1, le bouton disparait.
   Donc sur les fonds clairs l'action garde le brun fonce (10,31:1 d'encre, 12,35:1 de bord sur blanc).
   L'orange reste present ailleurs : pastilles des numeros, filets, contours des champs, survol du menu. */
.close .btn {
  --btn-bg: var(--beige); --btn-line: var(--beige); color: #2b1f18;
}
.close .btn:hover, .on-dark .close .btn:hover {
  --btn-bg: #fff; --btn-line: #fff; color: #2b1f18;
}
.cta-row .btn, .form-actions .btn {
  --btn-bg: var(--frame); --btn-line: var(--frame); color: var(--beige);
}
.cta-row .btn:hover, .form-actions .btn:hover {
  --btn-bg: var(--brown-hover); --btn-line: var(--brown-hover); color: var(--beige);
}
/* le bouton de demo garde le bleu : c'est le seul endroit ou le bleu est un aplat, et il le reste */

/* --- 3. Les numeros : l'orange passe en pastille au lieu de porter le texte --- */
/* Avant : chiffre orange sur carte blanche, 2,79:1 — sous le seuil. Maintenant l'orange est le fond
   et l'encre est brun fonce : 5,74:1, et le chiffre se voit de plus loin qu'avant. */
.bb-n { color: #2b1f18; background: var(--orange); border-radius: 999px;
  padding: 3px 10px 4px; right: 12px; top: 11px; font-size: 1.05rem; }
/* Les petites capitales (01/03, les numeros d'Approche) reprennent l'encre brun fonce, et l'orange
   passe dans un filet devant elles : present, mais il ne porte plus de mot. */
.swap-count, .ap-n, .ap-idx a span { color: var(--choco); display: inline-flex; align-items: center; gap: 8px; }
.swap-count::before, .ap-n::before, .ap-idx a span::before {
  content: ""; width: 18px; height: 3px; border-radius: 2px; background: var(--orange); flex: none;
}

/* --- 4. Le bandeau de fin : coins arrondis en haut, et la grande tortue derriere (maquette d'Audrey) --- */
.close { position: relative; overflow: hidden; }
/* 09/11 (Sam) : plus de coins arrondis sur la bande de fin. Ils laissaient voir un liseré de la
   page de part et d'autre, juste au-dessus du pied de page : la bande semblait posée de travers. */
.close { border-radius: 0; }
.close::before {
  content: ""; position: absolute; right: 2%; bottom: 10%; width: min(32%, 380px); aspect-ratio: 1000 / 627;
  background: url(../img/tortue-brun-brun.webp) right center / contain no-repeat;
  opacity: .40; pointer-events: none; z-index: 0;
}
.close .wrap { position: relative; z-index: 1; }
/* une seule grande tortue par bas de page : celle du pied de page laisse la place a celle du bandeau */
.foot-turtle { display: none; }
@media (max-width: 760px) { .close::before { width: 56%; right: -4%; bottom: 4%; opacity: .34; } }

/* --- 5. L'etape en cours --- */
/* 08/11 (Sam) : le filet bleu sous le mot n'a pas plu, le mot reste en bleu comme avant.
   A savoir : le bleu sur le beige mesure 1,83:1, sous le seuil de 3:1 d'un gros texte. C'est le seul
   echec de contraste qui reste sur le site, et c'est un choix assume, pas un oubli. */
.swap-slot span.on { color: var(--blue); }

/* --- 6. La page Contact (Sam, 08/11) ---------------------------------------------------------
   « Il ne manque pas la photo de nous ? » : une bande photo entre le titre et le formulaire.
   « Pas le remplissage, juste une couleur orange autour » : les champs prennent un contour orange
   et le beige clair de la page au lieu du blanc. L'encre reste brun fonce, 10,96:1 sur ce fond. */
.contact-ph { margin: clamp(26px, 4vw, 48px) auto 0; width: min(1180px, 92vw); }
.contact-ph img { width: 100%; height: auto; aspect-ratio: 2 / 1; object-fit: cover;
  border-radius: clamp(14px, 2vw, 24px); display: block; }
@media (max-width: 760px) { .contact-ph { width: 100%; } .contact-ph img { border-radius: 0; aspect-ratio: 3 / 2; } }

.join-form input, .join-form textarea, .join-form select {
  border: 2px solid var(--orange); background: var(--light-beige); color: var(--choco); border-radius: 14px;
}
.join-form input:focus, .join-form textarea:focus, .join-form select:focus {
  outline: 3px solid var(--blue); outline-offset: 2px; border-color: var(--orange); background: #fff;
}
.join-form input::placeholder, .join-form textarea::placeholder { color: var(--muted); }

/* --- 7. La phrase du hero : Inter Tight Medium, la typo d'Audrey (08/11) ---------------------
   Sam : « qu'est-ce qu'Audrey aurait proposé ? » Mesure, pas supposition : dans sa maquette
   (ASSETS/Simu_Site_1.png) la premiere ligne du titre fait 2272 px de large pour une capitale de
   107 px. A capitale egale, Inter Tight Medium donne 2269 px (-0,1 %), Inter Tight Regular 2218
   (-2,4 %), Google Sans Regular 2370 (+4,3 %), Google Sans Medium 2450 (+7,8 %). C'est Inter Tight.
   Son PDF le dit d'ailleurs : la secondaire est pour « les headlines courtes et impactantes ».
   Meme fonte et meme graisse sur ordinateur et sur telephone, comme Sam l'a demande. */
.hero-line1, html body.page-home .hero .hero-line1,
html body.page-home .hero .hero-line1 .ln + .ln {
  font-family: var(--font-2); font-weight: 500; letter-spacing: -.015em;
}

/* ==================== @passe-08-11-soir : ce que Sam a releve en regardant ====================  */

/* --- La phrase du hero : descendue le 08/11, remontee au milieu le 10/11 ---
   Le 08/11 elle tombait sur les visages, et elle etait descendue tout en bas. Sam la veut
   maintenant au milieu, et toujours pas sur les visages. Les deux tiennent : mesure faite sur la
   page a 1440x900, les deux visages occupent de 19 % a 33 % de la hauteur du hero, et le cadrage
   de la photo (cover, object-position 50% 38%) les garde dans le tiers haut quelle que soit la
   forme de la fenetre. Centree, la phrase occupe 43 a 57 % : dix points sous le dernier menton. */
@media (min-width: 761px) {
  html body.page-home .hero { justify-content: center; }
  html body.page-home .hero .wrap { min-height: 0; justify-content: center; padding-bottom: 0; }
  /* Au milieu, la phrase tombe sur le canape clair et sur la chemise blanche : mesure sur les pixels
     de la page, le pire fond passait de 4,77:1 (en bas, sous le voile dense) a 1,44:1, et 57 % du
     fond sous les lettres descendait sous 3:1. Le halo doux remet tout au-dessus : c'est le meme
     procede que sur telephone, ou la phrase est posee sur la photo pour les memes raisons.
     Un voile sur toute la largeur aurait assombri la photo entiere ; le halo n'assombrit que ce
     qui est sous les lettres. */
  html body.page-home .hero .hero-line1 { position: relative; isolation: isolate; }
  /* La boite deborde largement la phrase : avec closest-side, l'ellipse touche les quatre cotes
     et laisse les coins a nu. Serree, elle tombait a 2,17:1 au bout de la premiere ligne. */
  html body.page-home .hero .hero-line1::before {
    content: ""; position: absolute; z-index: -1; pointer-events: none;
    left: -15%; right: -15%; top: -50%; bottom: -50%;
    background: radial-gradient(closest-side at 50% 50%,
      rgba(18, 12, 8, .62) 0%, rgba(18, 12, 8, .60) 52%, rgba(18, 12, 8, .50) 76%,
      rgba(18, 12, 8, .26) 90%, rgba(18, 12, 8, 0) 100%);
    filter: blur(18px); }
  /* Mesure du fond reel, phrase rendue invisible et photographiee : pire 3,31:1, cinquieme
     centile 5,31:1, rien sous 3:1 (le seuil des grands caracteres, ici 49 px). */
}
@media (max-width: 760px) and (orientation: portrait), (max-width: 760px) and (min-height: 501px) {
  html body.page-home .hero { padding-bottom: calc(env(safe-area-inset-bottom) + 34px); }
}

/* --- Le choix de la langue quitte l'en-tete et descend dans le pied de page --- */
.site-header .lang { display: none; }
.site-footer .lang { display: inline-flex; align-items: center; gap: 0; border-radius: 999px;
  background: var(--surface); border: 1px solid var(--surface); overflow: hidden; align-self: center; }
.site-footer .lang a { color: var(--beige); text-decoration: none; font-family: var(--font-2);
  font-size: .76rem; font-weight: 700; letter-spacing: .08em; padding: 9px 14px; min-height: 40px;
  display: inline-flex; align-items: center; text-transform: uppercase; }
.site-footer .lang a[aria-current="true"] { background: var(--beige); color: var(--choco); }

/* --- A la premiere visite seulement : on demande la langue une fois (site.js section 8) --- */
.pick-lang { position: fixed; inset: 0; z-index: 200; display: grid; place-items: center;
  background: rgba(var(--frame-rgb), .62); padding: 20px; }
.pick-lang[hidden] { display: none; }
.pick-box { background: var(--beige); color: var(--choco); border-radius: 22px; padding: 26px 24px 22px;
  width: min(420px, 100%); box-shadow: 0 30px 80px rgba(20, 10, 4, .45); text-align: center; }
.pick-t { margin: 0 0 18px; font-family: var(--font-2); font-weight: 600; font-size: 1.1rem; line-height: 1.3; }
.pick-t span { display: block; font-size: .8rem; font-weight: 400; color: var(--brown); margin-top: 5px; }
.pick-row { display: grid; gap: 8px; }
.pick-row a { display: block; min-height: 48px; line-height: 48px; border-radius: 999px;
  background: var(--frame); color: var(--beige); text-decoration: none; font-weight: 600; }
.pick-row a:hover { background: var(--brown-hover); }

/* --- La tortue du bandeau : en orange, decoupee dans le masque, donc elle se voit (Sam) --- */
.close::before {
  /* 08/11 : le masque remplissait la silhouette et ne laissait qu'une tache. On revient a une image,
     la tortue reteinte en orange (tools, 08/11) : le trait et les plaques restent lisibles. */
  background: url(../img/tortue-orange.webp) right center / contain no-repeat;
  -webkit-mask: none; mask: none;
  opacity: .5; right: 3%; bottom: 14%; width: min(26%, 300px);
}
@media (max-width: 760px) { .close::before { width: 46%; right: 2%; bottom: 6%; opacity: .45; } }

/* --- La tortue de la carte de valeur etait coincee dans le coin : on la degage et on la voit --- */
.value-turtle { right: 4%; bottom: 6%; width: min(34%, 360px); opacity: .16; }
@media (max-width: 760px) { .value-turtle { bottom: 3%; right: -2%; width: min(52%, 260px); opacity: .13; } }

/* --- Contact : un seul fond sur toute la page, au lieu de deux qui se succedent --- */
body.page-contact { --page-bg: var(--beige); }
.contact-head, .contact-ways { background: transparent; }

/* --- Un peu plus d'orange sur les petites choses (Sam) --- */
.more-link::after, .more-link .ar { color: var(--orange); }
.btn--ghost { --btn-line: var(--orange); }
.sit-links a:hover { border-color: var(--orange); }
.card:hover { border-color: var(--orange); }

/* --- L'assistant parle d'une seule voix (Sam, 08/11) ------------------------------------------
   Sa bulle et son intro etaient en Comico, mais les choix proposes restaient en Google Sans : la
   boite melangeait deux voix. Tout ce que la tortue dit prend sa fonte. Comico n'a qu'une graisse,
   donc on retire les gras qui trainent, sinon le navigateur en fabrique un faux. */
.chip, .finder .rc .btn, .finder-main .res-t, .finder-sub, .finder-link,
.finder .finder-go, .finder-main > .btn {
  font-family: var(--font-3); font-weight: 400; letter-spacing: .01em;
}
.chip { font-size: .84rem; font-weight: 400; }

/* --- La tete de la page Interventions : les chiffres d'abord, sur le brun clair (Sam, 08/11) ------
   Avant, les trois chiffres finissaient en bas de page dans une boite brune posee sur le beige.
   Ils ouvrent maintenant la page : bande brun clair pleine largeur, puis tout le reste en beige. */
.sv-head { background: var(--surface); position: relative; overflow: hidden;
  padding: clamp(48px, 7vw, 92px) 0 clamp(40px, 5.5vw, 70px); }
.sv-head .wrap { position: relative; z-index: 1; }
.sv-head .page-title { color: var(--beige); max-width: 18ch; margin-bottom: clamp(26px, 4vw, 44px); }
.sv-head .value-figs { max-width: 60ch; }
.sv-head .value-note { color: #e8d7c2; font-size: .86rem; margin: clamp(18px, 2.4vw, 26px) 0 0;
  padding-top: clamp(14px, 2vw, 20px); border-top: 1px solid rgba(249, 232, 212, .22); max-width: 60ch; }
.sv-head-turtle { position: absolute; right: 3%; bottom: 8%; width: min(28%, 320px); height: auto;
  opacity: .14; pointer-events: none; user-select: none; z-index: 0; }
@media (max-width: 760px) { .sv-head-turtle { width: 48%; right: -2%; bottom: 3%; opacity: .12; } }
/* les cinq situations et toutes les demos restent sur un seul beige */
.sv-top { padding-top: clamp(34px, 4.5vw, 56px); }
.sv-s { background: var(--beige); }
.sv-s > .wrap > h2 { background: var(--beige); }
.sv-s > .wrap > h2::after { background: linear-gradient(to bottom, var(--beige), rgba(249, 232, 212, 0)); }

/* --- La tortue du bandeau de fin passe au bleu (Sam) --- */
.close::before { background: url(../img/tortue-brun-bleu.webp) right center / contain no-repeat; opacity: .55; }

/* --- La photo d'Approche : le cadrage remonte pour ne plus couper les tetes sur un 15 pouces --- */
.ap-hero > img { object-position: 50% 26%; }

/* ==================== @passe-08-11-nuit : derniers retours de Sam ==================== */

/* --- 1. La pastille de l'assistant : la tortue mordait sur le texte --- */
.finder-pill { gap: 14px; padding-left: 12px; padding-right: 18px; }
.finder-pill .pill-turtle { margin-right: 2px; }

/* --- 2. Les champs de Contact : une ligne, rien d'autre (Sam, 08/11) ---------------------------
   La forme dessinee du bouton s'etirait en lentille sur la largeur d'un champ : illisible. Plus de
   boite du tout, juste un filet bleu sous le texte, qui s'epaissit quand le champ a le focus. */
.join-form .field::after { content: none; }
.join-form input, .join-form textarea, .join-form select {
  border: 0; border-bottom: 2px solid var(--blue); border-radius: 0;
  background: transparent; color: var(--choco); padding-left: 2px; padding-right: 2px;
  transition: border-color .2s, box-shadow .2s;
}
.join-form input:focus, .join-form textarea:focus, .join-form select:focus {
  outline: none; border-bottom-color: var(--choco); box-shadow: 0 2px 0 0 var(--choco);
  background: transparent;
}
.join-form select { background-position: right 2px center; }
.join-form textarea { border: 0; border-bottom: 2px solid var(--blue); border-radius: 0; }
.join-form input::placeholder, .join-form textarea::placeholder { color: var(--muted); }

/* --- 3. La tete d'Interventions : brun fonce, la tortue coupee au bord, et les chiffres
       qui montent au lieu d'apparaitre l'un apres l'autre (Sam) --- */
.sv-head { background: var(--frame); padding: clamp(40px, 5vw, 70px) 0 clamp(36px, 4.5vw, 60px); }
.sv-head .wrap { display: grid; grid-template-columns: minmax(0, 1fr); gap: clamp(22px, 3vw, 34px); }
@media (min-width: 900px) {
  /* le titre et les chiffres cote a cote : c'est le vide a droite qui faisait mal sur un 15 pouces */
  .sv-head .wrap { grid-template-columns: minmax(0, 1.05fr) minmax(0, .95fr); align-items: center;
    column-gap: clamp(36px, 5vw, 72px); }
  .sv-head .page-title { grid-row: 1 / span 2; margin-bottom: 0; align-self: center; }
  .sv-head .value-figs { grid-column: 2; }
  .sv-head .value-note { grid-column: 2; margin-top: 0; }
}
.sv-head .page-title { max-width: 14ch; }
/* la tortue sort du cadre : on n'en voit qu'un morceau, comme Sam le demande */
/* Sam : « tu l'as entierement effacee. Mets-la legerement en fond, ou coupe-la deux fois. »
   Elle traverse le bas de la bande et sort des deux cotes : on en voit le milieu, pas les bouts. */
.sv-head-turtle { right: auto; left: -12%; bottom: -26%; width: min(74%, 820px); opacity: .17; }
@media (max-width: 899px) { .sv-head-turtle { left: -18%; bottom: -16%; width: 100%; opacity: .14; } }
/* les chiffres ne se devoilent plus un par un : ils sont la, et c'est le nombre qui monte */
.sv-head .value-figs.figs-anim .fig { opacity: 1; transform: none; transition: none; }

/* --- Le compteur etait invisible pendant qu'il montait (Sam : « les chiffres apparaissent blancs ») ---
   Le chiffre reel est mis en transparent pendant le comptage et le nombre en cours s'affiche dans un
   ::after. Celui-ci heritait de la couleur de son parent... devenu transparent. Resultat : on ne voyait
   rien pendant toute la seconde, puis le chiffre surgissait d'un coup. Il faut lui donner l'encre en
   clair, pas par heritage. --fig-ink est pose la ou la couleur du chiffre est decidee. */
.value-figs .fig b { --fig-ink: var(--blue); }
.fig b { --fig-ink: var(--brown); }
.value-figs .fig b, .sv-head .value-figs .fig b { --fig-ink: var(--blue); }
.fig b .cnt.counting::after { color: var(--fig-ink, currentColor); }

/* ==================== @passe-09-11 : retours de Sam sur la tete d'Interventions et la langue ====

   LA REGLE DE FOND (Sam) : le brun fonce est reserve a ce qui encadre le site — la barre du haut et
   le pied de page. Tout ce qui est dans les pages, quand c'est brun, est en brun clair. */
.sv-head { background: var(--surface); }

/* La tortue passe a droite : a gauche elle passait derriere le titre. Elle sort toujours du cadre. */
.sv-head-turtle { left: auto; right: -10%; bottom: -24%; width: min(62%, 700px); opacity: .15; }
@media (max-width: 899px) { .sv-head-turtle { right: -22%; left: auto; bottom: -14%; width: 92%; opacity: .12; } }

/* Les numeros de section et leur filet passent a l'orange */
.sv-s > .wrap > h2 span { color: var(--orange); }
.sv-s > .wrap > h2 { border-bottom-color: var(--orange); }

/* --- Le choix de la langue : une pastille dessinee qui montre la langue en cours, et s'ouvre --- */
.site-footer .lang { position: relative; background: transparent; border: 0; overflow: visible; }
.lang-now { display: inline-flex; align-items: center; gap: 8px; min-height: 44px; padding: 10px 18px;
  border: 0; background: transparent; color: var(--beige); cursor: pointer; font: inherit;
  font-family: var(--font-2); font-size: .78rem; font-weight: 700; letter-spacing: .1em;
  text-transform: uppercase; position: relative; isolation: isolate; --btn-h: 44px; }
.lang-now::before { content: ""; position: absolute; inset: 0; z-index: -1; pointer-events: none;
  background-color: var(--beige);
  -webkit-mask-image: url(../img/btn-line-l.svg), url(../img/btn-line-r.svg), url(../img/btn-line-m.svg);
  mask-image: url(../img/btn-line-l.svg), url(../img/btn-line-r.svg), url(../img/btn-line-m.svg);
  -webkit-mask-repeat: no-repeat; mask-repeat: no-repeat;
  -webkit-mask-position: left center, right center, center; mask-position: left center, right center, center;
  -webkit-mask-size: 22px 100%, 22px 100%, calc(100% - 42px) 100%;
  mask-size: 22px 100%, 22px 100%, calc(100% - 42px) 100%; }
.lang-now .ar { font-size: .7em; transition: transform .2s; }
.lang-now[aria-expanded="true"] .ar { transform: rotate(180deg); }
.site-footer .lang .lang-list { position: absolute; left: 0; bottom: calc(100% + 8px); z-index: 5;
  display: grid; gap: 2px; padding: 6px; border-radius: 14px; background: var(--surface);
  box-shadow: 0 14px 34px rgba(20, 10, 4, .4); min-width: 100%; }
.site-footer .lang .lang-list[hidden] { display: none; }
.site-footer .lang .lang-list a { padding: 9px 16px; border-radius: 10px; min-height: 40px; }
.site-footer .lang .lang-list a[aria-current="true"] { background: var(--beige); color: var(--choco); }

/* --- Les deux marques (Sam, 09/11) : la signature complete en haut, la tortue seule en bas --- */
.site-header .logo-img { height: 46px; }
@media (max-width: 760px) { .site-header .logo-img { height: 42px; } }
.site-footer .foot-mark { display: block; width: auto; height: 68px; }
/* plus de tortue en filigrane a droite du bandeau : celle du pied de page suffit */
.close::before { content: none; }

/* --- Les numeros de section : l'orange ne passe pas en texte sur le beige (2,33:1), il passe en
       pastille (5,74:1 d'encre). Meme traitement que les numeros des cartes. --- */
.sv-s > .wrap > h2 span { color: #2b1f18; background: var(--orange); border-radius: 999px;
  padding: .18em .5em .22em; margin-right: .5em; display: inline-block; }

/* --- Qui on est : le portrait suit le texte de la personne (Sam, 09/11) ------------------------
   Il restait en haut de la ligne pendant qu'on lisait toute la biographie. Il est maintenant colle
   sous la barre et descend avec le texte ; quand la biographie se termine, il part avec elle et
   celui de la personne suivante prend sa place. Seulement a partir de 820 px, la ou la ligne est
   en deux colonnes : sur telephone le portrait est au-dessus du texte, rien a epingler. */
@media (min-width: 820px) {
  .member .face { position: sticky; top: calc(var(--header-h) + clamp(20px, 3vh, 40px));
                  align-self: flex-start; }
}

/* --- Contact : la photo prend la colonne de droite, le formulaire vient dessous (Sam) --- */
.contact-head .wrap { grid-template-columns: minmax(0, 1fr); align-items: start; }
.contact-intro { display: grid; gap: clamp(14px, 2vw, 20px); justify-items: start; }
.contact-head .contact-turtle { position: static; width: clamp(120px, 14vw, 170px); height: auto;
  margin-top: clamp(6px, 1.5vw, 14px); opacity: 1; }
.contact-ph { margin: 0; width: 100%; }
.contact-ph img { width: 100%; height: auto; aspect-ratio: 4 / 3; object-fit: cover;
  object-position: 50% 28%; border-radius: clamp(14px, 2vw, 22px); display: block; }
@media (min-width: 900px) {
  .contact-head .wrap { grid-template-columns: minmax(0, 1fr) minmax(0, .92fr);
    column-gap: clamp(32px, 5vw, 64px); align-items: center; }
  .contact-ph img { aspect-ratio: 5 / 4; }
}
@media (max-width: 760px) {
  .contact-ph img { border-radius: 14px; aspect-ratio: 3 / 2; }
  .contact-head .contact-turtle { display: block; width: 108px; }  /* elle etait masquee sur telephone */
}

/* --- Contact, repris (Sam, 09/11) -------------------------------------------------------------
   Sam : « on ne voit pas toute la photo, on ne voit que nos tetes ». Elle n'est plus recadree du
   tout : le fichier garde le cadrage d'Alix, et la page l'affiche en entier. Plus de tortue ici. */
.contact-ph img { aspect-ratio: auto; object-fit: fill; height: auto; }
@media (min-width: 900px) { .contact-ph img { aspect-ratio: auto; } }
@media (max-width: 760px) { .contact-ph img { aspect-ratio: auto; } }

/* --- Les trois chiffres d'Interventions dans la forme dessinee (Sam) ---
   Le nombre est large et court, comme un bouton : la forme en trois morceaux s'y pose sans
   deformation, contrairement aux champs du formulaire ou elle s'etirait en lentille. */
.sv-head .fig b { position: relative; isolation: isolate; display: inline-flex; align-items: center;
  padding: 6px 22px 8px; --btn-h: 64px; margin-bottom: 8px; }
.sv-head .fig b::before { content: ""; position: absolute; inset: 0; z-index: -1; pointer-events: none;
  background-color: rgba(249, 232, 212, .10);
  -webkit-mask-image: url(../img/btn-shape-l.svg), url(../img/btn-shape-r.svg), url(../img/btn-shape-m.svg);
  mask-image: url(../img/btn-shape-l.svg), url(../img/btn-shape-r.svg), url(../img/btn-shape-m.svg);
  -webkit-mask-repeat: no-repeat; mask-repeat: no-repeat;
  -webkit-mask-position: left center, right center, center; mask-position: left center, right center, center;
  -webkit-mask-size: 32px 100%, 32px 100%, calc(100% - 62px) 100%;
  mask-size: 32px 100%, 32px 100%, calc(100% - 62px) 100%; }
.sv-head .fig { margin-bottom: 4px; }

/* --- La tete d'Interventions, version du 09/11 (Sam) ------------------------------------------
   Deux comptes complets — ils portent sur tous les projets — puis les trois familles de gain.
   L'argent n'est plus ici : il n'etait mesure que la ou le cout d'une heure etait connu, et un
   compte partiel pose a cote d'un compte complet se lit comme un total. Il reste dans les cas. */

/* Les trois familles : sept cas rendent du temps, deux evitent une depense, deux rendent possible
   ce qui ne l'etait pas. Le chiffre est compte dans build.py, il suit le classement. */
.sv-fams { margin-top: clamp(22px, 3vw, 32px); padding-top: clamp(16px, 2.2vw, 22px);
  border-top: 1px solid rgba(249, 232, 212, .26); }
.sv-fams-k { color: var(--cream-muted); font-family: var(--font-2); font-size: .72rem; letter-spacing: .13em;
  text-transform: uppercase; margin: 0 0 12px; }
.sv-fams ul { list-style: none; margin: 0; padding: 0; display: grid; gap: 8px; }
.sv-fams li { color: var(--beige); font-size: .95rem; display: flex; align-items: baseline; gap: 10px; }
.sv-fams li b { font-family: var(--font-2); font-weight: 700; font-size: 1.05rem; min-width: 1.4em; }
.sv-fams .sv-fam--temps b { color: var(--blue); }
.sv-fams .sv-fam--cout b { color: var(--orange); }
.sv-fams .sv-fam--possible b { color: var(--beige); }

/* L'etiquette sur chaque cas : on sait tout de suite de quel genre de gain il s'agit */
.fam { display: inline-block; font-family: var(--font-2); font-size: .66rem; font-weight: 700;
  letter-spacing: .12em; text-transform: uppercase; padding: 4px 10px 5px; border-radius: 999px;
  margin-bottom: 8px; }
.sv-c > .fam { align-self: start; }
.fam--temps { background: rgba(140, 181, 199, .3); color: var(--choco); }
.fam--cout { background: var(--orange); color: #2b1f18; }
.fam--possible { background: var(--choco); color: var(--beige); }


/* --- Le bas de page, refait d'un bloc (Sam, 09/11 : « c'est moche, les deux lignes sont terribles ») ---
   Le defaut n'etait pas la couleur : c'etaient quatre elements epingles aux quatre coins d'un cadre
   large, avec du vide entre eux. Le bouton flottait seul a droite du titre ; dans le pied, la tortue
   et la langue etaient plaquees aux deux bords et les liens centres sur une troisieme ligne : trois
   alignements differents dans un bloc de deux cents pixels.
   Maintenant tout part du meme bord gauche. Le bandeau est une colonne : titre, phrase, bouton, l'un
   sous l'autre. Le pied est une seule ligne : la tortue, les liens a sa suite, la langue au bout. */
.close .wrap { max-width: 56ch; gap: clamp(18px, 2.4vw, 26px); }
.close .btn { justify-self: start; }
@media (min-width: 860px) {
  .close .wrap { grid-template-columns: minmax(0, 1fr); justify-content: start; gap: clamp(18px, 2.4vw, 26px); }
}
.close .lead { margin-bottom: clamp(4px, .8vw, 10px); }

.site-footer { padding: clamp(22px, 2.6vw, 32px) 0; }
.site-footer .foot-mark { height: clamp(40px, 4vw, 48px); margin: 0; }
.site-footer .logo { margin: 0; flex: none; }
/* Sept liens plus la tortue plus la langue ne tiennent pas sur une ligne de 1180 px : les liens
   passaient a la ligne et retombaient au milieu, ce qui refaisait le defaut de depart. Ils occupent
   donc une colonne a eux, collee a la tortue, ou ils s'alignent a gauche sur deux rangs au besoin.
   Trois colonnes, un seul bord de depart, aucun vide au milieu. */
.site-footer .wrap { display: grid; grid-template-columns: auto minmax(0, 1fr) auto;
  align-items: center; gap: 10px clamp(22px, 2.8vw, 38px); }
.site-footer ul { display: flex; flex-wrap: wrap; gap: 2px clamp(16px, 1.8vw, 24px);
  border-top: 0; padding: 0; justify-content: flex-start; }
.site-footer ul a { padding: 5px 0; }
.site-footer .lang { flex: none; justify-self: end; }
@media (max-width: 760px) {
  /* sur telephone la ligne ne tient pas : la tortue et la langue se partagent le haut,
     les liens passent en deux colonnes dessous */
  .site-footer .wrap { display: grid; grid-template-columns: auto auto; justify-content: space-between;
    align-items: center; gap: 16px; }
  .site-footer .logo { grid-row: 1; grid-column: 1; }
  .site-footer .lang { grid-row: 1; grid-column: 2; justify-self: end; margin-left: 0; }
  .site-footer ul { grid-row: 2; grid-column: 1 / -1; display: grid; grid-template-columns: 1fr 1fr;
    gap: 0 18px; padding-top: 14px; border-top: 1px solid rgba(249, 232, 212, .18); }
  .site-footer ul a { font-size: .92rem; }
}

/* --- La tete d'Interventions sur ordinateur (Sam, 09/11) --------------------------------------
   Le titre fait quatre lignes ; les chiffres prennent toute sa hauteur pour que la colonne de
   droite ne flotte pas au milieu d'un vide brun. Ce sont les trois chiffres de l'accueil, ecrits
   une seule fois dans figs_html : .value-figs, pas une mise en forme a part.
   Sur telephone rien ne change. */
@media (min-width: 900px) {
  .sv-head { padding-top: clamp(44px, 5vw, 76px); padding-bottom: clamp(44px, 5vw, 76px); }
  .sv-head .wrap { align-items: stretch; }
  .sv-head .page-title { align-self: center; }
  .sv-head .value-figs { align-content: space-between; height: 100%; gap: clamp(18px, 2.6vh, 34px); }
  .sv-head .value-figs .fig b { font-size: clamp(2.3rem, 3.6vw, 3.6rem); }
  .sv-head .value-figs .fig > span { font-size: clamp(.95rem, 1.1vw, 1.08rem); }
}

/* --- Approche : la bande s'agrandit pour montrer plus de la photo (Sam, 09/11) -----------------
   A 620 px de haut sur un ecran large, le cadrage ne gardait que la moitie haute de l'image : on
   voyait les visages et rien en dessous. La bande monte a 740 px et la fenetre descend un peu :
   les jambes et les chaussures entrent dans le cadre sans que les tetes en sortent. */
.ap-hero { min-height: clamp(430px, 56vw, 740px); }
.ap-hero > img { object-position: 50% 36%; }

/* --- Contact : la tete etait trop aeree (Sam) --------------------------------------------------
   Beaucoup de beige autour d'une photo posee loin du titre. On resserre les marges, la photo prend
   toute sa colonne et le formulaire remonte. */
.contact-head { padding: clamp(28px, 3.4vw, 48px) 0 clamp(20px, 2.6vw, 34px); }
.contact-head .wrap { gap: clamp(20px, 3vw, 40px); }
/* La photo garde son cadrage entier, comme Sam l'avait demande : c'est la page qu'on resserre,
   pas l'image qu'on recadre. */
.contact-ph img { aspect-ratio: auto; object-fit: fill; height: auto; }
@media (min-width: 900px) {
  .contact-head .wrap { column-gap: clamp(26px, 3.4vw, 48px); align-items: center;
    grid-template-columns: minmax(0, .88fr) minmax(0, 1.12fr); }
}
.contact-box { padding-top: 0; }
body.page-contact .sec { padding-top: clamp(22px, 3vw, 40px); }

/* ------------------------------------------------------------------
   09/11 (Sam) : le recit des fondateurs passe sur le brun clair, et il
   y reste jusqu'a la bande de fin. Le beige courait sans interruption
   du titre jusqu'au pied de page, et rien ne marquait le passage du
   « qui on est » au « d'ou on vient ».
   Classe a part : la meme section .sec--tint sert l'expertise sur
   l'accueil, qui ne change pas.
   Brun clair #674c3f, encre beige : 6,31:1.
   ------------------------------------------------------------------ */
.sec--story { background: var(--surface); color: var(--beige); }
.sec--story h1, .sec--story h2, .sec--story h3 { color: var(--beige); }
.sec--story p, .sec--story li { color: var(--beige); }
.sec--story .quote { color: var(--beige); }
.sec--story a { color: var(--beige); text-decoration-color: rgba(249, 232, 212, .5); }
.sec--story a:hover { text-decoration-color: var(--beige); }

/* Le schema : tout ce qui etait trace en brun disparaitrait sur du brun. */
/* 09/11 (Sam a choisi B) : sur le brun, le blanc montait a 1 quand la troisieme dimension est lue.
   Il trouait le fond, ecrasait les deux autres cercles et avalait sa propre etiquette — beige sur
   blanc. Les trois plafonnent maintenant au meme niveau : aucun ne prend le dessus.
   .vc1 seul change de teinte ; .vc2 reste bleu et .vc3 blanc, les deux tiennent sur le brun. */
.sec--story .vc1 { fill: var(--beige); fill-opacity: .20; }
.sec--story .vc2 { fill-opacity: .38; }
.sec--story .vc3 { fill-opacity: .26; }
.sec--story .venn[data-on="1"] .vc1 { fill-opacity: .32; }
.sec--story .venn[data-on="2"] .vc2 { fill-opacity: .50; }
.sec--story .venn[data-on="3"] .vc3 { fill-opacity: .46; }
.sec--story .venn-core { fill: var(--choco); }
.sec--story .vr { stroke: var(--beige); }
/* Les etiquettes traversent trois aplats et le brun nu : aucune couleur unique ne tient partout.
   Mesure avec l'encre beige : 4,17 / 3,90 / 3,39 au repos, et 2,17:1 sur le cercle blanc quand la
   troisieme dimension est lue — sous le 4,5:1 d'un texte de 14 px gras.
   La charte a deja la reponse pour les etiquettes des anneaux : encre foncee, halo beige derriere.
   Le halo suit le texte partout, donc le rapport ne depend plus de ce qu'il y a dessous : 10,31:1. */
.sec--story .venn-l { color: var(--choco);
  text-shadow: 0 0 4px var(--beige), 0 0 4px var(--beige), 0 0 3px var(--beige), 0 0 2px var(--beige); }
.sec--story .venn-ic svg { stroke: var(--choco);
  filter: drop-shadow(0 0 2px var(--beige)) drop-shadow(0 0 2px var(--beige)); }

/* L'ombre des photos etait calculee pour du beige ; sur le brun elle salit. */
.sec--story .story-photo img { box-shadow: 0 22px 46px rgba(35, 22, 16, .28); }



/* ==================================================================================================
   Contact refaite (Sam, 09/11, sur la page de Galadrim)
   Du contenu a gauche, le formulaire a droite dans une carte claire posee sur un panneau brun.
   Ce qui faisait la difference chez Galadrim et manquait a mes premiers essais : la carte est
   CLAIRE sur un panneau colore (pas l'inverse), et les champs sont sur DEUX colonnes, ce qui rend
   la carte large et courte au lieu d'une colonne qui descend.
   Le panneau est un degrade des deux bruns, pas une photo : un portrait derriere une carte se fait
   couper en deux. La tortue y passe en filigrane.
   Mesures : encre #141414 sur la carte blanche 18,42:1 ; etiquettes --muted 5,82:1 ; filet des
   champs --muted 5,82:1 (il etait a 1,57:1 avec --line, on ne voyait pas ou taper) ; numeros 01-05
   en --brown 7,3:1 (ils etaient en bleu a 2,05:1, ce que la charte interdit sur fond clair).
   ================================================================================================== */
body.page-contact, body.page-join { background: var(--cream); }
body.page-contact .sec, body.page-contact .contact-ways,
body.page-join .sec { background: transparent; }

.ct-grid { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1.06fr);
  gap: clamp(34px, 4.6vw, 76px); align-items: start; }
.ct-k { font-family: var(--font-2); font-size: .72rem; font-weight: 700; letter-spacing: .16em;
  text-transform: uppercase; color: var(--muted); margin: 0 0 18px; }
.ct-h1 { font-size: clamp(2.2rem, 4vw, 3.6rem); line-height: 1.02; letter-spacing: -.03em;
  color: var(--choco); max-width: 13ch; margin: 0 0 20px; }
.ct-lead { font-size: clamp(1.02rem, 1.25vw, 1.15rem); line-height: 1.6; color: var(--body);
  max-width: 42ch; margin: 0; }
/* 10/11 (Sam) : les deux phrases du chapeau l'une sous l'autre. Ce sont deux <span> en bloc et non un
   <br>, pour que la coupure tienne a la redaction et non a la largeur. */
.ct-lead > span { display: block; }

/* Les cinq situations : les memes que la page Interventions, et les memes que le menu deroulant. */
.ct-cas { margin-top: clamp(32px, 4vw, 56px); }
.ct-cas-k { font-family: var(--font-2); font-size: .7rem; font-weight: 700; letter-spacing: .14em;
  text-transform: uppercase; color: var(--muted); margin: 0 0 12px; }
.ct-cas-l { list-style: none; margin: 0; padding: 0; display: grid; }
.ct-cas-l li { display: grid; grid-template-columns: auto minmax(0, 1fr) auto; align-items: baseline;
  gap: 0 14px; padding: 12px 0; border-bottom: 1px solid var(--line); }
.ct-cas-l li:first-child { border-top: 1px solid var(--line); }
.ct-n { font-family: var(--font-2); font-weight: 700; font-size: .76rem; color: var(--brown); letter-spacing: .04em; }
.ct-t { color: var(--ink); font-size: .98rem; line-height: 1.35; }
.ct-d { font-family: var(--font-2); font-size: .74rem; color: var(--muted); white-space: nowrap; }
.ct-cas-p { margin: 14px 0 0; font-size: .9rem; }

.ct-panel { position: relative; border-radius: clamp(18px, 2.4vw, 28px); overflow: hidden;
  isolation: isolate; padding: clamp(22px, 3.2vw, 52px); display: grid; align-items: center;
  background: linear-gradient(152deg, var(--surface) 0%, #5b4236 48%, var(--frame) 100%); }
.ct-panel::before { content: ""; position: absolute; right: -6%; bottom: -8%; width: min(62%, 400px);
  aspect-ratio: 571 / 358; background: url(../img/tortue-brun-beige.webp) center / contain no-repeat;
  opacity: .26; z-index: -1; }

.ct-card { background: #fff; border-radius: clamp(14px, 1.8vw, 20px);
  padding: clamp(22px, 2.6vw, 36px); box-shadow: 0 26px 60px rgba(35, 22, 16, .26); }
.ct-card-h { display: grid; grid-template-columns: auto minmax(0, 1fr); gap: 16px; align-items: center;
  margin-bottom: clamp(20px, 2.4vw, 28px); }
.ct-mark { width: 54px; height: auto; display: block; }
.ct-card-k { font-family: var(--font-2); font-size: .68rem; font-weight: 700; letter-spacing: .14em;
  text-transform: uppercase; color: var(--muted); margin: 0 0 3px; }
.ct-card-h h2 { font-size: clamp(1.15rem, 1.6vw, 1.4rem); line-height: 1.15; color: var(--ink); margin: 0; }

.ct-form { display: grid; gap: clamp(14px, 1.8vw, 20px); margin: 0; max-width: none; }
.ct-2 { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: clamp(14px, 1.8vw, 22px); }
.ct-f { display: grid; gap: 6px; }
.ct-card label { font-family: var(--font-2); font-size: .7rem; font-weight: 700; letter-spacing: .1em;
  text-transform: uppercase; color: var(--muted); }
.ct-card input, .ct-card select { font: inherit; border: 0; border-bottom: 1.5px solid var(--muted);
  border-radius: 0; background-color: transparent; color: var(--ink); padding: 8px 2px; width: 100%;
  -webkit-appearance: none; appearance: none; transition: border-color .2s, box-shadow .2s; }
.ct-card input:focus, .ct-card select:focus { outline: none; border-bottom-color: var(--choco);
  box-shadow: 0 1px 0 0 var(--choco); }
.ct-card select { padding-right: 28px; background-repeat: no-repeat; background-position: right 2px center;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='14' height='9' viewBox='0 0 14 9'%3E%3Cpath d='M1 1l6 6 6-6' fill='none' stroke='%236b645d' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E"); }
.ct-card select:invalid { color: var(--muted); }
.ct-card .form-actions { display: flex; flex-direction: row; justify-content: flex-end;
  align-items: center; gap: 14px; margin-top: 4px; flex-wrap: wrap; }
.ct-card .form-status { margin: 0; font-size: .9rem; color: var(--body); }

/* Sam, 09/11 : « enleve l'espace en bas ». Le bas de section et le haut de la bande des deux liens
   s'additionnaient sous une colonne gauche deja plus courte que le panneau. */
body.page-contact .ct, body.page-join .ct { padding-bottom: clamp(18px, 2.4vw, 34px); }
body.page-contact .contact-ways { padding: 0 0 clamp(24px, 3vw, 40px); }
body.page-contact .contact-ways .wrap { padding-top: clamp(16px, 2vw, 24px);
  border-top: 1px solid var(--line); }

@media (max-width: 899px) {
  .ct-grid { grid-template-columns: minmax(0, 1fr); }
  .ct-2 { grid-template-columns: minmax(0, 1fr); }
  .ct-panel { padding: clamp(16px, 4vw, 24px); }
}

/* --- Nous rejoindre : la meme carte que Contact, plus un champ long et la photo (Sam, 09/11) --- */
.ct-card textarea { font: inherit; border: 0; border-bottom: 1.5px solid var(--muted); border-radius: 0;
  background-color: transparent; color: var(--ink); padding: 8px 2px; width: 100%; resize: vertical;
  min-height: 7.5em; transition: border-color .2s, box-shadow .2s; }
.ct-card textarea:focus { outline: none; border-bottom-color: var(--choco); box-shadow: 0 1px 0 0 var(--choco); }
.jn-p > p { margin: 0 0 .9em; }
.jn-p > p:last-child { margin-bottom: 0; }
.jn-note { margin: 10px 0 0; font-size: .86rem; color: var(--muted); }
.jn-ph { margin: clamp(26px, 3.4vw, 44px) 0 0; }
.jn-ph img { display: block; width: 100%; height: auto; aspect-ratio: 3 / 2; object-fit: cover;
  object-position: 50% 32%; border-radius: clamp(14px, 2vw, 22px); }
@media (max-width: 899px) { .jn-ph { margin-top: clamp(20px, 4vw, 30px); } }
/* La ligne du CV, sous le champ long : le formulaire ouvre la messagerie, la piece jointe
   s'ajoute la-bas. Elle deviendra un vrai champ fichier le jour ou le formulaire aura un dos. */
.jn-cv { margin: 8px 0 0; font-size: .84rem; line-height: 1.45; color: var(--muted); }

/* ==================================================================================================
   Interventions : couleurs inversées (Sam, 09/11)
   La tête passe au beige et la bande des cinq situations au brun clair — l'inverse d'avant.
   Le filet au-dessus des chiffres disparaît (10/11 : il a disparu partout, la regle de base ne le
   dessine plus — il n'y a donc plus rien a annuler ici).

   Ce que l'inversion force : le bleu ne tient pas sur du beige (1,83:1, la charte l'interdit).
   Plutôt que de perdre le bleu que Sam avait demandé pour ces chiffres, la pastille dessinée qui
   était en beige translucide passe en brun foncé plein : le chiffre reste bleu et se lit à 5,62:1.
   ================================================================================================== */
.sv-head { background: var(--beige); }
.sv-head .page-title { color: var(--choco); }
.sv-head .value-figs .fig > span { color: var(--body); }
.sv-head .value-note { color: var(--muted); }

/* La pastille devient le fond sombre qui porte le bleu. */
.sv-head .fig b::before { background-color: var(--choco); }

/* La tortue en filigrane était beige : invisible sur du beige. Le fichier brun est posé dans le
   gabarit, pas par un content: url() — sinon le navigateur télécharge les deux. */
.sv-head-turtle { opacity: .16; }

/* La bande des cinq situations prend le brun clair que la tête abandonne. Les cartes restent
   blanches : blanc sur brun clair, elles se détachent mieux qu'elles ne le faisaient sur le beige. */
.sv-top { background: var(--surface); padding-bottom: clamp(34px, 4.5vw, 56px); }
.sv-top .bbx-k { color: var(--beige); }


/* ==================================================================================================
   La tête d'Interventions, centrée (Sam, 10/11 — il a choisi la 6)
   Le titre au centre, les trois chiffres en rangée dessous, et la tortue ENTIÈRE en filigrane
   derrière, large. Avant, elle était coupée par le bord droit : on ne voyait qu'un bout de carapace.
   Tout est réécrit ici — position, taille, opacité — parce que trois blocs plus haut la plaçaient
   encore à droite et hors cadre, y compris dans leurs media queries.
   ================================================================================================== */
.sv-head-turtle { left: 50%; right: auto; top: 50%; bottom: auto;
  transform: translate(-50%, -48%); width: min(96%, 1180px); height: auto; opacity: .1; }

/* 10/11 (Sam) : centré sur téléphone aussi. Les chiffres restaient alignés à gauche sous un titre
   qui, lui, était centré à partir de 900 px : deux axes sur la même bande selon la largeur.
   Tout est centré à toutes les largeurs ; seule la mise en rangée des trois chiffres attend 900 px. */
.sv-head .wrap { grid-template-columns: minmax(0, 1fr); justify-items: center; text-align: center;
  gap: clamp(22px, 3.4vw, 42px); align-items: start; }
/* 18ch sur telephone, c'est 366 px dans une fenetre de 390 : la boite du titre sortait du cadre
   et .sv-head, qui coupe ce qui depasse, en mangeait la fin sans que rien ne le signale. */
/* justify-items: center dimensionne l'element sur son contenu : le titre se faisait une boite de
   366 px dans une fenetre de 390, et .sv-head, qui coupe ce qui depasse, en mangeait la fin sans
   que rien ne le signale. justify-self: stretch le ramene a la largeur de la colonne ; c'est
   text-align qui le centre, pas la grille. */
.sv-head .page-title { grid-row: auto; grid-column: auto; justify-self: stretch; width: 100%;
  max-width: 100%; text-align: center; align-self: auto; margin-bottom: 0; }
.sv-head .value-figs { grid-column: auto; grid-row: auto; display: grid; height: auto;
  max-width: none; width: 100%; justify-items: center; text-align: center; align-content: start; }
.sv-head .value-figs .fig { display: grid; justify-items: center; }
.sv-head .value-figs .fig > span { max-width: 24ch; text-align: center; }

@media (min-width: 900px) {
  .sv-head .page-title { max-width: 18ch; justify-self: center; width: auto; }
  .sv-head .value-figs { grid-template-columns: repeat(3, minmax(0, 1fr)); gap: clamp(22px, 3vw, 48px); }
  .sv-head .value-figs .fig > span { max-width: 20ch; }
}

/* Sur téléphone la bande reste empilée ; la tortue garde la même place, un peu plus marquée
   parce qu'elle a moins de surface pour se faire voir. */
@media (max-width: 899px) {
  .sv-head-turtle { left: 50%; right: auto; bottom: auto; top: 50%;
    transform: translate(-50%, -46%); width: 128%; opacity: .12; }
}

/* --- Contact sur téléphone : la liste des cinq situations (Sam, 10/11) ------------------------
   Trois colonnes — numéro, titre, nombre de démos — tenaient encore à 390 px, mais le titre se
   retrouvait dans une colonne de 230 px : « Des outils qui ne communiquent pas / entre eux »,
   « Des opérations encore / largement manuelles ». Le nombre de démos, lui, partait tout seul
   contre le bord droit.
   Sur téléphone la ligne passe à deux colonnes et le nombre de démos descend sous le titre, aligné
   avec lui : le titre récupère toute la largeur et casse où la phrase le permet. */
@media (max-width: 700px) {
  .ct-cas-l li { grid-template-columns: auto minmax(0, 1fr); gap: 3px 12px; padding: 14px 0; }
  .ct-d { grid-column: 2; font-size: .76rem; }
  .ct-cas-k { margin-bottom: 10px; }
}

/* --- Contact et Nous rejoindre : le formulaire remonte sur téléphone (Sam, 10/11) -------------
   « on the phone we don't see the contact form » : il arrivait après le titre, la phrase et les
   cinq situations, soit à peu près un écran et demi plus bas. Sur une page dont le seul but est
   qu'on écrive, le formulaire ne peut pas être le dernier élément.
   La colonne de gauche se coupe en deux (.ct-intro et ce qui la suit), et les trois blocs
   deviennent frères dans la grille. Sur téléphone l'ordre devient : titre, FORMULAIRE, le reste.
   Sur ordinateur rien ne bouge : des zones nommées remettent intro et liste à gauche,
   le formulaire à droite sur les deux rangées. */
.ct-grid { grid-template-areas: "intro" "form" "reste";
  /* 10/11 : l'ecart entre les rangees etait compte deux fois — le gap de la grille PUIS une marge
     sur .ct-cas. 110 px entre la phrase et « Les cinq situations » sur ordinateur. Le gap des
     rangees se separe de celui des colonnes, et les marges disparaissent. */
  gap: clamp(20px, 2.4vw, 34px) clamp(34px, 4.6vw, 76px); }
.ct-intro { grid-area: intro; }
.ct-panel { grid-area: form; }
.ct-cas, .jn-ph { grid-area: reste; margin-top: 0; }

@media (min-width: 900px) {
  .ct-grid { grid-template-areas: "intro form" "reste form";
    grid-template-rows: auto 1fr; align-items: start; }
}

/* --- Contact : le bloc des deux liens passe au brun foncé (Sam, 10/11) ------------------------
   Il fermait la page sur le même crème que tout le reste, séparé par un simple filet. En brun il
   devient une bande, et le filet n'a plus lieu d'être : c'est la couleur qui sépare.
   D'abord en brun clair, puis en brun foncé le même jour, à la demande de Sam : la page se termine
   donc sur deux tons, crème puis brun foncé, et la bande ne fait plus qu'un bloc avec le pied, dont
   le filet beige à 18 % reste la seule séparation.
   C'est --frame, le brun qui encadre le site (barre du haut, bande de fin, pied), pas --surface.
   Encre beige sur #472f24 : 10,31:1, le meilleur contraste de la charte. */
body.page-contact .contact-ways { background: var(--frame); color: var(--beige);
  padding: clamp(30px, 4vw, 54px) 0 clamp(32px, 4.2vw, 58px); margin-top: clamp(26px, 3.4vw, 44px); }
body.page-contact .contact-ways .wrap { padding-top: 0; border-top: 0; }
body.page-contact .contact-ways h3 { color: var(--beige); }
body.page-contact .contact-ways p { color: var(--beige); }
body.page-contact .contact-ways .more-link { color: var(--beige);
  text-decoration-color: rgba(249, 232, 212, .55); }
body.page-contact .contact-ways .more-link:hover { text-decoration-color: var(--beige); }

/* ==================== @forms-n8n + @cookies (11/11, Rafi) ==================== */
/* Honeypot: in the form for bots, never seen or reached by people (aria-hidden, tabindex -1, off screen). */
.join-form .hp { position: absolute; left: -10000px; width: 1px; height: 1px; overflow: hidden; margin: 0; }
.join-form { position: relative; }
.join-form button[type="submit"][disabled] { opacity: .6; cursor: progress; }
.ct-card input[type="file"] { border: 0; padding: 6px 0; font-size: .9rem; color: var(--body); box-shadow: none; }
.ct-card input[type="file"]::file-selector-button { font: inherit; font-weight: 700; margin-right: 12px; padding: 8px 16px; min-height: 40px;
  border: 1.5px solid var(--brown); border-radius: 999px; background: transparent; color: var(--brown); cursor: pointer; }
/* Consent bar: bottom of the screen, above everything but the language picker; Refuse and Accept are the same button. */
.cookie-bar { position: fixed; left: 14px; right: 14px; bottom: calc(14px + env(safe-area-inset-bottom)); z-index: 96; max-width: 640px; margin: 0 auto;
  display: grid; gap: 12px; padding: 16px 18px; border-radius: 16px; background: var(--cream); color: var(--ink);
  border: 1.5px solid var(--brown); box-shadow: 0 12px 36px rgba(0,0,0,.18); font-size: .92rem; line-height: 1.45; }
.cookie-bar[hidden] { display: none; }
.cookie-bar p { margin: 0; }
.cookie-bar a { color: var(--brown); font-weight: 700; }
.cookie-btns { display: flex; flex-wrap: wrap; gap: 10px; }
.cookie-btns .btn { flex: 1 1 120px; justify-content: center; min-height: 44px; padding: 10px 20px; }
/* 11/11 (Sam) : dans le pied de page, « Cookies » doit se lire comme les autres liens — meme
   souligne, meme ligne. Le min-height de 44px (cible tactile) rendait son cadre plus haut que
   celui des liens, qui le poussait de 8px vers le bas : la hauteur reste, le texte se recentre. */
/* 11/11 (Sam) : dans le pied de page, « Cookies » doit se lire comme les autres liens — meme
   souligne, meme ligne. Son min-height de 44px (cible tactile) rendait sa boite plus haute que
   celle des liens et le poussait vers le bas. La boite copie donc exactement celle d'un lien, et
   les 44px tactiles reviennent par un ::after invisible, qui ne pese pas sur la mise en page. */
.cookie-manage { font: inherit; color: var(--beige); background: none; border: 0; padding: 5px 0;
  cursor: pointer; text-decoration: underline; display: inline-block; position: relative;
  line-height: inherit; vertical-align: baseline; }
.cookie-manage::after { content: ""; position: absolute; left: 0; right: 0; top: 50%;
  transform: translateY(-50%); height: 44px; }
.cookie-manage:hover { text-decoration: none; }
