/*
Theme Name: CV-TT3
Theme URI: https://www.canards-volants.fr/
Author: Olivier Ausems
Description: A child theme of TT3 for the Canards Volants.
Requires at least: 6.1
Tested up to: 7.1
Requires PHP: 7.4
Version: 0.35.0
Template: twentytwentythree
Text Domain: cv-tt3
Domain Path: /languages
*/

/* =============================================================
   Les Canards Volants — UI layer for WordPress / Greenshift
   Child theme of Twenty Twenty-Three
   -------------------------------------------------------------
   HOW TO USE: never restyle a block by hand in Greenshift.
   Add one of the cv-* classes below in the block's
   Advanced -> "Additional CSS class(es)" field, and let
   Greenshift handle only layout (grid, spacing, order).
   ============================================================= */

/* -------------------------------------------------------------
   1. TOKENS — change a value here, the whole site follows
   ------------------------------------------------------------- */
:root {
  /* Brand colours */
  --cv-blue:        #015EA1;   /* primary: headings + body text */
  --cv-blue-deep:   #004477;   /* dark surfaces, secondary text */
  --cv-blue-light:  #9CC8E6;   /* captions on dark, Thérébentine tints */
  --cv-red:         #D90A1C;   /* CTA / action only */
  --cv-green:       #199D2F;   /* "offert", go, nature */
  --cv-paper:       #FFFDF7;   /* default page field — never pure white */
  --cv-cream:       #EFE8D6;   /* aged-paper surfaces */
  --cv-ink:         #1A1A1F;   /* OUTLINES ONLY — not a text colour */
  --cv-mute:        #8A7F62;   /* small meta labels on cream */

  /* Series identity */
  --cv-serie-therebentine: #015EA1;
  --cv-serie-mamie:        #723A9A;
  --cv-serie-petaroo:      #FFFC01;
  --cv-serie-petaroo-fg:   #004477;  /* text that sits on the yellow */

  /* Depth — one shadow for the entire site */
  --cv-shadow:       5px 5px 0 0 rgba(26, 26, 31, 0.22);
  --cv-shadow-hover: 7px 7px 0 0 rgba(26, 26, 31, 0.22);
  --cv-shadow-press: 0 0 0 0 rgba(26, 26, 31, 0.22);

  /* Outlines & radii */
  --cv-border:       3px solid var(--cv-ink);
  --cv-border-thin:  2px solid var(--cv-ink);
  --cv-radius-sm:    8px;
  --cv-radius:       14px;
  --cv-radius-lg:    18px;
  --cv-radius-xl:    22px;
  --cv-radius-pill:  999px;

  /* Type */
  --cv-font-display: "Ranchers", system-ui, sans-serif;
  --cv-font-body:    "Nunito", system-ui, sans-serif;
  --cv-font-comic:   "Indie Flower", cursive;   /* speech bubbles only */
  --cv-font-shout:   "Bangers", cursive;        /* stickers only */

  /* Motion */
  --cv-dur-fast: 140ms;
  --cv-dur-base: 240ms;
  --cv-ease-bounce: cubic-bezier(.34, 1.56, .64, 1);

  /* Layout */
  --cv-max: 1180px;
}

/* -------------------------------------------------------------
   2. BASE — page field and text colour
   ------------------------------------------------------------- */
body {
  background: var(--cv-paper);
  color: var(--cv-blue);
  font-family: var(--cv-font-body);
  text-wrap: pretty;
}

h1, h2, h3, h4, h5, h6,
.cv-title {
  font-family: var(--cv-font-display);
  font-weight: 400;
  color: var(--cv-blue);
  line-height: 1;
  letter-spacing: 0;
}

a { color: var(--cv-blue); }
a:hover { color: var(--cv-blue-deep); }

/* Twenty Twenty-Three styles links inside post content as the palette's
   "secondary", and section 10's legacy shim still defines that slug as
   #E90000 so old content keeps its colours. The two combine to paint
   every link in page content red. The shim has to stay, so the link
   colour is restated here instead — (0,1,1) against the
   ":root :where(.wp-block-post-content a…)" rule's (0,1,0). */
.wp-block-post-content a:where(:not(.wp-element-button)) { color: var(--cv-blue); }
.wp-block-post-content a:where(:not(.wp-element-button)):hover { color: var(--cv-blue-deep); }

/* Small uppercase label above a heading */
.cv-eyebrow {
  font-weight: 800;
  font-size: 13px;
  letter-spacing: .12em;
  text-transform: uppercase;
  color: var(--cv-blue-deep);
}

/* Handwritten aside — only for speech-bubble lettering / captions */
.cv-note {
  font-family: var(--cv-font-comic);
  font-size: 17px;
  color: var(--cv-blue-deep);
}

/* -------------------------------------------------------------
   2b. PAGE RHYTHM — no global gaps

   Three separate things were putting bands of page background between
   the sections, all of them WordPress defaults rather than anything in
   the design:

     .wp-site-blocks             24px root padding, top and bottom,
                                 inherited from Twenty Twenty-Three
     :where(.wp-site-blocks) > * 1.5rem between header, main and footer
     :root :where(.is-layout-*)  1.5rem between every pair of siblings

   Sections carry their own padding, so the global rhythm goes and space
   is added deliberately — inside an element, or with a Spacer block.

   Scope matters here. Only the document's own children and the
   wide/full sections lose their gap; an ordinary paragraph in a blog
   post is still a plain unaligned child of post-content and keeps its
   1.5rem, which is what makes body copy readable.

   Specificity: the root rule is :where(), so it carries none at all,
   and the layout rules land at (0,1,0). Nothing here needs !important.
   ------------------------------------------------------------- */
body .wp-site-blocks {
  padding-top: 0;
  padding-bottom: 0;
}
.wp-site-blocks > * { margin-block-start: 0; }
.wp-block-post-content > .alignfull,
.wp-block-post-content > .alignwide { margin-block-start: 0; }

/* -------------------------------------------------------------
   3. BUTTONS
   Apply to the Button block. Gutenberg wraps the label in
   .wp-block-button__link, so the class is placed on the wrapper
   and reaches the link.
   ------------------------------------------------------------- */
.cv-btn > .wp-block-button__link,
a.cv-btn,
button.cv-btn,
.cv-btn.wp-block-button .wp-block-button__link {
  display: inline-block;
  font-family: var(--cv-font-body);
  font-weight: 900;
  font-size: 15px;
  text-transform: uppercase;
  letter-spacing: .05em;
  text-decoration: none;
  padding: 14px 24px;
  border: var(--cv-border);
  border-radius: var(--cv-radius);
  box-shadow: var(--cv-shadow);
  background: var(--cv-blue);
  color: var(--cv-paper);
  cursor: pointer;
  transition: transform var(--cv-dur-fast), box-shadow var(--cv-dur-fast);
}
.cv-btn > .wp-block-button__link:hover,
a.cv-btn:hover, button.cv-btn:hover,
.cv-btn.wp-block-button .wp-block-button__link:hover {
  transform: translate(-2px, -2px);
  box-shadow: var(--cv-shadow-hover);
}
.cv-btn > .wp-block-button__link:active,
a.cv-btn:active, button.cv-btn:active,
.cv-btn.wp-block-button .wp-block-button__link:active {
  transform: translate(5px, 5px);
  box-shadow: var(--cv-shadow-press);
}

/* Buy / add-to-cart — red */
.cv-btn--buy > .wp-block-button__link,
a.cv-btn--buy, button.cv-btn--buy,
.cv-btn--buy.wp-block-button .wp-block-button__link {
  background: var(--cv-red);
  color: var(--cv-paper);
}

/* Secondary — paper fill, no shadow.
   The design sets this one in sentence case: only the primary button
   shouts. It also runs narrower (20px sides, not 24) and answers hover
   with an underline instead of the lift the filled buttons use. */
.cv-btn--ghost > .wp-block-button__link,
a.cv-btn--ghost, button.cv-btn--ghost,
.cv-btn--ghost.wp-block-button .wp-block-button__link {
  background: var(--cv-paper);
  color: var(--cv-blue);
  box-shadow: none;
  text-transform: none;
  letter-spacing: normal;
  padding: 14px 20px;
}
.cv-btn--ghost > .wp-block-button__link:hover,
a.cv-btn--ghost:hover, button.cv-btn--ghost:hover,
.cv-btn--ghost.wp-block-button .wp-block-button__link:hover {
  transform: none;
  box-shadow: none;
  text-decoration: underline;
  text-decoration-thickness: 2px;
}

/* Card-sized: the design's in-card button is noticeably smaller than a
   standalone one. */
.cv-btn--sm > .wp-block-button__link,
a.cv-btn--sm, button.cv-btn--sm,
.cv-btn--sm.wp-block-button .wp-block-button__link {
  font-size: 13px;
  padding: 8px 16px;
  border-radius: 12px;
  box-shadow: 3px 3px 0 0 rgba(26, 26, 31, .22);
}

/* Sitting on a dark panel — cream outline instead of ink */
.cv-btn--on-dark > .wp-block-button__link,
a.cv-btn--on-dark,
.cv-btn--on-dark.wp-block-button .wp-block-button__link {
  border-color: var(--cv-paper);
}

/* -------------------------------------------------------------
   3b. CORE BUTTON DEFAULT

   The brief styles buttons only via an opt-in .cv-btn class. That
   works for new content, but every Button block already on the site
   is a plain core button and would keep rendering square and
   unstyled. These rules give the Button block the same treatment by
   default, so existing pages adopt the design without being edited.

   Specificity note: theme.json emits its button rules as
   ":root :where(...)", which lands at (0,1,0). A single class would
   tie and be decided by stylesheet order, so each selector here
   carries two classes to win outright — no !important needed.

   The variants cv-btn--buy / --ghost / --on-dark are NOT more
   specific than the colour rules below -- both compute to (0,3,0),
   and these sit later in the file, so they used to win and every
   variant rendered plain blue. Hence the :not([class*="cv-btn--"])
   guard: the defaults simply do not apply to a button that asked for
   a variant.
   ------------------------------------------------------------- */
/* Shape, type and depth — these apply to every button. */
.wp-block-button .wp-block-button__link,
.wp-block-button__link.wp-element-button {
  font-family: var(--cv-font-body);
  font-weight: 900;
  font-size: 15px;
  text-transform: uppercase;
  letter-spacing: .05em;
  text-decoration: none;
  padding: 14px 24px;
  border: var(--cv-border);
  border-radius: var(--cv-radius);
  box-shadow: var(--cv-shadow);
  cursor: pointer;
  transition: transform var(--cv-dur-fast), box-shadow var(--cv-dur-fast);
}

/* Colour is applied only where the author has not chosen one.
   WordPress adds .has-background / .has-text-color when a colour is
   picked in the editor, and its own rule for that colour sits at
   (0,1,0) — lower than the selectors here. Excluding those classes
   lets a deliberate choice survive instead of being overridden. */
.wp-block-button:not([class*="cv-btn--"]) .wp-block-button__link:not(.has-background) {
  background: var(--cv-blue);
}
.wp-block-button:not([class*="cv-btn--"]) .wp-block-button__link:not(.has-text-color),
.wp-block-button:not([class*="cv-btn--"]) .wp-block-button__link:not(.has-text-color):visited {
  color: var(--cv-paper);
}

.wp-block-button .wp-block-button__link:hover,
.wp-block-button__link.wp-element-button:hover {
  transform: translate(-2px, -2px);
  box-shadow: var(--cv-shadow-hover);
}
.wp-block-button:not([class*="cv-btn--"]) .wp-block-button__link:not(.has-background):hover {
  background: var(--cv-blue);
}
.wp-block-button .wp-block-button__link:active,
.wp-block-button__link.wp-element-button:active {
  transform: translate(5px, 5px);
  box-shadow: var(--cv-shadow-press);
}

