/* ==========================================================================
   Home redesign — extracted from the "Votre expert" mockup.
   Scope: the 5 integrated sections only (hero, categories row, youtube video,
   stats/trust, expert profile) + their shared section header + reveal anim.
   Chrome (navbar, flash bar, footer) lives in the redesign base/components.
   Accessibility: low-contrast greens/grays darkened to meet WCAG AA 4.5:1.
   ========================================================================== */

:root {
    --navy: #1c1c1c;
    --navy-light: #2a2a2a;
    --green: #00d4aa;
    --green-dark: #00b894;
    --orange: #ff6b35;
    --orange-light: #ff8c5a;
    --white: #ffffff;
    --gray-light: #f0f2f5;
    --gray: #596573;
    --text-dark: #1a1a1a;
    /* Orange readable as TEXT on the light hero: --orange (#ff6b35) only reaches
       2.5:1 on --gray-light, which fails AA even at display sizes. These two clear
       4.6:1 and 3.2:1 (AA large) respectively. */
    --orange-deep: #c2410c;
    --orange-mid: #ea580c;
    /* One step deeper again, for text sitting on the badge's translucent orange
       fill: --orange-deep lands at 4.21:1 there, just under AA. */
    --orange-darker: #9a3412;
}

/* ========== BASE ==========
   There is deliberately no reset here. This page used to carry its own, scoped as
   `.home-redesign *`, because it had dropped the legacy bundle and nothing else
   provided one. redesign/css/base.css now does — at document level, and it covers
   the same ground: the box-model reset, the body font and colour, a, ul, img.

   The scoped copy was not merely redundant, it was harmful. `.home-redesign *`
   scores one class, the same as a component's own `.cart-toast-product`, and it
   loaded after — so at equal specificity it won, and any component rendered inside
   this page silently lost its padding. That is exactly how the add-to-cart toast
   came to render edge to edge. A universal selector at document level (base.css)
   scores zero and loses to every component rule, which is the whole point of
   putting a reset there rather than under a class. */

/* ========== LAYOUT ========== */
.home-redesign h1,
.home-redesign h2,
.home-redesign h3 {
    font-family: 'Poppins', sans-serif;
}

.home-redesign .container {
    max-width: 1200px;
    margin: 0 auto;
    padding: 0 20px;
    padding-left: max(20px, env(safe-area-inset-left));
    padding-right: max(20px, env(safe-area-inset-right));
}

/* ========== ANIMATIONS ========== */
@keyframes float {
    0%, 100% { transform: translateY(0); }
    50% { transform: translateY(-10px); }
}

@keyframes slideUp {
    from { opacity: 0; transform: translateY(40px); }
    to { opacity: 1; transform: translateY(0); }
}

@keyframes fadeIn {
    from { opacity: 0; }
    to { opacity: 1; }
}

@keyframes shimmer {
    0% { background-position: -200% center; }
    100% { background-position: 200% center; }
}

@keyframes rotateBorder {
    0% { transform: rotate(0deg); }
    100% { transform: rotate(360deg); }
}

/* Reveal-on-scroll: visible by default (SEO/no-JS), JS adds `.active`. */
.reveal {
    opacity: 1;
    transform: translateY(0);
    transition: opacity 0.8s ease, transform 0.8s ease;
}

.reveal.active {
    opacity: 1;
    transform: translateY(0);
}

.reveal-delay-1 { transition-delay: 0.1s; }
.reveal-delay-2 { transition-delay: 0.2s; }
.reveal-delay-3 { transition-delay: 0.3s; }
.reveal-delay-4 { transition-delay: 0.4s; }

/* ========== SHARED SECTION HEADER ========== */
.section-header {
    text-align: center;
    /* 8, not 16: the titles carry their own leading (a 41px line box on a 33px
       glyph), so a 16px margin read as ~19px of empty space between a title and
       the block it introduces. */
    margin-bottom: 8px;
}

.section-badge {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    background: rgba(255, 107, 53, 0.1);
    border: 1px solid rgba(255, 107, 53, 0.25);
    padding: 6px 16px;
    border-radius: 50px;
    /* Deep by default: three of the four bands carrying a badge are light, where
       --orange only reaches 2.3:1. The dark video band overrides it below. */
    color: var(--orange-darker);
    font-size: 0.85rem;
    font-weight: 500;
    margin-bottom: 10px;
}

/* On the dark video band the deep orange is the unreadable one — go back to the
   bright accent, which clears AA against #141414. */
.video-section .section-badge {
    color: var(--orange);
}

.section-title {
    font-size: clamp(2rem, 4vw, 3rem);
    font-weight: 800;
    margin-bottom: 4px;
}

.section-title.light {
    color: var(--white);
}

.section-title .glow {
    text-shadow: 0 0 20px rgba(255, 107, 53, 0.5), 0 0 40px rgba(255, 107, 53, 0.2);
    color: var(--orange);
}

.section-subtitle {
    font-size: 1.1rem;
    max-width: 800px;
    margin: 0 auto;
    white-space: nowrap;
}

/* A11y: 0.6 white on the dark video gradient fails AA — bump to 0.78. */
.section-subtitle.light {
    color: rgba(255, 255, 255, 0.78);
}

