/* 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: #9A2A1C;
  --primary-ink: #FFFFFF;
  --accent: #1D3F75;
  --bg: #F6EFE2;
  --surface: #FFFBF3;
  --fg: #22190F;
  --fg-soft: #5A4A3C;
  --border: #E0D0B8;
  /* 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: #146C36;
  --bad: #A61B1B;

  --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); }

/* Maison — the bistro and artisan skin.
   Device: the page reads like a printed menu. Section titles sit centred over a
   short double rule, and every priced line runs to a dotted leader. */

:root {
  --h1: clamp(2.4rem, 9vw, 4.2rem);
  --h1-lh: 1.05;
  --h2: clamp(1.6rem, 6vw, 2.4rem);
  --display-weight: 600;
  --display-tracking: -0.01em;
  --body-size: 17px;
  --body-lh: 1.65;
  --radius: 10px;
  --btn-radius: 999px;
  --sec-pad: 56px;
  --sec-pad-wide: 72px;
  --card-shadow: 0 1px 2px rgba(64, 34, 12, .05);
  --eyebrow-tracking: .14em;
}

/* Centred titles over a double rule. The ornament is the strongest single cue
   that this is a carte and not a card grid. */
.section-title {
  text-align: center;
  margin-bottom: var(--s6);
  padding-bottom: var(--s4);
  position: relative;
}
.section-title::after {
  content: "";
  position: absolute; left: 50%; bottom: 0;
  width: 64px; height: 3px;
  transform: translateX(-50%);
  border-top: 1px solid var(--accent);
  border-bottom: 1px solid var(--accent);
}
.section-intro { text-align: center; margin-left: auto; margin-right: auto; }
/* Except in the contact column, where the intro sits over a left-aligned phone
   button: centred text above a flush-left button read as two layouts. */
.contact-layout .section-intro { text-align: left; margin-left: 0; }
/* A single-group carte is centred at 620px (.menu-1), so its note follows it
   instead of hanging off the left edge of the section. */
.menu-1 ~ .hours-note { max-width: 620px; margin-inline: auto; text-align: center; }

.card { box-shadow: var(--card-shadow); }
.menu-group h3 { text-align: center; }
.mi-price { color: var(--primary); }

/* Comptoir uses the editorial hero: the eyebrow carries the "depuis" line, so
   it gets room to breathe. */
.hero-editorial .eyebrow { margin-bottom: var(--s3); }

/* Signature: Ardoise. A French counter shop: the page opens under a striped
   awning, the name hangs on a blue enamel plaque over the day's slate, the
   counter itself is a wall of white faience with white enamel labels hung on
   it, and everything else sits on butcher's paper. Chalk (Caveat) is only
   ever written on the hero's slate; the rest speaks slab serif and plain sans. */

@font-face { font-family: 'Ardoise Slab'; font-style: normal; font-weight: 700; font-display: swap;
  src: url('fonts/zilla-slab-700.woff2') format('woff2'); }
@font-face { font-family: 'Ardoise Chalk'; font-style: normal; font-weight: 600; font-display: swap;
  src: url('fonts/caveat-600.woff2') format('woff2'); }
@font-face { font-family: 'Ardoise Sans'; font-style: normal; font-weight: 400; font-display: swap;
  src: url('fonts/work-sans-400.woff2') format('woff2'); }
@font-face { font-family: 'Ardoise Sans'; font-style: normal; font-weight: 600; font-display: swap;
  src: url('fonts/work-sans-600.woff2') format('woff2'); }

