/* Exhale child theme (parent: Hummingbird) — restores the old 1.6 site's look where asked. */

/* Font: Montserrat, as on the WordPress site (www.exhale-europe.com, Divi: "Montserrat, Helvetica, Arial, Lucida,
   sans-serif"). Self-hosted (no Google Fonts request): @fontsource/montserrat 5.1.0, weights 400-700, latin + latin-ext
   (PL/HR/DA/NN/SV characters). Hummingbird's Inter is set through --bs-body-font-family; tooltips/popovers name Inter directly. */
@font-face {
  font-family: "Montserrat";
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url("../fonts/montserrat-latin-ext-400-normal.woff2") format("woff2");
  unicode-range: U+0100-02AF,U+0304,U+0308,U+0329,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF;
}
@font-face {
  font-family: "Montserrat";
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url("../fonts/montserrat-latin-400-normal.woff2") format("woff2");
  unicode-range: U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+2074,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD;
}
@font-face {
  font-family: "Montserrat";
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url("../fonts/montserrat-latin-ext-500-normal.woff2") format("woff2");
  unicode-range: U+0100-02AF,U+0304,U+0308,U+0329,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF;
}
@font-face {
  font-family: "Montserrat";
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url("../fonts/montserrat-latin-500-normal.woff2") format("woff2");
  unicode-range: U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+2074,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD;
}
@font-face {
  font-family: "Montserrat";
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: url("../fonts/montserrat-latin-ext-600-normal.woff2") format("woff2");
  unicode-range: U+0100-02AF,U+0304,U+0308,U+0329,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF;
}
@font-face {
  font-family: "Montserrat";
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: url("../fonts/montserrat-latin-600-normal.woff2") format("woff2");
  unicode-range: U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+2074,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD;
}
@font-face {
  font-family: "Montserrat";
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url("../fonts/montserrat-latin-ext-700-normal.woff2") format("woff2");
  unicode-range: U+0100-02AF,U+0304,U+0308,U+0329,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF;
}
@font-face {
  font-family: "Montserrat";
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url("../fonts/montserrat-latin-700-normal.woff2") format("woff2");
  unicode-range: U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+2074,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD;
}
:root {
  --bs-body-font-family: "Montserrat", Helvetica, Arial, Lucida, sans-serif;
}
.tooltip,
.popover {
  --bs-tooltip-font-family: "Montserrat", Helvetica, Arial, Lucida, sans-serif;
  --bs-popover-font-family: "Montserrat", Helvetica, Arial, Lucida, sans-serif;
  font-family: "Montserrat", Helvetica, Arial, Lucida, sans-serif;
}

/* Main menu: the old theme showed every top-level label in capitals. */
.ps-mainmenu__tree-link[data-depth="1"] {
  text-transform: uppercase;
}

/* Keep the uppercase menu on one line (Hummingbird lets it wrap). */
.ps-mainmenu:is(.ps-mainmenu--desktop) .ps-mainmenu__tree {
  flex-wrap: nowrap;
  gap: 0;
}
.ps-mainmenu__tree > li .ps-mainmenu__tree-link {
  white-space: nowrap;
  padding-left: .6rem;
  padding-right: .6rem;
}
/* No focus frame after a mouse click (Hummingbird outlines :focus); keyboard focus keeps it. */
.ps-mainmenu:is(.ps-mainmenu--desktop) .ps-mainmenu__tree > li .ps-mainmenu__tree-link:focus:not(:focus-visible) {
  outline: none;
}
/* Hover: an underline drawn from left to right. */
.ps-mainmenu:is(.ps-mainmenu--desktop) .ps-mainmenu__tree > li > .ps-mainmenu__tree-item-wrapper > .ps-mainmenu__tree-link {
  position: relative;
}
.ps-mainmenu:is(.ps-mainmenu--desktop) .ps-mainmenu__tree > li > .ps-mainmenu__tree-item-wrapper > .ps-mainmenu__tree-link::after {
  content: "";
  position: absolute;
  left: .6rem;
  right: .6rem;
  bottom: .35rem;
  height: 2px;
  background: currentColor;
  transform: scaleX(0);
  transform-origin: left center;
  transition: transform .25s ease-out;
}
.ps-mainmenu:is(.ps-mainmenu--desktop) .ps-mainmenu__tree > li > .ps-mainmenu__tree-item-wrapper > .ps-mainmenu__tree-link:hover::after,
.ps-mainmenu:is(.ps-mainmenu--desktop) .ps-mainmenu__tree > li > .ps-mainmenu__tree-item-wrapper > .ps-mainmenu__tree-link:focus-visible::after {
  transform: scaleX(1);
}
@media (prefers-reduced-motion: reduce) {
  .ps-mainmenu:is(.ps-mainmenu--desktop) .ps-mainmenu__tree > li > .ps-mainmenu__tree-item-wrapper > .ps-mainmenu__tree-link::after {
    transition: none;
  }
}
/* Logo + menu + search on one row from 1200px (the desktop menu breakpoint):
   the menu keeps its natural width, the search box takes what is left. */
@media (min-width: 1200px) {
  .header-bottom__row {
    flex-wrap: nowrap;
  }
  .header-bottom__row .ps-mainmenu--desktop {
    flex: 0 0 auto;
    width: auto;
  }
  #_desktop_ps_searchbar {
    flex: 1 1 auto;
    min-width: 0;
    justify-content: flex-end;
  }
  #_desktop_ps_searchbar .ps-searchbar {
    width: 100%;
    max-width: 300px;
    min-width: 0; /* Hummingbird sets 19rem, which pushes the search over the menu */
  }
}

/* Top bar: phone + email as on the old site. */
.exhale-topbar-contact a {
  color: inherit;
  text-decoration: none;
  white-space: nowrap;
}
.exhale-topbar-contact .material-icons {
  font-size: 1.1em;
  vertical-align: -0.15em;
}
/* Phone + email + "Avis clients" need ~530px; Hummingbird's col-md-4 gives 380, so the links
   overflowed under the right column, which then caught the clicks. Left takes what it needs. */
