/* 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: #3FD0FF;
  --primary-ink: #04141C;
  --accent: #FFB648;
  --bg: #0B1220;
  --surface: #121C2E;
  --fg: #EEF3F8;
  --fg-soft: #A9B8C9;
  --border: #24324A;
  /* 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: #4ade80;
  --bad: #f87171;

  --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: Néon. A cocktail bar at night: dark ground, the name lit as a
   sign, a warm amber for the prices and a pink tube for emphasis. Section
   titles sit flush left over a short lit tube, never centred over a rule. */

@font-face { font-family: 'Neon Script'; font-style: normal; font-weight: 400; font-display: swap;
  src: url('fonts/yellowtail-400.woff2') format('woff2'); }
@font-face { font-family: 'Neon Display'; font-style: normal; font-weight: 500; font-display: swap;
  src: url('fonts/bricolage-grotesque-500.woff2') format('woff2'); }
@font-face { font-family: 'Neon Display'; font-style: normal; font-weight: 700; font-display: swap;
  src: url('fonts/bricolage-grotesque-700.woff2') format('woff2'); }
@font-face { font-family: 'Neon Sans'; font-style: normal; font-weight: 400; font-display: swap;
  src: url('fonts/dm-sans-400.woff2') format('woff2'); }
@font-face { font-family: 'Neon Sans'; font-style: normal; font-weight: 600; font-display: swap;
  src: url('fonts/dm-sans-600.woff2') format('woff2'); }

:root {
  --font-display: 'Neon Display', 'Arial Narrow', system-ui, sans-serif;
  --font-body: 'Neon Sans', system-ui, -apple-system, 'Segoe UI', sans-serif;
  --font-script: 'Neon Script', 'Brush Script MT', cursive;
  --display-weight: 700;
  --display-tracking: -0.025em;
  --h1: clamp(2.5rem, 10vw, 4.6rem);
  --h1-lh: 1.0;
  --h2: clamp(1.9rem, 7vw, 3rem);
  --radius: 6px;
  --radius-sm: 4px;
  --btn-radius: 999px;
  --sec-pad: 64px;
  --sec-pad-wide: 104px;
  --shadow-1: none;
  --shadow-2: none;
  --glow: 0 0 2px #fff, 0 0 8px var(--primary), 0 0 22px var(--primary), 0 0 42px color-mix(in srgb, var(--primary) 60%, transparent);
}