:root {
  --font-display: 'Ardoise Slab', 'Rockwell', Georgia, serif;
  --font-body: 'Ardoise Sans', system-ui, -apple-system, 'Segoe UI', sans-serif;
  --font-chalk: 'Ardoise Chalk', 'Bradley Hand', cursive;
  --display-weight: 700;
  --display-tracking: -0.01em;
  --h1: clamp(2.45rem, 10.5vw, 4.3rem);
  --h1-lh: 1.1;
  --h2: clamp(1.85rem, 7vw, 2.75rem);
  --radius: 6px;
  --radius-sm: 4px;
  --btn-radius: 6px;
  --sec-pad: 60px;
  --sec-pad-wide: 96px;
  --eyebrow-tracking: .16em;
  --shadow-1: none;
  --shadow-2: none;

  /* Slate and chalk. Every chalk colour clears 7:1 on the slate. */
  --slate: #29302D;
  --chalk: #F3EFE6;
  --chalk-soft: #C8C6BC;
  --chalk-yellow: #F0D688;
  --ecru: #E6D6B8;
  --cream: #F6EFE2;
  --enamel: var(--accent);
  --slate-tex:
    radial-gradient(ellipse 55% 26% at 28% 22%, rgba(255, 255, 255, .055), transparent 70%),
    radial-gradient(ellipse 40% 22% at 78% 78%, rgba(255, 255, 255, .04), transparent 70%),
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='180' height='180'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.85' numOctaves='2' stitchTiles='stitch'/%3E%3CfeColorMatrix values='0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 0 0 0 .09 0'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
  /* Oak: long uneven grain lines, darker at the edges. */
  --wood:
    linear-gradient(180deg, rgba(255, 235, 200, .16), transparent 30%, transparent 70%, rgba(0, 0, 0, .18)),
    repeating-linear-gradient(90deg, #8B5A31 0 3px, #7A4C28 3px 5px, #946339 5px 11px, #7F5130 11px 13px, #8E5D35 13px 19px);
  /* The awning: one red and one ecru stripe per scallop. */
  --awning: repeating-linear-gradient(90deg, var(--primary) 0 26px, var(--ecru) 26px 52px);
  /* A brass screw head, for the enamel plaque's corners. */
  --screw: #E9E3D6 0 3px, #7C7668 3.5px 4.5px, transparent 5px;
}

.preview-note { background: #1E1712; }
.site-head { background: color-mix(in srgb, var(--bg) 92%, transparent); border-bottom-color: var(--border); }
.brand {
  font-family: var(--font-display); font-weight: 700; font-size: 17px;
  text-transform: uppercase; letter-spacing: .07em; color: var(--primary);
  /* Break at the space, not at the hyphen in «Saint-Vincent». */
  text-wrap: balance;
}

.btn { letter-spacing: .01em; }
.btn-ghost { background: transparent; border: 2px solid color-mix(in srgb, var(--fg) 70%, transparent); }
.btn-ghost:hover { border-color: var(--fg); }

/* ---- the awning ----
   A valance rail, a band of stripes, and scallops cut by a mask so each
   scallop is exactly one stripe. The page opens under it and the call band
   hangs under it again; nowhere else. */
/* Clipped sideways only, so the slate can hang past the hero's bottom edge. */
.hero-sig { padding-top: 0; overflow-x: clip; overflow-y: visible; }
.hero-sig::before, .cta-band::before {
  content: ""; display: block; height: 50px;
  background:
    linear-gradient(180deg, color-mix(in srgb, var(--primary) 70%, #000) 0 7px, transparent 7px),
    linear-gradient(180deg, transparent 0 34px, rgba(0, 0, 0, .12) 34px 38px, transparent 38px),
    var(--awning);
  -webkit-mask:
    linear-gradient(#000, #000) top / 100% 37px no-repeat,
    radial-gradient(circle at 50% 0, #000 12.5px, transparent 13px) 0 37px / 26px 13px repeat-x;
  mask:
    linear-gradient(#000, #000) top / 100% 37px no-repeat,
    radial-gradient(circle at 50% 0, #000 12.5px, transparent 13px) 0 37px / 26px 13px repeat-x;
  margin-bottom: var(--s7);
}

/* ---- hero ---- */
.hero .eyebrow { color: var(--enamel); }
.hero h1 { color: var(--fg); text-wrap: balance; }
.hero .lede { max-width: 36ch; }
@media (min-width: 900px) {
  .hero-sig .hero-sig-grid { align-items: start; }
  .hero-sig .hero-main { padding-top: var(--s7); }
}

.ard-art { margin: 0; position: relative; max-width: 460px; }
@media (min-width: 900px) {
  /* The slate hangs down over the faience wall below, so it reads as hung
     in the shop rather than set in a grid cell. */
  .ard-art { margin-left: auto; z-index: 3; transform: translateY(170px) rotate(.8deg); }
}
.ard-art .sa-photo { border-radius: var(--radius); margin-bottom: var(--s5); }

/* The plaque: blue enamel, a white fillet inside the rim, a little shine
   from the top left. It hangs over the frame and overlaps it. */
.ard-plaque {
  position: relative; z-index: 2;
  display: grid; gap: 6px; justify-items: center; text-align: center;
  width: fit-content; max-width: 88%;
  margin: 0 auto -22px;
  padding: 18px 26px 16px;
  border-radius: 12px;
  background:
    linear-gradient(155deg, rgba(255, 255, 255, .20), rgba(255, 255, 255, 0) 42%),
    var(--enamel);
  box-shadow:
    inset 0 0 0 5px var(--enamel),
    inset 0 0 0 7px #F4F1EA,
    0 10px 18px -10px rgba(20, 12, 4, .55);
  transform: rotate(-2deg);
}
.ard-plaque-name {
  font-family: var(--font-display); font-weight: 700; color: #FFFFFF;
  text-transform: uppercase; letter-spacing: .05em;
  font-size: clamp(1.35rem, 6.2vw, 1.9rem); line-height: 1.12;
}
.ard-plaque-name span { display: block; }
.ard-plaque-street {
  font-size: 12px; font-weight: 600; letter-spacing: .14em; text-transform: uppercase;
  color: #DCE4F0; line-height: 1.35;
}

.ard-frame {
  padding: 13px;
  border-radius: 5px;
  background: var(--wood);
  box-shadow: 0 22px 34px -22px rgba(40, 20, 5, .65), inset 0 0 0 1px rgba(0, 0, 0, .3);
}
.ard-slate {
  display: block;
  background-color: var(--slate);
  background-image: var(--slate-tex);
  border-radius: 2px;
  box-shadow: inset 0 3px 10px rgba(0, 0, 0, .55);
  padding: 46px clamp(18px, 5vw, 30px) 22px;
  color: var(--chalk);
}
.ard-slate-t {
  display: inline-block;
  font-family: var(--font-chalk); font-weight: 600; font-size: 2.1rem; line-height: 1.15;
  padding-bottom: 6px; margin-bottom: 8px;
  /* A chalk underline, drawn by hand rather than ruled. */
  background: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='200' height='10' preserveAspectRatio='none'%3E%3Cpath d='M2 6 C40 2 80 9 120 5 S180 3 198 6' fill='none' stroke='%23F3EFE6' stroke-opacity='.75' stroke-width='2.4' stroke-linecap='round'/%3E%3C/svg%3E") left bottom / 100% 10px no-repeat;
}
.ard-list { list-style: none; margin: 0; padding: 0; }
.ard-list li {
  display: flex; align-items: baseline; flex-wrap: wrap; gap: 4px 10px;
  padding: 5px 0;
  font-family: var(--font-chalk); font-weight: 600; font-size: 1.75rem; line-height: 1.2;
}
.ard-list li::before {
  content: ""; flex: 0 0 12px; height: 2.5px; align-self: center;
  background: var(--chalk-soft); border-radius: 2px; transform: rotate(-8deg);
}
.ard-list .sa-l { flex: 1 1 20px; min-width: 20px; align-self: center; border-bottom: 2px dotted rgba(243, 239, 230, .4); }
.ard-list .sa-p {
  font-size: 1.35rem; color: var(--chalk-yellow);
  padding: 0 .45em; border: 2px solid rgba(240, 214, 136, .75);
  border-radius: 50% 46% 52% 44% / 60% 50% 56% 48%;
  transform: rotate(-3deg);
}
.ard-hours {
  margin: 14px 0 0; padding-top: 12px;
  border-top: 2px dashed rgba(243, 239, 230, .28);
  display: flex; flex-wrap: wrap; align-items: baseline; gap: 2px 12px;
}
.ard-hours-k {
  font-size: 12px; font-weight: 600; letter-spacing: .18em; text-transform: uppercase; color: var(--chalk);
}
.ard-hours-v { font-family: var(--font-chalk); font-size: 1.65rem; line-height: 1.2; color: var(--chalk-yellow); }

/* ---- sections ---- */
section + section { border-top: 0; }
.section-title, .menu-group h3 { text-align: left; }
.section-title { padding-bottom: 0; margin-bottom: var(--s5); max-width: 20ch; }
.section-title::after { display: none; }
.section-intro { text-align: left; margin-left: 0; }
.menu-1 ~ .hours-note { text-align: left; margin-inline: 0; }

/* The counter: a wall of white faience, laid in running bond, with a red
   and blue frieze along its top. What is on sale hangs on it as white enamel
   labels with a coloured rim, each from its own hook. No chalk here: a
   second slate right under the hero's read as the same board twice, the
   page's most template-like moment (2026-09-30). */
#specialites {
  position: relative;
  background-color: #FBF9F4;
  background-image:
    linear-gradient(180deg, var(--primary) 0 8px, #FBF9F4 8px 12px, var(--enamel) 12px 15px, transparent 15px),
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='72' height='36'%3E%3Cg fill='none' stroke='%23DCD5C8' stroke-width='1.5'%3E%3Cpath d='M0 .75h72M0 18.75h72M.75 0v18M36.75 18v18'/%3E%3C/g%3E%3C/svg%3E");
  background-repeat: no-repeat, repeat;
  background-position: 0 0, 0 15px;
  border-bottom: 1px solid var(--border);
}
#specialites .section-title { color: var(--fg); }
#specialites .products {
  display: grid; gap: calc(var(--s6) + 8px); grid-template-columns: 1fr;
  margin-top: var(--s6);
}
#specialites .product {
  --rim: var(--primary);
  --hook: 22%;
  position: relative;
  border: 5px solid var(--rim); border-radius: 12px;
  padding: var(--s5) var(--s5) var(--s4);
  background:
    linear-gradient(160deg, rgba(255, 255, 255, .9), rgba(255, 255, 255, 0) 38%),
    #FFFDF8;
  box-shadow:
    inset 0 0 0 3px #FFFDF8,
    inset 0 0 0 4.5px var(--rim),
    0 3px 0 -1px rgba(40, 20, 5, .12),
    0 16px 22px -16px rgba(40, 20, 5, .55);
}
#specialites .product:nth-child(4n+2) { --rim: var(--enamel); --hook: 74%; }
#specialites .product:nth-child(4n+3) { --rim: var(--enamel); --hook: 38%; }
#specialites .product:nth-child(4n+4) { --hook: 86%; }
/* The brass hook each label hangs from: a nail and a loop. */
#specialites .product::before {
  content: ""; position: absolute; top: -19px; left: var(--hook);
  width: 12px; height: 14px; transform: translateX(-50%);
  border: 3px solid #A8874F; border-bottom: 0; border-radius: 8px 8px 0 0;
}
#specialites .product::after {
  content: ""; position: absolute; top: -25px; left: var(--hook);
  width: 9px; height: 9px; transform: translateX(-50%); border-radius: 50%;
  background: radial-gradient(circle at 35% 35%, #E8D3A2, #8C6A35 70%);
}
#specialites .p-head { gap: 8px 14px; align-items: center; }
#specialites .p-name {
  font-family: var(--font-display); font-weight: 700; color: var(--fg);
  font-size: 1.55rem; line-height: 1.15; letter-spacing: -.005em;
}
/* The badge is a stamp in red enamel, not a chalk ring. */
#specialites .p-badge {
  font-family: var(--font-body); font-weight: 600; font-size: 12px;
  letter-spacing: .14em; text-transform: uppercase;
  background: var(--primary); color: #FFFFFF;
  padding: 5px 10px; border-radius: 3px;
  box-shadow: inset 0 0 0 2px var(--primary), inset 0 0 0 3px rgba(255, 255, 255, .75);
  transform: rotate(-2deg);
}
#specialites .p-desc { color: var(--fg-soft); font-size: 16px; margin-top: var(--s2); }
#specialites .product:first-child .p-name { font-size: clamp(1.9rem, 7.5vw, 2.6rem); line-height: 1.1; }
#specialites .product:first-child .p-head { flex-direction: column; align-items: flex-start; }

@media (max-width: 759px) {
  /* Hung at two widths down the wall, not a stack of equal cards. */
  #specialites .product:nth-child(even) { width: 88%; margin-left: auto; }
  #specialites .product:nth-child(4n+3) { width: 88%; }
}
@media (min-width: 760px) {
  #specialites .products { grid-template-columns: repeat(12, 1fr); gap: calc(var(--s7) + 4px) var(--s6); }
  #specialites .product { grid-column: span 6; }
  /* The first label is the big one, two rows tall; the next two sit beside
     it; a fourth that ends the list runs along the wall as a long strip. */
  #specialites .product:first-child:nth-last-child(n+3) {
    grid-column: 1 / span 7; grid-row: span 2;
    display: flex; flex-direction: column; justify-content: center;
    padding: var(--s6);
  }
  #specialites .product:first-child:nth-last-child(n+3) .p-head { margin-top: auto; }
  #specialites .product:first-child:nth-last-child(n+3) .p-desc { flex: none; font-size: 17px; max-width: 32ch; margin-bottom: auto; }
  #specialites .product:first-child:nth-last-child(n+3) ~ .product:nth-child(2),
  #specialites .product:first-child:nth-last-child(n+3) ~ .product:nth-child(3) { grid-column: 8 / span 5; }
  #specialites .product:nth-child(4):last-child {
    grid-column: 1 / span 10;
    display: flex; flex-wrap: wrap; align-items: baseline; gap: 4px var(--s6);
  }
  #specialites .product:nth-child(4):last-child .p-desc { margin-top: 0; }
}

/* The price note is a card hung on the tiles by a string. */
#specialites .hours-note {
  position: relative;
  display: block; width: fit-content; max-width: min(44ch, 100%);
  margin: calc(var(--s7) + 18px) 0 0 auto;
  background: var(--ecru); color: var(--fg);
  font-family: var(--font-display); font-weight: 700; font-size: 17px; line-height: 1.4;
  padding: var(--s3) var(--s5);
  border-radius: 3px;
  box-shadow: inset 0 0 0 1px rgba(90, 60, 20, .18), 0 10px 16px -12px rgba(40, 20, 5, .5);
  transform: rotate(1.2deg);
}
#specialites .hours-note::before {
  content: ""; position: absolute; left: 50%; top: -26px; width: 120px; height: 30px; transform: translateX(-50%);
  background: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='120' height='30'%3E%3Cpath d='M8 30 L60 5 L112 30' fill='none' stroke='%237A6440' stroke-width='1.6'/%3E%3Ccircle cx='60' cy='5' r='4' fill='%238C6A35'/%3E%3C/svg%3E") center / 100% 100% no-repeat;
}