@media (min-width: 992px) {
  .header-top__left {
    flex: 0 0 auto;
    width: auto;
  }
  .header-top__right {
    flex: 1 1 0;
    width: auto;
    min-width: 0;
  }
}
/* Tablet: both don't fit on one line — contact on one row, language/account/cart on the next. */
@media (min-width: 768px) and (max-width: 991.98px) {
  .header-top__left,
  .header-top__right {
    flex: 0 0 100%;
    width: 100%;
  }
}

/* Homepage like the old site (desktop): slider at the left (779), the two banners stacked at the
   right (381), within the page width. Hummingbird's home is already a 1-column grid; we give it 2
   columns. The banners live in ps_customtext (editable per language), which is flattened with
   display:contents so its banner row can sit in column 2. Below 992px Hummingbird's stacking stays. */
/* ps_customtext holds: banners | home text | editorial + reassurance (exhale-home-after).
   Flattened so each part is a grid item of the home; "after" goes below the products, as on the old site. */
.page-content--home > .ps-customtext,
.page-content--home > .ps-customtext > .container {
  display: contents;
}
.page-content--home > .ps-customtext > .container > * {
  grid-column: 1 / -1;
}
.page-content--home > .ps-customtext > .container > .exhale-home-after {
  order: 99;
}
@media (min-width: 992px) {
  .page-content--home {
    grid-template-columns: minmax(0, 779fr) minmax(0, 381fr);
    column-gap: 1.25rem;
    max-width: 960px; /* = Bootstrap .container, so the home lines up with the header */
    margin-inline: auto;
    padding-inline: .75rem;
  }
  .page-content--home > * {
    grid-column: 1 / -1;
  }
  .page-content--home > .ps-imageslider {
    grid-column: 1;
    grid-row: 1;
    margin-top: 1rem;
  }
  .page-content--home > .ps-customtext > .container > .exhale-home-banners {
    grid-column: 2;
    grid-row: 1;
    margin: 1rem 0 0;
    display: flex;
    flex-direction: column;
    justify-content: space-between;
    gap: 1rem;
  }
  .page-content--home .exhale-home-banners > div {
    width: 100%;
    max-width: none;
    padding: 0;
    margin: 0 !important;
  }
  /* Same height as the slider: the banner column doesn't size the row (height:0) but stretches to it
     (min-height:100%); each banner takes half, images cover their box anchored at the top (titles kept). */
  .page-content--home > .ps-customtext > .container > .exhale-home-banners {
    height: 0;
    min-height: 100%;
  }
  .page-content--home .exhale-home-banners > div {
    flex: 1 1 0;
    min-height: 0;
    overflow: hidden;
  }
  .page-content--home .exhale-home-banners a,
  .page-content--home .exhale-home-banners img {
    display: block;
    height: 100%;
  }
  .page-content--home .exhale-home-banners img {
    object-fit: cover;
    object-position: top center;
  }
}
@media (min-width: 1200px) { .page-content--home { max-width: 1140px; } }
@media (min-width: 1400px) { .page-content--home { max-width: 1320px; } }
.ps-imageslider img {
  width: 100%;
  height: auto;
}
/* The slide images carry their own text; the old site showed no caption box over them.
   Not display:none: Bootstrap's .d-lg-block{display:block!important} sits in Hummingbird's
   `@layer utilities`, and a layered !important beats any unlayered !important. */
.ps-imageslider__figcaption {
  visibility: hidden;
}

/* Old-site editorial ("6 reasons…") and reassurance band (from 1.6 editorial + blockcmsinfo). */
.exhale-home-editorial__title {
  font-size: 1.75rem;
  font-weight: 400;
  color: #777;
  margin-bottom: .25rem;
}
.exhale-home-editorial__sub {
  font-size: .9rem;
  margin-bottom: 1.5rem;
}
@media (min-width: 768px) {
  }

/* Language selector with flags (template modules/ps_languageselector/ps_languageselector.tpl). */
.exhale-langselector__toggle {
  color: inherit;
  text-decoration: none;
  display: inline-flex;
  align-items: center;
  gap: .35rem;
}
/* Chevron (Bootstrap ::after): no extra margin on top of the flex gap; flips up while the menu is open. */
.exhale-langselector__toggle::after {
  margin-left: 0;
  font-size: 1.15em;
  transition: transform .15s ease-out;
}
.exhale-langselector__toggle[aria-expanded="true"]::after {
  transform: rotate(180deg);
}
.exhale-langselector .dropdown-item {
  display: flex;
  align-items: center;
  gap: .5rem;
}
.exhale-langselector__flag {
  width: 16px;
  height: 11px;
  object-fit: cover;
}

/* Thumbnails: say why a product has no quantity / add-to-cart. Red like the product page's stock
   status (text-danger #ff4657), deepened to #d61f35 so the white text passes AA (5.1:1). */
.product-miniature .product-flags .badge.out_of_stock {
  background-color: #d61f35;
  border-color: #d61f35;
  color: #fff;
  font-weight: 500;
}
/* Hummingbird keeps 4rem free on the right for a wishlist button this shop doesn't have. */
.product-miniature .product-flags {
  padding-inline-end: .5rem;
}

/* --- Polish pass 2026-10-29 ------------------------------------------------------------- */

/* Mobile/tablet: ps_customtext is flattened (display:contents), which drops its .container
   padding — give its parts the container gutter back below the 2-column breakpoint. */
@media (max-width: 991.98px) {
  .page-content--home > .ps-customtext > .container > * {
    padding-inline: .75rem;
  }
  /* The two old-site banners side by side instead of two full-screen images. */
  .page-content--home .exhale-home-banners {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: .75rem;
    margin-inline: 0;
  }
  .page-content--home .exhale-home-banners > div {
    width: auto;
    max-width: none;
    padding: 0;
    margin: 0 !important;
  }
}

/* Product page: the stock badge over the photo is cut mid-sentence; the full message is shown
   under the price, as on the old site. */
