/* sub-page + shared chrome additions */
/* address entry (addr.js) */
.addr{position:relative;flex-wrap:wrap}
.addr-aux{flex:0 0 36px;height:36px;display:grid;place-items:center;background:none;border:0;border-radius:6px;color:var(--faint);cursor:pointer}
.addr-aux:hover{color:var(--ink);background:var(--cream)}
.addr-aux svg,.addr .btn svg{color:inherit}
.addr .btn{gap:8px;white-space:nowrap}
.addr .btn.busy{opacity:.8}
.spin{width:14px;height:14px;border:2px solid rgba(245,240,229,.35);border-top-color:var(--cream);border-radius:50%;animation:spin .7s linear infinite}
@keyframes spin{to{transform:rotate(360deg)}}
/* --focus reset (A-01): the suggestion popup is white and can be rendered inside the navy
   .cta section, where --focus would otherwise still be mustard. */
.addr-list{position:absolute;left:-1px;right:-1px;top:calc(100% + 8px);background:#fff;--focus:var(--teal-deep);border:1px solid var(--rule-ui);border-radius:10px;box-shadow:0 24px 60px -20px rgba(11,43,60,.35);padding:6px;z-index:30;text-align:left}
.addr-opt{display:flex;align-items:center;gap:12px;padding:10px 12px;border-radius:7px;cursor:pointer;color:var(--ink)}
.addr-opt svg{color:var(--faint);flex-shrink:0}
.addr-opt span{display:grid;line-height:1.3;min-width:0}
.addr-opt b{font-weight:600;font-size:15px}
.addr-opt small{font-size:12.5px;color:var(--dim)}
.addr-opt.hi{background:var(--cream)}.addr-opt.hi svg{color:var(--teal-deep)}
/* 12px floor: this line carries the Google Places attribution, which their ToS requires to
   be legible (03 §M5, 04 §1.1). Was 10.5px on the 2.4:1 --faint. */
.addr-foot{font-family:ui-monospace,Menlo,monospace;font-size:12px;color:var(--faint);padding:8px 12px 4px;border-top:1px solid var(--rule-soft);margin-top:4px}
.addr-status{flex:1 0 100%;display:flex;align-items:center;gap:8px;font-size:13.5px;color:var(--ink);padding:9px 10px 5px 0;margin-top:4px;border-top:1px solid var(--rule-soft);line-height:1.4;text-align:left}
.addr-status[hidden],.addr-list[hidden]{display:none}
.addr-status svg{flex-shrink:0}
.addr-status[data-kind="ok"] svg{color:var(--teal-deep)}
.addr-status[data-kind="warn"] svg{color:#8E5D14}
.dots{display:inline-flex;gap:3px;width:15px;justify-content:center}
.dots i{width:4px;height:4px;border-radius:50%;background:var(--dim);animation:dots 1s infinite}
.dots i:nth-child(2){animation-delay:.15s}.dots i:nth-child(3){animation-delay:.3s}
@keyframes dots{0%,80%,100%{opacity:.25}40%{opacity:1}}
.addr[data-phase="covered"],.addr[data-phase="ready"]{border-color:var(--teal-deep)}
.addr[data-phase="uncovered"]{border-color:rgba(142,93,20,.5)}
@media (max-width:560px){.addr .btn{flex:1 0 100%;justify-content:center;margin-top:4px}}
/* A-02 high-contrast parity: the toggle raised --rule to .4, which is still only 2.38:1 —
   i.e. the "high contrast" mode left form boundaries BELOW the 3:1 the default mode now
   meets. --rule-ui goes to .8 here (8.0:1 on #fff, 7.8:1 on #f4f4f4): in this mode more
   contrast is the whole point, so a near-solid boundary is correct, not merely tolerable. */
html[data-contrast="high"]{--dim:#1a2a33;--faint:#3a4a53;--rule:rgba(11,43,60,.4);--rule-soft:rgba(11,43,60,.25);--rule-ui:rgba(11,43,60,.8);--paper:#fff;--cream:#f4f4f4}
.nav-links a.on,.nav-dd-btn.on{color:var(--ink)}
.nav-right .seg.lang{margin-right:2px}.nav-right .seg.lang button{padding:6px 9px;font-size:12px}
/* nav breakpoint: 1100px, not 900 — see responsive.css §6 */
@media (max-width:1100px){.nav-right .seg.lang{display:none}}
.nav-dd{position:relative}
.nav-dd-btn{background:none;border:0;font:inherit;font-size:14.5px;font-weight:500;color:var(--dim);cursor:pointer;display:inline-flex;align-items:center;gap:6px;padding:0}
.nav-dd-btn:hover{color:var(--ink)}
.nav-menu{position:absolute;top:calc(100% + 18px);left:-16px;min-width:300px;background:#fff;border:1px solid var(--rule);border-radius:10px;padding:8px;box-shadow:0 24px 60px -24px rgba(11,43,60,.35);opacity:0;transform:translateY(-6px);pointer-events:none;transition:opacity .2s,transform .2s;display:grid}
.nav-dd:hover .nav-menu,.nav-dd.open .nav-menu,.nav-dd:focus-within .nav-menu{opacity:1;transform:none;pointer-events:auto}
.nav-menu a{display:grid;padding:10px 12px;border-radius:7px;color:var(--ink)}
.nav-menu a:hover{background:var(--cream)}
.nav-menu b{font-weight:600;font-size:14.5px}.nav-menu span{font-size:12.5px;color:var(--dim)}
.nav-dd::before{content:'';position:absolute;left:0;right:0;top:100%;height:20px}
/* A-02: icon-only control — it has no text label, so its border is the only thing that
   says where the button is. 1.31:1 before, 3.50:1 on --paper now. */
.burger{display:none;width:40px;height:40px;background:none;border:1px solid var(--rule-ui);border-radius:6px;cursor:pointer;flex-direction:column;justify-content:center;align-items:center;gap:6px}
.burger span{display:block;width:16px;height:1.5px;background:var(--ink)}
.nav-mobile{display:none}
/* nav breakpoint: 1100px, not 900 — see responsive.css §6. The JS scroll-lock release
   (site.js / consent.css .menu-lock) must use the SAME number: min-width:1101px. */
@media (max-width:1100px){.burger{display:flex}.nav-mobile{display:none;flex-direction:column;border-top:1px solid var(--rule-soft);padding:12px var(--pad) 20px}.nav-mobile a{padding:12px 0;font-size:17px;font-weight:500;border-bottom:1px solid var(--rule-soft)}.menu-open .nav-mobile{display:flex}}
/* live hero scene */
.hero-art .live{display:none;position:absolute;inset:0;color:var(--navy);overflow:visible;clip-path:none}
html[data-hero="live"] .hero-art{background:transparent;border-radius:0;overflow:visible;clip-path:none;aspect-ratio:1/1}
html[data-hero="live"] .hero-rule{margin-top:0}
html[data-hero="live"] .hero-art .photo,html[data-hero="live"] .hero-art .hero-tag{display:none}html[data-hero="live"] .hero-art .live{display:block}
html[data-hero="live"] .hero-art{aspect-ratio:1/1}
.sky{position:absolute;left:-6%;right:-8%;bottom:6%;height:44%;opacity:.2;color:var(--navy)}
.sky svg path,.sky svg line{stroke-width:1.1}
.skyline{position:absolute;inset:0;opacity:1;transition:opacity 1.4s;display:flex;align-items:flex-end}
.skyline.out{opacity:0}
.skyline.active{opacity:1}.skyline svg{width:100%;height:100%;display:block}.skyline svg{preserve-aspect-ratio:none}
.ground{position:absolute;left:-6%;right:-2%;bottom:-3%;height:7%;background:radial-gradient(ellipse at center,rgba(11,43,60,.22),transparent 72%);filter:blur(4px);z-index:1}
.live .mascot-fg{position:absolute;left:50%;bottom:0;width:112%;height:auto;max-width:none;object-fit:contain;transform:translateX(-48%);filter:drop-shadow(0 24px 30px rgba(11,43,60,.22));z-index:2}
.cloud{z-index:4}
.streams{position:absolute;inset:0;pointer-events:none;z-index:3}
.streams svg{width:100%;height:100%}
.ds{stroke:var(--teal-deep);stroke-width:1.4;fill:none;stroke-dasharray:3 7;opacity:.75;animation:dflow 2.2s linear infinite}
.ds.b{animation-duration:2.9s;opacity:.45;stroke-dasharray:2 6}.ds.c{animation-duration:3.4s;opacity:.35;stroke-dasharray:2 8}
@keyframes dflow{to{stroke-dashoffset:-20}}
.pk{fill:var(--teal);filter:drop-shadow(0 0 4px rgba(27,164,182,.6));offset-path:path('M 112 486 C 96 440 84 400 108 322');animation:pk 2.6s ease-in infinite}
.pk.two{animation-delay:.9s}.pk.three{animation-delay:1.8s}
@keyframes pk{0%{offset-distance:0;opacity:0}12%{opacity:1}85%{opacity:1}100%{offset-distance:100%;opacity:0}}
.cloud{position:absolute;top:2%;left:0;width:236px;background:var(--navy);color:var(--cream);border:1px solid rgba(27,164,182,.35);border-radius:10px;padding:12px 14px;font-size:11px;box-shadow:0 30px 60px -24px rgba(11,43,60,.5)}
.cloud .ch{display:flex;align-items:center;gap:8px;font-size:11px;letter-spacing:.12em;text-transform:uppercase;font-weight:600;padding-bottom:10px;border-bottom:1px solid rgba(27,164,182,.25)}
.cloud .ch i{width:6px;height:6px;border-radius:50%;background:#5EEBB7;margin-left:auto;box-shadow:0 0 0 3px rgba(94,235,183,.2);animation:pulse 2.2s infinite}
/* The live dot IS the pause control (WCAG 2.2.2, audit A-06). scene.js swaps the <i> above
   for <button class="ch-dot"> when it runs; with scripting off the <i> stays and nothing
   below applies, which is correct — nothing cycles without JS either.

   The button's own box is 6x6, exactly the <i>'s, so .ch's geometry, the card's height and
   the whole scene's scaling are byte-identical to before. Everything that is bigger than
   6px — the hover/paused glyph and the 24x24 pointer target — is drawn by absolutely
   positioned pseudo-elements, which take part in hit-testing but not in layout.
   .cloud is transform-scaled with the art (responsive.css §12: scale = min(1, artW/543px)),
   so a plain 24px target here would be 24 x that scale on screen — 12px on a 320px phone,
   which is where a touch target matters most. The ::after below therefore carries the
   INVERSE of that scale, written with the same tan(atan2()) ratio trick responsive.css uses
   (there is no other way to divide a length by a length in CSS), so the target measures 24
   real CSS px at every width. The plain 24px declaration comes first as the fallback for a
   browser without atan2(); there the target degrades in size only — never in layout. */
.cloud .ch .ch-dot{
  position:relative;flex:0 0 auto;margin-left:auto;
  width:6px;height:6px;padding:0;border:0;border-radius:50%;
  background:none;-webkit-appearance:none;appearance:none;
  color:#5EEBB7;cursor:pointer;touch-action:manipulation
}
/* the dot — same size, colour, halo and pulse the <i> had */
.cloud .ch .ch-dot::before{
  content:"";position:absolute;left:50%;top:50%;width:6px;height:6px;margin:-3px 0 0 -3px;
  border-radius:50%;background:currentColor;box-shadow:0 0 0 3px rgba(94,235,183,.2);
  animation:pulse 2.2s infinite;
  background-repeat:no-repeat;background-position:center;background-size:12px 12px
}
/* the pointer/touch target, centred on the dot and invisible */
.cloud .ch .ch-dot::after{
  content:"";position:absolute;left:50%;top:50%;width:24px;height:24px;
  transform:translate(-50%,-50%)
}
@supports (width:calc(1px * tan(atan2(2px,1px)))){
  .cloud .ch .ch-dot::after{
    --unscale:max(1, tan(atan2(543px, 100cqw)));
    width:calc(24px * var(--unscale));height:calc(24px * var(--unscale))
  }
}
/* hover and keyboard focus: two bars in place of the dot, same centre */
.cloud .ch .ch-dot:hover::before,
.cloud .ch .ch-dot:focus-visible::before{
  width:12px;height:12px;margin:-6px 0 0 -6px;
  background-color:transparent;box-shadow:none;animation:none;
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12'%3E%3Crect x='3' y='2.4' width='2.2' height='7.2' rx='.7' fill='%235EEBB7'/%3E%3Crect x='6.8' y='2.4' width='2.2' height='7.2' rx='.7' fill='%235EEBB7'/%3E%3C/svg%3E")
}
/* paused: a play triangle, and the pulse stops — the state is visible without hovering */
.cloud .ch .ch-dot[aria-pressed="true"]::before,
.cloud .ch .ch-dot[aria-pressed="true"]:hover::before{
  width:12px;height:12px;margin:-6px 0 0 -6px;
  background-color:transparent;box-shadow:none;animation:none;
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12'%3E%3Cpath d='M3.7 2.3 9.5 6 3.7 9.7Z' fill='%235EEBB7'/%3E%3C/svg%3E")
}
/* the 6px box would give the global ring a 10px square; push it out so it reads as a ring
   around the glyph. --focus is already mustard here (responsive.css §1, .cloud). */
.cloud .ch .ch-dot:focus-visible{outline-offset:6px;border-radius:50%}
.cloud .city{font-size:10.5px;letter-spacing:.14em;color:var(--teal);font-weight:600;padding:8px 0;border-bottom:1px solid rgba(27,164,182,.18)}
.cloud .cbody{transition:opacity .35s;padding-top:6px}.cloud .cbody.swap{opacity:0}
.cv{display:flex;justify-content:space-between;gap:10px;font-weight:600;font-size:12px;padding:4px 0 8px;white-space:nowrap}
/* .58 not .5 — cream at .5 is 4.32:1 on --navy, just under AA (04 §1.1 dark table) */
.cv span:last-child{color:rgba(245,240,229,.58);font-weight:500;font-variant-numeric:tabular-nums}
.cr{display:grid;grid-template-columns:7px minmax(0,1fr) auto;gap:8px;align-items:center;padding:5px 0;font-size:11.5px;color:rgba(245,240,229,.72)}
@keyframes rin{from{opacity:0;transform:translateX(8px)}to{opacity:1;transform:none}}
.cr i{width:7px;height:7px;border-radius:50%;background:#5EEBB7;box-shadow:0 0 6px currentColor;color:#5EEBB7}
.cr b{color:var(--cream);font-weight:600;font-variant-numeric:tabular-nums}
.cr.warn i{background:var(--mustard);color:var(--mustard)}.cr.warn b{color:var(--mustard)}
.cr.bad i{background:#FF7A7A;color:#FF7A7A}.cr.bad b{color:#FF7A7A}
.cb{margin-top:10px;padding:8px 10px;border-radius:6px;font-size:11.5px;font-weight:600;background:rgba(245,240,229,.06);border:1px solid rgba(245,240,229,.12);color:rgba(245,240,229,.8)}
.cb.yes{background:rgba(27,164,182,.14);border-color:rgba(27,164,182,.4);color:#7FE0EA}
.hello{position:absolute;right:38%;top:36%;z-index:3;background:var(--teal);color:var(--navy);font-size:12.5px;font-weight:600;padding:8px 12px;border-radius:6px;box-shadow:0 14px 30px -10px rgba(0,0,0,.5)}
/* sub-page vocab */
.ph{padding:clamp(56px,7vw,104px) 0 clamp(40px,5vw,72px)}
.ph .wrap{display:grid;grid-template-columns:minmax(0,1.2fr) minmax(0,.8fr);gap:clamp(32px,5vw,80px);align-items:end}
.ph h1{font-weight:500;font-size:clamp(46px,6.4vw,96px);line-height:.96;letter-spacing:-.04em;margin:18px 0 24px}
.ph h1 .em{color:var(--teal-deep)}
.ph .lead{margin-bottom:32px}
.ph .ctas{display:flex;gap:12px;flex-wrap:wrap;align-items:center}
.ph.dark{background:var(--navy);color:var(--cream)}
.ph.dark h1,.ph.dark .lead{color:var(--cream)}.ph.dark .lead{color:rgba(245,240,229,.72)}.ph.dark .kicker{color:rgba(245,240,229,.6)}.ph.dark .kicker b{color:var(--teal)}.ph.dark h1 .em{color:var(--teal)}
.ph.dark .btn-line{color:var(--cream);border-color:rgba(245,240,229,.3)}.ph.dark .btn-line:hover{border-color:var(--cream);color:var(--cream)}
.ph.dark .btn-navy{background:var(--cream);color:var(--navy)}
.ph.dark .arrow{color:var(--cream)}
.stats{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:0;border-top:1px solid var(--rule)}
.ph.dark .stats{border-color:rgba(245,240,229,.2)}
.stat{padding:22px 0 18px;border-bottom:1px solid var(--rule)}
.ph.dark .stat{border-color:rgba(245,240,229,.2)}
.stat:nth-child(odd){padding-right:24px;border-right:1px solid var(--rule)}.stat:nth-child(even){padding-left:24px}
.ph.dark .stat:nth-child(odd){border-right-color:rgba(245,240,229,.2)}
.stat b{display:block;font-weight:500;font-size:clamp(34px,3.4vw,48px);letter-spacing:-.04em;line-height:1;font-variant-numeric:tabular-nums}
.stat b em{font-family:var(--display);font-style:italic;color:var(--teal-deep);font-weight:400;letter-spacing:0}
.ph.dark .stat b em{color:var(--teal)}
.stat span{display:block;font-size:12.5px;color:var(--dim);margin-top:8px;letter-spacing:.06em;text-transform:uppercase;font-weight:500}
.ph.dark .stat span{color:rgba(245,240,229,.6)}
/* section-scoped: `.sec` is ALSO the class of the small print inside the phone mock's
   notification card (`.notif .sec`, styles.css), which was picking up 102px of block
   padding from this rule on the home page. Same failure mode as `.price`/`.incl`. */
section.sec{padding:clamp(72px,8vw,128px) 0}
section.sec.tint{background:var(--cream);border-block:1px solid var(--rule-soft)}
.sec .head{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1fr);gap:40px;align-items:end;margin-bottom:clamp(40px,5vw,64px)}
.sec .head .lead{justify-self:end}.sec .head h2{margin-top:14px}
.feats{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));border-top:1px solid var(--rule)}
.feat{padding:28px 32px 32px 0;border-bottom:1px solid var(--rule)}
.feat:not(:nth-child(3n)){border-right:1px solid var(--rule-soft)}
.feat:not(:nth-child(3n+1)){padding-left:32px}
.feat .num{font-family:var(--display);font-style:italic;font-size:28px;color:var(--teal-deep);margin-bottom:28px;line-height:1}
html[data-type="grotesk"] .feat .num{font-style:normal;font-weight:500}
.feat h3{margin-bottom:8px;font-size:20px}.feat p{color:var(--dim);font-size:15px}
.two{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1fr);gap:clamp(32px,6vw,96px);align-items:start}
.two h2{margin:14px 0 20px}
.timeline{border-top:1px solid var(--rule)}
.timeline div{display:grid;grid-template-columns:90px minmax(0,1fr);gap:20px;padding:18px 0;border-bottom:1px solid var(--rule)}
.timeline time{font-variant-numeric:tabular-nums;color:var(--teal-deep);font-weight:600;font-size:14px;padding-top:3px}
.timeline b{display:block;font-weight:500;font-size:18px;letter-spacing:-.015em}.timeline p{color:var(--dim);font-size:14.5px;margin-top:3px}
.logos{display:flex;gap:14px 40px;flex-wrap:wrap;align-items:center;margin-top:28px;font-size:13px;letter-spacing:.08em;text-transform:uppercase;color:var(--faint);font-weight:600}
/* lead form */
.contact{padding:clamp(80px,9vw,140px) 0;background:var(--navy);color:var(--cream)}
.contact .wrap{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1fr);gap:clamp(32px,6vw,96px);align-items:start}
.contact h2{color:var(--cream);margin:14px 0 20px}.contact .em{color:var(--teal)}
.contact .kicker{color:rgba(245,240,229,.6)}.contact .lead{color:rgba(245,240,229,.72)}
.contact .meta{margin-top:28px;font-size:14.5px;color:rgba(245,240,229,.7)}.contact .meta a{color:var(--cream);text-decoration:underline;text-underline-offset:3px}
/* A-01: --focus reset. `.contact` is navy and sets --focus:var(--mustard); this card is the
   PAPER surface inside it, so every input/select/textarea/submit in all six lead forms was
   painting a mustard ring on #FBF8F1 at 1.58:1 (3:1 required). --teal-deep is 5.23:1 there.
   Declared on the element that owns the light background — see the note on .addr. */
.lead-form{background:var(--paper);--focus:var(--teal-deep);color:var(--ink);border-radius:10px;padding:28px;display:grid;gap:14px;position:relative}
.lead-form .grid{display:grid;grid-template-columns:1fr 1fr;gap:14px}
.lead-form label{display:grid;gap:6px;font-size:12.5px;font-weight:600;color:var(--dim)}
/* A-02 — SC 1.4.11. The white fill separates the field from the paper card by only 1.06:1,
   so the border IS the field boundary, and at var(--rule) it measured 1.39:1 against the
   fill and 1.31:1 against the card. var(--rule-ui) measures 3.56 / 3.50 (see styles.css
   :root). Every state has to clear 3:1, not just the resting one. */
.lead-form input,.lead-form select,.lead-form textarea{font:inherit;font-size:15px;color:var(--ink);background:#fff;border:1px solid var(--rule-ui);border-radius:6px;height:46px;padding:0 12px;outline:0;width:100%}
.lead-form textarea{height:96px;padding:12px;resize:vertical}
.lead-form input:hover,.lead-form select:hover,.lead-form textarea:hover{border-color:rgba(11,43,60,.72)}   /* 5.6:1 on #fff */
.lead-form input:focus,.lead-form select:focus,.lead-form textarea:focus{border-color:var(--navy)}          /* 13.89:1 on #fff */
/* Invalid: :user-invalid, not :invalid — :invalid matches every empty `required` field on
   page load and would paint the whole form red before anyone has typed. The boundary must
   also not rely on colour alone (1.4.1), hence the extra weight. */
.lead-form input[aria-invalid="true"],.lead-form select[aria-invalid="true"],.lead-form textarea[aria-invalid="true"],
.lead-form input:user-invalid,.lead-form select:user-invalid,.lead-form textarea:user-invalid{
  border-color:#8E5D14;border-width:2px;padding-inline:11px      /* 4.6:1 on #fff; padding keeps the box the same size */
}
.lead-form textarea[aria-invalid="true"],.lead-form textarea:user-invalid{padding:11px}
/* Disabled controls are exempt from 1.4.11, but .lead-form.sent dims the fields to .6 while
   they are still on screen behind the success panel, which would drop the border to ~2.0:1.
   Compensate so the boundary survives the dim. */
.lead-form.sent input,.lead-form.sent select,.lead-form.sent textarea{border-color:rgba(11,43,60,.8)}
/* The shared .btn is white-space:nowrap; FR "Parler à l'équipe concessionnaires" is 283px
   and made the whole form a fixed 339px box, overflowing every viewport ≤356px
   (03 §M2, /fr/dealers). Let this one button wrap and grow instead. */
.lead-form .btn{justify-content:center;min-height:50px;height:auto;padding-block:12px;margin-top:4px;white-space:normal;text-wrap:balance;text-align:center;min-width:0}
.lead-form .fine{font-size:12px;color:var(--faint);text-align:center}
.lead-form .thanks{display:none;position:absolute;inset:0;background:var(--paper);border-radius:10px;padding:32px;text-align:center;place-content:center}
.lead-form .thanks b{display:block;font-family:var(--display);font-style:italic;font-size:34px;font-weight:400;margin-bottom:10px}
.lead-form.sent .thanks{display:grid}
/* calculator */
.calc{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1.1fr);gap:clamp(24px,4vw,56px);align-items:start}
.calc-in{display:grid;gap:34px;min-width:0}
.calc-in label{display:block;font-size:12.5px;letter-spacing:.1em;text-transform:uppercase;font-weight:600;color:var(--dim);margin-bottom:12px}
/* A-02: this border-bottom is the whole visible boundary of the calculator's number input
   (the input itself is border:0/background:transparent), so it is load-bearing, not a
   hairline — 1.31:1 on cream before, 3.43:1 now. */
.calc-field{display:flex;align-items:baseline;gap:10px;border-bottom:1px solid var(--rule-ui);padding-bottom:8px;flex-wrap:wrap}
.calc-field:focus-within{border-bottom-color:var(--navy)}
/* min-width:0 + a fluid clamp MINIMUM: a fixed 40px floor plus the number input's
   intrinsic width plus the FR unit label ("véhicules") overflowed the 280px column at
   320px (03 §H2). The input must be allowed to shrink inside the flex row. */
.calc-field input{font:inherit;font-size:clamp(28px,7vw,56px);font-weight:500;letter-spacing:-.04em;border:0;outline:0;background:transparent;width:100%;min-width:0;flex:1 1 0%;color:var(--ink);-moz-appearance:textfield}
.calc-field input::-webkit-inner-spin-button{-webkit-appearance:none}
.calc-field span{font-size:14px;color:var(--dim);white-space:nowrap;flex-shrink:0}
/* below 400px let the unit label drop to its own line instead of forcing the row wide */
@media (max-width:400px){.calc-field span{flex:1 0 100%;white-space:normal}}
/* Range input: the element box itself is the pointer target, and ::-webkit-slider-thumb
   does not enlarge it — a 2px-tall input was a 2px-tall hit area (03 §H3). Give the input
   a 44px box and paint the hairline with the track pseudo-elements instead. */
.calc input[type=range]{-webkit-appearance:none;appearance:none;accent-color:var(--navy);width:100%;height:44px;background:transparent;margin-top:6px;cursor:pointer}
/* A-02: the track is the only thing showing the slider's extent — 1.31:1 before. */
.calc input[type=range]::-webkit-slider-runnable-track{height:2px;background:var(--rule-ui);border-radius:2px}
.calc input[type=range]::-moz-range-track{height:2px;background:var(--rule-ui);border-radius:2px}
.calc input[type=range]::-webkit-slider-thumb{-webkit-appearance:none;width:20px;height:20px;margin-top:-9px;border-radius:50%;background:var(--navy);border:3px solid var(--paper);box-shadow:0 0 0 1px var(--rule-ui)}
.calc input[type=range]::-moz-range-thumb{width:16px;height:16px;border-radius:50%;background:var(--navy);border:0}
.presets{display:flex;gap:8px;flex-wrap:wrap;margin-top:14px}
.presets button{font:inherit;font-size:12.5px;font-weight:600;color:var(--dim);background:transparent;border:1px solid var(--rule);border-radius:5px;padding:6px 12px;cursor:pointer}
.presets button:hover,.presets button.on{border-color:var(--ink);color:var(--ink)}
.calc-out{border-top:2px solid var(--price-accent);padding-top:22px;min-width:0}
/* clamp minimum made fluid + anywhere-wrap: an 8-digit total ("$97,500,000") was 329px
   wide in a 280px column at 320px (03 §H2). */
.calc-out .total{font-weight:500;font-size:clamp(32px,9vw,104px);letter-spacing:-.05em;line-height:.95;font-variant-numeric:tabular-nums;overflow-wrap:anywhere}
.calc-out .total small{font-family:var(--display);font-style:italic;font-size:.28em;letter-spacing:0;color:var(--dim);margin-left:8px;font-weight:400}
.calc-out .sub{color:var(--dim);font-size:15px;margin-top:10px}
.lines{margin-top:28px;border-top:1px solid var(--rule)}
.lines div{display:flex;justify-content:space-between;gap:20px;padding:13px 0;border-bottom:1px solid var(--rule);font-size:15px}
/* The "High-use visits" row only exists when the fleet averages more than 4 visits a
   vehicle a year; `hidden` alone loses to the display:flex above. */
.lines div[hidden]{display:none}
.lines div span:last-child{font-variant-numeric:tabular-nums;font-weight:600}
.lines div small{display:block;color:var(--faint);font-size:12.5px;font-weight:400;margin-top:2px}
.lines .hi{font-size:17px}.lines .hi span:last-child{color:var(--teal-deep)}
.calc-out .fine{font-size:12.5px;color:var(--faint);margin-top:16px}
/* pricing */
.pcols{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1fr);gap:clamp(24px,4vw,64px)}
.pcol .kicker{margin-bottom:14px}
.pledger{border-top:1px solid var(--rule)}
.pledger div{display:flex;justify-content:space-between;gap:16px;padding:14px 0;border-bottom:1px solid var(--rule);font-size:16px}
/* Only the SHORT right-hand value stays nowrap. The label used to be nowrap too, which
   over-constrained the row: FR "Inspection des pneus — sculpture, pression, âge" next to
   "CHAQUE VISITE" blew past the viewport at 562–614px and 901–1066px (03 §H1). */
.pledger div span:last-child{color:var(--dim);font-size:13px;letter-spacing:.06em;text-transform:uppercase;font-weight:500;white-space:nowrap;padding-top:3px;flex-shrink:0}
.pledger div b{font-weight:600;min-width:0;overflow-wrap:anywhere}
.compare{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));border-top:1px solid var(--rule)}
.compare>div{padding:28px 32px 32px 0;border-bottom:1px solid var(--rule)}
.compare>div:not(:last-child){border-right:1px solid var(--rule-soft)}.compare>div:not(:first-child){padding-left:32px}
.compare .pn{font-weight:500;font-size:clamp(40px,4.4vw,64px);letter-spacing:-.045em;line-height:1;margin:14px 0 6px}
.compare .pn small{font-family:var(--display);font-style:italic;font-size:.32em;color:var(--dim);letter-spacing:0;font-weight:400;margin-left:4px}
.compare .pn.plan{color:var(--teal-deep)}
.compare p{color:var(--dim);font-size:15px;margin-top:10px}
.compare ul{list-style:none;margin-top:18px;display:grid;gap:8px;font-size:14.5px}
.compare li{padding-left:18px;position:relative}.compare li::before{content:'—';position:absolute;left:0;color:var(--teal-deep)}
.metrics{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));border-top:1px solid var(--rule)}
.metrics>div{padding:26px 24px 28px 0;border-bottom:1px solid var(--rule)}
.metrics>div:not(:last-child){border-right:1px solid var(--rule-soft)}.metrics>div:not(:first-child){padding-left:24px}
.metrics b{display:block;font-weight:500;font-size:clamp(36px,3.6vw,56px);letter-spacing:-.045em;line-height:1;font-variant-numeric:tabular-nums}
.metrics b em{font-family:var(--display);font-style:italic;font-weight:400;color:var(--teal-deep);letter-spacing:0}
.metrics span{display:block;font-size:12.5px;letter-spacing:.06em;text-transform:uppercase;color:var(--dim);font-weight:500;margin:10px 0 8px}
.metrics p{font-size:14px;color:var(--dim)}
.thesis{display:grid;gap:0;border-top:1px solid var(--rule)}
.thesis div{display:grid;grid-template-columns:minmax(0,.9fr) minmax(0,1.6fr);gap:32px;padding:28px 0;border-bottom:1px solid var(--rule)}
.thesis h3{font-size:24px}.thesis p{color:var(--dim);font-size:16px;max-width:62ch}
.disclaimer{font-size:12.5px;color:var(--faint);max-width:80ch;margin-top:28px}
@media (max-width:1100px){.feats{grid-template-columns:repeat(2,minmax(0,1fr))}.feat{padding-left:0!important;padding-right:24px;border-right:0!important}.feat:nth-child(odd){border-right:1px solid var(--rule-soft)!important}.feat:nth-child(even){padding-left:24px!important;padding-right:0}.metrics{grid-template-columns:repeat(2,minmax(0,1fr))}.metrics>div{padding-left:0!important;border-right:0!important}.metrics>div:nth-child(odd){border-right:1px solid var(--rule-soft)!important;padding-right:24px}.metrics>div:nth-child(even){padding-left:24px!important}}
@media (max-width:900px){.ph .wrap,.sec .head,.two,.contact .wrap,.calc,.pcols{grid-template-columns:1fr}.sec .head .lead{justify-self:start}.compare{grid-template-columns:1fr}.compare>div{padding-left:0!important;border-right:0!important}.thesis div{grid-template-columns:1fr;gap:10px}.lead-form .grid{grid-template-columns:1fr}.hero-art .live{font-size:11px}}
@media (max-width:640px){.feats{grid-template-columns:1fr}.feat{padding-left:0!important;padding-right:0!important;border-right:0!important}.metrics{grid-template-columns:1fr}.metrics>div{padding:20px 0!important;border-right:0!important}.timeline div{grid-template-columns:1fr;gap:4px}}
/* ---- requests from the other two fixers (docs/stress/fix-requests.md) ---- */
/* R-CSS-1 — footer "Privacy settings" button (Law 25 consent re-opener). Must read as a
   plain footer link inside the "© … · email · phone · Privacy settings" run. */