/* ---- a carte, when the shop has one: chalk on the framed slate ---- */
#carte .menu {
  background-color: var(--slate);
  background-image: var(--slate-tex);
  border: 13px solid #8B5A31;
  border-image: repeating-linear-gradient(90deg, #8B5A31 0 3px, #7A4C28 3px 5px, #946339 5px 11px, #7F5130 11px 13px) 13;
  box-shadow: inset 0 3px 10px rgba(0, 0, 0, .55), 0 22px 34px -22px rgba(40, 20, 5, .65);
  padding: clamp(20px, 5vw, 40px);
  color: var(--chalk);
}
#carte .menu-group h3 {
  font-family: var(--font-chalk); font-weight: 600; font-size: 2rem; letter-spacing: 0;
  color: var(--chalk); border-bottom: 2px dashed rgba(243, 239, 230, .28);
}
#carte .mi-name { color: var(--chalk); }
#carte .mi-desc { color: var(--chalk-soft); }
#carte .mi-price { font-family: var(--font-chalk); font-size: 1.5rem; color: var(--chalk-yellow); }
#carte .mi-leader { border-bottom-color: rgba(243, 239, 230, .35); }

/* ---- services: paper tickets off the counter roll, no icon tiles ---- */
#services .card {
  background: var(--surface); border: 0; border-radius: 0;
  border-top: 5px solid var(--primary);
  box-shadow: 0 0 0 1px var(--border), 0 12px 20px -18px rgba(40, 20, 5, .5);
  position: relative;
}
#services .card:nth-child(even) { border-top-color: var(--enamel); }
#services .card .icon { background: transparent; width: auto; height: auto; justify-content: start; color: var(--primary); margin-bottom: var(--s3); }
#services .card h3 { font-size: 1.3rem; }

