@charset "UTF-8";
/* ==========================================================================
   des trucs des choses

   Concept: the shop files its miscellany like a museum inventory. Everything
   is numbered; the catalogue reference is set larger than the product name,
   which is the joke and also the navigation. Discipline everywhere else so
   the product photography carries the page.

   Palette (all pairs checked against WCAG AA):
     ground  #DCE1E4   card #FFFFFF   ink   #141C2B
     accent  #1F4FD8   stamp #E3A21A  rule  #8A9099   dim #5C646E
   Accent on white 6.4:1 · accent on ground 4.9:1 · dim on white 6.0:1
   · ink on stamp 7.7:1. Buy button is white on accent, 6.4:1.
   ========================================================================== */

/* --------------------------------------------------------------- fonts -- */

@font-face {
  font-family: 'Archivo';
  src: url('/assets/fonts/archivo-latin.woff2') format('woff2');
  font-weight: 600 700;
  font-stretch: 110% 125%;
  font-style: normal;
  font-display: swap;
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA,
    U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193,
    U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'Archivo';
  src: url('/assets/fonts/archivo-latinext.woff2') format('woff2');
  font-weight: 600 700;
  font-stretch: 110% 125%;
  font-style: normal;
  font-display: swap;
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF,
    U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020,
    U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family: 'Plex';
  src: url('/assets/fonts/plex-latin.woff2') format('woff2');
  font-weight: 400 600;
  font-style: normal;
  font-display: swap;
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA,
    U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193,
    U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'Plex';
  src: url('/assets/fonts/plex-latinext.woff2') format('woff2');
  font-weight: 400 600;
  font-style: normal;
  font-display: swap;
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF,
    U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020,
    U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

/* --------------------------------------------------------------- tokens -- */

/* These are fallbacks. theme.json is the real source, and build.js writes it
   out as theme.css, which loads after this file and overrides everything
   below. The values are kept here so this stylesheet still renders correctly
   on its own — open site.css in isolation and the shop is not colourless. */

:root {
  --ground: #DCE1E4;
  --card: #FFFFFF;
  --ink: #141C2B;
  --accent: #1F4FD8;
  --accent-deep: #163AA2;
  --stamp: #E3A21A;
  --rule: #8A9099;
  --dim: #5C646E;
  /* Secondary text on the ink cover — 7.8:1 against #141C2B. */
  --on-ink-dim: #A7B0BA;

  --display: 'Archivo', 'Helvetica Neue', Arial, sans-serif;
  --body: 'Plex', ui-sans-serif, system-ui, 'Segoe UI', Roboto, sans-serif;

  /* An index-card corner: neither square nor pill. */
  --radius: 3px;

  --gap: 1.5rem;
  --pad: clamp(1rem, 4vw, 2.5rem);
  /* One content box for the masthead, the page and the footer. Every band
     that spans the window sets this max-width and this padding on the same
     border-box, so their contents share a left and right edge. */
  --wrap: 84rem;
  --rail-w: 13.5rem;
  --measure: 34rem;
}

/* ---------------------------------------------------------------- reset -- */

*, *::before, *::after { box-sizing: border-box; }

html {
  -webkit-text-size-adjust: 100%;
  scroll-behavior: smooth;
}

body {
  margin: 0;
  background: var(--ground);
  color: var(--ink);
  font-family: var(--body);
  font-size: 1rem;
  line-height: 1.55;
  font-variant-numeric: tabular-nums;
  -webkit-font-smoothing: antialiased;
}

img { max-width: 100%; height: auto; display: block; }

/* Any explicit `display` beats the UA's [hidden] rule, which would leave the
   empty cart badge and the hidden cart panels visible. Keep this above the
   components that set display. */
[hidden] { display: none !important; }

a { color: var(--accent); text-underline-offset: 0.18em; }
a:hover { color: var(--accent-deep); }

h1, h2, h3 {
  font-family: var(--display);
  font-weight: 700;
  font-stretch: 118%;
  line-height: 1.1;
  letter-spacing: -0.005em;
  margin: 0;
}

button { font: inherit; }

/* Keyboard focus must always be obvious. Never remove without replacing. */
:focus-visible {
  outline: 3px solid var(--accent);
  outline-offset: 3px;
  border-radius: 1px;
}

.visually-hidden {
  position: absolute;
  width: 1px; height: 1px;
  padding: 0; margin: -1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
  border: 0;
}

.skip {
  position: absolute;
  left: -9999px;
  top: 0;
  z-index: 100;
  background: var(--ink);
  color: #fff;
  padding: 0.75rem 1rem;
  text-decoration: none;
}
.skip:focus {
  left: 0;
  color: #fff;
}

/* ---------------------------------------------------------------- strip -- */
/* Three facts a buyer would otherwise have to hunt for. Not a slogan. */

.strip {
  margin: 0;
  padding: 0.5rem var(--pad);
  background: var(--ink);
  color: var(--on-ink-dim);
  font-size: 0.75rem;
  text-align: center;
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 0.4rem 0.75rem;
}
.strip__item { white-space: nowrap; }
.strip__sep { color: var(--rule); }

/* ------------------------------------------------------------- masthead -- */

/* The rule runs edge to edge; the name and the nav sit on the same content
   box as .shell below, so the shop name lines up with the page's left edge
   and the cart link with its right. Same max-width, same padding, same
   border-box — anything else drifts apart as the window widens. */
.masthead {
  border-bottom: 2px solid var(--ink);
}

.masthead__inner {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 1rem;
  flex-wrap: wrap;
  padding: 1.1rem var(--pad);
  max-width: var(--wrap);
  margin: 0 auto;
}

.masthead__name {
  font-family: var(--display);
  font-weight: 700;
  font-stretch: 125%;
  font-size: 1.0625rem;
  letter-spacing: 0.02em;
  color: var(--ink);
  text-decoration: none;
}
.masthead__name:hover { color: var(--accent); }

.masthead__nav {
  display: flex;
  gap: 1.5rem;
  font-size: 0.875rem;
}
.masthead__nav a {
  color: var(--ink);
  text-decoration: none;
  border-bottom: 1px solid transparent;
  padding-bottom: 2px;
}
.masthead__nav a:hover { border-bottom-color: var(--accent); color: var(--accent); }

.masthead__count {
  display: inline-block;
  min-width: 1.35em;
  margin-left: 0.4em;
  padding: 0.05em 0.3em;
  background: var(--ink);
  color: #fff;
  border-radius: var(--radius);
  font-size: 0.8125rem;
  text-align: center;
}

/* ----------------------------------------------------------------- rail -- */
/* The signature element: the whole catalogue, numbered, on every page. */

.shell {
  display: grid;
  grid-template-columns: var(--rail-w) minmax(0, 1fr);
  gap: clamp(1.5rem, 4vw, 3.5rem);
  padding: var(--pad);
  max-width: var(--wrap);
  margin: 0 auto;
  align-items: start;
}

.rail {
  position: sticky;
  top: var(--pad);
  font-size: 0.8125rem;
}

.rail__title {
  font-family: var(--display);
  font-weight: 600;
  font-stretch: 125%;
  font-size: 0.6875rem;
  letter-spacing: 0.13em;
  text-transform: uppercase;
  color: var(--dim);
  margin: 0 0 0.6rem;
}

.rail__list {
  list-style: none;
  margin: 0;
  padding: 0;
  border-top: 1px solid var(--rule);
}

.rail__row {
  display: block;
  padding: 0.55rem 0.35rem;
  color: var(--ink);
  text-decoration: none;
  border-bottom: 1px solid rgba(138, 144, 153, 0.35);
}
.rail__row:hover {
  background: var(--card);
  color: var(--ink);
}
.rail__name {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.rail__row.is-current {
  background: var(--ink);
  color: #fff;
}

/* On the home page the index waits until you reach the selection, where a
   column of catalogue numbers becomes navigation rather than decoration.
   Keyed off the `js` class set in <head>, so it is hidden from the first
   paint — hiding it from a script afterwards would flash it on screen first.
   With scripting off the class is never set and the index is simply there. */
.js .page-home .rail {
  opacity: 0;
  visibility: hidden;
  transform: translateY(-0.5rem);
  transition: opacity 0.45s ease, transform 0.45s ease, visibility 0s linear 0.45s;
}
.js .page-home .rail.is-revealed {
  opacity: 1;
  visibility: visible;
  transform: none;
  transition: opacity 0.45s ease, transform 0.45s ease, visibility 0s;
}

/* ----------------------------------------------------------------- main -- */

.main { min-width: 0; }

.head { margin-bottom: 2.5rem; }

.head__title {
  font-size: clamp(1.75rem, 4.5vw, 2.75rem);
  font-stretch: 125%;
}

.head__lede {
  margin: 0.9rem 0 0;
  max-width: var(--measure);
  font-size: 1.0625rem;
  color: var(--dim);
}

/* ---------------------------------------------------------------- cover -- */
/* The home page opens like the cover of the catalogue rather than like a
   page of text. On a phone this is the whole first screen, so it has to say
   what the shop is, how big it is, and where to go next — without scrolling. */

.cover {
  background: var(--ink);
  color: var(--ground);
  border-radius: var(--radius);
  padding: clamp(1.5rem, 6vw, 3rem);
  margin-bottom: 2.5rem;
}

.cover__eyebrow {
  margin: 0 0 1.25rem;
  font-family: var(--display);
  font-weight: 600;
  font-stretch: 125%;
  font-size: 0.6875rem;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--stamp);
}

.cover__title {
  font-size: clamp(2rem, 8vw, 3.25rem);
  font-stretch: 125%;
  line-height: 1.04;
  letter-spacing: -0.015em;
  max-width: 16ch;
  color: var(--ground);
}

.cover__lede {
  margin: 1.1rem 0 0;
  max-width: 38ch;
  font-size: 1.0625rem;
  color: var(--on-ink-dim);
}

.cover__actions { margin: 1.75rem 0 0; }

/* Navigation, not an action — so it stays out of the accent-blue vocabulary
   that "Ajouter au panier" and "Payer" own. */
.btn--cover {
  background: var(--ground);
  color: var(--ink);
  border-color: var(--ground);
}
.btn--cover:hover { background: var(--stamp); border-color: var(--stamp); color: var(--ink); }

.cover__meta {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 1rem;
  margin: 2rem 0 0;
  padding-top: 1.1rem;
  border-top: 1px solid rgba(220, 225, 228, 0.28);
}
/* Numbers stay on one baseline even if a label wraps to two lines. */
.cover__cell {
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  height: 100%;
}
.cover__cell dt {
  font-family: var(--display);
  font-weight: 600;
  font-stretch: 125%;
  font-size: 0.625rem;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--on-ink-dim);
}
.cover__cell dd {
  margin: 0.3rem 0 0;
  font-family: var(--display);
  font-weight: 700;
  font-stretch: 118%;
  font-size: clamp(1rem, 4.2vw, 1.25rem);
  white-space: nowrap;
  color: var(--ground);
}