.page-product .product__images .product-flags .out_of_stock {
  display: none;
}


/* --- Minimal visual polish 2026-10-29 -----------------------------------------------------
   Brand colour: Hummingbird ships Bootstrap blue (#0b69f6). Use the logo cyan (#00b0e0),
   deepened to #0b7aa0 so text and white-on-colour buttons pass WCAG AA (4.9:1). Variables
   only: links, buttons, focus rings and pagination all follow. */
:root,
[data-bs-theme=light] {
  --bs-primary: #0b7aa0;
  --bs-primary-rgb: 11, 122, 160;
  --bs-blue: #0b7aa0;
  --bs-link-color: #0b7aa0;
  --bs-link-color-rgb: 11, 122, 160;
  --bs-link-hover-color: #08607e;
  --bs-link-hover-color-rgb: 8, 96, 126;
  --bs-focus-ring-color: rgba(11, 122, 160, .3);
  --bs-primary-text-emphasis: #053243;
  --bs-primary-bg-subtle: #d3edf5;
  --bs-primary-border-subtle: #a6d6e6;
}
.btn-primary {
  --bs-btn-bg: #0b7aa0;
  --bs-btn-border-color: #0b7aa0;
  --bs-btn-hover-bg: #08607e;
  --bs-btn-hover-border-color: #08607e;
  --bs-btn-active-bg: #075470;
  --bs-btn-active-border-color: #075470;
  --bs-btn-disabled-bg: #0b7aa0;
  --bs-btn-disabled-border-color: #0b7aa0;
  --bs-btn-focus-shadow-rgb: 11, 122, 160;
}
.btn-outline-primary {
  --bs-btn-color: #0b7aa0;
  --bs-btn-border-color: #0b7aa0;
  --bs-btn-hover-bg: #0b7aa0;
  --bs-btn-hover-border-color: #0b7aa0;
  --bs-btn-active-bg: #08607e;
  --bs-btn-active-border-color: #08607e;
  --bs-btn-focus-shadow-rgb: 11, 122, 160;
}
::selection {
  background: #c9eaf5;
  color: #0b2733;
}

/* Product cards: names in the text colour (blue only on hover), so price and name read as one unit. */
.product-miniature__title {
  color: var(--bs-body-color);
  font-weight: 500;
  text-decoration: none;
}
.product-miniature__title:hover,
.product-miniature__title:focus-visible {
  color: var(--bs-link-hover-color);
}

/* Home section titles ("Produits phares", "Meilleures ventes"): centred, more air above than below. */
.page-content--home .section-title {
  text-align: center;
  margin-top: 1rem;
  margin-bottom: 1.5rem;
}

/* Editorial "6 raisons…" block: the 4 guide links come from 1.6 content as
   <h4><button class="btn btn-default"><a>…</a></button></h4> (btn-default no longer exists). */
.exhale-home-editorial h4 {
  display: inline-block;
  margin: 0 .5rem .6rem 0;
  font-size: 1rem;
}
.exhale-home-editorial .btn-default {
  padding: 0;
  border: 1px solid var(--bs-border-color);
  border-radius: var(--bs-border-radius);
  background: transparent;
  transition: border-color .15s ease-out;
}
.exhale-home-editorial .btn-default a {
  display: block;
  padding: .5rem 1rem;
  color: var(--bs-body-color);
  text-decoration: none;
  transition: color .15s ease-out;
}
.exhale-home-editorial .btn-default:hover,
.exhale-home-editorial .btn-default:focus-within {
  border-color: var(--bs-primary);
}
.exhale-home-editorial .btn-default:hover a,
.exhale-home-editorial .btn-default a:focus-visible {
  color: var(--bs-primary);
}
.exhale-home-editorial__title {
  color: var(--bs-body-color);
  font-weight: 500;
}

/* Reassurance band: icons in the brand colour instead of grey. */

/* Footer: quieter links, brighter on hover; titles as small caps labels. */
.footer-block__title {
  text-transform: uppercase;
  letter-spacing: .04em;
  font-size: .95rem;
}
footer .footer-block a,
footer .ps-contactinfo a {
  color: #c8ccd1;
  text-decoration: none;
}
footer .footer-block a:hover,
footer .footer-block a:focus-visible,
footer .ps-contactinfo a:hover,
footer .ps-contactinfo a:focus-visible {
  color: #fff;
  text-decoration: underline;
  text-underline-offset: .2em;
}
/* "Votre compte" title is itself a link: keep it the same colour as the other footer titles. */
footer .footer-block__title a,
footer .footer-block .footer-block__title a {
  color: inherit;
  text-decoration: none;
}

/* Reassurance (delivery / assistance / payment): white, framed by hairlines, three columns
   split by thin dividers; icons as tinted brand-colour circles. Stacks below 768px. */
.exhale-home-reassurance {
  margin-top: 2.5rem;
  padding-block: 2rem;
  border-top: 1px solid var(--bs-border-color);
  border-bottom: 1px solid var(--bs-border-color);
}
.exhale-home-reassurance ul {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  gap: 1.75rem;
}
.exhale-home-reassurance li {
  display: flex;
  gap: 1rem;
  align-items: flex-start;
}
.exhale-reassurance__icon {
  flex: 0 0 3rem;
  height: 3rem;
  border-radius: 50%;
  background: var(--bs-primary-bg-subtle);
  color: var(--bs-primary);
  font-size: 1.5rem;
  display: flex;
  align-items: center;
  justify-content: center;
}
.exhale-home-reassurance h3 {
  text-wrap: balance; /* no lone "3X" on the second line */
  font-size: .95rem;
  font-weight: 600;
  letter-spacing: .02em;
  line-height: 1.35;
  margin: .2rem 0 .4rem;
}
.exhale-home-reassurance p {
  font-size: .875rem;
  line-height: 1.55;
  color: var(--bs-secondary-color);
  margin-bottom: .2rem;
}
/* 3 items (most languages) or 4 (FR: + 15-day guarantee). Phones: icon beside the text.
   From 768px: icon above the title, equal columns on one shared left edge, no dividers
   (they ran the height of the longest item and left the first column flush-left). */