/* ---- reviews: a note pinned to the paper ---- */
.quote {
  background: transparent; border: 0; border-radius: 0;
  border-left: 4px solid var(--enamel); padding: var(--s2) 0 var(--s2) var(--s5);
}
.quote blockquote { font-size: 18px; }
.stars { color: var(--primary); }

/* ---- hours: a blue enamel plaque screwed to the wall ----
   Cream on the blue clears 9:1; today's row is a cream band in blue ink. */
#horaires .hours {
  border-collapse: separate; border-spacing: 0;
  padding: 24px 22px;
  border-radius: 14px;
  background:
    radial-gradient(circle at 15px 15px, var(--screw)),
    radial-gradient(circle at calc(100% - 15px) 15px, var(--screw)),
    radial-gradient(circle at 15px calc(100% - 15px), var(--screw)),
    radial-gradient(circle at calc(100% - 15px) calc(100% - 15px), var(--screw)),
    linear-gradient(160deg, rgba(255, 255, 255, .16), rgba(255, 255, 255, 0) 40%),
    var(--enamel);
  box-shadow:
    inset 0 0 0 6px var(--enamel),
    inset 0 0 0 7.5px var(--cream),
    0 14px 24px -16px rgba(20, 20, 40, .6);
}
#horaires .hours th, #horaires .hours td {
  padding: 11px 14px; color: var(--cream);
  border-bottom: 1px dashed rgba(246, 239, 226, .3);
}
#horaires .hours th { font-weight: 600; letter-spacing: .02em; }
#horaires .hours td { font-family: var(--font-display); font-weight: 700; }
#horaires .hours tr.today th, #horaires .hours tr.today td {
  background: var(--cream); color: var(--enamel); border-bottom-color: transparent;
}
#horaires .hours tr.today th { border-radius: 4px 0 0 4px; }
#horaires .hours tr.today td { border-radius: 0 4px 4px 0; }
#horaires .hours tr:last-child th, #horaires .hours tr:last-child td { border-bottom: 0; }
#horaires .hours-note { margin-top: var(--s5); }
.addr .label { color: var(--enamel); letter-spacing: .16em; }
.addr { font-family: var(--font-display); font-weight: 700; font-size: 1.3rem; line-height: 1.35; }
.map-frame { border-radius: 4px; border: 1px solid var(--border); }