.head__meta {
  margin: 0.5rem 0 0;
  font-size: 0.8125rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--dim);
}

.head__actions { margin: 1.5rem 0 0; }

.section { margin-top: 3rem; }

.section__title {
  font-size: 0.6875rem;
  font-weight: 600;
  font-stretch: 125%;
  letter-spacing: 0.13em;
  text-transform: uppercase;
  color: var(--dim);
  padding-bottom: 0.6rem;
  border-bottom: 1px solid var(--rule);
  margin-bottom: 1.5rem;
}

.section__more { margin-top: 1.75rem; font-size: 0.9375rem; }

/* The home page has no page-level sidebar, so the hero, the trust row and the
   closing blocks run the full width and stay centred. The index belongs to
   the selection alone: it begins with the products and ends with them.
   The cart has no sidebar either — it is the end of the browsing path. */
.page-home .shell,
.page-cart .shell { grid-template-columns: minmax(0, 1fr); }

.selection__body { display: grid; }
.selection__main { min-width: 0; }

@media (min-width: 48.0625rem) {
  .selection__body {
    grid-template-columns: var(--rail-w) minmax(0, 1fr);
    gap: clamp(1.5rem, 4vw, 3.5rem);
    align-items: start;
  }
  /* Six selected items land as two clean rows of three, rather than a row of
     four with two gaps beside it. */
  .page-home .grid { grid-template-columns: repeat(3, minmax(0, 1fr)); }
  .page-home .section__more { display: flex; justify-content: center; }
  .page-home .section__more .btn { min-width: 18rem; text-align: center; }
}