.linklike{font:inherit;font-size:inherit;color:inherit;background:none;border:0;padding:0;
  margin:0;cursor:pointer;text-decoration:none;line-height:inherit;min-height:24px}
.linklike:hover{color:var(--ink);text-decoration:underline;text-underline-offset:3px}
.linklike:focus-visible{text-decoration:underline;text-underline-offset:3px}
/* R-JS-1 — Escape must visually close the "For business" panel even though focus returns to
   the trigger inside .nav-dd (which :focus-within would otherwise keep open). */
.nav-dd[data-dismissed] .nav-menu{opacity:0;transform:translateY(-6px);pointer-events:none}
/* R-JS-2 — cap the address suggestion list so it can never run past the fold; addr.js keeps
   the scroll-into-view behaviour and can drop its inline max-height now. */
.addr-list{max-height:min(46vh,340px);overflow-y:auto;overscroll-behavior:contain}
/* R-JS-3 — the success panel now takes focus */
.lead-form .thanks:focus-visible{outline:2px solid var(--focus,var(--teal-deep));outline-offset:-4px;border-radius:10px}
.lead-form.sent input,.lead-form.sent select,.lead-form.sent textarea,.lead-form.sent .btn{opacity:.6}
/* R-CSS-4 — the Custom preset. (The inline "email me this estimate" form that used to live
   here was removed: the owner's design sends the estimate with the main fleet lead form
   instead, through the hidden fields + .est-attach box below.) */