@media (min-width: 768px) {
  .exhale-home-reassurance {
    padding-block: 2.25rem;
  }
  .exhale-home-reassurance ul {
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 2rem 2.5rem;
  }
  .exhale-home-reassurance li {
    flex-direction: column;
    gap: .9rem;
  }
  .exhale-home-reassurance .exhale-reassurance__icon {
    flex: none; /* in a column the 3rem flex-basis would set the height and squash the circle */
    width: 3rem;
  }
  .exhale-home-reassurance h3 {
    margin: 0 0 .4rem;
  }
  .exhale-home-reassurance p {
    max-width: 34ch;
  }
}
@media (min-width: 992px) {
  .exhale-home-reassurance ul {
    grid-template-columns: none;
    grid-auto-flow: column;
    grid-auto-columns: minmax(0, 1fr);
    gap: 2.5rem;
  }
}
/* 1.6 editorial content carries inline color:#4ed0f0 (1.8:1 on white): use the brand colour (4.9:1).
   !important is needed to beat an inline style; content left untouched. */
.exhale-home-editorial [style*="#4ed0f0"],
.exhale-home-editorial [style*="#4ED0F0"] {
  color: var(--bs-primary) !important;
}

/* Footer first column: white logo (assets/img/logo-footer-white.png, derived from the shop logo)
   with "Nous suivre" + social icons under it (child templates/_partials/footer.tpl). */
.exhale-footer-brand {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 1.25rem;
  margin-bottom: 1.5rem;
}
.exhale-footer-brand__logo img {
  display: block;
  width: 149px;
  height: auto;
}
.exhale-social__title {
  margin: 0 0 .5rem;
  font-size: .95rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: .04em;
  color: #fff;
}
.exhale-social__list {
  margin-left: -.5rem;
}
.exhale-social__list a {
  display: inline-flex;
  color: #c8ccd1;
  transition: color .15s ease-out;
}
.exhale-social__list a:hover,
.exhale-social__list a:focus-visible {
  color: #fff;
}
.exhale-social__list svg {
  width: 20px;
  height: 20px;
}
@media (max-width: 767.98px) {
  .exhale-footer-brand { align-items: center; text-align: center; }
  .exhale-social__list { margin-left: 0; justify-content: center; }
}

/* "EXHALE FANS EUROPE" concept text: intro of the editorial section, below the products. */
.exhale-home-concept {
  margin-bottom: 2rem;
}
.exhale-home-concept h3 {
  font-size: 1.25rem;
  font-weight: 600;
  margin-bottom: .75rem;
}

/* Product descriptions (1.6 content): h3/h4 used inconsistently (h4 first, h3 after, one underlined
   inline) — one calm scale: h3 = section heading, h4 = sub-heading; more space above than below. */
.product__description h3,
.product__description-short h3 {
  font-size: 1.15rem;
  font-weight: 600;
  line-height: 1.35;
  margin: 1.75rem 0 .6rem;
}
.product__description h4,
.product__description-short h4 {
  font-size: 1rem;
  font-weight: 600;
  line-height: 1.4;
  margin: 1.25rem 0 .5rem;
}
.product__description > :first-child,
.product__description hr + h3,
.product__description hr + h4 {
  margin-top: 0;
}
.product__description h3 [style*="underline"],
.product__description h4 [style*="underline"] {
  text-decoration: none !important;
}
.product__description hr {
  margin: 1.5rem 0;
  opacity: .12;
}

/* 1.6 content buttons (a.btn-default.button with inline grey box) → brand primary button. */
.rich-text a.btn-default.button {
  display: inline-flex;
  align-items: center;
  gap: .35rem;
  padding: .6rem 1.15rem !important;
  border-radius: var(--bs-border-radius);
  background: var(--bs-primary) !important;
  color: #fff !important;
  font-weight: 500;
  text-decoration: none;
  transition: background-color .15s ease-out;
}
.rich-text a.btn-default.button:hover,
.rich-text a.btn-default.button:focus-visible {
  background: var(--bs-link-hover-color) !important;
}
.rich-text a.btn-default.button span {
  background: none !important;
  border: 0 !important;
  color: inherit !important;
}
.rich-text a.btn-default.button i[class^="icon-"] {
  display: none;
}

/* Language menu: tighter rows (Hummingbird uses .75rem vertical padding per item). */
.exhale-langselector .dropdown-menu {
  --bs-dropdown-item-padding-y: .4rem;
  --bs-dropdown-item-padding-x: .85rem;
  --bs-dropdown-font-size: .95rem;
  --bs-dropdown-min-width: 0;
  padding: .3rem;
}
/* Items inset in the menu with their own rounded corners: the active background no longer pokes
   out past the menu's rounded border. */
.exhale-langselector .dropdown-item {
  border-radius: calc(var(--bs-border-radius) - 2px);
}
.exhale-langselector .dropdown-item.active,
.exhale-langselector .dropdown-item:active {
  background-color: var(--bs-primary);
  color: #fff;
}
/* Empty paragraphs left in 1.6 content add double gaps between description sections. */
.product__description p:empty,
.product__description-short p:empty {
  display: none;
}

/* Home side banners: slow zoom of the image inside its frame + soft lift on hover/focus.
   The frame clips the zoom (overflow hidden); no motion for users who ask for reduced motion. */