/* ---------------------------------------------------------------- trust -- */

.trust {
  list-style: none;
  margin: 0 0 3rem;
  padding: 0;
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(13rem, 1fr));
  gap: 1px;
  background: var(--rule);
  border: 1px solid var(--rule);
  border-radius: var(--radius);
  overflow: hidden;
}
.trust__item {
  display: flex;
  align-items: flex-start;
  gap: 0.7rem;
  padding: 1rem 1.1rem;
  background: var(--card);
}
.mark { flex: none; color: var(--accent); margin-top: 0.1rem; }
.trust__text { display: block; }
.trust__title {
  display: block;
  font-weight: 600;
  font-size: 0.875rem;
}
.trust__sub {
  display: block;
  margin-top: 0.1rem;
  font-size: 0.8125rem;
  color: var(--dim);
}

/* -------------------------------------------------------------- filters -- */

.filters {
  display: flex;
  flex-wrap: wrap;
  gap: 0.4rem;
  margin-bottom: 1.75rem;
}
.filters__tab {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  padding: 0.45rem 0.85rem;
  border: 1px solid var(--rule);
  border-radius: var(--radius);
  background: var(--card);
  color: var(--ink);
  text-decoration: none;
  font-size: 0.875rem;
  font-weight: 500;
}
.filters__tab:hover { border-color: var(--ink); color: var(--ink); }
.filters__tab.is-active {
  background: var(--ink);
  border-color: var(--ink);
  color: #fff;
}
.filters__count {
  font-size: 0.75rem;
  color: var(--dim);
  font-variant-numeric: tabular-nums;
}
.filters__tab.is-active .filters__count { color: var(--stamp); }

/* --------------------------------------------------------------- crumbs -- */

.crumbs {
  display: flex;
  flex-wrap: wrap;
  gap: 0.4rem;
  margin-bottom: 1.5rem;
  font-size: 0.8125rem;
  color: var(--dim);
}
.crumbs a { color: var(--dim); }
.crumbs a:hover { color: var(--accent); }

/* ----------------------------------------------------------------- grid -- */

.grid {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(13rem, 1fr));
  gap: var(--gap);
}

.card { position: relative; }

.card__link {
  display: flex;
  flex-direction: column;
  background: var(--card);
  border-radius: var(--radius);
  padding: 0.75rem;
  color: var(--ink);
  text-decoration: none;
  height: 100%;
  border: 1px solid transparent;
  transition: transform 0.15s ease, box-shadow 0.15s ease, border-color 0.15s ease;
}
.card__link:hover {
  transform: translateY(-2px);
  box-shadow: 0 6px 18px rgba(20, 28, 43, 0.13);
  border-color: rgba(20, 28, 43, 0.14);
  color: var(--ink);
}

.card__frame {
  display: block;
  background: var(--ground);
  border-radius: 2px;
  overflow: hidden;
  aspect-ratio: 4 / 5;
}
.card__img { width: 100%; height: 100%; object-fit: cover; }