/* Core's outline style maps onto the design's ghost button. */
.wp-block-button.is-style-outline .wp-block-button__link {
  border: var(--cv-border);
  box-shadow: none;
}
.wp-block-button.is-style-outline .wp-block-button__link:not(.has-background),
.wp-block-button.is-style-outline .wp-block-button__link:not(.has-background):hover {
  background: var(--cv-paper);
}
.wp-block-button.is-style-outline .wp-block-button__link:not(.has-text-color),
.wp-block-button.is-style-outline .wp-block-button__link:not(.has-text-color):visited {
  color: var(--cv-blue);
}

/* On a dark panel the ink outline disappears — switch to paper. */
.cv-panel--blue .wp-block-button .wp-block-button__link,
.cv-panel--purple .wp-block-button .wp-block-button__link,
.cv-trust-strip .wp-block-button .wp-block-button__link {
  border-color: var(--cv-paper);
}

/* -------------------------------------------------------------
   3c. GREENSHIFT BUTTONS

   Greenshift's button block has different markup from core's: the
   CSS class you type in the editor lands on the wrapper div, while
   the button itself is the <a class="gspb-buttonbox"> inside it.

       div.gspb_button_wrapper.cv-btn
         └── a.gspb-buttonbox
               └── span.gspb-buttonbox-textwrap ...

   So none of the .cv-btn rules above can reach it.

   Greenshift also emits per-block CSS as
   ".gspb_button-id-XXXX > .gspb-buttonbox { ... }" — specificity
   (0,2,0), printed in an inline <style> in the body, i.e. after this
   stylesheet. Matching that specificity would lose on source order,
   so these selectors carry three classes to win cleanly.

   This is opt-in via .cv-btn, deliberately. Greenshift bakes each
   button's colours into its own per-block CSS, and unlike core there
   is no .has-background marker to detect a deliberate choice — so
   styling every Greenshift button by default would silently flatten
   colours chosen per block.
   ------------------------------------------------------------- */
.cv-btn.gspb_button_wrapper > .gspb-buttonbox,
.cv-btn.wp-block-greenshift-blocks-button > .gspb-buttonbox {
  font-family: var(--cv-font-body);
  font-weight: 900;
  font-size: 15px;
  text-transform: uppercase;
  letter-spacing: .05em;
  text-decoration: none;
  padding: 14px 24px;
  border: var(--cv-border);
  border-radius: var(--cv-radius);
  box-shadow: var(--cv-shadow);
  background-color: var(--cv-blue);
  color: var(--cv-paper);
  cursor: pointer;
  transition: transform var(--cv-dur-fast), box-shadow var(--cv-dur-fast);
}

/* The label sits in nested spans; make sure they follow the anchor. */
.cv-btn.gspb_button_wrapper > .gspb-buttonbox .gspb-buttonbox-title,
.cv-btn.gspb_button_wrapper > .gspb-buttonbox .gspb-buttonbox-text {
  color: inherit;
  font: inherit;
  letter-spacing: inherit;
  text-transform: inherit;
}

/* The border has to be re-declared here, not just on the base rule.
   Greenshift emits its own ".gspb_button-id-XXXX > .gspb-buttonbox:hover"
   rule that re-sets border to 2px in the old "contrast" blue — (0,3,0),
   tying with the base rule above and winning on source order. The result
   was a border painted the same colour as the hover fill, so it read as
   having disappeared. Declaring it on :hover reaches (0,4,0) and wins. */
.cv-btn.gspb_button_wrapper > .gspb-buttonbox:hover,
.cv-btn.wp-block-greenshift-blocks-button > .gspb-buttonbox:hover {
  background-color: var(--cv-blue);
  color: var(--cv-paper);
  border: var(--cv-border);
  transform: translate(-2px, -2px);
  box-shadow: var(--cv-shadow-hover);
}
.cv-btn.gspb_button_wrapper > .gspb-buttonbox:active,
.cv-btn.wp-block-greenshift-blocks-button > .gspb-buttonbox:active {
  transform: translate(5px, 5px);
  box-shadow: var(--cv-shadow-press);
}

/* Variants, matching the core-button modifiers. */
.cv-btn--buy.gspb_button_wrapper > .gspb-buttonbox,
.cv-btn--buy.gspb_button_wrapper > .gspb-buttonbox:hover {
  background-color: var(--cv-red);
  color: var(--cv-paper);
}
.cv-btn--ghost.gspb_button_wrapper > .gspb-buttonbox,
.cv-btn--ghost.gspb_button_wrapper > .gspb-buttonbox:hover {
  background-color: var(--cv-paper);
  color: var(--cv-blue);
  box-shadow: none;
}
.cv-btn--on-dark.gspb_button_wrapper > .gspb-buttonbox,
.cv-btn--on-dark.gspb_button_wrapper > .gspb-buttonbox:hover {
  border-color: var(--cv-paper);
}

/* -------------------------------------------------------------
   4. PANELS — the outlined, offset-shadow surface
   ------------------------------------------------------------- */
.cv-panel {
  background: var(--cv-paper);
  border: var(--cv-border);
  border-radius: var(--cv-radius-xl);
  box-shadow: var(--cv-shadow);
  padding: 32px 36px;
}
.cv-panel--cream  { background: var(--cv-cream); }
.cv-panel--blue   { background: var(--cv-blue-deep); color: var(--cv-paper); }
.cv-panel--yellow { background: var(--cv-serie-petaroo); color: var(--cv-serie-petaroo-fg); }
.cv-panel--purple { background: var(--cv-serie-mamie); color: var(--cv-paper); }

/* Text inside a dark panel */
.cv-panel--blue h1, .cv-panel--blue h2, .cv-panel--blue h3,
.cv-panel--blue .cv-title,
.cv-panel--purple h1, .cv-panel--purple h2, .cv-panel--purple h3,
.cv-panel--purple .cv-title { color: var(--cv-paper); }
.cv-panel--blue p, .cv-panel--purple p { color: var(--cv-cream); }
.cv-panel--blue .cv-note { color: var(--cv-blue-light); }

/* -------------------------------------------------------------
   5. STICKERS, BADGES, PILLS
   ------------------------------------------------------------- */
.cv-badge {                        /* "Nouveau !", "Offert !" */
  display: inline-block;
  font-family: var(--cv-font-shout);
  font-size: 22px;
  letter-spacing: .04em;
  background: var(--cv-red);
  color: var(--cv-paper);
  border: var(--cv-border-thin);
  border-radius: var(--cv-radius-sm);
  padding: 2px 14px;
  box-shadow: 2px 2px 0 0 rgba(26, 26, 31, .22);
  transform: rotate(-6deg);
}
.cv-badge--gift  { background: var(--cv-green); }
/* The offer badge is the one badge with no outline: the design gives it
   a flat red fill and a gentler tilt, so it reads as a ribbon on the
   panel rather than a sticker stuck to it. */
.cv-badge--offer {
  font-size: 20px;
  transform: rotate(-2deg);
  border: 0;
  box-shadow: none;
  padding: 2px 14px;
}

.cv-pill {                         /* "Dès 5 ans", series tags */
  display: inline-block;
  background: var(--cv-paper);
  color: var(--cv-blue);
  border: var(--cv-border-thin);
  border-radius: var(--cv-radius-pill);
  padding: 3px 14px;
  font-weight: 800;
  font-size: 13px;
}

/* -------------------------------------------------------------
   6. HERO — full-bleed illustration + floating paper panel
   Put .cv-hero on the full-width Cover/Group block,
   .cv-hero__panel on the Group block inside it.
   ------------------------------------------------------------- */
.cv-hero {
  position: relative;
  min-height: 620px;
  border-bottom: var(--cv-border);
  background-size: cover;
  background-position: center 25%;
  background-repeat: no-repeat;
  display: flex;
  align-items: center;
}
/* Kill the Cover block's dim overlay — the brand has no overlays */
.cv-hero .wp-block-cover__background,
.cv-hero .wp-block-cover__gradient-background { opacity: 0 !important; }

.cv-hero__panel {
  position: relative;
  /* 580px is the design's width. At that size the two buttons wrap onto
     separate lines, which is what the mockup does too. Add the class
     cv-hero__panel--wide to the panel to buy the ~80px that keeps them
     on one row on a desktop; remove it to go back to the design. */
  max-width: var(--cv-hero-panel-max, 580px);
  background: var(--cv-paper);
  border: var(--cv-border);
  border-radius: var(--cv-radius-lg);
  /* The hero card sits deeper than the rest of the site: the design
     gives it 8px, not the 5px --cv-shadow everything else uses. */
  box-shadow: 8px 8px 0 0 rgba(26, 26, 31, .22);
  padding: 30px 34px;
}
/* The card is left-aligned inside the 1180px container. Do NOT use
   Cover's "content position" control for this: it sets
   .has-custom-content-position, whose core rule forces the inner
   container to margin:0;width:auto, which kills the container's own
   centring and throws the card against the viewport edge. */
.cv-hero__panel--wide { --cv-hero-panel-max: 660px; }

/* Left-aligned inside the 1180px container. This only works because the
   group around the panel uses flow layout: a constrained parent makes
   WordPress generate a .wp-container-* rule that centres every child,
   and that rule cannot be outranked without !important. Do not switch
   that group back to Constrained in the editor. */
.cv-hero .cv-hero__panel { margin-left: 0; margin-right: auto; }

/* Spacing inside the card. WordPress's flow layout puts a 24px
   block gap between siblings at (0,1,0); the design is tighter than
   that, so each element states its own margin at (0,2,0). */
.cv-hero__panel .cv-eyebrow      { margin: 0 0 10px; }
.cv-hero__panel h2               { margin: 0 0 10px; line-height: .92; }
.cv-hero__panel p                { margin: 0 0 14px; }
.cv-hero__panel .cv-hero__pills  { margin: 0 0 20px; }
.cv-hero__panel .wp-block-buttons { margin: 0; }
.cv-hero__panel .cv-note         { margin: 16px 0 0; font-size: 18px; }

/* The entrance animation lives on the Greenshift container that wraps
   this panel, not here -- see patterns/parts/hero.php. Greenshift emits
   its own per-block CSS inline, after this stylesheet, so anything
   declared here for opacity or transform would be overridden anyway. */
.cv-hero__panel h2,
.cv-hero__panel .cv-title { font-size: clamp(38px, 6vw, 66px); margin: 0 0 10px; line-height: .92; }

/* Visually hidden, but present for screen readers and crawlers.

   The homepage's H1 names the site; the loudest thing in the hero is an
   album announcement, which is an h2 because it heads that section
   rather than describing the page. Putting the site line in the eyebrow
   slot was worse on both counts: an eyebrow is a label, not a heading,
   and it left a screen-reader user hearing a tagline followed by an
   unrelated h2 beneath it.

   Google treats out-of-view text as de-emphasised rather than deceptive,
   and headings are a weak signal either way, so this costs little and
   buys a correct document outline. */
.cv-visually-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

/* Cover paints its contents white, and core re-asserts that on every
   heading and paragraph inside it with
   ":root :where(.wp-block-cover h1:not(.has-text-color)) { color: inherit }"
   at (0,1,0) -- a direct rule, so it beats anything merely inherited.
   The panel is paper, so the text colours have to be stated here, and
   the order matters: the eyebrow, note, badge and pill rules tie with
   the paragraph rule at (0,2,0) and win on coming later. */
.cv-hero__panel { color: var(--cv-blue); }
.cv-hero__panel h1,
.cv-hero__panel h2,
.cv-hero__panel .cv-title { color: var(--cv-blue); }
.cv-hero__panel p { color: var(--cv-blue); }
.cv-hero__panel .cv-eyebrow { color: var(--cv-blue-deep); }
.cv-hero__panel .cv-note { color: var(--cv-blue-deep); }
.cv-hero__panel .cv-pill { color: var(--cv-blue); }
.cv-hero__panel .cv-badge { color: var(--cv-paper); }

/* No mobile art direction here on purpose.
   A second crop for phones is *content*, not design: it is another
   image someone has to choose and upload, so its home is the editor,
   not this file. Hard-coding an /wp-content/uploads/ path in the
   stylesheet breaks the moment the site moves or the file is replaced.
   If a phone-specific crop is wanted, set it on the Greenshift
   container (responsive background) or move the Cover's focal point. */