#presets #customBtn[aria-pressed="true"],#presets #customBtn.on,
#presets [data-custom][aria-pressed="true"],#presets [data-custom].on{border-color:var(--ink);color:var(--ink)}

/* Fleet lead form — "Attached to your request", kept in sync by fleet-calc.js.
   The box is cream, but it sits inside the navy `.contact` section, whose `.kicker` rule is
   cream-on-navy — so the label has to be re-coloured for the light box or it is invisible
   (the prototype has this contrast bug; it is not reproduced here). */
/* --focus reset (A-01): cream box inside the navy .contact section. No focusable child
   today, but the box is kept in sync by fleet-calc.js and is the obvious place for a
   "remove this estimate" control to land later — the ring must already be right. */
.est-attach{display:flex;flex-direction:column;gap:4px;padding:14px 16px;border:1px solid var(--rule);border-radius:10px;background:var(--cream);--focus:var(--teal-deep);margin:6px 0 4px;color:var(--ink)}
.est-attach b{font-weight:600;font-size:15px}
.contact .est-attach .kicker{color:var(--dim)}
/* breadcrumbs — used on every non-home page (moved from seo.css, which only SEO pages load) */
.crumbs{border-bottom:1px solid var(--rule-soft);font-size:13px;color:var(--dim)}
.crumbs ol{list-style:none;display:flex;flex-wrap:wrap;gap:6px 10px;padding:12px 0}
.crumbs li+li::before{content:'/';color:var(--faint);margin-right:10px}
.crumbs a{color:var(--dim)}.crumbs a:hover{color:var(--ink)}.crumbs span{color:var(--ink);font-weight:500}