/* Body grows so that price and stock sit on a common baseline across a row,
   however long the names and descriptions above them run. */
.card__body {
  display: flex;
  flex-direction: column;
  flex: 1;
  margin-top: 0.7rem;
}
.card__name {
  font-weight: 600;
  font-size: 0.9375rem;
  line-height: 1.3;
}
.card__desc {
  display: -webkit-box;
  -webkit-line-clamp: 2;
  line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
  margin-top: 0.25rem;
  font-size: 0.8125rem;
  line-height: 1.4;
  color: var(--dim);
}
.card__meta {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: 0.6rem;
  margin-top: auto;
  padding-top: 0.6rem;
}
.card__price {
  white-space: nowrap;
  font-weight: 600;
  font-size: 0.9375rem;
}
.card__stock {
  font-size: 0.75rem;
  white-space: nowrap;
  color: var(--dim);
}
.card__stock--low { color: #8A5A00; font-weight: 500; }
.card__stock--out { color: var(--dim); }

/* ------------------------------------------------------------------ tag -- */

.tag {
  position: absolute;
  top: 0.75rem;
  right: 0.75rem;
  font-family: var(--display);
  font-weight: 600;
  font-stretch: 125%;
  font-size: 0.625rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  padding: 0.2rem 0.42rem;
  border-radius: 2px;
  pointer-events: none;
}
.tag--digital { background: var(--stamp); color: var(--ink); }

/* Inside prose the tag sits inline rather than pinned to a card corner. */
.note .tag {
  position: static;
  display: inline-block;
  margin-right: 0.5rem;
}

/* -------------------------------------------------------------- product -- */

.product {
  display: grid;
  grid-template-columns: minmax(0, 1.35fr) minmax(0, 1fr);
  gap: clamp(1.5rem, 4vw, 3rem);
  align-items: start;
}

.gallery { display: grid; gap: 0.75rem; }

/* Several images become a carousel rather than a column. The track is a plain
   scroll container that snaps, so a phone swipes it with scripts off; the
   arrows and the dots are the same gesture for a mouse, and stay hidden until
   site.js is there to make them do something. */
.gallery--carousel { position: relative; display: block; }

.gallery__track {
  display: flex;
  gap: 0.75rem;
  overflow-x: auto;
  scroll-snap-type: x mandatory;
  scroll-behavior: smooth;
  overscroll-behavior-x: contain;
  scrollbar-width: none;
}
.gallery__track::-webkit-scrollbar { display: none; }

.gallery--carousel .shot {
  flex: 0 0 100%;
  scroll-snap-align: center;
}

.gallery__arrow {
  position: absolute;
  top: 50%;
  transform: translateY(-50%);
  display: none;
  width: 2.25rem;
  height: 2.25rem;
  padding: 0;
  place-items: center;
  border: 1px solid var(--rule);
  border-radius: 50%;
  background: #fff;
  color: var(--ink);
  cursor: pointer;
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.12);
}
.js .gallery--carousel .gallery__arrow { display: grid; }
.gallery__arrow:hover { border-color: var(--ink); }
.gallery__arrow[disabled] {
  opacity: 0.3;
  cursor: default;
  box-shadow: none;
}
.gallery__arrow--prev { left: 0.5rem; }
.gallery__arrow--next { right: 0.5rem; }

.gallery__dots {
  display: none;
  justify-content: center;
  gap: 0.15rem;
  margin-top: 0.35rem;
}
.js .gallery--carousel .gallery__dots { display: flex; }
.gallery__dot {
  width: 1.5rem;
  height: 1.5rem;
  padding: 0;
  border: 0;
  background: none;
  cursor: pointer;
  display: grid;
  place-items: center;
}
.gallery__dot::before {
  content: '';
  width: 0.45rem;
  height: 0.45rem;
  border-radius: 50%;
  border: 1px solid var(--dim);
}
.gallery__dot.is-current::before {
  background: var(--ink);
  border-color: var(--ink);
}

.shot {
  margin: 0;
  background: var(--card);
  border-radius: var(--radius);
  padding: 0.75rem;
}
.shot img {
  width: 100%;
  border-radius: 2px;
}

.product__panel { position: sticky; top: var(--pad); }

.product__name {
  font-size: clamp(1.75rem, 3.6vw, 2.5rem);
  font-stretch: 118%;
  margin-bottom: 0.4rem;
}

.product__price {
  font-size: 1.25rem;
  font-weight: 500;
  margin: 0;
}

.product__vat {
  margin: 0.15rem 0 0;
  font-size: 0.75rem;
  color: var(--dim);
}

.product__desc {
  margin: 1.1rem 0 0;
  max-width: var(--measure);
}

.product__buy { margin: 1.5rem 0 0; }

.note {
  margin: 1.5rem 0 0;
  padding: 0.85rem 1rem;
  background: var(--card);
  border-radius: var(--radius);
  border-left: 3px solid var(--accent);
  font-size: 0.875rem;
  max-width: var(--measure);
}

.product__long { margin-top: 2rem; }

.soldout {
  margin: 0;
  font-weight: 500;
  color: var(--dim);
}

.addstatus {
  margin: 0.7rem 0 0;
  min-height: 1.4em;
  font-size: 0.875rem;
  color: var(--accent-deep);
}