/* Sticker pinned to the panel's top-right corner. .cv-badge tilts
   every badge -6deg; the hero's leans the other way, +8deg, so it has
   to be restated here (and inside the keyframes above, or the
   animation's final frame would drop the rotation). */
.cv-hero__sticker {
  position: absolute;
  top: -18px;
  right: -14px;
  z-index: 2;
  transform: rotate(8deg);
}

/* Trust strip directly under the hero */
.cv-trust-strip {
  background: var(--cv-blue-deep);
  color: var(--cv-paper);
  font-weight: 700;
  font-size: 14px;
}
.cv-trust-strip p { margin: 0; color: var(--cv-paper); }

/* -------------------------------------------------------------
   6b. HEADER NAVIGATION

   The design's nav is plain Nunito 800 at 15px, and the active tab is
   marked by a 3px red rule underneath it — nothing else changes, no
   fill, no colour shift. The same red marks the section: the shop tab
   stays lit on a product page, which is what cv_tt3_nav_mark_current()
   in functions.php exists to make possible.

   Specificity note: theme.json styles links as
   ":root :where(a:where(:not(.wp-element-button)))" at (0,1,0), so two
   classes here is enough to win.
   ------------------------------------------------------------- */
/* Core forces every nav link to inherit, with the class doubled to reach
   (0,3,0):
     .wp-block-navigation .wp-block-navigation-item__content.wp-block-navigation-item__content { color: inherit }
   A single-class rule here never applied. The top level looked right
   only by accident — it inherited the page's blue — while submenu links
   inherited the #000 core puts on the submenu container. Matching the
   doubled class states the colour where it actually lands. */
.wp-block-navigation .wp-block-navigation-item__content.wp-block-navigation-item__content {
  color: var(--cv-blue);
}
.wp-block-navigation .wp-block-navigation-item__content {
  font-family: var(--cv-font-body);
  font-weight: 800;
  font-size: 15px;
  color: var(--cv-blue);
  text-decoration: none;
  padding: 8px 12px;
  border-radius: var(--cv-radius-sm);
  border-bottom: 3px solid transparent;
  transition: border-color var(--cv-dur-fast), color var(--cv-dur-fast);
}
.wp-block-navigation .wp-block-navigation-item__content:hover,
.wp-block-navigation .wp-block-navigation-item__content:focus {
  color: var(--cv-blue-deep);
  text-decoration: none;
}

/* The red marker — current page, and any ancestor of it. */
.wp-block-navigation .current-menu-item > .wp-block-navigation-item__content,
.wp-block-navigation .current-menu-ancestor > .wp-block-navigation-item__content,
.wp-block-navigation .current-menu-parent > .wp-block-navigation-item__content,
.wp-block-navigation .current_page_item > .wp-block-navigation-item__content {
  border-bottom-color: var(--cv-red);
}

/* Submenus keep core's open/close behaviour untouched; only the surface
   is restyled, into the same paper card the rest of the site uses. */
/* Core guards the submenu's surface with :not() selectors, which land at
   (0,3,0) — so these mirror those selectors rather than trying to
   outrank them, and win on load order. Without this the submenu keeps
   core's white ground and hairline grey border. */
.wp-block-navigation:not(.has-background) .wp-block-navigation__submenu-container {
  background-color: var(--cv-paper);
  border: var(--cv-border-thin);
}
.wp-block-navigation:not(.has-text-color) .wp-block-navigation__submenu-container {
  color: var(--cv-blue);
}
.wp-block-navigation .wp-block-navigation__submenu-container {
  border-radius: var(--cv-radius);
  box-shadow: var(--cv-shadow);
  padding: 6px;
}
.wp-block-navigation .wp-block-navigation__submenu-container .wp-block-navigation-item__content {
  font-size: 14px;
  padding: 7px 12px;
  border-bottom: 0;
  border-radius: var(--cv-radius-sm);
  white-space: nowrap;
}
.wp-block-navigation .wp-block-navigation__submenu-container .wp-block-navigation-item__content:hover {
  background: var(--cv-cream);
}
/* Inside a submenu the marker would look like a stray underline, so the
   active child gets the fill treatment instead. */
.wp-block-navigation .wp-block-navigation__submenu-container .current-menu-item > .wp-block-navigation-item__content.wp-block-navigation-item__content {
  background: var(--cv-cream);
  color: var(--cv-blue-deep);
}

/* -------------------------------------------------------------
   6c. MINI CART

   Woo's mini-cart block maps almost one-to-one onto the design's cart
   button: __button is the button, __badge is the red count pill. The
   block keeps its drawer and its live count; only the skin changes.
   ------------------------------------------------------------- */
.wc-block-mini-cart__button {
  display: flex;
  align-items: center;
  gap: 8px;
  background: var(--cv-paper);
  color: var(--cv-blue);
  border: var(--cv-border);
  border-radius: var(--cv-radius);
  box-shadow: 3px 3px 0 0 rgba(26, 26, 31, .22);
  padding: 9px 18px;
  font-family: var(--cv-font-body);
  font-weight: 900;
  font-size: 14px;
  text-transform: uppercase;
  letter-spacing: .05em;
  cursor: pointer;
  transition: transform var(--cv-dur-fast), box-shadow var(--cv-dur-fast);
}
.wc-block-mini-cart__button:hover {
  transform: translate(-2px, -2px);
  box-shadow: 5px 5px 0 0 rgba(26, 26, 31, .22);
}
.wc-block-mini-cart__button:active {
  transform: translate(3px, 3px);
  box-shadow: var(--cv-shadow-press);
}
/* Woo parks the count outside the button: position:absolute, left:100%,
   margin-left:-44%, so it floats over the icon's top-right corner. The
   design has it sitting inside, beside the icon, so the badge is put
   back into normal flow and the wrapper spaces the two. */
.wc-block-mini-cart__quantity-badge { gap: 8px; }
.wc-block-mini-cart__button .wc-block-mini-cart__badge {
  position: static;
  left: auto;
  margin-left: 0;
  transform: none;
  min-width: 22px;
  height: 22px;
  padding: 0 6px;
  border-radius: var(--cv-radius-pill);
  font-family: var(--cv-font-body);
  font-size: 13px;
  font-weight: 800;
  line-height: 1;
  letter-spacing: 0;
}
/* Colour is a fallback only. Woo binds the badge's background-color and
   color through the Interactivity API, which writes them as inline
   styles at runtime and beats any stylesheet — so the real values are
   set as block attributes on wp:woocommerce/mini-cart in
   parts/header.html, not here. */
.wc-block-mini-cart__badge {
  background: var(--cv-red);
  color: var(--cv-paper);
  border: 0;
}
/* The label the block has no setting for; injected by
   cv_tt3_mini_cart_skin() in functions.php. */
.cv-cart__label { line-height: 1; }

.wc-block-mini-cart__button .wc-block-mini-cart__icon {
  width: 20px;
  height: 20px;
  margin: 0;
  color: var(--cv-blue);
}
/* The drawer itself, so it does not arrive as stock Woo white. */
.wc-block-mini-cart__drawer .wc-block-components-drawer {
  background: var(--cv-paper);
  border-left: var(--cv-border);
}

/* -------------------------------------------------------------
   7. CARDS — album card & series tile
   ------------------------------------------------------------- */
.cv-card {
  background: var(--cv-paper);
  border: var(--cv-border);
  border-radius: 16px;
  box-shadow: var(--cv-shadow);
  overflow: hidden;
  /* Column, full height: the cards sit in a Columns row that stretches
     them, and without this each one is only as tall as its own text, so
     four cards with different title lengths end up ragged. */
  display: flex;
  flex-direction: column;
  height: 100%;
  transition: transform var(--cv-dur-fast), box-shadow var(--cv-dur-fast);
}
/* No block gap between the cover and the body — the flow layout's
   1.5rem was showing as a band of paper above the body's top border. */
.cv-card > * { margin: 0; }
.cv-card .wp-block-image { margin: 0; }

.cv-card__art {
  margin: 0;
  aspect-ratio: 1;
  overflow: hidden;
}
.cv-card__art img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center;
}
.cv-card:hover { transform: translate(-2px, -2px); box-shadow: var(--cv-shadow-hover); }
.cv-card img { display: block; width: 100%; height: auto; }
.cv-card__body {
  padding: 14px 16px 16px;
  border-top: var(--cv-border);
  display: flex;
  flex-direction: column;
  gap: 8px;
  flex: 1;
}
.cv-card__body > * { margin: 0; }

.cv-card__title { font-weight: 800; font-size: 17px; line-height: 1.25; }
.cv-card__title a { color: inherit; text-decoration: none; }
.cv-card__art a { display: block; height: 100%; }

/* Pinned to the bottom, so price and button line up across cards
   whatever length the titles above them run to. */
.cv-card__row { margin-top: auto; }

.cv-card__price { font-family: var(--cv-font-display); font-size: 24px; color: var(--cv-blue); }

.cv-serie-tile {
  position: relative;
  display: flex;
  flex-direction: column;
  overflow: hidden;
  border: var(--cv-border);
  border-radius: var(--cv-radius-lg);
  box-shadow: var(--cv-shadow);
  text-decoration: none;
  transition: transform var(--cv-dur-fast), box-shadow var(--cv-dur-fast);
}
.cv-serie-tile:hover { transform: translate(-2px, -2px); box-shadow: var(--cv-shadow-hover); }
/* The art is an ordinary Image block so an editor can swap it per series
   the usual way, rather than the path living in this file. The crop is
   done here: 170px tall, centred, filling the width. */
.cv-serie-tile__art {
  margin: 0;
  height: 170px;
  overflow: hidden;
  border-bottom: var(--cv-border);
}
.cv-serie-tile__art img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center;
}

.cv-serie-tile__body {
  padding: 16px 20px 18px;
  display: flex;
  flex-direction: column;
  gap: 4px;
}
.cv-serie-tile__body > * { margin: 0; }
.cv-serie-tile__body .cv-title {
  font-size: 34px;
  line-height: 1;
  text-shadow: 2px 2px 0 rgba(26, 26, 31, .18);
}
.cv-serie-tile__age  { font-weight: 800; font-size: 13px; }
.cv-serie-tile__more {
  font-weight: 900;
  font-size: 13px;
  text-transform: uppercase;
  letter-spacing: .06em;
  margin-top: 6px;
}

/* The tile paints its own text colour per series, so the link has to
   take it rather than the site's link blue — otherwise "Découvrir"
   comes out blue on a blue tile. */
.cv-serie-tile__body a {
  color: inherit;
  text-decoration: none;
}
/* Whole tile clickable, the way the design's <a>-wrapped tile behaves. */
.cv-serie-tile__more a::after {
  content: "";
  position: absolute;
  inset: 0;
}

.cv-serie--therebentine { background: var(--cv-serie-therebentine); }
.cv-serie--mamie        { background: var(--cv-serie-mamie); }
.cv-serie--petaroo      { background: var(--cv-serie-petaroo); }

.cv-serie--therebentine .cv-serie-tile__body,
.cv-serie--therebentine .cv-serie-tile__body .cv-title,
.cv-serie--mamie .cv-serie-tile__body,
.cv-serie--mamie .cv-serie-tile__body .cv-title { color: var(--cv-paper); }
.cv-serie--petaroo .cv-serie-tile__body,
.cv-serie--petaroo .cv-serie-tile__body .cv-title { color: var(--cv-serie-petaroo-fg); }

/* -------------------------------------------------------------
   7b. OFFER PANEL — the pack's mini covers

   Three squares, fanned out slightly, each holding one cover. A gallery
   was the wrong block for this: it wants to lay out and caption its own
   images, and the captions ended up printed over the panel.

   These are three ordinary Image blocks, each in its own group, so the
   crop is ours and the pictures stay swappable.
   ------------------------------------------------------------- */