.page-content--home .exhale-home-banners > div {
  overflow: hidden;
  border-radius: var(--bs-border-radius);
  transition: box-shadow .35s cubic-bezier(.22, 1, .36, 1);
}
.page-content--home .exhale-home-banners img {
  transition: transform .6s cubic-bezier(.22, 1, .36, 1);
  transform-origin: top center; /* the banner title (top) stays put while the fan grows */
  will-change: transform;
}
.page-content--home .exhale-home-banners > div:hover,
.page-content--home .exhale-home-banners > div:focus-within {
  box-shadow: 0 10px 24px -12px rgba(11, 39, 51, .35);
}
.page-content--home .exhale-home-banners > div:hover img,
.page-content--home .exhale-home-banners > div:focus-within img {
  transform: scale(1.05);
}
.page-content--home .exhale-home-banners a:focus-visible {
  outline: 2px solid var(--bs-primary);
  outline-offset: -2px;
}
@media (prefers-reduced-motion: reduce) {
  .page-content--home .exhale-home-banners > div,
  .page-content--home .exhale-home-banners img {
    transition: none;
  }
  .page-content--home .exhale-home-banners > div:hover img,
  .page-content--home .exhale-home-banners > div:focus-within img {
    transform: none;
  }
}

/* Reading UX for the home concept + editorial ("6 raisons…"): same two columns as the slider/banners
   row (779fr / 381fr, same gap) so every edge lines up: main text in the left column (readable measure),
   "EXHALE FANS EUROPE" as a side panel in the right column (not sticky: it slid under the fixed header
   and over the reassurance band); reassurance band full width below.
   Below 992px everything stacks (concept first, as before). */
.exhale-home-concept,
.exhale-home-editorial {
  font-size: 1.0625rem;
  line-height: 1.7;
}
@media (min-width: 992px) {
  .page-content--home .exhale-home-after {
    display: grid;
    grid-template-columns: minmax(0, 779fr) minmax(0, 381fr);
    column-gap: 1.25rem;
    align-items: start;
  }
  /* Main text fills its column (same width as the slider above) — no extra gutter next to the panel;
     slightly larger type keeps the line length comfortable at that width. */
  .exhale-home-after > .exhale-home-editorial {
    grid-column: 1;
    grid-row: 1;
    font-size: 1.125rem;
  }
  .exhale-home-after > .exhale-home-concept {
    grid-column: 2;
    grid-row: 1;
    margin-top: 2.75rem !important;
    padding: 1.5rem;
    border-radius: var(--bs-border-radius-lg, .5rem);
    background: var(--bs-primary-bg-subtle);
    font-size: 1rem;
  }
  .exhale-home-after > .exhale-home-reassurance {
    grid-column: 1 / -1;
  }
  .exhale-home-after > .exhale-home-editorial > .exhale-home-editorial__title:first-child {
    margin-top: 2.75rem;
  }
}
.exhale-home-concept p,
.exhale-home-editorial p {
  margin-bottom: .9rem;
}
.exhale-home-concept {
  margin-top: 1.5rem;
  margin-bottom: 0;
}
.exhale-home-concept h3 {
  font-size: .95rem;
  font-weight: 600;
  letter-spacing: .06em;
  text-transform: uppercase;
  color: var(--bs-primary);
  margin-bottom: .75rem;
}
.exhale-home-editorial__title {
  font-size: clamp(1.5rem, 1.1rem + 1.4vw, 2rem);
  font-weight: 600;
  line-height: 1.2;
  text-wrap: balance;
  margin: 2.75rem 0 .5rem;
}
.exhale-home-editorial__sub {
  font-size: 1rem;
  color: var(--bs-secondary-color);
  margin-bottom: 1.75rem;
}
.exhale-home-editorial h2:not(.exhale-home-editorial__title) {
  font-size: 1.375rem;
  font-weight: 600;
  line-height: 1.3;
  margin: 2.5rem 0 1rem;
}
.exhale-home-editorial h4:first-of-type {
  margin-top: 1.5rem;
}

/* Product buy box: clear hierarchy — name (semi-bold), price (strongest element, "TTC" beside it),
   calm short description, out-of-stock heading and availability message toned into one system. */
.page-product .product__name {
  font-size: clamp(1.5rem, 1.2rem + .8vw, 1.875rem);
  font-weight: 600;
  line-height: 1.25;
  letter-spacing: -.01em;
  text-wrap: balance;
  margin-bottom: .75rem;
}
.page-product .product__prices-block {
  display: flex;
  align-items: baseline;
  flex-wrap: wrap;
  gap: .5rem;
  margin-bottom: 1.25rem;
}
.page-product .product__price {
  font-size: 1.875rem;
  font-weight: 700;
  line-height: 1.1;
}
.page-product .product__tax-label {
  font-size: .875rem;
  color: var(--bs-secondary-color);
}
.page-product .product__description-short {
  font-size: 1rem;
  line-height: 1.6;
}
.page-product .product__description-short p {
  margin-bottom: .65rem;
}
.page-product .product__description-short strong {
  font-weight: 600;
}
.page-product .product__description-short em {
  color: var(--bs-secondary-color);
}
.page-product .product__description-short h3 {
  font-size: .95rem;
  font-weight: 700;
  letter-spacing: .04em;
  text-transform: uppercase;
  margin: 1.25rem 0 .4rem;
}
.page-product .product__description-short h3 [style*="underline"] {
  text-decoration: none !important;
}

/* Availability ("Libellé si en rupture de stock", per product): a soft alert instead of large red text. */
.page-product .product__availability-status.text-danger {
  display: flex;
  align-items: flex-start;
  gap: .6rem;
  padding: .75rem 1rem;
  border-radius: var(--bs-border-radius);
  background: rgba(220, 53, 69, .07);
  color: #a61e2d !important;
  font-size: .9rem;
  line-height: 1.5;
}
.page-product .product__availability-icon {
  font-size: 1.15rem;
  margin-top: .1rem;
}
/* .text-danger lives in Hummingbird's @layer utilities (its !important wins over ours): colour the
   children instead. "TTC" beside the price: the block is a column in Hummingbird. */
.page-product .product__availability-status.text-danger > * {
  color: #a61e2d;
}
.page-product .product__prices-block {
  flex-direction: row;
}

/* Référence / État above the short description (child templates/catalog/product.tpl), like 1.6. */
.exhale-product-meta {
  display: flex;
  flex-wrap: wrap;
  gap: .25rem 1.5rem;
  margin: 0 0 1rem;
  font-size: .9rem;
  color: var(--bs-secondary-color);
}
.exhale-product-meta__label {
  font-weight: 600;
  color: var(--bs-body-color);
}
.exhale-product-meta__label::after {
  content: " :";
}