.preview-note { background: #0b0710; }
.site-head { background: color-mix(in srgb, var(--bg) 84%, transparent); }
.brand { font-family: var(--font-script); font-size: 30px; letter-spacing: 0; color: var(--primary);
  text-shadow: 0 0 10px color-mix(in srgb, var(--primary) 55%, transparent); }

/* ---- hero ---- */
.hero-sig { padding-top: var(--s7); overflow: hidden; }
.hero .eyebrow { color: var(--accent); }
.hero h1 { font-weight: 700; }
.hero .lede { max-width: 38ch; }
.btn-ghost { background: transparent; color: var(--fg); border-color: color-mix(in srgb, var(--fg) 30%, transparent); }
.btn-primary { box-shadow: 0 0 0 1px color-mix(in srgb, var(--primary) 70%, #fff), 0 0 24px -4px color-mix(in srgb, var(--primary) 70%, transparent); }

.neon-wall {
  position: relative; margin: 0;
  border-radius: var(--radius);
  padding: clamp(28px, 6vw, 48px) clamp(20px, 5vw, 40px) clamp(24px, 5vw, 36px);
  /* Brick: a running bond drawn in two gradients, darker mortar lines on the
     ground colour. No image, so it costs nothing and never fails to load. */
  background-color: #1d1322;
  background-image:
    radial-gradient(ellipse at 50% 38%, color-mix(in srgb, var(--primary) 22%, transparent), transparent 62%),
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='64' height='56'%3E%3Cg fill='none' stroke='%23110a15' stroke-width='2'%3E%3Cpath d='M0 1h64M0 29h64M1 1v28M33 29v28'/%3E%3C/g%3E%3C/svg%3E");
  background-size: 100% 100%, 64px 56px;
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--fg) 8%, transparent), inset 0 -60px 80px -40px #000;
  text-align: center;
}
.neon-wall .sa-photo { border-radius: var(--radius-sm); margin-bottom: var(--s5); }
.neon-sign { display: grid; justify-items: center; gap: var(--s3); }
.neon-word {
  font-family: var(--font-script);
  font-size: clamp(3.4rem, 15vw, 6rem);
  line-height: 1.05;
  color: #ffe9f3;
  text-shadow: var(--glow);
  transform: rotate(-4deg);
  padding: 0 .1em;
}
.neon-tube {
  width: min(72%, 280px); height: 4px; border-radius: 4px;
  background: color-mix(in srgb, var(--accent) 80%, #fff);
  box-shadow: 0 0 6px var(--accent), 0 0 18px var(--accent);
}
.neon-street { font-size: 13px; letter-spacing: .16em; text-transform: uppercase; color: color-mix(in srgb, var(--fg) 78%, transparent); }

.neon-plate {
  margin: clamp(24px, 5vw, 36px) auto 0;
  max-width: 300px;
  background: linear-gradient(180deg, #2a2030, #1b1420);
  border: 1px solid color-mix(in srgb, var(--accent) 45%, transparent);
  border-radius: 4px;
  padding: var(--s4) var(--s5);
  text-align: left;
  position: relative;
}
/* Two screws, because it is a plate and not a card. */
.neon-plate::before, .neon-plate::after {
  content: ""; position: absolute; top: 8px; width: 6px; height: 6px; border-radius: 50%;
  background: color-mix(in srgb, var(--accent) 60%, #333);
}
.neon-plate::before { left: 8px; } .neon-plate::after { right: 8px; }
.neon-plate-t {
  display: block; text-align: center; margin-bottom: var(--s2);
  font-size: 12px; letter-spacing: .22em; text-transform: uppercase; color: var(--accent); font-weight: 600;
}
.neon-week { list-style: none; margin: 0; padding: 0; font-size: 14.5px; font-variant-numeric: tabular-nums; }
.neon-week li { display: flex; justify-content: space-between; gap: var(--s4); padding: 3px 0;
  border-bottom: 1px dashed color-mix(in srgb, var(--fg) 14%, transparent); }
.neon-week li:last-child { border-bottom: 0; }
.neon-week .sa-d { color: var(--fg-soft); }
.neon-week .sa-h { color: var(--fg); font-weight: 600; }

/* Phone: the lit sign is the first thing under the header, compacted to a
   strip of brick, and the hours plate goes because #horaires repeats it. */
@media (max-width: 899.98px) {
  :root { --h1-lh: 1.1; }
  .hero-sig { padding-top: var(--s5); }
  .hero-sig-grid { gap: var(--s5); }
  .hero-sig .hero-art { order: -1; }
  .neon-wall { padding: 22px 16px 18px; }
  .neon-wall .sa-photo { max-height: 180px; object-fit: cover; margin-bottom: var(--s4); }
  .neon-sign { gap: var(--s2); }
  .neon-word { font-size: clamp(2.8rem, 13vw, 3.6rem); }
  .neon-tube { width: min(60%, 220px); height: 3px; }
  .neon-street { font-size: 12px; letter-spacing: .14em; }
  .neon-plate { display: none; }
  .hero .eyebrow { margin-bottom: var(--s2); }
}

/* Desktop: the wall IS the hero. The brick runs the full width of the
   window, the name hangs lit across the middle of it at shop-sign size, the
   plate is screwed to the wall at the right, and the headline sits under
   the sign on the left with the lede and the buttons beside it, the way a
   bar's chalk line sits under its sign. From 1100px: between 900 and 1100
   the two columns of the base stay, since the sign needs the width. */
@media (min-width: 1100px) {
  .hero-sig {
    padding: 0 0 var(--s7);
    background-color: #1d1322;
    background-image:
      radial-gradient(ellipse 60% 55% at 50% 30%, color-mix(in srgb, var(--primary) 20%, transparent), transparent 70%),
      linear-gradient(180deg, transparent 60%, var(--bg)),
      url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='64' height='56'%3E%3Cg fill='none' stroke='%23110a15' stroke-width='2'%3E%3Cpath d='M0 1h64M0 29h64M1 1v28M33 29v28'/%3E%3C/g%3E%3C/svg%3E");
    background-size: 100% 100%, 100% 100%, 64px 56px;
  }
  .hero-sig-grid {
    grid-template-columns: minmax(0, 1.25fr) minmax(0, 1fr);
    grid-template-areas: "art art" "eyebrow ." "h1 lede" "h1 actions" "h1 status";
    column-gap: var(--s9); row-gap: 0; align-items: start;
  }
  .hero-sig .hero-main { display: contents; }
  .hero-sig .eyebrow { grid-area: eyebrow; }
  .hero-sig h1 { grid-area: h1; margin: 0; font-size: clamp(3.4rem, 5vw, 4.6rem); }
  .hero-sig .lede { grid-area: lede; align-self: end; max-width: 36ch; margin-top: var(--s2); }
  .hero-sig .hero-actions { grid-area: actions; }
  .hero-sig .status-line { grid-area: status; justify-self: start; }
  .hero-sig .hero-art { grid-area: art; }
  .neon-wall {
    background: none; box-shadow: none; border-radius: 0;
    padding: var(--s9) 0 var(--s8);
    display: grid; grid-template-columns: 1fr auto 1fr; align-items: center;
  }
  .neon-wall .sa-photo { grid-column: 1 / -1; max-height: 420px; object-fit: cover; }
  .neon-sign { grid-column: 2; gap: var(--s4); }
  .neon-word { font-size: clamp(7rem, 11vw, 10.5rem); line-height: 1; }
  .neon-tube { width: 100%; height: 5px; }
  .neon-street { font-size: 15px; letter-spacing: .3em; }
  .neon-plate {
    grid-column: 3; justify-self: end; align-self: end;
    margin: 0 0 calc(-1 * var(--s7)); width: 224px; transform: rotate(2deg);
    box-shadow: 0 18px 30px -12px #000;
  }
  .neon-plate-t { margin-top: var(--s1); }
}

/* ---- the call lights like a tube ----
   Every call button carries its lit glow already drawn on a ::after, off.
   Pointing at it (only where there is a pointer: a phone keeps :hover stuck
   after a tap), tabbing to it or pressing it turns the glow on, and a press
   strikes it the way a tube catches: on, a stutter, on. Only the glow's
   opacity moves, so nothing on the page shifts, and the look is the
   brightening itself, not a colour that darkens under the finger as the
   base does. */
.btn-primary, .btn-oncta { position: relative; -webkit-tap-highlight-color: transparent; }
.btn-primary::after, .btn-oncta::after {
  content: ""; position: absolute; inset: -1px; border-radius: inherit; pointer-events: none;
  box-shadow:
    inset 0 0 10px color-mix(in srgb, #fff 45%, transparent),
    0 0 0 1px color-mix(in srgb, var(--primary) 40%, #fff),
    0 0 16px 2px var(--primary),
    0 0 46px 10px color-mix(in srgb, var(--primary) 70%, transparent);
  opacity: 0;
}
.btn-primary:hover, .btn-oncta:hover { background: color-mix(in srgb, var(--primary) 85%, #fff); }
@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 .3s ease-out; }
  .btn-primary:active::after, .btn-oncta:active::after { animation: neon-strike .42s linear; }
  @keyframes neon-strike {
    0% { opacity: 0; } 18% { opacity: 1; } 30% { opacity: .2; }
    44% { opacity: 1; } 58% { opacity: .55; } 70%, 100% { opacity: 1; }
  }
  .neon-word { animation: neon-hum 7s infinite; }
  @keyframes neon-hum {
    0%, 91%, 100% { opacity: 1; }
    92% { opacity: .55; } 93% { opacity: 1; } 95% { opacity: .7; } 96% { opacity: 1; }
  }
}

/* ---- sections ---- */
section + section { border-top: 0; }
.section-title, .menu-group h3 { text-align: left; }
.section-title { padding-bottom: var(--s4); position: relative; margin-bottom: var(--s6); }
.section-title::after {
  content: ""; position: absolute; left: 0; bottom: 0; transform: none;
  width: 72px; height: 3px; border: 0; border-radius: 3px;
  background: var(--primary);
  box-shadow: 0 0 8px var(--primary), 0 0 20px color-mix(in srgb, var(--primary) 60%, transparent);
}
.section-intro { text-align: left; margin-left: 0; }
.menu-1 ~ .hours-note { text-align: left; margin-inline: 0; }

/* The carte: two columns of lines on a slightly lifted board. */
#carte .menu {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: clamp(20px, 4vw, 40px);
}
.menu-group h3 {
  font-family: var(--font-script); font-weight: 400; font-size: 2rem; letter-spacing: 0;
  color: var(--primary); border-bottom-color: var(--border);
}
.mi-name { font-weight: 600; }
.mi-price { color: var(--accent); }
.mi-leader { border-bottom-color: color-mix(in srgb, var(--accent) 40%, transparent); }

/* Gallery frames: empty, and saying so, but as frames on a wall. */
.gallery { gap: var(--s4); }
.photo-slot {
  border: 1px solid color-mix(in srgb, var(--fg) 16%, transparent);
  background:
    repeating-linear-gradient(135deg, transparent 0 14px, color-mix(in srgb, var(--fg) 3%, transparent) 14px 15px),
    var(--surface);
  color: var(--fg-soft);
}
.photo-slot svg { opacity: .7; color: var(--primary); }

/* The band: not a slab of colour, a lit frame on the dark. */
.cta-band {
  background: transparent; color: var(--fg);
  margin: 0 var(--s5);
}
.cta-band .wrap {
  border: 2px solid var(--primary); border-radius: 18px;
  padding: clamp(32px, 6vw, 56px) var(--s5);
  box-shadow: 0 0 18px -2px var(--primary), inset 0 0 18px -6px var(--primary);
}
.cta-band h2 { font-family: var(--font-script); font-weight: 400; letter-spacing: 0; font-size: clamp(2.3rem, 8vw, 3.4rem);
  color: #ffe9f3; text-shadow: var(--glow); }
.btn-oncta { background: var(--primary); color: var(--primary-ink); border-color: var(--primary); }
.btn-oncta:hover { background: color-mix(in srgb, var(--primary) 85%, #fff); }
.cta-band .cta-num { color: var(--accent); }

.hours th, .hours td { border-bottom-color: var(--border); }
.addr .label, .site-foot h4 { color: var(--accent); }
.field input, .field textarea { border-color: color-mix(in srgb, var(--fg) 30%, var(--border)); background: #1a121f; }
.site-foot { border-top-color: var(--border); }
.action-bar { background: color-mix(in srgb, var(--bg) 92%, transparent); }

/* ---- hours and access: the week on the same screwed plate as the hero's,
   and the map at night. The embed is OpenStreetMap's day tiles; inverted and
   turned back round the hue wheel they read as streets under street lamps,
   and the pin keeps its colour family. ---- */
#horaires .hours-layout > div:first-child {
  position: relative;
  background: linear-gradient(180deg, #2a2030, #1b1420);
  border: 1px solid color-mix(in srgb, var(--accent) 45%, transparent);
  border-radius: 4px;
  padding: var(--s5) var(--s5) var(--s4);
}
#horaires .hours-layout > div:first-child::before,
#horaires .hours-layout > div:first-child::after {
  content: ""; position: absolute; top: 10px; width: 7px; height: 7px; border-radius: 50%;
  background: color-mix(in srgb, var(--accent) 60%, #333);
}
#horaires .hours-layout > div:first-child::before { left: 10px; }
#horaires .hours-layout > div:first-child::after { right: 10px; }
#horaires .hours td { color: var(--fg); }
.map-frame {
  border: 2px solid var(--primary); border-radius: 12px;
  box-shadow: 0 0 14px -2px var(--primary);
  background: #1a121f;
}
.map-frame iframe { filter: invert(.92) hue-rotate(180deg) saturate(.7) brightness(.95); }

/* ---- contact: the heading, the words and the call ride in the left column
   beside the form, so the column is never an empty half of the page. ---- */
@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; }
}
#contact form {
  background: var(--surface);
  border: 1px solid var(--border); border-radius: 14px;
  padding: clamp(20px, 4vw, 36px);
  box-shadow: inset 0 0 22px -12px var(--primary);
}
#contact .section-intro { font-size: 1.15rem; }

/* ---- the lines move (owner, fb-0097) ----
   The lit tube under each section title strikes on once, the way a tube
   catches, when its title scrolls in. The name's hum stays the loop. */
@media (prefers-reduced-motion: no-preference) {
  .section-title.reveal::after { opacity: 0; }
  .section-title.reveal.in::after { opacity: 1; animation: neon-title-strike .9s linear .25s both; }
  @keyframes neon-title-strike {
    0% { opacity: 0; } 20% { opacity: 1; } 32% { opacity: .15; }
    46% { opacity: 1; } 60% { opacity: .5; } 72%, 100% { opacity: 1; }
  }
}