/* ---- photos: oak frames with a linen mat, waiting on the wall ----
   Each frame carries a card naming what it waits for, the way a commission
   is pinned up, instead of a camera icon. The cues say where a photo would
   be taken, never anything about the shop. */
#photos { background: color-mix(in srgb, var(--ecru) 30%, var(--bg)); }
#photos .gallery { gap: var(--s5); }
.photo-slot {
  border: 11px solid #8B5A31;
  border-image: repeating-linear-gradient(90deg, #8B5A31 0 3px, #7A4C28 3px 5px, #946339 5px 11px, #7F5130 11px 13px) 11;
  border-radius: 0;
  background: #F1EADC;
  box-shadow: inset 0 0 0 10px #F1EADC, inset 0 0 0 11px #D8CBB3, inset 0 3px 8px 10px rgba(60, 40, 15, .10), 0 12px 18px -14px rgba(40, 20, 5, .55);
  color: var(--fg-soft); font-size: 12px; font-weight: 600; letter-spacing: .12em; text-transform: uppercase;
  gap: 10px;
}
.photo-slot svg { display: none; }
.photo-slot::before {
  display: block; justify-self: center;
  font-family: var(--font-display); font-weight: 700; font-size: 1.25rem; line-height: 1.2;
  letter-spacing: 0; text-transform: none; color: var(--fg);
  background: #FFFDF8; padding: 7px 16px 8px;
  border-radius: 2px; border-top: 3px solid var(--primary);
  box-shadow: 0 6px 10px -8px rgba(40, 20, 5, .55), inset 0 0 0 1px var(--border);
  transform: rotate(-2deg);
}
.gallery > .photo-slot:nth-child(1)::before { content: "La devanture"; }
.gallery > .photo-slot:nth-child(2)::before { content: "Le comptoir"; transform: rotate(1.5deg); border-top-color: var(--enamel); }
.gallery > .photo-slot:nth-child(3)::before { content: "À l'intérieur"; transform: rotate(-1deg); }

/* ---- contact: the order slip, torn off a pad ----
   A header row says what the slip is. From 880px the slip starts level with
   the heading and the left column rides beside it as the page scrolls. */
#contact form {
  position: relative;
  display: grid; grid-template-columns: 1fr; column-gap: var(--s4);
  background: var(--surface);
  padding: var(--s5);
  box-shadow: 0 16px 26px -20px rgba(40, 20, 5, .45), 0 0 0 1px var(--border);
}
#contact form > * { grid-column: 1 / -1; min-width: 0; }
#contact form::before {
  content: ""; position: absolute; left: 0; right: 0; top: -7px; height: 8px;
  background: radial-gradient(circle at 7px 0, transparent 5px, var(--surface) 5.5px) 0 0 / 14px 8px repeat-x;
}
#contact form::after {
  content: "Bon de commande"; order: -1; grid-column: 1 / -1;
  font-family: var(--font-display); font-weight: 700; font-size: 1.35rem; line-height: 1.2;
  color: var(--primary); letter-spacing: .01em;
  padding-bottom: 10px; margin-bottom: var(--s5);
  border-bottom: 4px double var(--primary);
}
@media (min-width: 880px) {
  #contact .wrap { display: grid; grid-template-columns: 5fr 6fr; grid-template-rows: auto 1fr; column-gap: var(--s7); 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; margin-top: 7px; grid-template-columns: 1fr 1fr; }
  #contact form > .field:nth-of-type(1) { grid-column: 1; }
  #contact form > .field:nth-of-type(2) { grid-column: 2; }
}
#contact .field input, #contact .field textarea {
  background: transparent; border: 0; border-radius: 0;
  /* The only edge the field has, so it is held to the 3:1 of a control. */
  border-bottom: 2px solid color-mix(in srgb, var(--fg) 62%, var(--surface));
  padding-left: 2px; padding-right: 2px;
}
/* The message field is ruled like a carbon pad. */
#contact .field textarea {
  background: repeating-linear-gradient(180deg, transparent 0 31px, color-mix(in srgb, var(--enamel) 22%, var(--surface)) 31px 32px);
  line-height: 32px; padding-top: 0;
}
#contact .field input:focus, #contact .field textarea:focus { border-bottom-color: var(--enamel); outline-offset: 4px; }
#contact .field.invalid input, #contact .field.invalid textarea { border-bottom-color: var(--bad); }