.stockline {
  margin: 1rem 0 0;
  font-size: 0.8125rem;
  color: var(--dim);
}
.stockline::before {
  content: '';
  display: inline-block;
  width: 0.45rem;
  height: 0.45rem;
  border-radius: 50%;
  background: var(--dim);
  margin-right: 0.45rem;
  vertical-align: 0.05em;
}
.stockline--low { color: #8A5A00; }
.stockline--low::before { background: var(--stamp); }
.stockline--out::before { background: var(--rule); }

.buyrow {
  display: flex;
  align-items: stretch;
  gap: 0.6rem;
  flex-wrap: wrap;
}
.buyrow__qty {
  display: flex;
  align-items: center;
  gap: 0.45rem;
  padding: 0 0.6rem;
  border: 1px solid var(--rule);
  border-radius: var(--radius);
  background: #fff;
}
.buyrow__qtylabel {
  font-size: 0.75rem;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--dim);
}
.buyrow .qty { width: 3.25rem; border: 0; padding: 0.55rem 0; }
.buyrow .qty:focus-visible { outline-offset: 1px; }
.buyrow .btn--buy { flex: 1; min-width: 12rem; }

/* -------------------------------------------------------------- details -- */

.details {
  margin-top: 1.5rem;
  border-top: 1px solid var(--rule);
  max-width: var(--measure);
}
.details__item { border-bottom: 1px solid var(--rule); }
.details__summary {
  cursor: pointer;
  padding: 0.8rem 1.75rem 0.8rem 0;
  position: relative;
  font-weight: 600;
  font-size: 0.9375rem;
  list-style: none;
}
.details__summary::-webkit-details-marker { display: none; }
.details__summary::after {
  content: '';
  position: absolute;
  right: 0.35rem;
  top: 50%;
  width: 0.5rem;
  height: 0.5rem;
  border-right: 1.5px solid var(--dim);
  border-bottom: 1.5px solid var(--dim);
  transform: translateY(-70%) rotate(45deg);
  transition: transform 0.15s ease;
}
.details__item[open] .details__summary::after { transform: translateY(-30%) rotate(-135deg); }
.details__body {
  padding: 0 0 1rem;
  font-size: 0.875rem;
  color: var(--dim);
}
.details__body p { margin: 0; }

/* ------------------------------------------------------- custom orders -- */
/* A service, not a product — so it sits outside the grid and looks it. */

.custom {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  align-items: center;
  gap: clamp(1.5rem, 4vw, 3rem);
  margin: 3rem 0;
  padding: clamp(1.5rem, 4vw, 2.5rem);
  background: var(--card);
  border: 1px solid var(--rule);
  border-left: 4px solid var(--stamp);
  border-radius: var(--radius);
}
.custom__eyebrow {
  margin: 0 0 0.6rem;
  font-family: var(--display);
  font-weight: 600;
  font-stretch: 125%;
  font-size: 0.6875rem;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: #8A5A00;
}
.custom__title {
  font-size: clamp(1.375rem, 3.2vw, 1.875rem);
  font-stretch: 118%;
  margin-bottom: 0.6rem;
}
.custom__text {
  margin: 0;
  max-width: 46ch;
  color: var(--dim);
}
.custom__points {
  list-style: none;
  margin: 1rem 0 0;
  padding: 0;
  display: flex;
  flex-wrap: wrap;
  gap: 0.4rem 1.25rem;
  font-size: 0.875rem;
}
.custom__points li { position: relative; padding-left: 1rem; }
.custom__points li::before {
  content: '';
  position: absolute;
  left: 0;
  top: 0.55em;
  width: 0.45rem;
  height: 0.45rem;
  background: var(--stamp);
  border-radius: 1px;
}
.custom__actions {
  display: flex;
  align-items: center;
  gap: 1rem;
  flex-wrap: wrap;
  margin: 1.5rem 0 0;
}
.custom__meta { font-size: 0.8125rem; color: var(--dim); }
.custom__figure { color: var(--rule); opacity: 0.75; }
.custom__figure svg { width: clamp(7rem, 14vw, 11rem); height: auto; }

/* ---------------------------------------------------------------- steps -- */

.steps { margin: 3rem 0 0; }
.steps__list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(15rem, 1fr));
  gap: 1px;
  background: var(--rule);
  border: 1px solid var(--rule);
  border-radius: var(--radius);
  overflow: hidden;
}
.steps__item { background: var(--card); padding: 1.25rem 1.25rem 1.4rem; }
.steps__num {
  margin: 0 0 0.5rem;
  font-family: var(--display);
  font-weight: 700;
  font-stretch: 125%;
  font-size: 1.5rem;
  color: var(--stamp);
  line-height: 1;
}
.steps__head {
  font-size: 1rem;
  font-stretch: 110%;
  margin-bottom: 0.35rem;
}
.steps__text {
  margin: 0;
  font-size: 0.875rem;
  color: var(--dim);
}

.section--related { margin-top: 3.5rem; }

/* --------------------------------------------------------------- button -- */