/* The panel's text column, to the design's own measurements. */
.cv-pack__title { font-size: 46px; line-height: 1; margin: 14px 0 10px; }
.cv-pack__blurb { font-size: 16px; margin: 0 0 6px; max-width: 52ch; }
.cv-pack__dates { margin: 0 0 18px; }

/* Button and the saving sit on one line, vertically centred. */
.cv-pack__cta { align-items: center; }
.cv-panel--blue .cv-pack__save {
  color: var(--cv-paper);
  font-weight: 800;
  font-size: 15px;
  margin: 0;
}
.cv-pack__save s { opacity: .6; }

/* Two up, one below, pulled into the pair: a triangle rather than a
   row. Grid rather than flex because the third cover has to span both
   columns to sit centred under them, which flex cannot express.

   The block's own layout is Default (flow) so WordPress emits no
   competing flex container rule for this group. */
.cv-pack__minis {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  justify-items: center;
  align-items: start;
  gap: 14px;
  max-width: 420px;
  margin-left: auto;
}
.cv-pack__minis > * { margin: 0; }

.cv-pack__mini {
  position: relative;
  width: 100%;
  max-width: 190px;
  aspect-ratio: 1;
  border: 2px solid var(--cv-paper);
  border-radius: 12px;
  /* Not hidden: the "Offert !" sticker hangs off the bottom edge, so
     the cover's corners are rounded on the image instead. */
  overflow: visible;
}
.cv-pack__mini .wp-block-image,
.cv-pack__mini figure { margin: 0; height: 100%; }
.cv-pack__mini img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center;
  border-radius: 10px;
}

/* The third sits under the pair, overlapping them slightly so the three
   read as a stack that has been fanned out. */
.cv-pack__mini:nth-child(3) {
  grid-column: 1 / -1;
  margin-top: -26px;
  z-index: 2;
}

/* Fanned, so they read as books rather than a grid. */
.cv-pack__mini:nth-child(1) { transform: rotate(-5deg); }
.cv-pack__mini:nth-child(2) { transform: rotate(4deg); }
.cv-pack__mini:nth-child(3) { transform: rotate(-2deg); }

/* The "Offert !" sticker is a plain paragraph carrying
   cv-badge cv-badge--gift cv-pack__gift. To move it to a different
   cover, drag the paragraph into that cover's group; to drop the offer,
   delete the paragraph. Nothing else has to change, which is the point:
   which album is free changes with every pack. */
.cv-pack__gift {
  position: absolute;
  /* Straddling the bottom edge rather than sitting inside it. In the
     design the sticker is tucked within a 108px square, where it fills
     most of the cover; hung off the edge it reads as applied to the
     album instead of hiding it. */
  bottom: -12px;
  left: 50%;
  transform: translateX(-50%) rotate(-6deg);
  margin: 0;
  font-size: 18px;
  padding: 2px 10px;
  white-space: nowrap;
  z-index: 3;
}

/* -------------------------------------------------------------
   7c. BLOG — "Les nouveaux blogs"

   One featured post beside a two-up list of the rest. Both are Query
   Loops, so the section fills itself from the blog.
   ------------------------------------------------------------- */
.cv-blog__head { align-items: baseline; margin-bottom: 26px; }
.cv-blog__head h2 { margin: 0 0 6px; }
.cv-blog__sub { margin: 0; font-size: 17px; }
.cv-blog__all {
  margin: 0;
  font-weight: 900;
  font-size: 13px;
  text-transform: uppercase;
  letter-spacing: .06em;
}
.cv-blog__all a {
  color: var(--cv-blue);
  text-decoration: none;
  border-bottom: 3px solid var(--cv-blue);
  padding-bottom: 2px;
}

/* Shared card treatment. The featured one is simply bigger. */
.cv-blog__feat,
.cv-blog__card {
  background: var(--cv-paper);
  border: var(--cv-border);
  overflow: hidden;
  transition: transform var(--cv-dur-fast), box-shadow var(--cv-dur-fast);
}
.cv-blog__feat { border-radius: 18px; box-shadow: var(--cv-shadow); }
.cv-blog__card { border-radius: 14px; box-shadow: 4px 4px 0 0 rgba(26, 26, 31, .22); }
.cv-blog__feat:hover { transform: translate(-2px, -2px); box-shadow: var(--cv-shadow-hover); }
.cv-blog__card:hover { transform: translate(-2px, -2px); box-shadow: 6px 6px 0 0 rgba(26, 26, 31, .22); }

.cv-blog__feat > *,
.cv-blog__card > * { margin: 0; }
.cv-blog__img,
.cv-blog__card-img { margin: 0; border-bottom: var(--cv-border); background: var(--cv-cream); }
.cv-blog__img img,
.cv-blog__card-img img { width: 100%; object-fit: cover; }
.cv-blog__card-img img { object-position: center 22%; }

.cv-blog__feat-body { padding: 20px 24px 24px; }
.cv-blog__card-body {
  padding: 12px 14px 14px;
  display: flex;
  flex-direction: column;
  gap: 6px;
}

/* Category on the featured card is a cream pill; on the small cards it
   is just a small label, as the design has it. */
.cv-blog__cat {
  display: inline-block;
  background: var(--cv-cream);
  color: var(--cv-blue);
  border: var(--cv-border-thin);
  border-radius: var(--cv-radius-pill);
  padding: 2px 12px;
  font-weight: 800;
  font-size: 12px;
  letter-spacing: .04em;
  text-transform: uppercase;
}
.cv-blog__cat a { color: inherit; text-decoration: none; }

.cv-blog__title { margin: 12px 0 8px; font-size: 32px; line-height: 1.05; }
.cv-blog__title a { color: var(--cv-blue); text-decoration: none; }
/* The design caps this at 46ch, which is a sensible measure at the width
   it was drawn — but the featured card here is wider than that, so the
   cap left a short column of text in a broad card. Let it fill. */
.cv-blog__teaser { margin: 0; font-size: 15px; }

.cv-blog__card-cat {
  font-weight: 900;
  font-size: 10.5px;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--cv-mute);
}
.cv-blog__card-cat a { color: inherit; text-decoration: none; }
.cv-blog__card-title {
  margin: 0;
  font-family: var(--cv-font-body);
  font-weight: 800;
  font-size: 15px;
  line-height: 1.2;
}
.cv-blog__card-title a { color: var(--cv-blue); text-decoration: none; }

@media (max-width: 781px) {
  .cv-blog__title { font-size: 26px; }
}

/* -------------------------------------------------------------
   8. WOOCOMMERCE — Woo writes its own markup, so we target
   its classes rather than adding cv-* by hand.
   ------------------------------------------------------------- */
/* Woo lays its loop out with floats and percentage widths. A grid gives
   equal-height cards for free, which is what lets the price row sit on
   the floor of every card regardless of how long the titles run. */
.woocommerce ul.products {
  display: grid;
  /* Follows Woo's own columns-N class, so the shop setting and the
     shortcode's columns attribute both work instead of being overruled. */
  grid-template-columns: repeat(var(--cv-shop-cols, 4), minmax(0, 1fr));
  gap: 20px;
  margin: 0;
  padding: 0;
  list-style: none;
}
.woocommerce ul.products::before,
.woocommerce ul.products::after { content: none; }
.woocommerce ul.products.columns-1 { --cv-shop-cols: 1; }
.woocommerce ul.products.columns-2 { --cv-shop-cols: 2; }
.woocommerce ul.products.columns-3 { --cv-shop-cols: 3; }
.woocommerce ul.products.columns-5 { --cv-shop-cols: 5; }
.woocommerce ul.products.columns-6 { --cv-shop-cols: 6; }