/* ---- the call band: a painted shop sign under the awning ---- */
.cta-band { background: transparent; color: var(--fg); padding-top: 0; }
.cta-band::before { margin-bottom: 0; }
.cta-band .wrap {
  background: var(--primary); color: var(--primary-ink);
  padding: clamp(36px, 7vw, 60px) var(--s5);
  box-shadow: inset 0 0 0 8px var(--primary), inset 0 0 0 10px #E9C77F;
  max-width: calc(var(--maxw) - var(--s5) * 2);
  width: calc(100% - var(--s4) * 2);
}
.cta-band h2 { color: #FFFFFF; text-transform: uppercase; letter-spacing: .03em; }
.cta-band p { opacity: 1; color: #FFFFFF; }
.cta-band .cta-num { color: #FFFFFF; }
.btn-oncta { background: #FFFFFF; color: var(--primary); border-color: #FFFFFF; }

.site-foot { border-top: 0; position: relative; }
.site-foot::before {
  content: ""; position: absolute; left: 0; right: 0; top: 0; height: 7px;
  background: linear-gradient(180deg, var(--primary) 0 4px, var(--bg) 4px 5px, var(--enamel) 5px 7px);
}
.site-foot h4 { color: var(--enamel); }
.action-bar { background: color-mix(in srgb, var(--bg) 95%, transparent); }

/* ---- phone ---- */
/* Under 900px the plaque and the slate come first, straight under the
   awning, so the first screen is the shop front and not the shared headline
   skeleton. The slate is written smaller and loses its phone line: the call
   button under the headline and the sticky bar both carry the number. */
@media (max-width: 899.98px) {
  .hero-sig::before { margin-bottom: var(--s5); }
  .hero-sig-grid { gap: var(--s5); }
  .hero-sig .hero-art { order: -1; }
  .ard-art { max-width: 420px; margin-inline: auto; }
  .ard-art .sa-photo { max-height: 180px; object-fit: cover; margin-bottom: var(--s4); }
  .ard-plaque { padding: 12px 20px 11px; gap: 3px; margin-bottom: -16px; }
  .ard-plaque-name { font-size: clamp(1.2rem, 5.4vw, 1.6rem); line-height: 1.12; }
  .ard-plaque-street { font-size: 11px; }
  .ard-frame { padding: 10px; }
  .ard-slate { padding: 30px 18px 12px; }
  .ard-slate-t { font-size: 1.75rem; padding-bottom: 4px; margin-bottom: 2px; }
  .ard-list li { padding: 1px 0; }
  .ard-hours { display: none; }
  .hero .eyebrow { margin-bottom: var(--s2); }
}
/* On a phone the badge cannot share a line with the name: it drops under
   it, indented to the chalk dash, and the leader that would point at
   nothing goes. */
@media (max-width: 480px) {
  .ard-list li { font-size: 1.4rem; }
  .ard-list .sa-l { display: none; }
  .ard-list .sa-p { margin-left: 22px; font-size: 1.1rem; }
  .photo-slot {
    letter-spacing: .08em; font-size: 11px; border-width: 9px; gap: 6px;
    box-shadow: inset 0 0 0 7px #F1EADC, inset 0 0 0 8px #D8CBB3, 0 12px 18px -14px rgba(40, 20, 5, .55);
  }
  .photo-slot::before { font-size: 1.05rem; padding: 5px 10px 6px; }
  #horaires .hours { padding: 20px 12px; }
  #horaires .hours th, #horaires .hours td { padding: 10px 10px; }
}

/* ---- the map, in the slate's wooden frame. ---- */
.map-frame { padding: 10px; background: var(--wood); border: 0; box-shadow: 0 16px 24px -18px rgba(40, 20, 5, .6); }
.map-frame iframe { border-radius: 2px; filter: sepia(.18) saturate(.9); }

/* ---- the call, underlined in chalk ----
   Pointing at a call button (only where there is a pointer), tabbing to it
   or pressing it draws a chalk line under its words, left to right, the way
   the price on the slate gets underlined. Nothing moves until touched. */
.btn-primary, .btn-oncta { position: relative; -webkit-tap-highlight-color: transparent; }
.btn-primary::after, .btn-oncta::after {
  content: ""; position: absolute; left: 18%; right: 18%; bottom: 8px; height: 2px;
  border-radius: 2px; pointer-events: none; opacity: .85;
  background: repeating-linear-gradient(90deg, currentColor 0 13px, transparent 13px 15px, currentColor 15px 31px, transparent 31px 32px);
  transform: scaleX(0); transform-origin: left center;
}
@media (hover: hover) {
  .btn-primary:hover::after, .btn-oncta:hover::after { transform: scaleX(1); }
}
.btn-primary:focus-visible::after, .btn-oncta:focus-visible::after,
.btn-primary:active::after, .btn-oncta:active::after { transform: scaleX(1); }
@media (prefers-reduced-motion: no-preference) {
  .btn-primary::after, .btn-oncta::after { transition: transform .38s cubic-bezier(.3, .7, .3, 1); }
  .btn-primary:active::after, .btn-oncta:active::after { animation: ardoise-chalk .26s ease-out; }
  @keyframes ardoise-chalk { from { transform: scaleX(0); } to { transform: scaleX(1); } }
}

/* ---- the lines move (owner, fb-0097) ----
   Light slides across the blue enamel plaque now and then, the shine it
   already has from the top left travelling over it. (The awning's breathing
   was too small to see: owner, 2026-09-30.) */
.ard-plaque { overflow: hidden; }
@media (prefers-reduced-motion: no-preference) {
  .ard-plaque::after {
    content: ""; position: absolute; top: 0; bottom: 0; left: 0; width: 40%; pointer-events: none;
    background: linear-gradient(90deg, transparent, rgba(255, 255, 255, .32) 50%, transparent);
    animation: ard-shine 7s ease-in-out infinite;
  }
  @keyframes ard-shine {
    0%, 55% { transform: translateX(-160%) skewX(-18deg); }
    85%, 100% { transform: translateX(360%) skewX(-18deg); }
  }
}
