/* restore-extras.css - repairs applied to cabinet-medical-issylesmoulineaux.com, 2026-08-19.
   Loaded last so it wins on equal specificity. Every block below states the defect it closes;
   nothing here changes the site's design language, only the places where it was unusable. */

/* ---------------------------------------------------------------------------
   A. HORIZONTAL SCROLL AT 1440.
   The site ships two desktop layouts of its own: a 1200px one behind
   @media (min-width:1280px) using header.png, and a 1600px one behind
   @media (min-width:1400px) using header1600.png. A 1440px screen therefore got the
   1600px layout and scrolled sideways by 160px - on the ORIGINAL site too. The
   breakpoint is moved to 1620px in the source stylesheets so that 1400-1619 gets the
   site's OWN 1200px layout instead of a clipped 1600px one. Nothing is invented: both
   layouts are the site's. What is left here is the belt-and-braces cap.
   --------------------------------------------------------------------------- */
.sur-header,
.entete,
header.carousel,
.container.option-container {
  max-width: 100%;
}

/* ---------------------------------------------------------------------------
   B. HORIZONTAL SCROLL AT 390.
   .option-navheader carries margin-left:120px !important at every width, so on a
   390px phone the burger sat at x=120..405 and pushed the document to 405px. The
   original masked it with body{overflow-x:hidden} at <=750px, which hides the
   symptom and still measures as sideways scroll.
   Two of the five stylesheets load from the BODY on the 26 section pages, so being last in
   the head is not enough to win: the selectors below are deliberately heavier than the ones
   they override rather than relying on source order.
   --------------------------------------------------------------------------- */
@media screen and (max-width: 991px) {
  /* Two separate causes, both measured. (1) the site's own margin-left:120px !important, which
     put the burger at x=120..405. (2) Bootstrap's .navbar-header{margin:0 -15px}, which is meant
     to cancel .container's 15px padding - but this site overrides .option-container to padding:0,
     so the negative margin has nothing to cancel and widens the div to 405 all by itself. Fixing
     only (1) left the document at exactly 405 again. */
  nav.navbar .navbar-header.option-navheader,
  nav.navbar .navbar-collapse.marge-menu {
    margin-left: 0 !important; margin-right: 0 !important;
  }
  body .marge-services { margin-left: 0 !important; }
  body .marge-contact-home { margin-left: 0 !important; }
  body .marge-droite { margin-left: 0 !important; margin-right: 0 !important; }
  nav.navbar .logo { margin-left: 10px !important; }
  body .icones { margin-left: 0 !important; height: auto !important; }
  body .monwrappercontact,
  body .monwrapper,
  body .wrapperinfo { max-width: 100%; margin-left: 0 !important; margin-right: 0 !important; }
  body .ribbon-wrapper-blue { display: none; }
}
/* Everything on this site is content-box, so a padding rule ADDS width. The phone fix is a hard
   cap on the two containers instead, measured after the first attempt shipped 402px in 390.
   html{overflow-x:hidden} is deliberately NOT used: it would clip the symptom and make
   documentElement.scrollWidth report 390 while elements still stuck out to 405, i.e. it would
   make the legibility gate pass while measuring nothing. */
@media screen and (max-width: 767px) {
  body .container, body .contenu, body .row { max-width: 100% !important; margin-left: 0 !important;
    margin-right: 0 !important; }
  body img, body iframe, body table { max-width: 100%; }
  /* Editor-set inline geometry: /centre-laser/ ships <img style="float:left;height:550px;
     margin-left:40px">, which max-width alone cannot contain - the margin pushed the document to
     415px in a 390px viewport. Height, float and side margins all have to go on a phone. */
  body .container img, body .contenu img, body p img {
    height: auto !important; float: none !important;
    margin-left: 0 !important; margin-right: 0 !important; }
  /* The two Tarifs tables and the prosthesis comparison table are genuinely wider than a phone -
     615px and 715px measured - and squeezing a price list into 390px makes it unreadable. They
     scroll inside their own box instead, which is the one place sideways scrolling is correct. */
  body table { display: block; width: 100%; max-width: 100%; overflow-x: auto; }
}

