/* Vitrine — landing template for local shops.
   Mobile-first. No build step. Every colour comes from a token so a site can be
   re-skinned from its JSON without touching this file. */

:root {
  --primary: #8B1E1E;
  --primary-ink: #FBF5EA;
  --accent: #1E3557;
  --bg: #F2EADB;
  --surface: #E8DCC5;
  --fg: #1D1916;
  --fg-soft: #574A3F;
  --border: #D3C4A8;
  /* Open / closed, sent / failed, and a field in error. Theme tokens since
     2026-09-23: as literals they could not follow a dark palette, and the
     contrast check in render.py could not measure them. */
  --ok: #1E6B34;
  --bad: #9B1C1C;

  --radius: 14px;
  --radius-sm: 9px;
  --btn-radius: 999px;
  --shadow-1: 0 1px 2px rgba(17, 12, 10, .05), 0 1px 3px rgba(17, 12, 10, .04);
  --shadow-2: 0 10px 30px -12px rgba(17, 12, 10, .22);
  --card-shadow: none;

  /* Skins override these. Every value here is what the original single
     template used, so the classique profile needs no skin file at all. */
  --h1: clamp(2.5rem, 11vw, 4.75rem);
  --h1-lh: 1.08;
  --h2: clamp(1.75rem, 6.5vw, 2.6rem);
  --display-weight: 400;
  --display-tracking: -0.015em;
  --body-size: 17px;
  --body-lh: 1.65;
  --sec-pad: 48px;
  --sec-pad-wide: 48px;
  --eyebrow-tracking: .12em;

  --s1: 4px;  --s2: 8px;  --s3: 12px; --s4: 16px;
  --s5: 24px; --s6: 32px; --s7: 48px; --s8: 64px; --s9: 88px;

  --maxw: 1080px;
  --font-display: "Vitrine Display", Georgia, "Times New Roman", serif;
  --font-body: "Vitrine Sans", system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
}

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

html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; }
@media (prefers-reduced-motion: reduce) { html { scroll-behavior: auto; } }

body {
  margin: 0;
  background: var(--bg);
  color: var(--fg);
  font-family: var(--font-body);
  font-size: var(--body-size);
  line-height: var(--body-lh);
  -webkit-font-smoothing: antialiased;
}

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

h1, h2, h3 {
  font-family: var(--font-display);
  font-weight: var(--display-weight);
  line-height: 1.08;
  letter-spacing: var(--display-tracking);
  margin: 0;
}
/* 1.08 is display leading for a one-line h1. Section titles wrap on a phone,
   and at 1.08 two lines of h2 sat 2px apart (fb-0007, back on h2 at the
   2026-09-23 round check). h3 is small enough to need body-ish leading. */
h2 { line-height: 1.15; }
h3 { line-height: 1.25; }

a { color: inherit; }

.wrap { width: 100%; max-width: var(--maxw); margin: 0 auto; padding: 0 var(--s5); }

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

:where(a, button, input, textarea, select):focus-visible {
  outline: 3px solid var(--accent);
  outline-offset: 2px;
  border-radius: 4px;
}

/* ---------- preview ribbon (demo pages only) ---------- */