/* ========== HERO SECTION ========== */
.hero {
    min-height: auto;
    /* Vertical only. The horizontal gutter belongs to the .container inside — and
       the child of this section IS that container (class="container hero-grid"), so
       20px here was a SECOND gutter stacked on its. The hero content started 40px
       from the edge where every other section starts at 20px, which is what made
       the band look narrower than the categories panel and the best-seller grid.
       The safe-area insets go with it: .home-redesign .container already declares
       the same max(20px, env(...)) on both sides. */
    padding: 24px 0 22px;
    display: flex;
    align-items: center;
    justify-content: center;
    position: relative;
    /* Light hero: the black slab it used to be read as a hole under the navy chrome
       (navbar/footer are --navy #1c1c1c, the hero was a darker #000).

       Not flat white though — that was half of what read as emptiness, since white
       shows every pixel it does not use. Two soft radial washes give the band a
       centre of gravity behind the portrait and a warm corner behind the text, at
       an opacity low enough that the 4.5:1 on the body copy is untouched. */
    background:
        radial-gradient(760px 520px at 78% 34%, rgba(255, 107, 53, 0.13), transparent 68%),
        radial-gradient(620px 420px at 8% 88%, rgba(28, 28, 28, 0.055), transparent 70%),
        linear-gradient(180deg, #fdfcfb 0%, var(--gray-light) 100%);
    overflow: hidden;
}

/* Scoped under .home-redesign to match .home-redesign .container, which sits on
   the same element and re-declares padding at 0,2,0 — a bare .hero-grid loses. */
.home-redesign .hero-grid {
    display: grid;
    /* Without this the band is narrower than every other section of the page. .hero
       is a flex container, so this grid is a flex ITEM and shrink-wraps to its
       contents — 840px of the 1200px it shares with .container, whose max-width
       only caps a width it never reached. The text started 148px in from the edge
       the categories panel and the best-seller grid sit on. */
    width: 100%;
    /* The text column is the wide one, because it is now the one carrying content:
       badge, title, and the four figures that fill it. Earlier shapes gave that
       column nothing but a title, then tried to fix the emptiness by resizing —
       a bigger title, a centred stack, a bleeding photograph. What actually fills
       a column is what it says. */
    /* Each column hugs its own content, and what is left over becomes the gutter:
       the text sits on the page's left edge, the portrait on its right, and the two
       land on the same measure as the categories panel and the best-seller grid
       below. Fractions cannot do that — they divide the width, so the columns grow
       and the content floats somewhere inside them instead of on the edges. */
    grid-template-columns: auto auto;
    justify-content: space-between;
    align-items: center;
    /* One row of two columns. The row gap is what is left of a second row that
       carried the "En savoir plus" link, removed with it; it still applies on a
       phone, where the grid stacks into a single column.

       The column gap is a MINIMUM, not the gutter: space-between hands the leftover
       to the middle, and this only stops the two columns touching once the band
       gets narrow enough that there is no leftover. */
    gap: 2px 64px;
}


.hero-content {
    text-align: left;
    position: relative;
    z-index: 2;
    padding: 0;
}

.hero h1 {
    font-size: clamp(2.2rem, 4.4vw, 3.4rem);
    font-weight: 900;
    color: var(--text-dark);
    line-height: 1.08;
    margin-bottom: 4px;
    animation: slideUp 1s ease forwards;
    animation-delay: 0.2s;
    opacity: 0;
}

.hero h1 .highlight {
    /* Keep the brand on a single line — never break at the "Anti-Nuisibles" hyphen. */
    white-space: nowrap;
    /* Deep stops only: the original orange/amber shimmer sat at ~2.1:1 on the light
       hero. These stay above the 3:1 the display size requires. */
    background: linear-gradient(135deg, var(--orange-deep), var(--orange-mid), var(--orange-deep));
    background-size: 200% auto;
    -webkit-background-clip: text;
    -webkit-text-fill-color: transparent;
    background-clip: text;
    animation: shimmer 3s linear infinite;
}

/* Full bleed: pinned to the band's right edge, so there is no page margin left
   for the eye to read as emptiness. The name, the certification and the action
   ride on the photograph over a scrim — they cannot move into the text column,
   which would put them before the portrait on a phone. */
.hero-image {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 12px;
}

.hero-image-name {
    font-family: 'Poppins', sans-serif;
    font-weight: 700;
    font-size: 1.15rem;
    color: var(--text-dark);
}

/* The hero's only action, and the one thing that has to read as clickable now
   that the portrait itself is no longer a link. Scoped under .home-redesign like
   the other buttons of the page, so a bare `a` rule cannot outrank it.




/* Rounded square, not a circle: the hero image is a composed thumbnail with
   type baked into it ("Expert anti-nuisibles : la réalité du terrain"), and a
   circular mask ate its corners and clipped the wordmark. */
/* No animation on this frame, deliberately.
   It carried `gradientShift` (background-position) and `glowPulseOrange`
   (box-shadow), both running forever. Neither can be composited: each forces a
   full repaint of the element every frame, and box-shadow repaints the 80px of
   glow around it too — on the element whose paint defines the page's LCP.
   Measured on the homepage: 867 ms of style/layout and 742 ms of paint on the
   main thread, against 2 020 ms of LCP element render delay while every
   stylesheet had already landed at 562 ms. Removing these two took 300 ms off
   the LCP.
   What they bought: a gradient sliding inside a 4px ring, and a glow breathing
   between 20 and 40px of blur. The ring itself is still here, fixed.
   If a frame ever needs to move again, animate `opacity` or `transform` on a
   pseudo-element — those the compositor can do without the main thread — and put
   it behind prefers-reduced-motion. */
.hero-image-frame {
    width: min(380px, 100%);
    aspect-ratio: 1;
    border-radius: 28px;
    position: relative;
    padding: 4px;
    background: linear-gradient(135deg, var(--orange), var(--orange-light), #ff4500, var(--orange));
    background-size: 300% 300%;
}

.hero-image-frame img {
    width: 100%;
    height: 100%;
    /* One notch tighter than the frame so the gradient ring stays even. */
    border-radius: 24px;
    object-fit: cover;
    display: block;
}

/* The four figures that fill the text column (#529). All four come from data the
   page already holds — years, subscribers, the review aggregates, the order count —
   so the column is filled with what convinces rather than with white space or a
   bigger typeface. */
.hero-stats {
    display: grid;
    /* Two by two at every width, desktop included. It was a row of four, which
       only ever fitted on a desktop: the phone got a 2x2 below 768px, and the
       tablet — where the portrait still sits beside these figures, leaving the
       text column NARROWER than a 390px phone — got neither, so "150 000+" lost
       its "+" and the four cells ended up at four different heights.

       One declaration for every width rather than a measured breakpoint, because
       the 2x2 was chosen for how it reads on a desktop too: the box then matches
       the width of the title above it exactly, and the hero loses 50px of height. */
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 1px;
    margin: 24px 0 0;
    padding: 0;
    list-style: none;
    background: var(--line-soft, rgba(0, 0, 0, 0.08));
    border: 1px solid rgba(0, 0, 0, 0.08);
    border-radius: 14px;
    overflow: hidden;
}

.hero-stat {
    background: var(--white);
    padding: 12px 16px;
}

.hero-stat-value {
    display: block;
    font-family: 'Poppins', sans-serif;
    font-size: 1.35rem;
    font-weight: 800;
    color: var(--text-dark);
    line-height: 1.2;
    /* The four values sit in a row and are read as a set — lining figures keep
       them from jittering against each other. */
    font-variant-numeric: tabular-nums;
}

.hero-stat-value.is-rating {
    color: var(--orange-deep);
}

/* The star and the figure share a line. .hero-stat-value is a block — on its own
   the star took a line of its own above it and made this cell one line taller than
   the three beside it. */
.hero-stat-figure {
    display: flex;
    align-items: baseline;
    gap: 4px;
}

/* Filled, against the icon component's own fill="none": a CSS declaration beats a
   presentation attribute, so the shared outline star serves both uses without a
   second asset. Hollow, at this size, it reads as a shape rather than a rating. */
.hero-stat-star {
    color: var(--orange-deep);
    line-height: 1;
}

.hero-stat-star svg {
    width: 0.9em;
    height: 0.9em;
    fill: currentColor;
    stroke: none;
    /* The glyph's box sits on the text baseline; the star's optical centre is a
       touch above it. */
    vertical-align: -0.08em;
}

.hero-stat-label {
    display: block;
    font-size: 0.76rem;
    /* Not the lighter grey used elsewhere: under 0.8rem it falls below 4.5:1. */
    color: #5a6068;
    margin-top: 2px;
}

/* The rating cell is a link to /avis-clients; the other three are not links, so
   the cell must not look like a button — only the hover says it is clickable. */
.home-redesign .hero-stat-link {
    display: block;
    color: inherit;
}

.home-redesign .hero-stat-link:hover {
    color: inherit !important;
}

.home-redesign .hero-stat-link:hover .hero-stat-label {
    color: var(--orange-deep);
    text-decoration: underline;
}

/* ========== CATEGORIES ROW ========== */
.categories-row {
    /* Kept dark against the now-light hero: the pills are white-on-translucent and
       this band is what bridges the hero into the navy video section below.

       The section stays full-bleed and carries the GROUND; the navy is on its
       .container, which is the panel. Two elements rather than one because the
       panel is inset — bounding the section itself left nothing behind it to
       paint, and what showed through was the page's white.

       Grey, not white, and the same --gray-light the best-sellers band below
       already uses: the panel then sits on a continuous ground from here to the
       products instead of on a white strip that reads as a gap.

       No hairline any more. It used to carry a border-bottom because the band that
       follows — best sellers, on light grey — is filled after load and collapses to
       nothing when the catalogue has sold nothing in thirty days; the video section
       below starts its gradient on the SAME navy, so with that band gone the two
       dark sections met at a seam of identical colour and the page read as one
       black slab. Inset on the grey, the panel has its own edges on all four sides,
       so there is no seam left to terminate — the corners are square, and it is the
       margin that separates it, not the rounding. */
    background: var(--gray-light);
    padding: 16px 0;
    position: relative;
}

/* The panel itself. It takes .container's 1200px measure rather than restating it,
   so it lines up with every other section of the page, and only overrides the
   padding — .container's 0 20px is a text gutter, this needs a panel's inset. */
.categories-row .container {
    background: var(--navy);
    padding: 20px 24px 16px;
}

.categories-title {
    margin: 0;
    text-align: center;
    font-family: 'Poppins', sans-serif;
    font-weight: 700;
    font-size: 1.15rem;
    color: var(--white);
}

.categories-list {
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    gap: 10px;
    /* No narrow cap: the row is centred anyway, and a fixed 700px was 41px short
       of the five current pills — enough to wrap the last one onto its own line on
       a 1200px container. The container is what bounds the width. */
    max-width: 100%;
    margin: 8px auto 0;
}

/* Scoped under .home-redesign so the color beats `.home-redesign a { color: inherit }`
   (which would otherwise drag the pill text down to the page's dark body color). */
.home-redesign .category-pill {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 8px;
    padding: 9px 18px;
    border-radius: 50px;
    background: rgba(255, 255, 255, 0.08);
    border: 1px solid rgba(255, 255, 255, 0.12);
    color: var(--white);
    font-family: 'Poppins', sans-serif;
    font-weight: 500;
    font-size: 0.9rem;
    white-space: nowrap;
    cursor: pointer;
    transition: all 0.3s ease;
}

.category-pill:hover {
    background: var(--orange);
    border-color: var(--orange);
    color: var(--white);
    transform: translateY(-2px);
}

.category-pill svg {
    width: 1em;
    height: 1em;
    font-size: 0.95rem;
    color: var(--orange);
    transition: color 0.3s ease;
}

.category-pill:hover svg {
    color: var(--white);
}

/* One rule for every pill icon, whatever an editor uploads.

   Sized by HEIGHT with `width: auto`, not into a square box: these are uploaded
   files with no common aspect ratio — the rodent silhouette is ~1.9:1, the
   cockroach is taller than wide. Forcing 24x24 on both left the rodent with a
   third of the ink of its neighbours for the same box.

   The filter recolours whatever comes in to the brand orange, so an editor does
   not have to care about the file's own colours, and the hover flips it to white
   against the pill's dark fill. */
.category-pill-icon {
    /* One square box for every icon, whatever it was uploaded as.

       Sizing on height alone let the rodent — the only landscape glyph of the
       five, 281x150 — paint 34x18 where the others painted 20x20, and it
       dominated the row. The obvious reading was that a wide silhouette and a
       compact one cannot be balanced by a geometric rule, so the fix had to be a
       width cap tuned per shape.

       That reading was wrong, and measuring said so. Rasterised into an IDENTICAL
       square and counted pixel by pixel, the five carry 9 248 to 10 164 opaque
       pixels — under 10% apart. The rodent is wide but thin: its bounding box is
       nearly twice the others', its ink is not. Balancing bounding boxes was
       balancing the wrong thing.

       So the box is square and the glyph is contained in it. No cap, no per-shape
       tuning, and an editor can upload any aspect ratio without taking over the
       row — which is the whole point of these being administered. */
    width: 20px;
    height: 20px;
    object-fit: contain;
    vertical-align: middle;
    filter: brightness(0) invert(51%) sepia(95%) saturate(1471%) hue-rotate(344deg) brightness(101%) contrast(101%);
    transition: filter 0.3s ease;
}

.category-pill:hover .category-pill-icon {
    filter: brightness(0) invert(1);
}

/* ========== BEST SELLERS ========== */
/* The cards themselves are the site's shared product card (product_card_v2.css),
   rendered server-side by /ajax/best-sellers. This section only owns the band,
   the grid's column count and the skeletons that hold its geometry. */
.bestsellers-section {
    padding: 20px 0;
    background: var(--gray-light);
}

/* The home shows exactly FOUR best sellers, and the shared grid is not written for
   four — it goes three across from 768px and only reaches four at 1200px. Between
   those two widths the fourth card drops onto a row of its own, alone against two
   empty columns.

   So this section overrides the shared grid on both sides of that gap. Overridden
   here rather than fixed in product_card_v2.css: that grid is shared with search,
   the category pages and the blog, where the item count is whatever the query
   returns and three across is right.

   Scoped under .home-redesign on purpose, and this is the whole reason the old
   1200px rule here never did anything: `.home-bestsellers-grid` and
   `.product-card-v2-grid` have the same specificity, and the shared sheet loads
   last, so it won every tie. The old rule only looked like it worked because it
   declared the same four columns the shared grid already gave it.

   Tablet: two by two, at the card's normal size. The cap is what keeps it there —
   two columns left to fill the band stretched a card to 482px wide and 620px tall
   at 1023px, right before the same card drops to 231px at 1024. 580px is two
   desktop-width cards plus the 20px gap, so the pair is centred at the size the
   card is drawn for instead of being blown up to fill the row. */
@media (min-width: 768px) and (max-width: 1023px) {
    .home-redesign .home-bestsellers-grid {
        grid-template-columns: repeat(2, minmax(0, 1fr));
        max-width: 580px;
        margin-inline: auto;
    }
}

/* From 1024px the row of four fits — 235px a card at that width, against the 330px
   it gets at 1440. Brought down from the shared grid's 1200px, which is what left
   the orphan standing across the whole 1024-1199 range. */
@media (min-width: 1024px) {
    .home-redesign .home-bestsellers-grid {
        grid-template-columns: repeat(4, minmax(0, 1fr));
    }
}

/* Skeletons must match the card that replaces them — same shell, same blocks in
   the same order — or the swap reintroduces the shift they prevent. */
.product-card-skeleton {
    pointer-events: none;
}

.skeleton-block,
.skeleton-line {
    display: block;
    border-radius: 6px;
    background: linear-gradient(90deg, #e9ecf1 25%, #f4f6f9 37%, #e9ecf1 63%);
    background-size: 400% 100%;
    animation: skeletonSheen 1.4s ease infinite;
}

.product-card-skeleton .product-card-v2-content {
    display: flex;
    flex-direction: column;
    gap: 8px;
}

.skeleton-line-title { width: 90%; height: 2.4em; }
.skeleton-line-stars { width: 55%; height: 1.1em; }
.skeleton-line-price { width: 35%; height: 1.6em; }

.skeleton-button {
    width: 100%;
    height: 38px;
    border-radius: 8px;
    margin-top: 4px;
}

@keyframes skeletonSheen {
    0% { background-position: 100% 50%; }
    100% { background-position: 0 50%; }
}

/* A skeleton is decoration; it should not pulse for a reader who asked for calm. */
@media (prefers-reduced-motion: reduce) {
    .skeleton-block,
    .skeleton-line {
        animation: none;
    }
}

/* The section title sits on the light band, so it needs the deep stops. */
.section-title .highlight-orange {
    color: var(--orange-deep);
}

/* ========== YOUTUBE VIDEO SECTION ========== */
.video-section {
    padding: 20px 0;
    background: linear-gradient(180deg, var(--navy) 0%, #141414 100%);
    position: relative;
    overflow: hidden;
}

.video-section::before {
    content: '';
    position: absolute;
    top: -50%;
    left: -50%;
    width: 200%;
    height: 200%;
    background: radial-gradient(circle at center, rgba(255, 107, 53, 0.04) 0%, transparent 50%);
    animation: rotateBorder 30s linear infinite;
    pointer-events: none;
}

/* The cell exists only to carry the card's Matomo attributes: media_card.html is
   shared with the hub and the rail, and putting them on the <a> there would tag
   those two surfaces as well. `contents` keeps it out of the layout. */
.home-video-cell {
    display: contents;
}

/* Three across on desktop, one per row on a phone. The cards themselves are the
   shared media card (media-card.css) — this only owns the grid and the palette.

   Dark variant: the video band is near-black, and the card's default white
   surface read as three sheets of paper stapled onto it. Redeclaring the --vd-*
   tokens in this scope re-themes the SAME component — no second card, no
   !important, and the hub keeps its light one. */
.home-video-grid {
    --vd-surface: rgba(255, 255, 255, 0.05);
    --vd-ink: #ffffff;
    --vd-body: rgba(255, 255, 255, 0.78);
    --vd-muted: rgba(255, 255, 255, 0.66);
    --vd-icon: rgba(255, 255, 255, 0.66);
    --vd-line: rgba(255, 255, 255, 0.14);
    --vd-line-strong: rgba(255, 107, 53, 0.55);
    --vd-chip-bg: rgba(255, 255, 255, 0.12);
    --vd-chip-ink: rgba(255, 255, 255, 0.88);
    --vd-shadow: 0 10px 30px rgba(0, 0, 0, 0.5);
    display: grid;
    grid-template-columns: 1fr;
    gap: 16px;
    margin-bottom: 28px;
}

@media (min-width: 768px) {
    .home-video-grid {
        grid-template-columns: repeat(3, minmax(0, 1fr));
        gap: 20px;
    }
}

/* The two video CTAs carry two wordings and show one, so the pair fits a single
   row at every width — see the max-width: 480px block for the swap. */
.cta-label-short {
    display: none;
}

.video-cta-container {
    display: flex;
    align-items: center;
    justify-content: center;
    /* No wrap: these two are a pair, and stacked they read as two decisions
       instead of one row of secondary actions. They are sized to fit side by
       side down to 320px. */
    flex-wrap: nowrap;
    gap: 10px;
}

/* Secondary CTAs beside the red subscribe button: same pill, outlined, so the
   YouTube action stays the primary one of the section.
   Scoped under .home-redesign for the same reason .category-pill is: the page
   reset's `.home-redesign a { color: inherit }` outranks a bare class rule and
   would drag these labels down to the dark body color, on a dark band. */
.home-redesign .video-detail-btn,
.home-redesign .video-hub-btn {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    padding: 9px 18px;
    white-space: nowrap;
    border-radius: 50px;
    border: 1px solid rgba(255, 255, 255, 0.25);
    background: rgba(255, 255, 255, 0.06);
    color: var(--white);
    font-family: 'Poppins', sans-serif;
    font-weight: 600;
    font-size: 0.85rem;
    transition: all 0.3s ease;
}

/* The colors here also shield the three buttons from redesign.css's global
   `a:hover { color: #ec7330 }`, which outranks a plain `.btn { color }` rule and
   would otherwise paint the label orange on hover. */
.home-redesign .video-detail-btn:hover,
.home-redesign .video-hub-btn:hover {
    background: rgba(255, 255, 255, 0.14);
    border-color: rgba(255, 255, 255, 0.45);
    color: var(--white);
    transform: translateY(-3px);
}

.home-redesign .video-detail-btn svg,
.home-redesign .video-hub-btn svg {
    width: 1em;
    height: 1em;
    font-size: 1.05rem;
}

/* Scoped like the other home buttons so `.home-redesign a { color: inherit }` cannot
   repaint the label: it was computing to #1a1a1a on the red button. */
.home-redesign .subscribe-btn {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    background: #ff0000;
    color: var(--white);
    padding: 9px 20px;
    white-space: nowrap;
    border-radius: 50px;
    font-family: 'Poppins', sans-serif;
    font-weight: 600;
    font-size: 0.85rem;
    transition: all 0.3s ease;
}

.home-redesign .subscribe-btn:hover {
    background: #cc0000;
    color: var(--white);
    transform: translateY(-3px);
    box-shadow: 0 8px 25px rgba(255, 0, 0, 0.3);
}

.home-redesign .subscribe-btn svg {
    width: 1em;
    height: 1em;
    font-size: 1.15rem;
}

/* ========== LATEST ARTICLES ========== */
/* The cards are the blog's own component (blog/css/components/blog-card.css);
   this owns the band, the grid and the way out to /blog/. */
.blog-section {
    /* Same rhythm as the video and expert bands it sits between — it was 24/28,
       which read as a wider gap above its title than every other section's. */
    padding: 20px 0;
    background: var(--white);
}

.home-blog-grid {
    display: grid;
    grid-template-columns: 1fr;
    gap: 16px;
}

@media (min-width: 768px) {
    .home-blog-grid {
        grid-template-columns: repeat(3, minmax(0, 1fr));
        gap: 20px;
    }
}

/* Same reason as .home-video-cell: the wrapper exists only to carry the card's
   Matomo attributes, and must not take part in the layout. */
.home-blog-cell {
    display: contents;
}

.blog-cta-container {
    display: flex;
    justify-content: center;
    margin-top: 24px;
}

/* Outlined like the reviews CTA — a way out of the section, not the section's
   main action, which is the cards themselves. */
.home-redesign .blog-cta {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    padding: 11px 24px;
    border: 1px solid var(--orange-deep);
    border-radius: 50px;
    color: var(--orange-deep);
    font-family: 'Poppins', sans-serif;
    font-weight: 700;
    font-size: 0.92rem;
    transition: background-color 0.2s ease, color 0.2s ease;
}

/* The label colour is repeated: redesign.css ships a global
   `a:hover { color: #ec7330 !important }` that would leave the text orange on an
   orange fill. */
.home-redesign .blog-cta:hover {
    background: var(--orange-deep);
    color: var(--white) !important;
}

.blog-cta svg {
    width: 1em;
    height: 1em;
}

/* ========== STATS / TRUST SECTION ========== */
.stats-section {
    padding: 20px 0;
    background: linear-gradient(135deg, var(--orange) 0%, #e05520 100%);
    position: relative;
}

.stats-grid {
    display: grid;
    grid-template-columns: repeat(4, 1fr);
    gap: 16px;
}

.stat-card {
    text-align: center;
    /* A grid track is `minmax(auto, 1fr)`, and `auto` floors at min-content — which
       here is the whole formatted number, since toLocaleString('fr-FR') separates
       thousands with NARROW NO-BREAK SPACEs (U+202F) that offer no wrap point. So
       "23 500 000+" is one 189px token, and without this the track refuses to
       shrink and the grid overflows its container on mobile. */
    min-width: 0;
    padding: 16px 12px;
    background: rgba(255, 255, 255, 0.15);
    backdrop-filter: blur(10px);
    -webkit-backdrop-filter: blur(10px);
    border-radius: 20px;
    border: 1px solid rgba(255, 255, 255, 0.2);
    transition: transform 0.3s ease;
}

.stat-card:hover {
    transform: translateY(-5px);
}

.stat-card svg {
    width: 1em;
    height: 1em;
    font-size: 2rem;
    color: var(--navy);
    margin-bottom: 10px;
    display: block;
    margin-left: auto;
    margin-right: auto;
}

.stat-card .stat-number {
    font-family: 'Poppins', sans-serif;
    font-size: 2.5rem;
    font-weight: 800;
    color: var(--white);
    display: block;
    line-height: 1.2;
}

.stat-card .stat-text {
    font-size: 1rem;
    color: var(--white);
    font-weight: 500;
}

/* ========== EXPERT PROFILE SECTION ========== */
.expert-section {
    padding: 20px 0;
    background: var(--white);
}

/* ========== CUSTOMER REVIEWS ========== */
/* Score summary — the mockup's weight (a big number, not a line of small text),
   split in two the way /avis-clients does. Side by side on desktop, stacked on
   a phone, with a rule between them so the two scopes read as two answers. */
.reviews-summary {
    display: flex;
    align-items: center;
    justify-content: center;
    flex-wrap: wrap;
    gap: 16px 48px;
    margin-bottom: 8px;
}

/* Phone: the two scores share a line instead of stacking two 2.5rem numbers, so
   the review card starts higher. */
@media (max-width: 768px) {
    /* The two scores share a line instead of stacking two 2.5rem numbers. */
    .reviews-summary {
        gap: 6px 18px;
        margin-bottom: 6px;
    }

    .review-score {
        gap: 6px;
    }

    .review-score-number {
        font-size: 1.35rem;
    }

    .review-score-max {
        font-size: 0.8rem;
    }

    .review-score-detail {
        flex-direction: row;
        align-items: center;
        gap: 6px;
    }

    .review-score-count {
        font-size: 0.75rem;
    }

    /* The review card was inset 52px each side — the page container's 20px, the
       carousel's 24px (room for the prev/next arrows, which are hidden at this
       width) and the slide's 8px, stacked. The arrows being gone, that room is
       just margin; the negative inline margin eats part of the container's own so
       the card reaches a 12px gutter. */
    .home-redesign .home-review-carousel {
        padding-left: 0;
        padding-right: 0;
        margin-left: -8px;
        margin-right: -8px;
    }

    .home-review-carousel__slide {
        padding: 0 4px;
    }
}

/* The carousel's 40px top padding exists for /avis-clients, where it has to clear
   the white panel above it (a margin would collapse there). On the home it stacks
   on top of the summary's own margin — 64px between the ratings and the first
   review. */
.home-redesign .home-review-carousel {
    padding-top: 8px;
}

.review-score {
    display: flex;
    align-items: center;
    gap: 14px;
}

.review-score-value {
    display: flex;
    align-items: baseline;
    gap: 6px;
}

.review-score-number {
    font-family: 'Poppins', sans-serif;
    font-weight: 800;
    font-size: 2.5rem;
    line-height: 1;
    color: var(--navy);
    /* The number counts up (see review_score.html): proportional digits are
       different widths, so "1,1" and "4,3" would not occupy the same box and the
       "/ 5" beside it would twitch for the whole two seconds. */
    font-variant-numeric: tabular-nums;
}

.review-score-max {
    font-size: 1rem;
    font-weight: 500;
    color: var(--gray);
}

.review-score-detail {
    display: flex;
    flex-direction: column;
    gap: 2px;
}

/* font-size drives the shared SVG stars (review/_stars.html sizes them in em). */
.review-score-stars {
    font-size: 18px;
    line-height: 1;
}

.review-score-count {
    font-size: 0.9rem;
    color: var(--gray);
    /* Same reason as the number above: the count animates from one digit to two. */
    font-variant-numeric: tabular-nums;
}


/* The carousel itself is styled by review/css/home_reviews.css (shared with
   /avis-clients) — this band only sets it off from the white expert section
   above, since the cards are white. */
.reviews-cta-container {
    display: flex;
    justify-content: center;
    margin-top: 20px;
}

/* Outlined, not solid: the section already ends on the carousel's own product
   links, and a filled orange pill here would outrank them. */
.home-redesign .reviews-cta {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    padding: 11px 24px;
    border: 1px solid var(--orange-deep);
    border-radius: 50px;
    color: var(--orange-deep);
    font-family: 'Poppins', sans-serif;
    font-weight: 700;
    font-size: 0.92rem;
    transition: background-color 0.2s ease, color 0.2s ease;
}

/* The label colour is repeated: redesign.css ships a global
   `a:hover { color: #ec7330 !important }` that would leave the text orange on an
   orange fill. */
.home-redesign .reviews-cta:hover {
    background: var(--orange-deep);
    color: var(--white) !important;
}

.reviews-cta svg {
    width: 1em;
    height: 1em;
}

/* The 8px top was tuned when this band followed the expert section and only had
   to clear it; moved up the page it now opens a band of its own, and its title
   was sitting 12px higher than every other. */
.reviews-section {
    padding: 20px 0 32px;
    background: var(--gray-light);
}


.expert-grid {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 16px;
    align-items: center;
}

.expert-image-container {
    position: relative;
}

/* 3:2, the photograph's own ratio. It used to be a square with a dark gradient
   behind it, which was a placeholder for an image that had not been chosen yet;
   now that a real one is in, the frame follows the picture rather than the other
   way round. */
.expert-image-frame {
    width: 100%;
    max-width: 380px;
    margin: 0 auto;
    border-radius: 20px;
    overflow: hidden;
    position: relative;
}

/* The animated orange edge the placeholder carried, kept: it is what ties this
   block to the hero portrait's frame. Inset behind the image via z-index, so the
   radius of the two stays concentric. */
.expert-image-frame::before {
    content: '';
    position: absolute;
    top: -2px;
    left: -2px;
    right: -2px;
    bottom: -2px;
    background: linear-gradient(135deg, var(--orange), var(--orange-light), #ff4500, var(--orange));
    border-radius: 22px;
    z-index: -1;
    background-size: 200% 200%;
}

.expert-image-frame img {
    display: block;
    width: 100%;
    height: auto;
    border-radius: 20px;
}

.expert-content h2 {
    font-size: 1.8rem;
    font-weight: 800;
    margin-bottom: 2px;
    color: var(--navy);
}

.expert-role {
    /* On the white expert band --orange measures 2.83:1. */
    color: var(--orange-deep);
    font-family: 'Poppins', sans-serif;
    font-weight: 600;
    font-size: 1rem;
    margin-bottom: 6px;
}

.expert-bio {
    color: #000000;
    font-size: 0.95rem;
    line-height: 1.6;
    margin-bottom: 10px;
}

/* The two figures the paragraph exists to convey. 700, not the display font's
   inherited weight: at body size a heavier stroke reads as a heading fragment
   dropped into a sentence. */
.expert-bio strong {
    font-weight: 700;
    color: var(--text-dark);
}

.certifications {
    display: flex;
    flex-wrap: wrap;
    gap: 12px;
}

.cert-badge {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    padding: 10px 20px;
    background: var(--gray-light);
    border-radius: 50px;
    font-weight: 500;
    font-size: 0.9rem;
    color: var(--navy);
    transition: all 0.3s ease;
}

.cert-badge:hover {
    background: var(--orange);
    color: var(--white);
    transform: translateY(-2px);
}

.cert-badge svg {
    width: 1em;
    height: 1em;
    color: var(--orange);
    font-size: 1rem;
}

.cert-badge:hover svg {
    color: var(--white);
}

/* ========== RESPONSIVE ========== */
@media (max-width: 1024px) {
    .stats-grid {
        grid-template-columns: repeat(2, 1fr);
    }

    /* Tablet two-column range: shrink the title so the nowrap brand line
       still fits the narrower text column (avoids horizontal overflow). */
    .hero h1 {
        font-size: clamp(1.9rem, 4.5vw, 2.8rem);
    }

}

@media (max-width: 768px) {
    /* Sized off the viewport, not off a floor: at the 2rem the clamp used to
       bottom out at, "Nos Produits Best-Sellers" needed 419px for the 350px a
       phone offers, so it broke at its hyphen — "Best-" over "Sellers". The vw
       term is set by the longest title on the page, which is that one. */
    .section-title {
        font-size: clamp(1.25rem, 6.6vw, 2rem);
    }

    .home-redesign .hero-grid {
        grid-template-columns: 1fr;
        text-align: center;
        /* Stacked, the 40px meant for two columns reads as loose blocks — the badge
           in particular floated away from the name it qualifies. */
        gap: 10px;
    }

    /* The one place the text column stops being a box.

       The hero reads title / portrait / name / figures / link here, and the figures
       have to sit under the name — which lives in the OTHER column. `order` only
       moves an element among its siblings, so the figures have to become siblings of
       the portrait: `contents` drops this wrapper out of the box tree and hands its
       three children straight to .hero-grid, which is a single column at this width.

       Deliberately confined to this query. On a desktop the wrapper is a real box
       again, and that is what keeps title, subtitle and figures reading as one block
       against a portrait 166px taller than they are — as grid children of their own
       they would each be placed separately and that difference would open as a hole
       between the subtitle and the figures. */
    .hero-content {
        display: contents;
    }

    /* Placed, because `contents` means the order below is the only thing left saying
       what comes first. The subtitle is hidden at this width, so it takes no slot.

       Selected through .hero-content, not as `.hero-grid > *`: `contents` removes
       the wrapper's BOX, not the wrapper — these two are still its DOM children, and
       a child combinator on the grid would match neither. */
    .home-redesign .hero-content > h1 {
        order: 1;
        text-align: center;
    }

    .home-redesign .hero-image {
        order: 2;
    }

    .home-redesign .hero-content > .hero-stats {
        order: 3;
    }

    /* Not on a phone. The column is the full width there, so the paragraph buys
       nothing against a portrait it no longer sits beside — and it costs the height
       that decides whether the figures and the category pills are reachable without
       a scroll. Everything it says is repeated further down, in the expert section
       it is included from, so nothing is lost: this is the same trade the old hero
       subtitle made, for a paragraph four times longer. */
    .hero-bio {
        display: none;
    }

    /* The 2x2 itself is set on .hero-stats, for every width. Only the spacing is
       a phone concern. */
    .hero-stats {
        margin-top: 4px;
    }

    .hero-stat {
        padding: 10px 12px;
    }

    .hero-stat-value {
        font-size: 1.2rem;
    }

    /* Four items stack here (portrait, name, badge, action) — at the desktop
       16px they cost 48px of gap alone, which pushed what follows past the fold. */
    .hero-image {
        gap: 10px;
    }

    /* The three article cards already carry their own vertical spacing on a
       phone, so the band only needs to clear its neighbours. */
    .blog-section {
        padding: 8px 0;
    }

    /* Fill the column rather than sit small in the middle of it: stacked under
       the text, the portrait is the section's image and 250px left a third of the
       width empty on each side. Capped at 320px, which is the width the 1x asset
       is cut for — past that it would be upscaled. */
    .hero-image-frame {
        width: min(82vw, 320px);
        height: min(82vw, 320px);
    }

    .hero h1 {
        font-size: 2.2rem;
    }

    .section-subtitle {
        white-space: normal;
        padding: 0 8px;
    }

    .expert-grid {
        grid-template-columns: 1fr;
        text-align: center;
        padding: 0 8px;
        gap: 10px;
    }

    .expert-content h2 {
        font-size: 1.5rem;
    }

    .expert-role {
        font-size: 0.9rem;
    }

    .expert-bio {
        font-size: 0.9rem;
        line-height: 1.6;
    }

    .certifications {
        justify-content: center;
    }

    .stats-grid {
        grid-template-columns: repeat(2, 1fr);
        gap: 16px;
    }

    .stat-card {
        padding: 24px 16px;
    }

    /* Fluid rather than a fixed step: the widest figure is unbreakable (see
       .stat-card), so the type has to shrink with the card or it spills. Sized so
       "23 500 000+" still fits the narrower of the two columns at 320px. */
    .stat-card .stat-number {
        font-size: clamp(1rem, 5.4vw, 2rem);
    }

    /* Flex rather than a grid: with a category count that is not a multiple of the
       column count — 5 categories over 3 or 2 columns — a grid parks the last pill
       in column 1 and leaves a hole beside it, while a wrapped flex row centres the
       remainder. The basis keeps the columns even; grow stays 0 so a lone last pill
       keeps its width instead of stretching across the row. */
    .categories-list {
        gap: 8px;
    }

    .category-pill {
        flex: 0 1 calc(33.333% - 6px);
        justify-content: center;
        padding: 10px 8px;
        font-size: 0.8rem;
        white-space: nowrap;
    }
}

@media (max-width: 480px) {
    /* Stacked, and the gap tightened: side by side the two scores each get half a
       phone's width and the counts wrap mid-label. */
    .reviews-summary {
        flex-direction: column;
        gap: 14px;
    }

    .review-score-number {
        font-size: 2rem;
    }

    .hero {
        padding: 8px 20px 16px;
    }

    .category-pill {
        flex-basis: calc(50% - 4px);
    }

    /* The two video CTAs stay on one row down to 320px, which the full wording
       cannot do: "Toutes nos vidéos" + "S'abonner à la chaîne" needs 402px of a
       280px container. Tighter padding, and the subscribe label keeps its verb. */
    .home-redesign .video-hub-btn,
    .home-redesign .subscribe-btn {
        padding: 8px 13px;
        font-size: 0.78rem;
    }

    .cta-label-full {
        display: none;
    }

    .cta-label-short {
        display: inline;
    }
}