/* Product images like 1.6: main image opens the gallery on click (assets/js/custom.js), and the
   gallery opens with a zoom-in instead of Bootstrap's slide-down. Reduced motion: plain fade. */
.page-product .product__carousel .carousel-item img {
  cursor: zoom-in;
}
.product-images-modal.fade .modal-dialog {
  transform: scale(.88);
  opacity: 0;
  transition: transform .35s cubic-bezier(.22, 1, .36, 1), opacity .25s ease-out;
}
.product-images-modal.show .modal-dialog {
  transform: none;
  opacity: 1;
}
.page-product .product__thumbnail {
  transition: opacity .15s ease-out;
}
.page-product .product__thumbnail:not(.active):hover {
  opacity: .8;
}
@media (prefers-reduced-motion: reduce) {
  .product-images-modal.fade .modal-dialog {
    transform: none;
    transition: opacity .15s linear;
  }
}

/* Product page / cart reassurance (blockreassurance, child displayBlockProduct.tpl): same look as the
   homepage band — tinted brand circles with Material icons, semi-bold title, muted description. */
.blockreassurance--product .reassurance,
.blockreassurance--cart .reassurance,
.blockreassurance .reassurance {
  display: flex;
  align-items: flex-start;
  gap: 1rem;
  padding: .75rem 0;
}
.blockreassurance .reassurance + .reassurance {
  border-top: 1px solid var(--bs-border-color);
}
.blockreassurance .reassurance__image {
  flex: 0 0 auto;
  width: auto;
}
.blockreassurance .reassurance__content {
  display: flex;
  flex-direction: column;
  gap: .2rem;
}
.blockreassurance .reassurance__title {
  font-size: .9rem;
  font-weight: 600;
  letter-spacing: .02em;
  line-height: 1.35;
}
.blockreassurance .reassurance__desc {
  font-size: .85rem;
  line-height: 1.5;
  color: var(--bs-secondary-color);
}
/* Module CSS squeezes the icon box: give the circle a fixed square size. */
.blockreassurance .reassurance__image {
  display: flex;
  flex: 0 0 2.75rem;
  min-width: 2.75rem;
  margin: 0;
}
.blockreassurance .exhale-reassurance__icon {
  width: 2.75rem;
  height: 2.75rem;
  flex: 0 0 2.75rem;
  font-size: 1.35rem;
}
.blockreassurance .reassurance {
  padding: .85rem 0 !important;
  margin: 0 !important;
}
/* Hummingbird spaces items with a 1rem grid gap on top of our padding + divider: keep the divider only. */
.blockreassurance--cart,
.blockreassurance--checkout,
.blockreassurance--product {
  gap: 0;
}
.blockreassurance .reassurance {
  padding: .7rem 0 !important;
}

/* Listing "Trier par": Hummingbird stretches the dropdown over half the row; on desktop it fits
   its longest option and sits on the right. Mobile keeps the full-width button. */
@media (min-width: 992px) {
  .products__sort {
    justify-content: flex-end;
  }
  .products__sort-dropdown {
    flex-grow: 0;
    min-width: 13rem;
    position: relative; /* the open list is as wide as the button */
  }
  .products__sort-dropdown .dropdown-menu {
    width: 100%;
    --bs-dropdown-min-width: 0;
  }
  .products__sort-dropdown .dropdown-item {
    white-space: normal; /* "Date d'ajout, du plus récent au plus ancien" wraps instead of overflowing */
  }
}

/* Product cards (every listing): Hummingbird's grid is frameless and assumes photos cut out on white;
   Exhale's photos mix white and grey backgrounds. Light card + one neutral image tile: white areas of
   the photos blend into the tile (multiply), so every product sits on the same background. */
.product-miniature__inner {
  height: 100%;
  display: flex;
  flex-direction: column;
  border: 1px solid var(--bs-border-color);
  border-radius: .75rem;
  background: #fff;
  overflow: hidden;
  transition: box-shadow .25s cubic-bezier(.22, 1, .36, 1), border-color .25s ease-out;
}
.product-miniature__inner:hover,
.product-miniature__inner:focus-within {
  border-color: var(--bs-primary-border-subtle);
  box-shadow: 0 12px 28px -18px rgba(11, 39, 51, .35);
}
.product-miniature__image-container {
  background: #f3f5f6;
  border-radius: 0;
}
.product-miniature__image-link,
.product-miniature__image-link.outline--rounded {
  border-radius: 0;
}
.product-miniature__image {
  mix-blend-mode: multiply;
  border-radius: 0;
  transition: transform .5s cubic-bezier(.22, 1, .36, 1);
}
.product-miniature__inner:hover .product-miniature__image {
  transform: scale(1.03);
}
.product-miniature__bottom {
  flex: 1 1 auto;
  display: flex;
  flex-direction: column;
  padding: .9rem 1rem 1rem;
}
.product-miniature__infos {
  flex: 1 1 auto;
}
@media (prefers-reduced-motion: reduce) {
  .product-miniature__inner,
  .product-miniature__image {
    transition: none;
  }
  .product-miniature__inner:hover .product-miniature__image {
    transform: none;
  }
}

/* Cookie banner (uecookie 2.1.0). The module prints its own CSS inline (colours !important), so these
   selectors are more specific; nothing here is lost when the module is updated. Wording unchanged. */