@media (max-width: 899px) {
  .woocommerce ul.products { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
@media (max-width: 599px) {
  .woocommerce ul.products { grid-template-columns: minmax(0, 1fr); }
}

.woocommerce ul.products li.product {
  position: relative;
  background: var(--cv-paper);
  border: var(--cv-border);
  border-radius: 16px;
  box-shadow: var(--cv-shadow);
  /* No overflow:hidden — see li.wc-block-product. */
  padding: 0 0 14px;
  /* Undo the float layout the grid replaces. */
  width: auto;
  float: none;
  margin: 0;
  /* Two rows: the link fills the first, price and button share the
     second. space-between pins that second row to the bottom.

     Every one of these is stated on purpose. WooCommerce ships a Twenty
     Twenty-Three compatibility stylesheet that sets this same selector
     to flex-direction:column, justify-content:space-between,
     align-items:flex-start and text-align:center. Leaving the direction
     unset left it on column, which made the link's flex-basis:100% mean
     100% of the *height* — so price and button wrapped into a second
     column beside the card and were clipped away by overflow:hidden. */
  display: flex;
  flex-direction: row;
  flex-wrap: wrap;
  justify-content: flex-start;
  align-items: center;
  align-content: space-between;
  text-align: left;
  transition: transform var(--cv-dur-fast), box-shadow var(--cv-dur-fast);
}
/* WooCommerce's small-screen sheet forces every card to 48% and floats
   it, with
     .woocommerce ul.products[class*=columns-] li.product
   which is (0,4,2) — one unit above the rule just above, because an
   attribute selector counts the same as a class. Inside a grid cell that
   leaves each card at half its column with a gutter beside it, which is
   what the phone screenshot showed. Matching the selector, rather than
   trying to outrank it, hands the width back to the grid. */
.woocommerce ul.products[class*="columns-"] li.product {
  width: auto;
  float: none;
  clear: none;
  margin: 0;
}

.woocommerce ul.products li.product > a.woocommerce-loop-product__link {
  flex: 1 0 100%;
  display: block;
}
.woocommerce ul.products li.product img {
  width: 100%;
  height: auto;
  aspect-ratio: 1;
  object-fit: cover;
  object-position: center;
}
.woocommerce ul.products li.product:hover { transform: translate(-2px, -2px); box-shadow: var(--cv-shadow-hover); }
.woocommerce ul.products li.product a img { margin: 0; border-bottom: var(--cv-border); border-radius: 13px 13px 0 0; }
.woocommerce ul.products li.product .woocommerce-loop-product__title {
  font-family: var(--cv-font-body);
  font-weight: 800;
  font-size: 17px;
  line-height: 1.25;
  color: var(--cv-blue);
  padding: 12px 16px 10px;
}
.woocommerce ul.products li.product .price {
  font-family: var(--cv-font-display);
  font-size: 24px;
  color: var(--cv-blue);
  margin: 0 auto 0 16px;
  padding: 0;
}
/* The card's button is the small blue one, not the red buy button the
   product page uses. */
.woocommerce ul.products li.product a.button {
  margin: 0 16px 0 0;
  background: var(--cv-blue);
  font-size: 13px;
  padding: 8px 16px;
  border-radius: 12px;
  box-shadow: 3px 3px 0 0 rgba(26, 26, 31, .22);
}
.woocommerce ul.products li.product a.button:hover {
  box-shadow: 5px 5px 0 0 rgba(26, 26, 31, .22);
}

.woocommerce a.button,
.woocommerce button.button,
.woocommerce input.button,
.woocommerce #respond input#submit,
.woocommerce a.button.alt,
.woocommerce button.button.alt {
  font-family: var(--cv-font-body);
  font-weight: 900;
  font-size: 14px;
  text-transform: uppercase;
  letter-spacing: .05em;
  background: var(--cv-red);
  color: var(--cv-paper);
  border: var(--cv-border);
  border-radius: var(--cv-radius);
  box-shadow: var(--cv-shadow);
  padding: 13px 22px;
  transition: transform var(--cv-dur-fast), box-shadow var(--cv-dur-fast);
}
.woocommerce a.button:hover,
.woocommerce button.button:hover,
.woocommerce input.button:hover,
.woocommerce a.button.alt:hover,
.woocommerce button.button.alt:hover {
  background: var(--cv-red);
  color: var(--cv-paper);
  transform: translate(-2px, -2px);
  box-shadow: var(--cv-shadow-hover);
}
.woocommerce a.button:active,
.woocommerce button.button:active,
.woocommerce a.button.alt:active {
  transform: translate(5px, 5px);
  box-shadow: var(--cv-shadow-press);
}

/* Sale sticker on a product cover.

   Two markups, one look. The classic loop and the product page print
   Woo's span.onsale; the block catalogue prints the Product Sale Badge
   block, which Woo styles as a white outlined pill and pins top-right —
   right where the age pill sits. Both get the .cv-badge sticker (red,
   Bangers, tilted, outlined) and hang over the top-LEFT corner of the
   card, past its edge, the way the hero's sticker hangs off its panel;
   the age pill keeps the right corner. For that to show, the cards no
   longer clip their overflow — the cover rounds its own top corners
   instead (see the img rules).

   Selectors carry a tag name so they outrank the "Promo label" rule
   still living in the Customizer's Additional CSS on the live site. */
.woocommerce ul.products li.product span.onsale,
body.woocommerce div.product span.onsale,
li.wc-block-product .wc-block-components-product-sale-badge {
  position: absolute;
  top: -12px;
  left: -12px;
  right: auto;
  z-index: 3;
  margin: 0;
  min-height: 0;
  min-width: 0;
  width: auto;
  font-family: var(--cv-font-shout);
  font-size: 20px;
  font-weight: 400;
  letter-spacing: .04em;
  line-height: 1.4;
  text-transform: uppercase;
  background: var(--cv-red);
  color: var(--cv-paper);
  border: var(--cv-border-thin);
  border-radius: var(--cv-radius-sm);
  box-shadow: 3px 3px 0 0 rgba(26, 26, 31, .22);
  transform: rotate(-8deg);
  padding: 2px 14px;
}
li.wc-block-product .wc-block-components-product-sale-badge span {
  font: inherit;
  color: inherit;
}

/* Sale price. The old price goes small, grey and struck; the new one
   keeps the price size and turns red, the same red as the sticker. */
.woocommerce ul.products li.product .price del,
.woocommerce div.product p.price del,
li.wc-block-product .wc-block-components-product-price del {
  opacity: 1;
  font-family: var(--cv-font-body);
  font-weight: 700;
  font-size: .75em;
  color: var(--cv-mute);
  text-decoration: line-through;
  margin-right: .3em;
  vertical-align: .1em;
}
.woocommerce ul.products li.product .price ins,
.woocommerce div.product p.price ins,
li.wc-block-product .wc-block-components-product-price ins {
  text-decoration: none;
  font-weight: inherit;
  color: var(--cv-red);
}

/* Quantity input & single-product summary */
.woocommerce .quantity .qty {
  border: var(--cv-border);
  border-radius: var(--cv-radius-sm);
  font-family: var(--cv-font-body);
  font-weight: 800;
  color: var(--cv-blue);
  padding: 10px;
}
.woocommerce div.product .product_title { font-family: var(--cv-font-display); color: var(--cv-blue); }
.woocommerce div.product p.price { font-family: var(--cv-font-display); color: var(--cv-blue); font-size: 34px; }
.woocommerce div.product .woocommerce-tabs ul.tabs li {
  border: var(--cv-border);
  border-radius: var(--cv-radius-sm) var(--cv-radius-sm) 0 0;
  background: var(--cv-cream);
}

/* Free-shipping / notice bars */
.woocommerce-info,
.woocommerce-message {
  background: var(--cv-cream);
  border: var(--cv-border);
  border-radius: var(--cv-radius);
  box-shadow: var(--cv-shadow);
  color: var(--cv-blue);
  font-weight: 700;
}
.woocommerce-info::before,
.woocommerce-message::before { color: var(--cv-blue); }

/* -------------------------------------------------------------
   9. RESPONSIVE
   ------------------------------------------------------------- */
@media (max-width: 900px) {
  .cv-hero { min-height: 460px; background-position: center 30%; }
  .cv-hero__panel { max-width: none; padding: 24px 22px; }
  .cv-panel { padding: 24px 22px; }
  .cv-serie-tile__art { height: 140px; }
}
@media (max-width: 600px) {
  .cv-hero { min-height: 400px; }
  .cv-badge { font-size: 18px; }
  :root { --cv-shadow: 4px 4px 0 0 rgba(26,26,31,.22); }
}

/* -------------------------------------------------------------
   8c. PRODUCT GRID — block rendering (Product Collection)

   The catalogue is built from blocks, so its cards are <li
   class="wc-block-product">, not the classic ul.products li.product
   that section 8 styles. Same design, different markup: this section
   gives the block cards the treatment, so both paths look alike.
   ------------------------------------------------------------- */
.wc-block-product-template {
  display: grid;
  grid-template-columns: repeat(var(--cv-shop-cols, 3), minmax(0, 1fr));
  gap: 20px;
  margin: 0;
  padding: 0;
  list-style: none;
}
.wc-block-product-template.columns-1 { --cv-shop-cols: 1; }
.wc-block-product-template.columns-2 { --cv-shop-cols: 2; }
.wc-block-product-template.columns-4 { --cv-shop-cols: 4; }
.wc-block-product-template.columns-5 { --cv-shop-cols: 5; }
@media (max-width: 899px) {
  .wc-block-product-template { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
@media (max-width: 599px) {
  .wc-block-product-template { grid-template-columns: minmax(0, 1fr); }
}

li.wc-block-product {
  position: relative;
  background: var(--cv-paper);
  border: var(--cv-border);
  border-radius: 16px;
  box-shadow: var(--cv-shadow);
  /* No overflow:hidden — the sale sticker hangs past the corner. The
     cover, the only child that reaches the edge, rounds itself. */
  margin: 0;
  padding: 0 0 14px;
  /* Full height so the button sits on the floor of every card whatever
     length the titles above it run to. */
  display: flex;
  flex-direction: column;
  transition: transform var(--cv-dur-fast), box-shadow var(--cv-dur-fast);
}
li.wc-block-product:hover {
  transform: translate(-2px, -2px);
  box-shadow: var(--cv-shadow-hover);
}

li.wc-block-product .wc-block-components-product-image {
  margin: 0;
  border-bottom: var(--cv-border);
}
li.wc-block-product .wc-block-components-product-image img {
  display: block;
  width: 100%;
  height: auto;
  aspect-ratio: 1;
  object-fit: cover;
  object-position: center;
  /* Card radius minus the 3px border, so the picture follows the frame. */
  border-radius: 13px 13px 0 0;
}

li.wc-block-product .wp-block-post-title {
  margin: 0;
  padding: 12px 16px 10px;
  font-family: var(--cv-font-body);
  font-weight: 800;
  font-size: 17px;
  line-height: 1.25;
  text-align: left;
}
li.wc-block-product .wp-block-post-title a {
  color: var(--cv-blue);
  text-decoration: none;
}

li.wc-block-product .wp-block-woocommerce-product-price {
  margin: 0;
  padding: 0 16px;
  text-align: left;
}
/* The archive template gives the Price block the "small" preset, and
   WordPress prints that preset class with !important. Newer Woo puts
   the class on the outer wrapper, older Woo (the live site) on this
   inner element, where it beat the size below. !important on both so
   the price is 24px whichever element carries the preset. */
li.wc-block-product .wp-block-woocommerce-product-price,
li.wc-block-product .wc-block-components-product-price {
  font-family: var(--cv-font-display);
  font-size: 24px !important;
  color: var(--cv-blue);
}

/* Button pinned to the bottom, sized as the design's in-card button. */
li.wc-block-product .wc-block-components-product-button {
  margin: 12px 16px 0;
  text-align: left;
}
li.wc-block-product .wc-block-components-product-button .wp-block-button__link {
  font-family: var(--cv-font-body);
  font-weight: 900;
  font-size: 13px;
  text-transform: uppercase;
  letter-spacing: .05em;
  background: var(--cv-blue);
  color: var(--cv-paper);
  border: var(--cv-border);
  border-radius: 12px;
  box-shadow: 3px 3px 0 0 rgba(26, 26, 31, .22);
  padding: 8px 16px;
  transition: transform var(--cv-dur-fast), box-shadow var(--cv-dur-fast);
}
li.wc-block-product .wc-block-components-product-button .wp-block-button__link:hover {
  transform: translate(-2px, -2px);
  box-shadow: 5px 5px 0 0 rgba(26, 26, 31, .22);
}
/* "View cart" link Woo appends after an add. */
li.wc-block-product a.added_to_cart {
  display: inline-block;
  margin: 8px 16px 0;
  font-weight: 800;
  font-size: 13px;
  color: var(--cv-blue-deep);
}

/* The age sits on the cover, top-right, as the design draws it — not in
   a row under it. Positioned against the card, whose first child is the
   square cover, so 10px from the card's corner is 10px from the
   picture's corner. */
.cv-card__age {
  position: absolute;
  top: 10px;
  right: 10px;
  z-index: 2;
  color: var(--cv-ink);
  font-size: 12px;
  padding: 1px 10px;
  white-space: nowrap;
}

/* -------------------------------------------------------------
   8e. PRODUCT PAGE — gallery and buy panel

   A deliberately small pass: the cover and its thumbnails get the
   outlined, shadowed treatment the rest of the site uses, and the
   price / quantity / add-to-cart / reassurance block becomes one
   panel. Everything else on the page is left as WooCommerce renders
   it.
   ------------------------------------------------------------- */
/* The frame goes on the slider's viewport, not the image. FlexSlider
   gives .flex-viewport overflow:hidden, so a border and an offset shadow
   on the <img> inside it get cut off on the right and bottom — which is
   exactly how it looked. Framing the viewport puts the outline around
   the whole thing and lets the shadow fall outside it. */
.woocommerce div.product .woocommerce-product-gallery .flex-viewport {
  border: var(--cv-border);
  border-radius: var(--cv-radius-lg);
  box-shadow: 8px 8px 0 0 rgba(26, 26, 31, .22);
}
.woocommerce div.product .flex-viewport .woocommerce-product-gallery__image img {
  border: 0;
  border-radius: 0;
  box-shadow: none;
  display: block;
}
/* Single-image products have no slider, so the frame stays on the image. */
.woocommerce div.product .woocommerce-product-gallery__image img {
  border: var(--cv-border);
  border-radius: var(--cv-radius-lg);
  box-shadow: 8px 8px 0 0 rgba(26, 26, 31, .22);
  display: block;
}
/* The zoom overlay Woo lays over the cover would sit on top of the
   border, so it takes the same radius. */
.woocommerce div.product .woocommerce-product-gallery__trigger {
  border-radius: var(--cv-radius-pill);
}

/* The gallery column is a flex column, so the hint can be ordered under
   the thumbnails FlexSlider appends at runtime. */
.woocommerce div.product div.images {
  display: flex;
  flex-direction: column;
}
.woocommerce div.product div.images .flex-viewport { order: 1; }
.woocommerce div.product div.images .flex-control-thumbs { order: 2; }
.woocommerce div.product div.images .cv-gallery-hint { order: 3; }

/* Thumbnails: small outlined squares on one row.

   Woo sets ".woocommerce div.product div.images .flex-control-thumbs li"
   to width:25%;float:left at (0,4,2), and adds clear:left to every 4n+1
   child at (0,5,2) — which is what forced four per line with the rest
   wrapping. Both are matched here rather than outranked. */
.woocommerce div.product div.images .flex-control-thumbs {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
  margin: 14px 0 0;
  padding: 0;
  list-style: none;
  float: none;
  overflow: visible;
}
.woocommerce div.product div.images .flex-control-thumbs li {
  width: auto;
  margin: 0;
  float: none;
  list-style: none;
}
.woocommerce div.product .woocommerce-product-gallery--columns-3 .flex-control-thumbs li:nth-child(3n+1),
.woocommerce div.product .woocommerce-product-gallery--columns-4 .flex-control-thumbs li:nth-child(4n+1),
.woocommerce div.product .woocommerce-product-gallery--columns-5 .flex-control-thumbs li:nth-child(5n+1) {
  clear: none;
}
.woocommerce div.product div.images .flex-control-thumbs img {
  width: 76px;
  height: 76px;
  object-fit: cover;
  border: var(--cv-border-thin);
  border-radius: 10px;
  box-shadow: none;
  opacity: 1;
  cursor: pointer;
  transition: transform var(--cv-dur-fast);
}
.woocommerce div.product div.images .flex-control-thumbs img:hover,
.woocommerce div.product div.images .flex-control-thumbs img.flex-active {
  transform: translate(-1px, -1px);
  opacity: 1;
}

.woocommerce div.product .woocommerce-product-gallery { margin-bottom: 12px; }

.cv-gallery-hint {
  font-family: var(--cv-font-comic);
  font-size: 17px;
  color: var(--cv-blue-deep);
  margin: 12px 0 0;
}

/* The buy panel. */
.cv-buy-panel {
  background: #F5F1E6;
  border: var(--cv-border);
  border-radius: 16px;
  padding: 22px 24px;
  margin: 22px 0 0;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 20px;
}
.woocommerce div.product .cv-buy-panel p.price {
  margin: 0;
  font-family: var(--cv-font-display);
  font-size: 44px;
  line-height: 1;
  color: var(--cv-blue);
}
.cv-buy-panel form.cart {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 20px;
  flex: 1 1 auto;
  margin: 0;
}

/* Quantity: one outlined box with the buttons inside it. */
.woocommerce div.product .cv-buy-panel .quantity {
  display: flex;
  align-items: center;
  border: var(--cv-border);
  border-radius: 12px;
  background: var(--cv-paper);
  overflow: hidden;
}
.woocommerce div.product .cv-buy-panel .quantity input.qty {
  width: 46px;
  height: 44px;
  border: 0;
  background: none;
  font-family: var(--cv-font-body);
  font-weight: 900;
  font-size: 17px;
  color: var(--cv-blue);
  text-align: center;
}
.woocommerce div.product .cv-buy-panel .quantity input[type=number]::-webkit-outer-spin-button,
.woocommerce div.product .cv-buy-panel .quantity input[type=number]::-webkit-inner-spin-button {
  -webkit-appearance: none;
  margin: 0;
}
.woocommerce div.product .cv-buy-panel .quantity input.qty { -moz-appearance: textfield; }

.woocommerce div.product .cv-buy-panel button.single_add_to_cart_button {
  flex: 1 1 auto;
  min-width: 220px;
  margin: 0;
}

/* Stripe's express buttons (Apple Pay, Google Pay) render inside form.cart,
   at woocommerce_after_add_to_cart_button — so they arrive as flex items in
   the quantity/add-to-cart row, where they are squeezed to ~100px and pushed
   out past the panel's right border. Giving the container its own full-width
   row puts them under the button, which is where the plugin assumes they are.
   Only one ever shows: Apple Pay in Safari, Google Pay in Chrome; the plugin
   hides the other with an inline display:none. */
.cv-buy-panel .wc-stripe-product-checkout-container {
  flex: 1 1 100%;
  margin: 0;
}
.cv-buy-panel .wc_stripe_product_payment_methods {
  display: flex;
  flex-direction: column;
  gap: 10px;
  margin: 0;
  padding: 0;
}

/* Reassurance lines sit under the row, full width of the panel. */
.cv-reassurance {
  flex: 1 1 100%;
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 6px;
}
.cv-reassurance li {
  display: flex;
  align-items: center;
  gap: 8px;
  margin: 0;
  font-weight: 700;
  font-size: 14px;
  color: var(--cv-blue);
}
.cv-reassurance img { height: 13px; width: auto; flex: none; }

@media (max-width: 600px) {
  .woocommerce div.product .cv-buy-panel button.single_add_to_cart_button { min-width: 100%; }
}

/* -------------------------------------------------------------
   8b. SHOP ARCHIVE FURNITURE — breadcrumb, count, sorting, categories
   ------------------------------------------------------------- */
.woocommerce-breadcrumb {
  font-weight: 800;
  font-size: 13px;
  letter-spacing: .06em;
  text-transform: uppercase;
  color: var(--cv-blue-deep);
  margin: 0 0 18px;
}
.woocommerce-result-count {
  font-weight: 700;
  font-size: 14px;
  color: var(--cv-blue-deep);
  margin: 0;
}

/* Native select, given the same outline the buttons have. */
.woocommerce .woocommerce-ordering select {
  font-family: var(--cv-font-body);
  font-weight: 800;
  font-size: 14px;
  color: var(--cv-blue);
  background: var(--cv-paper);
  border: var(--cv-border-thin);
  border-radius: var(--cv-radius-sm);
  padding: 8px 12px;
  cursor: pointer;
}

/* The filter column, collapsible on phones.

   functions.php gives the column .cv-filters and wraps the "Filtrer"
   heading's text in .cv-filters__toggle. On wide screens the button is
   invisible as a button: it inherits the heading's type and does nothing
   you can see. Below 781px, where WordPress stacks the columns, the
   column collapses to that one bar, the sort row and the products follow
   straight after, and a tap opens the lists in place. */
.cv-filters__toggle {
  display: inline;
  font: inherit;
  color: inherit;
  background: none;
  border: 0;
  padding: 0;
  margin: 0;
  cursor: default;
  text-align: left;
}
@media (max-width: 781px) {
  /* The template's inline 100px top padding lined the column up with the
     product grid beside it; stacked, it is just a hole under the title. */
  .cv-filters { padding: 0 !important; }
  .cv-filters > :not(.cv-filters__title) { display: none; }
  .cv-filters.is-open > :not(.cv-filters__title) { display: revert; }
  .cv-filters__title { margin: 0 0 16px; }
  .cv-filters.is-open .cv-filters__title { margin-bottom: 8px; }
  .cv-filters__toggle {
    display: flex;
    align-items: center;
    justify-content: space-between;
    width: 100%;
    padding: 10px 14px;
    font-family: var(--cv-font-body);
    font-weight: 800;
    font-size: 14px;
    color: var(--cv-blue);
    background: var(--cv-paper);
    border: var(--cv-border-thin);
    border-radius: var(--cv-radius-sm);
    cursor: pointer;
  }
  /* Chevron: a corner of a box, turned. Same drawing as the sort select
     beside it, so the two controls read as a pair. */
  .cv-filters__toggle::after {
    content: "";
    width: 8px;
    height: 8px;
    margin-right: 4px;
    border-right: 2px solid currentColor;
    border-bottom: 2px solid currentColor;
    transform: translateY(-2px) rotate(45deg);
    transition: transform var(--cv-dur-fast);
  }
  .cv-filters__toggle[aria-expanded="true"]::after {
    transform: translateY(2px) rotate(-135deg);
  }
  .cv-filters.is-open { margin-bottom: 8px; }
}

/* The category filter list: a plain stack of links, no bullets.

   The block nests a real <ul> inside the parent's <li>, marked
   --depth-0 / --depth-1, so the hierarchy is in the DOM. Zeroing padding
   on every list flattened it, and with "Pétaroo" and "Thérébentine"
   appearing under both BD and Albums de Coloriage, a flat list gave no
   way to tell the two pairs apart. Children are indented behind a soft
   guide line instead of restoring browser bullets — same information,
   in the same visual language as the rest of the filter. */
.wc-block-product-categories-list {
  list-style: none;
  margin: 0;
  padding: 0;
}
.wc-block-product-categories-list li { margin: 0; }

/* Any nested list, not only depth-1, so a third level would follow. */
.wc-block-product-categories-list .wc-block-product-categories-list {
  margin: 2px 0 6px 7px;
  padding-left: 14px;
  border-left: 2px solid var(--cv-blue-light);
}
/* Children read as subordinate: lighter and a shade smaller. */
.wc-block-product-categories-list .wc-block-product-categories-list a {
  font-weight: 700;
  font-size: 14px;
}
.wc-block-product-categories-list a {
  display: inline-block;
  padding: 5px 0;
  font-weight: 800;
  font-size: 15px;
  color: var(--cv-blue);
  text-decoration: none;
}
.wc-block-product-categories-list a:hover {
  color: var(--cv-blue-deep);
  text-decoration: underline;
  text-decoration-thickness: 2px;
  text-underline-offset: 3px;
}
.wc-block-product-categories-list-item-count {
  color: var(--cv-mute);
  font-weight: 700;
}

/* The age filter, sitting under the category list in the same panel.

   WooCommerce's own Product Filters block set, driven by ?filter_pa_age
   through WC_Query's layered nav — no custom query code, so a Woo major
   update has nothing of ours to break. Only the skin is ours, and it is
   matched to the category list directly above it so the two read as one
   filter panel rather than two plugins stacked.

   Two of Woo's own rules have to be answered rather than skinned over.

   The options sit in a <fieldset>. Woo flattens it with
   `.wc-block-product-filter-checkbox-list fieldset { display: contents }`,
   but that class only exists in the editor — the front end renders the
   wrapper as `.wp-block-woocommerce-product-filter-checkbox-list`, so the
   rule never matches and the browser's own fieldset border and 0.75em
   padding survive. That was the frame drawn around the ages, and the
   reason they sat a notch to the right of the categories above them.
   Zeroed here rather than set to `display: contents`, which drops the
   fieldset and its legend out of the accessibility tree.

   And Woo writes the box as `input[type=checkbox].…__input` — a type and
   an attribute ahead of the class. A bare class selector loses to that
   however late this stylesheet loads, so the house outline is written at
   the same weight, and so is the tick, which Woo pins with `svg.…__mark`. */
.wc-block-product-filter-checkbox-list fieldset,
.wp-block-woocommerce-product-filter-checkbox-list fieldset {
  margin: 0;
  padding: 0;
  border: 0;
  min-width: 0;
}
.wc-block-product-filter-checkbox-list__items {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 2px;
}
.wc-block-product-filter-checkbox-list__item {
  display: flex;
  align-items: center;
  padding: 4px 0;
  margin: 0;
}
/* 8px, with the 15px box, puts the age labels at the same left edge as the
   sub-category links above — see the note on the box below. */
.wc-block-product-filter-checkbox-list__label {
  display: flex;
  align-items: center;
  gap: 8px;
  cursor: pointer;
  font-weight: 800;
  font-size: 15px;
  color: var(--cv-blue);
}
.wc-block-product-filter-checkbox-list__label:hover {
  color: var(--cv-blue-deep);
}
/* Woo shrinks the text to .875em inside the label; the categories above
   are at full size, so hand it back. */
.wc-block-product-filter-checkbox-list__text-wrapper {
  font-size: 1em;
  gap: 6px;
}
.wc-block-product-filter-checkbox-list__count {
  color: var(--cv-mute);
  font-weight: 700;
  font-size: 14px;
}

/* The box: blue, not ink, and 15px rather than 19px.

   Ink at 19px made the control the heaviest thing in a panel that is
   otherwise blue text and one hairline guide — the checkbox shouted louder
   than the ages it filters. The house outline is right everywhere it frames
   content; at the scale of a form control in a quiet sidebar it is not.
   Blue at 2px keeps it in the panel's own family and still reads as drawn
   rather than as a browser default.

   The size is doing alignment work as well. At 15px with an 8px gap the
   label text lands on 133px — the same left edge as "Mamie Odevie" and
   "Pétaroo" under their parents. The panel had three left edges (110 for
   the top-level categories, 133 for their children, 138 for the ages);
   it now has two, and the ages sit on an edge that already existed.

   They are not hung out in the left margin, which is what would put the
   labels flush with "Pack" and "BD". Measured, that needs the boxes at
   87px — 23px outside the panel's own left edge, past "Filtrer" and both
   headings, with nothing to align to and the viewport edge to worry about
   on a narrow screen. That trades a small misalignment for a louder one.

   Woo draws its own tick as a separate __mark element, so the input only
   has to carry the box and the fill. */
.wc-block-product-filter-checkbox-list__input-wrapper {
  position: relative;
  display: inline-flex;
  flex: 0 0 auto;
}
/* Woo's placeholder square — currentColor at 10% — sits behind the box
   and shows past its corners. */
.wc-block-product-filter-checkbox-list__input-wrapper::before {
  content: none;
}
input[type="checkbox"].wc-block-product-filter-checkbox-list__input {
  appearance: none;
  -webkit-appearance: none;
  width: 15px;
  height: 15px;
  margin: 0;
  border: 2px solid var(--cv-blue);
  border-radius: 4px;
  background: var(--cv-paper);
  cursor: pointer;
  transition: background-color var(--cv-dur-fast) ease,
              border-color var(--cv-dur-fast) ease;
}
.wc-block-product-filter-checkbox-list__label:hover
  input[type="checkbox"].wc-block-product-filter-checkbox-list__input {
  border-color: var(--cv-blue-deep);
}
input[type="checkbox"].wc-block-product-filter-checkbox-list__input:checked {
  background: var(--cv-blue);
  border-color: var(--cv-blue);
}
/* Keyboard users get a ring the mouse never shows. Offset so it sits
   outside the box rather than crowding the 2px outline. */
input[type="checkbox"].wc-block-product-filter-checkbox-list__input:focus-visible {
  outline: 2px solid var(--cv-blue-deep);
  outline-offset: 2px;
}
svg.wc-block-product-filter-checkbox-list__mark {
  position: absolute;
  inset: 0;
  width: 15px;
  height: 15px;
  padding: 2px;
  color: var(--cv-paper);
  pointer-events: none;
}
@media ( prefers-reduced-motion: reduce ) {
  input[type="checkbox"].wc-block-product-filter-checkbox-list__input {
    transition: none;
  }
}

/* -------------------------------------------------------------
   8d. CART DRAWER

   The mini cart's panel is rendered by WooCommerce's script, so there is
   no markup of ours to hang classes on — everything here targets Woo's
   own block classes. The design draws it as a paper panel with a 3px ink
   edge, outlined rows, and the site's buttons.
   ------------------------------------------------------------- */
.wc-block-components-drawer {
  background: var(--cv-paper);
  border-left: var(--cv-border);
}
.wc-block-components-drawer__content { background: var(--cv-paper); }

/* Header: Ranchers title, outlined square close button.

   Written as h2.wc-block-mini-cart__title because that is how WooCommerce
   writes it, and a bare class loses to it. Woo's rule is not just cosmetic:
   it insets the title 16px, pulls it -32px into the items below, and masks
   its own bottom 24px to transparent so the list appears to scroll under a
   sticky header. All three had to go — the mask was quietly erasing the ink
   border, and the negative margin dragged the shipping bar up into the
   title. */
h2.wc-block-mini-cart__title {
  font-family: var(--cv-font-display);
  font-weight: 400;
  font-size: 32px;
  color: var(--cv-blue);
  padding: 20px 24px;
  margin: 0;
  mask-image: none;
  border-bottom: var(--cv-border);
}
/* Woo styles this button as
     .wc-block-components-button.wc-block-components-drawer__close
   at (0,2,0), with !important on background, colour, padding and
   position. A single-class rule here lost every property except the one
   carrying !important — which is why it rendered as an empty outlined
   box. Matching the two-class shape, and keeping Woo's own placement. */
.wc-block-components-button.wc-block-components-drawer__close {
  border: 0;
  opacity: 1;
  color: var(--cv-blue) !important;
  margin: 0;
  padding: 7px !important;
  top: 18px;
  right: 20px;
}
.wc-block-components-button.wc-block-components-drawer__close svg {
  fill: currentColor;
  width: 20px;
  height: 20px;
}

/* The free-shipping progress bar, between the drawer title and the items.

   Ours, not WooCommerce's — cv-* markup rendered by the theme into the mini
   cart's title block, so unlike the rest of this section the selectors here
   cannot be moved out from under us by a Woo release. The figure comes from
   the shipping settings via cv_tt3_free_shipping_threshold(). */
.cv-ship-bar {
  padding: 16px 24px 18px;
  border-bottom: 1px solid var(--cv-cream);
}
.cv-ship-bar__label {
  margin: 0 0 10px;
  font-weight: 800;
  font-size: 15px;
  line-height: 1.3;
  color: var(--cv-blue);
}
.cv-ship-bar__track {
  height: 14px;
  border-radius: var(--cv-radius-pill);
  background: var(--cv-cream);
  overflow: hidden;
}
.cv-ship-bar__fill {
  display: block;
  height: 100%;
  min-width: 14px;
  border-radius: var(--cv-radius-pill);
  background: var(--cv-green);
  transition: width var(--cv-dur-base) ease;
}
/* Arrived: the sentence turns green with the bar rather than staying blue,
   so the state reads at a glance without a second element to explain it. */
.cv-ship-bar.is-complete .cv-ship-bar__label {
  color: var(--cv-green);
}
@media ( prefers-reduced-motion: reduce ) {
  .cv-ship-bar__fill { transition: none; }
}

/* No box per line. An outlined row plus an outlined thumbnail plus the
   drawer's own edge stacked three frames inside each other and read as
   clutter; spacing separates the lines well enough on its own. */
.wc-block-mini-cart-items .wc-block-cart-items__row {
  border: 0;
  padding: 10px 2px;
  background: none;
}
.wc-block-mini-cart-items .wc-block-cart-item__wrap {
  border: 0;
  padding: 0;
  background: none;
}

/* The design shows each line's price once, under the title. Woo also
   prints a line total on the right, which repeated it. */
.wc-block-mini-cart-items .wc-block-cart-item__total { display: none; }

/* Two actions side by side: "voir mon panier" as the ghost button, and
   checkout as the buy button. The design draws one, but Woo's pair is
   the better shopping flow, so the pair stays and takes the site's two
   button treatments instead.

   Woo's outline style is guarded as
     .wc-block-components-button:not(.is-link).is-style-outline:not(:focus)
   at (0,4,0) — hence the matching four-unit selectors below rather than
   anything shorter. */
.wc-block-mini-cart__footer-actions {
  display: flex;
  gap: 12px;
}
.wc-block-mini-cart__footer-actions > * { flex: 1 1 0; }

.wc-block-components-button.wc-block-mini-cart__footer-cart.is-style-outline:not(:focus),
.wc-block-components-button.wc-block-mini-cart__footer-cart:not(:focus) {
  background: var(--cv-paper);
  color: var(--cv-blue);
  border: var(--cv-border);
  border-radius: var(--cv-radius);
  box-shadow: none;
  padding: 15px 18px;
  font-family: var(--cv-font-body);
  font-weight: 900;
  font-size: 14px;
  text-transform: uppercase;
  letter-spacing: .05em;
}
.wc-block-components-button.wc-block-mini-cart__footer-cart.is-style-outline:hover,
.wc-block-components-button.wc-block-mini-cart__footer-cart:hover {
  background: var(--cv-cream);
  color: var(--cv-blue-deep);
  opacity: 1;
}
.wc-block-cart-item__image img {
  width: 56px;
  height: 56px;
  object-fit: cover;
  border: var(--cv-border-thin);
  border-radius: 8px;
}
/* Woo sets this at
     table.wc-block-cart-items .wc-block-cart-items__row .wc-block-components-product-name
   — (0,3,1), font-weight 500. Four classes and an element to answer it. */
.wc-block-mini-cart__items table.wc-block-cart-items .wc-block-cart-items__row .wc-block-components-product-name,
.wc-block-mini-cart__items .wc-block-cart-item__product .wc-block-components-product-name {
  font-weight: 800;
  font-size: 14.5px;
  line-height: 1.2;
  color: var(--cv-blue);
  text-decoration: none;
}
.wc-block-mini-cart__items .wc-block-components-product-name:hover {
  text-decoration: underline;
}

/* The design's line shows title, price and quantity — not the product's
   whole short description, which is what Woo puts here by default and
   what made the panel read like a different site. */
.wc-block-components-product-metadata__description { display: none; }

.wc-block-cart-item__prices .wc-block-components-product-price,
.wc-block-components-product-price {
  font-weight: 700;
  font-size: 13px;
  color: var(--cv-blue-deep);
}

/* Quantity stepper: outlined squares either side of the count. */
.wc-block-components-quantity-selector {
  border: var(--cv-border-thin);
  border-radius: 8px;
  background: var(--cv-paper);
}
.wc-block-components-quantity-selector__button {
  color: var(--cv-blue);
  font-weight: 900;
  opacity: 1;
}
.wc-block-components-quantity-selector__input {
  font-weight: 900;
  font-size: 14px;
  color: var(--cv-blue);
}
.wc-block-cart-item__remove-link {
  color: var(--cv-red);
  font-weight: 900;
  text-decoration: none;
}

/* Footer: label against a Ranchers total, then the red buy button. */
.wc-block-components-totals-item {
  font-weight: 800;
  font-size: 15px;
  color: var(--cv-blue);
}
.wc-block-components-totals-footer-item .wc-block-components-totals-item__value,
.wc-block-components-totals-item__value {
  font-family: var(--cv-font-display);
  font-weight: 400;
  font-size: 34px;
  color: var(--cv-blue);
}
.wc-block-components-button.wc-block-mini-cart__footer-checkout {
  justify-content: center;
  background: var(--cv-red);
  color: var(--cv-paper);
  border: var(--cv-border);
  border-radius: var(--cv-radius);
  box-shadow: var(--cv-shadow);
  padding: 15px 24px;
  font-family: var(--cv-font-body);
  font-weight: 900;
  font-size: 15px;
  text-transform: uppercase;
  letter-spacing: .05em;
  transition: transform var(--cv-dur-fast), box-shadow var(--cv-dur-fast);
}
.wc-block-components-button.wc-block-mini-cart__footer-checkout:hover {
  transform: translate(-2px, -2px);
  box-shadow: var(--cv-shadow-hover);
}

/* -------------------------------------------------------------
   8f. FORMS — Everest Forms

   The contact form, and anything else built with the same plugin. Its
   markup is plain: input.input-text for every field, a label wrapping
   .evf-label, and button.evf-submit. The design's input is a paper box
   with the same ink outline everything else has.
   ------------------------------------------------------------- */
.everest-forms .evf-field { margin-bottom: 20px; }

.everest-forms .evf-field-label { display: block; margin-bottom: 6px; }
.everest-forms .evf-label {
  font-family: var(--cv-font-body);
  font-weight: 800;
  font-size: 14px;
  color: var(--cv-blue);
}
.everest-forms .evf-field-label abbr.required {
  color: var(--cv-red);
  border: 0;
  text-decoration: none;
  margin-left: 2px;
}

.everest-forms input.input-text,
.everest-forms textarea.input-text,
.everest-forms select {
  width: 100%;
  box-sizing: border-box;
  /* Not paper: the page is already paper, so a field in the same colour
     reads as a hole rather than an input. */
  background: #F5F1E6;
  color: var(--cv-blue);
  border: var(--cv-border);
  border-radius: 12px;
  padding: 12px 16px;
  font-family: var(--cv-font-body);
  font-weight: 700;
  font-size: 15px;
  line-height: 1.4;
  outline: none;
  transition: border-color var(--cv-dur-fast), box-shadow var(--cv-dur-fast);
}
.everest-forms textarea.input-text {
  min-height: 160px;
  resize: vertical;
}
.everest-forms input.input-text::placeholder,
.everest-forms textarea.input-text::placeholder { color: var(--cv-mute); }

.everest-forms input.input-text:focus,
.everest-forms textarea.input-text:focus,
.everest-forms select:focus {
  border-color: var(--cv-blue);
  box-shadow: 3px 3px 0 0 rgba(26, 26, 31, .22);
}

/* The submit button is the buy button: this is the page's one action.

   Everest ships
     .wp-block-everest-forms-form-selector button.button:not(.button-large)
   at (0,3,1), setting background:0 0 and color:#555 — which is why this
   rendered as a grey system button:

     .everest-forms button.button:not(.button-large)         (0,3,1)
     .everest-forms button.button:not(.button-large):hover   (0,4,1)  #eee

   Its :not(.button-large) is what makes those numbers awkward — the argument
   counts. Borrowing the same guard here adds a class we already satisfy and
   puts us one ahead of the plugin in both states, so the win comes from
   specificity rather than load order. That matters: production runs LiteSpeed,
   which combines stylesheets and may not preserve the order a tie relies on.

   The hover rule must restate background and colour. An earlier version set
   only transform and box-shadow, so the plugin's hover repainted the button
   grey while the border, radius and shadow stayed ours. */
.wp-block-everest-forms-form-selector button.button.evf-submit:not(.button-large),
.everest-forms button.button.evf-submit:not(.button-large),
.everest-forms .evf-submit-container button.evf-submit:not(.button-large) {
  background: var(--cv-red);
  color: var(--cv-paper);
  border: var(--cv-border);
  border-radius: var(--cv-radius);
  box-shadow: var(--cv-shadow);
  padding: 14px 26px;
  font-family: var(--cv-font-body);
  font-weight: 900;
  font-size: 15px;
  text-transform: uppercase;
  letter-spacing: .05em;
  cursor: pointer;
  transition: transform var(--cv-dur-fast), box-shadow var(--cv-dur-fast);
}
.wp-block-everest-forms-form-selector button.button.evf-submit:not(.button-large):hover,
.wp-block-everest-forms-form-selector button.button.evf-submit:not(.button-large):focus,
.everest-forms button.button.evf-submit:not(.button-large):hover,
.everest-forms button.button.evf-submit:not(.button-large):focus {
  background: var(--cv-red);
  color: var(--cv-paper);
  transform: translate(-2px, -2px);
  box-shadow: var(--cv-shadow-hover);
}
.wp-block-everest-forms-form-selector button.button.evf-submit:not(.button-large):active,
.everest-forms button.button.evf-submit:not(.button-large):active {
  background: var(--cv-red);
  color: var(--cv-paper);
  transform: translate(5px, 5px);
  box-shadow: var(--cv-shadow-press);
}

/* Validation and confirmation, in the palette rather than plugin defaults. */
.everest-forms .evf-error,
.everest-forms label.evf-error {
  color: var(--cv-red);
  font-weight: 800;
  font-size: 13px;
  margin-top: 6px;
  display: block;
}
.everest-forms input.input-text.evf-error,
.everest-forms textarea.input-text.evf-error { border-color: var(--cv-red); }

.everest-forms-notice--success,
.evf-confirmation-container {
  background: var(--cv-paper);
  border: var(--cv-border);
  border-left: 8px solid var(--cv-green);
  border-radius: var(--cv-radius);
  box-shadow: var(--cv-shadow);
  padding: 16px 20px;
  font-weight: 700;
  color: var(--cv-blue);
}

/* The honeypot must stay hidden whatever the field styling says. */
.everest-forms .evf-honeypot-container { display: none !important; }

/* -------------------------------------------------------------
   9b. FOOTER — interim colours only

   The footer is still the v0.2 markup and is due to be rebuilt to the
   design. It paints itself with palette slugs that no longer exist:
   "black", "dark" and "textondark" are not in theme.json and, unlike
   base / contrast / primary and the rest, section 10's shim does not
   define them either. So those classes resolve to nothing, the text
   falls back to whatever it inherits, and the headings pick up the
   global heading colour — deep blue on near-black, which is the
   unreadable result on screen.

   This section only makes the footer legible on its dark ground. It is
   deliberately shallow: no layout, no spacing, nothing that would have
   to be unpicked when the footer is rebuilt properly. Delete it then.
   ------------------------------------------------------------- */
footer.wp-block-template-part {
  background: var(--cv-ink);
  color: var(--cv-cream);
}
footer.wp-block-template-part h1,
footer.wp-block-template-part h2,
footer.wp-block-template-part h3,
footer.wp-block-template-part h4,
footer.wp-block-template-part h5,
footer.wp-block-template-part h6,
footer.wp-block-template-part .cv-title {
  color: var(--cv-paper);
}
footer.wp-block-template-part p,
footer.wp-block-template-part li,
footer.wp-block-template-part td {
  color: var(--cv-cream);
}
/* Links carry the paper colour rather than the site blue, which is
   unreadable here. (0,1,2) beats the (0,1,1) that WordPress emits for
   the group's own link-colour support. */
footer.wp-block-template-part a {
  color: var(--cv-paper);
  text-decoration-thickness: 1px;
  text-underline-offset: 3px;
}
footer.wp-block-template-part a:hover {
  color: var(--cv-blue-light);
}
/* Separators and any rule lines, so they read on the dark ground. */
footer.wp-block-template-part hr,
footer.wp-block-template-part .wp-block-separator {
  border-color: var(--cv-mute);
  opacity: .45;
}

/* -------------------------------------------------------------
   10. LEGACY PALETTE SHIM — not part of the original design spec.
   Added during implementation to protect existing content.

   The v0.2 palette (base / contrast / primary / secondary /
   tertiary / highlight / odevie) no longer exists in theme.json.
   WordPress only emits .has-{slug}-color rules for palette
   entries that still exist, so the existing posts and pages that
   carry those classes would otherwise render with no colour rule
   at all, silently falling back to inherited colour.

   These declarations reproduce the v0.2 hex values exactly, so
   legacy content keeps looking as it does today. Migrate content
   to the cv-* palette at your own pace, then delete this section.
   ------------------------------------------------------------- */
:root {
  --wp--preset--color--base:      #f3f3f1;
  --wp--preset--color--contrast:  #015EA1;
  --wp--preset--color--primary:   #2184F9;
  --wp--preset--color--secondary: #E90000;
  --wp--preset--color--tertiary:  #2ADB32;
  --wp--preset--color--highlight: #FF9800;
  --wp--preset--color--odevie:    #696CFF;
}

/* The rest of the live v0.2 palette, recovered 2026-08-25 from the
   wp_global_styles entry in ../archives/cv-content.xml.

   The block above was reconstructed from cv-tt3 v0.2's theme.json, which
   turned out to be the wrong source: the site stored a user global-styles
   palette as "palette":{"theme":[…]}, and that replaces the theme's own
   palette outright. These sixteen slugs were live and none of them were
   shimmed, so every piece of legacy content using them — the whole
   footer among it — has been falling back to inherited colour.

   "black" is not from that palette; it is a WordPress core default that
   theme.json's "defaultPalette": false removed. */
:root {
  --wp--preset--color--accent:            #de1414;   /* Accented Color */
  --wp--preset--color--accentbg:          #41474c;   /* Accented Dark Background */
  --wp--preset--color--accenttwo:         #00d084;   /* Accented Secondary */
  --wp--preset--color--button:            #ffd800;   /* Accented Buttons */
  --wp--preset--color--textonbutton:      #010101;   /* Text over buttons */
  --wp--preset--color--dark:              #000001;   /* Dark panels (footer, header) */
  --wp--preset--color--textondark:        #fffffe;   /* Text on dark panels */
  --wp--preset--color--textonprimary:     #fffffd;   /* Text over primary */
  --wp--preset--color--inputbg:           #fafbfd;   /* Input background */
  --wp--preset--color--inputtext:         #444444;   /* Input text */
  --wp--preset--color--lightbg:           #f9fafb;   /* Accented Light Background */
  --wp--preset--color--lightborder:       #cecece6b;   /* Borders, dividers */
  --wp--preset--color--lightgrey:         #6f8099;   /* Light grey, meta text */
  --wp--preset--color--lighttag:          #94fe5226;   /* Tag colour */
  --wp--preset--color--lightsecondarytag: #b952fe26;   /* Secondary tag colour */
  --wp--preset--color--price:             #444444;   /* Price colour (WooCommerce) */
  --wp--preset--color--black:             #000000;   /* WordPress core default, removed by defaultPalette:false */
}

.has-accent-color { color: var(--wp--preset--color--accent); }
.has-accent-background-color { background-color: var(--wp--preset--color--accent); }
.has-accentbg-color { color: var(--wp--preset--color--accentbg); }
.has-accentbg-background-color { background-color: var(--wp--preset--color--accentbg); }
.has-accenttwo-color { color: var(--wp--preset--color--accenttwo); }
.has-accenttwo-background-color { background-color: var(--wp--preset--color--accenttwo); }
.has-button-color { color: var(--wp--preset--color--button); }
.has-button-background-color { background-color: var(--wp--preset--color--button); }
.has-textonbutton-color { color: var(--wp--preset--color--textonbutton); }
.has-textonbutton-background-color { background-color: var(--wp--preset--color--textonbutton); }
.has-dark-color { color: var(--wp--preset--color--dark); }
.has-dark-background-color { background-color: var(--wp--preset--color--dark); }
.has-textondark-color { color: var(--wp--preset--color--textondark); }
.has-textondark-background-color { background-color: var(--wp--preset--color--textondark); }
.has-textonprimary-color { color: var(--wp--preset--color--textonprimary); }
.has-textonprimary-background-color { background-color: var(--wp--preset--color--textonprimary); }
.has-inputbg-color { color: var(--wp--preset--color--inputbg); }
.has-inputbg-background-color { background-color: var(--wp--preset--color--inputbg); }
.has-inputtext-color { color: var(--wp--preset--color--inputtext); }
.has-inputtext-background-color { background-color: var(--wp--preset--color--inputtext); }
.has-lightbg-color { color: var(--wp--preset--color--lightbg); }
.has-lightbg-background-color { background-color: var(--wp--preset--color--lightbg); }
.has-lightborder-color { color: var(--wp--preset--color--lightborder); }
.has-lightborder-background-color { background-color: var(--wp--preset--color--lightborder); }
.has-lightgrey-color { color: var(--wp--preset--color--lightgrey); }
.has-lightgrey-background-color { background-color: var(--wp--preset--color--lightgrey); }
.has-lighttag-color { color: var(--wp--preset--color--lighttag); }
.has-lighttag-background-color { background-color: var(--wp--preset--color--lighttag); }
.has-lightsecondarytag-color { color: var(--wp--preset--color--lightsecondarytag); }
.has-lightsecondarytag-background-color { background-color: var(--wp--preset--color--lightsecondarytag); }
.has-price-color { color: var(--wp--preset--color--price); }
.has-price-background-color { background-color: var(--wp--preset--color--price); }
.has-black-color { color: var(--wp--preset--color--black); }
.has-black-background-color { background-color: var(--wp--preset--color--black); }

.has-base-color      { color: var(--wp--preset--color--base); }
.has-contrast-color  { color: var(--wp--preset--color--contrast); }
.has-primary-color   { color: var(--wp--preset--color--primary); }
.has-secondary-color { color: var(--wp--preset--color--secondary); }
.has-tertiary-color  { color: var(--wp--preset--color--tertiary); }
.has-highlight-color { color: var(--wp--preset--color--highlight); }
.has-odevie-color    { color: var(--wp--preset--color--odevie); }

.has-base-background-color      { background-color: var(--wp--preset--color--base); }
.has-contrast-background-color  { background-color: var(--wp--preset--color--contrast); }
.has-primary-background-color   { background-color: var(--wp--preset--color--primary); }
.has-secondary-background-color { background-color: var(--wp--preset--color--secondary); }
.has-tertiary-background-color  { background-color: var(--wp--preset--color--tertiary); }
.has-highlight-background-color { background-color: var(--wp--preset--color--highlight); }
.has-odevie-background-color    { background-color: var(--wp--preset--color--odevie); }

.has-base-border-color      { border-color: var(--wp--preset--color--base); }
.has-contrast-border-color  { border-color: var(--wp--preset--color--contrast); }
.has-primary-border-color   { border-color: var(--wp--preset--color--primary); }
.has-secondary-border-color { border-color: var(--wp--preset--color--secondary); }
.has-tertiary-border-color  { border-color: var(--wp--preset--color--tertiary); }
.has-highlight-border-color { border-color: var(--wp--preset--color--highlight); }
.has-odevie-border-color    { border-color: var(--wp--preset--color--odevie); }

/* The v0.2 gradient, still referenced by older Cover/Group blocks */
.has-primary-to-secondary-gradient-background {
  background: linear-gradient(160deg, #2184F9, #E90000);
}