.btn {
  display: inline-block;
  font-family: var(--display);
  font-weight: 600;
  font-stretch: 118%;
  font-size: 0.9375rem;
  letter-spacing: 0.01em;
  padding: 0.72rem 1.35rem;
  border-radius: var(--radius);
  border: 2px solid transparent;
  cursor: pointer;
  text-decoration: none;
  transition: background-color 0.15s ease, color 0.15s ease;
}

/* White on accent: 6.4:1. */
.btn--buy {
  background: var(--accent);
  color: #fff;
  border-color: var(--accent);
}
.btn--buy:hover { background: var(--accent-deep); border-color: var(--accent-deep); color: #fff; }
.btn--buy[disabled] { background: var(--dim); border-color: var(--dim); cursor: default; }

.btn--ghost {
  background: transparent;
  color: var(--ink);
  border-color: var(--ink);
}
.btn--ghost:hover { background: var(--ink); color: #fff; }

/* ----------------------------------------------------------------- cart -- */

.cart__table {
  width: 100%;
  border-collapse: collapse;
  background: var(--card);
  border-radius: var(--radius);
  overflow: hidden;
  font-size: 0.9375rem;
}

.cart__table th,
.cart__table td {
  padding: 0.8rem 0.75rem;
  text-align: left;
  border-bottom: 1px solid rgba(138, 144, 153, 0.3);
  vertical-align: middle;
}

.cart__table thead th {
  font-family: var(--display);
  font-weight: 600;
  font-stretch: 125%;
  font-size: 0.6875rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--dim);
}

.cart__table .num { text-align: right; }
.cart__table tbody tr:last-child td { border-bottom: 0; }

.cart__item { display: flex; align-items: center; gap: 0.75rem; }
.cart__thumb {
  width: 3rem;
  aspect-ratio: 4 / 5;
  object-fit: cover;
  border-radius: 2px;
  background: var(--ground);
  flex: none;
}
.cart__itemname { color: var(--ink); text-decoration: none; font-weight: 500; }
.cart__itemname:hover { color: var(--accent); }
.cart__itemtype {
  display: block;
  font-size: 0.75rem;
  color: var(--dim);
}

.qty {
  width: 4.25rem;
  padding: 0.35rem 0.45rem;
  font: inherit;
  font-variant-numeric: tabular-nums;
  text-align: right;
  border: 1px solid var(--rule);
  border-radius: 2px;
  background: #fff;
  color: var(--ink);
}

.remove {
  background: none;
  border: 0;
  padding: 0.35rem;
  color: var(--dim);
  cursor: pointer;
  text-decoration: underline;
  font-size: 0.8125rem;
}
.remove:hover { color: var(--ink); }

.cart__foot {
  margin-top: 1.75rem;
  display: grid;
  gap: 0.9rem;
  justify-items: start;
  max-width: 26rem;
}

.totals { margin: 0; width: 100%; }
.totals__row {
  display: flex;
  justify-content: space-between;
  gap: 1rem;
  padding: 0.4rem 0;
}
.totals__row dt, .totals__row dd { margin: 0; }
.totals__row--grand {
  border-top: 2px solid var(--ink);
  margin-top: 0.3rem;
  padding-top: 0.6rem;
  font-size: 1.125rem;
  font-weight: 600;
}

.cart__note, .cart__terms {
  margin: 0;
  font-size: 0.8125rem;
  color: var(--dim);
}
.cart__note:empty { display: none; }

.cart__free {
  color: var(--ink);
  background: var(--stamp);
  border-radius: 2px;
  padding: 0.1rem 0.35rem;
  font-weight: 500;
}

.cart__error {
  margin: 0;
  padding: 0.75rem 1rem;
  background: #fff;
  border-left: 3px solid #B3261E;
  border-radius: var(--radius);
  color: #7A1A15;
  font-size: 0.875rem;
}

.cart__dropped, .notice {
  margin: 0 0 1.25rem;
  padding: 0.75rem 1rem;
  background: var(--card);
  border-left: 3px solid var(--stamp);
  border-radius: var(--radius);
  font-size: 0.875rem;
}

.cart__empty p { margin: 0 0 1rem; }

/* Wherever the cart is still a table, the numbers take the width they need and
   no more, so the article — the one column with something to say — keeps the
   rest instead of leaving a metre of gap before the price. */
@media (min-width: 48.0625rem) {
  .cart__table th.num,
  .cart__table td.num { width: 1%; white-space: nowrap; }
}

/* On a wide screen the cart is two things side by side: the list of what you
   are buying, and the receipt. Full width, the table stretched four numbers
   across a metre of screen and left the totals stranded underneath with half
   the page empty beside them.

   The summary is the narrow column on the right, where a receipt goes, and it
   sticks as the list scrolls so the total and the pay button stay in view. */
@media (min-width: 60rem) {
  .cart__filled {
    display: grid;
    /* The receipt is as narrow as it can be read at, so the list keeps the
       width — a cramped article column is what makes a cart look broken. */
    grid-template-columns: minmax(0, 1fr) clamp(15rem, 24vw, 20rem);
    gap: clamp(1.5rem, 3vw, 2.5rem);
    align-items: start;
  }
  .cart__dropped { grid-column: 1 / -1; }

  .cart__foot {
    position: sticky;
    top: var(--pad);
    margin-top: 0;
    max-width: none;
    justify-items: stretch;
    gap: 0.75rem;
    padding: 1.25rem;
    background: var(--card);
    border-radius: var(--radius);
  }
  .cart__cta { width: 100%; }
  .cart__foot .btn--buy { width: 100%; }
  .cart__foot .cart__free { display: inline-block; }
}

/* ---------------------------------------------------------------- prose -- */

.prose { max-width: var(--measure); }
.prose > * + * { margin-top: 1.1rem; }
.prose h2 {
  font-size: 1.1875rem;
  font-stretch: 118%;
  margin-top: 2.25rem;
}
.prose h3 { font-size: 1rem; font-stretch: 110%; margin-top: 1.75rem; }
.prose p, .prose li { color: var(--ink); }
.prose ul, .prose ol { padding-left: 1.25rem; }
.prose li + li { margin-top: 0.4rem; }
.prose code {
  background: var(--card);
  padding: 0.1em 0.35em;
  border-radius: 2px;
  font-size: 0.9em;
}
.thanks { max-width: var(--measure); }

/* --------------------------------------------------------------- footer -- */

/* Same content box as the masthead and .shell — see --wrap. The padding sits
   on .foot and the inner blocks subtract it from the max-width, rather than
   the other way round, so the hairline rule above the copyright line ends
   where the columns end instead of running a padding wider than them. */
.foot {
  border-top: 2px solid var(--ink);
  margin-top: 4.5rem;
  padding: 2.5rem var(--pad) 2rem;
}
.foot p { margin: 0; }

.foot__cols {
  max-width: calc(var(--wrap) - var(--pad) * 2);
  margin: 0 auto;
  display: grid;
  grid-template-columns: 1.6fr repeat(3, 1fr);
  gap: 2rem;
}

.foot__mark {
  font-family: var(--display);
  font-weight: 700;
  font-stretch: 125%;
  font-size: 1rem;
}
.foot__blurb {
  margin-top: 0.5rem;
  max-width: 28ch;
  font-size: 0.875rem;
  color: var(--dim);
}
.foot__pay { margin-top: 1.1rem; }
.foot__paylabel {
  display: block;
  font-family: var(--display);
  font-weight: 600;
  font-stretch: 125%;
  font-size: 0.625rem;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--dim);
}
.foot__paylist {
  display: block;
  margin-top: 0.2rem;
  font-size: 0.8125rem;
}