/* ---------------------------------------------------------------------------
   C. TEXT ON THE BRAND BLUE.
   White on #428bca is 3.63:1 - under the 4.5:1 floor, and it is the colour of every
   call to action on the site ("Prendre Rendez Vous", "Prendre Rendez-vous en ligne",
   the breadcrumb bar). #337ab7 is Bootstrap 3's own darker brand blue and measures
   4.56:1 against white, so the design reads the same and the text is legible.
   --------------------------------------------------------------------------- */
.btn-primary,
.breadcrumb-color,
.btn-primary:focus,
.btn-primary.focus { background-color: #337ab7; border-color: #2e6da4; color: #fff; }
.btn-primary:hover,
.btn-primary:active,
.btn-primary.active { background-color: #286090; border-color: #204d74; color: #fff; }
.text-primary { color: #337ab7; }

/* The same #428bca / #4c80ae used as TEXT measures 3.16-3.63:1 on the light grounds this site
   paints, and it is the colour of the telephone number, the opening hours, every sub-heading in a
   treatment page and the woven link. #2f6ea5 measures 5.38:1 on white and 5.0:1 on the #eaf0f3
   strip, and is close enough to the original that the design is unchanged. */
.bleu,
.breadcrumb-list,
.text-urgence,
.contacteznous,
.telephone,
.telephone a,
.media-body a,
.media-body h3,
.urgencesText a,
.big_texte,
.contenu h2,
.contenu h3,
.contenu h4,
.contenu strong span,
.page-header,
p a, li a, td a { color: #2f6ea5; }
/* MEASURED REGRESSION, caught by re-running the gate rather than by looking: the rule above is
   `p a`, and "Prendre Rendez-vous en ligne" is <p><a class="btn btn-primary">. It repainted the
   button's white label the same blue as the button - 1.18:1, i.e. invisible - on every page. */
p a.btn, li a.btn, td a.btn, a.btn, a.btn-primary,
p a.button, .urgencesText a.btn, .urgencesText a.button { color: #fff; }
.breadcrumb-list .breadcrumb-current { color: #333; }
.sur-header .text-urgence,
.sur-header .contacteznous,
.sur-header .telephone a { color: #2a5f90; }

/* Probed, not guessed: the sub-headings inside treatment copy are <strong>/<u>, painted #428bca
   by the theme, and the footer's column headings are #4569d2 on #3e3e3e - 2.14:1, the worst
   number on the site. */
body p strong, body p u, body li strong, body li u,
body td strong, body th strong, body td u,
body p em, body li em, body p i:not([class*="fa"]),
body h5 strong, body h6 strong,
body .page-actions strong { color: #2f6ea5; }
footer h4, footer .list1 h4 { color: #9dc7ea; }

/* The footer's grey-on-charcoal list was 3.4:1 against #333. */
footer .gris,
footer .lien-liste,
p.gris,
.lien-aleph { color: #d9dde1 !important; }

/* ---------------------------------------------------------------------------
   D. TYPE TOO SMALL TO READ, CONTROLS TOO SMALL TO HIT.
   The breadcrumb strip was 11px. Every menu item in the section sub-menus and the
   breadcrumb was under 24px tall, i.e. under the finger-target floor.
   --------------------------------------------------------------------------- */
/* 12px is the floor, and the CHILDREN carry their own size: setting it on .breadcrumb-list alone
   left .breadcrumb-current and .chevron at 11px, which is what the gate measured. */
.breadcrumb-list,
.breadcrumb-list *,
.post-meta,
.post-meta *,
.osm-credit,
.osm-credit * { font-size: 12px; }

/* Standalone links that are the whole of their paragraph, their cell or their figure are tap
   targets, not prose, and every one of them measured 15-18px tall. Probed one by one rather than
   guessed: the four homepage service tiles (an <a> wrapping an <img>, collapsed to line-height),
   the hours/telephone block, the "Prendre RDV" line, the footer's social badges and its logo. */
.item-hover .img a,
footer figure a,
footer .box_inner > div > a { display: inline-block; line-height: 0; }
/* /contact/ lists the telephone, the fax and the address as one short <p> each, so the anchor is
   nearly the whole paragraph and counts as a control rather than prose - at 18px tall. */
p > a[href^="tel:"],
p > a[href^="mailto:"],
.media-body p a,
.urgencesText p a,
.urgencesText > div > a,
.list1 a,
.o5-legal ul li a,
.section-index li a,
footer .lien-liste { display: inline-block; min-height: 28px; line-height: 28px; }

/* The section sub-menu that sits on the banner: 3.4:1 links on a near-white panel. Heavier
   selectors than the first attempt, which style.css out-specified and the gate caught unchanged. */
body .sub-menu li a,
body .menuBottom li a,
body ul.sub-menu li.menu-item a { color: #2f6ea5; }
body h4 strong,
body .attorney-short-bio h4 strong,
body .panel-heading a,
body .panel-title a { color: #2f6ea5; }
/* Bootstrap accordion headers on the practitioner pages: an <a> 20px tall inside <h4>. */
body .panel-heading a,
body .panel-title a { display: inline-block; min-height: 28px; line-height: 28px; }

.breadcrumb-list a,
.breadcrumb-list .breadcrumb-current,
.sub-menu.menuBottom a,
.menu-item a,
.list-social-icons a,
footer .lien-liste,
.option-liens-noir,
.flex-direction-nav a { display: inline-block; min-height: 28px; line-height: 28px; }

.sur-header a,
.sur-header .telephone a { min-height: 28px; line-height: 28px; display: inline-block; }

/* ---------------------------------------------------------------------------
   E. THE MAP WE HOST INSTEAD OF THE GOOGLE IFRAME, AND ITS ATTRIBUTION.
   ODbL wants the credit visible, and the legibility gate wants it >= 12px, so it is
   ordinary page text under the picture rather than four pixels burned into a 200px
   raster.
   --------------------------------------------------------------------------- */
.carte-cmi { max-width: 100%; height: auto; display: block; margin: 0 auto; }
.carte-cmi-large { width: 100%; max-height: 400px; object-fit: cover; object-position: center; }
.osm-credit { margin: 4px 0 8px; text-align: center; color: #444; }
.osm-credit a { color: #2f6ea5; text-decoration: underline; }

/* ---------------------------------------------------------------------------
   F. VIDEO THAT LOADS ONLY WHEN THE VISITOR ASKS FOR IT.
   --------------------------------------------------------------------------- */
.video-embed { position: relative; max-width: 854px; margin: 1em auto; padding: 24px;
  background: #eef2f6 url('/img/logo-4fb1e561.png') center 12px / 120px auto no-repeat;
  border: 1px solid #cfd8e0; text-align: center; }
.video-embed-play { display: inline-block; margin-top: 84px; padding: 10px 22px; border: 0;
  border-radius: 3px; background: #337ab7; color: #fff; font-size: 16px; cursor: pointer;
  min-height: 44px; }
.video-embed-play:hover { background: #286090; }
.video-embed-note { display: block; margin-top: 8px; font-size: 12px; color: #444; }
.video-embed iframe { width: 100%; aspect-ratio: 16 / 9; height: auto; border: 0; }
.video-indisponible { padding: 12px; background: #f1f3f5; border-left: 3px solid #9fb3c8;
  color: #333; font-size: 14px; }

/* ---------------------------------------------------------------------------
   G. THE TWO FORMS THE ORIGINAL SITE SHIPPED WITH EVERY FIELD DISABLED.
   --------------------------------------------------------------------------- */
.contact-route { margin: 8px 0 12px; }
.contact-route p { margin: 0 0 6px; }
.contact-route a { font-size: 17px; color: #2f6ea5; display: inline-block; min-height: 28px;
  line-height: 28px; }

/* ---------------------------------------------------------------------------
   H. THE ONE-SLIDE "SLIDER".
   Each section page carries a single banner image inside a FlexSlider that the capture
   froze mid-initialisation: inline min-width:1600px, position:absolute, and a prev/next
   pair already carrying .flex-disabled. Two dead arrows over one picture is the frozen
   widget on the client's list, so the markup is unwrapped to a plain banner (see
   o5_cmi_banner.py) and this makes it behave like a picture.
   --------------------------------------------------------------------------- */
.page-banner { width: 100%; height: 317px; overflow: hidden;
  background-repeat: no-repeat; background-position: left top; }

/* The section-menu panel is #element{position:absolute; width:100%; left:120px} with no
   positioned ancestor, so it sizes itself against the VIEWPORT: 1440 wide starting at x=120,
   right edge 1560, i.e. 120px of sideways scroll on every one of the 26 section pages at 1440.
   The same arithmetic overflows at any width where the container is narrower than the viewport,
   which is why it was there on the original too. Giving .menupagetype position:relative makes
   width:100% mean "the container", which is what it was written to mean; top:0 then lands the
   panel exactly on the banner, the way it already does at the site's own widest breakpoint
   (measured: banner top 315 = panel top 315 at 1700px; 275 vs 235 at 1440 before this rule). */
@media screen and (min-width: 1300px) {
  body .menupagetype { position: relative; }
  body #element { left: 0 !important; width: 100% !important; top: 0 !important; }
}
/* Below 1300 the site hides the banner and the panel with visibility:hidden, which leaves a
   317px blank band above the content on every tablet - an empty placeholder block by any
   reading. display:none removes the band instead of merely blanking it. */
@media screen and (max-width: 1299px) {
  body .menupagetype { display: none !important; }
}

/* ---------------------------------------------------------------------------
   I. AUTHORED SECTION PAGES (see o5_cmi_content.py).
   --------------------------------------------------------------------------- */
.page-intro { font-size: 16px; line-height: 1.6; }
.page-intro p { margin-bottom: 12px; }
.section-index { list-style: none; padding-left: 0; margin: 14px 0 20px; }
.section-index li { margin: 0 0 6px; }
.section-index a { display: inline-block; min-height: 28px; line-height: 28px; font-size: 15px;
  color: #2f6ea5; }
.page-actions { margin: 18px 0 26px; padding: 14px; background: #eef2f6;
  border: 1px solid #d6dee6; }
.page-actions p { margin: 0 0 6px; }
.page-actions a { color: #2f6ea5; display: inline-block; min-height: 28px; line-height: 28px; }

/* The section banner is a 1600px-wide decorative band cropped by overflow:hidden; on a phone it
   is 4x the viewport. Scaling it instead of cropping keeps the band readable and keeps the
   document 390px wide. */
@media screen and (max-width: 767px) {
  body .page-banner { height: 0; padding-bottom: 19.8%; background-size: contain; }
}

/* ---------------------------------------------------------------------------
   J. SMOOTH SCROLLING WITHOUT THE BROKEN PLUGIN.
   The archived jquery.smooth-scroll.js never assigns $.fn.smoothScroll, so the site's own
   $('.nav ul a').smoothScroll() threw on every page load. The in-page anchors (/#lecentre) work
   without it; this restores the easing the site was reaching for, in CSS.
   --------------------------------------------------------------------------- */
html { scroll-behavior: smooth; }
@media (prefers-reduced-motion: reduce) { html { scroll-behavior: auto; } }

/* ---------------------------------------------------------------------------
   K. THE ROUND "RDV" BADGE, FOUND BY LOOKING AND NOT BY A GATE.
   <a class="button button-circle button-primary"><strong>RDV</strong></a> renders as a 100px
   blue disc. The anchor's own colour is white, but a `strong` rule in the theme repaints the
   label #428bca - blue on blue, contrast 1:1 - so the disc is a blank circle in the middle of
   the homepage. Measured: strong computed colour rgb(66,139,202) on background rgb(66,139,202).
   qa_legibility did not report it; the screenshot did.
   --------------------------------------------------------------------------- */
.button-primary,
.button-primary-flat { background-color: #337ab7; border-color: #2e6da4; }
a.button strong,
.button-circle strong,
.button-primary strong { color: #fff; }
.button-circle { line-height: 100px; text-align: center; font-weight: 700; }

/* ---------------------------------------------------------------------------
   L. THE TWO SIDEBAR BOXES WERE SIZED FOR THINGS THAT ARE NO LONGER IN THEM.
   .monwrappercontact is height:470px and .monwrapper height:450px, fixed, because one held a
   four-field form and the other a Google Maps iframe plus its chrome. The form was disabled by
   the original site and is now a two-line contact route, and the map is a picture with a credit
   line, so both boxes rendered with 250px of empty white under their content.
   --------------------------------------------------------------------------- */
.monwrappercontact,
.monwrapper { height: auto !important; min-height: 0; padding-bottom: 24px; }

/* ---------------------------------------------------------------------------
   M. ON A PHONE THE SIDEBAR WAS INVISIBLE BUT STILL TOOK UP THE ROOM.
   style.css hides .monwrappercontact and .wrapperinfo with visibility:hidden below 750px. That
   left ~500px of blank white between the last paragraph and the footer on every treatment page -
   and it hid the two things a phone visitor most needs, the telephone/e-mail block and the map.
   The original had reason to hide them: the box held a form whose every field it had disabled.
   It now holds a working contact route, so it is shown.
   --------------------------------------------------------------------------- */
@media screen and (max-width: 991px) {
  body .monwrappercontact,
  body .monwrapper,
  body .wrapperinfo,
  body .wrapperinfo .marge-droite { visibility: visible !important; height: auto !important; }
  body .monwrappercontact,
  body .monwrapper { padding-left: 12px; padding-right: 12px; margin: 16px 0 !important; }
}

/* ---------------------------------------------------------------------------
   N. THE FOUR HOMEPAGE SERVICE CARDS OVERLAPPED EACH OTHER ON A PHONE.
   Measured at 390: .row-2 is width:15% = 56px, but the .item-hover circle inside it is a fixed
   150px, so each card spilled 94px over the .marow-3 text block beside it and the second row of
   photographs sat on top of "Spécialité Médicales" and "Ophtalmologie". The grid was written for
   a 1200-1600px row of six inline-blocks; below 992 it has to stack.
   --------------------------------------------------------------------------- */
@media screen and (max-width: 991px) {
  /* Second measurement, after stacking made it WORSE: .marow is height:370px, .cadre 740px and
     #icones 850px, all fixed. Once the children stack they run to ~1040px inside a 370px box, so
     the second row started 230px above the end of the first and the photographs landed on top of
     the headings. Every one of those heights has to become auto, not just the outermost. */
  body #icones,
  body #icones .cadre,
  body #icones .marow { height: auto !important; }
  body #icones .marow { text-align: center; }
  body #icones .row-2,
  body #icones .row-3,
  body #icones .marow-3 {
    display: block; width: 100% !important; max-width: 320px;
    height: auto !important; margin: 0 auto 18px !important; text-align: center;
  }
  body #icones .item-hover { margin: 0 auto; }
  body #icones .masque_services { visibility: visible !important; }
  body #icones .mini_texte { visibility: hidden; height: 0; overflow: hidden; }
}

/* ---------------------------------------------------------------------------
   O. TWO CONTROLS A SIBLING WAS SITTING ON.
   qa_legibility now hit-tests each control down its centre line instead of trusting its box, and
   it found two places where the box was big enough but the finger would land on something else:

   1. The section sub-menu's last row. <aside class="post-meta"> ("Contactez nous au 01 84 19 23
      00") is painted over the bottom 4px of "La toxine botulique" - elementFromPoint returns
      ASIDE for dy=24 and dy=26. The menu gets a stacking context of its own and the aside is
      pushed clear.
   2. /404.html's list of principal pages: twelve 28px rows in one column ran the page past the
      fold. Two columns is the ordinary layout for a link list of that length, halves the block
      and keeps every row inside the measured viewport.
   --------------------------------------------------------------------------- */
.menupagetype nav .sub-menu { position: relative; z-index: 2; }
.menupagetype .post-meta { position: relative; z-index: 1; margin-top: 10px; }

.o5-legal > ul { columns: 2; column-gap: 32px; margin: 8px 0 16px; }
.o5-legal > ul li { break-inside: avoid; }
@media screen and (max-width: 560px) { .o5-legal > ul { columns: 1; } }

/* The "Horaires" corner ribbon on the sidebar box: 3.32:1. */
.ribbon-blue { background: #337ab7 !important; color: #fff !important; }
.ribbon-blue a { color: #fff !important; }

/* ---------------------------------------------------------------------------
   P. AN EDITOR-INDENTED ELEMENT PUSHES ITS CONTENT OFF A PHONE.
   /centre-laser/'s price leaflet is <p style="margin-left:160px"><img style="width:490px">. The
   img-only reset in block B (line ~64) strips margin/float/height set ON THE IMG itself, but here
   the CKEditor "indent" margin sits on the WRAPPING <p>, one level up, so that reset never reaches
   it: at 390 the paragraph's own 160px margin shoves the already-shrunk image right and only about
   half of it is on screen - unreadable, on the one page that exists to give prices. The same
   author habit (CKEditor's indent button, always a multiple of 40px, or a value pasted straight
   from Word as pt/cm) wraps images the same way on /cryolipolyse/ (two result photos,
   margin-left:40px) and /la-toxine-botulique/ (two product/procedure photos, margin-left:120px
   and 200px) and /les-volumes-du-visage/ (one photo, margin-left:120px).

   ROUND 2 (this edit): the first version of this rule matched only <p>. It missed the identical
   habit applied to a SELECTION instead of a single paragraph: CKEditor's indent button also
   indents a highlighted <ul>. /peeling/ ships six <ul class="pucev" style="margin-left:
   320px|80px|40px"> checkmark lists - measured 95px of real horizontal document overflow at 390,
   a three-item list clipped off the right edge. /tarifs_esthetique/ ships two
   <ul style="margin-left:40px"> - measured 36px of overflow at 390. Sweeping the rest of the site
   (grep for inline margin-left/padding-left across all 110 pages) turned up one more carrier of
   the same pattern that nobody had measured yet: /acide-hyaluronique/'s
   <ul style="margin-left:160px"> (its 7 <li class="pucev"> children each ALSO carry
   margin-left:2em from the site's own stylesheet, compounding on top of the inline value) - same
   author habit, same risk class, closed by the same rule.

   Nothing about the defect is "the value is a multiple of 40" or "the tag is <p>" - the actual
   author habit is "CKEditor indented whatever was selected, landing the margin on whatever tag
   wrapped it". A tag-specific selector will always miss the next tag. The fix below matches the
   STYLE ATTRIBUTE, not an element name, so it doesn't matter what CKEditor wrapped: any element
   carrying inline margin-left or padding-left loses it on a phone.
   The same sweep found exactly two other carriers, both template fragments identical on every one
   of the 110 pages, neither ever paired with a fixed width: the footer social-icon
   <div style="margin-left:50px"> and the sidebar hours <p style="padding-left:20px"> (x2). Being
   auto-width blocks with no accompanying width, the indent alone was never enough to overflow a
   container that itself auto-shrinks - unlike margin-left/padding-left stacked with a fixed width,
   which is why images get their own separate, value-independent max-width:100% cap in block B and
   are intentionally not part of this rule. They get reset to 0 anyway: a substring match can't
   distinguish "safe 50px" from "unsafe 320px" and doesn't need to, since removing an indent that
   was never load-bearing costs nothing on a phone.
   Substring attribute match, not a fixed value or a fixed tag, because both the indent step and
   the wrapping element vary page to page. */
@media screen and (max-width: 767px) {
  body [style*="margin-left"] { margin-left: 0 !important; }
  body [style*="padding-left"] { padding-left: 0 !important; }
}

/* ---------------------------------------------------------------------------
   Q. A RUN OF &nbsp; USED AS MANUAL TAB-SPACING BETWEEN A LABEL AND A PRICE.
   /tarifs_esthetique/'s price list is plain text with no table: the author lined up each
   price by typing dozens of consecutive &nbsp; between the label and the figure, e.g.
   <p style="margin-left:70.8pt">1 s&eacute;ance&nbsp;(x51)&nbsp;<strong>250&euro;</strong></p>.
   &nbsp; forbids a line break at that position (Unicode line-breaking class GL - glue), and
   consecutive &nbsp; entities have no break opportunity BETWEEN them either, so a run of N of
   them is one atomic, unbreakable token roughly N space-widths wide. At 390 that token alone
   is wider than the viewport - measured 36px of real horizontal document overflow - and no
   margin/padding rule can shrink it, because this is CONTENT width, not an indent (Block P,
   above, already zeroes the two <ul style="margin-left:40px"> lists on the same page; neither
   touches this).

   Each &nbsp;-run itself (nothing else) is wrapped server-side in <span class="tab-espace">
   (see the sweep that found all 23 runs across 6 pages) so the fix cannot reach any character
   outside the run - real prose words either side are untouched by construction, not merely by
   restraint.

   word-break:break-all was tried first and REJECTED after measuring it, not on the strength of
   its reputation: applied to the whole paragraph it broke real words mid-syllable the moment a
   line got tight ("réaction" rendered as "réacti-on", "séance" as "séanc-e" -
   screenshotted at 390 on /l_endodontie/ and /tarifs_esthetique/) because break-all makes EVERY
   character boundary breakable, not just the ones inside the &nbsp; run. Scoping break-all to
   only the inner <span> to avoid that fixed nothing - measured overflow stayed at 36px, byte for
   byte the same as before the rule existed - because the boundary immediately before the first
   &nbsp; keeps its GL (glue) restriction from the character itself; word-break on the span's own
   box does not reach across that boundary.

   overflow-wrap:break-word is the opposite kind of rule: a LAST-RESORT break, inserted only
   where a piece of content would otherwise overflow and no ordinary break point exists for it -
   it does not touch content that already fits at a normal space. Measured on an isolated copy of
   the exact failing markup and confirmed on the live page (numbers below): scoped to the same
   <span class="tab-espace">, it takes the price line to 0px overflow at 390, and a full sentence
   ending in the same kind of trailing &nbsp; run ("...physiologique." + 32 &nbsp;) renders with
   every French word intact - no last-resort break ever fires there because the sentence's normal
   spaces already give it enough break points to fit. This is the opposite of an assumption: it
   was checked against a prior claim (an earlier note here, now corrected) that overflow-wrap
   cannot break a &nbsp; run at all - that claim did not survive a second measurement.
   Scoping to .tab-espace is kept anyway (belt and braces: it costs nothing and documents intent)
   and the rule stays under the 767px breakpoint, so nothing changes above it - the two reviews
   that already signed off on the 1440 layout are untouched because the selector does not exist
   at that width.

   Rejected alternatives:
   - Replacing the &nbsp; run with a flex/table two-cell layout in the markup: correct for a
     genuine label+price pair, but several carriers of this pattern are a single long sentence
     with a trailing tab (l_endodontie, les_implants, impact-de-la-succion-du-pouce) or a
     leading tab before a sub-heading (hydrafacial, tarifs_laser), not a two-column row - a
     structural rewrite would have to special-case each shape and risks disturbing text a
     fixer was told not to touch.
   - Shortening the &nbsp; run itself in the HTML: fixes the overflow everywhere including
     1440, which is exactly the layout the two reviews already passed - out of scope for a
     phone-only defect.
   - html/body{overflow-x:hidden}: already rejected once in this file (see block B) - it hides
     the symptom and makes the gate measure 0 while content still runs off the edge.
   --------------------------------------------------------------------------- */
@media screen and (max-width: 767px) {
  body .tab-espace { overflow-wrap: break-word; }
}