.preview-note {
  background: #1c1917;
  color: #fafaf9;
  font-size: 14px;
  line-height: 1.45;
  padding: var(--s3) var(--s5);
  text-align: center;
}
.preview-note strong { color: #fde68a; font-weight: 600; }

/* ---------- header ---------- */

.site-head {
  position: sticky; top: 0; z-index: 40;
  background: color-mix(in srgb, var(--bg) 88%, transparent);
  backdrop-filter: blur(10px);
  border-bottom: 1px solid var(--border);
}
.site-head .wrap {
  display: flex; align-items: center; gap: var(--s4);
  min-height: 62px;
}
.brand {
  font-family: var(--font-display);
  font-size: 20px;
  /* It inherited body leading, so "Volaillerie Saint-" / "Vincent" wrapped
     with a paragraph's gap between the two halves of one name. */
  line-height: 1.2;
  letter-spacing: -0.01em;
  text-decoration: none;
  margin-right: auto;
}
.nav { display: none; gap: var(--s5); font-size: 15px; }
.nav a { text-decoration: none; color: var(--fg-soft); padding: var(--s2) 0; }
.nav a:hover { color: var(--fg); }
@media (min-width: 860px) { .nav { display: flex; } }

/* ---------- buttons ---------- */

.btn {
  display: inline-flex; align-items: center; justify-content: center;
  gap: var(--s2);
  min-height: 48px;
  padding: 0 var(--s5);
  border-radius: var(--btn-radius);
  border: 1px solid transparent;
  font: inherit; font-size: 16px; font-weight: 600;
  text-decoration: none;
  cursor: pointer;
  transition: transform .18s ease, background-color .18s ease, box-shadow .18s ease;
}
.btn svg { width: 19px; height: 19px; flex: 0 0 auto; }
.btn:active { transform: scale(.97); }
.btn-primary { background: var(--primary); color: var(--primary-ink); box-shadow: var(--shadow-1); }
.btn-primary:hover { background: color-mix(in srgb, var(--primary) 88%, #000); }
.btn-ghost { background: var(--surface); color: var(--fg); border-color: var(--border); }
.btn-ghost:hover { border-color: color-mix(in srgb, var(--fg) 30%, var(--border)); }
.btn-sm { min-height: 42px; font-size: 15px; padding: 0 var(--s4); }
@media (prefers-reduced-motion: reduce) { .btn { transition: none; } .btn:active { transform: none; } }

/* ---------- hero ---------- */

.hero { padding: var(--s7) 0 var(--s6); }
.hero-grid { display: grid; gap: var(--s6); grid-template-columns: 1fr; align-items: start; }
@media (min-width: 980px) {
  .hero { padding: var(--s8) 0 var(--s7); }
  .hero-grid { grid-template-columns: minmax(0, 1.55fr) minmax(280px, .95fr); gap: var(--s7); }
}

/* The card repeats what the hours section says further down. On a phone that
   would just be a second scroll of the same thing, so it only appears once
   there is a column standing empty next to the headline. */
.hero-card { display: none; }
@media (min-width: 980px) {
  .hero-card {
    display: block;
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    padding: var(--s5);
    box-shadow: var(--shadow-2);
  }
  .hero-card-row { display: flex; gap: var(--s4); margin: 0 0 var(--s4); font-size: 16px; }
  .hero-card-row .k {
    flex: 0 0 92px;
    font-size: 12px; letter-spacing: .09em; text-transform: uppercase;
    font-weight: 600; color: var(--accent); padding-top: 4px;
  }
  .hero-card-row .v { color: var(--fg); font-variant-numeric: tabular-nums; }
  .hero-card-row .v a { text-decoration: none; font-weight: 600; }
  .hero-card .btn { width: 100%; }
}
.hero .eyebrow {
  font-size: 13px; font-weight: 600; letter-spacing: var(--eyebrow-tracking); text-transform: uppercase;
  color: var(--accent); margin: 0 0 var(--s4);
}
.hero h1 {
  font-size: var(--h1); line-height: var(--h1-lh);
  margin-bottom: var(--s4);
}
.hero .lede {
  font-size: clamp(1.06rem, 4vw, 1.3rem);
  color: var(--fg-soft);
  max-width: 34ch;
  margin: 0 0 var(--s5);
}
.hero-actions { display: flex; flex-wrap: wrap; gap: var(--s3); }
.hero-actions .btn { flex: 1 1 auto; }
@media (min-width: 640px) { .hero-actions .btn { flex: 0 0 auto; } }

.status-line {
  display: inline-flex; align-items: center; gap: var(--s2);
  margin-top: var(--s5);
  font-size: 15px; font-weight: 600;
}
.status-dot { width: 9px; height: 9px; border-radius: 50%; background: var(--fg-soft); flex: 0 0 auto; }
.status-open   .status-dot { background: var(--ok); }
.status-closed .status-dot { background: var(--bad); }
.status-open   { color: var(--ok); }
.status-closed { color: var(--bad); }
.status-line .status-detail { color: var(--fg-soft); font-weight: 400; }

/* ---------- sections ---------- */

section { padding: var(--sec-pad) 0; }
section + section { border-top: 1px solid var(--border); }
.section-title { font-size: var(--h2); margin-bottom: var(--s5); }
.section-intro { color: var(--fg-soft); max-width: 60ch; margin: calc(var(--s5) * -1 + var(--s3)) 0 var(--s6); }

/* ---------- services ---------- */

.cards { display: grid; gap: var(--s4); grid-template-columns: 1fr; }
@media (min-width: 700px) { .cards { grid-template-columns: repeat(2, 1fr); gap: var(--s5); } }
@media (min-width: 980px) { .cards.cards-3 { grid-template-columns: repeat(3, 1fr); } }

.card {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: var(--s5);
}
.card .icon {
  width: 42px; height: 42px; border-radius: 11px;
  display: grid; place-items: center;
  background: color-mix(in srgb, var(--accent) 14%, var(--surface));
  color: var(--accent);
  margin-bottom: var(--s4);
}
.card .icon svg { width: 22px; height: 22px; }
.card h3 { font-size: 1.25rem; margin-bottom: var(--s2); }
.card p { margin: 0; color: var(--fg-soft); font-size: 16px; }

/* ---------- hours ---------- */

.hours-layout { display: grid; gap: var(--s6); grid-template-columns: 1fr; }
@media (min-width: 880px) { .hours-layout { grid-template-columns: 1fr 1fr; gap: var(--s7); align-items: start; } }

.hours { width: 100%; border-collapse: collapse; font-variant-numeric: tabular-nums; }
.hours th, .hours td { text-align: left; padding: var(--s3) 0; border-bottom: 1px solid var(--border); }
.hours th { font-weight: 500; color: var(--fg-soft); }
.hours td { text-align: right; font-weight: 500; }
.hours tr.today th, .hours tr.today td { color: var(--fg); font-weight: 700; }
.hours tr:last-child th, .hours tr:last-child td { border-bottom: 0; }
.hours-note { font-size: 15px; color: var(--fg-soft); margin-top: var(--s4); }

.map-frame {
  border: 1px solid var(--border);
  border-radius: var(--radius);
  overflow: hidden;
  background: var(--surface);
}
.map-frame iframe { width: 100%; height: 300px; border: 0; display: block; }
.addr { font-style: normal; margin: 0 0 var(--s4); font-size: 17px; line-height: 1.6; }
.addr .label { display: block; font-size: 13px; letter-spacing: .1em; text-transform: uppercase; color: var(--accent); font-weight: 600; margin-bottom: var(--s2); }

/* ---------- photos ---------- */

.gallery { display: grid; gap: var(--s3); grid-template-columns: repeat(2, 1fr); }
@media (min-width: 760px) { .gallery { grid-template-columns: repeat(3, 1fr); gap: var(--s4); } }
.gallery figure { margin: 0; border-radius: var(--radius); overflow: hidden; background: var(--surface); }
.gallery img { aspect-ratio: 4 / 3; object-fit: cover; width: 100%; }
/* Two up on a phone, so an odd count left the last frame alone on its row
   with a hole beside it: three of the four gallery pages at 390 (2026-09-23).
   The last one takes the whole row instead, at half the height a doubled 4/3
   would give it. CSS rather than a count rule, because the count of a
   customer's photos is theirs (see build_portfolio). */
@media (max-width: 759px) {
  .gallery > :last-child:nth-child(odd) { grid-column: span 2; }
  .gallery > .photo-slot:last-child:nth-child(odd),
  .gallery > figure:last-child:nth-child(odd) img { aspect-ratio: 8 / 3; }
}

/* ⚠ `align-content` as well as `place-items`. The slot has TWO children (the
   camera and its label) and a grid's implicit rows STRETCH by default, so
   without this the two rows split the box in half: the icon floats in the top
   half and the caption in the bottom, with a void between them that reads as a
   broken image rather than an empty frame. `.planche-slot` had it from the
   start, which is why the portfolio slots never looked wrong. */
.photo-slot {
  aspect-ratio: 4 / 3;
  border: 1px dashed color-mix(in srgb, var(--fg) 28%, var(--border));
  border-radius: var(--radius);
  display: grid; place-items: center; align-content: center; text-align: center;
  padding: var(--s4);
  color: var(--fg-soft);
  font-size: 14px;
  background: color-mix(in srgb, var(--surface) 70%, var(--bg));
}
.photo-slot svg { width: 26px; height: 26px; margin: 0 auto var(--s2); display: block; opacity: .55; }

/* ---------- reviews ---------- */

.quotes { display: grid; gap: var(--s4); grid-template-columns: 1fr; }
@media (min-width: 820px) { .quotes { grid-template-columns: repeat(2, 1fr); gap: var(--s5); } }
.quote {
  background: var(--surface); border: 1px solid var(--border);
  border-radius: var(--radius); padding: var(--s5);
}
.quote blockquote { margin: 0 0 var(--s4); font-size: 17px; }
.quote figcaption { font-size: 14px; color: var(--fg-soft); }
.stars { display: flex; gap: 2px; color: var(--accent); margin-bottom: var(--s3); }
.stars svg { width: 17px; height: 17px; }

/* ---------- contact form ---------- */

.contact-layout { display: grid; gap: var(--s6); grid-template-columns: 1fr; }
@media (min-width: 880px) { .contact-layout { grid-template-columns: 5fr 6fr; gap: var(--s7); align-items: start; } }

.field { margin-bottom: var(--s4); }
.field label { display: block; font-size: 15px; font-weight: 600; margin-bottom: var(--s2); }
.field .hint { display: block; font-weight: 400; color: var(--fg-soft); font-size: 14px; margin-top: 2px; }
.field input, .field textarea {
  width: 100%;
  min-height: 48px;
  padding: var(--s3) var(--s4);
  font: inherit; font-size: 16px;
  color: var(--fg);
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
}
.field textarea { min-height: 140px; resize: vertical; }
.field input:focus, .field textarea:focus { border-color: var(--accent); }
.field .err { display: none; color: var(--bad); font-size: 14px; margin-top: var(--s2); font-weight: 500; }
.field.invalid .err { display: block; }
.field.invalid input, .field.invalid textarea { border-color: var(--bad); }

.hp { position: absolute; left: -9999px; opacity: 0; height: 0; }

.form-note { font-size: 14px; color: var(--fg-soft); margin: var(--s4) 0 0; }
.form-status { margin: var(--s4) 0 0; font-size: 16px; font-weight: 600; }
.form-status.ok  { color: var(--ok); }
.form-status.bad { color: var(--bad); }

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

.site-foot {
  border-top: 1px solid var(--border);
  padding: var(--s6) 0 calc(var(--s8) + env(safe-area-inset-bottom));
  font-size: 15px;
  color: var(--fg-soft);
}
.foot-grid { display: grid; gap: var(--s5); grid-template-columns: 1fr; }
@media (min-width: 760px) { .foot-grid { grid-template-columns: repeat(3, 1fr); } }
.site-foot h4 { font-family: var(--font-body); font-size: 14px; letter-spacing: .1em; text-transform: uppercase; color: var(--fg); margin: 0 0 var(--s3); }
.site-foot a { text-decoration: none; }
.site-foot a:hover { text-decoration: underline; }
/* The one footer link that goes somewhere on the page, so it has to look like
   a link. After `.site-foot a`, which it has to beat. */
.foot-hours a { text-decoration: underline; text-underline-offset: 3px; }
.colophon { margin-top: var(--s6); padding-top: var(--s4); border-top: 1px solid var(--border); font-size: 13px; }

/* ---------- sticky mobile action bar ---------- */

.action-bar {
  position: fixed; left: 0; right: 0; bottom: 0; z-index: 50;
  display: flex; gap: var(--s2);
  padding: var(--s3) var(--s4) calc(var(--s3) + env(safe-area-inset-bottom));
  background: color-mix(in srgb, var(--bg) 94%, transparent);
  backdrop-filter: blur(10px);
  border-top: 1px solid var(--border);
}
.action-bar .btn { flex: 1 1 0; min-width: 0; }
.action-bar .btn span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
@media (min-width: 860px) { .action-bar { display: none; } .site-foot { padding-bottom: var(--s7); } }

/* ---------- entrance motion (subtle, opt-out) ---------- */

@media (prefers-reduced-motion: no-preference) {
  .reveal { opacity: 0; transform: translateY(10px); transition: opacity .45s ease-out, transform .45s ease-out; }
  .reveal.in { opacity: 1; transform: none; }
}

/* ==========================================================================
   Section library. Everything below is shared by every skin; a skin file
   changes the variables above and adds its own one structural device.
   ========================================================================== */

@media (min-width: 900px) { section { padding: var(--sec-pad-wide) 0; } }

/* ---------- hero variants ---------- */

.hero-band { margin-top: var(--s6); }
.hero-band img { width: 100%; aspect-ratio: 21 / 9; max-height: 460px; object-fit: cover; }
/* The empty state is deliberately shorter than a real photo would be. At 21/9
   across a desktop viewport an empty dashed box reads as a broken image the
   size of a billboard.
   ⚠ `width: 100%` is what makes the height cap a cap rather than a WIDTH.
   Without it the box is sized from `max-height` back through the aspect ratio
   -- 300px tall means 686px wide -- so it sat left-aligned against the viewport
   edge, half the width of the band a real photo fills, which is exactly what
   made it read as broken. `align-content` for the same reason as `.photo-slot`
   above. */
.hero-slot {
  aspect-ratio: 16 / 7; max-height: 300px; width: 100%;
  display: grid; place-items: center; align-content: center; text-align: center; gap: var(--s2);
  border: 1px dashed color-mix(in srgb, var(--fg) 26%, var(--border));
  background: color-mix(in srgb, var(--surface) 70%, var(--bg));
  color: var(--fg-soft); font-size: 14px; padding: var(--s4);
}
.hero-slot svg { width: 28px; height: 28px; opacity: .55; }

/* An empty band is held to the page measure, and to a placeholder's height.
   Full-bleed is the media hero's device and a photograph should keep it, but an
   empty frame taking the same room is a 1425x300 dashed void running edge to
   edge past every other block on the page -- the one thing with no side gutters,
   which is exactly what makes it read as a broken image rather than as a frame
   waiting for a picture. Shrinking it is the same call base.css already made
   with max-height, carried the rest of the way.
   ⚠ `aspect-ratio: auto` and `max-height: none` both have to go, or the ratio
   fights min-height and the box springs back to 300px. */
.hero-band-empty { padding: 0 var(--s5); }
.hero-band-empty .hero-slot {
  aspect-ratio: auto; max-height: none; min-height: 148px;
  /* Minus the gutters, not just `--maxw`. `.wrap` puts its padding INSIDE its
     max-width, so a 1080 box centred in the band lines up with the wrap's border
     edge and comes out 24px wider on each side than the `.photo-slot` frames in
     the gallery. Two dashed placeholders on one page at two different widths is
     worse than either width on its own. */
  max-width: calc(var(--maxw) - var(--s5) * 2); margin: 0 auto;
  border-radius: var(--radius);
}

.hero-typographic .hero-rule {
  display: block; width: 64px; height: 1px;
  background: color-mix(in srgb, var(--fg) 45%, transparent);
  margin: var(--s5) 0;
}
.hero-editorial .since { color: var(--fg-soft); font-weight: 500; }
.hero-editorial .status-inline { margin-top: var(--s4); }
.hero-today {
  margin: var(--s2) 0 var(--s5);
  color: var(--fg-soft); font-size: 15px;
  font-variant-numeric: tabular-nums;
}
.hero-today strong { color: var(--fg); }

/* ---------- services price line ---------- */

.card-price {
  margin: var(--s3) 0 0;
  font-family: var(--font-display);
  font-size: 18px; font-weight: 600; color: var(--fg);
  font-variant-numeric: tabular-nums;
}

/* ---------- menu (la carte) ---------- */

.menu { display: grid; gap: var(--s6); grid-template-columns: 1fr; }
@media (min-width: 820px) { .menu { grid-template-columns: repeat(2, 1fr); gap: var(--s6) var(--s7); } }
/* A single group in a two-column grid leaves half the page empty and stretches
   the price leaders across it. One group gets one centred column. */
.menu-1 { grid-template-columns: 1fr; max-width: 620px; margin-inline: auto; }
@media (min-width: 820px) { .menu-1 { grid-template-columns: 1fr; } }
.menu-group h3 {
  font-size: 1.15rem; margin-bottom: var(--s3);
  padding-bottom: var(--s2); border-bottom: 1px solid var(--border);
}
.menu-list, .products, .brands { list-style: none; margin: 0; padding: 0; }
.menu-item { padding: var(--s3) 0; }
.menu-item, .p-head {
  display: flex; align-items: baseline; gap: var(--s2); flex-wrap: wrap;
}
.mi-name, .p-name { font-weight: 600; }
.mi-leader {
  flex: 1 1 24px; min-width: 24px; align-self: center;
  border-bottom: 2px dotted var(--border);
}
.mi-price {
  font-family: var(--font-display); font-weight: 600;
  font-variant-numeric: tabular-nums; white-space: nowrap;
}
.mi-desc, .p-desc {
  flex: 1 1 100%; margin: var(--s1) 0 0;
  color: var(--fg-soft); font-size: 15px;
}

/* ---------- products (spécialités) ---------- */

.product { padding: var(--s4) 0; border-bottom: 1px solid var(--border); }
.product:last-child { border-bottom: 0; }
.p-badge {
  font-size: 12px; font-weight: 600; letter-spacing: .04em;
  padding: 3px var(--s2); border-radius: var(--radius-sm);
  background: color-mix(in srgb, var(--accent) 15%, var(--surface));
  color: var(--accent); white-space: nowrap;
}

/* ---------- steps (le parcours) ---------- */

.steps { list-style: none; margin: 0; padding: 0; counter-reset: none; }
.step { display: flex; gap: var(--s4); padding-bottom: var(--s5); position: relative; }
.step:last-child { padding-bottom: 0; }
.step-n {
  /* Width and height are both explicit: on desktop the list turns into a
     column flex and a flex-basis would become the HEIGHT, which stretched the
     numerals into ellipses. */
  flex: 0 0 auto; width: 40px; height: 40px;
  display: grid; place-items: center;
  border: 2px solid var(--accent); border-radius: 50%;
  color: var(--accent); font-weight: 700; font-size: 15px;
  background: var(--bg);
  font-variant-numeric: tabular-nums;
}
/* The connector runs behind the numerals and stops at the last one. */
.step:not(:last-child)::before {
  content: ""; position: absolute; left: 19px; top: 40px; bottom: 8px;
  width: 2px; background: color-mix(in srgb, var(--accent) 35%, var(--border));
}
/* Headings inherit the display leading, 1.08, which is right for an h1 and much
   too tight once a 17px h3 wraps: on a phone every one of these titles wraps,
   and the two lines all but touch. Both sections are absent from `classique`,
   so the pixel contract does not see this. */
.step-b h3 { font-size: 1.15rem; line-height: 1.25; margin-bottom: var(--s2); }
.step-b p { margin: 0; color: var(--fg-soft); font-size: 16px; }
@media (min-width: 900px) {
  .steps { display: flex; gap: var(--s5); }
  .step { flex: 1 1 0; flex-direction: column; padding-bottom: 0; }
  .step:not(:last-child)::before {
    left: 48px; right: -24px; top: 19px; bottom: auto; width: auto; height: 2px;
  }
}

/* ---------- portfolio (la planche) ---------- */

.s-portfolio { overflow: hidden; }
.planche {
  display: grid; gap: 2px; margin-top: var(--s5);
  grid-template-columns: repeat(2, 1fr);
  grid-auto-flow: dense;
}
@media (min-width: 760px) { .planche { grid-template-columns: repeat(4, 1fr); } }
.planche-tile { margin: 0; position: relative; overflow: hidden; }
.planche-tile img { width: 100%; aspect-ratio: 4 / 5; object-fit: cover; }
.planche-tile:first-child { grid-column: span 2; grid-row: span 2; }
.planche-tile figcaption {
  position: absolute; left: 0; right: 0; bottom: 0;
  padding: var(--s3) var(--s4);
  font-size: 13px; color: #fff;
  background: linear-gradient(to top, rgba(0, 0, 0, .62), transparent);
}
.planche-slot {
  aspect-ratio: 4 / 5;
  display: grid; place-items: center; align-content: center; gap: var(--s2);
  text-align: center; padding: var(--s4);
  border: 1px dashed color-mix(in srgb, var(--fg) 26%, var(--border));
  background: color-mix(in srgb, var(--surface) 70%, var(--bg));
  color: var(--fg-soft); font-size: 13px;
}
.planche-slot:first-child { grid-column: span 2; grid-row: span 2; }
.planche-slot svg { width: 26px; height: 26px; opacity: .5; }
/* A plate with no photograph in it at all (build_portfolio adds the class).
   Held to the page measure and square tiles, the same call .hero-band-empty
   makes: full-bleed empty frames on ylann were ~1100px of dashed void on a
   phone (2026-09-23). The box matches .wrap: max-width with the padding
   inside it. The 2x2 tile's cap is phone-only: from 760px it shares its two
   rows with tiles 2 to 5, and a cap there would leave it short of them. */
.planche-empty { max-width: var(--maxw); margin-inline: auto; padding: 0 var(--s5); }
.planche-empty .planche-slot { aspect-ratio: 1 / 1; }
@media (max-width: 759px) {
  .planche-empty .planche-slot:first-child { aspect-ratio: auto; height: 260px; }
}

/* ---------- trust (garanties) ---------- */

.trust { list-style: none; margin: 0; padding: 0; display: grid; gap: var(--s5); }
@media (min-width: 820px) { .trust { grid-template-columns: repeat(2, 1fr); gap: var(--s5) var(--s7); } }
.trust-row { display: flex; gap: var(--s4); align-items: flex-start; }
.t-icon {
  flex: 0 0 40px; height: 40px; border-radius: var(--radius-sm);
  display: grid; place-items: center;
  background: color-mix(in srgb, var(--accent) 13%, var(--surface));
  color: var(--accent);
}
.t-icon svg { width: 21px; height: 21px; }
.trust-row h3 { font-size: 1.1rem; line-height: 1.25; margin-bottom: var(--s2); }
.trust-row p { margin: 0; color: var(--fg-soft); font-size: 16px; }

/* ---------- faq ---------- */

.faq { max-width: 68ch; }
.faq-item { border-bottom: 1px solid var(--border); }
.faq-item summary {
  cursor: pointer; list-style: none;
  padding: var(--s4) 0; padding-right: var(--s6);
  font-weight: 600; position: relative;
}
.faq-item summary::-webkit-details-marker { display: none; }
.faq-mark {
  position: absolute; right: 4px; top: 50%; width: 12px; height: 2px;
  background: var(--accent); transform: translateY(-50%);
}
.faq-mark::after {
  content: ""; position: absolute; inset: 0;
  background: var(--accent); transform: rotate(90deg);
  transition: opacity .18s ease;
}
.faq-item[open] .faq-mark::after { opacity: 0; }
.faq-a { padding: 0 0 var(--s4); color: var(--fg-soft); }
@media (prefers-reduced-motion: reduce) { .faq-mark::after { transition: none; } }

/* ---------- brands ---------- */

.brands { display: flex; flex-wrap: wrap; gap: var(--s2); }
.brands li {
  border: 1px solid var(--border); border-radius: var(--radius-sm);
  padding: var(--s2) var(--s4); font-size: 15px; font-weight: 500;
  background: var(--surface);
}

/* ---------- cta band ---------- */

.cta-band {
  background: var(--primary);
  color: var(--primary-ink);
  text-align: center;
  border-top: 0;
}
.cta-band h2 { font-size: var(--h2); margin-bottom: var(--s3); }
.cta-band p { margin: 0 auto var(--s5); max-width: 44ch; opacity: .88; }
.btn-oncta {
  background: var(--primary-ink); color: var(--primary);
  border-color: var(--primary-ink);
}
.btn-oncta:hover { background: color-mix(in srgb, var(--primary-ink) 88%, var(--primary)); }
/* `.cta-band .cta-num`, not `.cta-num`: `.cta-band p` above outranks a single
   class, so its bottom margin and .88 opacity won and the number sat ~8px
   under the button (2026-09-23). */
.cta-band .cta-num {
  margin: var(--s4) auto 0; font-family: var(--font-display);
  font-size: 1.4rem; font-variant-numeric: tabular-nums; opacity: 1;
}

/* ---------- signature hero (profiles.SIGNATURES) ----------
   The headline column and the signature's composition side by side from
   900px, stacked below it. The composition is the signature's to draw
   (template/signatures/<name>/); this only gives it a column. */

.hero-sig-grid { display: grid; gap: var(--s6); grid-template-columns: 1fr; align-items: center; }
@media (min-width: 900px) {
  .hero-sig-grid { grid-template-columns: minmax(0, 1.1fr) minmax(0, .9fr); gap: var(--s7); }
}
.hero-art { min-width: 0; }
.hero-art .sa-photo { width: 100%; height: auto; display: block; }

/* The band's second button (cta_band.link): same size, drawn in outline so
   the call stays the first choice. */
.btn-oncta-alt {
  /* The band's own text colour, whatever a signature painted the band:
     primary-ink on the default band, dark ink on a light card. */
  background: transparent; color: inherit;
  border-color: color-mix(in srgb, currentColor 60%, transparent);
  margin-left: var(--s2);
}
.btn-oncta-alt:hover { background: color-mix(in srgb, currentColor 10%, transparent); }

/* Studio — the media-led skin for trades whose work is the product.
   Device: a dark ground and a full-bleed spanning-tile plate. Square corners,
   no shadows (they die on dark anyway), tight tracked display type. */

:root {
  --h1: clamp(2.6rem, 11vw, 5.2rem);
  --h1-lh: 0.98;
  --h2: clamp(1.7rem, 6.5vw, 2.8rem);
  --display-weight: 700;
  --display-tracking: -0.03em;
  --body-size: 16.5px;
  --body-lh: 1.6;
  --radius: 2px;
  --radius-sm: 2px;
  --btn-radius: 4px;
  --sec-pad: 64px;
  --sec-pad-wide: 96px;
  --shadow-1: none;
  --shadow-2: none;
  --card-shadow: none;
  --eyebrow-tracking: .2em;
}

.section-title { text-transform: uppercase; letter-spacing: -0.01em; }
.btn-primary { box-shadow: none; }
.card, .quote, .brands li { background: var(--surface); }

/* The plate runs edge to edge. On a phone that is two columns; the first tile
   still takes the 2x2 slot so the grid never reads as a uniform contact sheet. */
.planche { gap: 2px; }
.planche-tile img, .planche-slot { aspect-ratio: 4 / 5; }
.planche-tile img { transition: transform .25s ease-out, filter .25s ease-out; }
.planche-tile:hover img { transform: scale(1.02); filter: brightness(1.06); }
@media (prefers-reduced-motion: reduce) {
  .planche-tile img { transition: none; }
  .planche-tile:hover img { transform: none; filter: none; }
}

.hero-slot, .planche-slot {
  border-color: color-mix(in srgb, var(--fg) 22%, var(--border));
  background: color-mix(in srgb, var(--surface) 80%, var(--bg));
}
/* Each slot's own dashed border plus the plate's 2px gap drew two parallel
   dashed lines between neighbours. One inset outline per tile instead. */
.planche-slot {
  border: 0;
  outline: 1px dashed color-mix(in srgb, var(--fg) 22%, var(--border));
  outline-offset: -1px;
}

/* --border on the dark ground is 1.44:1, under the 3:1 a form control's edge
   needs (WCAG 1.4.11), so the fields all but vanished. The error and focus
   colours in base.css still win on specificity. */
.field input, .field textarea { border-color: color-mix(in srgb, var(--fg) 35%, var(--border)); }

/* The preview ribbon is near-black by default, which vanishes on a dark page. */
.preview-note { background: #2c261d; }

/* Signature: Barbershop. An old-school barber's on a cream wall: oxblood,
   navy and bone, the name gilded on black glass, prices in tall condensed
   figures. One device, repeated with intent: the barber-pole diagonal stripe
   (down the tariff board, beside every section title, as the call band).
   Titles sit flush left on a stripe that runs out to the margin, like a
   shop's fascia, and the price list turns into ruled rows, never cards. */

@font-face { font-family: 'Barber Display'; font-style: normal; font-weight: 400; font-display: swap;
  src: url('fonts/anton-400.woff2') format('woff2'); }
@font-face { font-family: 'Barber Sans'; font-style: normal; font-weight: 400; font-display: swap;
  src: url('fonts/barlow-400.woff2') format('woff2'); }
@font-face { font-family: 'Barber Sans'; font-style: normal; font-weight: 600; font-display: swap;
  src: url('fonts/barlow-600.woff2') format('woff2'); }
@font-face { font-family: 'Barber Cond'; font-style: normal; font-weight: 600; font-display: swap;
  src: url('fonts/barlow-condensed-600.woff2') format('woff2'); }

:root {
  --font-display: 'Barber Display', Impact, 'Arial Narrow', sans-serif;
  --font-body: 'Barber Sans', system-ui, -apple-system, 'Segoe UI', sans-serif;
  --font-cond: 'Barber Cond', 'Arial Narrow', system-ui, sans-serif;
  --display-weight: 400;
  --display-tracking: 0.01em;
  --h1: clamp(2.7rem, 12.4vw, 5.4rem);
  --h1-lh: 1.1;
  --h2: clamp(2rem, 8.6vw, 3.4rem);
  --body-size: 17px;
  --radius: 3px;
  --radius-sm: 2px;
  --btn-radius: 3px;
  --sec-pad: 72px;
  --sec-pad-wide: 112px;
  --eyebrow-tracking: .2em;

  /* The board and the gilding. Measured on #141C27: gold 8.7:1, cream 13.6:1,
     the soft cream 7.8:1, the darkest gold stop 5.9:1. */
  --board: #141C27;
  --gold: #D9B45F;
  --gold-hi: #F1D995;
  --gold-lo: #B8924A;
  --cream: #EFE4CC;
  --cream-soft: #B9AE98;
  --enamel: #FBF6EC;
  --pole-red: #8B1E1E;
  --pole-blue: #1E3557;
  --pole-white: #FBF5EA;
  /* Hard stops on a diagonal alias in a screenshot; each stop gets 0.6px.
     The period is 36.77px along the stripe, which is exactly 52px across and
     down, so a 52px tile repeats (and the pole turns) without a seam. */
  --pole: repeating-linear-gradient(-45deg,
    var(--pole-red) 0 8.59px, var(--pole-white) 9.19px 17.78px,
    var(--pole-blue) 18.38px 26.97px, var(--pole-white) 27.57px 36.17px, var(--pole-red) 36.77px);
}

/* Anton has one weight. Anything asking the display face for 600 or 700 would
   be smeared into a fake bold. */
body { font-synthesis: none; }

.preview-note { background: #1D1916; color: #F6EFE2; }
.preview-note strong { color: #F1D995; }

/* ---- header: the fascia ---- */
.site-head { background: color-mix(in srgb, var(--bg) 92%, transparent); border-bottom: 0;
  box-shadow: 0 1px 0 var(--border); }
/* The header and the footer get solid enamel rules, navy on an oxblood
   hairline; the diagonal stripe is kept for the pole moments only (the board,
   the titles, the call band), where it has the width to read as a pole. */
.site-head::after { content: ""; display: block; height: 5px;
  background: linear-gradient(var(--pole-blue) 0 4px, var(--pole-red) 4px 5px); }
.brand {
  font-family: var(--font-display); font-size: 23px; letter-spacing: .04em;
  text-transform: uppercase; color: var(--fg);
}
.nav a { font-family: var(--font-cond); font-weight: 600; font-size: 16px;
  letter-spacing: .1em; text-transform: uppercase; color: var(--fg-soft); }
.nav a:hover { color: var(--primary); }
.btn-sm { min-height: 44px; }

/* ---- buttons: square, condensed, like a shop's price tickets ---- */
.btn {
  font-family: var(--font-cond); font-weight: 600; font-size: 18px;
  letter-spacing: .08em; text-transform: uppercase;
}
.btn-sm { font-size: 16px; }
.btn-primary { background: var(--primary); color: var(--primary-ink); box-shadow: inset 0 -3px 0 rgba(0, 0, 0, .22); }
.btn-primary:hover { background: color-mix(in srgb, var(--primary) 86%, #000); }
.btn-ghost { background: transparent; color: var(--fg); border: 2px solid var(--fg); }
.btn-ghost:hover { background: var(--fg); color: var(--bg); }

/* ---- hero ---- */
.hero-sig { padding-top: var(--s7); padding-bottom: var(--s6); overflow: hidden; }
.hero .eyebrow {
  display: inline-flex; align-items: center; gap: var(--s3);
  font-family: var(--font-cond); font-size: 15px; font-weight: 600; color: var(--accent);
}
.hero .eyebrow::before {
  content: ""; width: 34px; height: 12px; flex: 0 0 auto; border-radius: 2px;
  background: var(--pole); box-shadow: inset 0 0 0 1px rgba(29, 25, 22, .25);
}
.hero h1 {
  text-transform: uppercase; letter-spacing: .005em;
  font-size: var(--h1); line-height: var(--h1-lh);
  margin-bottom: var(--s5);
  text-wrap: balance;
}
.hero .lede { max-width: 36ch; color: var(--fg-soft); font-size: clamp(1.06rem, 4.2vw, 1.25rem); }
.status-line { font-family: var(--font-cond); letter-spacing: .06em; font-size: 16px; }

/* The board. Black glass in a thin gilt line, the pole down its left edge. */
.bb-board { position: relative; margin: 0; }
.bb-board .sa-photo { border-radius: var(--radius); margin-bottom: var(--s5);
  border: 6px solid var(--board); }
.bb-glass {
  position: relative;
  background:
    radial-gradient(ellipse 90% 60% at 30% 0%, rgba(255, 255, 255, .07), transparent 70%),
    var(--board);
  color: var(--cream);
  border-radius: 4px;
  padding: clamp(26px, 6vw, 40px) clamp(20px, 5vw, 36px) clamp(22px, 5vw, 30px) clamp(46px, 11vw, 64px);
  box-shadow:
    inset 0 0 0 6px var(--board), inset 0 0 0 7px var(--gold-lo),
    inset 0 0 0 10px var(--board), inset 0 0 0 11px color-mix(in srgb, var(--gold-lo) 45%, var(--board)),
    0 22px 40px -24px rgba(29, 25, 22, .55);
}
.bb-pole {
  position: absolute; z-index: 1; left: clamp(14px, 3.4vw, 20px); top: 22px; bottom: 22px;
  width: clamp(16px, 4vw, 22px); border-radius: 12px;
  background: var(--pole); background-size: 52px 52px;
  box-shadow: inset 3px 0 4px rgba(0, 0, 0, .28), inset -3px 0 4px rgba(0, 0, 0, .22);
}

.bb-sign { margin: 0 0 var(--s5); line-height: 1; }
.bb-sign-a, .bb-sign-b {
  display: block; font-family: var(--font-display); text-transform: uppercase;
  background: linear-gradient(180deg, var(--gold-hi) 0%, var(--gold) 46%, var(--gold-lo) 100%);
  -webkit-background-clip: text; background-clip: text;
  -webkit-text-fill-color: transparent; color: var(--gold);
  filter: drop-shadow(0 2px 0 rgba(0, 0, 0, .55));
}
.bb-sign-a { font-size: clamp(1.5rem, 6.6vw, 2.1rem); letter-spacing: .14em; line-height: 1.15; }
.bb-sign-b { font-size: clamp(3.6rem, 18vw, 5.6rem); letter-spacing: .02em; line-height: 1.02; margin-top: 2px; }

.bb-list-t {
  display: flex; align-items: center; gap: var(--s3);
  margin: 0 0 var(--s3);
  font-family: var(--font-cond); font-weight: 600; font-size: 14px; letter-spacing: .22em;
  text-transform: uppercase; color: var(--gold);
}
.bb-list-t::after { content: ""; flex: 1 1 auto; height: 1px; background: color-mix(in srgb, var(--gold) 55%, transparent); }
.bb-list { list-style: none; margin: 0; padding: 0; }
.bb-list li {
  display: flex; align-items: baseline; gap: var(--s2);
  padding: 7px 0;
}
.bb-list li + li { border-top: 1px solid rgba(239, 228, 204, .1); }
.bb-list .sa-n {
  font-family: var(--font-cond); font-weight: 600; font-size: clamp(15px, 4.2vw, 17px);
  letter-spacing: .05em; text-transform: uppercase; color: var(--cream); line-height: 1.25;
  flex: 0 1 auto; min-width: 0;
}
.bb-list .sa-l { flex: 1 1 16px; min-width: 16px; align-self: center;
  border-bottom: 2px dotted color-mix(in srgb, var(--gold) 50%, transparent); transform: translateY(4px); }
.bb-list .sa-p {
  font-family: var(--font-display); font-size: clamp(1.45rem, 6.4vw, 1.9rem); line-height: 1.1;
  color: var(--gold); white-space: nowrap; font-variant-numeric: tabular-nums;
}
.bb-addr {
  margin: var(--s5) 0 0; padding-top: var(--s3);
  border-top: 1px solid color-mix(in srgb, var(--gold) 40%, transparent);
  font-family: var(--font-cond); font-weight: 600; font-size: 13.5px; letter-spacing: .16em;
  text-transform: uppercase; color: var(--cream-soft);
}

/* The enamel plate under the board: white field, navy edge, rounded corners,
   hung a little off the board's axis like everything screwed to a wall. */
.bb-plate {
  position: relative;
  width: min(100% - 28px, 330px);
  margin: -14px 0 0 auto; z-index: 2;
  background: var(--enamel);
  color: var(--pole-blue);
  border-radius: 10px;
  padding: var(--s4) var(--s5) var(--s3);
  box-shadow:
    inset 0 0 0 3px var(--enamel), inset 0 0 0 5px var(--pole-blue),
    0 10px 18px -12px rgba(29, 25, 22, .55), 0 0 0 1px rgba(29, 25, 22, .12);
  transform: rotate(-1.2deg);
}
.bb-plate::before, .bb-plate::after {
  content: ""; position: absolute; top: 11px; width: 7px; height: 7px; border-radius: 50%;
  background: radial-gradient(circle at 35% 35%, #fff, #9a9186 70%);
  box-shadow: 0 0 0 1px rgba(29, 25, 22, .3);
}
.bb-plate::before { left: 12px; } .bb-plate::after { right: 12px; }
.bb-plate-t {
  display: block; text-align: center; margin-bottom: var(--s2);
  font-family: var(--font-display); font-size: 20px; letter-spacing: .14em; text-transform: uppercase;
  color: var(--pole-red);
}
.bb-week { list-style: none; margin: 0; padding: 0; font-variant-numeric: tabular-nums; }
.bb-week li { display: flex; justify-content: space-between; align-items: baseline; gap: var(--s4);
  padding: 4px 0; border-top: 1px solid color-mix(in srgb, var(--pole-blue) 22%, transparent); }
.bb-week .sa-d { font-family: var(--font-cond); font-weight: 600; font-size: 15px; letter-spacing: .08em;
  text-transform: uppercase; color: var(--pole-blue); }
.bb-week .sa-h { font-weight: 600; font-size: 15.5px; color: #1D1916; text-align: right; }

@media (min-width: 900px) {
  .hero-sig { padding-top: var(--s8); }
  .bb-glass { padding-left: 72px; }
  .bb-pole { left: 22px; width: 24px; }
}

/* Phone: the tariff board is the first thing on the screen, not the fifth.
   It goes above the headline, compacted (a shorter sign, tighter glass), and
   the enamel plate and the address line stay off it: #horaires and the lede
   already carry both, and together they pushed the headline off the screen. */
@media (max-width: 899.98px) {
  .hero-sig { padding-top: var(--s5); }
  .hero-sig-grid { gap: var(--s5); }
  .hero-sig .hero-art { order: -1; }
  .bb-glass { padding: 20px 18px 14px 50px; }
  .bb-pole { left: 16px; top: 16px; bottom: 16px; width: 18px; }
  .bb-sign { margin-bottom: var(--s3); }
  .bb-sign-a { font-size: clamp(1.15rem, 5vw, 1.5rem); line-height: 1.1; }
  .bb-sign-b { font-size: clamp(2.6rem, 12.5vw, 3.6rem); line-height: 1.05; }
  .bb-list-t { margin-bottom: var(--s1); font-size: 13px; }
  .bb-list li { padding: 4px 0; }
  .bb-list .sa-p { font-size: clamp(1.3rem, 5.8vw, 1.6rem); }
  .bb-addr, .bb-plate { display: none; }
  .hero .eyebrow { margin-bottom: var(--s2); }
}

/* The pole turns, slowly. Off for anyone who asked for less motion. The
   stripes ride on a ::before one tile taller than the pole and slide down
   by exactly that tile, so the turn is a transform and has no seam; the
   pole's own inset shading moves onto a ::after above them. */
.bb-pole { overflow: hidden; }
@media (prefers-reduced-motion: no-preference) {
  .bb-pole { background: none; box-shadow: none; }
  .bb-pole::before {
    content: ""; position: absolute; left: 0; right: 0; top: -52px; bottom: 0;
    background: var(--pole); background-size: 52px 52px;
    animation: bb-turn 7s linear infinite;
  }
  .bb-pole::after {
    content: ""; position: absolute; inset: 0; border-radius: inherit;
    box-shadow: inset 3px 0 4px rgba(0, 0, 0, .28), inset -3px 0 4px rgba(0, 0, 0, .22);
  }
  @keyframes bb-turn { from { transform: translateY(0); } to { transform: translateY(52px); } }
}

/* ---- section titles: fascia lettering on a stripe that runs to the margin ---- */
section + section { border-top: 0; }
.section-title {
  display: flex; align-items: center; gap: var(--s4);
  text-transform: uppercase; letter-spacing: .01em; line-height: 1.15;
  margin-bottom: var(--s6);
}
.section-title::after {
  content: ""; flex: 1 1 40px; min-width: 40px; height: 14px; border-radius: 2px;
  background: var(--pole); box-shadow: inset 0 0 0 1px rgba(29, 25, 22, .2);
}
/* Phone: a long title wraps and would squeeze the stripe into a stub beside
   it, so every title carries its stripe underneath instead, one full-width
   band of pole, the same on all sections. */
@media (max-width: 559px) {
  .section-title { flex-wrap: wrap; row-gap: var(--s3); }
  .section-title::after { flex: 0 0 100%; order: 2; height: 12px; }
}
.section-intro { text-align: left; margin-left: 0; font-size: 17.5px; max-width: 54ch; }

/* ---- #realisations: a frame wall waiting for the cuts ---- */
/* The frame wall and the price list belong together: a tight seam between
   them, not a full section gap. */
.s-portfolio { padding-bottom: 20px; }
@media (min-width: 900px) { #services { padding-top: 88px; } }
.planche.planche-empty {
  gap: 20px; margin-top: var(--s6);
  padding: 26px var(--s5);
  counter-reset: bb-frame;
}
@media (min-width: 760px) {
  .planche.planche-empty {
    /* The wall itself: a faint pinstripe paper behind the frames, inside the
       measure. The page ground stays plain. */
    max-width: calc(var(--maxw) - var(--s5) * 2);
    padding: 36px;
    gap: 28px;
  }
  /* The wall paper goes on the section, never on the grid (fb-0023). */
  .s-portfolio {
    background:
      repeating-linear-gradient(90deg, transparent 0 21px, rgba(139, 30, 30, .07) 21px 22px, transparent 22px 26px, rgba(30, 53, 87, .06) 26px 27px),
      var(--surface);
  }
}
.planche-empty .planche-slot {
  counter-increment: bb-frame;
  position: relative;
  outline: 0; border: 0;
  border-radius: 1px;
  /* Frame, then a bone mat, then a hairline where the photo will sit. */
  background:
    linear-gradient(var(--enamel), var(--enamel)) padding-box;
  box-shadow:
    inset 0 0 0 9px #241A14,
    inset 0 0 0 10px #4A3526,
    inset 0 0 0 22px var(--enamel),
    inset 0 0 0 23px color-mix(in srgb, var(--fg) 30%, var(--enamel)),
    6px 10px 16px -8px rgba(29, 25, 22, .45);
  color: var(--fg-soft);
  font-family: var(--font-cond); font-weight: 600; font-size: 14px; letter-spacing: .14em; text-transform: uppercase;
  padding: 34px;
}
.planche-empty .planche-slot svg { color: var(--primary); opacity: .75; width: 28px; height: 28px; }
.planche-empty .planche-slot::after {
  content: "N\00B0\00A0" counter(bb-frame);
  position: absolute; left: 50%; bottom: -13px; transform: translateX(-50%);
  background: var(--gold); color: #241A14;
  font-family: var(--font-cond); font-weight: 600; font-size: 12.5px; letter-spacing: .14em;
  padding: 3px 10px; border-radius: 2px;
  box-shadow: inset 0 0 0 1px rgba(36, 26, 20, .35);
}
.planche-empty .planche-slot:nth-child(2) { transform: rotate(1.1deg); }
.planche-empty .planche-slot:nth-child(3) { transform: rotate(-.8deg); }
.planche-empty .planche-slot:nth-child(4) { transform: rotate(.6deg); }
.planche-empty .planche-slot:nth-child(5) { transform: rotate(-1deg); }
.planche-empty .planche-slot:first-child {
  box-shadow:
    inset 0 0 0 12px #241A14,
    inset 0 0 0 13px #4A3526,
    inset 0 0 0 30px var(--enamel),
    inset 0 0 0 31px color-mix(in srgb, var(--fg) 30%, var(--enamel)),
    8px 14px 22px -10px rgba(29, 25, 22, .5);
  font-size: 16px;
}
@media (max-width: 759px) {
  .planche-empty .planche-slot:first-child { height: 250px; }
  /* Small frames: the label on one line, never an orphan "ICI". */
  .planche-empty .planche-slot:not(:first-child) { padding: 26px 18px; }
  .planche-empty .planche-slot:not(:first-child) span {
    white-space: nowrap; font-size: 12px; letter-spacing: .06em; }
}

/* ---- #services: the price list as ruled rows, durations first ---- */
#services { background: transparent; }
#services .cards {
  display: block;
  border-top: 3px solid var(--fg);
  border-bottom: 3px solid var(--fg);
}
@media (min-width: 820px) {
  #services .cards { display: grid; grid-template-columns: 1fr 1fr; column-gap: var(--s8); }
}
#services .card {
  background: transparent; border: 0; border-radius: 0; padding: var(--s4) 0;
  display: grid; grid-template-columns: 1fr auto; column-gap: var(--s4); align-items: baseline;
  border-bottom: 1px solid var(--border);
}
@media (min-width: 820px) {
  #services .card:nth-last-child(-n+2) { border-bottom: 0; }
}
@media (max-width: 819px) {
  #services .card:last-child { border-bottom: 0; }
}
#services .card .icon { display: none; }
#services .card h3 {
  grid-column: 1; font-family: var(--font-cond); font-weight: 600; font-size: 1.28rem;
  letter-spacing: .04em; text-transform: uppercase; line-height: 1.2; margin: 0 0 4px;
}
#services .card p { grid-column: 1; font-size: 16px; color: var(--fg-soft); }
#services .card .card-price {
  grid-column: 2; grid-row: 1 / span 2; align-self: center;
  margin: 0; font-family: var(--font-display); font-weight: 400;
  font-size: clamp(2rem, 9vw, 2.6rem); line-height: 1.1; color: var(--primary);
}

/* ---- the call band: the pole itself, a white enamel plate hung on it ---- */
.cta-band {
  background: var(--pole);
  color: var(--fg);
  padding: clamp(44px, 9vw, 88px) 0;
}
.cta-band .wrap {
  max-width: 560px;
  background: var(--enamel);
  border-radius: 12px;
  padding: clamp(28px, 6vw, 44px) clamp(20px, 5vw, 40px);
  box-shadow: inset 0 0 0 4px var(--enamel), inset 0 0 0 7px var(--pole-blue),
    0 18px 30px -18px rgba(0, 0, 0, .6);
  width: calc(100% - var(--s5) * 2);
}
.cta-band h2 {
  font-size: clamp(2.2rem, 10vw, 3.3rem); line-height: 1.15; text-transform: uppercase;
  color: var(--pole-red); letter-spacing: .02em;
  text-wrap: balance;
}
.cta-band p { color: #3E342C; opacity: 1; }
.btn-oncta { background: var(--pole-blue); color: var(--enamel); border-color: var(--pole-blue); }
.btn-oncta:hover { background: color-mix(in srgb, var(--pole-blue) 85%, #000); }
.cta-band .cta-num { font-size: 1.7rem; color: var(--pole-blue); letter-spacing: .04em; font-weight: 400; }

/* ---- #horaires ---- */
.hours th { font-family: var(--font-cond); font-weight: 600; letter-spacing: .08em; text-transform: uppercase;
  color: var(--fg-soft); font-size: 16.5px; }
.hours td { font-weight: 600; }
.hours th, .hours td { border-bottom: 1px dashed color-mix(in srgb, var(--fg) 22%, transparent); padding: 14px 0; }
.hours tr.today th, .hours tr.today td { color: var(--primary); }
.hours { border-top: 3px solid var(--fg); border-bottom: 3px solid var(--fg); }
.addr .label, .site-foot h4 { font-family: var(--font-cond); letter-spacing: .18em; color: var(--primary); }
.map-frame { border: 6px solid var(--fg); border-radius: 2px; }

/* ---- contact ---- */
#contact { position: relative; }
.field label { font-family: var(--font-cond); font-weight: 600; letter-spacing: .06em; text-transform: uppercase; font-size: 15.5px; }
.field .hint { text-transform: none; letter-spacing: 0; font-family: var(--font-body); }
.field input, .field textarea { background: var(--enamel); border: 1.5px solid color-mix(in srgb, var(--fg) 55%, var(--border)); border-radius: 2px; }

/* ---- footer and bar ---- */
.site-foot { border-top: 0; position: relative; }
.site-foot::before { content: ""; position: absolute; left: 0; right: 0; top: 0; height: 6px;
  background: linear-gradient(var(--pole-red) 0 1px, var(--pole-blue) 1px 6px); }
.site-foot h4 { color: var(--fg); }
.action-bar { background: color-mix(in srgb, var(--bg) 95%, transparent); border-top: 2px solid var(--fg); }
.bb-nw { white-space: nowrap; }

/* ---- the map, black and white like the old photos by the mirror. ---- */
.map-frame iframe { filter: grayscale(1) contrast(1.08); }

/* ---- contact, desktop: the heading, the words and the call ride in the
   left column beside the form (sticky), so the column is never an empty
   half of the page; name and e-mail share a line. ---- */
@media (min-width: 880px) {
  #contact .wrap { display: grid; grid-template-columns: 5fr 6fr; grid-template-rows: auto 1fr; column-gap: var(--s8); align-items: start; }
  #contact .section-title { grid-column: 1; grid-row: 1; }
  #contact .contact-layout { display: contents; }
  #contact .contact-layout > div { grid-column: 1; grid-row: 2; position: sticky; top: 110px; }
  #contact form { grid-column: 2; grid-row: 1 / span 2; display: grid; grid-template-columns: 1fr 1fr; column-gap: var(--s4); }
  #contact form > * { grid-column: 1 / -1; min-width: 0; }
  #contact form > .field:nth-of-type(1) { grid-column: 1; }
  #contact form > .field:nth-of-type(2) { grid-column: 2; }
}

/* ---- the call, striped like the pole ----
   Pointing at a call button (only where there is a pointer), tabbing to it
   or pressing it shows the pole's stripe inside it, faint and under the
   words, and while it is held the stripe runs, as the pole does. Nothing
   moves until touched. 36px across the stripe is 50.91px along the button,
   so the run repeats without a seam. */
.btn-primary, .btn-oncta { position: relative; isolation: isolate; overflow: hidden; -webkit-tap-highlight-color: transparent; }
.btn-primary::after, .btn-oncta::after {
  content: ""; position: absolute; z-index: -1; top: 0; bottom: 0; left: -51px; right: 0;
  pointer-events: none; opacity: 0;
  background: repeating-linear-gradient(-45deg,
    rgba(251, 245, 234, .2) 0 9px, transparent 9px 18px,
    rgba(10, 18, 32, .22) 18px 27px, transparent 27px 36px);
}
@media (hover: hover) {
  .btn-primary:hover::after, .btn-oncta:hover::after { opacity: 1; }
}
.btn-primary:focus-visible::after, .btn-oncta:focus-visible::after,
.btn-primary:active::after, .btn-oncta:active::after { opacity: 1; }
@media (prefers-reduced-motion: no-preference) {
  .btn-primary::after, .btn-oncta::after { transition: opacity .25s ease-out; }
  .btn-primary:hover::after, .btn-oncta:hover::after,
  .btn-primary:focus-visible::after, .btn-oncta:focus-visible::after,
  .btn-primary:active::after, .btn-oncta:active::after { animation: bb-stripe 1.1s linear infinite; }
  @keyframes bb-stripe { from { transform: translateX(0); } to { transform: translateX(50.91px); } }
}

/* ---- the lines move (owner, fb-0097) ----
   The stripe beside each section title runs out to the margin once as the
   title scrolls in. (The pole's own turn is further up, with the hero.) */
@media (prefers-reduced-motion: no-preference) {
  .section-title.reveal::after { transform: scaleX(0); transform-origin: left center; }
  .section-title.reveal.in::after { transform: none; transition: transform .9s cubic-bezier(.3, .7, .3, 1) .2s; }
}