html body #cookieNotice {
  opacity: 1;
  background: #1f2429;
  box-shadow: 0 -4px 16px rgba(0, 0, 0, .18);
  padding: 1rem 1.25rem;
  font-family: inherit;
}
html body #cookieNotice .ue-container {
  max-width: 1116px;
  margin: 0 auto;
  width: 100%;
  gap: 1.5rem;
}
html body #cookieNotice .ue-spacer {
  display: none;
}
html body #cookieNotice .ue-content {
  text-align: start;
  font-size: .875rem;
  line-height: 1.55;
  justify-content: flex-start;
}
html body #cookieNotice .ue-content,
html body #cookieNotice .ue-content * {
  color: #e9ecef !important;
}
html body #cookieNotice .ue-content a {
  color: #fff !important;
  text-decoration: underline;
  text-underline-offset: 2px;
  white-space: nowrap; /* "En savoir plus" never split over two lines */
}
html body #cookieNotice .ue-close-btn {
  background: #0b7aa0;
  border: 1px solid #0b7aa0;
  border-radius: .375rem;
  color: #fff !important;
  font-size: .875rem;
  font-weight: 600;
  line-height: 1.2;
  padding: .6rem 1.4rem;
  white-space: nowrap;
  transition: background-color .15s ease-out;
}
html body #cookieNotice .ue-close-btn::first-letter {
  text-transform: uppercase;
}
html body #cookieNotice .ue-close-btn:hover {
  opacity: 1 !important;
  background: #086584 !important; /* the module forces transparent !important on hover */
  border-color: #086584;
}
@media (max-width: 767.98px) {
  html body #cookieNotice .ue-container {
    gap: .75rem;
  }
  html body #cookieNotice .ue-actions {
    width: 100%;
    margin-top: 0;
  }
  html body #cookieNotice .ue-close-btn {
    width: 100%;
    text-align: center;
  }
}

/* 100vw (full-bleed hero) includes the vertical scrollbar: clip the few px instead of a horizontal scroll.
   clip, not hidden: no scroll container, so sticky elements keep working. */
body {
  overflow-x: clip;
}
/* Homepage hero "hybrid" (templates/index.tpl, PM choice 30/10): vortex video full width under a dark scrim
   (bottom + left, stronger on phones), sentence-case headline in white, accent in the logo cyan (readable on dark).
   Contrast measured against the brightest 10% behind the text: desktop 7.2 / 5.0, phone 4.8 / 3.5 (AA large). */
.exhale-hero {
  position: relative;
  isolation: isolate;
  overflow: hidden;
  display: flex;
  align-items: flex-end;
  min-height: min(86vh, 820px);
  margin-bottom: 1.5rem;
  color: #fff;
  background: #1d2a31 url("../img/hero/hero-vortex-poster.webp") center / cover no-repeat;
}
.exhale-hero__video {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  z-index: -2;
}
.exhale-hero__veil {
  position: absolute;
  inset: 0;
  z-index: -1;
  background:
    linear-gradient(to top, rgba(6, 18, 26, .68) 0%, rgba(6, 18, 26, .42) 42%, rgba(6, 18, 26, .06) 72%, rgba(6, 18, 26, 0) 82%),
    linear-gradient(to right, rgba(6, 18, 26, .38) 0%, rgba(6, 18, 26, .18) 38%, rgba(6, 18, 26, 0) 60%);
}
.exhale-hero__grid {
  padding-block: clamp(2.5rem, 6vw, 4.5rem);
}
.exhale-hero__copy {
  display: grid;
  gap: 1.6rem;
  justify-items: start;
}
.exhale-hero__title {
  margin: 0;
  max-width: 14ch;
  color: #fff;
  font-size: clamp(2.4rem, 5vw, 4.9rem);
  font-weight: 600;
  line-height: 1.02;
  letter-spacing: -.035em;
  text-wrap: balance;
  text-shadow: 0 2px 30px rgba(0, 0, 0, .25);
}
.exhale-hero__accent {
  color: #00b0e0;
}
.exhale-hero__lede {
  margin: 0;
  max-width: 48ch;
  color: rgba(255, 255, 255, .86);
  font-size: clamp(1rem, 1.25vw, 1.15rem);
  line-height: 1.6;
}
.exhale-hero__actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 1rem 1.5rem;
}
.exhale-hero__cta {
  display: inline-flex;
  align-items: center;
  gap: .5rem;
  padding: 1rem 1.6rem;
  border-radius: 10px;
  font-weight: 600;
  box-shadow: 0 12px 28px -10px rgba(0, 0, 0, .6);
}
.exhale-hero__link {
  display: inline-flex;
  align-items: center;
  gap: .35rem;
  color: #fff;
  font-weight: 600;
  text-decoration: none;
  border-bottom: 1.5px solid currentColor;
  padding-bottom: .15rem;
}
.exhale-hero__link:hover {
  color: #00b0e0;
}
.exhale-hero__cta .material-icons,
.exhale-hero__link .material-icons {
  font-size: 1.15rem;
  transition: transform .25s cubic-bezier(.16, 1, .3, 1);
}
.exhale-hero__cta:hover .material-icons,
.exhale-hero__cta:focus-visible .material-icons,
.exhale-hero__link:hover .material-icons,
.exhale-hero__link:focus-visible .material-icons {
  transform: translateX(4px);
}
/* One entrance: the copy rises once. */
.exhale-hero__copy > * {
  animation: exhale-rise 1.1s cubic-bezier(.16, 1, .3, 1) both;
}
.exhale-hero__copy > :nth-child(2) { animation-delay: .1s; }
.exhale-hero__copy > :nth-child(3) { animation-delay: .2s; }
@keyframes exhale-rise {
  from { opacity: .001; transform: translateY(18px); }
  to { opacity: 1; transform: none; }
}
@media (max-width: 767.98px) {
  .exhale-hero__veil {
    /* Phones: the headline sits higher, over the bright light lines, so the scrim stays a bit stronger here. */
    background: linear-gradient(to top, rgba(6, 18, 26, .84) 0%, rgba(6, 18, 26, .66) 50%, rgba(6, 18, 26, .2) 74%, rgba(6, 18, 26, 0) 88%);
  }
  .exhale-hero__title {
    text-shadow: 0 1px 2px rgba(0, 0, 0, .35), 0 2px 24px rgba(0, 0, 0, .45);
  }
}
@media (max-width: 575.98px) {
  .exhale-hero {
    min-height: 640px;
  }
  .exhale-hero__cta {
    width: 100%;
    justify-content: center;
  }
}
@media (prefers-reduced-motion: reduce) {
  .exhale-hero__video { display: none; } /* the poster (section background) stays */
  .exhale-hero__copy > * { animation: none; }
}