.foot__head {
  font-family: var(--display);
  font-weight: 600;
  font-stretch: 125%;
  font-size: 0.625rem;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--dim);
  padding-bottom: 0.6rem;
  border-bottom: 1px solid var(--rule);
}
.foot__list {
  list-style: none;
  margin: 0.7rem 0 0;
  padding: 0;
  font-size: 0.875rem;
}
.foot__list li + li { margin-top: 0.45rem; }
.foot__list a { color: var(--ink); text-decoration: none; }
.foot__list a:hover { color: var(--accent); text-decoration: underline; }

.foot__base {
  max-width: calc(var(--wrap) - var(--pad) * 2);
  margin: 2.5rem auto 0;
  padding-top: 1.1rem;
  border-top: 1px solid var(--rule);
  display: flex;
  flex-wrap: wrap;
  gap: 0.4rem 1.5rem;
  justify-content: space-between;
  font-size: 0.75rem;
  color: var(--dim);
}

/* ----------------------------------------------------------- responsive -- */

@media (max-width: 61rem) {
  /* One column, and the images sit directly under the name — the order you
     read a product in: what it is called, what it looks like, what it costs.
     The panel dissolves into the column with `display: contents` so its
     children can be ordered around the gallery without a second copy of the
     name in the markup. */
  .product {
    display: flex;
    flex-direction: column;
    gap: 0;
  }
  .product__panel { display: contents; }
  .product__panel > * { order: 3; }
  .product__panel > .product__name { order: 1; margin-bottom: 0.75rem; }
  .gallery { order: 2; }
  .product__price { margin-top: 1.1rem; }
}