/* Mobile menu (offcanvas #mobileMenu).
   - Client request 30/10: language selector at the top of the menu (it sat at the very bottom). The
     additionnals block becomes display:contents so its two parts are flex items of the offcanvas: the
     selector moves up under the close button (order), the contact links stay at the bottom.
   - The contact links reuse the desktop top-bar markup (one nowrap row): on a phone the email was cut and
     "Avis clients" sat off-screen → stacked. Layered Bootstrap !important utilities (align-items-center,
     gap-3) beat ours → align-self on the children. */
#mobileMenu .offcanvas-header {
  order: -2;
}
/* d-flex is display:flex !important in Hummingbird's @layer utilities; an unlayered !important loses to it,
   the same layer with a more specific selector wins. */
@layer utilities {
  #mobileMenu .ps-mainmenu__additionnals {
    display: contents !important;
  }
  #mobileMenu .ps-mainmenu__selects {
    margin-right: 0 !important; /* me-auto: an auto margin stops the separator from spanning the menu */
  }
}
#mobileMenu .ps-mainmenu__selects {
  order: -1;
  align-self: stretch;
  padding: 0 1rem .75rem;
  border-bottom: 1px solid var(--bs-border-color, #dee2e6);
}
#mobileMenu #_mobile_ps_currencyselector:empty {
  display: none;
}
#mobileMenu .exhale-langselector__toggle {
  padding-left: 0;
}
/* Popper aligned the list on the button's right edge (dropdown-menu-end, right for the desktop top bar),
   which put it flush against the screen edge here: anchor it under the flag instead. */
#mobileMenu .exhale-langselector .dropdown-menu {
  inset: 100% auto auto 0 !important;
  transform: none !important;
  margin-top: .25rem;
}
#mobileMenu #_mobile_ps_contactinfo {
  margin-top: auto;
  padding: 1.25rem 1rem;
  border-top: 1px solid var(--bs-border-color, #dee2e6);
}
#mobileMenu .exhale-topbar-contact {
  flex-direction: column;
}
#mobileMenu .exhale-topbar-contact > a {
  align-self: flex-start;
  white-space: normal;
  overflow-wrap: anywhere;
}

/* --- Product thumbnails, narrow cards 2026-11-02 ------------------------------------------
   1) .product-miniature__infos is a grid with implicit rows that stretch to fill the card, so
      the slack is split between title and price rows and prices end up at different heights
      when titles wrap differently. Give all the slack to the title row: prices line up.
   2) Below 13.5rem of card width Hummingbird switches the add button to full width with its
      text label (container query, not viewport): "Ajouter au panier" + cart icon then wraps onto
      two lines (2-col mobile, and 4-col at ~1024px). Same container query: drop the icon, and
      give "Ajouter au panier" and "Voir détails" the same font, line-height and padding (same
      38px height). Font is 1rem when the label fits, scaled down with the card (cqi) only on
      the narrowest cards: label ≈ 8.7em wide, button = card - 44px of padding/borders. */
.product-miniature__infos {
  grid-template-rows: 1fr;
  grid-auto-rows: auto;
}
@container product-miniature (width < 13.5rem) {
  .product-miniature__add .material-icons {
    display: none;
  }
  .product-miniature__add,
  .product-miniature__details {
    font-size: min(1rem, calc((100cqi - 44px) / 8.9));
    line-height: 1.5rem;
    padding-block: .375rem;
    padding-inline: .25rem;
  }
  .product-miniature__add-text {
    line-height: inherit;
  }
}

/* Mobile menu 2026-11-02: "CONTACT" is typed in capitals in its menu label, the other items
   aren't. Uppercase every item of the mobile menu so they all look the same (desktop unchanged). */
.ps-mainmenu__mobile .menu__link {
  text-transform: uppercase;
}

/* --- Homepage motion 2026-11-02 ------------------------------------------------------------
   CSS only, no JS. Everything is inside prefers-reduced-motion: no-preference, so visitors who
   ask their OS for less motion get the static page. */
@keyframes exhale-arrow-nudge {
  0%, 100% { transform: translateX(0); }
  50%      { transform: translateX(5px); }
}
@keyframes exhale-rise {
  from { opacity: 0; transform: translateY(18px); }
  to   { opacity: 1; transform: none; }
}
@media (prefers-reduced-motion: no-preference) {
  /* 1) Arrow links/buttons: the arrow keeps sliding to the right, faster on hover. */
  .exhale-hero__cta > .material-icons,
  .exhale-hero__link > .material-icons,
  .ps-featuredproducts a.btn > .material-icons {
    animation: exhale-arrow-nudge 1.6s ease-in-out infinite;
  }
  .exhale-hero__cta:hover > .material-icons,
  .exhale-hero__link:hover > .material-icons,
  .ps-featuredproducts a.btn:hover > .material-icons {
    animation-duration: .8s;
  }

  /* 2) Hero copy rises in once on load, one line after the other. */
  .exhale-hero__copy > * {
    animation: exhale-rise .7s cubic-bezier(.2, .7, .2, 1) both;
  }
  .exhale-hero__copy > :nth-child(2) { animation-delay: .12s; }
  .exhale-hero__copy > :nth-child(3) { animation-delay: .24s; }

  /* 3) Below the hero, blocks rise in as they scroll into view (scroll-driven animation, no
     JS). Browsers without animation-timeline skip the whole block: content stays visible. */
  @supports (animation-timeline: view()) {
    .page-content--home .ps-featuredproducts h2,
    .page-content--home .ps-featuredproducts .product-miniature,
    .page-content--home .exhale-home-concept > *,
    .page-content--home .exhale-home-editorial > *,
    .page-content--home .exhale-home-reassurance li {
      animation: exhale-rise linear both;
      animation-timeline: view();
      animation-range: entry 0% entry 70%;
    }
  }
}