@media (max-width: 48rem) {
  .shell {
    grid-template-columns: minmax(0, 1fr);
    gap: 1.5rem;
  }

  /* Rail collapses to a horizontal row of category chips. */
  .rail {
    position: static;
    margin: 0 calc(var(--pad) * -1);
    padding: 0 var(--pad);
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
  }
  .rail__title { display: none; }
  .rail__list {
    display: flex;
    gap: 0.4rem;
    border-top: 0;
    padding-bottom: 0.25rem;
  }
  .rail__row {
    border: 1px solid var(--rule);
    border-bottom: 1px solid var(--rule);
    border-radius: var(--radius);
    padding: 0.3rem 0.6rem;
    background: var(--card);
  }
  .rail__row.is-current { border-color: var(--ink); }
  .rail__name { white-space: nowrap; }

  /* No index on the home page at this size. The masthead already carries the
     categories, and a phone has better uses for the space.

     None on the catalogue pages either: the filter bar under the heading is
     the same three links with their counts, and one of them said Tout twice
     on the same screen. The filter bar is the one that stays, because it is
     where the eye already is once the heading has been read. */
  .page-home .rail,
  .page-catalogue .rail { display: none; }

  /* Two products per row. One-up turns six items into six screenfuls, which
     is the difference between browsing a catalogue and scrolling past it. */
  .grid {
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 0.75rem;
  }
  .card__link { padding: 0.5rem; }
  /* Name over price: side by side leaves neither enough room at this width. */
  .card__meta {
    flex-direction: column;
    align-items: flex-start;
    gap: 0.1rem;
    margin-top: 0.55rem;
    font-size: 0.8125rem;
  }
  .card__price { color: var(--ink); }
  .tag { top: 0.5rem; right: 0.5rem; font-size: 0.5625rem; }

  /* Full-width tap target rather than a text link at the end of the list. */
  .btn--wide { display: block; text-align: center; }
  .section__more { margin-top: 1.5rem; }

  /* Keep the masthead on one line so it does not eat the first screen. */
  .masthead__inner {
    flex-wrap: nowrap;
    align-items: center;
    padding-top: 0.9rem;
    padding-bottom: 0.9rem;
    gap: 0.5rem;
  }
  .masthead__name { font-size: 0.9375rem; }
  .masthead__nav { gap: 0.85rem; font-size: 0.8125rem; flex: none; }
  /* The two type links live in the filter bar and the footer on small
     screens; the masthead keeps only the catalogue and the cart. */
  .masthead__nav a[href="/produits/objets/"],
  .masthead__nav a[href="/produits/fichiers/"] { display: none; }

  .strip {
    font-size: 0.6875rem;
    padding: 0.4rem 0.75rem;
    gap: 0.25rem 0.5rem;
  }
  /* One promise is enough on a phone; the rest are on the product pages. */
  .strip__item:not(:first-child),
  .strip__sep { display: none; }

  .trust {
    grid-template-columns: repeat(2, minmax(0, 1fr));
    margin-bottom: 2.5rem;
  }
  .trust__item { padding: 0.8rem 0.75rem; gap: 0.5rem; }
  .trust__title { font-size: 0.8125rem; }
  .trust__sub { font-size: 0.75rem; }

  .custom {
    grid-template-columns: minmax(0, 1fr);
    margin: 2.5rem 0;
  }
  /* The illustration is atmosphere, and atmosphere is what a small screen
     has least room for. */
  .custom__figure { display: none; }
  .custom__points { flex-direction: column; gap: 0.35rem; }
  .custom__actions { gap: 0.6rem; }
  .custom__actions .btn { width: 100%; text-align: center; }

  .steps__item { padding: 1rem; }

  .buyrow .btn--buy { min-width: 0; }

  /* Arrows are for a mouse. A phone swipes the track itself, and the dots
     say how far along it is. */
  .js .gallery--carousel .gallery__arrow { display: none; }

  .foot__cols { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 1.75rem 1.25rem; }
  .foot__col--brand { grid-column: 1 / -1; }
  .foot__base { margin-top: 2rem; }

  /* The table reflows — five columns will not fit a phone — but not into five
     stacked lines either. The article takes the first line, and the numbers
     that go together (quantity, unit price, line total) sit on one line under
     it, with the total right-aligned where a receipt puts it. */
  .cart__table, .cart__table tbody, .cart__table td {
    display: block;
    width: 100%;
  }
  .cart__table thead { display: none; }
  .cart__table tr {
    display: grid;
    grid-template-columns: auto auto minmax(0, 1fr) auto;
    grid-template-areas:
      'item  item  item  item'
      'qty   price total remove';
    align-items: end;
    column-gap: 0.75rem;
    row-gap: 0.6rem;
    border-bottom: 1px solid rgba(138, 144, 153, 0.3);
    padding: 0.9rem 0.75rem;
  }
  .cart__table tbody tr:last-child { border-bottom: 0; }
  .cart__table td {
    border-bottom: 0;
    padding: 0;
    text-align: left;
  }
  .cart__table .num { text-align: left; }

  .cart__table td:nth-child(1) { grid-area: item; }
  .cart__table td:nth-child(2) { grid-area: price; }
  .cart__table td:nth-child(3) { grid-area: qty; }
  .cart__table td:nth-child(4) { grid-area: total; text-align: right; font-weight: 600; }
  .cart__table td:nth-child(5) { grid-area: remove; }

  /* The label rides above its number rather than beside it: four labels and
     four values on one line is what made this cramped in the first place. */
  .cart__table td[data-label]::before {
    content: attr(data-label);
    display: block;
    margin-bottom: 0.15rem;
    font-size: 0.6875rem;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--dim);
  }
  /* The article names itself. */
  .cart__table td:nth-child(1)::before { display: none; }

  .cart__table .qty {
    width: 3.25rem;
    padding: 0.3rem 0.35rem;
    text-align: center;
  }
  .cart__foot { max-width: none; }
}

/* Touch targets stay comfortable on coarse pointers. */
@media (pointer: coarse) {
  .rail__row { padding-top: 0.55rem; padding-bottom: 0.55rem; }
  .remove { padding: 0.55rem; }
}

@media (prefers-reduced-motion: reduce) {
  html, .gallery__track { scroll-behavior: auto; }
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
  }
  .card__link:hover { transform: none; }
}

@media print {
  .rail, .masthead__nav, .foot__nav, .product__buy, .cart__cta { display: none; }
  body { background: #fff; }
}
