/* CreoHaus site stylesheet (new design, Berry and Tangerine, 2026-09-21).
   Order: brand tokens > section token bridge > site base > textures > recipes > CreoHaus knob settings > button system.
   Recipe blocks are copied verbatim from _agency-ops/section-library; fix them in the master, never here. */

/* ---- Brand tokens (design-system.md section 2) ---- */
:root {
  --paper: #FFF8E8; --paper-2: #FBEBD6; --ink: #3A0F22; --berry-mid: #551A33; --ink-soft: #6B4556;
  --light: #FFF3E4; --muted: #B48C9C; --tangerine: #E55D25; --tangerine-hover: #F07A45;
  --play-berry: #E4BACB; --play-periwinkle: #BCC6FF; --play-mint: #C6E8C3; --play-butter: #F7D98A;
  --line: rgba(58, 15, 34, 0.12); --line-dark: rgba(255, 243, 228, 0.14);
  --container-max: calc((100vw + 1408px) / 2);   /* whole site = hero width: side margins halved */
  --section-pad: 90px;
}
@media (min-width: 768px) { :root { --section-pad: 130px; } }

/* ==== SECTION TOKEN BRIDGE (section library) ==== */
:root {
  --sl-light-bg: var(--paper);
  --sl-light-surface: var(--paper-2);
  --sl-light-surface-2: var(--paper-2);
  --sl-light-text: var(--ink);
  --sl-light-muted: var(--ink-soft);
  --sl-light-border: var(--line);
  --sl-dark-bg: var(--ink);
  --sl-dark-surface: var(--berry-mid);
  --sl-dark-surface-2: var(--berry-mid);
  --sl-dark-text: var(--light);
  --sl-dark-muted: var(--muted);
  --sl-dark-border: var(--line-dark);
  --sl-accent: var(--tangerine);
  --sl-on-accent: var(--ink);
  --sl-radius: 0px;
  --sl-radius-sm: 0px;
  --sl-shadow: 0 1px 2px rgba(58, 15, 34, 0.06), 0 12px 32px rgba(58, 15, 34, 0.10);
  --sl-ease: cubic-bezier(0.4, 0, 0.2, 1);
  --sl-font-display: "Big Shoulders Display", sans-serif;
  --sl-font-body: "DM Sans", sans-serif;
}
:root, [data-band="light"] { --sl-bg: var(--sl-light-bg); --sl-surface: var(--sl-light-surface); --sl-surface-2: var(--sl-light-surface-2); --sl-text: var(--sl-light-text); --sl-muted: var(--sl-light-muted); --sl-border: var(--sl-light-border); }
[data-band="dark"] { --sl-bg: var(--sl-dark-bg); --sl-surface: var(--sl-dark-surface); --sl-surface-2: var(--sl-dark-surface-2); --sl-text: var(--sl-dark-text); --sl-muted: var(--sl-dark-muted); --sl-border: var(--sl-dark-border); }
/* ==== END SECTION TOKEN BRIDGE ==== */

/* ---- Site base ---- */
*, *::before, *::after { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; scroll-padding-top: 100px; }   /* anchors clear the sticky header */
body { margin: 0; background: var(--paper); color: var(--ink); font-family: var(--sl-font-body); font-size: 17px; font-weight: 400; line-height: 1.7; -webkit-font-smoothing: antialiased; }
@media (max-width: 767px) { body { font-size: 16px; } }
h1, h2, h3, h4 { margin: 0; font-family: var(--sl-font-display); font-weight: 800; line-height: 1.02; letter-spacing: -0.02em; text-transform: uppercase; text-wrap: balance; }
h2 { font-size: clamp(40px, 5vw, 64px); }
h3 { font-size: 22px; }
p { margin: 0; }
a { color: inherit; }
ul, ol { margin: 0; padding: 0; }
img, video { max-width: 100%; display: block; }
.container { max-width: var(--container-max); margin: 0 auto; padding: 0 24px; }
.section { padding: var(--section-pad) 0; }
/* Two same-band sections in a row: the first drops its bottom padding, so the gap between them is one
   section padding, not two (Yvad, 2026-09-22). Comments between sections don't break the + combinator. */
.section[data-band="light"]:has(+ .section[data-band="light"]),
.section[data-band="dark"]:has(+ .section[data-band="dark"]) { padding-bottom: 0; } /* same-band neighbours */
.eyebrow { display: block; font-size: 13px; font-weight: 600; letter-spacing: 0.14em; text-transform: uppercase; line-height: 1.4; color: var(--tangerine); }
[data-band="light"] .eyebrow { color: var(--ink); } /* Tangerine fails AA at 13px on Paper (3.35:1) */
.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; }

/* Global reveal: fade-up on scroll, ~120ms stagger via --d (design-system.md section 8). */
[data-reveal] { opacity: 0; transform: translateY(24px); transition: opacity 800ms ease, transform 800ms ease; transition-delay: var(--d, 0ms); }
[data-reveal].is-in { opacity: 1; transform: none; }
@media (prefers-reduced-motion: reduce) { [data-reveal] { opacity: 1; transform: none; transition: none; } }

/* Photo / video placeholder until real media exists (never stock). */
.sl-ph { position: absolute; inset: 0; display: flex; align-items: center; justify-content: center; padding: 16px; text-align: center; font-size: 13px; font-weight: 600; letter-spacing: 0.1em; text-transform: uppercase; color: var(--sl-muted);
  background: repeating-linear-gradient(135deg, rgba(58,15,34,.06) 0 2px, transparent 2px 22px), var(--sl-surface-2); }
[data-band="dark"] .sl-ph { background: repeating-linear-gradient(135deg, rgba(255,243,228,.06) 0 2px, transparent 2px 22px), var(--sl-surface-2); }

/* Welcome video stand-in until the real film exists (placeholder, per HERO-FINAL.md). */
.ch-vid-ph { position: absolute; inset: 0; overflow: hidden; display: flex; align-items: flex-start; padding: 18px 20px; font-size: 13px; font-weight: 600; letter-spacing: .1em; text-transform: uppercase; color: var(--muted);
  background: repeating-linear-gradient(135deg, rgba(255,243,228,.05) 0 2px, transparent 2px 22px), var(--berry-mid); }

/* ==== RECIPES ==== */

/* recipe: nav/2026-09_creohaus_keyline-box-nav */
/* ==== RECIPE CSS START: nav/2026-09_creohaus_keyline-box-nav ==== */
/* Logo left; on the right a keylined box of links with the primary action butted against it, both one button
   height tall. Links roll: each word is two stacked copies, the second in the hover colour, and hover rolls the
   stack up one line (transform only), back down on leave. An optional hub opens a keylined panel instantly on
   hover or tap. Phones: logo + burger, and a keylined panel that slides down from under the bar over a blurred
   scrim. The header is not sticky: it scrolls away with the page. */
.sl-kbn {
  --sl-kbn-link-size: 20px;                     /* knob: link type size (display face, uppercase) */
  --sl-kbn-box: var(--sl-bg);                   /* knob: fill of the links box, the dropdown and the phone panel */
  --sl-kbn-hover: var(--sl-accent);             /* knob: link hover and current-page colour */
  --sl-kbn-h: var(--btn-height, 56px);          /* box height = the site's one button height */
  position: relative;
  z-index: 1100000;
  color: var(--sl-text);
  padding: 16px 0;
}
.sl-kbn[data-overlay] { position: absolute; top: 0; left: 0; right: 0; }
/* Knob data-sticky: pinned to the top of the screen (takes no space, like data-overlay). Once the page scrolls, a bar
   background fades in behind it (opacity only) so it stays readable over any band. No transform on the header: it
   would trap the fixed scrim inside the header. */
.sl-kbn[data-sticky] { position: fixed; top: 0; left: 0; right: 0; }
.sl-kbn[data-sticky]::before {
  content: ""; position: absolute; inset: 0; z-index: -3; pointer-events: none;
  background: var(--sl-kbn-bar, var(--sl-bg)); border-bottom: 1px solid var(--sl-border); box-shadow: var(--sl-shadow);
  opacity: 0; transition: opacity 250ms ease;
}
.sl-kbn[data-sticky].is-scrolled::before, .sl-kbn[data-sticky].is-open::before { opacity: 1; }
.sl-kbn:not([data-overlay]) { background: var(--sl-bg); }
.sl-kbn__bar { display: flex; align-items: center; justify-content: space-between; gap: 16px; min-height: var(--sl-kbn-h); }
.sl-kbn__logo { display: inline-flex; align-items: center; flex: none; }
.sl-kbn__logo img { height: var(--sl-kbn-logo-h, 32px); width: auto; display: block; }
.sl-kbn__logo:focus-visible { outline: 2px solid var(--sl-text); outline-offset: 4px; }

/* Desktop: the box + the action. */
.sl-kbn__end { display: none; align-items: stretch; }
.sl-kbn__box {
  display: flex; align-items: center; gap: 36px;
  height: var(--sl-kbn-h); padding: 0 24px;
  background: var(--sl-kbn-box); border: 1px solid var(--sl-text); border-right: 0;
  border-radius: var(--sl-radius) 0 0 var(--sl-radius);
}
@media (min-width: 1024px) {
  .sl-kbn__end { display: flex; }
}

/* A link: a one-line window over two stacked copies. */
.sl-kbn__link {
  position: relative; display: inline-flex; align-items: center; gap: 6px;
  font-family: var(--sl-font-display); font-size: var(--sl-kbn-link-size); font-weight: 800;
  line-height: 1.15; letter-spacing: 0.01em; text-transform: uppercase;
  color: var(--sl-text); text-decoration: none; white-space: nowrap;
  background: none; border: 0; padding: 0; cursor: pointer;
}
.sl-kbn__roll { position: relative; display: block; overflow: hidden; line-height: 1.2; }   /* no padding: the copy must land exactly where the first sat */
.sl-kbn__roll > span { display: block; transition: transform 280ms cubic-bezier(0, 0.1, 0.95, 0.9); }
.sl-kbn__roll > span + span { position: absolute; left: 0; right: 0; top: 100%; color: var(--sl-kbn-hover); }
.sl-kbn__link:hover .sl-kbn__roll > span,
.sl-kbn__link:focus-visible .sl-kbn__roll > span,
.sl-kbn__dd.is-open .sl-kbn__trigger .sl-kbn__roll > span { transform: translateY(-100%); }
.sl-kbn__link.is-active { color: var(--sl-kbn-hover); }
.sl-kbn__link:focus-visible { outline: 2px solid var(--sl-text); outline-offset: 6px; }
.sl-kbn__link:active { transform: translateY(1px); }

/* Optional hub: opens instantly on hover (desktop) or tap / Enter (anywhere). The ::before bridge keeps the hover
   alive across the gap to the panel. */
.sl-kbn__dd { position: relative; display: flex; align-items: center; height: 100%; }
.sl-kbn__dd::before { content: ""; position: absolute; top: 100%; left: -24px; right: -24px; height: 28px; }
.sl-kbn__caret { position: relative; width: 16px; height: 16px; flex: none; }
.sl-kbn__caret svg { position: absolute; inset: 0; width: 16px; height: 16px; transition: opacity 280ms ease; }
.sl-kbn__caret svg + svg { opacity: 0; color: var(--sl-kbn-hover); }
.sl-kbn__dd.is-open .sl-kbn__caret svg:first-child { opacity: 0; }
.sl-kbn__dd.is-open .sl-kbn__caret svg + svg { opacity: 1; }
.sl-kbn__panel {
  position: absolute; top: calc(100% + 28px); right: -25px;
  display: none; grid-template-columns: repeat(var(--sl-kbn-cols, 3), max-content); column-gap: 64px; row-gap: 14px;
  padding: 40px; background: var(--sl-kbn-box); border: 1px solid var(--sl-text); border-radius: var(--sl-radius);
  box-shadow: 0 4px 20px rgba(0, 0, 0, 0.25);
}
.sl-kbn__dd.is-open .sl-kbn__panel { display: grid; }
.sl-kbn__panel a { font-family: var(--sl-font-display); font-size: var(--sl-kbn-link-size); font-weight: 800; line-height: 1.2; text-transform: uppercase; color: var(--sl-text); text-decoration: none; transition: color 300ms ease-in-out; }
.sl-kbn__panel a:hover, .sl-kbn__panel a:focus-visible, .sl-kbn__panel a.is-active { color: var(--sl-kbn-hover); }
.sl-kbn__panel a:focus-visible { outline: 2px solid var(--sl-text); outline-offset: 4px; }
/* Knob data-dd-span: line the hub panel up with the menu instead of hanging it off the hub link.
   "box" = from the left edge of the links box to the right edge of the action button; "word" = from the left edge of
   the hub's word to the right edge of the action button (the JS measures the word). Links fill the width in
   --sl-kbn-dd-cols columns (default 2, "word" 1) and "All ..." takes its own row. Knob data-dd-attach: the panel
   hangs straight off the box, sharing its bottom line, like an extension of the menu (otherwise it floats
   --sl-kbn-dd-gap below, default 12px). */
.sl-kbn[data-dd-span] .sl-kbn__end { position: relative; }
.sl-kbn[data-dd-span] .sl-kbn__dd { position: static; }
.sl-kbn[data-dd-span] .sl-kbn__dd::before { top: 100%; left: 0; right: 0; height: calc(var(--sl-kbn-dd-gap, 12px) + 2px); }
.sl-kbn[data-dd-span] .sl-kbn__panel {
  top: calc(100% + var(--sl-kbn-dd-gap, 12px)); left: 0; right: 0;
  grid-template-columns: repeat(var(--sl-kbn-dd-cols, 2), minmax(0, 1fr)); column-gap: 32px; row-gap: 14px; padding: 32px;
}
.sl-kbn[data-dd-span="word"] .sl-kbn__panel { left: var(--sl-kbn-dd-x, 0px); grid-template-columns: repeat(var(--sl-kbn-dd-cols, 1), minmax(0, 1fr)); }
.sl-kbn[data-dd-span] .sl-kbn__panel a { white-space: normal; }
.sl-kbn[data-dd-span] .sl-kbn__panel a:first-child { grid-column: 1 / -1; padding-bottom: 14px; border-bottom: 1px solid var(--sl-border); }
.sl-kbn[data-dd-span][data-dd-attach] { --sl-kbn-dd-gap: -1px; }
.sl-kbn[data-dd-span][data-dd-attach] .sl-kbn__panel { border-radius: 0 0 var(--sl-radius) var(--sl-radius); box-shadow: 0 18px 28px -12px rgba(0, 0, 0, 0.3); }

/* Phones: burger (icon only) that turns into an X while the panel is open, and a sliding panel. */
.sl-kbn__burger { display: flex; flex-direction: column; justify-content: center; gap: 6px; width: 48px; height: 48px; padding: 10px 9px; margin-right: -9px; border: 0; background: none; color: var(--sl-text); cursor: pointer; }
.sl-kbn__burger span { display: block; width: 100%; height: 3px; background: currentColor; transition: transform 300ms var(--sl-ease), opacity 200ms ease; }   /* explicit width: a <button> flex column does not stretch its children */
.sl-kbn.is-open .sl-kbn__burger span:nth-child(1) { transform: translateY(9px) rotate(45deg); }   /* 9px = gap 6 + line 3 */
.sl-kbn.is-open .sl-kbn__burger span:nth-child(2) { opacity: 0; }
.sl-kbn.is-open .sl-kbn__burger span:nth-child(3) { transform: translateY(-9px) rotate(-45deg); }
.sl-kbn__burger:focus-visible { outline: 2px solid var(--sl-text); outline-offset: 2px; }
@media (min-width: 1024px) { .sl-kbn__burger, .sl-kbn__drawer, .sl-kbn__scrim { display: none; } }

.sl-kbn__scrim {
  position: fixed; inset: 0; z-index: -2;
  background: rgba(0, 0, 0, 0.18); -webkit-backdrop-filter: blur(6px); backdrop-filter: blur(6px);
  opacity: 0; visibility: hidden; transition: opacity 300ms ease, visibility 300ms;
}
.sl-kbn.is-open .sl-kbn__scrim { opacity: 1; visibility: visible; }
.sl-kbn__drawer { position: absolute; top: 100%; left: 0; right: 0; z-index: -1; overflow: hidden; pointer-events: none; padding-bottom: 24px; }
.sl-kbn.is-open .sl-kbn__drawer { pointer-events: auto; }
.sl-kbn__sheet {
  display: flex; flex-direction: column; align-items: flex-start; gap: 16px;
  padding: 24px; background: var(--sl-kbn-box); border: 1px solid var(--sl-text); border-radius: var(--sl-radius);
  box-shadow: 0 0 20px rgba(0, 0, 0, 0.1);
  transform: translateY(calc(-100% - 90px)); visibility: hidden;
  transition: transform 420ms ease, visibility 420ms;
}
.sl-kbn.is-open .sl-kbn__sheet { transform: none; visibility: visible; }
.sl-kbn__sheet .sl-kbn__link { font-size: calc(var(--sl-kbn-link-size) + 2px); }
.sl-kbn__sheet .btn { margin-top: 8px; }
.sl-kbn__group { display: flex; flex-direction: column; align-self: stretch; gap: 12px; }
.sl-kbn__group-head { display: flex; align-items: center; justify-content: space-between; }
.sl-kbn__group-toggle { width: 48px; height: 48px; margin: -12px -12px -12px 0; border: 0; background: none; color: var(--sl-text); cursor: pointer; display: grid; place-items: center; }
.sl-kbn__group-toggle svg { width: 20px; height: 20px; transition: transform 300ms ease; }
.sl-kbn__group.is-open .sl-kbn__group-toggle svg { transform: rotate(180deg); }
.sl-kbn__sublinks { display: none; flex-direction: column; gap: 0; padding-left: 16px; }
.sl-kbn__group.is-open .sl-kbn__sublinks { display: flex; }
.sl-kbn__sublinks a { display: flex; align-items: center; min-height: 48px; font-size: 17px; font-weight: 500; color: var(--sl-muted); text-decoration: none; } /* 48px tap rows (touch-target rule) */
.sl-kbn__sublinks a:hover { color: var(--sl-text); }
.sl-kbn__sublinks a:focus-visible { outline: 2px solid var(--sl-accent); outline-offset: 2px; }
.sl-kbn__sublinks a.is-active { color: var(--sl-text); font-weight: 700; }

@media (prefers-reduced-motion: reduce) {
  .sl-kbn__roll > span, .sl-kbn__caret svg, .sl-kbn__sheet, .sl-kbn__scrim, .sl-kbn__burger span, .sl-kbn[data-sticky]::before { transition: none; }
}
/* ==== RECIPE CSS END ==== */

/* recipe: hero/2026-09_creohaus_phone-primary-type-hero */
/* ==== RECIPE CSS START: hero/2026-09_creohaus_phone-primary-type-hero ==== */
.sl-ppt {
  background: var(--sl-bg);
  color: var(--sl-text);
  min-height: min(100svh, 940px);
  display: flex;
  align-items: center;
  padding: 104px 0 56px;
  overflow: hidden;
}
.sl-ppt__inner { width: 100%; }
.sl-ppt__stage { position: relative; display: grid; grid-template-columns: 1fr; gap: 28px; }
.sl-ppt__type { position: relative; z-index: 1; }
.sl-ppt__eyebrow { margin-bottom: 20px; }
.sl-ppt__title {
  font-size: var(--sl-ppt-title, clamp(48px, 9vw, 116px));
  line-height: 0.92;
  letter-spacing: -0.03em;
  text-transform: var(--sl-ppt-case, uppercase);
  font-weight: 800;
}
.sl-ppt[data-title-tone="accent"] .sl-ppt__title { color: var(--sl-accent); }
.sl-ppt__line { display: block; }
.sl-ppt__sub { margin-top: 20px; max-width: 44ch; color: var(--sl-muted); }
.sl-ppt__media {
  position: relative;
  z-index: 2;
  aspect-ratio: 4 / 5;
  width: 100%;
  max-width: 440px;
  border-radius: var(--sl-radius);
  overflow: hidden;
  background: var(--sl-surface-2);
}
.sl-ppt__media > img,
.sl-ppt__media > video { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }

@media (min-width: 768px) {
  .sl-ppt__stage { align-items: end; }
  /* Split claim: the second line shifts right, once, as layout. */
  .sl-ppt[data-split="on"] .sl-ppt__line--shift { text-align: right; margin-top: -0.12em; }
  .sl-ppt[data-split="on"] .sl-ppt__sub { margin-left: auto; text-align: right; }
  /* Floating media: a tall portrait pinned top right, the oversized claim bottom left. The claim scales with
     the viewport and stays inside its column, so the media never covers a letter (a hidden claim fails). */
  .sl-ppt[data-media="overlap"] .sl-ppt__stage { min-height: clamp(30rem, 44vw, 40rem); }
  .sl-ppt[data-media="overlap"] .sl-ppt__type { max-width: var(--sl-ppt-type-w, 68%); }
  .sl-ppt[data-media="overlap"] .sl-ppt__title { font-size: var(--sl-ppt-title, clamp(44px, 6.2vw, 96px)); }
  .sl-ppt[data-media="overlap"] .sl-ppt__media { position: absolute; right: 0; top: 0; width: 30%; max-width: 460px; }
  .sl-ppt[data-media="overlap"][data-split="on"] .sl-ppt__sub { margin-left: 0; text-align: left; }
  .sl-ppt[data-media="beside"] .sl-ppt__stage { grid-template-columns: 7fr 5fr; align-items: center; }
  .sl-ppt[data-media="beside"] .sl-ppt__media { justify-self: end; }
}

/* Knob data-media="tall": claim column left, a portrait media column right whose top meets the eyebrow and whose
   bottom meets the buttons (the copy sets its height). Phones: eyebrow, claim, media, paragraph, buttons. */
.sl-ppt__line { margin-left: var(--sl-ppt-optical, 0em); }       /* pull lines left by the font's side bearing */
.sl-ppt__line--flush { margin-left: 0; }                         /* a line whose first letter has none */
.sl-ppt[data-media="tall"] .sl-ppt__type { display: contents; }
.sl-ppt[data-media="tall"] .sl-ppt__stage { grid-template-areas: "eyebrow" "title" "media" "sub"; row-gap: 24px; }
.sl-ppt[data-media="tall"] .sl-ppt__eyebrow { grid-area: eyebrow; margin: 0; }
.sl-ppt[data-media="tall"] .sl-ppt__title { grid-area: title; font-size: clamp(52px, 14.5vw, 96px); line-height: 0.95; }
.sl-ppt[data-media="tall"] .sl-ppt__sub { grid-area: sub; margin: 0; max-width: 56ch; }
.sl-ppt[data-media="tall"] .sl-ppt__media { grid-area: media; overflow: visible; aspect-ratio: 4 / 5; max-width: 460px; }
@media (min-width: 1024px) {
  .sl-ppt[data-media="tall"] .sl-ppt__inner {
    display: grid;
    grid-template-columns: minmax(0, 1fr) var(--sl-ppt-media-w, 38%);
    grid-template-rows: auto auto auto minmax(0, 1fr) auto;
    column-gap: 48px;
  }
  .sl-ppt[data-media="tall"] .sl-ppt__stage { display: contents; }
  .sl-ppt[data-media="tall"] .sl-ppt__eyebrow { grid-column: 1; grid-row: 1; line-height: 1; }
  /* --sl-ppt-cap-top / --sl-ppt-base-trim: the font's gap above the caps and below the baseline, so the
     visible letters sit exactly 14px from the eyebrow and the paragraph. */
  .sl-ppt[data-media="tall"] .sl-ppt__title { grid-column: 1; grid-row: 2; font-size: var(--sl-ppt-title-tall, clamp(64px, 9vw, 180px)); margin-top: calc(14px - var(--sl-ppt-cap-top, 0em)); margin-bottom: calc(0em - var(--sl-ppt-base-trim, 0em)); }
  .sl-ppt[data-media="tall"] .sl-ppt__sub { grid-column: 1; grid-row: 3; margin-top: 14px; }
  .sl-ppt[data-media="tall"] .sl-ppt__foot { grid-column: 1; grid-row: 5; margin-top: 56px; }
  .sl-ppt[data-media="tall"] .sl-ppt__media { grid-column: 2; grid-row: 1 / -1; align-self: stretch; width: 100%; max-width: none; aspect-ratio: auto; }
}

/* Optional: typewriter word inside the claim (data-sl-opt-typewriter, data-words="one|two"). */
.sl-ppt__tw { color: var(--sl-accent); }
.sl-ppt__tw-cursor { display: inline-block; width: 0.08em; height: 0.78em; margin-left: 0.05em; background: var(--sl-accent); transform: translateY(0.04em); animation: sl-ppt-blink 1s steps(1) infinite; }
@keyframes sl-ppt-blink { 50% { opacity: 0; } }

/* Optional: a bouncing punctuation mark at the end of the claim (data-sl-opt-bang). Drops, squashes on landing,
   springs up; a flat ring spreads from its foot. 1.45s loop. */
.sl-ppt__bang { position: relative; display: inline-block; color: var(--sl-accent); }
.sl-ppt__bang-glyph { display: inline-block; transform-origin: 50% 100%; animation: sl-ppt-bounce 1.45s infinite; }
.sl-ppt__bang-ring { position: absolute; left: 50%; bottom: 0.01em; width: 0.62em; height: 0.15em; margin-left: -0.31em; overflow: visible; z-index: -1; fill: none; stroke: currentColor; stroke-width: 3; opacity: 0; animation: sl-ppt-ring 1.45s cubic-bezier(.2,.6,.3,1) infinite; }
.sl-ppt__bang-ring ellipse { vector-effect: non-scaling-stroke; }
@keyframes sl-ppt-bounce {
  0%   { transform: translateY(0) scale(1, 1); animation-timing-function: cubic-bezier(.2,.8,.3,1); }
  7%   { transform: translateY(0) scale(1.1, .78); animation-timing-function: cubic-bezier(.3,0,.3,1); }
  19%  { transform: translateY(0) scale(.97, 1.05); animation-timing-function: cubic-bezier(.2,.65,.35,1); }
  58%  { transform: translateY(-0.13em) scale(1, 1); animation-timing-function: cubic-bezier(.55,0,.85,.35); }
  97%  { transform: translateY(-0.004em) scale(.98, 1.03); animation-timing-function: linear; }
  100% { transform: translateY(0) scale(1, 1); }
}
@keyframes sl-ppt-ring { 0% { transform: scale(.24); opacity: 1; } 52% { transform: scale(1); opacity: 0; } 100% { transform: scale(1); opacity: 0; } }

/* Optional: spinning sound badge on the media (data-sl-opt-badge). Media autoplays muted; the badge toggles sound. */
.sl-ppt__badge { position: absolute; z-index: 5; right: 12px; bottom: 12px; width: 95px; height: 95px; border: 0; padding: 0; background: none; cursor: pointer; display: grid; place-items: center; }
.sl-ppt__badge:focus-visible { outline: 2px solid var(--sl-accent); outline-offset: 4px; border-radius: 50%; }
.sl-ppt__badge-ring { position: absolute; inset: 0; width: 100%; height: 100%; animation: sl-ppt-spin 40s linear infinite; }
.sl-ppt__badge-disc { fill: var(--sl-ppt-badge, var(--sl-surface)); }
.sl-ppt__badge-text { fill: var(--sl-ppt-badge-ink, var(--sl-text)); font-family: var(--sl-font-body); font-weight: 700; font-size: 10.5px; letter-spacing: 1px; }
.sl-ppt__badge-core { position: relative; width: 50px; height: 50px; border-radius: 50%; background: var(--sl-accent); color: var(--sl-on-accent); display: grid; place-items: center; }
.sl-ppt__badge-core svg { width: 24px; height: 24px; }
.sl-ppt__badge .is-on, [data-sound="on"] .sl-ppt__badge .is-off { display: none; }
[data-sound="on"] .sl-ppt__badge .is-on { display: block; }
@keyframes sl-ppt-spin { to { transform: rotate(360deg); } }
@media (min-width: 1024px) {
  .sl-ppt__badge { right: 24px; bottom: 24px; width: 121px; height: 121px; }
  .sl-ppt__badge-core { width: 64px; height: 64px; }
}
@media (prefers-reduced-motion: reduce) { .sl-ppt__tw-cursor, .sl-ppt__bang-glyph, .sl-ppt__bang-ring, .sl-ppt__badge-ring { animation: none; } }

.sl-ppt__foot { margin-top: 40px; display: flex; flex-direction: column; gap: 20px; }
@media (min-width: 900px) { .sl-ppt__foot { flex-direction: row; align-items: center; justify-content: space-between; } }
.sl-ppt__proof {
  display: inline-flex;
  align-items: center;
  gap: 12px;
  max-width: 340px;
  padding: 8px 16px 8px 8px;
  border: 1px solid var(--sl-border);
  border-radius: 999px;
  color: var(--sl-muted);
  font-size: 14px;
}
.sl-ppt__proof-face {
  width: 40px;
  height: 40px;
  flex-shrink: 0;
  border-radius: 50%;
  background: var(--sl-surface-2);
  overflow: hidden;
}
.sl-ppt__proof-face img { width: 100%; height: 100%; object-fit: cover; }
.sl-ppt__actions { display: flex; flex-direction: column; align-items: stretch; gap: 12px; }
@media (min-width: 640px) { .sl-ppt__actions { flex-direction: row; align-items: center; gap: 16px; } }

/* Load settle, play once. Never on the phone control. */
@keyframes sl-ppt-rise { from { opacity: 0; transform: translateY(24px); } to { opacity: 1; transform: none; } }
.sl-ppt__eyebrow, .sl-ppt__type, .sl-ppt__media { animation: sl-ppt-rise 0.75s cubic-bezier(0.2, 0.7, 0.2, 1) both; }
.sl-ppt__type { animation-delay: 0.08s; }
.sl-ppt__media { animation-delay: 0.16s; }
@media (prefers-reduced-motion: reduce) { .sl-ppt__eyebrow, .sl-ppt__type, .sl-ppt__media { animation: none; } }
/* ==== RECIPE CSS END ==== */

/* recipe: stats-counters/2026-09_creohaus_notched-stat-staircase */
/* ==== RECIPE CSS START: stats-counters/2026-09_creohaus_notched-stat-staircase ==== */
/* A row of solid colour bars that share one baseline like a bar chart. Each bar's height is its own
   figure scaled against the largest one (JS reads data-value), so the chart is honest when every
   figure shares a unit. One bar is "open" at a time: its column widens (4fr vs 1fr), it rises to the
   full reference height and reveals its sentence. The open bar auto-advances on a fixed cycle shown
   by a progress line on the next control. Neighbouring bars interlock through a cut bottom-left corner.

   Why the chart row has a FIXED height: only the bars move inside it, so nothing below the section
   ever shifts while a bar opens (animating the row itself shoves the rest of the page every cycle). */
.sl-nss {
  --sl-nss-h: 400px;                                   /* knob: reference (tallest / open) bar height */
  --sl-nss-cut: 36px;                                  /* knob: corner cut depth, 45 degrees */
  --sl-nss-num-size: clamp(44px, 4.8vw, 72px);         /* knob: figure size */
  --sl-nss-speed: 500ms;                               /* column + height transition */
  background: var(--sl-bg);
  color: var(--sl-text);
}
.sl-nss[data-cut="off"] { --sl-nss-cut: 0px; }

/* Head: intro left, controls right, on one baseline. The site's own h2 size applies. */
.sl-nss__head { display: flex; flex-wrap: wrap; align-items: flex-end; justify-content: space-between; gap: 32px; }
.sl-nss__intro { display: flex; flex-direction: column; gap: 14px; max-width: 62ch; }
.sl-nss__intro p { color: var(--sl-muted); }
.sl-nss__controls { display: flex; gap: 10px; flex-shrink: 0; }
.sl-nss__ctrl {
  position: relative; width: 48px; height: 48px; padding: 0; overflow: hidden;
  display: grid; place-items: center;
  background: transparent; color: var(--sl-text);
  border: 2px solid var(--sl-text); border-radius: var(--sl-radius-sm);
  cursor: pointer;
  transition: background-color 200ms var(--sl-ease), color 200ms var(--sl-ease);
}
.sl-nss__ctrl svg { width: 16px; height: 16px; display: block; position: relative; z-index: 1; }
.sl-nss__ctrl:hover { background: var(--sl-text); color: var(--sl-bg); }
.sl-nss__ctrl:active { transform: translateY(1px); }
.sl-nss__ctrl:focus-visible { outline: 2px solid var(--sl-text); outline-offset: 3px; }
/* Progress: a line along the bottom of the next control fills over one cycle (transform only). */
.sl-nss__progress {
  position: absolute; left: 0; right: 0; bottom: 0; height: 4px;
  background: var(--sl-accent); transform: scaleX(0); transform-origin: left center;
}

/* ---- The chart ---- */
.sl-nss__chart {
  display: grid; grid-template-columns: 4fr 1fr 1fr 1fr; align-items: end;
  height: var(--sl-nss-h); margin-top: 48px;
  transition: grid-template-columns var(--sl-nss-speed) ease-in-out;
}
.sl-nss__bar {
  --c: var(--sl-surface-2); --on: var(--sl-text); --num: var(--on);
  position: relative; min-width: 0;
  height: calc(var(--sl-nss-h) * var(--r, 1));
  margin-left: -1px;                                   /* hides the sub-pixel seam between fr columns */
  cursor: pointer; outline: none;
  transition: height var(--sl-nss-speed) ease-in-out;
}
.sl-nss__bar:first-child { margin-left: 0; }
.sl-nss__bar.is-open { height: var(--sl-nss-h); cursor: default; }
/* Bar colours, cycled by position. Each is a root knob so a client paints the set from its palette. */
.sl-nss__bar:nth-child(4n+1) { --c: var(--sl-nss-c1, var(--sl-surface-2)); --on: var(--sl-nss-on1, var(--sl-text)); --num: var(--sl-nss-num1, var(--on)); }
.sl-nss__bar:nth-child(4n+2) { --c: var(--sl-nss-c2, var(--sl-text));      --on: var(--sl-nss-on2, var(--sl-bg));   --num: var(--sl-nss-num2, var(--on)); }
.sl-nss__bar:nth-child(4n+3) { --c: var(--sl-nss-c3, var(--sl-surface));   --on: var(--sl-nss-on3, var(--sl-text)); --num: var(--sl-nss-num3, var(--on)); }
.sl-nss__bar:nth-child(4n+4) { --c: var(--sl-nss-c4, var(--sl-accent));    --on: var(--sl-nss-on4, var(--sl-on-accent)); --num: var(--sl-nss-num4, var(--on)); }

/* The notch: each bar's shape is cut bottom-left. A small square of the LEFT neighbour's colour
   (__fill) pokes under the next bar, so the cut reveals the neighbour instead of the page. The
   shape paints above every fill (z 1 vs 0), and bars never create their own stacking context. */
.sl-nss__fill {
  position: absolute; bottom: 0; left: calc(100% - 2px); z-index: 0;
  width: calc(var(--sl-nss-cut) + 4px); height: calc(var(--sl-nss-cut) + 2px);
  background: var(--c);
}
.sl-nss__bar:last-child .sl-nss__fill { display: none; }
.sl-nss__shape {
  position: absolute; inset: 0; z-index: 1; overflow: hidden;
  display: flex; flex-direction: column; justify-content: flex-end;
  padding: 24px 20px;
  background: var(--c); color: var(--on);
  clip-path: polygon(0 0, 100% 0, 100% 100%, var(--sl-nss-cut) 100%, 0 calc(100% - var(--sl-nss-cut)));
  border-radius: var(--sl-radius);
  transition: padding var(--sl-nss-speed) ease-in-out;
}
.sl-nss__bar.is-open .sl-nss__shape { padding: 36px 32px; }
.sl-nss__bar:focus-visible .sl-nss__shape { outline: 3px solid var(--on); outline-offset: -8px; }
.sl-nss__content { display: flex; gap: 24px; height: 100%; }
.sl-nss__text { display: flex; flex-direction: column; justify-content: flex-end; flex: 1; min-width: 0; }

.sl-nss__tag {
  font-size: 13px; font-weight: 600; letter-spacing: 0.14em; text-transform: uppercase; line-height: 1.3;
  margin-bottom: 12px; opacity: 0.8;
}
.sl-nss__num {
  display: flex; font-family: var(--sl-font-display); font-weight: 800;
  font-size: var(--sl-nss-num-size); line-height: 1; letter-spacing: -0.01em;
  color: var(--num); margin-bottom: 12px;
}
.sl-nss__label { font-size: 16px; font-weight: 600; line-height: 1.35; }
.sl-nss__desc {
  max-width: 46ch; margin-top: 10px; font-size: 16px; line-height: 1.6;
  max-height: 0; opacity: 0; overflow: hidden;
  transition: max-height var(--sl-nss-speed) ease-in-out, opacity 350ms ease;
}
.sl-nss__bar.is-open .sl-nss__desc { max-height: 12em; opacity: 0.88; }
/* Closed bars keep only the figure and label. */
.sl-nss__bar:not(.is-open) .sl-nss__tag { opacity: 0; }
.sl-nss__tag { transition: opacity 300ms ease; }

/* Optional media slot beside the open bar's text (a real photo per figure, or delete it). */
.sl-nss__media { position: relative; width: 0; flex-shrink: 0; opacity: 0; overflow: hidden; border-radius: var(--sl-radius-sm); transition: width var(--sl-nss-speed) ease-in-out, opacity 300ms ease; }
.sl-nss__bar.is-open .sl-nss__media { width: 34%; opacity: 1; }
.sl-nss__media > img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }

/* Rolling figure: each numeral is a 0-9 column translated into place. The column's width is its
   widest digit, so figures never shift sideways even in fonts without tabular numerals. */
.sl-nss__digit { display: inline-block; height: 1em; overflow: hidden; vertical-align: top; }
.sl-nss__roll { display: flex; flex-direction: column; align-items: center; transition: transform 700ms cubic-bezier(0.4, 0, 0.2, 1); }
.sl-nss__roll span { display: block; height: 1em; line-height: 1; }
.sl-nss__sym { display: inline-block; }
.sl-nss__sr { position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0; }

/* Optional closing line under the chart. */
.sl-nss__pull {
  margin-top: 64px; padding-left: 28px; max-width: var(--sl-nss-pull-w, 58ch); text-wrap: pretty;
  border-left: 3px solid var(--sl-accent);
  font-size: clamp(20px, 2.1vw, 28px); font-weight: 600; line-height: 1.45;
}
.sl-nss__pull em { font-style: normal; color: var(--sl-nss-em, var(--sl-text)); }
/* Optional sources line (data-sl-opt-sources): every figure on the chart, linked to where it comes from. */
.sl-nss__sources { margin-top: 28px; max-width: 110ch; font-size: 14px; line-height: 1.6; color: var(--sl-muted); }
.sl-nss__sources a { color: inherit; text-decoration: underline; text-underline-offset: 3px; }
.sl-nss__sources a:hover { color: var(--sl-text); }
.sl-nss__sources a:focus-visible { outline: 2px solid var(--sl-accent); outline-offset: 2px; }

/* ---- Phones and small tablets: bars stack, every sentence shows, no cycling. A meter along the
   top of each bar keeps the proportion visible once the heights are gone. ---- */
@media (max-width: 959px) {
  .sl-nss__controls { display: none; }
  .sl-nss__chart { display: flex; flex-direction: column; gap: 12px; height: auto; margin-top: 32px; }
  .sl-nss__bar, .sl-nss__bar.is-open { height: auto; margin-left: 0; cursor: default; }
  .sl-nss__fill { display: none; }
  .sl-nss__shape, .sl-nss__bar.is-open .sl-nss__shape { position: relative; inset: auto; padding: 44px 24px 26px; clip-path: polygon(0 0, 100% 0, 100% 100%, min(var(--sl-nss-cut), 26px) 100%, 0 calc(100% - min(var(--sl-nss-cut), 26px))); }
  /* Meter: an inset line with a faint full-width track, so it reads as a proportion, not a cut. */
  .sl-nss__shape::before, .sl-nss__shape::after { content: ""; position: absolute; left: 24px; right: 24px; top: 22px; height: 4px; background: var(--num); }
  .sl-nss__shape::before { opacity: 0.16; }
  .sl-nss__shape::after { transform: scaleX(var(--r, 1)); transform-origin: left center; }
  .sl-nss__content { flex-direction: column; }
  .sl-nss__bar .sl-nss__tag, .sl-nss__bar:not(.is-open) .sl-nss__tag { opacity: 0.8; }
  .sl-nss__desc, .sl-nss__bar.is-open .sl-nss__desc { max-height: none; opacity: 0.88; } /* the open bar's 12em cap is desktop only */
  .sl-nss__media, .sl-nss__bar.is-open .sl-nss__media { width: 100%; height: 180px; opacity: 1; }
  .sl-nss__pull { margin-top: 40px; padding-left: 20px; }
}

@media (prefers-reduced-motion: reduce) {
  .sl-nss__chart, .sl-nss__bar, .sl-nss__shape, .sl-nss__desc, .sl-nss__media, .sl-nss__tag, .sl-nss__roll { transition: none; }
}
.sl-nss[data-motion="off"] :is(.sl-nss__chart, .sl-nss__bar, .sl-nss__shape, .sl-nss__desc, .sl-nss__media, .sl-nss__tag, .sl-nss__roll) { transition: none; }
.sl-nss[data-motion="off"] .sl-nss__progress, .sl-nss[data-motion="manual"] .sl-nss__progress { display: none; }

/* Line art in the media slot (inline SVG): strokes take the bar's text colour; shapes with class sl-nss__knock fill
   with the bar colour, hiding whatever sits behind them. */
.sl-nss__media > svg { position: absolute; inset: 0; width: 100%; height: 100%; color: var(--on); }
.sl-nss__media .sl-nss__knock { fill: var(--c); }

/* Knob data-phone="carousel" (below 960px): instead of stacking, the bars become one swipeable card at a time with a
   peek of the next. It auto-advances every data-cycle-phone ms (pauses while a finger is down, while focused and off
   screen; never with reduced motion); arrows and swipe both work. Line art sits above the text at --sl-nss-art-h. */
@media (max-width: 959px) {
  /* Arrows move under the cards (near the thumb): the head's parts and the chart re-flow as one column. */
  .sl-nss[data-phone="carousel"] > .container { display: flex; flex-direction: column; }
  .sl-nss[data-phone="carousel"] .sl-nss__head { display: contents; }
  .sl-nss[data-phone="carousel"] .sl-nss__chart { order: 1; }
  .sl-nss[data-phone="carousel"] .sl-nss__controls { display: flex; order: 2; margin-top: 16px; }
  .sl-nss[data-phone="carousel"] .sl-nss__pull { order: 3; }
  .sl-nss[data-phone="carousel"] .sl-nss__sources { order: 4; }
  .sl-nss[data-phone="carousel"] .sl-nss__chart {
    flex-direction: row; align-items: stretch; gap: 12px;
    overflow-x: auto; scroll-snap-type: x mandatory; overscroll-behavior-x: contain; scrollbar-width: none;
    margin-inline: calc(-1 * var(--sl-nss-bleed, 24px)); padding-inline: var(--sl-nss-bleed, 24px); scroll-padding-inline: var(--sl-nss-bleed, 24px);
  }
  .sl-nss[data-phone="carousel"] .sl-nss__chart::-webkit-scrollbar { display: none; }
  .sl-nss[data-phone="carousel"] .sl-nss__bar { flex: 0 0 min(86%, 420px); display: flex; scroll-snap-align: center; }
  .sl-nss[data-phone="carousel"] .sl-nss__shape,
  .sl-nss[data-phone="carousel"] .sl-nss__bar.is-open .sl-nss__shape { flex: 1; justify-content: flex-start; }
  /* Art takes every pixel the text leaves in the card (never under --sl-nss-art-h), so the gap to the text is the same
     content gap on every card. Frame line art tight (viewBox = the painted edge) so it has no built-in margin. */
  .sl-nss[data-phone="carousel"] .sl-nss__content { flex: 1; height: auto; min-height: 0; }
  .sl-nss[data-phone="carousel"] .sl-nss__text { flex: none; }
  .sl-nss[data-phone="carousel"] .sl-nss__media,
  .sl-nss[data-phone="carousel"] .sl-nss__bar.is-open .sl-nss__media { order: -1; width: 100%; height: auto; flex: 1 1 var(--sl-nss-art-h, 120px); min-height: var(--sl-nss-art-h, 120px); opacity: 1; }
  .sl-nss[data-phone="carousel"] .sl-nss__media > svg { position: absolute; inset: 0; width: 100%; height: 100%; }
}
/* ==== RECIPE CSS END ==== */

/* recipe: texture/2026-09_creohaus_linen */
/* ==== TEXTURE CSS START: texture/2026-09_creohaus_linen ==== */
/* Fine linen: Tight woven threads (1px, every 3px, across and down) with a little fibre irregularity from seamless SVG noise. Reads as quality paper stock.
   Opt in on any section root with data-texture="linen" (space-separated with other textures that don't also use ::before).
   Colour: --sl-tex-rgb (R G B). Strength: --sl-tex-strength. Static: nothing to reduce for reduced motion.
   Thread gradients are tiled at 3px: one untiled gradient down a very tall section (3,000px+) loses its 1px lines in Chrome. */
[data-texture~="linen"] { position: relative; isolation: isolate; }
[data-texture~="linen"]::before {
  content: ""; position: absolute; inset: 0; z-index: -1; pointer-events: none;
  background: rgb(var(--sl-tex-rgb, 24 24 27));
  -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='180' height='180'%3E%3Cfilter id='n' x='0' y='0' width='100%25' height='100%25'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9 0.35' numOctaves='3' seed='4' stitchTiles='stitch'/%3E%3CfeColorMatrix values='0 0 0 0 0  0 0 0 0 0  0 0 0 0 0  0 0 0 0.22 -0.1'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url%28%23n%29'/%3E%3C/svg%3E") 0 0 / 180px 180px, repeating-linear-gradient(0deg, rgb(0 0 0 / .035) 0 1px, transparent 1px 3px) 0 0 / 3px 3px, repeating-linear-gradient(90deg, rgb(0 0 0 / .028) 0 1px, transparent 1px 3px) 0 0 / 3px 3px; mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='180' height='180'%3E%3Cfilter id='n' x='0' y='0' width='100%25' height='100%25'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9 0.35' numOctaves='3' seed='4' stitchTiles='stitch'/%3E%3CfeColorMatrix values='0 0 0 0 0  0 0 0 0 0  0 0 0 0 0  0 0 0 0.22 -0.1'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url%28%23n%29'/%3E%3C/svg%3E") 0 0 / 180px 180px, repeating-linear-gradient(0deg, rgb(0 0 0 / .035) 0 1px, transparent 1px 3px) 0 0 / 3px 3px, repeating-linear-gradient(90deg, rgb(0 0 0 / .028) 0 1px, transparent 1px 3px) 0 0 / 3px 3px;
  opacity: var(--sl-tex-strength, 1);
}
/* ==== TEXTURE CSS END ==== */

/* recipe: logo-cloud/2026-09_creohaus_medallion-wipe-logo-marquee */
/* ==== RECIPE CSS START: logo-cloud/2026-09_creohaus_medallion-wipe-logo-marquee ==== */
/* A row of before/after logo cards scrolls behind a fixed brand medallion. Each card is split on the
   medallion's centre line: the "before" art shows on the side it came from, the "after" mark on the
   side it is heading to, so every logo is visibly rebuilt as it passes behind the medallion. */
.sl-mwm {
  --sl-mwm-h: 120px;          /* card height; width is 1.6x (artboard ratio) */
  --sl-mwm-med: 190px;        /* medallion size: keep it taller than a card so the seam stays hidden */
  --sl-mwm-gap: 48px;
  --sl-mwm-speed: 60;         /* px per second */
  --sl-mwm-mark: 70%;         /* brand mark size inside the medallion */
  --sl-mwm-glow-size: 18px;   /* halo blur; the stage grows to fit it so it never gets cut off */
  --sl-mwm-glow-strength: 0.45;
  background: var(--sl-bg); color: var(--sl-text); overflow: hidden;
}
.sl-mwm__head { text-align: center; max-width: 760px; margin: 0 auto 12px; }
.sl-mwm__head > * + * { margin-top: 14px; }
.sl-mwm__head p:not(.eyebrow) { color: var(--sl-muted); }

/* the edge-fade mask clips anything outside this box, so it is sized to hold the full halo (no hard cut-off line) */
.sl-mwm__stage { position: relative; height: calc(var(--sl-mwm-med) + 2 * max(24px, var(--sl-mwm-glow-size) * 3)); display: flex; align-items: center;
  -webkit-mask-image: linear-gradient(90deg, transparent 0, rgba(0,0,0,1) 7%, rgba(0,0,0,1) 93%, transparent 100%);
          mask-image: linear-gradient(90deg, transparent 0, rgba(0,0,0,1) 7%, rgba(0,0,0,1) 93%, transparent 100%); }
.sl-mwm__track { position: relative; display: flex; align-items: center; gap: var(--sl-mwm-gap);
  margin: 0; padding: 0; list-style: none; will-change: transform; }

/* card: 1.6:1, top-right and bottom-left cut at 45deg (12.5% of width = 20% of height) */
.sl-mwm__card { position: relative; flex: 0 0 auto; height: var(--sl-mwm-h); width: calc(var(--sl-mwm-h) * 1.6);
  clip-path: polygon(0 0, 87.5% 0, 100% 20%, 100% 100%, 12.5% 100%, 0 80%); }
.sl-mwm[data-cut="off"] .sl-mwm__card { clip-path: none; }
.sl-mwm__face { position: absolute; inset: 0; }
.sl-mwm__face--before img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
.sl-mwm__face--after { display: flex; align-items: center; justify-content: center; color: var(--sl-text); }
.sl-mwm__face--after > svg:not(.sl-mwm__edge), .sl-mwm__face--after > img { width: 74%; height: 60%; object-fit: contain; overflow: visible; }
.sl-mwm__face--after .sl-mwm__accent { fill: var(--sl-accent); }
.sl-mwm__edge { position: absolute; inset: 0; width: 100%; height: 100%; pointer-events: none; overflow: visible; }
.sl-mwm__edge polygon { fill: none; stroke-width: 3; vector-effect: non-scaling-stroke; }
.sl-mwm__face--before .sl-mwm__edge polygon { stroke: var(--sl-border); }
.sl-mwm__face--after .sl-mwm__edge polygon { stroke: var(--sl-text); stroke-opacity: 0.38; }
.sl-mwm[data-cut="off"] .sl-mwm__edge { display: none; }

/* medallion: inverse of the band, brand mark in the accent */
.sl-mwm__medallion { position: absolute; top: 50%; left: 50%; z-index: 3; width: var(--sl-mwm-med); height: var(--sl-mwm-med);
  transform: translate(-50%, -50%); pointer-events: none; }
.sl-mwm__shape { position: absolute; inset: 0; width: 100%; height: 100%; overflow: visible; }
.sl-mwm__shape .sl-mwm__fill { fill: var(--sl-text); }
/* halo: an accent copy of the shape, blurred so it fades out evenly on every side */
.sl-mwm__halo { position: absolute; inset: 0; opacity: var(--sl-mwm-glow-strength); filter: blur(var(--sl-mwm-glow-size)); }
.sl-mwm__halo span { position: absolute; inset: 0; background: var(--sl-accent); border-radius: 50%; }
.sl-mwm[data-shape="hex"] .sl-mwm__halo span { border-radius: 0;
  clip-path: polygon(50% 1%, 92.5% 25.5%, 92.5% 74.5%, 50% 99%, 7.5% 74.5%, 7.5% 25.5%); }
.sl-mwm[data-glow="off"] .sl-mwm__halo { display: none; }
.sl-mwm__shape .sl-mwm__hex { display: none; }
.sl-mwm[data-shape="hex"] .sl-mwm__shape .sl-mwm__hex { display: inline; }
.sl-mwm[data-shape="hex"] .sl-mwm__shape .sl-mwm__circ { display: none; }
.sl-mwm__mark { position: absolute; inset: 0; display: flex; align-items: center; justify-content: center; color: var(--sl-accent); }
.sl-mwm__mark > svg, .sl-mwm__mark > img { height: var(--sl-mwm-mark); width: auto; }

.sl-mwm__labels { display: flex; justify-content: space-between; max-width: 760px; margin: 10px auto 0; padding: 0 24px;
  font-family: var(--sl-font-body); font-size: 12px; font-weight: 600; letter-spacing: 0.14em; text-transform: uppercase;
  color: var(--sl-muted); }
.sl-mwm__sr { position: absolute; width: 1px; height: 1px; margin: -1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }

@media (max-width: 640px) {
  .sl-mwm { --sl-mwm-h: 76px; --sl-mwm-med: 126px; --sl-mwm-gap: 28px; --sl-mwm-speed: 42; --sl-mwm-glow-size: 12px; }
}
/* ==== RECIPE CSS END ==== */

/* recipe: services-features/2026-09_creohaus_task-offer-cards */
/* ==== RECIPE CSS START: services-features/2026-09_creohaus_task-offer-cards ==== */
.sl-toc { background: var(--sl-bg); color: var(--sl-text); }
.sl-toc__head { max-width: 680px; }
.sl-toc__head h2 { margin-top: 14px; }
/* :not(.eyebrow) so a section label above the heading keeps the site's own eyebrow colour and rhythm. */
.sl-toc__head p:not(.eyebrow) { margin-top: 14px; color: var(--sl-muted); }

/* Optional category chips: they really filter (never decorative tabs). */
.sl-toc__chips { margin-top: 28px; display: flex; flex-wrap: wrap; gap: 8px; }
.sl-toc__chip {
  min-height: 40px;
  padding: 8px 16px;
  border: 1px solid var(--sl-border);
  border-radius: var(--sl-toc-chip-radius, 999px);
  background: var(--sl-surface);
  color: var(--sl-text);
  font-size: 14px;
  font-weight: 600;
  cursor: pointer;
  transition: background-color 0.2s var(--sl-ease), color 0.2s var(--sl-ease), border-color 0.2s var(--sl-ease);
}
.sl-toc__chip:hover { border-color: var(--sl-text); }
.sl-toc__chip[aria-selected="true"] { background: var(--sl-text); border-color: var(--sl-text); color: var(--sl-bg); }
.sl-toc__chip:focus-visible { outline: 2px solid var(--sl-text); outline-offset: 2px; }

.sl-toc__grid { list-style: none; margin-top: 32px; display: grid; grid-template-columns: 1fr; gap: 16px; }
@media (min-width: 640px) { .sl-toc__grid { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 1024px) { .sl-toc__grid { grid-template-columns: repeat(var(--sl-toc-cols, 3), 1fr); } }
.sl-toc__card {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  padding: 24px;
  background: var(--sl-surface);
  border: 1px solid var(--sl-border);
  border-radius: var(--sl-radius);
  transition: transform 0.2s var(--sl-ease), box-shadow 0.2s var(--sl-ease);
}
.sl-toc__card:hover { transform: translateY(-2px); box-shadow: var(--sl-shadow); }
/* Card fills, cycled by position (knobs; default: every card the surface). Text stays --sl-text, so only pick
   fills the text reads on. --sl-toc-line: card keyline. */
.sl-toc__card:nth-child(3n+1) { background: var(--sl-toc-c1, var(--sl-surface)); }
.sl-toc__card:nth-child(3n+2) { background: var(--sl-toc-c2, var(--sl-surface)); }
.sl-toc__card:nth-child(3n+3) { background: var(--sl-toc-c3, var(--sl-surface)); }
.sl-toc__card { border-color: var(--sl-toc-line, var(--sl-border)); }
.sl-toc__card[hidden] { display: none; }
.sl-toc__icon { width: 52px; height: 52px; margin-bottom: 18px; border-radius: var(--sl-radius-sm); background: var(--sl-toc-icon-bg, var(--sl-surface-2)); display: flex; align-items: center; justify-content: center; }
.sl-toc__icon .material-symbols-outlined { font-size: 26px; }
.sl-toc__outcome { margin: 6px 0 20px; color: var(--sl-muted); flex: 1; }
.sl-toc__exit { margin-top: 40px; }   /* optional: delete the block on a page that IS the full list (a hub) */
@media (prefers-reduced-motion: reduce) { .sl-toc__card { transition: none; } }
/* ==== RECIPE CSS END ==== */

/* recipe: ticker/2026-09_creohaus_three-row-chip-ticker */
/* ==== RECIPE CSS START: ticker/2026-09_creohaus_three-row-chip-ticker ==== */
/* Lead-in knob (--sl-trc-lead + --sl-trc-lead-bg): paints a slab of a NEIGHBOURING band's colour
   across the very top of this band, above its own top padding. Use it when the ticker sits between
   two bands of the same colour and would otherwise read as part of the one above it: the slab gives
   it its own top edge. The stack reads, top to bottom: the previous band's bottom padding, the
   lead-in slab, this band's top padding, the rows. A gradient does it with no extra markup, and the
   default resolves to this band's own colour at zero height, so the knob is off until it is set. */
.sl-trc { color: var(--sl-text); overflow: hidden;
  background: linear-gradient(to bottom,
    var(--sl-trc-lead-bg, var(--sl-bg)) 0 var(--sl-trc-lead, 0px),
    var(--sl-bg) var(--sl-trc-lead, 0px));
  padding: calc(var(--sl-trc-pad, 40px) + var(--sl-trc-lead, 0px)) 0 var(--sl-trc-pad, 40px); }
.sl-trc__row { overflow: hidden; }
.sl-trc__row + .sl-trc__row { margin-top: var(--sl-trc-gap, 12px); }

/* The loop: each track carries its items N times and travels exactly one copy, so the seam never
   shows. N is NOT fixed. It is computed from measured widths in the JS below, because the number of
   copies a row needs depends on how wide one copy is against the viewport: a row of three short
   words needs far more copies than a row of six long ones. Hardcoding a count is the bug that makes
   a short row run out before the right edge. The shift is set in px by the JS. */
.sl-trc__track { list-style: none; display: flex; align-items: center; width: max-content;
  gap: var(--sl-trc-chip-gap, 12px); padding: 0; margin: 0;
  animation: sl-trc-run 40s linear infinite; }
@keyframes sl-trc-run { from { transform: translateX(0); } to { transform: translateX(calc(-1 * var(--sl-trc-shift, 100%))); } }

/* Speed is px per second, not a duration, so every row moves at the same visual pace no matter how
   much text it carries. The JS turns it into a duration. Keep the per-row values slightly different
   or the rows drift into sync and line up into columns. */
.sl-trc { --sl-trc-speed: 48; }

/* Direction and start offset per row. The middle row runs the other way. */
.sl-trc__row:nth-child(2) .sl-trc__track { animation-direction: reverse; margin-left: var(--sl-trc-off-2, -180px); }
.sl-trc__row:nth-child(3) .sl-trc__track { margin-left: var(--sl-trc-off-3, -90px); }

/* Pause under a pointer, and while the band is off screen (house rule: no loop runs unseen). */
.sl-trc:hover .sl-trc__track,
.sl-trc:not(.is-live) .sl-trc__track { animation-play-state: paused; }

.sl-trc__chip { display: inline-flex; align-items: center; white-space: nowrap;
  gap: var(--sl-trc-icon-gap, 10px); font-family: var(--sl-font-display); font-weight: 700;
  text-transform: uppercase; letter-spacing: 0.01em; line-height: 1;
  font-size: var(--sl-trc-size-sm, 22px); padding: 13px 20px; border-radius: var(--sl-radius-sm); }
@media (min-width: 768px) { .sl-trc__chip { font-size: var(--sl-trc-size, 26px); padding: 15px 24px; } }
.sl-trc__icon { display: inline-flex; font-size: var(--sl-trc-icon, 19px); line-height: 1; }

/* Style knob. outline is the default: the accent stays a hairline, so a band of many chips does
   not spend the accent budget the section's buttons need. */
.sl-trc__chip { background: transparent; color: var(--sl-text); border: 1px solid var(--sl-border); }
.sl-trc__icon { color: var(--sl-accent); }
.sl-trc[data-style="solid"] .sl-trc__chip { background: var(--sl-accent); color: var(--sl-on-accent); border-color: var(--sl-accent); }
.sl-trc[data-style="solid"] .sl-trc__icon { color: var(--sl-on-accent); }
/* mixed: the middle row is the loud one, the outer rows frame it. */
.sl-trc[data-style="mixed"] .sl-trc__row:nth-child(2) .sl-trc__chip { background: var(--sl-accent); color: var(--sl-on-accent); border-color: var(--sl-accent); }
.sl-trc[data-style="mixed"] .sl-trc__row:nth-child(2) .sl-trc__icon { color: var(--sl-on-accent); }
/* type: no containers at all, hairline rules between the rows instead. */
.sl-trc[data-style="type"] .sl-trc__chip { background: none; border: 0; padding: 10px 0; gap: 14px; }
.sl-trc[data-style="type"] .sl-trc__track { gap: 34px; }
.sl-trc[data-style="type"] .sl-trc__row { padding: 6px 0; }
.sl-trc[data-style="type"] .sl-trc__row + .sl-trc__row { margin-top: 0; border-top: 1px solid var(--sl-border); }

/* Tilt knob (data-tilt): an angled strip. The band edges are cut on a slant with clip-path (never a rotated band,
   which would push past the screen edge and cause sideways scroll) and each row is rotated by the same angle, wider
   than the band so its ends stay hidden. The band overlaps its neighbours by the full slant so the cut triangles
   show the bands above and below (half the slant leaves a sliver of bare page). --sl-trc-tilt: angle (default 3deg, rising to the right). */
.sl-trc[data-tilt] {
  --sl-trc-rise: calc(100vw * tan(var(--sl-trc-tilt, 3deg)));
  position: relative; z-index: 1;
  clip-path: polygon(0 var(--sl-trc-rise), 100% 0, 100% calc(100% - var(--sl-trc-rise)), 0 100%);
  padding-top: calc(var(--sl-trc-pad, 40px) + var(--sl-trc-rise));
  padding-bottom: calc(var(--sl-trc-pad, 40px) + var(--sl-trc-rise));
  margin: calc(-1 * var(--sl-trc-rise)) 0;
}
.sl-trc[data-tilt] .sl-trc__row { width: 112%; margin-left: -6%; transform: rotate(calc(-1 * var(--sl-trc-tilt, 3deg))); }

/* The list is the content; it stays readable if the CSS or JS never arrives. */
@media (prefers-reduced-motion: reduce) { .sl-trc__track { animation: none; } }
/* ==== RECIPE CSS END ==== */

/* recipe: gallery-portfolio/2026-08_creohaus_stretched-media-upward-accordion (Mode F 2026-09-26: brief knobs, optional carousel / accordion) */
/* ==== RECIPE CSS START: gallery-portfolio/2026-08_creohaus_stretched-media-upward-accordion ==== */
.sl-sua { background: var(--sl-bg); color: var(--sl-text); }
/* Mobile order (design-standards Mobile Order rule): eyebrow, heading, media, body, cta, accordion. */
.sl-sua__grid {
  /* --sl-sua-max narrows the whole block and centres it in the container, for when the section
     should not run the full page width. It centres the BLOCK, not the text inside it. */
  max-width: var(--sl-sua-max, none);
  margin-inline: auto;
  display: grid;
  grid-template-columns: 1fr;
  grid-template-areas: "eyebrow" "heading" "media" "body" "cta" "acc";
  row-gap: 20px;
}
.sl-sua__copy { display: contents; }
.sl-sua__eyebrow { grid-area: eyebrow; }
.sl-sua__heading { grid-area: heading; }
.sl-sua__body { grid-area: body; color: var(--sl-muted); }
.sl-sua__cta { grid-area: cta; }
.sl-sua__acc { grid-area: acc; }
.sl-sua__media {
  grid-area: media;
  position: relative;
  aspect-ratio: var(--sl-sua-ratio, 4 / 3);
  border-radius: var(--sl-radius);
  overflow: hidden;
  background: var(--sl-sua-media-bg, var(--sl-surface-2));
}
/* Absolutely positioned so the slot's height comes from the layout, never from the file. */
.sl-sua__media > img,
.sl-sua__media > video { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: var(--sl-sua-fit, cover); }

@media (min-width: 768px) {
  .sl-sua__grid {
    grid-template-columns: 7fr 5fr;
    grid-template-areas: "media copy";
    column-gap: 3rem;
    align-items: stretch;
  }
  .sl-sua[data-media-side="right"] .sl-sua__grid { grid-template-columns: 5fr 7fr; grid-template-areas: "copy media"; }
  .sl-sua__copy { grid-area: copy; display: flex; flex-direction: column; row-gap: 20px; }
  /* Stretched grid item: top edge level with the eyebrow, bottom edge level with the accordion. */
  .sl-sua__media { aspect-ratio: auto; min-height: 100%; }
  /* data-media-fit="ratio": the media still stretches top to bottom, but its COLUMN narrows so the
     resulting box is portrait. Stretching a portrait photo across a wide column is what crops heads
     off. Width is viewport-relative so the shape holds as the row height changes. */
  .sl-sua[data-media-fit="ratio"] .sl-sua__grid {
    grid-template-columns: minmax(0, var(--sl-sua-media-w, clamp(320px, 34vw, 560px))) minmax(0, 1fr);
  }
  .sl-sua[data-media-fit="ratio"][data-media-side="right"] .sl-sua__grid {
    grid-template-columns: minmax(0, 1fr) minmax(0, var(--sl-sua-media-w, clamp(320px, 34vw, 560px)));
  }
  /* A narrow media column hands the copy column the rest of a wide page, which pushes body copy past
     a readable measure. Cap the paragraph (not the heading or the accordion, which want the width).
     It also keeps the copy column tall, which is what keeps the media box portrait. */
  .sl-sua[data-media-fit="ratio"] .sl-sua__body { max-width: var(--sl-sua-copy-max, 54ch); }
  /* Opens upward: reserve a measured zone and pin the list to its BOTTOM, so an opening row pushes
     the rows above it up while the CTA above the zone never moves. Re-measure per copy length. */
  .sl-sua__acc { position: relative; min-height: var(--sl-sua-reserve, 310px); margin-top: 8px; }
  .sl-sua__acc .sl-sua__list { position: absolute; left: 0; right: 0; bottom: 0; }
}
/* Portrait media needs width. Between 768 and 1023 the two-column split squeezes the media column
   to about 345px against a tall copy column, which crops roughly 40% off the sides of the photo.
   In ratio mode, stay stacked through that range and split at 1024 instead. */
@media (min-width: 768px) and (max-width: 1023.98px) {
  .sl-sua[data-media-fit="ratio"] .sl-sua__grid {
    grid-template-columns: 1fr;
    grid-template-areas: "eyebrow" "heading" "media" "body" "cta" "acc";
    column-gap: 0;
  }
  .sl-sua[data-media-fit="ratio"] .sl-sua__copy { display: contents; }
  .sl-sua[data-media-fit="ratio"] .sl-sua__media { aspect-ratio: var(--sl-sua-ratio, 4 / 3); min-height: 0; }
  .sl-sua[data-media-fit="ratio"] .sl-sua__acc { position: static; min-height: 0; margin-top: 0; }
  .sl-sua[data-media-fit="ratio"] .sl-sua__acc .sl-sua__list { position: static; }
}

@media (min-width: 1024px) {
  .sl-sua__acc { min-height: var(--sl-sua-reserve-lg, 250px); }
}

.sl-sua__list {
  display: flex;
  flex-direction: column;
  gap: 1px;
  background: var(--sl-border);
  border: 1px solid var(--sl-border);
  border-radius: var(--sl-radius);
  overflow: hidden;
}
.sl-sua__item { background: var(--sl-surface); }
.sl-sua__q {
  width: 100%;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  padding: 14px 20px;
  text-align: left;
  background: none;
  border: 0;
  cursor: pointer;
  font: inherit;
  font-weight: 600;
  color: var(--sl-text);
  transition: background-color 0.3s var(--sl-ease);
}
.sl-sua__q:hover { background: var(--sl-surface-2); }
.sl-sua__q:focus-visible { outline: 2px solid var(--sl-text); outline-offset: -2px; }
.sl-sua__icon { position: relative; flex-shrink: 0; width: 20px; height: 20px; }
.sl-sua__icon::before,
.sl-sua__icon::after {
  content: "";
  position: absolute;
  top: 50%;
  left: 50%;
  background: var(--sl-text);
  transform: translate(-50%, -50%);
}
.sl-sua__icon::before { width: 12px; height: 2px; }
.sl-sua__icon::after { width: 2px; height: 12px; transition: transform 0.3s var(--sl-ease); }
.sl-sua__item.is-open .sl-sua__icon::after { transform: translate(-50%, -50%) rotate(90deg) scaleX(0); }
.sl-sua__a { max-height: 0; overflow: hidden; transition: max-height 0.4s var(--sl-ease); }
.sl-sua__a p { padding: 0 20px 16px; color: var(--sl-muted); }
@media (prefers-reduced-motion: reduce) { .sl-sua__a, .sl-sua__icon::after { transition: none; } }

/* --- data-media="carousel": stacked slides, one visible, crossfade on a timer. --- */
.sl-sua__slides {
  position: absolute;
  inset: 0;
  margin: 0;
  padding: 0;
  list-style: none;
  /* The slides clip themselves, so data-marker-place="edge" can let the marker hang off
     the media box without the drifting photo spilling with it. */
  overflow: hidden;
  border-radius: inherit;
}
.sl-sua__slide {
  position: absolute;
  inset: 0;
  opacity: 0;
  transition: opacity var(--sl-sua-fade, 900ms) var(--sl-ease);
}
.sl-sua__slide.is-on { opacity: 1; }
/* Same rule as the single-media slot: the slot owns the height, never the file. */
.sl-sua__slide > img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: var(--sl-sua-fit, cover); }
/* data-motion="drift": the live slide creeps in, so a held photo never reads as frozen. */
.sl-sua[data-motion="drift"] .sl-sua__slide > img {
  transform: scale(1);
  transition: transform calc(var(--sl-sua-interval, 4500ms) + var(--sl-sua-fade, 900ms)) linear;
}
.sl-sua[data-motion="drift"] .sl-sua__slide.is-on > img { transform: scale(var(--sl-sua-drift, 1.06)); }

/* Optional per-slide credit line, filled from each slide's data-credit. */
.sl-sua__cap {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 2;
  padding: 28px 20px 16px;
  font-size: 0.8125rem;
  letter-spacing: 0.01em;
  /* A caption on a photo is light-on-dark whatever band the section is in. */
  color: var(--sl-sua-cap-color, var(--sl-dark-text));
  background: linear-gradient(to top, rgb(0 0 0 / 0.55), rgb(0 0 0 / 0));
  pointer-events: none;
}

/* Optional annotation marker: a label plus a hand-drawn arrow that rocks toward the media.
   Measured from the reference (agenflow.webflow.io, 2026-09-22): the block sits still at its
   tilt and only the ARROW moves, 1s each way, 2s round trip, rotation plus a small travel.
   We take the idea, not the artwork: the arrow path is ours. */
.sl-sua__marker {
  position: absolute;
  z-index: 3;
  display: flex;
  align-items: center;
  gap: var(--sl-sua-marker-gap, 10px);
  transform: rotate(var(--sl-sua-marker-tilt, -8deg));
  color: var(--sl-sua-marker-color, var(--sl-text));
  pointer-events: none;
}
.sl-sua__marker-text {
  font-family: var(--sl-sua-marker-font, inherit);
  /* Fluid by default: one knob covers desktop and phone, so a marker never swamps a small photo. */
  font-size: var(--sl-sua-marker-size, clamp(18px, 4vw, 28px));
  line-height: 1.1;
}
.sl-sua__marker-arrow {
  flex-shrink: 0;
  width: var(--sl-sua-marker-arrow-w, clamp(32px, 6vw, 48px));
  height: auto;
  animation: sl-sua-wiggle var(--sl-sua-marker-dur, 1s) var(--sl-sua-marker-ease, linear) infinite alternate;
}
/* The wiggle, measured off the reference's testimonial arrow (agenflow.webflow.io, 2026-09-22,
   frame-sampled at 60fps over 2.2s):
     duration 1s each way, yoyo, infinite  ->  2s round trip
     ease "none"  ->  STRICTLY LINEAR. Measured deviation from a linear ramp 0.010deg, from an
     ease-in-out 1.052deg, so a constant-speed sweep is the real thing, not an eased one.
     rotation +5deg -> -5deg, x +5px -> -5px, y -5px -> +5px: x tracks the rotation and y opposes
     it, which is what makes it read as a pen rocking rather than a spinner.
   Composition order matters: the reference's computed matrix carries the raw x/y in its translation
   components, so the translate happens in the UNROTATED frame and the rotation follows.
   --sl-sua-arrow-tilt is the resting angle, added to the swing so the arrow rocks AROUND its pose.
   Both live inside the keyframes because an animation's `transform` overrides the element's own
   (known-bugs/animation-transform-overrides-static-transform.md). */
@keyframes sl-sua-wiggle {
  from {
    transform: translate(var(--sl-sua-arrow-shift, 5px), calc(-1 * var(--sl-sua-arrow-shift, 5px)))
               rotate(calc(var(--sl-sua-arrow-tilt, 0deg) + var(--sl-sua-marker-swing, 5deg)))
               scaleX(var(--sl-sua-arrow-flip, 1));
  }
  to {
    transform: translate(calc(-1 * var(--sl-sua-arrow-shift, 5px)), var(--sl-sua-arrow-shift, 5px))
               rotate(calc(var(--sl-sua-arrow-tilt, 0deg) - var(--sl-sua-marker-swing, 5deg)))
               scaleX(var(--sl-sua-arrow-flip, 1));
  }
}
/* Reduced motion kills the animation, so the resting pose is applied directly there. */
@media (prefers-reduced-motion: reduce) {
  .sl-sua__marker-arrow {
    transform: rotate(var(--sl-sua-arrow-tilt, 0deg)) scaleX(var(--sl-sua-arrow-flip, 1));
  }
}
.sl-sua[data-marker-pos="tl"] .sl-sua__marker { top: 6%; left: 6%; }
.sl-sua[data-marker-pos="tr"] .sl-sua__marker { top: 6%; right: 6%; flex-direction: row-reverse; }
.sl-sua[data-marker-pos="bl"] .sl-sua__marker { bottom: 8%; left: 6%; }
.sl-sua[data-marker-pos="br"] .sl-sua__marker { bottom: 8%; right: 6%; flex-direction: row-reverse; }
.sl-sua[data-marker-pos="tr"] .sl-sua__marker-arrow,
.sl-sua[data-marker-pos="br"] .sl-sua__marker-arrow { --sl-sua-arrow-flip: -1; }

/* --- data-controls="dots": real controls, never decoration. Each dot is a button that switches the
   photo, the strip doubles as the timer, and the media takes swipe and click. A control that does
   not control anything fails review, so all three paths go through the same show(). --- */
.sl-sua__bar {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 2;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 40px 12px 4px 20px;
  background: linear-gradient(to top, rgb(0 0 0 / 0.55), rgb(0 0 0 / 0));
  pointer-events: none;
}
.sl-sua__bar .sl-sua__cap { position: static; padding: 0; background: none; flex: 1 1 auto; min-width: 0; }
.sl-sua__dots { display: flex; align-items: center; gap: 0; margin: 0; padding: 0; list-style: none; flex: 0 0 auto; }
/* A 48px hit area around a 9px dot: the tap-target rule without a 48px blob on the photo. */
.sl-sua__dotbtn {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 48px;
  height: 48px;
  padding: 0;
  border: 0;
  background: none;
  cursor: pointer;
  pointer-events: auto;
  -webkit-tap-highlight-color: transparent;
}
.sl-sua__dotbtn:focus-visible { outline: 2px solid var(--sl-dark-text); outline-offset: -8px; }
.sl-sua__dot {
  position: relative;
  display: block;
  width: 9px;
  height: 9px;
  border-radius: 999px;
  overflow: hidden;
  background: rgb(255 255 255 / 0.45);
  transition: width 0.35s var(--sl-ease), background-color 0.35s var(--sl-ease);
}
.sl-sua__dotbtn:hover .sl-sua__dot { background: rgb(255 255 255 / 0.75); }
.sl-sua__dotbtn[aria-current="true"] .sl-sua__dot { width: 30px; background: rgb(255 255 255 / 0.32); }
/* The fill IS the timer: one interval exactly, paused whenever the carousel is paused. */
.sl-sua__dotbtn[aria-current="true"] .sl-sua__dot::after {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: inherit;
  background: var(--sl-dark-text);
  transform-origin: left center;
  transform: scaleX(0);
  animation: sl-sua-fill var(--sl-sua-interval, 4500ms) linear forwards;
}
.sl-sua.is-paused .sl-sua__dotbtn[aria-current="true"] .sl-sua__dot::after { animation-play-state: paused; }
@keyframes sl-sua-fill { to { transform: scaleX(1); } }
/* Swipe on touch, click on a pointer. pan-y keeps vertical page scrolling native. */
.sl-sua[data-controls="dots"] .sl-sua__slides { cursor: pointer; touch-action: pan-y; }

/* data-marker-scrim="on": a soft darkening at the top of the media so a coloured marker stays
   legible over ANY photo in the rotation, not just the first one. A brand accent over real
   photography is a contrast gamble: the photo changes every few seconds and the marker does not. */
.sl-sua[data-marker-scrim="on"] .sl-sua__media::before {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  top: 0;
  height: var(--sl-sua-marker-scrim-h, 34%);
  z-index: 1;
  border-radius: inherit;
  background: linear-gradient(to bottom, rgb(0 0 0 / var(--sl-sua-marker-scrim, 0.42)), rgb(0 0 0 / 0));
  pointer-events: none;
}

/* data-marker-place="edge": the marker straddles the media's top edge, part of the arrow off the
   photo and part on it. The slides keep clipping themselves (see .sl-sua__slides above). */
.sl-sua[data-marker-place="edge"] .sl-sua__media { overflow: visible; }
.sl-sua[data-marker-place="edge"] .sl-sua__marker { top: calc(-1 * var(--sl-sua-marker-hang, 30px)); }

/* data-marker-stack="above": arrow over the label, pointing down at it. The label is written
   first in the DOM (it is the thing being said), so the column reverses to lift the arrow. */
.sl-sua[data-marker-stack="above"] .sl-sua__marker {
  flex-direction: column-reverse;
  align-items: var(--sl-sua-marker-align, flex-start);
  gap: var(--sl-sua-marker-gap, 2px);
}
.sl-sua[data-marker-stack="above"] .sl-sua__marker-arrow {
  /* Nudges the arrow along the label so its tip can be aimed at a particular word rather than
     just sitting over the start of the line. */
  margin-left: var(--sl-sua-marker-arrow-x, 12px);
  margin-right: var(--sl-sua-marker-arrow-r, 0px);
}

/* Two arrow shapes ship with the recipe. data-arrow picks one; "curve" is the default. */
.sl-sua__marker-arrow [data-sl-arrow-shape] { display: none; }
.sl-sua:not([data-arrow]) .sl-sua__marker-arrow [data-sl-arrow-shape="curve"],
.sl-sua[data-arrow="curve"] .sl-sua__marker-arrow [data-sl-arrow-shape="curve"],
.sl-sua[data-arrow="hook"] .sl-sua__marker-arrow [data-sl-arrow-shape="hook"] { display: inline; }

@media (prefers-reduced-motion: reduce) {
  .sl-sua__slide { transition: none; }
  .sl-sua__dot { transition: none; }
  .sl-sua__dotbtn[aria-current="true"] .sl-sua__dot::after { animation: none; transform: scaleX(1); }
  .sl-sua__marker-arrow { animation: none; }
  .sl-sua[data-motion="drift"] .sl-sua__slide > img { transition: none; transform: none; }
}
/* --- Mode F 2026-09-26: a brief instead of an accordion (first used as a case study opener, from a
   Mabbly case study reference: one opening sentence, then labelled rows, the pictures beside it).
   Every piece is opt-in; an install without these attributes renders exactly as before. --- */
/* data-heading="statement": the heading reads as one opening sentence in the body face, not a display headline. */
.sl-sua[data-heading="statement"] .sl-sua__heading {
  font-family: var(--sl-font-body);
  font-weight: 500;
  font-size: var(--sl-sua-statement-size, clamp(24px, 2.4vw, 34px));
  line-height: 1.3;
  letter-spacing: -0.01em;
  text-transform: none;
  max-width: var(--sl-sua-statement-max, 32ch);
}
/* data-detail="rows": the accordion slot holds a labelled list instead. A label beside its text (stacked on
   phones); a row's text is a paragraph or a list of links, each with an arrow. Nothing hides behind a tap. */
.sl-sua__rows { grid-area: acc; margin: var(--sl-sua-rows-top, 16px) 0 0; display: grid; gap: var(--sl-sua-row-gap, 28px); }
.sl-sua:not([data-detail="rows"]) .sl-sua__rows { display: none; }
.sl-sua[data-detail="rows"] .sl-sua__acc { display: none; }
.sl-sua__row { display: grid; gap: 6px; }
.sl-sua__row dt { font-weight: 700; color: var(--sl-sua-row-label, var(--sl-text)); }
.sl-sua__row dd { margin: 0; color: var(--sl-muted); }
.sl-sua__row dd > p { margin: 0; }
.sl-sua__links { list-style: none; margin: 0; padding: 0; max-width: var(--sl-sua-links-max, 440px); }
.sl-sua__links a {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  min-height: 48px;
  border-bottom: 1px solid var(--sl-border);
  color: var(--sl-text);
  font-weight: 500;
  text-decoration: none;
}
.sl-sua__links a:focus-visible { outline: 2px solid var(--sl-text); outline-offset: 2px; }
.sl-sua__arrow { flex-shrink: 0; width: 18px; height: 18px; transition: transform 0.3s var(--sl-ease); }
.sl-sua__links a:hover .sl-sua__arrow { transform: translateX(4px); }
.sl-sua__links a:active .sl-sua__arrow { transform: translateX(6px); }
@media (min-width: 768px) {
  .sl-sua__row { grid-template-columns: var(--sl-sua-row-label-w, 150px) minmax(0, 1fr); column-gap: 24px; }
  /* A link row is 48px tall (tap target), so its label drops to the first link's text line. */
  .sl-sua__row--links dt { padding-top: 12px; }
}
@media (prefers-reduced-motion: reduce) { .sl-sua__arrow { transition: none; } }

/* data-inset="bl | br" + data-sl-opt-inset: a second, smaller picture over a bottom corner of the media
   (a "before" beside the main picture, a detail beside the whole). Ringed in the band colour so it reads
   as a separate print laid on top. Pair with --sl-sua-fit: contain when the main file must not crop. */
.sl-sua__inset {
  position: absolute;
  z-index: 2;
  bottom: var(--sl-sua-inset-y, 16px);
  width: var(--sl-sua-inset-w, 46%);
  margin: 0;
  border-radius: var(--sl-radius-sm);
  overflow: hidden;
  background: var(--sl-surface);
  box-shadow: 0 0 0 var(--sl-sua-inset-ring, 5px) var(--sl-bg), 0 18px 40px rgb(0 0 0 / 0.22);
}
.sl-sua:not([data-inset]) .sl-sua__inset { display: none; }
.sl-sua[data-inset="bl"] .sl-sua__inset { left: var(--sl-sua-inset-x, 16px); }
.sl-sua[data-inset="br"] .sl-sua__inset { right: var(--sl-sua-inset-x, 16px); }
.sl-sua__inset img { display: block; width: 100%; height: auto; }
.sl-sua__inset figcaption { padding: 8px 12px; font-size: 0.8125rem; line-height: 1.3; color: var(--sl-muted); }
/* ==== RECIPE CSS END ==== */

/* recipe: steps-process/2026-08_creohaus_sequential-fill-phase-timeline */
/* ==== RECIPE CSS START: steps-process/2026-08_creohaus_sequential-fill-phase-timeline ==== */
.sl-sft { background: var(--sl-bg); color: var(--sl-text); }
.sl-sft__head { max-width: 720px; margin: 0 auto 48px; text-align: center; }
.sl-sft__head h2 { margin-top: 14px; }
.sl-sft__sub { margin-top: 14px; color: var(--sl-muted); }

/* Mobile: stacked spine. Each phase (including the last) owns a FIXED-length line below its badge,
   so a longer paragraph never stretches one line longer than the others. */
.sl-sft__timeline { list-style: none; display: flex; flex-direction: column; }
.sl-sft__item { position: relative; display: flex; gap: 16px; padding-bottom: var(--sl-sft-gap, 24px); }
.sl-sft__line { position: absolute; z-index: 1; top: 56px; left: 27px; width: 2px; height: var(--sl-sft-line, 58px); }
.sl-sft__base { position: absolute; inset: 0; background: var(--sl-border); }
.sl-sft__fill {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 0%;
  background: var(--sl-text);
  transition: width var(--sl-sft-step, 450ms) cubic-bezier(0.25, 0.46, 0.45, 0.94), height var(--sl-sft-step, 450ms) cubic-bezier(0.25, 0.46, 0.45, 0.94);
}
/* Growing BOTH axes to 100% lets the breakpoint decide which one shows: one rule, both layouts. */
.sl-sft.is-filled .sl-sft__fill { width: 100%; height: 100%; }
/* Knob data-light: when the section comes into view (not tied to scrolling), the line runs in the accent and each
   step's badge lights up in the accent the moment the line reaches it. Delays are set by the JS (step N = N x step). */
.sl-sft[data-light] .sl-sft__fill { background: var(--sl-accent); }
.sl-sft[data-light] .sl-sft__badge-mid,
.sl-sft[data-light] .sl-sft__badge-inner,
.sl-sft[data-light] .sl-sft__badge-inner .material-symbols-outlined { transition: border-color 0.35s ease, box-shadow 0.35s ease, color 0.35s ease, background-color 0.35s ease; }
.sl-sft[data-light].is-filled .sl-sft__badge-mid { border-color: var(--sl-accent); box-shadow: 0 0 0 1px var(--sl-accent); }
.sl-sft[data-light].is-filled .sl-sft__badge-inner .material-symbols-outlined { color: var(--sl-accent); }
/* data-light="fill": the lit badge fills with the accent, the inner square's line takes the band text colour for
   separation, and the icon takes the band background colour. */
.sl-sft[data-light="fill"].is-filled .sl-sft__badge-mid { background-color: var(--sl-accent); }
.sl-sft[data-light="fill"].is-filled .sl-sft__badge-inner { background-color: transparent; border-color: var(--sl-text); }
.sl-sft[data-light="fill"].is-filled .sl-sft__badge-inner .material-symbols-outlined { color: var(--sl-bg); }

/* Triple-nested badge: circle > bordered square > muted square + icon. */
.sl-sft__badge { position: relative; z-index: 2; flex-shrink: 0; width: 56px; height: 56px; padding: 4px; border-radius: 50%; background: var(--sl-bg); display: flex; align-items: center; justify-content: center; }
.sl-sft__badge-mid { width: 100%; height: 100%; padding: 5px; border: 1px solid var(--sl-border); border-radius: max(0px, calc(var(--sl-radius) + 2px)); background: var(--sl-surface); display: flex; align-items: center; justify-content: center; }
.sl-sft__badge-inner { width: 100%; height: 100%; border: 1px solid var(--sl-border); border-radius: var(--sl-radius-sm); background: var(--sl-surface-2); display: flex; align-items: center; justify-content: center; }
.sl-sft__badge-inner .material-symbols-outlined { font-size: 20px; }
.sl-sft__content { padding-top: 4px; }
.sl-sft__label { display: block; margin-bottom: 4px; font-size: 13px; font-weight: 700; letter-spacing: 0.08em; text-transform: uppercase; color: var(--sl-muted); }
.sl-sft__content p { margin-top: 6px; color: var(--sl-muted); }
.sl-sft__cta { margin-top: 40px; display: flex; justify-content: center; }

@media (min-width: 768px) {
  /* One column per phase, however many phases there are. */
  .sl-sft__timeline { display: grid; grid-auto-flow: column; grid-auto-columns: 1fr; column-gap: 32px; }
  .sl-sft__item { flex-direction: column; align-items: flex-start; gap: 0; padding-bottom: 0; padding-top: 88px; }
  .sl-sft__badge { position: absolute; top: 0; left: 0; width: 64px; height: 64px; }
  /* Each line spans its OWN column only (width 100%, never into the gap): distinct lines, left-justified. */
  .sl-sft__line { top: 32px; left: 0; width: 100%; height: 2px; }
  .sl-sft__fill { width: 0%; height: 100%; }
  .sl-sft__content { padding-top: 0; }
}
@media (prefers-reduced-motion: reduce) { .sl-sft__fill { transition: none; } }
/* ==== RECIPE CSS END ==== */

/* recipe: gallery-portfolio/2026-09_creohaus_folder-tab-project-cards */
/* ==== RECIPE CSS START: gallery-portfolio/2026-09_creohaus_folder-tab-project-cards ==== */
/* Each project is a coloured folder: an angled tab on top carrying a short label, and the folder body below holding
   the media (the "document" inside), the project name, one line, tags and a quiet exit. The whole card is one link.
   Hover lifts the folder and eases the media forward (transform only). Colours cycle by position (knobs). */
.sl-ftc { background: var(--sl-bg); color: var(--sl-text); }
.sl-ftc__head { display: flex; flex-wrap: wrap; align-items: flex-end; justify-content: space-between; gap: 24px 48px; }
.sl-ftc__intro { display: flex; flex-direction: column; gap: 14px; max-width: 640px; }
.sl-ftc__intro p:not(.eyebrow) { color: var(--sl-muted); }

.sl-ftc__grid { list-style: none; margin: 48px 0 0; padding: 0; display: grid; grid-template-columns: 1fr; gap: 40px 24px; }
@media (min-width: 768px) { .sl-ftc__grid { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 1200px) { .sl-ftc__grid { grid-template-columns: repeat(var(--sl-ftc-cols, 2), 1fr); } }

.sl-ftc__item { display: flex; }
/* The card is NOT a link. Only its exit is. A card-wide link makes the screenshot itself clickable,
   and it forces the exit to be a ghost span because anchors cannot nest, which in turn defeats the
   button checkers. One real link in the exit is simpler and more honest about what is clickable. */
.sl-ftc__card {
  --c: var(--sl-surface); --on: var(--sl-text);
  position: relative; display: flex; flex-direction: column; width: 100%;
  color: var(--on);
}
.sl-ftc__item:nth-child(4n+1) .sl-ftc__card { --c: var(--sl-ftc-c1, var(--sl-surface)); --on: var(--sl-ftc-on1, var(--sl-text)); }
.sl-ftc__item:nth-child(4n+2) .sl-ftc__card { --c: var(--sl-ftc-c2, var(--sl-surface-2)); --on: var(--sl-ftc-on2, var(--sl-text)); }
.sl-ftc__item:nth-child(4n+3) .sl-ftc__card { --c: var(--sl-ftc-c3, var(--sl-surface)); --on: var(--sl-ftc-on3, var(--sl-text)); }
.sl-ftc__item:nth-child(4n+4) .sl-ftc__card { --c: var(--sl-ftc-c4, var(--sl-surface-2)); --on: var(--sl-ftc-on4, var(--sl-text)); }

/* The tab: a label on the folder's top edge, its right side cut at 45 degrees (--sl-ftc-cut). It overlaps the body by
   1px so no seam shows between them. */
.sl-ftc__tab {
  align-self: flex-start; position: relative; z-index: 1; margin-bottom: -1px;
  max-width: 78%; padding: 12px 22px; padding-right: calc(22px + var(--sl-ftc-cut, 28px));
  background: var(--c); border-radius: var(--sl-radius) 0 0 0;
  clip-path: polygon(0 0, calc(100% - var(--sl-ftc-cut, 28px)) 0, 100% 100%, 0 100%);
  font-size: 13px; font-weight: 600; letter-spacing: 0.14em; text-transform: uppercase; line-height: 1.3;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.sl-ftc__body {
  flex: 1; display: flex; flex-direction: column; gap: 14px;
  padding: 16px 16px 24px; background: var(--c);
  border-radius: 0 var(--sl-radius) var(--sl-radius) var(--sl-radius);
}
@media (min-width: 768px) { .sl-ftc__body { padding: 20px 20px 28px; } }
.sl-ftc__media { position: relative; aspect-ratio: var(--sl-ftc-ratio, 16 / 10); overflow: hidden; border-radius: var(--sl-radius-sm); background: var(--sl-surface-2); }
.sl-ftc__media > img, .sl-ftc__media > video, .sl-ftc__media > .sl-ph { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
/* --- data-media-mode="scroll": a full-page capture scrolls inside the slot, top to bottom and
   back, the way a screen recording of the site would. One tall image moved with a transform, so it
   costs a fraction of a video and needs none of video's autoplay handling.

   The travel is computed, not guessed: -100% of the image's own height plus one slot height lands
   its bottom edge exactly on the slot's bottom edge. `cqh` reads the slot's height directly, so it
   stays exact at every breakpoint even though this slot changes shape between layouts. That is why
   the slot becomes a size container.

   (The card used to scale this on hover; that came out when the card stopped being a link.) --- */
.sl-ftc[data-media-mode="scroll"] .sl-ftc__media { container-type: size; }
.sl-ftc[data-media-mode="scroll"] .sl-ftc__media img[data-sl-scroll] {
  position: absolute;
  top: 0;
  left: 0;
  right: auto;
  bottom: auto;
  width: 100%;
  height: auto;
  object-fit: fill;
  transition: none;   /* the card's transform transition would fight the animation */
  animation: sl-ftc-scroll var(--sl-ftc-scroll-dur, 14s) linear infinite alternate;
}
@keyframes sl-ftc-scroll {
  from { transform: translateY(0); }
  to   { transform: translateY(calc(-100% + 100cqh)); }
}
/* Nothing should animate while it is off screen. */
.sl-ftc.is-offscreen .sl-ftc__media img[data-sl-scroll] { animation-play-state: paused; }
@media (prefers-reduced-motion: reduce) {
  .sl-ftc[data-media-mode="scroll"] .sl-ftc__media img[data-sl-scroll] { animation: none; }
}

.sl-ftc__text { display: flex; flex-direction: column; gap: 8px; padding: 6px 4px 0; }
.sl-ftc__line { opacity: 0.85; }
.sl-ftc__tags { list-style: none; margin: 0; padding: 0 4px; display: flex; flex-wrap: wrap; gap: 8px; }
.sl-ftc__tags li { padding: 6px 12px; border: 1px solid currentColor; border-radius: var(--sl-radius-sm); font-size: 13px; font-weight: 600; line-height: 1.2; opacity: 0.85; }
.sl-ftc__go { margin-top: auto; padding: 8px 4px 0; }

/* No card-level hover: nothing here is clickable except the exit, and a lift or a media zoom would
   promise otherwise. The exit carries its own hover from the button system. */

.sl-ftc__exit { margin-top: 48px; }

/* Knob data-layout="stack": the folders pile up as you scroll, at every width. Every folder pins at the same line
   (--sl-ftc-top, clear of any sticky nav) one layer above the last, and each tab owns one slot of the width (1/n for
   n folders), so the earlier tabs stay visible and the last folder lands with every tab lined up in a row. When the
   list ends the finished pile scrolls away together. Pure CSS (position: sticky); the JS only drives the optional
   project index. Every body is one fixed height, so no folder underneath ever peeks out below.
   Phones and tablets get upright folders (media on top); under 768px the tabs show 1, 2, 3 instead of their labels. */
.sl-ftc[data-layout="stack"] { --_h: min(520px, calc(100svh - var(--sl-ftc-top, 24px) - var(--sl-ftc-tab-h, 48px) - 120px)); }
.sl-ftc[data-layout="stack"] .sl-ftc__grid { --n: 4; display: block; counter-reset: sl-ftc; }
.sl-ftc[data-layout="stack"] .sl-ftc__grid:has(> .sl-ftc__item:nth-child(2):last-child) { --n: 2; }
.sl-ftc[data-layout="stack"] .sl-ftc__grid:has(> .sl-ftc__item:nth-child(3):last-child) { --n: 3; }
.sl-ftc[data-layout="stack"] .sl-ftc__grid:has(> .sl-ftc__item:nth-child(5):last-child) { --n: 5; }
.sl-ftc[data-layout="stack"] .sl-ftc__grid:has(> .sl-ftc__item:nth-child(6):last-child) { --n: 6; }
.sl-ftc[data-layout="stack"] .sl-ftc__item { position: sticky; top: var(--sl-ftc-top, 24px); counter-increment: sl-ftc; }
/* The run between folders is a beat where the pinned folder sits whole (button included) before the next covers it. */
.sl-ftc[data-layout="stack"] .sl-ftc__item + .sl-ftc__item { margin-top: var(--sl-ftc-stack-gap, clamp(64px, 30vh, 320px)); }
.sl-ftc[data-layout="stack"] .sl-ftc__item:nth-child(1) { --i: 0; z-index: 1; }
.sl-ftc[data-layout="stack"] .sl-ftc__item:nth-child(2) { --i: 1; z-index: 2; }
.sl-ftc[data-layout="stack"] .sl-ftc__item:nth-child(3) { --i: 2; z-index: 3; }
.sl-ftc[data-layout="stack"] .sl-ftc__item:nth-child(4) { --i: 3; z-index: 4; }
.sl-ftc[data-layout="stack"] .sl-ftc__item:nth-child(5) { --i: 4; z-index: 5; }
.sl-ftc[data-layout="stack"] .sl-ftc__item:nth-child(6) { --i: 5; z-index: 6; }

/* Tab: its own slot, cut on both sides so neighbouring tabs meet at the base with a notch between them. */
.sl-ftc[data-layout="stack"] .sl-ftc__tab {
  display: flex; align-items: center; justify-content: center;
  width: calc(100% / var(--n)); max-width: none; height: var(--sl-ftc-tab-h, 48px); margin-left: calc(100% / var(--n) * var(--i));
  padding: 0 calc(var(--sl-ftc-cut, 28px) + 6px); border-radius: 0;
  clip-path: polygon(var(--sl-ftc-cut, 28px) 0, calc(100% - var(--sl-ftc-cut, 28px)) 0, 100% 100%, 0 100%);
}
@media (max-width: 767px) {
  /* A slot on a phone is too narrow for a label: the tab shows the folder number (the label stays for screen readers). */
  .sl-ftc[data-layout="stack"] { --sl-ftc-cut: 20px; }
  .sl-ftc[data-layout="stack"] .sl-ftc__tab { font-size: 0; letter-spacing: 0; }
  .sl-ftc[data-layout="stack"] .sl-ftc__tab::before { content: counter(sl-ftc); font: 800 22px/1 var(--sl-font-display); }
}

/* Body, phones and tablets: upright (media on top, then name, tags, exit). */
.sl-ftc[data-layout="stack"] .sl-ftc__body {
  flex: none; /* flex-basis would override the fixed height */
  display: grid; grid-template-columns: minmax(0, 1fr); grid-template-rows: auto auto auto auto;
  grid-template-areas: "media" "text" "tags" "go"; gap: 14px;
  /* Rows size to content and the card follows, so a media that keeps its ratio can never overflow
     into the title below it. A `1fr` media row inside a fixed card height did exactly that once the
     slot started holding a full-ratio screenshot. */
  height: auto; padding: 16px 16px 20px;
  border-radius: 0 0 var(--sl-radius) var(--sl-radius);
}
.sl-ftc[data-layout="stack"] .sl-ftc__media { grid-area: media; aspect-ratio: auto; height: auto; min-height: 0; }
/* A slot holding a screenshot of a PAGE has to keep that screenshot's shape. Letting the card crop
   it costs the parts that carry the meaning: the client's nav sits at the very top of a hero and
   their buttons at the very bottom, so a vertical crop takes exactly the evidence the card exists to
   show. (Measured before this: the stack gave a 1.26 slot on a phone, cropping 21% off the width and
   cutting the left edge off every headline, and 1.98 at 1920, cropping 24% off the height and
   removing the nav.) So the slot keeps the ratio at every width, and the CARD sizes to the media
   rather than the media being squeezed into a fixed card. */
.sl-ftc[data-layout="stack"] .sl-ftc__media { aspect-ratio: var(--sl-ftc-ratio, 16 / 10); height: auto; }
.sl-ftc[data-layout="stack"] .sl-ftc__text { grid-area: text; padding: 0 4px; gap: 6px; }
.sl-ftc[data-layout="stack"] .sl-ftc__tags { grid-area: tags; padding: 0 4px; }
.sl-ftc[data-layout="stack"] .sl-ftc__go { grid-area: go; margin-top: 0; padding: 0 4px; }


/* Keyboard: a focused folder comes to the front of the pile, so focus never lands on a covered link. */
.sl-ftc[data-layout="stack"] .sl-ftc__item:focus-within { z-index: 10; }

@media (min-width: 1024px) {
  /* Body, desktop, full width: copy column left (name, line, tags, exit at the foot), media filling the right column. */
  .sl-ftc[data-layout="stack"] { --_h: min(560px, calc(100svh - var(--sl-ftc-top, 24px) - 96px)); }
  .sl-ftc[data-layout="stack"] .sl-ftc__body {
    grid-template-columns: minmax(0, 5fr) minmax(0, 7fr); grid-template-rows: auto auto 1fr;
    grid-template-areas: "text media" "tags media" "go media"; gap: 20px clamp(32px, 4vw, 64px);
    padding: clamp(28px, 3vw, 48px);
  }
  .sl-ftc[data-layout="stack"] .sl-ftc__media { height: 100%; }
  .sl-ftc[data-layout="stack"] .sl-ftc__text { padding: 0; gap: 12px; }
  .sl-ftc[data-layout="stack"] .sl-ftc__tags { align-self: start; padding: 0; }
  .sl-ftc[data-layout="stack"] .sl-ftc__go { align-self: end; padding: 0; }

  /* Knob data-split="on" (with stack): the intro pins in a left column while the folders pile up on the right. The
     intro is exactly one folder tall, so the two leave together once the last folder lands. Folders stand upright
     (media across the top, name and exit under it). Put data-sl-opt-exit inside .sl-ftc__intro to pin it with the
     heading; below 1024px it then drops under the folders. */
  .sl-ftc[data-layout="stack"][data-split="on"] { --_h: min(620px, calc(100svh - var(--sl-ftc-top, 24px) - 96px)); }
  .sl-ftc[data-layout="stack"][data-split="on"] > .container {
    display: grid; grid-template-columns: var(--sl-ftc-split, minmax(0, 5fr) minmax(0, 7fr)); column-gap: clamp(40px, 5vw, 96px); align-items: start;
  }
  .sl-ftc[data-layout="stack"][data-split="on"] .sl-ftc__head {
    grid-column: 1; grid-row: 1 / span 2; position: sticky; top: var(--sl-ftc-top, 24px); align-self: start; align-items: flex-start;
    height: calc(var(--sl-ftc-tab-h, 48px) + var(--sl-ftc-stack-h, var(--_h))); padding-top: var(--sl-ftc-tab-h, 48px);
  }
  .sl-ftc[data-layout="stack"][data-split="on"] .sl-ftc__intro { gap: 20px; }
  .sl-ftc[data-layout="stack"][data-split="on"] .sl-ftc__grid { grid-column: 2; grid-row: 1; margin-top: 0; }
  .sl-ftc[data-layout="stack"][data-split="on"] > .container > .sl-ftc__exit { grid-column: 2; grid-row: 2; }
  .sl-ftc[data-layout="stack"][data-split="on"] .sl-ftc__intro > .sl-ftc__exit { margin-top: 12px; }
  .sl-ftc[data-layout="stack"][data-split="on"] .sl-ftc__body {
    grid-template-columns: minmax(0, 1fr) auto; grid-template-rows: minmax(0, 1fr) auto auto;
    grid-template-areas: "media media" "text go" "tags go"; gap: 14px 24px; padding: 20px 20px 24px;
  }
  .sl-ftc[data-layout="stack"][data-split="on"] .sl-ftc__media { height: auto; }
  /* Rows size to their content so a full-ratio media cannot overlap the title beneath it, and the
     card follows. --sl-ftc-shrink keeps a pinned card inside a short laptop viewport by narrowing
     the media (which shortens it through the ratio) rather than cropping it. Verified fitting at
     1024x768, 1280x720, 1440x700, 1440x789, 1440x900, 1680x1050 and 1920x1080.
     --sl-ftc-ratio-n is --sl-ftc-ratio as a plain number, because a calc() cannot multiply by a
     `16 / 10` aspect-ratio value. Change both together. */
  .sl-ftc[data-layout="stack"][data-split="on"] .sl-ftc__body {
    grid-template-rows: auto auto auto;
    height: auto;
  }
  .sl-ftc[data-layout="stack"][data-split="on"] .sl-ftc__head { height: auto; }
  .sl-ftc[data-layout="stack"][data-split="on"] .sl-ftc__media {
    width: min(100%, calc((100svh - var(--sl-ftc-shrink, 360px)) * var(--sl-ftc-ratio-n, 1.6)));
    margin-inline: auto;
  }
  .sl-ftc[data-layout="stack"][data-split="on"] .sl-ftc__text { padding: 4px 4px 0; gap: 6px; }
  .sl-ftc[data-layout="stack"][data-split="on"] .sl-ftc__tags { padding: 0 4px; }
  /* The optional project index shows only in the desktop split. */
  .sl-ftc[data-layout="stack"][data-split="on"] .sl-ftc__index { display: flex; }
}
@media (max-width: 1023px) {
  /* Split markup below 1024px: the intro's parts and the pinned exit re-flow as one column, the exit after the folders. */
  .sl-ftc[data-layout="stack"][data-split="on"] > .container { display: flex; flex-direction: column; gap: 14px; }
  .sl-ftc[data-layout="stack"][data-split="on"] .sl-ftc__head,
  .sl-ftc[data-layout="stack"][data-split="on"] .sl-ftc__intro { display: contents; }
  .sl-ftc[data-layout="stack"][data-split="on"] .sl-ftc__grid { order: 1; margin-top: 34px; }
  .sl-ftc[data-layout="stack"][data-split="on"] .sl-ftc__exit { order: 2; margin-top: 34px; }
}

/* Optional project index (data-sl-opt-index, desktop split only): one row per folder under the intro. The row of the
   folder on top of the pile is marked (aria-current, set by the JS) and each row jumps to its folder. */
.sl-ftc__index { display: none; list-style: none; margin: 8px 0 0; padding: 0; flex-direction: column; border-top: 1px solid var(--sl-border); }
.sl-ftc__index a {
  display: flex; align-items: center; gap: 14px; min-height: 52px; padding: 12px 0; border-bottom: 1px solid var(--sl-border);
  color: var(--sl-muted); text-decoration: none; font-size: 16px; font-weight: 600; line-height: 1.3;
}
.sl-ftc__index li:nth-child(4n+1) { --c: var(--sl-ftc-c1, var(--sl-surface)); }
.sl-ftc__index li:nth-child(4n+2) { --c: var(--sl-ftc-c2, var(--sl-surface-2)); }
.sl-ftc__index li:nth-child(4n+3) { --c: var(--sl-ftc-c3, var(--sl-surface)); }
.sl-ftc__index li:nth-child(4n+4) { --c: var(--sl-ftc-c4, var(--sl-surface-2)); }
.sl-ftc__index-chip { width: 12px; height: 12px; flex: none; background: var(--c); box-shadow: 0 0 0 1px var(--sl-border); transition: transform 300ms var(--sl-ease); }
.sl-ftc__index-name { transition: transform 300ms var(--sl-ease); }
.sl-ftc__index-now { margin-left: auto; font-size: 13px; font-weight: 700; letter-spacing: 0.14em; text-transform: uppercase; color: var(--sl-accent); opacity: 0; transition: opacity 300ms var(--sl-ease); }
.sl-ftc__index a:hover, .sl-ftc__index a:focus-visible, .sl-ftc__index a[aria-current="true"] { color: var(--sl-text); }
.sl-ftc__index a:hover .sl-ftc__index-name, .sl-ftc__index a:focus-visible .sl-ftc__index-name { transform: translateX(4px); }
.sl-ftc__index a:active .sl-ftc__index-name { transform: translateX(2px); }
.sl-ftc__index a:focus-visible { outline: 2px solid var(--sl-text); outline-offset: 2px; }
.sl-ftc__index a[aria-current="true"] .sl-ftc__index-chip { transform: scale(1.35); }
.sl-ftc__index a[aria-current="true"] .sl-ftc__index-now { opacity: 1; }
@media (prefers-reduced-motion: reduce) { .sl-ftc__index-chip, .sl-ftc__index-name, .sl-ftc__index-now { transition: none; } }
/* Optional logo per index row (data-sl-opt-logo, in place of the chip): the client's logo on a small tile in its
   folder colour, so the list reads as "companies we built for". The logo inherits the text colour. */
.sl-ftc__index-logo { flex: none; display: flex; align-items: center; justify-content: center; width: var(--sl-ftc-logo-w, 76px); height: var(--sl-ftc-logo-h, 40px); padding: 5px 8px; background: var(--c); color: var(--sl-text); border-radius: var(--sl-radius-sm); box-shadow: 0 0 0 1px var(--sl-border); transition: box-shadow 300ms var(--sl-ease); }
.sl-ftc__index-logo img, .sl-ftc__index-logo svg { width: 100%; height: 100%; object-fit: contain; }
.sl-ftc__index a[aria-current="true"] .sl-ftc__index-logo { box-shadow: 0 0 0 2px var(--sl-text); }
/* ==== RECIPE CSS END ==== */

/* recipe: team-about/2026-09_creohaus_owner-video-portrait-inset */
/* ==== RECIPE CSS START: team-about/2026-09_creohaus_owner-video-portrait-inset ==== */
.sl-ovp { background: var(--sl-bg); color: var(--sl-text); }
/* Mobile order: eyebrow, heading, media, body, cta. */
.sl-ovp__grid { display: grid; grid-template-columns: 1fr; grid-template-areas: "eyebrow" "heading" "media" "body" "cta"; row-gap: 20px; }
.sl-ovp__copy { display: contents; }
.sl-ovp__eyebrow { grid-area: eyebrow; }
.sl-ovp__heading { grid-area: heading; }
.sl-ovp__body { grid-area: body; display: flex; flex-direction: column; gap: 12px; color: var(--sl-muted); }
.sl-ovp__cta { grid-area: cta; display: flex; flex-direction: column; align-items: stretch; gap: 12px; }
@media (min-width: 640px) { .sl-ovp__cta { flex-direction: row; align-items: center; } }
.sl-ovp__role { display: block; margin-top: 6px; color: var(--sl-muted); font-size: 16px; font-weight: 400; letter-spacing: 0; }
.sl-ovp__media { grid-area: media; position: relative; margin-bottom: 32px; }
@media (min-width: 1024px) {
  .sl-ovp__grid { grid-template-columns: 6fr 6fr; grid-template-areas: "media copy"; column-gap: 56px; align-items: center; }
  .sl-ovp__copy { grid-area: copy; display: flex; flex-direction: column; row-gap: 20px; }
  .sl-ovp__media { margin-bottom: 0; }
}
/* Warmth anchor: a large real portrait. */
.sl-ovp__portrait { position: relative; aspect-ratio: 4 / 5; border-radius: var(--sl-radius); overflow: hidden; background: var(--sl-surface-2); box-shadow: var(--sl-shadow); }
.sl-ovp__portrait > img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
/* Inset film card overlaps the portrait's corner. */
.sl-ovp__inset {
  position: absolute;
  right: 12px;
  bottom: -28px;
  width: 50%;
  max-width: 260px;
  border: 4px solid var(--sl-bg);
  border-radius: var(--sl-radius);
  overflow: hidden;
  background: var(--sl-surface);
  box-shadow: 0 16px 40px rgba(0, 0, 0, 0.28);
}
@media (min-width: 1024px) { .sl-ovp__inset { right: -20px; bottom: -32px; } }
.sl-ovp__film { position: relative; aspect-ratio: 16 / 9; background: var(--sl-bg); color: var(--sl-text); }
.sl-ovp__poster, .sl-ovp__video { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; transition: opacity 0.4s var(--sl-ease); }
.sl-ovp__video { opacity: 0; }
.sl-ovp__play { position: absolute; top: 50%; left: 50%; z-index: 2; width: 48px; height: 48px; border: 0; border-radius: 50%; background: rgba(255, 255, 255, 0.96); color: rgba(0, 0, 0, 0.9); display: flex; align-items: center; justify-content: center; cursor: pointer; transform: translate(-50%, -50%); transition: transform 0.2s var(--sl-ease), opacity 0.4s var(--sl-ease); }
.sl-ovp__play:hover { transform: translate(-50%, -50%) scale(1.06); }
.sl-ovp__play:focus-visible { outline: 2px solid rgba(255, 255, 255, 0.9); outline-offset: 3px; }
.sl-ovp__play svg { width: 18px; height: 18px; margin-left: 2px; }
.sl-ovp__inset-cap { padding: 8px 12px; font-size: 14px; font-weight: 500; color: var(--sl-muted); }
.sl-ovp.is-playing .sl-ovp__video { opacity: 1; }
.sl-ovp.is-playing .sl-ovp__poster, .sl-ovp.is-playing .sl-ovp__play { opacity: 0; pointer-events: none; }
/* Knob: no film yet. Same "who" slot, portrait only, no empty gap. */
.sl-ovp[data-no-video] .sl-ovp__inset { display: none; }
.sl-ovp[data-no-video] .sl-ovp__media { margin-bottom: 0; }
/* Knob: data-media="pair". Two real photos instead of portrait + film: a keyline-framed anchor (back)
   and a smaller photo floating over its lower-left corner (front). Place them so the overlap only
   lands on empty ground/sky: measure the subjects first, then set the geometry vars below.
   Geometry is in % of the pair box: x / w of its width, front-y of its height.
   Set each ratio to the photo's real width / height so nothing is cropped. */
.sl-ovp__pair { display: none; }
.sl-ovp[data-media="pair"] .sl-ovp__portrait, .sl-ovp[data-media="pair"] .sl-ovp__inset { display: none; }
.sl-ovp[data-media="pair"] .sl-ovp__media { margin-bottom: 0; }
.sl-ovp[data-media="pair"] .sl-ovp__pair {
  --sl-ovp-keyline-off: 10px;
  --sl-ovp-ring: 4px;
  display: block;
  position: relative;
  width: 100%;
  aspect-ratio: 1 / var(--sl-ovp-pair-h, 1.08);
}
@media (min-width: 768px) { .sl-ovp[data-media="pair"] .sl-ovp__pair { --sl-ovp-keyline-off: 18px; --sl-ovp-ring: 6px; } }
.sl-ovp__pair-back, .sl-ovp__pair-front { position: absolute; margin: 0; background: var(--sl-surface-2); border-radius: var(--sl-radius); }
.sl-ovp__pair-back > img, .sl-ovp__pair-front > img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; border-radius: inherit; }
.sl-ovp__pair-back {
  z-index: 1;
  left: var(--sl-ovp-back-x, 20%);
  top: 0;
  width: var(--sl-ovp-back-w, 72%);
  aspect-ratio: var(--sl-ovp-back-ratio, 3 / 4);
}
.sl-ovp__pair-back > img { object-position: var(--sl-ovp-back-pos, 50% 50%); }
/* The keyline: a thin accent outline offset down and right behind the anchor photo. data-keyline="off" removes it. */
.sl-ovp__pair-back::before {
  content: "";
  position: absolute;
  top: var(--sl-ovp-keyline-off);
  left: var(--sl-ovp-keyline-off);
  right: calc(var(--sl-ovp-keyline-off) * -1);
  bottom: calc(var(--sl-ovp-keyline-off) * -1);
  z-index: -1;
  border: 2px solid var(--sl-ovp-keyline, var(--sl-accent));
  border-radius: inherit;
  pointer-events: none;
}
.sl-ovp[data-keyline="off"] .sl-ovp__pair-back::before { display: none; }
.sl-ovp__pair-front {
  z-index: 2;
  left: var(--sl-ovp-front-x, 0%);
  top: var(--sl-ovp-front-y, 57.4%);
  width: var(--sl-ovp-front-w, 44%);
  aspect-ratio: var(--sl-ovp-front-ratio, 1);
  /* a band-coloured gap ring cuts the front photo cleanly out of the anchor, then a soft drop shadow */
  box-shadow: 0 0 0 var(--sl-ovp-ring) var(--sl-bg), 0 22px 48px rgba(0, 0, 0, 0.35);
}
.sl-ovp__pair-front > img { object-position: var(--sl-ovp-front-pos, 50% 50%); }
/* CreoHaus skin: measured on the two job-site photos (2026-09-23). Real ratios, so neither photo is cropped;
   the floating photo covers only the empty driveway in the lawn crew shot (its x 0-.33, y .64-1). */
#owner { --sl-ovp-pair-h: 1.08; --sl-ovp-back-x: 20%; --sl-ovp-back-w: 72%; --sl-ovp-back-ratio: 1084 / 1451; --sl-ovp-front-x: 0%; --sl-ovp-front-y: 57.4%; --sl-ovp-front-w: 44%; --sl-ovp-front-ratio: 1277 / 1232; }
/* ==== RECIPE CSS END ==== */

/* recipe: testimonials/2026-08_creohaus_uniform-tile-reviews-marquee */
/* ==== RECIPE CSS START: testimonials/2026-08_creohaus_uniform-tile-reviews-marquee ==== */
.sl-rvm { background: var(--sl-bg); color: var(--sl-text); }
.sl-rvm__head { max-width: 720px; margin: 0 auto 40px; text-align: center; }
.sl-rvm__head h2 { margin-top: 12px; }
/* Fixed-px edge fade on desktop; none on phones (tiles cut off cleanly at the edge). */
.sl-rvm__marquee {
  overflow: hidden;
  -webkit-mask-image: linear-gradient(to right, transparent, rgba(0, 0, 0, 1) 28px, rgba(0, 0, 0, 1) calc(100% - 28px), transparent);
  mask-image: linear-gradient(to right, transparent, rgba(0, 0, 0, 1) 28px, rgba(0, 0, 0, 1) calc(100% - 28px), transparent);
}
@media (max-width: 640px) { .sl-rvm__marquee { -webkit-mask-image: none; mask-image: none; } }
.sl-rvm__track { display: flex; width: max-content; animation: sl-rvm-scroll var(--sl-rvm-duration, 60s) linear infinite; will-change: transform; backface-visibility: hidden; }   /* own layer: a wide moving strip can otherwise flash blank while it repaints */
/* Hover pause is JS-driven (never CSS :hover, which goes stale when a tile resizes under the cursor). */
.sl-rvm__marquee:focus-within .sl-rvm__track,
.sl-rvm__track.is-paused { animation-play-state: paused; }
.sl-rvm__group { display: flex; gap: 20px; flex-shrink: 0; padding-right: 20px; }
@keyframes sl-rvm-scroll { to { transform: translateX(var(--sl-rvm-shift, -50%)); } }
@media (prefers-reduced-motion: reduce) { .sl-rvm__track { animation: none; } }

.sl-rvm__tile {
  position: relative;
  z-index: 1;
  width: 300px;
  max-height: 260px;
  flex-shrink: 0;
  display: flex;
  flex-direction: column;
  padding: 22px;
  overflow: hidden;
  background: var(--sl-surface);
  border: 1px solid var(--sl-border);
  border-radius: var(--sl-radius);
  transition: max-height 0.4s var(--sl-ease), border-color 0.3s var(--sl-ease), box-shadow 0.3s var(--sl-ease);
}
.sl-rvm__tile.is-expanded { z-index: 10; border-color: var(--sl-text); box-shadow: 0 16px 40px rgba(0, 0, 0, 0.18); }
.sl-rvm__stars { margin-bottom: 10px; flex-shrink: 0; color: var(--sl-rvm-star, var(--sl-accent)); font-size: 15px; letter-spacing: 2px; }
.sl-rvm__text {
  margin-bottom: 8px;
  display: -webkit-box;
  -webkit-line-clamp: 5;
  -webkit-box-orient: vertical;
  overflow: hidden;
  transition: opacity 0.32s var(--sl-ease);
}
.sl-rvm__tile.is-expanded .sl-rvm__text { display: block; overflow: visible; }
/* Hidden unless the clamp truncates the text; JS sets display:block explicitly (never ''). */
.sl-rvm__toggle {
  display: none;
  align-self: flex-start;
  margin: 0 0 12px;
  padding: 0;
  border: 0;
  background: none;
  cursor: pointer;
  font-size: 14px;
  font-weight: 600;
  color: var(--sl-text);
  text-decoration: underline;
  text-underline-offset: 2px;
}
.sl-rvm__toggle:focus-visible { outline: 2px solid var(--sl-text); outline-offset: 2px; }
.sl-rvm__meta { display: flex; align-items: center; gap: 10px; margin-top: auto; padding-top: 12px; border-top: 1px solid var(--sl-border); flex-shrink: 0; }
.sl-rvm__avatar { width: 32px; height: 32px; flex-shrink: 0; border-radius: 50%; object-fit: cover; }
.sl-rvm__initials { width: 32px; height: 32px; flex-shrink: 0; border-radius: 50%; display: flex; align-items: center; justify-content: center; font-size: 12px; font-weight: 700; background: var(--sl-surface-2); color: var(--sl-text); }
.sl-rvm__who { display: flex; flex-direction: column; min-width: 0; }
.sl-rvm__name { font-size: 14px; font-weight: 600; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.sl-rvm__src { font-size: 12px; color: var(--sl-muted); }
@media (max-width: 640px) { .sl-rvm__tile { width: 260px; max-height: 244px; padding: 18px; } }
.sl-rvm__foot { margin-top: 36px; display: flex; justify-content: center; }
/* ==== RECIPE CSS END ==== */

/* recipe: cta/2026-09_creohaus_final-cta-dual-button */
/* ==== RECIPE CSS START: cta/2026-09_creohaus_final-cta-dual-button ==== */
.sl-fcta { background: var(--sl-fcta-bg, var(--sl-bg)); color: var(--sl-text); }
.sl-fcta__inner {
  max-width: var(--sl-fcta-max, 640px);
  margin: 0 auto;
  text-align: center;
}
.sl-fcta__sub { margin-top: 14px; color: var(--sl-muted); }
.sl-fcta__actions {
  margin-top: 32px;
  display: flex;
  flex-direction: column;
  align-items: stretch;
  gap: 12px;
}
@media (min-width: 640px) {
  .sl-fcta__actions { flex-direction: row; align-items: center; justify-content: center; gap: 16px; }
}
/* Knob: data-align="left" */
.sl-fcta[data-align="left"] .sl-fcta__inner { margin: 0; text-align: left; }
@media (min-width: 640px) {
  .sl-fcta[data-align="left"] .sl-fcta__actions { justify-content: flex-start; }
}
/* ==== RECIPE CSS END ==== */

/* recipe: footer/2026-08_creohaus_standard-agency-footer */
/* recipe: hero/2026-09_creohaus_framed-page-header */
/* ==== RECIPE CSS START: hero/2026-09_creohaus_framed-page-header ==== */
/* Short inner-page header: one solid panel inside an accent outline, no media. Every interior page
   (about, contact, hubs) shares it, so the H1 sits at one size site-wide. */
.sl-fph {
  background: var(--sl-bg);
  color: var(--sl-text);
  padding-block: var(--sl-fph-pad, 24px);
  padding-top: var(--sl-fph-top, var(--sl-fph-pad, 24px));
}
@media (min-width: 768px) {
  .sl-fph { padding-block: var(--sl-fph-pad-lg, 40px); padding-top: var(--sl-fph-top-lg, var(--sl-fph-pad-lg, 40px)); }
}
.sl-fph__frame {
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  gap: 14px;
  text-align: center;
  min-height: var(--sl-fph-min, 180px);
  padding: 28px 24px;
  background: var(--sl-fph-panel, var(--sl-surface));
  border: var(--sl-fph-line, 2px) solid var(--sl-accent);
  border-radius: var(--sl-radius);
}
@media (min-width: 768px) {
  .sl-fph__frame { min-height: var(--sl-fph-min-lg, 30vh); padding: 40px 64px; }
}
.sl-fph__title {
  margin: 0;
  font-size: var(--sl-fph-title, clamp(40px, 9vw, 108px));
  line-height: 1.02;
  letter-spacing: -0.03em;
  text-transform: var(--sl-fph-title-case, none);
}
.sl-fph__sub { max-width: 640px; color: var(--sl-muted); }
/* Optional fact line under the sub: short, true facts separated by middots. Delete the block when there are none. */
.sl-fph__facts { font-size: 13px; font-weight: 600; letter-spacing: 0.14em; text-transform: uppercase; color: var(--sl-muted); }

/* Knob data-frame="none": no panel and no outline, just the headline on the band (agency standard for inner-page
   headers, Yvad 2026-09-23: headline only, no eyebrow, sub or facts; texture, brand colour or a faint real photo behind). */
.sl-fph[data-frame="none"] .sl-fph__frame { background: none; border: 0; padding-inline: 0; }

/* Knob: data-align="left" */
.sl-fph[data-align="left"] .sl-fph__frame { align-items: flex-start; text-align: left; }
/* ==== RECIPE CSS END ==== */

/* recipe: team-about/2026-09_creohaus_owner-video-letter-signature */
/* ==== RECIPE CSS START: team-about/2026-09_creohaus_owner-video-letter-signature ==== */
.sl-ovl { background: var(--sl-bg); color: var(--sl-text); }
.sl-ovl__grid { display: grid; grid-template-columns: 1fr; gap: 32px; align-items: stretch; }
@media (min-width: 1024px) { .sl-ovl__grid { grid-template-columns: 7fr 5fr; gap: 40px; } }
.sl-ovl__letter {
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  padding: 28px 22px;
  background: var(--sl-surface);
  border: 1px solid var(--sl-border);
  border-radius: var(--sl-radius);
  box-shadow: var(--sl-shadow);
}
@media (min-width: 640px) { .sl-ovl__letter { padding: 48px; } }
.sl-ovl__role { font-size: 13px; font-weight: 600; letter-spacing: 0.14em; text-transform: uppercase; color: var(--sl-accent); }
.sl-ovl__letter h2 { margin-top: 12px; }
.sl-ovl__body { margin-top: 24px; display: flex; flex-direction: column; gap: 16px; font-family: var(--sl-ovl-letter-font, var(--sl-font-body)); font-size: 18px; line-height: 1.7; color: var(--sl-muted); }
.sl-ovl__sign { margin-top: 40px; padding-top: 24px; border-top: 1px solid var(--sl-border); }
/* Swap the text for a real scanned signature image when the owner provides one. */
.sl-ovl__sig { font-family: var(--sl-ovl-sig-font, var(--sl-font-display)); font-style: italic; font-size: 32px; line-height: 1.1; color: var(--sl-text); }
.sl-ovl__sig img { height: 56px; width: auto; }
.sl-ovl__sig-role { margin-top: 6px; color: var(--sl-muted); }
.sl-ovl__actions { margin-top: 24px; display: flex; flex-direction: column; align-items: stretch; gap: 12px; }
@media (min-width: 640px) { .sl-ovl__actions { flex-direction: row; align-items: center; } }

.sl-ovl__media { position: relative; min-height: 360px; aspect-ratio: 4 / 5; border-radius: var(--sl-radius); overflow: hidden; background: var(--sl-bg); color: var(--sl-text); }
@media (min-width: 1024px) { .sl-ovl__media { aspect-ratio: auto; } }
.sl-ovl__poster, .sl-ovl__video { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; transition: opacity 0.4s var(--sl-ease); }
.sl-ovl__poster img { width: 100%; height: 100%; object-fit: cover; }
.sl-ovl__video { opacity: 0; }
.sl-ovl__play {
  position: absolute;
  top: 50%;
  left: 50%;
  z-index: 2;
  width: 64px;
  height: 64px;
  border: 0;
  border-radius: 50%;
  background: rgba(255, 255, 255, 0.96);
  color: rgba(0, 0, 0, 0.9);
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  transform: translate(-50%, -50%);
  transition: transform 0.2s var(--sl-ease), opacity 0.4s var(--sl-ease);
}
.sl-ovl__play:hover { transform: translate(-50%, -50%) scale(1.05); }
.sl-ovl__play:focus-visible { outline: 2px solid rgba(255, 255, 255, 0.9); outline-offset: 3px; }
.sl-ovl__play svg { width: 22px; height: 22px; margin-left: 3px; }
.sl-ovl__caption { position: absolute; left: 16px; right: 16px; bottom: 16px; z-index: 2; padding: 8px 14px; border-radius: 999px; background: rgba(0, 0, 0, 0.6); color: rgba(255, 255, 255, 0.86); font-size: 14px; text-align: center; transition: opacity 0.4s var(--sl-ease); }
.sl-ovl.is-playing .sl-ovl__video { opacity: 1; }
.sl-ovl.is-playing .sl-ovl__poster,
.sl-ovl.is-playing .sl-ovl__play,
.sl-ovl.is-playing .sl-ovl__caption { opacity: 0; pointer-events: none; }
/* Knob data-no-video: portrait only. The poster slot holds the owner's photo; no play button or caption
   (a play button with nothing behind it would mislead). */
.sl-ovl[data-no-video] .sl-ovl__play,
.sl-ovl[data-no-video] .sl-ovl__video,
.sl-ovl[data-no-video] .sl-ovl__caption { display: none; }
/* Phones and tablets (agency Mobile Order rule): eyebrow, heading, photo, letter, signature + CTA.
   The letter card and its inner wrapper become transparent to the grid (display: contents) so the photo can sit
   between the heading and the letter; the card look returns at 1024px, where the two columns sit side by side. */
@media (max-width: 1023px) {
  .sl-ovl__grid { gap: 0; }
  .sl-ovl__letter, .sl-ovl__letter > div:first-child { display: contents; }
  .sl-ovl__role { order: 1; }
  .sl-ovl__letter h2 { order: 2; }
  .sl-ovl__media { order: 3; margin-top: 24px; }
  .sl-ovl__body { order: 4; }
  .sl-ovl__sign { order: 5; margin-top: 32px; }
}
/* ==== RECIPE CSS END ==== */

/* recipe: services-features/2026-08_creohaus_summary-panel-services-accordion */
/* ==== RECIPE CSS START: services-features/2026-08_creohaus_summary-panel-services-accordion ==== */
/* DO NOT BREAK (see notes.md, RULES FOR REBUILDING): no overshoot easing; body laid out at the final open width;
   row locked to its tallest tab by lockHeight(); summary as wide as the open column. Test: row height constant on every
   frame of every switch. Removing any one of these brings back the shake. */
.sl-spa { background: var(--sl-bg); color: var(--sl-text); }
/* Knob data-type="site": the head (eyebrow, title, sub) drops the recipe's own signature type and takes the client
   site's eyebrow / h2 / body styles, so the section matches the rest of the site. Add class="eyebrow" to the eyebrow. */
.sl-spa:not([data-type="site"]) .sl-spa__eyebrow {
  display: flex;
  align-items: stretch;
  gap: 14px;
  color: var(--sl-accent);
  font-size: 13px;
  font-weight: 600;
  letter-spacing: 0.12em;
  text-transform: uppercase;
}
.sl-spa:not([data-type="site"]) .sl-spa__eyebrow::before { content: ""; width: 2px; background: var(--sl-accent); }
/* Deliberate display heading (the signature). Set --sl-spa-title to the site's h2 size to conform. */
.sl-spa__title { margin-top: 20px; }
.sl-spa:not([data-type="site"]) .sl-spa__title {
  font-size: var(--sl-spa-title, clamp(48px, 9vw, 100px));
  font-weight: 500;
  letter-spacing: -0.05em;
  line-height: 0.95;
  color: var(--sl-muted);
}
.sl-spa__sub { margin-top: 16px; max-width: 620px; }
.sl-spa:not([data-type="site"]) .sl-spa__sub { font-size: clamp(20px, 2.4vw, 28px); line-height: 1.3; }
.sl-spa[data-type="site"] .sl-spa__title { margin-top: 14px; color: var(--sl-text); }
.sl-spa[data-type="site"] .sl-spa__sub { margin-top: 14px; max-width: 60ch; color: var(--sl-muted); }

.sl-spa__row { display: flex; gap: 4px; margin-top: 56px; align-items: stretch; min-height: 520px; }
/* Knob --sl-spa-max: cap the head and the row to a narrower, centred block (default: the full container). */
.sl-spa [data-sl-head], .sl-spa__row { max-width: var(--sl-spa-max, none); margin-inline: auto; }
.sl-spa__col {
  position: relative;
  display: flex;
  flex-direction: column;
  flex: 0 0 var(--sl-spa-w-min, 184px);
  padding: var(--sl-spa-pad, 32px);
  border: 0;
  text-align: left;
  font: inherit;
  color: var(--sl-text);
  background: var(--sl-surface);
  border-radius: var(--sl-radius);
  overflow: hidden;
  cursor: pointer;
  /* Column switch: a plain ease, no overshoot (Yvad 2026-09-23: the bounce reads as a glitch; only the switch should move).
     Knob --sl-spa-ease brings a curve back if a brand wants one. */
  transition: flex-basis 0.48s var(--sl-spa-ease, cubic-bezier(0.4, 0, 0.2, 1)), background-color 0.4s ease, color 0.4s ease;
}
.sl-spa__col.is-active { flex: 0 0 var(--sl-spa-w, 372px); background: var(--sl-accent); color: var(--sl-on-accent); }
.sl-spa__col:focus-visible { outline: 2px solid var(--sl-text); outline-offset: 3px; }
.sl-spa__top { display: flex; align-items: flex-start; gap: 8px; }
.sl-spa__arrow { display: inline-flex; transform: rotate(135deg); transition: transform 0.35s var(--sl-spa-ease, cubic-bezier(0.4, 0, 0.2, 1)); }
.sl-spa__col.is-active .sl-spa__arrow,
.sl-spa__col:hover .sl-spa__arrow { transform: rotate(0deg); }
.sl-spa__num { font-size: 32px; font-weight: 500; white-space: nowrap; color: var(--sl-muted); transition: font-size 0.4s var(--sl-spa-ease, cubic-bezier(0.4, 0, 0.2, 1)), color 0.3s ease; }
.sl-spa__col.is-active .sl-spa__num { font-size: 64px; color: currentColor; opacity: 0.55; }
.sl-spa__body { display: block; opacity: 0; max-height: 0; overflow: hidden; transition: opacity 0.35s ease 0.1s; }
.sl-spa__col.is-active .sl-spa__body { opacity: 1; max-height: none; overflow: visible; }
.sl-spa__name { display: block; margin: 16px 0 10px; font-size: 22px; font-weight: 600; white-space: nowrap; }
.sl-spa__desc { display: block; margin-bottom: 10px; max-width: 280px; line-height: 1.6; opacity: 0.82; }
.sl-spa__img { position: relative; display: block; width: 100%; aspect-ratio: 305 / 297; border-radius: var(--sl-radius-sm); overflow: hidden; background: rgba(0, 0, 0, 0.14); }
.sl-spa__img img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
/* data-art on the media slot: brand line art (inline SVG, currentColor) instead of a photo. No dark backing; the art
   takes the column's text colour. Give hidden-line fills class="sl-spa__knock" (they take the accent fill). */
.sl-spa__img[data-art] { background: none; display: flex; align-items: center; justify-content: center; padding: 10%; }
.sl-spa__img[data-art] svg { width: 100%; height: 100%; }
.sl-spa__knock { fill: var(--sl-accent); }
.sl-spa__bottom { display: flex; flex-direction: column; align-items: flex-start; gap: 10px; margin-top: auto; }
.sl-spa__col.is-active .sl-spa__bottom { margin-top: 10px; }
.sl-spa__bottom svg { opacity: 0; transition: opacity 0.3s ease, color 0.3s ease; }
.sl-spa__col.is-active .sl-spa__bottom svg { opacity: 0.85; }
.sl-spa__label { font-size: 21px; transition: font-size 0.3s ease; }
.sl-spa__col:not(.is-active):hover .sl-spa__num { color: var(--sl-text); }
.sl-spa__col:not(.is-active):hover .sl-spa__bottom svg { opacity: 1; color: var(--sl-accent); }
.sl-spa__col:not(.is-active):hover .sl-spa__label { font-size: 28px; }

.sl-spa__summary { flex: 1 1 380px; display: flex; flex-direction: column; padding: 32px 28px; background: var(--sl-surface); border-radius: var(--sl-radius); }
.sl-spa__summary-tag { margin-bottom: 24px; font-size: 13px; color: var(--sl-muted); }
.sl-spa__summary h3 { margin-bottom: 16px; }
.sl-spa__summary p { margin-bottom: 28px; color: var(--sl-muted); }
.sl-spa__dots { display: grid; grid-template-columns: repeat(5, 1fr); gap: 20px; margin-bottom: auto; padding-bottom: 24px; }
.sl-spa__dots span { justify-self: center; width: 6px; height: 6px; border-radius: 50%; background: color-mix(in srgb, var(--sl-text) 25%, transparent); transition: background-color 0.6s ease; }
.sl-spa__dots span.on { background: var(--sl-accent); }
.sl-spa__foot { padding-top: 18px; border-top: 1px solid var(--sl-border); }
/* The active column's text always sits on the accent: force the on-accent colour on every part, so a client
   site's own span / p colours can't leave light text on the accent fill. */
.sl-spa__col.is-active .sl-spa__name,
.sl-spa__col.is-active .sl-spa__desc,
.sl-spa__col.is-active .sl-spa__label { color: var(--sl-on-accent); }
/* The open column's name may wrap (narrow --sl-spa-w values) and its description reads at full strength on the accent. */
.sl-spa__col.is-active .sl-spa__name { white-space: normal; text-wrap: balance; line-height: 1.25; }
.sl-spa__col.is-active .sl-spa__desc { opacity: 1; }
/* Desktop switch, no jump (Yvad 2026-09-23, measured): the open column's content is laid out at its final width from
   the first frame, so it never wraps narrow while the column widens (that pushed the row from 520 to 739px mid-switch),
   and the JS locks the row to its tallest tab (tabs had settled at 528 to 583px, moving everything below). */
@media (min-width: 861px) {
  .sl-spa__col { min-width: 0; }
  .sl-spa__body { width: calc(var(--sl-spa-w, 372px) - 2 * var(--sl-spa-pad, 32px)); flex: none; }
}
.sl-spa__row.is-measuring, .sl-spa__row.is-measuring * { transition: none !important; }
/* Knob data-summary="center": no dot grid and no divider; the summary text and its button sit together,
   centred in the panel. Use when the summary carries a real point of its own rather than a recap. */
.sl-spa[data-summary="center"] .sl-spa__summary { flex: 0 0 var(--sl-spa-w, 372px); justify-content: center; align-items: center; text-align: center; }   /* as wide as the open column */
.sl-spa[data-summary="center"] .sl-spa__dots { display: none; }
.sl-spa[data-summary="center"] .sl-spa__summary p { max-width: 34ch; margin-bottom: 24px; }
.sl-spa[data-summary="center"] .sl-spa__foot { padding-top: 0; border-top: 0; }

/* Mobile: vertical accordion, summary panel closes the section (not first, unlike the source). */
@media (max-width: 860px) {
  .sl-spa__row { flex-direction: column; min-height: 0; }
  .sl-spa__summary { flex-basis: auto; }
  .sl-spa__summary-tag { display: none; }
  .sl-spa__col { flex: 0 0 auto !important; width: 100%; transition: background-color 0.4s ease; }
  .sl-spa__col:not(.is-active) { flex-direction: row; align-items: center; padding: 20px 22px; }
  .sl-spa__col:not(.is-active) .sl-spa__top { align-items: center; gap: 14px; }
  .sl-spa__col:not(.is-active) .sl-spa__body { opacity: 1; max-height: none; overflow: visible; transition: none; }
  .sl-spa__col:not(.is-active) .sl-spa__name { display: inline; margin: 0 0 0 14px; font-size: 16px; font-weight: 500; }
  .sl-spa__col:not(.is-active) .sl-spa__desc,
  .sl-spa__col:not(.is-active) .sl-spa__img,
  .sl-spa__col:not(.is-active) .sl-spa__bottom { display: none; }
  .sl-spa__col.is-active .sl-spa__name { white-space: normal; }
  .sl-spa__desc { max-width: 100%; }
  .sl-spa__arrow, .sl-spa__num { transition-timing-function: ease-out; }
}
@media (prefers-reduced-motion: reduce) { .sl-spa__col, .sl-spa__arrow, .sl-spa__num, .sl-spa__body { transition: none; } }
/* ==== RECIPE CSS END ==== */

/* CreoHaus skin: About page (Yvad, 2026-09-23) */
.sl-fph { --sl-fph-title-case: uppercase; --sl-fph-top: 120px; --sl-fph-top-lg: 136px; }   /* H1 uppercase like every site heading; top padding clears the sticky nav */
[data-band="light"] .sl-ovl__role { color: var(--ink); }   /* same as the site eyebrow on light (Tangerine fails AA at 13px on Paper) */
.sl-ovl { --sl-ovl-sig-font: "Caveat", cursive; }
.sl-ovl__sig { font-style: normal; font-weight: 600; font-size: 40px; }
#apart { --sl-spa-max: 1140px; --sl-spa-w: 330px; --sl-spa-w-min: 155px; --sl-spa-pad: 24px; }   /* 2 x 330 + 3 x 155 + 4 x 4 gaps = 1141: the Real Client Photos block width */
/* 2026-09-25 QA fix: the fixed 1141px row pushed /about 141px sideways at 1024 (861-1190px wide). The widths now scale with
   the room there is (min(1140px, 100vw - 64px)): the three closed columns keep 120-155px so their labels fit, the open column
   and the summary share the rest. 1440 is unchanged (330 / 155); 861-1189px fits with 16px column padding and 18px labels. */
#apart { --sl-spa-room: min(1140px, 100vw - 64px); --sl-spa-w-min: clamp(126px, calc(var(--sl-spa-room) * 0.1358), 155px); --sl-spa-w: calc((var(--sl-spa-room) - 16px - 3 * var(--sl-spa-w-min)) / 2); }
@media (min-width: 861px) and (max-width: 1189px) { #apart { --sl-spa-pad: 16px; } #apart .sl-spa__col .sl-spa__label { font-size: 18px; } #apart .sl-spa__col.sl-spa__col:not(.is-active):hover .sl-spa__label { font-size: 19px; } }
@media (min-width: 861px) and (max-width: 1060px) { #apart .sl-spa__col .sl-spa__label { font-size: 16px; } #apart .sl-spa__col.sl-spa__col:not(.is-active):hover .sl-spa__label { font-size: 17px; } }
#apart .sl-spa__label { font-family: var(--sl-font-display); font-weight: 800; font-size: 22px; line-height: 1.05; letter-spacing: 0.01em; text-transform: uppercase; }
#apart .sl-spa__col:not(.is-active):hover .sl-spa__label { font-size: 24px; }

/* recipe: gallery-portfolio/2026-09_creohaus_photo-reel-marquee */
/* ==== RECIPE CSS START: gallery-portfolio/2026-09_creohaus_photo-reel-marquee ==== */
/* Motion family: testimonials/2026-08_creohaus_uniform-tile-reviews-marquee (seamless loop, exact-pixel shift, enough
   copies for the screen width, track on its own layer, JS-driven hover pause, touch pause, reduced-motion stop). */
.sl-prm { background: var(--sl-bg); color: var(--sl-text); }
.sl-prm__head { max-width: 720px; margin: 0 auto 40px; text-align: center; }
.sl-prm__head > * + * { margin-top: 14px; }
.sl-prm__head p:last-child { color: var(--sl-muted); }
/* Full width by default; data-width="contained" holds the reel to the content block. */
.sl-prm[data-width="contained"] .sl-prm__frame { max-width: calc(var(--sl-prm-max, 1140px) + 48px); margin: 0 auto; padding: 0 24px; }
.sl-prm__frame { display: flex; flex-direction: column; gap: var(--sl-prm-gap, 16px); }
.sl-prm__marquee {
  overflow: hidden;
  -webkit-mask-image: linear-gradient(to right, transparent, rgba(0, 0, 0, 1) var(--sl-prm-fade, 28px), rgba(0, 0, 0, 1) calc(100% - var(--sl-prm-fade, 28px)), transparent);
  mask-image: linear-gradient(to right, transparent, rgba(0, 0, 0, 1) var(--sl-prm-fade, 28px), rgba(0, 0, 0, 1) calc(100% - var(--sl-prm-fade, 28px)), transparent);
}
@media (max-width: 640px) { .sl-prm__marquee { -webkit-mask-image: none; mask-image: none; } }
.sl-prm__track { display: flex; width: max-content; animation: sl-prm-scroll var(--sl-prm-duration, 60s) linear infinite; will-change: transform; backface-visibility: hidden; }   /* own layer: a wide moving strip can otherwise flash blank while it repaints */
.sl-prm__marquee[data-reverse] .sl-prm__track { animation-direction: reverse; }
/* Hover pause is JS-driven (never CSS :hover, which goes stale on a moving strip). */
.sl-prm__track.is-paused { animation-play-state: paused; }
.sl-prm__group { display: flex; gap: var(--sl-prm-gap, 16px); flex-shrink: 0; padding-right: var(--sl-prm-gap, 16px); margin: 0; }
@keyframes sl-prm-scroll { to { transform: translateX(var(--sl-prm-shift, -50%)); } }

/* Tiles share one height; width follows the shape. data-shape="mixed" keeps each photo's orientation
   (data-orient on the tile), "portrait" crops every photo to the portrait frame. */
.sl-prm__tile {
  position: relative;
  flex-shrink: 0;
  height: var(--sl-prm-h, clamp(260px, 26vw, 380px));
  aspect-ratio: var(--sl-prm-portrait, 3 / 4);
  margin: 0;
  overflow: hidden;
  border-radius: var(--sl-radius);
  background: var(--sl-surface-2);
}
.sl-prm[data-shape="mixed"] .sl-prm__tile[data-orient="landscape"] { aspect-ratio: var(--sl-prm-landscape, 3 / 2); }
.sl-prm[data-rows="2"] .sl-prm__tile { height: var(--sl-prm-h2, clamp(200px, 19vw, 290px)); }
.sl-prm__tile img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; display: block; }
.sl-prm__cap {
  position: absolute;
  left: 10px;
  bottom: 10px;
  max-width: calc(100% - 20px);
  padding: 6px 9px 5px;
  background: var(--sl-bg);
  color: var(--sl-text);
  font-size: var(--sl-prm-cap-size, 14px);
  line-height: 1.2;
  font-weight: 600;
  border-radius: var(--sl-radius-sm);
}
.sl-prm[data-caption="off"] .sl-prm__cap { display: none; }
@media (max-width: 640px) {
  .sl-prm__tile { height: var(--sl-prm-h-phone, 240px); }
  .sl-prm[data-rows="2"] .sl-prm__tile { height: var(--sl-prm-h2-phone, 190px); }
}
/* Reduced motion: no loop. The first row becomes a strip you can swipe; copies and the second row are hidden. */
@media (prefers-reduced-motion: reduce) {
  .sl-prm__track { animation: none; }
  .sl-prm__marquee:not([data-sl-row2]) { overflow-x: auto; -webkit-mask-image: none; mask-image: none; scroll-snap-type: x proximity; }
  .sl-prm__tile { scroll-snap-align: start; }
  .sl-prm__group[aria-hidden="true"], .sl-prm__marquee[data-sl-row2] { display: none; }
}
/* ==== RECIPE CSS END ==== */

/* CreoHaus skin: About real-work strip (board option 1, Yvad 2026-09-23). Continues the dark #apart band, so the two
   share one padding (same-band rule): #apart drops its bottom padding, the strip keeps a short top. Captions in the
   site label style. */
#apart { padding-bottom: 0; }
#real-work { padding-top: 56px; }
@media (max-width: 767px) { #real-work { padding-top: 40px; } }
#real-work .sl-prm__cap { font-family: var(--sl-font-display); font-weight: 800; font-size: 15px; letter-spacing: 0.02em; text-transform: uppercase; padding: 6px 9px 4px; }

/* recipe: services-features/2026-09_creohaus_product-demo-rows */
/* ==== RECIPE CSS START: services-features/2026-09_creohaus_product-demo-rows ==== */
/* Named products, one row each: a media panel (phone playing the real thing, a photo, or line art) beside the name,
   a one-line promise and a short checked list. Rows alternate sides. Every row can carry its own tone
   (--sl-pdr-tone) that fills its panel, tag and check badges, so groups of products read as families. */
.sl-pdr { background: var(--sl-bg); color: var(--sl-text); }
.sl-pdr__head { max-width: 760px; margin: 0 auto var(--sl-pdr-head-gap, 72px); text-align: center; }
.sl-pdr__head > * + * { margin-top: 14px; }
.sl-pdr__head > p:not(.eyebrow) { color: var(--sl-muted); }
.sl-pdr__jump { display: flex; flex-wrap: wrap; justify-content: center; gap: 6px 18px; margin-top: 22px; padding: 0; list-style: none; }
.sl-pdr__jump a { color: var(--sl-text); font-weight: 600; text-decoration: underline; text-decoration-color: var(--sl-border); text-underline-offset: 5px; text-decoration-thickness: 2px; transition: text-decoration-color 0.2s ease; }
.sl-pdr__jump a:hover, .sl-pdr__jump a:focus-visible { text-decoration-color: currentColor; }
.sl-pdr__jump a:focus-visible { outline: 2px solid currentColor; outline-offset: 4px; }

.sl-pdr__rows { display: flex; flex-direction: column; gap: var(--sl-pdr-row-gap, 112px); max-width: var(--sl-pdr-max, 1140px); margin: 0 auto; }
.sl-pdr__row {
  display: grid;
  grid-template-columns: 1fr;
  grid-template-areas: "tag" "name" "media" "promise" "list" "cta";
  row-gap: 14px;
  align-items: center;
  scroll-margin-top: var(--sl-pdr-anchor-offset, 24px);
}
.sl-pdr__copy { display: contents; }
.sl-pdr__tag { grid-area: tag; justify-self: start; padding: 5px 10px 4px; border-radius: var(--sl-radius-sm); background: var(--sl-pdr-tone, var(--sl-surface-2)); color: var(--sl-pdr-on-tone, var(--sl-text)); font-size: 13px; font-weight: 700; letter-spacing: 0.1em; text-transform: uppercase; }
.sl-pdr__name { grid-area: name; }
.sl-pdr__media { grid-area: media; margin: 10px 0; }
.sl-pdr__promise { grid-area: promise; font-size: var(--sl-pdr-promise-size, 20px); line-height: 1.5; font-style: var(--sl-pdr-promise-style, italic); }
.sl-pdr__list { grid-area: list; display: flex; flex-direction: column; gap: 18px; margin: 10px 0 0; padding: 0; list-style: none; }
.sl-pdr__cta { grid-area: cta; margin-top: 10px; }
.sl-pdr__item { display: grid; grid-template-columns: 28px 1fr; column-gap: 14px; align-items: start; }
.sl-pdr__check { width: 28px; height: 28px; margin-top: 1px; display: flex; align-items: center; justify-content: center; border-radius: var(--sl-radius-sm); background: var(--sl-pdr-tone, var(--sl-surface-2)); color: var(--sl-pdr-on-tone, var(--sl-text)); }
.sl-pdr__check svg { width: 16px; height: 16px; }
.sl-pdr__item strong { display: block; font-weight: 700; }
.sl-pdr__item span { color: var(--sl-muted); }

@media (min-width: 900px) {
  .sl-pdr__row {
    grid-template-columns: var(--sl-pdr-media-w, 5fr) var(--sl-pdr-copy-w, 6fr);
    grid-template-areas: "media copy";
    column-gap: var(--sl-pdr-col-gap, 80px);
  }
  .sl-pdr__copy { display: flex; flex-direction: column; align-items: flex-start; gap: 14px; grid-area: copy; }
  .sl-pdr__media { margin: 0; }
  /* data-sides: alternate (default, first row media left), media-left, media-right */
  .sl-pdr:not([data-sides="media-left"]) .sl-pdr__row:nth-child(even),
  .sl-pdr[data-sides="media-right"] .sl-pdr__row { grid-template-columns: var(--sl-pdr-copy-w, 6fr) var(--sl-pdr-media-w, 5fr); grid-template-areas: "copy media"; }
  .sl-pdr[data-sides="media-right"] .sl-pdr__row:nth-child(even) { grid-template-areas: "copy media"; }
}

/* Media panel: the tone fills it; what sits inside depends on data-media on the row. */
.sl-pdr__panel { position: relative; aspect-ratio: var(--sl-pdr-panel-ratio, 1 / 1); border-radius: var(--sl-radius); background: var(--sl-pdr-tone, var(--sl-surface-2)); color: var(--sl-pdr-on-tone, var(--sl-text)); overflow: hidden; display: flex; align-items: center; justify-content: center; }
/* phone: a device frame drawn in CSS (no stock device image) holding a looping clip or crossfading screens */
.sl-pdr__phone { position: relative; height: 84%; aspect-ratio: 9 / 19.5; padding: var(--sl-pdr-bezel, 9px); border-radius: var(--sl-pdr-phone-radius, 36px); background: var(--sl-text); box-shadow: 0 2px 4px rgba(0, 0, 0, 0.08), 0 12px 24px rgba(0, 0, 0, 0.12), 0 28px 56px rgba(0, 0, 0, 0.16); transform: rotate(var(--sl-pdr-phone-tilt, 0deg)); }
.sl-pdr__screen { position: relative; width: 100%; height: 100%; overflow: hidden; border-radius: calc(var(--sl-pdr-phone-radius, 36px) - var(--sl-pdr-bezel, 9px)); background: var(--sl-bg); }
.sl-pdr__screen > img, .sl-pdr__screen > video { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; object-position: top; transition: opacity 0.6s ease; }
.sl-pdr__screen[data-slides] > :not(.is-on) { opacity: 0; }
/* photo: fills the panel */
.sl-pdr__row[data-media="photo"] .sl-pdr__panel > img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
/* art: line art (inline SVG, currentColor) centred with breathing room */
.sl-pdr__row[data-media="art"] .sl-pdr__panel > svg,
.sl-pdr__row[data-media="art"] .sl-pdr__panel > img { width: var(--sl-pdr-art-w, 62%); height: auto; max-height: 70%; }
@media (max-width: 899px) {
  .sl-pdr__rows { gap: var(--sl-pdr-row-gap-phone, 72px); }
  .sl-pdr__head { margin-bottom: var(--sl-pdr-head-gap-phone, 48px); }
  .sl-pdr__promise { font-size: var(--sl-pdr-promise-size-phone, 18px); }
}
@media (prefers-reduced-motion: reduce) { .sl-pdr__screen > img, .sl-pdr__screen > video { transition: none; } }
/* ==== RECIPE CSS END ==== */

/* recipe: cta/2026-09_creohaus_anxiety-cta-plan */
/* ==== RECIPE CSS START: cta/2026-09_creohaus_anxiety-cta-plan ==== */
.sl-acp { background: var(--sl-bg); color: var(--sl-text); }
.sl-acp__panel {
  display: grid;
  grid-template-columns: 1fr;
  gap: 40px;
  align-items: start;
  max-width: var(--sl-acp-max, none);
  margin-inline: auto;
}
.sl-acp[data-layout="card"] .sl-acp__panel {
  background: var(--sl-surface);
  border: 1px solid var(--sl-border);
  border-radius: var(--sl-radius);
  box-shadow: var(--sl-shadow);
  padding: 32px 24px;
}
@media (min-width: 900px) {
  .sl-acp__panel { grid-template-columns: 1fr 1fr; gap: 64px; }
  .sl-acp[data-layout="card"] .sl-acp__panel { padding: 56px; }
}
.sl-acp__lead { display: flex; flex-direction: column; align-items: flex-start; gap: 20px; }
.sl-acp__sub { color: var(--sl-muted); max-width: 46ch; }
.sl-acp__actions { display: flex; flex-direction: column; align-items: stretch; gap: 12px; width: 100%; }
@media (min-width: 640px) { .sl-acp__actions { flex-direction: row; align-items: center; width: auto; } }
.sl-acp__alt { color: var(--sl-muted); }
.sl-acp__alt a { color: var(--sl-text); font-weight: 600; text-underline-offset: 3px; }

.sl-acp__plan { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 28px; }
.sl-acp__step { display: flex; gap: 18px; align-items: flex-start; }
.sl-acp__num {
  flex-shrink: 0;
  width: 44px;
  height: 44px;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  font-weight: 700;
  background: var(--sl-surface-2);
  color: var(--sl-text);
}
.sl-acp__step p { margin-top: 6px; color: var(--sl-muted); }
/* data-marker="check": the list is what is included, not a sequence, so each marker holds a check icon instead of a
   number (use a <ul>). Numbers stay the default for real first steps. */
.sl-acp[data-marker="check"] .sl-acp__num { border-radius: var(--sl-radius-sm); }
.sl-acp__num svg { width: 20px; height: 20px; }
/* ==== RECIPE CSS END ==== */

/* CreoHaus skin: Services page (Yvad, 2026-09-23). Row tones are set per row in services.html (outcome colours). */
#products { --sl-pdr-anchor-offset: 112px; }   /* a jump link lands below the 88px sticky nav */
.sl-pdr .sl-spa__knock { fill: var(--sl-pdr-tone, var(--sl-surface-2)); }   /* hidden lines in the keyline art take the panel tone */
.sl-pdr__tag { font-family: var(--sl-font-display); font-weight: 800; font-size: 15px; letter-spacing: 0.04em; padding: 6px 10px 4px; }   /* site label style */
/* Logo Refresh panel: a real client logo, before and after */
.ch-logo-ba { width: 86%; display: grid; grid-template-columns: 1fr auto 1fr; align-items: center; gap: 14px; }
.ch-logo-ba figure { margin: 0; display: flex; flex-direction: column; align-items: center; gap: 10px; }
.ch-logo-ba img, .ch-logo-ba__after { width: 100%; aspect-ratio: 192 / 120; display: block; box-shadow: 0 2px 4px rgba(58, 15, 34, 0.08), 0 10px 24px rgba(58, 15, 34, 0.12); }
.ch-logo-ba img { height: auto; object-fit: cover; }   /* the height attribute would otherwise beat aspect-ratio on narrow screens */
.ch-logo-ba__after { display: flex; align-items: center; justify-content: center; padding: 14%; box-sizing: border-box; background: var(--ink); color: var(--paper); }
.ch-logo-ba__after svg { width: 100%; height: 100%; }
.ch-logo-ba figcaption { font-family: var(--sl-font-display); font-weight: 800; font-size: 15px; letter-spacing: 0.04em; text-transform: uppercase; }
.ch-logo-ba__arrow svg { width: 26px; height: 26px; transform: rotate(45deg); }
#haus-plan { --sl-acp-max: 1140px; }   /* lines up with the product rows above */
#haus-plan .sl-acp__num { box-shadow: inset 0 0 0 1px var(--sl-border); }   /* the marker square is the card colour on dark: a hairline keeps it a badge */
#haus-plan .ch-not-yet { margin-top: 8px; padding-top: 20px; border-top: 1px solid var(--sl-border); }
#haus-plan .ch-not-yet strong { color: var(--sl-text); }

/* CreoHaus demo scenes (prototype, Yvad 2026-09-23; promote to the library once approved).
   A phone acting out what a service does, animated by GSAP in site.js (demo scenes block). Without GSAP, or with
   reduced motion, the scene shows its finished frame. Sizes follow the phone's width (container units). */
/* 3D device (Yvad rounds 2-3): a Berry body facing the viewer straight on (round 3: no tilt, so the screen reads
   flat and crisp), with a thin lower-right edge (stacked shadows) for thickness, a side button, glass shine on the
   screen and a soft ground shadow. The phone itself is never tweened. */
.ch-scene { position: relative; height: 88%; aspect-ratio: 9 / 19; max-width: 100%; }
.ch-scene::after { content: ""; position: absolute; z-index: 0; left: 4%; right: 4%; bottom: -3.5%; height: 5%; border-radius: 50%; background: radial-gradient(closest-side, rgba(58, 15, 34, 0.38), rgba(58, 15, 34, 0)); filter: blur(4px); }
.ch-phone { position: relative; z-index: 1; width: 100%; height: 100%; padding: 3.4%; border-radius: 12% / 5.8%;
  background: linear-gradient(140deg, var(--berry-mid) 0%, var(--ink) 38%, var(--ink) 100%);
  box-shadow: inset 0 0 0 1.5px rgba(255, 243, 228, 0.22), inset 3px 3px 4px rgba(255, 243, 228, 0.12),
    1px 1px 0 var(--berry-mid), 2px 2px 0 var(--berry-mid), 3px 3px 0 var(--ink), 4px 4px 0 var(--ink),
    0 16px 30px rgba(58, 15, 34, 0.24), 0 36px 70px rgba(58, 15, 34, 0.2); }
.ch-phone::before { content: ""; position: absolute; right: -4px; top: 21%; width: 4px; height: 10%; border-radius: 0 3px 3px 0; background: linear-gradient(90deg, var(--ink), var(--berry-mid)); }   /* side button */
.ch-phone__screen { position: relative; width: 100%; height: 100%; overflow: hidden; border-radius: 10% / 4.9%; background: var(--paper); container-type: inline-size; font-family: var(--sl-font-body); color: var(--ink); }
.ch-phone__screen::after { content: ""; position: absolute; z-index: 10; inset: 0; pointer-events: none; background: linear-gradient(118deg, rgba(255, 255, 255, 0.32) 0%, rgba(255, 255, 255, 0.08) 26%, rgba(255, 255, 255, 0) 42%); }   /* glass shine */
.ch-phone__screen::before { content: ""; position: absolute; z-index: 9; top: 2.4%; left: 50%; width: 30%; height: 3.4%; margin-left: -15%; border-radius: 99px; background: var(--ink); }   /* camera island */
.ch-status { position: absolute; z-index: 8; top: 0; left: 0; right: 0; height: 8.5%; display: flex; align-items: center; justify-content: space-between; padding: 0 9%; font-size: 5cqw; font-weight: 700; }
.ch-status__icons { display: flex; gap: 2.4cqw; align-items: center; }
.ch-status__icons i { display: block; width: 5cqw; height: 3cqw; border-radius: 1cqw; background: currentColor; }
.ch-status__icons i:first-child { width: 4cqw; clip-path: polygon(0 100%, 100% 0, 100% 100%); border-radius: 0; }
.ch-status--light { color: var(--light); }

/* incoming call */
.ch-call { position: absolute; inset: 0; z-index: 2; display: flex; flex-direction: column; align-items: center; padding: 26% 8% 12%; background: var(--berry-mid); color: var(--light); text-align: center; }
.ch-call__who { position: relative; width: 30cqw; height: 30cqw; margin-bottom: 7cqw; }
.ch-call__ring { position: absolute; inset: 0; border-radius: 50%; border: 0.8cqw solid var(--light); opacity: 0; }
.ch-call__avatar { position: absolute; inset: 0; display: flex; align-items: center; justify-content: center; border-radius: 50%; background: var(--muted); color: var(--ink); font-family: var(--sl-font-display); font-weight: 800; font-size: 11cqw; letter-spacing: 0.02em; }
.ch-call__name { font-size: 8.5cqw; font-weight: 600; line-height: 1.2; }
.ch-call__meta { margin-top: 2cqw; font-size: 5cqw; color: var(--muted); }
.ch-call__actions { margin-top: auto; width: 100%; display: flex; justify-content: space-between; padding: 0 6%; }
.ch-call__btn { display: flex; flex-direction: column; align-items: center; gap: 2.4cqw; font-size: 4.2cqw; color: var(--light); }
.ch-call__btn span { width: 17cqw; height: 17cqw; display: flex; align-items: center; justify-content: center; border-radius: 50%; }
.ch-call__btn svg { width: 8cqw; height: 8cqw; }
.ch-call__btn--no span { background: var(--tangerine); }
.ch-call__btn--no svg { transform: rotate(135deg); }
.ch-call__btn--yes span { background: var(--play-mint); color: var(--ink); }

/* notification, time gap, thread */
.ch-notif { position: absolute; z-index: 6; top: 9.5%; left: 5%; right: 5%; display: flex; gap: 3.5cqw; align-items: center; padding: 3.6cqw 4cqw; border-radius: 5cqw; background: var(--light); box-shadow: 0 2px 6px rgba(12, 2, 8, 0.12), 0 10px 24px rgba(12, 2, 8, 0.16); font-size: 4.4cqw; line-height: 1.3; }
.ch-notif__icon { flex: none; width: 10cqw; height: 10cqw; display: flex; align-items: center; justify-content: center; border-radius: 2.6cqw; background: var(--tangerine); color: var(--ink); }
.ch-notif__icon svg { width: 5.6cqw; height: 5.6cqw; }
.ch-notif b { display: block; font-size: 4.8cqw; }
.ch-notif span { color: var(--ink-soft); }
.ch-later { position: absolute; z-index: 7; top: 50%; left: 50%; padding: 2.6cqw 5cqw; border-radius: 99px; background: var(--ink); color: var(--light); font-size: 4.6cqw; font-weight: 600; white-space: nowrap; transform: translate(-50%, -50%); }
.ch-thread { position: absolute; inset: 0; z-index: 1; display: flex; flex-direction: column; padding-top: 11%; background: var(--paper); }
.ch-thread__compose { display: flex; align-items: center; gap: 2.6cqw; margin: 0 4cqw 5cqw; }
.ch-thread__compose span { flex: 1; padding: 2.6cqw 4cqw; border-radius: 99px; box-shadow: inset 0 0 0 1px var(--line); font-size: 4.2cqw; color: var(--ink-soft); }
.ch-thread__compose i { width: 8.6cqw; height: 8.6cqw; display: flex; align-items: center; justify-content: center; border-radius: 50%; background: var(--line); color: var(--ink-soft); }
.ch-thread__compose svg { width: 4.4cqw; height: 4.4cqw; }
.ch-thread__delivered { align-self: flex-end; margin-top: -1.6cqw; font-size: 3.4cqw; color: var(--ink-soft); }
.ch-thread__head { display: flex; align-items: center; gap: 3cqw; padding: 3cqw 6cqw 4cqw; border-bottom: 1px solid var(--line); }
.ch-thread__head i { width: 9cqw; height: 9cqw; display: flex; align-items: center; justify-content: center; border-radius: 50%; background: var(--muted); color: var(--ink); font-family: var(--sl-font-display); font-weight: 800; font-size: 4cqw; font-style: normal; }
.ch-thread__head b { font-size: 5cqw; }
.ch-thread__head small { display: block; font-size: 3.8cqw; color: var(--ink-soft); font-weight: 400; }
.ch-thread__body { flex: 1; display: flex; flex-direction: column; gap: 3cqw; padding: 5cqw 5cqw; font-size: 4.3cqw; line-height: 1.38; }
.ch-thread__stamp { align-self: center; font-size: 3.6cqw; color: var(--ink-soft); }
.ch-bubble { position: relative; max-width: 80%; padding: 2.8cqw 4cqw; border-radius: 4.6cqw; }
.ch-bubble--out { align-self: flex-end; background: var(--ink); color: var(--light); border-bottom-right-radius: 1.2cqw; }
.ch-bubble--in { align-self: flex-start; background: var(--paper-2); color: var(--ink); border-bottom-left-radius: 1.2cqw; box-shadow: inset 0 0 0 1px var(--line); }
.ch-bubble__from { display: block; margin-bottom: 1cqw; font-size: 3.4cqw; font-weight: 700; letter-spacing: 0.04em; text-transform: uppercase; opacity: 0.7; }
.ch-typing { position: absolute; inset: 0; display: flex; align-items: center; justify-content: center; gap: 1.6cqw; }
.ch-typing i { width: 1.8cqw; height: 1.8cqw; border-radius: 50%; background: currentColor; opacity: 0.6; }
.ch-saved { position: absolute; z-index: 6; left: 6%; right: 6%; bottom: 13%; display: flex; gap: 3cqw; align-items: center; justify-content: center; padding: 3.4cqw 4cqw; border-radius: 99px; background: var(--ink); color: var(--light); font-size: 4.4cqw; font-weight: 600; }
.ch-saved svg { width: 5cqw; height: 5cqw; color: var(--tangerine); }
/* finished frame (no GSAP / reduced motion): call screen, "later" chip and typing dots hidden, thread shown */
.ch-scene:not(.is-live) .ch-call, .ch-scene:not(.is-live) .ch-later, .ch-scene:not(.is-live) .ch-typing, .ch-scene:not(.is-live) .ch-notif { display: none; }
/* the scene's panel in the product rows: a Berry stage instead of a play colour */
.sl-pdr__row[data-media="scene"] .sl-pdr__panel { background: var(--paper-2); box-shadow: inset 0 0 0 1px var(--line); }   /* light stage: Berry lives in the phone (Yvad round 2) */

/* Scenes that cross from the customer's phone to the owner's (data-roles): a role tag above the phone says whose
   screen it is. The phone gives up a little height so the tag fits in the panel; the device CSS is unchanged.
   data-still="off" marks the layers that are not part of the finished frame (hidden when the scene is not live). */
.ch-scene[data-roles] { height: 80%; margin-top: 8%; }
.ch-role { position: absolute; z-index: 2; left: 50%; bottom: calc(100% + 10px); display: grid; transform: translateX(-50%); white-space: nowrap; }
.ch-role > span { grid-area: 1 / 1; justify-self: center; padding: 5px 12px; border-radius: 99px; background: var(--paper); box-shadow: inset 0 0 0 1px var(--line); font-family: var(--sl-font-body); font-size: clamp(11px, 1.1vw, 13px); font-weight: 700; letter-spacing: 0.06em; text-transform: uppercase; color: var(--ink); }
.ch-scene:not(.is-live) [data-still="off"] { display: none; }
.ch-tap { position: absolute; z-index: 3; left: 50%; top: 50%; width: 12cqw; height: 12cqw; margin: -6cqw 0 0 -6cqw; border-radius: 50%; background: rgba(58, 15, 34, 0.2); box-shadow: 0 0 0 1.6cqw rgba(58, 15, 34, 0.08); opacity: 0; pointer-events: none; }
.ch-tap--light { background: rgba(255, 243, 228, 0.35); box-shadow: 0 0 0 1.6cqw rgba(255, 243, 228, 0.14); }
.ch-notif small { display: block; font-size: 3.3cqw; font-weight: 700; letter-spacing: 0.04em; text-transform: uppercase; color: var(--ink-soft); }
.ch-notif .ch-notif__icon--app { background: var(--ink); color: var(--light); }
.ch-notif--msg { align-items: flex-start; }
.ch-notif--msg div > span { display: block; margin-top: 0.6cqw; color: var(--ink); }
.ch-notif--lock { top: 38%; background: rgba(255, 243, 228, 0.94); color: var(--ink); }
.ch-saved--toast { bottom: 10%; }

/* Instant Reply Inbox: the business's website form (customer's phone) */
.ch-site { position: absolute; inset: 0; z-index: 4; display: flex; flex-direction: column; gap: 2.8cqw; padding: 11% 6cqw 0; background: var(--paper); font-size: 4.2cqw; }
.ch-site__url { align-self: center; display: flex; align-items: center; gap: 1.4cqw; padding: 1.4cqw 4cqw; border-radius: 99px; background: var(--paper-2); font-size: 3.4cqw; color: var(--ink-soft); }
.ch-site__url svg { width: 3cqw; height: 3cqw; }
.ch-site__brand { display: flex; align-items: center; gap: 2.4cqw; margin-top: 1.6cqw; padding-bottom: 3cqw; border-bottom: 1px solid var(--line); font-size: 4.4cqw; font-weight: 700; }
.ch-site__brand i { width: 8cqw; height: 8cqw; display: flex; align-items: center; justify-content: center; border-radius: 2cqw; background: var(--ink); color: var(--light); font-family: var(--sl-font-display); font-style: normal; font-weight: 800; font-size: 3.4cqw; }
.ch-site__title { margin-top: 1.4cqw; font-family: var(--sl-font-display); font-size: 7.4cqw; font-weight: 800; line-height: 1.1; letter-spacing: -0.02em; }
.ch-site__sub { margin-top: -1.4cqw; color: var(--ink-soft); }
.ch-field { display: flex; flex-direction: column; gap: 1.2cqw; }
.ch-field > span { font-size: 3.4cqw; font-weight: 700; color: var(--ink-soft); }
.ch-field em { display: block; min-height: 9.6cqw; padding: 2.4cqw 3.2cqw; border-radius: 2.4cqw; background: var(--light); box-shadow: inset 0 0 0 1px var(--line); font-style: normal; line-height: 1.35; }
.ch-field--area em { min-height: 24cqw; }
.ch-site__submit { display: grid; margin-top: 1.4cqw; }
.ch-site__submit > span { grid-area: 1 / 1; }
.ch-site__btn { position: relative; display: flex; align-items: center; justify-content: center; padding: 3cqw; border-radius: 99px; background: var(--ink); color: var(--light); font-size: 4.4cqw; font-weight: 700; }
.ch-site__thanks { display: flex; align-items: center; justify-content: center; gap: 2cqw; padding: 3cqw; border-radius: 99px; background: var(--paper-2); box-shadow: inset 0 0 0 1px var(--line); font-weight: 600; }
.ch-site__thanks svg { width: 4.4cqw; height: 4.4cqw; }

/* the owner's lock screen */
.ch-lock { position: absolute; inset: 0; z-index: 3; display: flex; flex-direction: column; align-items: center; padding-top: 20%; background: linear-gradient(165deg, var(--berry-mid) 0%, var(--ink) 70%); color: var(--light); }
.ch-lock__time { font-size: 19cqw; font-weight: 600; line-height: 1; letter-spacing: -0.02em; }
.ch-lock__date { margin-top: 2.4cqw; font-size: 4.4cqw; color: var(--muted); }

/* the Conversations list */
.ch-inbox { position: absolute; inset: 0; z-index: 2; display: flex; flex-direction: column; padding-top: 11%; background: var(--paper); }
.ch-inbox__head { display: flex; align-items: center; justify-content: space-between; padding: 3cqw 5cqw 3.4cqw; border-bottom: 1px solid var(--line); }
.ch-inbox__head b { font-size: 6cqw; }
.ch-inbox__tabs { display: flex; gap: 1.6cqw; }
.ch-inbox__tabs em { padding: 1.2cqw 2.8cqw; border-radius: 99px; font-style: normal; font-size: 3.4cqw; color: var(--ink-soft); box-shadow: inset 0 0 0 1px var(--line); }
.ch-inbox__tabs em.is-on { background: var(--ink); color: var(--light); box-shadow: none; }
.ch-inbox__list { margin: 0; padding: 0; list-style: none; }
.ch-inbox__row { position: relative; display: flex; align-items: center; gap: 3cqw; padding: 3.2cqw 5cqw; border-bottom: 1px solid var(--line); background: var(--paper); }
.ch-inbox__row.is-new { background: var(--light); }
.ch-inbox__row > div { flex: 1; min-width: 0; }
.ch-inbox__row b { display: block; font-size: 4.2cqw; }
.ch-inbox__row div span { display: block; overflow: hidden; white-space: nowrap; text-overflow: ellipsis; font-size: 3.6cqw; color: var(--ink-soft); }
.ch-inbox__row time { align-self: flex-start; font-size: 3.2cqw; color: var(--ink-soft); }
.ch-inbox__row.is-new time { color: var(--ink); font-weight: 700; }
.ch-inbox__row.is-new::after { content: ""; position: absolute; right: 5.4cqw; bottom: 4.4cqw; width: 2.2cqw; height: 2.2cqw; border-radius: 50%; background: var(--tangerine); }   /* unread */
.ch-inbox__av { flex: none; width: 10cqw; height: 10cqw; display: flex; align-items: center; justify-content: center; border-radius: 50%; background: var(--paper-2); box-shadow: inset 0 0 0 1px var(--line); }
.ch-inbox__av svg { width: 5cqw; height: 5cqw; }

/* the lead's thread: form card, the automatic reply, a text / email switch */
.ch-formcard { align-self: stretch; display: flex; flex-direction: column; gap: 1cqw; padding: 3cqw 3.6cqw; border-radius: 3.6cqw; background: var(--paper-2); box-shadow: inset 0 0 0 1px var(--line); font-size: 3.9cqw; }
.ch-formcard__tag { display: flex; align-items: center; gap: 1.4cqw; font-size: 3.2cqw; font-weight: 700; letter-spacing: 0.04em; text-transform: uppercase; color: var(--ink-soft); }
.ch-formcard__tag svg { width: 3.6cqw; height: 3.6cqw; }
.ch-formcard b { font-size: 4.2cqw; }
.ch-formcard u { font-size: 3.4cqw; font-weight: 600; }
.ch-chan { flex: none; display: flex; align-items: center; gap: 0.8cqw; padding: 2.2cqw 2.8cqw; border-radius: 99px; background: var(--ink); color: var(--light); font-size: 3.6cqw; }
.ch-chan__opts { display: grid; }
.ch-chan__opts > span { grid-area: 1 / 1; }
.ch-chan svg { width: 3.4cqw; height: 3.4cqw; }
.ch-thread__compose .ch-chan span { flex: none; padding: 0; border-radius: 0; box-shadow: none; font-size: inherit; color: inherit; }   /* not the message field style */

/* One-Tap Reviews: the owner's Reviews screen and the request sheet */
.ch-revs { position: absolute; inset: 0; z-index: 4; display: flex; flex-direction: column; gap: 3cqw; padding: 11% 5cqw 0; background: var(--paper); }
.ch-revs__head { display: flex; align-items: center; justify-content: space-between; padding-top: 3cqw; }
.ch-revs__head b { font-size: 6.4cqw; }
.ch-revs__plus { position: relative; width: 10.5cqw; height: 10.5cqw; display: flex; align-items: center; justify-content: center; border-radius: 50%; background: var(--ink); color: var(--light); }
.ch-revs__plus svg { width: 5cqw; height: 5cqw; }
.ch-revs__tabs { display: flex; gap: 5cqw; border-bottom: 1px solid var(--line); }
.ch-revs__tabs em { padding-bottom: 2cqw; font-style: normal; font-size: 3.8cqw; color: var(--ink-soft); }
.ch-revs__tabs em.is-on { color: var(--ink); font-weight: 700; box-shadow: inset 0 -0.8cqw 0 var(--ink); }
.ch-revs__label, .ch-sheet__label { font-size: 3.2cqw; font-weight: 700; letter-spacing: 0.05em; text-transform: uppercase; color: var(--ink-soft); }
.ch-skel { display: flex; align-items: center; gap: 3cqw; padding: 2cqw 0; }
.ch-skel > i { flex: none; width: 9cqw; height: 9cqw; border-radius: 50%; background: var(--paper-2); }
.ch-skel > div { flex: 1; display: flex; flex-direction: column; gap: 1.6cqw; }
.ch-skel s { display: block; width: 62%; height: 2.4cqw; border-radius: 99px; background: var(--paper-2); }
.ch-skel s + s { width: 38%; }
.ch-skel > em { padding: 1cqw 2.6cqw; border-radius: 99px; box-shadow: inset 0 0 0 1px var(--line); font-style: normal; font-size: 3cqw; color: var(--ink-soft); }
.ch-sheet, .ch-gr { position: absolute; left: 0; right: 0; bottom: 0; display: flex; flex-direction: column; border-radius: 6cqw 6cqw 0 0; background: var(--light); box-shadow: 0 -4px 18px rgba(58, 15, 34, 0.16); }
.ch-sheet { z-index: 5; height: 80%; padding: 2.4cqw 5cqw 0; }
.ch-sheet__grab { align-self: center; width: 11cqw; height: 1.2cqw; border-radius: 99px; background: var(--line); }
.ch-sheet__title { margin: 3.4cqw 0 3cqw; font-size: 5.2cqw; }
.ch-sheet__stack { position: relative; flex: 1; }
.ch-sheet__pick, .ch-sheet__compose { position: absolute; inset: 0; display: flex; flex-direction: column; gap: 2.6cqw; }
.ch-sheet__search { padding: 2.4cqw 3.6cqw; border-radius: 99px; background: var(--paper); box-shadow: inset 0 0 0 1px var(--line); font-size: 3.8cqw; color: var(--ink-soft); }
.ch-contact { position: relative; display: flex; align-items: center; gap: 3cqw; padding: 2cqw 2.4cqw; margin: 0 -2.4cqw; border-radius: 3cqw; }
.ch-contact i, .ch-chip i, .ch-gr__biz i { flex: none; display: flex; align-items: center; justify-content: center; border-radius: 50%; background: var(--muted); color: var(--ink); font-family: var(--sl-font-display); font-style: normal; font-weight: 800; }
.ch-contact i { width: 9cqw; height: 9cqw; font-size: 4cqw; }
.ch-contact b { display: block; font-size: 4.2cqw; }
.ch-contact div span { display: block; font-size: 3.4cqw; color: var(--ink-soft); }
.ch-revs, .ch-sheet, .ch-gr, .ch-inbox { line-height: 1.3; }   /* app UI, not the page body measure */
[data-scene="reviews"] .ch-saved { line-height: 1.3; text-align: center; }
.ch-sheet__to { display: flex; align-items: center; gap: 2.6cqw; }
.ch-chip { display: flex; align-items: center; gap: 1.6cqw; padding: 1cqw 3cqw 1cqw 1cqw; border-radius: 99px; background: var(--paper-2); font-size: 3.8cqw; font-weight: 600; }
.ch-chip i { width: 6cqw; height: 6cqw; font-size: 2.8cqw; }
.ch-sheet__msg { padding: 3cqw 3.4cqw; border-radius: 3cqw; background: var(--paper); box-shadow: inset 0 0 0 1px var(--line); font-size: 3.7cqw; line-height: 1.4; }
.ch-sheet__msg u, .ch-link { display: block; margin-top: 1.2cqw; font-weight: 600; }
.ch-sheet__via { display: flex; gap: 4cqw; font-size: 3.8cqw; }
.ch-check { display: flex; align-items: center; gap: 1.6cqw; color: var(--ink-soft); }
.ch-check i, .ch-check svg { width: 4.4cqw; height: 4.4cqw; border-radius: 1cqw; }
.ch-check i { box-shadow: inset 0 0 0 1.5px var(--muted); }
.ch-check.is-on { color: var(--ink); font-weight: 600; }
.ch-check.is-on svg { padding: 0.5cqw; background: var(--ink); color: var(--light); }
.ch-sheet__send { margin-top: auto; margin-bottom: 7cqw; }

/* the customer's side: the text with the link, then the review box (a plain sheet, "Google" in words, no logo) */
.ch-bubble--biz { align-self: flex-start; background: var(--ink); color: var(--light); border-bottom-left-radius: 1.2cqw; }
.ch-link { position: relative; text-decoration: underline; text-underline-offset: 0.6cqw; }
.ch-gr { z-index: 3; height: 84%; gap: 3cqw; padding: 2.4cqw 5.4cqw 0; }
.ch-gr__src { margin-top: 1.4cqw; font-size: 3.6cqw; font-weight: 700; color: var(--ink-soft); }
.ch-gr__biz { display: flex; align-items: center; gap: 3cqw; }
.ch-gr__biz i { width: 10cqw; height: 10cqw; border-radius: 2.6cqw; background: var(--ink); color: var(--light); font-size: 3.8cqw; }
.ch-gr__biz b { display: block; font-size: 4.6cqw; }
.ch-gr__biz span { display: block; font-size: 3.4cqw; color: var(--ink-soft); }
.ch-gr__stars { display: flex; justify-content: center; gap: 2.4cqw; margin-top: 2cqw; }
.ch-star { position: relative; width: 11cqw; height: 11cqw; }
.ch-star svg { position: absolute; inset: 0; width: 100%; height: 100%; fill: none; stroke: var(--muted); stroke-width: 1.6; stroke-linejoin: round; }
.ch-star i { position: absolute; inset: 0; }
.ch-star i svg { fill: var(--tangerine); stroke: var(--tangerine); }
.ch-gr__eg { align-self: center; padding: 0.8cqw 2.6cqw; border-radius: 99px; box-shadow: inset 0 0 0 1px var(--line); font-size: 3cqw; font-weight: 700; letter-spacing: 0.05em; text-transform: uppercase; color: var(--ink-soft); }
.ch-gr__box { position: relative; display: grid; min-height: 28cqw; padding: 3cqw 3.4cqw; border-radius: 3cqw; box-shadow: inset 0 0 0 1px var(--muted); font-size: 4cqw; line-height: 1.4; }
.ch-gr__box > span { grid-area: 1 / 1; }
.ch-gr__ph { color: var(--ink-soft); }
.ch-gr__post { align-self: flex-end; padding: 2.6cqw 7cqw; }

/* Logo Refresh (Yvad 2026-09-23, round 2: Lawns By Rainey). Centred on the phone, bigger label and name, his full
   rectangular logos. The card lifts, flips once in 3D (old logo on the front, new on the back) and settles: picked on
   https://claude.ai/artifact/MP3D4SPXEHwcLJrF2FFQ97 (C's lift + A's flip). Perspective lives on the lift box, 3D on the
   card; fades go on the lift box, never the card (opacity on a preserve-3d element flattens it). The client's work
   keeps its real colours: the After face is his header green, as on his live site. */
.ch-lr { position: absolute; inset: 0; z-index: 4; display: flex; flex-direction: column; align-items: center; justify-content: center; padding: 0 6cqw 8cqw; background: var(--paper); line-height: 1.2; }
.ch-lr__eyebrow { font-size: 4.6cqw; font-weight: 700; letter-spacing: 0.07em; text-transform: uppercase; color: var(--ink-soft); }
.ch-lr__name { margin: 1.6cqw 0 13cqw; font-family: var(--sl-font-display); font-size: 11.5cqw; font-weight: 800; letter-spacing: -0.01em; }
.ch-lr__3d { position: relative; width: 88cqw; aspect-ratio: 720 / 451; perspective: 160cqw; }
.ch-lr__shadow { position: absolute; left: 8%; right: 8%; bottom: -6%; height: 10%; border-radius: 50%; background: radial-gradient(closest-side, rgba(58, 15, 34, 0.32), rgba(58, 15, 34, 0)); }
.ch-lr__card { position: absolute; inset: 0; transform-style: preserve-3d; }
.ch-lr__face { position: absolute; inset: 0; overflow: hidden; border-radius: 2cqw; backface-visibility: hidden; -webkit-backface-visibility: hidden; box-shadow: 0 1px 2px rgba(58, 15, 34, 0.1), 0 6px 16px rgba(58, 15, 34, 0.12); }
.ch-lr__face--before { background: #FFFDF6; }
.ch-lr__face--before img { display: block; width: 100%; height: 100%; object-fit: cover; }
.ch-lr__face--after { display: flex; align-items: center; justify-content: center; background: #1B2E1F; transform: rotateY(180deg); }   /* Rainey's header green */
.ch-lr__face--after img { width: 64%; height: auto; }
.ch-scene:not(.is-live) .ch-lr__card { transform: rotateY(180deg); }   /* finished frame: the new logo */
.ch-lr__tags { display: grid; margin-top: 7cqw; }
.ch-lr__tags > span { grid-area: 1 / 1; justify-self: center; padding: 1.6cqw 5cqw; border-radius: 99px; box-shadow: inset 0 0 0 1px var(--line); font-size: 4.2cqw; font-weight: 700; letter-spacing: 0.06em; text-transform: uppercase; color: var(--ink-soft); }
.ch-lr__tags > span[data-s="tagAfter"] { background: var(--ink); color: var(--light); box-shadow: none; }
/* his live site, and the browser's tab view */
.ch-web { position: absolute; inset: 0; z-index: 3; display: flex; flex-direction: column; gap: 2.4cqw; padding-top: 13%; background: #151E1E; line-height: 1.3; }
.ch-web .ch-site__url { background: var(--paper-2); }
.ch-web__shot { position: relative; }
.ch-web__shot::after { content: ""; position: absolute; left: 0; right: 0; bottom: 0; height: 22%; background: linear-gradient(rgba(21, 30, 30, 0), #151E1E); }   /* the capture stops above his call button (no phone number); fade it into the site colour */
.ch-web__shot img { display: block; width: 100%; height: auto; }
.ch-ring { position: absolute; left: 3%; top: 1%; width: 27%; height: 11%; border-radius: 1.2cqw; box-shadow: 0 0 0 0.35cqw var(--tangerine); opacity: 0; }   /* thin: it is seen zoomed in */
.ch-ring--round { left: -1.6cqw; top: -1.6cqw; width: calc(100% + 3.2cqw); height: calc(100% + 3.2cqw); border-radius: 50%; box-shadow: 0 0 0 0.3cqw var(--tangerine); }
.ch-cap { position: absolute; z-index: 5; left: 50%; bottom: 12%; padding: 2.4cqw 5cqw; border-radius: 99px; background: var(--ink); color: var(--light); font-size: 4.4cqw; font-weight: 600; white-space: nowrap; transform: translateX(-50%); }
.ch-tabs { position: absolute; inset: 0; z-index: 2; padding: 13% 5cqw 0; background: var(--ink); color: var(--light); line-height: 1.3; }
.ch-tabs__title { display: block; margin-bottom: 4cqw; text-align: center; font-size: 4.4cqw; }
.ch-tabs__grid { display: grid; grid-template-columns: 1fr 1fr; gap: 3.6cqw; }
.ch-tab { overflow: hidden; border-radius: 3.6cqw; background: var(--paper); color: var(--ink); }
.ch-tab__head { display: flex; align-items: center; gap: 1.8cqw; padding: 2cqw 2.4cqw; }
.ch-tab__fav { position: relative; flex: none; width: 5.6cqw; height: 5.6cqw; border-radius: 1.2cqw; background: var(--paper-2); }
.ch-tab__fav img { display: block; width: 100%; height: 100%; border-radius: 1.2cqw; }
.ch-tab__t { overflow: hidden; white-space: nowrap; text-overflow: ellipsis; font-size: 3.1cqw; font-weight: 600; }
.ch-tab__shot { display: block; width: 100%; aspect-ratio: 3 / 4.4; object-fit: cover; object-position: top; background: var(--paper-2); }
.ch-tabs .ch-cap { background: var(--light); color: var(--ink); }
.ch-tab--blank .ch-tab__t { color: var(--ink-soft); font-weight: 400; }
/* Website (Yvad 2026-09-24, AZ Home Remodeling): a laptop and the phone on one stage (board pick A, overlap).
   The scene fills the square panel (container units = % of the panel). The laptop is new but built from the phone's
   body: ink gradient, edge light, stacked edge, soft shadows, front-facing. The phone device CSS is the approved one;
   here it is sized by its holder, which GSAP moves forward (the only scene where a device moves: Yvad asked for it).
   The laptop's blur is a backdrop-filter layer whose opacity fades (transform/opacity only). */
.ch-scene--duo { width: 100%; height: 100%; aspect-ratio: auto; container-type: inline-size; }
.ch-scene--duo::after { display: none; }
.ch-pg { display: block; width: 100%; height: auto; }
.ch-lap { position: absolute; z-index: 1; left: 4cqw; top: 14cqw; width: 80cqw; }   /* own layer: its blur stays behind the phone */
.ch-lap__lid { position: relative; padding: 2.2%; border-radius: 3.4% / 5.4%; background: linear-gradient(140deg, var(--berry-mid) 0%, var(--ink) 38%, var(--ink) 100%);
  box-shadow: inset 0 0 0 1.5px rgba(255, 243, 228, 0.22), inset 3px 3px 4px rgba(255, 243, 228, 0.12), 1px 1px 0 var(--berry-mid), 2px 2px 0 var(--ink), 0 16px 30px rgba(58, 15, 34, 0.22), 0 30px 60px rgba(58, 15, 34, 0.16); }
.ch-lap__screen { position: relative; aspect-ratio: 16 / 10; overflow: hidden; border-radius: 1.2%; background: #F4F1EA; }
.ch-lap__screen::after { content: ""; position: absolute; z-index: 5; inset: 0; pointer-events: none; background: linear-gradient(118deg, rgba(255, 255, 255, 0.22) 0%, rgba(255, 255, 255, 0.05) 26%, rgba(255, 255, 255, 0) 42%); }   /* glass shine */
.ch-lap__chrome { position: relative; z-index: 3; display: flex; align-items: center; gap: 1.4%; height: 7%; padding: 0 2%; background: var(--paper-2); }
.ch-lap__chrome i { width: 1.2%; aspect-ratio: 1; border-radius: 50%; background: var(--muted); }
.ch-lap__chrome b { margin: 0 auto; padding: 0.2% 4%; border-radius: 99px; background: var(--paper); font-family: var(--sl-font-body); font-size: 1.45cqw; font-weight: 600; color: var(--ink-soft); }
.ch-lap__view { position: absolute; left: 0; right: 0; top: 7%; bottom: 0; overflow: hidden; }
.ch-lap__nav { position: absolute; z-index: 2; top: 0; left: 0; width: 100%; height: auto; }
.ch-lap__base { position: relative; height: 1.8cqw; margin: 0 -4%; border-radius: 0.4cqw 0.4cqw 6% 6% / 0.4cqw 0.4cqw 100% 100%; background: linear-gradient(180deg, var(--berry-mid), var(--ink)); box-shadow: 0 10px 18px rgba(58, 15, 34, 0.22); }
.ch-lap__base::before { content: ""; position: absolute; left: 42%; right: 42%; top: 0; height: 40%; border-radius: 0 0 8px 8px; background: rgba(0, 0, 0, 0.25); }
.ch-lap__blur { position: absolute; inset: -1.5cqw -6% -4.5cqw; z-index: 6; -webkit-backdrop-filter: blur(1cqw); backdrop-filter: blur(1cqw); background: rgba(251, 235, 214, 0.55); border-radius: 3cqw; opacity: 0; }   /* covers the lid, the base and its shadow; the tint fades the laptop back (Yvad round 2) */
.ch-duo__ph { position: absolute; z-index: 3; right: 5cqw; bottom: 6cqw; height: 56cqw; aspect-ratio: 9 / 19; }
.ch-duo__ph::after { content: ""; position: absolute; z-index: 0; left: 4%; right: 4%; bottom: -3.5%; height: 5%; border-radius: 50%; background: radial-gradient(closest-side, rgba(58, 15, 34, 0.38), rgba(58, 15, 34, 0)); filter: blur(4px); }
.ch-phone__screen--dark { background: #141414; }   /* the client site's own header black */
.ch-phone__screen--dark .ch-status { background: #141414; }
.ch-duo__view { position: absolute; left: 0; right: 0; top: 8.5%; bottom: 0; overflow: hidden; font-family: var(--sl-font-body); }
.ch-duo__nav { position: absolute; z-index: 2; top: 0; left: 0; width: 100%; height: auto; }
.ch-duo__bar { position: absolute; z-index: 2; bottom: 0; left: 0; width: 100%; height: auto; }
/* the bar is 16.7cqw tall (130/780 of the width); rings sit on it, one per button or all three */
.ch-duo__ring { position: absolute; z-index: 4; left: 1cqw; bottom: 0.8cqw; width: 31.3cqw; height: 15.1cqw; border-radius: 2.4cqw; box-shadow: 0 0 0 0.9cqw var(--tangerine); opacity: 0; }
.ch-duo__ring--2 { left: 34.3cqw; }
.ch-duo__ring--3 { left: 67.7cqw; }
.ch-duo__ring--all { width: 98cqw; }
.ch-duo__tap { left: 16.7cqw; top: auto; bottom: 8.3cqw; margin: 0 0 -6cqw -6cqw; }
.ch-duo__cap { z-index: 5; bottom: 22cqw; font-size: 4.6cqw; }
.ch-duo__sheet { position: absolute; z-index: 6; left: 3%; right: 3%; bottom: 3%; padding: 5cqw; border-radius: 6cqw; background: var(--light); color: var(--ink); text-align: center; line-height: 1.3; opacity: 0; }
.ch-duo__sheet small { display: block; font-size: 4cqw; color: var(--ink-soft); }
.ch-duo__sheet b { display: block; margin: 1.4cqw 0 4cqw; font-size: 6.2cqw; }
.ch-duo__sheet span { display: flex; align-items: center; justify-content: center; gap: 2cqw; padding: 3.4cqw; border-radius: 99px; background: var(--ink); color: var(--light); font-size: 5cqw; font-weight: 700; }
.ch-duo__sheet span svg { width: 4.6cqw; height: 4.6cqw; }
.ch-duo__sheet em { display: block; margin-top: 3cqw; font-style: normal; font-size: 4.6cqw; color: var(--ink-soft); }
.ch-duo__chip { position: absolute; z-index: 6; left: 6%; right: 6%; top: 34%; display: flex; gap: 2.6cqw; align-items: center; justify-content: center; padding: 3.4cqw 4cqw; border-radius: 99px; background: var(--ink); color: var(--light); font-size: 4.4cqw; font-weight: 600; opacity: 0; }
.ch-duo__chip svg { width: 1.3em; height: 1.3em; flex: none; color: var(--tangerine); }

/* Site duo (Yvad 2026-09-28, the case study website standard): the same laptop and phone as the website scene, soft
   berry so they read on a dark band, no zoom and no blur. Both screens scroll in sync, stopping on each section, down to
   the footer and back up (site.js "Site duo"). Pages are stacked image slices (.ch-pg holds them) so a long site stays
   under WebP's size limit. A before / after pair lives in two .ch-set layers; the section's data-show picks one. */
.ch-scene--site { position: relative; height: auto; aspect-ratio: 100 / 67; }
.ch-scene--site .ch-lap { left: 0; top: 0; width: 82cqw; }
.ch-scene--site .ch-duo__ph { right: 0; bottom: 2cqw; height: 50cqw; }
.ch-scene--site .ch-lap__lid, .ch-scene--site .ch-phone {
  background: var(--play-berry);   /* one flat soft berry, no light corner (Yvad 2026-09-28) */
  box-shadow: inset 0 0 0 1.5px rgba(255, 255, 255, 0.28),
    1px 1px 0 var(--muted), 2px 2px 0 var(--muted), 3px 3px 0 var(--ink-soft), 0 18px 34px rgba(0, 0, 0, 0.3), 0 40px 80px rgba(0, 0, 0, 0.26); }
.ch-scene--site .ch-lap__lid { box-shadow: inset 0 0 0 1.5px rgba(255, 255, 255, 0.28), 1px 1px 0 var(--muted), 2px 2px 0 var(--ink-soft), 0 18px 34px rgba(0, 0, 0, 0.3), 0 34px 70px rgba(0, 0, 0, 0.24); }
.ch-scene--site .ch-lap__base { background: var(--play-berry); box-shadow: 0 12px 22px rgba(0, 0, 0, 0.32); }
.ch-scene--site .ch-phone::before { background: var(--muted); }
.ch-scene--site .ch-duo__ph::after { background: radial-gradient(closest-side, rgba(0, 0, 0, 0.45), rgba(0, 0, 0, 0)); }
.ch-scene--site .ch-pg img { display: block; width: 100%; height: auto; }
.ch-scene--site .ch-phone__screen { background: var(--ds-site-status, #141414); }
.ch-scene--site .ch-status { background: var(--ds-site-status, #141414); }
.ch-scene--site .ch-status--dark { color: var(--ink); }
.ch-scene--site .ch-lap__screen::after, .ch-scene--site .ch-phone__screen::after { display: none; }   /* no glass shine: no light top-left corner on the devices */
.sl-sss:not([data-show="before"]) .ch-set[data-set="before"], .sl-sss[data-show="before"] .ch-set[data-set="after"] { display: none; }
.ch-set { position: absolute; inset: 0; }
.ch-duo__chip--summary { top: 30%; opacity: 1; }   /* part of the finished frame */

/* Show Up Local (Yvad 2026-09-24): PowerHaus Fitness's real Google Business Profile, looked up by name (a "near me"
   search ending on the card would claim a map result the business doesn't have). Photo-first layout, picked on
   https://claude.ai/artifact/Qjy1bA4229T1ui4T1jBx1r (B); client switched to PowerHaus so Lawns By Rainey stays for Real
   Shoot. Her real photos, category, hours, towns, services and site; "Google" in words, no logo; no rating, review
   count, list or position. Research + sources: brand_assets/google-profile-research.md. Her site keeps its real
   colour (#122F39, PowerHaus navy). */
.ch-lp { position: absolute; inset: 0; line-height: 1.3; }
.ch-lp__search { position: absolute; inset: 0; z-index: 5; display: flex; flex-direction: column; align-items: center; padding: 42% 6cqw 0; background: var(--paper); }
.ch-lp__word { margin-bottom: 6cqw; font-size: 9cqw; font-weight: 700; letter-spacing: -0.02em; }
.ch-lp__pill { position: relative; display: flex; align-items: center; gap: 2.6cqw; width: 100%; padding: 3.2cqw 3.2cqw 3.2cqw 4.4cqw; border-radius: 99px; background: var(--paper-2); box-shadow: inset 0 0 0 1px var(--line), 0 2px 8px rgba(58, 15, 34, 0.08); font-size: 4.4cqw; }
.ch-lp__pill > svg { flex: none; width: 4.6cqw; height: 4.6cqw; color: var(--ink-soft); }
.ch-lp__q { flex: 1; min-height: 1.3em; white-space: nowrap; }
.ch-lp__go { position: relative; flex: none; width: 9cqw; height: 9cqw; display: flex; align-items: center; justify-content: center; border-radius: 50%; background: var(--ink); color: var(--light); }
.ch-lp__go svg { width: 4.4cqw; height: 4.4cqw; }
.ch-lp__hint { margin-top: 5cqw; font-size: 3.6cqw; color: var(--ink-soft); }
.ch-lp__res { position: absolute; inset: 0; z-index: 2; overflow: hidden; background: var(--paper); }
.ch-lp__top { position: absolute; left: 5cqw; right: 5cqw; top: 13%; }
.ch-lp__top .ch-lp__pill { padding: 2.4cqw 3.6cqw; font-size: 3.9cqw; }
.ch-lp__prof { position: absolute; left: 0; right: 0; top: 21%; display: flex; flex-direction: column; gap: 3cqw; padding: 0 5cqw; }
.ch-lp__photos { display: grid; grid-template-columns: 2fr 1fr; grid-template-rows: 1fr 1fr; gap: 1.2cqw; height: 40cqw; }
.ch-lp__ph { position: relative; overflow: hidden; border-radius: 2.2cqw; background: rgba(58, 15, 34, 0.07); }
.ch-lp__ph:first-child { grid-row: 1 / 3; }
.ch-lp__ph:first-child img { object-position: 50% 22%; }
.ch-lp__ph img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
.ch-lp__ph em { position: absolute; inset: 0; display: flex; align-items: center; justify-content: center; font-style: normal; font-size: 3.3cqw; color: var(--ink-soft); }
.ch-lp__head { display: flex; align-items: center; gap: 3cqw; }
.ch-lp__logo { flex: none; width: 11cqw; height: 11cqw; overflow: hidden; border-radius: 2.6cqw; box-shadow: 0 0 0 1px var(--line); }
.ch-lp__logo img { display: block; width: 100%; height: 100%; }
.ch-lp__name { display: block; font-size: 5.6cqw; font-weight: 700; letter-spacing: -0.01em; }
.ch-lp__cat { display: block; font-size: 3.7cqw; color: var(--ink-soft); }
.ch-lp__acts { display: flex; align-items: center; gap: 2.2cqw; }
.ch-lp__act { position: relative; display: flex; align-items: center; gap: 1.4cqw; padding: 1.9cqw 3.4cqw; border-radius: 99px; box-shadow: inset 0 0 0 1px var(--line); font-size: 3.7cqw; font-weight: 600; }
.ch-lp__act svg { width: 3.8cqw; height: 3.8cqw; }
.ch-lp__act--web { background: var(--ink); color: var(--light); box-shadow: none; }
.ch-lp__act--add { color: var(--ink-soft); font-weight: 500; box-shadow: inset 0 0 0 1px var(--muted); }
.ch-lp__slot { display: grid; }
.ch-lp__slot > * { grid-area: 1 / 1; }
.ch-lp__rows { display: flex; flex-direction: column; }
.ch-lp__row { display: grid; grid-template-columns: 5.6cqw 1fr 5cqw; align-items: center; gap: 2.8cqw; padding: 2.4cqw 0; border-top: 1px solid var(--line); font-size: 3.9cqw; }
.ch-lp__row > svg { width: 4.6cqw; height: 4.6cqw; color: var(--ink-soft); }
.ch-lp__val { display: grid; min-width: 0; }
.ch-lp__val > span { grid-area: 1 / 1; overflow: hidden; white-space: nowrap; text-overflow: ellipsis; }
.ch-lp__add { color: var(--ink-soft); }
.ch-lp__val b { font-weight: 700; }
.ch-lp__chips { display: flex; gap: 1.4cqw; overflow: hidden; }
.ch-lp__chips i { padding: 0.8cqw 2.4cqw; border-radius: 99px; background: var(--paper-2); box-shadow: inset 0 0 0 1px var(--line); font-size: 3.4cqw; font-style: normal; white-space: nowrap; }
.ch-lp__ok { width: 5cqw; height: 5cqw; display: flex; align-items: center; justify-content: center; border-radius: 50%; background: var(--play-mint); color: var(--ink); }
.ch-lp__ok svg { width: 3.2cqw; height: 3.2cqw; }
.ch-lp__ph .ch-lp__ok { position: absolute; top: 1.4cqw; right: 1.4cqw; }
.ch-lp__note { position: absolute; z-index: 6; left: 8%; right: 8%; top: 44%; padding: 3.6cqw 5cqw; border-radius: 5cqw; background: var(--ink); color: var(--light); font-size: 4.4cqw; font-weight: 600; text-align: center; box-shadow: 0 8px 20px rgba(58, 15, 34, 0.3); }
.ch-lp__web { position: absolute; inset: 0; z-index: 4; display: flex; flex-direction: column; gap: 2.4cqw; padding-top: 13%; background: #122F39; }   /* her site's colour */
.ch-lp__web .ch-site__url { background: var(--paper-2); }
.ch-lp__shot { position: relative; }
.ch-lp__shot img { display: block; width: 100%; height: auto; }
.ch-lp__shot::after { content: ""; position: absolute; left: 0; right: 0; bottom: 0; height: 22%; background: linear-gradient(rgba(18, 47, 57, 0), #122F39); }
.ch-lp__ring { position: absolute; left: 3.5%; top: 1.4%; width: 60%; height: 7.8%; border-radius: 1.4cqw; box-shadow: 0 0 0 0.45cqw var(--tangerine); opacity: 0; }
[data-scene="local"] .ch-saved { bottom: 7%; gap: 2cqw; padding: 3.4cqw 3cqw; font-size: 4cqw; white-space: nowrap; box-shadow: 0 8px 20px rgba(58, 15, 34, 0.28); }
[data-scene="local"] .ch-saved svg { flex: none; color: var(--tangerine); }

/* Real Shoot (Yvad 2026-09-24, Lawns By Rainey): "Behind the lens", picked on
   https://claude.ai/artifact/9yVRmg3HnqazT1cW4fscRL (A, round 2). Yvad's real photo of the shoot on his job site; a lens
   frames the setup (the skid steer); shutter flash to the real photo he took in that moment; then Rainey's live
   homepage with the hero video Yvad shot (captured frame by frame at 390px @2x, phone number masked). Round 2: both
   photos shown WHOLE, fitted to the screen width on a blurred copy of themselves (never cropped). The shot doesn't drop
   into his site: it isn't on it yet. His site keeps its real colour (#1B2E1F, his header green). */
.ch-rs { position: absolute; inset: 0; overflow: hidden; background: var(--ink); line-height: 1.3; }
.ch-rs__fitbox { position: absolute; inset: 0; display: flex; align-items: center; overflow: hidden; }
.ch-rs__blur { position: absolute; inset: -8%; width: 116%; max-width: none; height: 116%; object-fit: cover; filter: blur(3cqw) brightness(0.62) saturate(1.1); }
.ch-rs__fit { position: relative; width: 100%; }
.ch-rs__fit > img { display: block; width: 100%; height: auto; }
.ch-rs__lens { position: absolute; left: 47%; top: 40%; width: 34%; height: 38%; pointer-events: none; }
.ch-rs__lens i { position: absolute; width: 5cqw; height: 5cqw; border: 0 solid var(--light); filter: drop-shadow(0 0 1px rgba(12, 2, 8, 0.5)); }
.ch-rs__lens i:nth-child(1) { left: 0; top: 0; border-width: 0.7cqw 0 0 0.7cqw; }
.ch-rs__lens i:nth-child(2) { right: 0; top: 0; border-width: 0.7cqw 0.7cqw 0 0; }
.ch-rs__lens i:nth-child(3) { left: 0; bottom: 0; border-width: 0 0 0.7cqw 0.7cqw; }
.ch-rs__lens i:nth-child(4) { right: 0; bottom: 0; border-width: 0 0.7cqw 0.7cqw 0; }
.ch-rs__lens b { position: absolute; left: 50%; top: 50%; width: 2.2cqw; height: 2.2cqw; margin: -1.1cqw 0 0 -1.1cqw; border-radius: 50%; box-shadow: 0 0 0 0.5cqw var(--light); }
.ch-rs__flash { position: absolute; inset: 0; z-index: 7; background: var(--light); opacity: 0; pointer-events: none; }
.ch-rs__lab { position: absolute; z-index: 6; left: 50%; top: 12%; padding: 1.8cqw 4.4cqw; border-radius: 99px; background: rgba(58, 15, 34, 0.82); color: var(--light); font-size: 4cqw; font-weight: 600; white-space: nowrap; transform: translateX(-50%); }
.ch-rs__cap { position: absolute; z-index: 6; left: 50%; bottom: 9%; padding: 2.4cqw 5cqw; border-radius: 99px; background: var(--ink); color: var(--light); font-size: 4.4cqw; font-weight: 600; white-space: nowrap; transform: translateX(-50%); box-shadow: 0 6px 16px rgba(12, 2, 8, 0.3); }
.ch-rs__web { position: absolute; inset: 0; z-index: 8; display: flex; flex-direction: column; gap: 2.4cqw; padding-top: 13%; background: #1B2E1F; }   /* his header green */
.ch-rs__web .ch-site__url { background: var(--paper-2); }
.ch-rs__vid { position: relative; }
.ch-rs__vid img, .ch-rs__vid video { display: block; width: 100%; height: auto; aspect-ratio: 600 / 942; object-fit: cover; }
.ch-rs__vid video { position: absolute; inset: 0; }
.ch-rs__web .ch-rs__cap { bottom: 12%; }
[data-scene="shoot"] .ch-saved { z-index: 9; bottom: 6%; gap: 2cqw; padding: 3.4cqw 3cqw; font-size: 4.2cqw; white-space: nowrap; box-shadow: 0 8px 20px rgba(12, 2, 8, 0.3); }
[data-scene="shoot"] .ch-saved svg { flex: none; color: var(--tangerine); }
[data-scene="shoot"] .ch-status { z-index: 9; }   /* the clock stays above his site layer */

/* recipe: why-choose-us/2026-09_creohaus_autoplay-progress-tabs (Mode F 2026-09-24: list, CTA, demo media, per-tab duration, stop on click, chips, hashes) */
/* ==== RECIPE CSS START: why-choose-us/2026-09_creohaus_autoplay-progress-tabs ==== */
.sl-apt {
  --sl-apt-bar-h: 3px;
  --sl-apt-media-min: 440px;
  background: var(--sl-bg);
  color: var(--sl-text);
}
.sl-apt__head { max-width: 720px; margin-bottom: 48px; }
.sl-apt__head h2 { margin-top: 14px; }
.sl-apt__sub { margin-top: 14px; color: var(--sl-muted); }

/* The card: tabs above the panel on phones and tablets, tabs beside it from 1024px. */
.sl-apt__card {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  border: 1px solid var(--sl-border);
  border-radius: var(--sl-radius);
  overflow: hidden;
  background: var(--sl-surface);
}
.sl-apt__tabs { display: flex; flex-direction: column; background: var(--sl-surface-2); border-bottom: 1px solid var(--sl-border); }
.sl-apt__tab {
  position: relative;
  display: flex;
  flex-direction: column;
  gap: 8px;
  width: 100%;
  padding: 20px 20px 22px;
  border: 0;
  border-bottom: 1px solid var(--sl-border);
  border-radius: 0;
  background: transparent;
  color: var(--sl-muted);
  font: inherit;
  text-align: left;
  cursor: pointer;
  transition: background-color 300ms var(--sl-ease), color 300ms var(--sl-ease);
}
.sl-apt__tab:last-child { border-bottom: 0; }
.sl-apt__tab:hover { color: var(--sl-text); }
.sl-apt__tab[aria-selected="true"] { background: var(--sl-surface); color: var(--sl-text); }
.sl-apt__tab:focus-visible { outline: 2px solid var(--sl-accent); outline-offset: -2px; }
.sl-apt__tab-top { display: flex; align-items: center; gap: 10px; }
.sl-apt__tab-top .material-symbols-outlined { font-size: 22px; }
.sl-apt__tab-title { font-size: 18px; font-weight: 600; line-height: 1.3; }
.sl-apt__tab-desc { font-size: 16px; line-height: 1.5; color: var(--sl-muted); }

/* The progress line: a track along the active tab's base, filled left to right while that tab shows.
   When it fills, the next tab takes over. Without JS (or with reduced motion) it simply shows full. */
.sl-apt__bar { position: absolute; left: 0; right: 0; bottom: 0; height: var(--sl-apt-bar-h); background: var(--sl-border); opacity: 0; transition: opacity 300ms var(--sl-ease); }
.sl-apt__tab[aria-selected="true"] .sl-apt__bar { opacity: 1; }
.sl-apt__bar-fill { display: block; height: 100%; background: var(--sl-accent); transform-origin: 0 50%; transform: scaleX(1); }
.sl-apt.is-armed .sl-apt__bar-fill { transform: scaleX(0); }
.sl-apt.is-armed .sl-apt__bar-fill.is-running { animation: sl-apt-fill var(--sl-apt-dur, 6000ms) linear forwards; }
.sl-apt.is-paused .sl-apt__bar-fill.is-running { animation-play-state: paused; }
@keyframes sl-apt-fill { from { transform: scaleX(0); } to { transform: scaleX(1); } }

/* Every panel shares one grid cell, so the card is always as tall as its longest panel:
   switching tabs never moves the page. */
.sl-apt__panels { display: grid; }
.sl-apt__panel {
  grid-area: 1 / 1;
  display: flex;
  flex-direction: column;
  visibility: hidden;
  opacity: 0;
  transition: opacity 300ms var(--sl-ease), visibility 0s linear 300ms;
}
.sl-apt__panel.is-active { visibility: visible; opacity: 1; transition: opacity 300ms var(--sl-ease), visibility 0s; }
.sl-apt__media { position: relative; aspect-ratio: var(--sl-apt-ratio, 4 / 3); overflow: hidden; background: var(--sl-surface-2); }
/* direct children only: a photo or video that IS the slot. Never deeper (a demo scene inside the slot keeps its own images). */
.sl-apt__media > img, .sl-apt__media > video { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
.sl-apt__copy { display: flex; flex-direction: column; gap: 14px; padding: 24px 20px 28px; }
.sl-apt__copy p { color: var(--sl-muted); }
/* Optional checklist + Learn More in the copy column (Mode F 2026-09-24). */
.sl-apt__list { display: flex; flex-direction: column; gap: 10px; margin: 4px 0 0; padding: 0; list-style: none; }
.sl-apt__list li { display: grid; grid-template-columns: 24px minmax(0, 1fr); gap: 10px; align-items: start; color: var(--sl-muted); }
.sl-apt__list .material-symbols-outlined { font-size: 22px; color: var(--sl-accent); line-height: 1.3; }
.sl-apt__list strong { color: var(--sl-text); font-weight: 600; }
.sl-apt__cta { margin-top: 8px; }
/* data-media="demo" on a media slot: a live demo (a coded animation) instead of a photo. It sits centred on the
   slot's ground at its own size; the slot keeps a square shape below 1024px and fills the panel height above. */
.sl-apt__media[data-media="demo"] { display: flex; align-items: center; justify-content: center; aspect-ratio: var(--sl-apt-demo-ratio, 1 / 1); }
.sl-apt__media[data-media="demo"] > * { position: relative; }
/* data-groups="labels": a small label opens each group of tabs in the list (from 1024px; phones keep plain chips).
   Its fill comes from --sl-apt-group-bg on the tab (default: the surface tone). Mode F 2026-09-24. */
.sl-apt__tab-group { display: none; }
@media (min-width: 1024px) {
  .sl-apt[data-groups="labels"] .sl-apt__tab-group { display: inline-flex; align-self: flex-start; margin: 0 0 6px; padding: 3px 8px; background: var(--sl-apt-group-bg, transparent); box-shadow: inset 0 0 0 1px var(--sl-apt-group-line, var(--sl-border)); color: var(--sl-apt-group-text, var(--sl-text)); font-family: var(--sl-font-display); font-size: 14px; font-weight: 800; letter-spacing: 0.05em; text-transform: uppercase; line-height: 1.2; }
  .sl-apt[data-groups="labels"] .sl-apt__tab:has(.sl-apt__tab-group):not(:first-child) { border-top: 2px solid var(--sl-border); }
}
/* Stopped (data-stop-on-click): the line shows full and stays put. */
.sl-apt.is-stopped .sl-apt__bar-fill, .sl-apt.is-stopped .sl-apt__bar-fill.is-running { animation: none; transform: scaleX(1); }
/* data-tabs-mobile="chips": below 1024px the tabs become one row of chips that swipes sideways (titles only). */
@media (max-width: 1023.98px) {
  .sl-apt[data-tabs-mobile="chips"] .sl-apt__tabs { flex-direction: row; gap: 8px; padding: 12px; overflow-x: auto; overscroll-behavior-x: contain; scroll-snap-type: x proximity; scrollbar-width: none; }
  .sl-apt[data-tabs-mobile="chips"] .sl-apt__tabs::-webkit-scrollbar { display: none; }
  .sl-apt[data-tabs-mobile="chips"] .sl-apt__tab { flex: none; width: auto; padding: 10px 16px 12px; border: 1px solid var(--sl-border); border-radius: var(--sl-apt-chip-radius, 999px); overflow: hidden; scroll-snap-align: start; white-space: nowrap; }
  .sl-apt[data-tabs-mobile="chips"] .sl-apt__tab:last-child { border-bottom: 1px solid var(--sl-border); }
  .sl-apt[data-tabs-mobile="chips"] .sl-apt__tab[aria-selected="true"] { border-color: var(--sl-text); }
  .sl-apt[data-tabs-mobile="chips"] .sl-apt__tab-desc { display: none; }
  .sl-apt[data-tabs-mobile="chips"] .sl-apt__tab-title { font-size: 16px; }
  .sl-apt[data-tabs-mobile="chips"] .sl-apt__bar { left: 16px; right: 16px; bottom: 5px; border-radius: 99px; overflow: hidden; }
}

/* ---- Mode F 2026-09-24 (b): index tabs, group gaps, a card of separate columns, a framed media column,
   and phones stepping through every tab by group. All opt-in; the optional parts below stay hidden without their knob. ---- */
.sl-apt__tab-num, .sl-apt__tab-go, .sl-apt__groups, .sl-apt__step { display: none; }
/* data-tabs-style="index" (from 1024px): a numbered index. Display-font uppercase titles, a number before each
   (span.sl-apt__tab-num), the group label as a full-width strip, the open tab solid in the band's text colour,
   and an arrow (span.sl-apt__tab-go) that slides in on hover and stays on the open tab. */
@media (min-width: 1024px) {
  .sl-apt[data-tabs-style="index"] .sl-apt__tab { justify-content: flex-start; gap: 6px; padding: 20px 28px 22px; }   /* top-aligned, so a group strip sits flush on the tab's top edge */
  .sl-apt[data-tabs-style="index"] .sl-apt__tab-top { width: 100%; }
  .sl-apt[data-tabs-style="index"] .sl-apt__tab-top > .material-symbols-outlined:not(.sl-apt__tab-go) { display: none; }
  .sl-apt[data-tabs-style="index"] .sl-apt__tab-num { display: inline-block; min-width: 30px; font-family: var(--sl-font-display); font-size: 16px; font-weight: 800; letter-spacing: 0.06em; color: var(--sl-muted); }
  .sl-apt[data-tabs-style="index"] .sl-apt__tab-title { font-family: var(--sl-font-display); font-size: var(--sl-apt-index-size, 24px); font-weight: 800; line-height: 1; letter-spacing: 0.01em; text-transform: uppercase; }
  .sl-apt[data-tabs-style="index"] .sl-apt__tab-desc { padding-left: 40px; }
  .sl-apt[data-tabs-style="index"] .sl-apt__tab-go { display: inline-block; margin-left: auto; font-size: 20px; opacity: 0; transform: translateX(-8px); transition: opacity 300ms var(--sl-ease), transform 300ms var(--sl-ease); }
  .sl-apt[data-tabs-style="index"] .sl-apt__tab:hover .sl-apt__tab-go, .sl-apt[data-tabs-style="index"] .sl-apt__tab[aria-selected="true"] .sl-apt__tab-go { opacity: 1; transform: none; }
  .sl-apt[data-tabs-style="index"] .sl-apt__tab:hover:not([aria-selected="true"]) { background: var(--sl-surface); color: var(--sl-text); }
  .sl-apt[data-tabs-style="index"] .sl-apt__tab[aria-selected="true"] { background: var(--sl-text); color: var(--sl-bg); }
  .sl-apt[data-tabs-style="index"] .sl-apt__tab[aria-selected="true"] .sl-apt__tab-desc,
  .sl-apt[data-tabs-style="index"] .sl-apt__tab[aria-selected="true"] .sl-apt__tab-num { color: color-mix(in srgb, var(--sl-bg) 74%, transparent); }
  .sl-apt[data-tabs-style="index"] .sl-apt__tab[aria-selected="true"] .sl-apt__bar { background: color-mix(in srgb, var(--sl-bg) 20%, transparent); }
  .sl-apt[data-tabs-style="index"][data-groups="labels"] .sl-apt__tab-group { align-self: stretch; margin: -20px -28px 12px; padding: 7px 28px; background: var(--sl-apt-group-bg, var(--sl-surface)); box-shadow: inset 0 -1px 0 var(--sl-apt-group-line, var(--sl-border)); color: var(--sl-apt-group-text, var(--sl-text)); }   /* a strip always has a fill, so it reads on the open (solid) tab too */
}
/* data-group-break="gap" (with data-groups="labels", from 1024px): a gap between groups in the tab list; the tabs
   inside one group stay joined. --sl-apt-group-gap. */
@media (min-width: 1024px) {
  .sl-apt[data-group-break="gap"] .sl-apt__tabs { background: transparent; border: 0; }
  .sl-apt[data-group-break="gap"] .sl-apt__tab { background: var(--sl-surface-2); border: 1px solid var(--sl-border); border-top-width: 0; }
  .sl-apt[data-group-break="gap"] .sl-apt__tab:first-child,
  .sl-apt[data-group-break="gap"][data-groups="labels"] .sl-apt__tab:has(.sl-apt__tab-group) { border-top: 1px solid var(--sl-border); }
  .sl-apt[data-group-break="gap"][data-groups="labels"] .sl-apt__tab:has(.sl-apt__tab-group):not(:first-child) { margin-top: var(--sl-apt-group-gap, 16px); }
}
/* data-card="columns": the card comes apart into separate boxes with a gap between them (--sl-apt-col-gap): the tab list,
   the media and the copy each stand on their own. */
.sl-apt[data-card="columns"] .sl-apt__card { gap: var(--sl-apt-col-gap, 16px); border: 0; border-radius: 0; background: transparent; overflow: visible; }
.sl-apt[data-card="columns"] .sl-apt__panel { gap: var(--sl-apt-col-gap, 16px); }
.sl-apt[data-card="columns"] .sl-apt__tabs,
.sl-apt[data-card="columns"] .sl-apt__media,
.sl-apt[data-card="columns"] .sl-apt__copy { border: 1px solid var(--sl-border); border-radius: var(--sl-radius); }
.sl-apt[data-card="columns"] .sl-apt__copy { background: var(--sl-surface); }
@media (min-width: 1024px) {
  .sl-apt[data-card="columns"][data-group-break="gap"] .sl-apt__tabs { border: 0; border-radius: 0; }
}
/* data-media-frame="keyline": the media column is a framed box: its own ground (--sl-apt-frame-bg), a small inner
   padding (--sl-apt-frame-pad) and a thin keyline rectangle (--sl-apt-frame-line). A photo sits inside the keyline;
   a demo fills the space inside it. An optional caption (span.sl-apt__media-cap) sits on the keyline's top edge. */
.sl-apt[data-media-frame="keyline"] .sl-apt__media { padding: var(--sl-apt-frame-pad, 14px); background: var(--sl-apt-frame-bg, var(--sl-surface-2)); }
.sl-apt[data-media-frame="keyline"] .sl-apt__media::after { content: ""; position: absolute; inset: var(--sl-apt-frame-pad, 14px); z-index: 2; border: 1px solid var(--sl-apt-frame-line, var(--sl-border)); pointer-events: none; }
.sl-apt[data-media-frame="keyline"] .sl-apt__media > img,
.sl-apt[data-media-frame="keyline"] .sl-apt__media > video { inset: var(--sl-apt-frame-pad, 14px); width: calc(100% - 2 * var(--sl-apt-frame-pad, 14px)); height: calc(100% - 2 * var(--sl-apt-frame-pad, 14px)); }
.sl-apt__media-cap { display: none; }
.sl-apt[data-media-frame="keyline"] .sl-apt__media-cap { position: absolute; z-index: 3; top: calc(var(--sl-apt-frame-pad, 14px) - 0.7em); left: calc(var(--sl-apt-frame-pad, 14px) + 14px); display: inline-flex; align-items: center; gap: 8px; padding: 0 8px; background: var(--sl-apt-frame-bg, var(--sl-surface-2)); color: var(--sl-text); font-family: var(--sl-font-display); font-size: 14px; font-weight: 800; letter-spacing: 0.08em; line-height: 1.4; text-transform: uppercase; }
/* Figure-plate extras (Mode F 2026-09-24 d). In a keyline frame, span.sl-apt__media-fig labels the bottom edge (e.g. "Fig. 02")
   and span.sl-apt__media-dot is a slow blinking dot inside the caption. div.sl-apt__copy-meta opens the copy column with a
   tag (--sl-apt-tag-bg / --sl-apt-tag-text, per panel) and a counter ("02 / 07"). data-copy="sheet" turns the copy column
   into a ruled sheet: the meta row over a rule in the text colour, the checklist on hairlines, top-aligned from 1024px. */
@keyframes sl-apt-blink { 0%, 100% { opacity: 1; } 50% { opacity: 0.25; } }
.sl-apt__media-fig { display: none; }
.sl-apt[data-media-frame="keyline"] .sl-apt__media > .sl-apt__media-fig { display: block; position: absolute; z-index: 3; right: calc(var(--sl-apt-frame-pad, 14px) + 14px); bottom: calc(var(--sl-apt-frame-pad, 14px) - 0.7em); padding: 0 8px; background: var(--sl-apt-frame-bg, var(--sl-surface-2)); color: var(--sl-muted); font-family: var(--sl-font-display); font-size: 14px; font-weight: 800; letter-spacing: 0.08em; line-height: 1.4; text-transform: uppercase; }
.sl-apt__media-dot { display: inline-block; width: 8px; height: 8px; background: var(--sl-text); animation: sl-apt-blink 1.6s ease-in-out infinite; }
.sl-apt__copy-meta { display: flex; align-items: center; justify-content: space-between; gap: 12px; }
.sl-apt__copy-tag { padding: 4px 10px; background: var(--sl-apt-tag-bg, var(--sl-surface-2)); color: var(--sl-apt-tag-text, var(--sl-text)); font-family: var(--sl-font-display); font-size: 15px; font-weight: 800; letter-spacing: 0.04em; line-height: 1.2; text-transform: uppercase; }
.sl-apt__copy-count { margin-left: auto; color: var(--sl-muted); font-family: var(--sl-font-display); font-size: 16px; font-weight: 800; letter-spacing: 0.06em; }
.sl-apt[data-copy="sheet"] .sl-apt__copy-meta { padding-bottom: 14px; border-bottom: 1px solid var(--sl-text); }
.sl-apt[data-copy="sheet"] .sl-apt__list { gap: 0; }
.sl-apt[data-copy="sheet"] .sl-apt__list li { padding: 12px 0; border-bottom: 1px solid var(--sl-border); }
@media (min-width: 1024px) {
  .sl-apt[data-copy="sheet"] .sl-apt__copy { justify-content: flex-start; padding: 32px 40px 40px; }
  .sl-apt[data-copy="sheet"] .sl-apt__cta { margin-top: 12px; }
}
@media (prefers-reduced-motion: reduce) { .sl-apt__media-dot { animation: none; } }
/* data-tabs-mobile="groups" (below 1024px): one row of group buttons (div.sl-apt__groups > button[data-sl-group],
   short words), then a stepper: previous arrow, the open tab (number + title + its progress line), next arrow.
   The arrows step through every tab and cross into the next group; the group row follows. Arrows are the button
   system's SQUARE role. */
@media (max-width: 1023.98px) {
  .sl-apt[data-tabs-mobile="groups"] .sl-apt__card { grid-template-columns: auto minmax(0, 1fr) auto; grid-template-areas: "groups groups groups" "prev tabs next" "panels panels panels"; }
  .sl-apt[data-tabs-mobile="groups"] .sl-apt__groups { grid-area: groups; display: grid; grid-auto-flow: column; grid-auto-columns: minmax(0, 1fr); gap: var(--sl-apt-group-gap-m, 6px); }
  .sl-apt[data-tabs-mobile="groups"] .sl-apt__group { min-height: 48px; padding: 8px 6px; border: 1px solid var(--sl-border); border-radius: var(--sl-radius); background: var(--sl-surface); color: var(--sl-text); font-family: var(--sl-font-display); font-size: 16px; font-weight: 800; letter-spacing: 0.04em; line-height: 1.1; text-transform: uppercase; cursor: pointer; transition: background-color 300ms var(--sl-ease), color 300ms var(--sl-ease); }
  .sl-apt[data-tabs-mobile="groups"] .sl-apt__group[aria-pressed="true"] { background: var(--sl-apt-group-bg, var(--sl-text)); border-color: var(--sl-apt-group-line, var(--sl-text)); color: var(--sl-apt-group-text, var(--sl-bg)); }
  .sl-apt[data-tabs-mobile="groups"] .sl-apt__group:focus-visible { outline: 2px solid var(--sl-accent); outline-offset: 2px; }
  .sl-apt[data-tabs-mobile="groups"] .sl-apt__group:active { transform: translateY(1px); }
  .sl-apt[data-tabs-mobile="groups"] .sl-apt__step { display: contents; }
  .sl-apt[data-tabs-mobile="groups"] [data-sl-prev] { grid-area: prev; align-self: center; }
  .sl-apt[data-tabs-mobile="groups"] [data-sl-next] { grid-area: next; align-self: center; }
  .sl-apt[data-tabs-mobile="groups"] .sl-apt__tabs { grid-area: tabs; align-self: stretch; border: 0; background: transparent; }
  .sl-apt[data-tabs-mobile="groups"] .sl-apt__tab { display: none; }
  .sl-apt[data-tabs-mobile="groups"] .sl-apt__tab[aria-selected="true"] { display: flex; justify-content: center; height: 100%; padding: 8px 12px 12px; background: transparent; }
  .sl-apt[data-tabs-mobile="groups"] .sl-apt__tab-top { gap: 8px; }
  .sl-apt[data-tabs-mobile="groups"] .sl-apt__tab-top > .material-symbols-outlined { display: none; }
  .sl-apt[data-tabs-mobile="groups"] .sl-apt__tab-num { display: inline; font-family: var(--sl-font-display); font-size: 16px; font-weight: 800; color: var(--sl-muted); }
  .sl-apt[data-tabs-mobile="groups"] .sl-apt__tab-title { font-family: var(--sl-font-display); font-size: 20px; font-weight: 800; line-height: 1.1; text-transform: uppercase; }
  .sl-apt[data-tabs-mobile="groups"] .sl-apt__tab-desc,
  .sl-apt[data-tabs-mobile="groups"] .sl-apt__tab-group { display: none; }
  .sl-apt[data-tabs-mobile="groups"] .sl-apt__bar { left: 12px; right: 12px; bottom: 4px; }
  .sl-apt[data-tabs-mobile="groups"] .sl-apt__panels { grid-area: panels; }
  .sl-apt[data-tabs-mobile="groups"]:not([data-card="columns"]) .sl-apt__groups { padding: 12px 12px 0; }
}

@media (min-width: 1024px) {
  .sl-apt__card { grid-template-columns: minmax(0, 1fr) minmax(0, 2fr); }
  .sl-apt__tabs { border-bottom: 0; border-right: 1px solid var(--sl-border); }
  .sl-apt__tab { flex: 1 1 0; justify-content: center; padding: 28px 28px 30px; }
  /* Split panel: photo left, copy right. The photo fills the panel's full height. */
  .sl-apt__panel { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); min-height: var(--sl-apt-media-min); }
  .sl-apt__media { aspect-ratio: auto; }
  .sl-apt__copy { justify-content: center; padding: 48px 44px; }
  .sl-apt__media[data-media="demo"] { aspect-ratio: auto; }
}
@media (prefers-reduced-motion: reduce) {
  .sl-apt__tab, .sl-apt__bar, .sl-apt__panel { transition: none; }
}
/* ==== RECIPE CSS END ==== */

/* Services hub (CreoHaus 2026-09-24): the seven demo scenes inside the tabs. Each demo sits on a square light stage
   (the scene standard: a light panel, the brand's dark colour lives in the device), as big as the slot allows. */
.sl-apt__media[data-media="demo"] { container-type: size; background: var(--sl-surface-2); }
.ch-hub__stage { width: min(100cqw, 100cqh); aspect-ratio: 1 / 1; display: flex; align-items: center; justify-content: center; background: var(--paper-2); box-shadow: inset 0 0 0 1px var(--line); }
/* The checks take their outcome tone as a square, like the old rows. */
.sl-apt__list .ch-hub__check { display: flex; align-items: center; justify-content: center; width: 24px; height: 24px; margin-top: 2px; background: var(--ch-hub-tone); color: var(--ink); font-size: 18px; line-height: 1; font-variation-settings: "wght" 600; }
/* Hub look = the recipe's "Figure plate index" preset (Yvad picked it 2026-09-24 on https://claude.ai/artifact/4hKt9A3Mc32BAvKBJa8cVD):
   everything structural comes from the recipe knobs; below is only the CreoHaus skin. */
.sl-apt[data-card="columns"] { --sl-apt-col-gap: 16px; --sl-apt-group-gap: 18px; --sl-apt-frame-pad: 14px; --sl-apt-frame-bg: var(--paper-2); --sl-apt-frame-line: rgba(58, 15, 34, 0.3); }
.sl-apt[data-tabs-style="index"] .sl-apt__tab { background: var(--paper); }
.sl-apt[data-card="columns"] .sl-apt__copy { background: var(--paper); }   /* three surfaces: Paper list, Paper 2 frame, Paper sheet */
@media (min-width: 1024px) {   /* a little tighter than the recipe default, so the whole card fits under the sticky nav on a 900px-tall screen */
  .sl-apt[data-tabs-style="index"] .sl-apt__tab { padding: 16px 28px 18px; }
  .sl-apt[data-tabs-style="index"][data-groups="labels"] .sl-apt__tab-group { margin: -16px -28px 10px; }
}
/* The demo frame carries the ground, so the stage goes clear; from 1024px a one-phone scene gets the whole frame (it scales
   with its stage), the laptop + phone scene keeps its square. */
.sl-apt[data-media-frame="keyline"] .ch-hub__stage { background: none; box-shadow: none; }
@media (min-width: 1024px) {
  .sl-apt[data-media-frame="keyline"] .ch-hub__stage:not(:has(.ch-scene--duo)) { width: 100cqw; height: 100cqh; aspect-ratio: auto; }
}
@media (max-width: 1023.98px) {   /* phones: the two-phone scenes' role tag needs room under the keyline and its caption */
  .sl-apt[data-media-frame="keyline"] .ch-scene[data-roles] { height: 76%; margin-top: 13%; }
}

/* recipe: faq/2026-08_creohaus_dot-collapse-faq-accordion */
/* ==== RECIPE CSS START: faq/2026-08_creohaus_dot-collapse-faq-accordion ==== */
.sl-dcf { background: var(--sl-bg); color: var(--sl-text); }
.sl-dcf__inner { max-width: var(--sl-dcf-max, 780px); margin: 0 auto; }
.sl-dcf__head { text-align: center; margin-bottom: 40px; }
.sl-dcf__head h2 { margin-top: 12px; }
.sl-dcf__sub { margin: 16px auto 0; max-width: 48ch; color: var(--sl-muted); }

.sl-dcf__list { display: flex; flex-direction: column; gap: 8px; }
.sl-dcf__row {
  border: 1px solid var(--sl-border);
  border-radius: var(--sl-radius);
  overflow: hidden;
  background: color-mix(in srgb, var(--sl-surface-2) 40%, var(--sl-surface));
  transition: background-color 0.25s ease;
}
.sl-dcf__row.is-open { background: var(--sl-surface); }
.sl-dcf__q { margin: 0; }
.sl-dcf__trigger {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  width: 100%;
  margin: 0;
  border: 0;
  background: none;
  cursor: pointer;
  text-align: left;
  color: var(--sl-text);
  font: inherit;
  /* Resting padding. The open-state question-to-answer gap is exactly half of it (see below). */
  padding: var(--sl-dcf-pad, 20px) 24px;
  transition: background-color 0.25s ease;
}
@media (min-width: 640px) { .sl-dcf__trigger { padding-left: 32px; padding-right: 32px; } }
.sl-dcf__row:not(.is-open) .sl-dcf__trigger:hover { background: color-mix(in srgb, var(--sl-surface-2) 75%, var(--sl-surface)); }
.sl-dcf__trigger:focus-visible { outline: 2px solid var(--sl-text); outline-offset: -2px; }
.sl-dcf__row.is-open .sl-dcf__trigger { padding-bottom: calc(var(--sl-dcf-pad, 20px) / 2); }

/* Collapse indicator: 3 shapes; opening a row sends the outer two into the middle one. */
.sl-dcf__ind { display: flex; flex-shrink: 0; gap: 6px; align-items: center; --step: 12px; }
.sl-dcf[data-indicator="vertical"] .sl-dcf__ind { flex-direction: column; }
.sl-dcf[data-indicator="horizontal"] .sl-dcf__ind { flex-direction: row; }
.sl-dcf__dot {
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--sl-text);
  transition: transform 0.3s ease, opacity 0.3s ease;
}
.sl-dcf[data-indicator-shape="square"] .sl-dcf__dot { border-radius: 0; }
/* Star: for a brand whose own mark carries stars. A 6px box reads as a blob once cut into points, so the star
   variant gets a bigger box and a tighter gap; the collapse animation is untouched. */
.sl-dcf[data-indicator-shape="star"] .sl-dcf__ind { gap: 3px; --step: 14px; }
.sl-dcf[data-indicator-shape="star"] .sl-dcf__dot {
  width: 11px;
  height: 11px;
  border-radius: 0;
  clip-path: polygon(50% 0%, 61% 35%, 98% 35%, 68% 57%, 79% 91%, 50% 70%, 21% 91%, 32% 57%, 2% 35%, 39% 35%);
}
.sl-dcf[data-indicator="vertical"] .is-open .sl-dcf__dot:first-child { transform: translateY(var(--step)); opacity: 0; }
.sl-dcf[data-indicator="vertical"] .is-open .sl-dcf__dot:last-child { transform: translateY(calc(var(--step) * -1)); opacity: 0; }
.sl-dcf[data-indicator="horizontal"] .is-open .sl-dcf__dot:first-child { transform: translateX(var(--step)); opacity: 0; }
.sl-dcf[data-indicator="horizontal"] .is-open .sl-dcf__dot:last-child { transform: translateX(calc(var(--step) * -1)); opacity: 0; }

.sl-dcf__panel { height: 0; overflow: hidden; transition: height 0.4s ease; }
.sl-dcf__answer { padding: 0 24px var(--sl-dcf-pad, 20px); color: var(--sl-muted); }
@media (min-width: 640px) { .sl-dcf__answer { padding-left: 32px; padding-right: 32px; } }
/* Longer answers: .sl-dcf__answer may be a div holding several <p> and a <ul>. */
.sl-dcf__answer > * + * { margin-top: 12px; }
.sl-dcf__answer ul { margin-bottom: 0; padding-left: 1.2em; list-style: square; }
.sl-dcf__answer li + li { margin-top: 6px; }
.sl-dcf__answer strong { color: var(--sl-text); font-weight: 600; }

/* Knob: data-layout="split". Desktop (1024+): head on the left, pinned under the sticky nav while the list scrolls
   (--sl-dcf-top), list on the right. The optional data-sl-opt-cta block puts the section's next step beside the
   questions; it is hidden under 1024px, where the page's sticky call bar already carries it. */
.sl-dcf__cta { margin-top: 28px; display: none; }
@media (min-width: 1024px) {
  .sl-dcf[data-layout="split"] .sl-dcf__inner {
    max-width: var(--sl-dcf-split-max, 1200px);
    display: grid;
    grid-template-columns: 5fr 7fr;
    column-gap: 64px;
    align-items: start;
  }
  .sl-dcf[data-layout="split"] .sl-dcf__head { position: sticky; top: var(--sl-dcf-top, 120px); margin-bottom: 0; text-align: left; }
  .sl-dcf[data-layout="split"] .sl-dcf__sub { margin-left: 0; }
  .sl-dcf[data-layout="split"] .sl-dcf__cta { display: flex; }
}
@media (prefers-reduced-motion: reduce) {
  .sl-dcf__panel, .sl-dcf__dot, .sl-dcf__row { transition: none; }
}
/* ==== RECIPE CSS END ==== */
/* CreoHaus skin (2026-09-23): the FAQ sits under the 88px sticky nav, so the pinned head clears it. */
#faq { --sl-dcf-top: 120px; }

/* ==== RECIPE CSS START: footer/2026-08_creohaus_standard-agency-footer ==== */
.sl-ftr { background: var(--sl-bg); color: var(--sl-text); padding: 80px 0 32px; }
/* Content-sized columns + space-between: the gaps between columns read equal, whatever each holds. */
.sl-ftr__grid {
  display: grid;
  grid-template-columns: auto auto auto auto;
  justify-content: space-between;
  gap: 32px;
  margin-bottom: 56px;
}
@media (max-width: 900px) { .sl-ftr__grid { grid-template-columns: 1fr 1fr; justify-content: initial; gap: 36px; } }
@media (max-width: 540px) { .sl-ftr__grid { grid-template-columns: 1fr; } }

.sl-ftr__logo { display: inline-block; margin-bottom: 20px; }
.sl-ftr__logo img { height: var(--sl-ftr-logo-h, 88px); width: auto; }
.sl-ftr__desc { color: var(--sl-muted); max-width: 280px; }

.sl-ftr__col h4 {
  font-family: var(--sl-font-body);
  font-weight: 600;
  font-size: 13px;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--sl-muted);
  margin-bottom: 18px;
}
.sl-ftr__col .sl-ftr__social-head { margin-top: 24px; }
.sl-ftr__col a,
.sl-ftr__col p {
  display: block;
  color: var(--sl-text);
  opacity: 0.8;
  margin-bottom: 12px;
  text-decoration: none;
  transition: opacity 0.3s var(--sl-ease), color 0.3s var(--sl-ease);
}
.sl-ftr__col a:hover { opacity: 1; color: var(--sl-accent); }
.sl-ftr__col--info a,
.sl-ftr__col--info p { display: flex; align-items: center; gap: 10px; max-width: 240px; }
.sl-ftr__icon { font-size: 18px; flex-shrink: 0; color: var(--sl-muted); }

/* .sl-ftr__grid prefix: the social links sit inside a column whose "a" rule is display:block.
   Without the extra class the column rule wins on source order and the icon centring collapses. */
.sl-ftr__social { display: flex; gap: 12px; }
.sl-ftr__grid .sl-ftr__social a {
  width: 40px;
  height: 40px;
  margin: 0;
  opacity: 1;
  border-radius: 50%;
  border: 1px solid var(--sl-border);
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--sl-text);
  transition: background-color 0.3s var(--sl-ease), border-color 0.3s var(--sl-ease), color 0.3s var(--sl-ease);
}
.sl-ftr__grid .sl-ftr__social a:hover { background: var(--sl-accent); border-color: var(--sl-accent); color: var(--sl-on-accent); }
.sl-ftr__social svg { width: 16px; height: 16px; }

.sl-ftr__bottom {
  border-top: 1px solid var(--sl-border);
  padding-top: 28px;
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  align-items: center;
  gap: 16px;
  color: var(--sl-muted);
  font-size: 14px;
}
.sl-ftr__credit {
  color: var(--sl-text);
  font-family: var(--sl-font-display);
  font-size: 17px;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  text-decoration: none;
  transition: opacity 0.3s var(--sl-ease);
}
.sl-ftr__credit:hover { opacity: 0.75; }
.sl-ftr__credit-accent { color: var(--sl-accent); }
/* Optional part data-sl-opt-legal: Privacy / Terms links in the bottom bar, between the copyright and the credit
   (legal pages link from here only, never the main nav). Same muted small print as the copyright; 48px tap rows on
   phones. Delete the block if the site has no legal pages yet. */
.sl-ftr__legal { display: flex; flex-wrap: wrap; gap: 4px 24px; }
.sl-ftr__legal a {
  color: var(--sl-muted);
  text-decoration: underline;
  text-decoration-color: transparent;
  text-underline-offset: 3px;
  transition: color 0.3s var(--sl-ease), text-decoration-color 0.3s var(--sl-ease);
}
.sl-ftr__legal a:hover { color: var(--sl-text); text-decoration-color: currentColor; }
.sl-ftr__legal a:focus-visible { outline: 2px solid var(--sl-text); outline-offset: 4px; }
.sl-ftr__legal a:active { transform: translateY(1px); }
@media (max-width: 767px) { .sl-ftr__legal a { display: inline-flex; align-items: center; min-height: 48px; } }
/* Knob: data-links="roll". Column links set like the keyline-box nav (display face, 800, uppercase) and roll on
   hover the same way: each link is a one-line window over two stacked copies of its text; the first slides up and
   out, the accent copy slides in from below. Markup per link:
   <a href="..."><span class="sl-ftr__roll"><span>Label</span><span aria-hidden="true">Label</span></span></a>
   Phone numbers keep plain text (never animated) but take the same type. */
.sl-ftr[data-links="roll"] .sl-ftr__col a {
  width: fit-content;
  font-family: var(--sl-font-display);
  font-size: var(--sl-ftr-link-size, 20px);
  font-weight: 800;
  line-height: 1.15;
  letter-spacing: 0.01em;
  text-transform: uppercase;
  opacity: 1;
}
.sl-ftr[data-links="roll"] .sl-ftr__col a:hover { color: var(--sl-text); }
.sl-ftr[data-links="roll"] .sl-ftr__col a[href^="tel:"]:hover { color: var(--sl-ftr-hover, var(--sl-accent)); }
/* CreoHaus 2026-10-14: the footer email keeps its real case (uppercase display type reads oddly for an address) and hovers like the phone. */
.sl-ftr[data-links="roll"] .sl-ftr__col a[href^="mailto:"] { text-transform: none; }
.sl-ftr[data-links="roll"] .sl-ftr__col a[href^="mailto:"]:hover { color: var(--sl-ftr-hover, var(--sl-accent)); }
.sl-ftr[data-links="roll"] .sl-ftr__col a:focus-visible { outline: 2px solid var(--sl-text); outline-offset: 6px; }
.sl-ftr[data-links="roll"] .sl-ftr__col a:active { transform: translateY(1px); }
.sl-ftr__roll { position: relative; display: block; overflow: hidden; line-height: 1.2; }   /* no padding: the copy must land exactly where the first sat */
.sl-ftr__roll > span { display: block; transition: transform 280ms cubic-bezier(0, 0.1, 0.95, 0.9); }
.sl-ftr__roll > span + span { position: absolute; left: 0; right: 0; top: 100%; color: var(--sl-ftr-hover, var(--sl-accent)); }
.sl-ftr__col a:hover .sl-ftr__roll > span,
.sl-ftr__col a:focus-visible .sl-ftr__roll > span { transform: translateY(-100%); }
@media (prefers-reduced-motion: reduce) { .sl-ftr__roll > span { transition: none; } }
/* Phones: every roll link is a 48px tap target (padding, not a bigger font), rows touch instead of a 12px margin. */
@media (max-width: 767px) { .sl-ftr[data-links="roll"] .sl-ftr__col a { min-height: 48px; padding-block: 12px; margin-bottom: 0; } }
/* ==== RECIPE CSS END ==== */

/* recipe: cta/2026-09_creohaus_mobile-sticky-call-bar */
/* ==== RECIPE CSS START: cta/2026-09_creohaus_mobile-sticky-call-bar ==== */
/* The agency's day-one mobile bar: pinned to the bottom of the screen on phones and small tablets, one Call and one
   main action side by side, always visible (web-build.md standard). The page gets bottom padding so nothing ends up
   hidden behind it. */
.sl-msb {
  position: fixed; left: 0; right: 0; bottom: 0; z-index: 999999;
  display: flex; align-items: stretch; gap: 8px;
  padding: 10px 12px calc(10px + env(safe-area-inset-bottom));
  background: var(--sl-bg); color: var(--sl-text);
  border-top: 1px solid var(--sl-border);
  box-shadow: 0 -8px 24px rgba(0, 0, 0, 0.12);
}
.sl-msb > .btn { flex: 1 1 0; min-width: 0; }
body:has(.sl-msb) { padding-bottom: calc(var(--btn-height, 52px) + 21px + env(safe-area-inset-bottom)); }   /* = the bar: 10 + 10 padding + 1 border + button */
@media (min-width: 1024px) {
  .sl-msb { display: none; }
  body:has(.sl-msb) { padding-bottom: 0; }
}
/* ==== RECIPE CSS END ==== */

/* ==== CREOHAUS KNOB SETTINGS (declared knobs only) ==== */
/* Hero: tall layout. Values measured for Big Shoulders Display 800 (HERO-FINAL.md): the claim is the largest size
   that keeps ANOTHER LEAD! on one line; side bearing 0.031em on B and N; cap gap 0.0477em; baseline trim 0.0895em. */
#hero {
  --sl-ppt-title-tall: clamp(80px, min(11.85vw, calc((0.62 * (min(100vw, (100vw + 1408px) / 2) - 48px) - 64px) / 4.85)), 238px);
  --sl-ppt-optical: -0.031em;
  --sl-ppt-cap-top: 0.0477em;
  --sl-ppt-base-trim: 0.0895em;
  --sl-ppt-badge: var(--play-butter);
  --sl-ppt-badge-ink: var(--ink);
  --sl-tex-rgb: 58 15 34;
}

/* Nav: runs over the hero; links box in Paper so it reads as a panel on the linen; hover and current page Tangerine
   (display type at 20px+ bold counts as large text, 3.35:1 passes AA large). */
#site-nav { --sl-kbn-bar: var(--paper); --sl-kbn-box: var(--paper); --sl-kbn-hover: var(--tangerine); --sl-kbn-logo-h: 36px; }
@media (min-width: 1024px) { #site-nav { --sl-kbn-logo-h: 44px; } }   /* Yvad 2026-09-23: logo bigger, more pronounced (was 30px) */

/* The Reality: Berry band after the light hero (light and dark alternate), bars in the play set with Berry Ink
   text. Tangerine stays on the progress line, the closing rule and the closing phrase only. */
#reality {
  --sl-tex-rgb: 255 243 228;
  --sl-tex-strength: 0.9;
  --sl-nss-c1: var(--play-butter);     --sl-nss-on1: var(--ink);
  --sl-nss-c2: var(--paper);           --sl-nss-on2: var(--ink);
  --sl-nss-c3: var(--play-berry);      --sl-nss-on3: var(--ink);
  --sl-nss-c4: var(--play-periwinkle); --sl-nss-on4: var(--ink);
  --sl-nss-em: var(--tangerine);
  --sl-nss-h: 440px;
  --sl-nss-pull-w: none;               /* closing line runs to the end of the last bar */
}

/* Real Client Photos: portrait client photography, three photos crossfading every 4.5s with real
   controls (dots, swipe, click). Marker picked on https://claude.ai/artifact/JfN17hBGrc5QdrF3njxsLQ
   (board 2 option 4, Yvad 2026-09-22), refined the same day: Caveat in Tangerine, arrow centred over
   the label pointing down at the "n" of Client, desktop media narrowed to a portrait column.
   Stacking: do NOT give this section a z-index. The marquee above (#trust) sits at z-index 1 and is
   meant to stay in front; lifting the whole section over it clipped the marquee (Yvad 2026-09-22).
   The arrow can't be raised on its own either, because data-texture="linen" puts isolation: isolate
   on the section root, which seals it as a stacking context. So the overhang is kept clear of the
   marquee by geometry instead: measured clearance is 40px at 1280 and 28px at 1440, and the wide
   screen rule below buys back what the marquee's 3deg tilt eats above 1800px. */
#real-photos {
  position: relative;
  --sl-sua-ratio: 4 / 5;                          /* phones */
  --sl-sua-media-w: min(470px, 45vw);             /* narrow column -> portrait box. Flat above ~1045px so the block is identical at every desktop width */
  --sl-sua-marker-font: "Caveat", cursive;
  --sl-sua-marker-size: clamp(21px, 5.2vw, 31px);
  --sl-sua-marker-color: var(--tangerine);
  --sl-sua-marker-tilt: -8deg;
  --sl-sua-marker-hang: clamp(16px, 2.65vw, 38px);
  --sl-sua-marker-arrow-w: clamp(42px, 7.2vw, 86px);
  /* Widened from 1040px (Yvad 2026-09-22). 1040 was the one width where the accordion ended level
     with "WE TAKE THEM.", but widening pulls the heading's balanced line end LEFT while the
     accordion moves right, so no wider value re-aligns. 1140px is where the body paragraph reaches
     its full 54ch measure (72 characters); past it the column grows but the text does not. */
  --sl-sua-max: 1140px;
}
/* The marquee above is tilted 3deg, so its low corner reaches further down as the page gets wider.
   Measured clearance to the arrow: 40px at 1280, 28px at 1440, 16px at 1680, 3px at 1920. Pull the
   overhang in slightly on wide screens so the two never meet. */
#real-photos {
  /* The marquee above is tilted 3deg, so its low corner reaches further down the wider the page
     gets (about 0.026px per px of width). Past ~1700px that eats the arrow's clearance. Buy it back
     with top padding rather than by shrinking the overhang, so the arrow keeps the size and hang
     that were approved at every width. Measured clearance: 40px at 1280, 28px at 1440, 3px at 1920
     and an 8.5px overlap at 2560 before this rule. */
  padding-top: calc(var(--section-pad) + max(0px, (100vw - 1700px) * 0.045));
}
/* Arrow sits over the middle of the label rather than its first word. */
#real-photos .sl-sua__marker { align-items: center; }
#real-photos .sl-sua__marker-arrow {
  --sl-sua-arrow-tilt: 64deg;   /* composed inside the wiggle keyframes, never set as transform */
  --sl-sua-marker-arrow-x: 38px;   /* centred item: a left margin shifts it by half, so this puts the drawn tip on the n of Client */
}

/* Linen on every band (design-system.md): Berry Ink threads on light bands, Light Text threads on Berry bands. */
[data-band="light"][data-texture~="linen"] { --sl-tex-rgb: 58 15 34; }
[data-band="dark"][data-texture~="linen"] { --sl-tex-rgb: 255 243 228; --sl-tex-strength: 0.9; }

/* Services: the three outcome cards in the play colours (Ink text on each passes AA, design-system.md tier 3). */
#services { --sl-toc-c1: var(--play-butter); --sl-toc-c2: var(--play-berry); --sl-toc-c3: var(--play-periwinkle); --sl-toc-line: transparent; --sl-toc-icon-bg: var(--paper); }

/* Trust strip: angled Berry band between two Paper bands, two rows; the second (who we build for) carries the Tangerine chips. */
#trust { --sl-trc-tilt: 3deg; --sl-trc-speed: 44; --sl-trc-pad: 16px; }

/* Rebrands: no heading, so the strip gets a small padding of its own; What we do below starts right after it. */
#rebrands { padding-top: clamp(40px, 5vw, 64px); padding-bottom: clamp(40px, 5vw, 64px); }
#rebrands + #services { padding-top: 0; }

/* Work: four folders in the play colours, stacked (Agenflow Our Work), pinned just under the sticky nav. */
#work { --sl-ftc-top: 112px; /* nav is 88px tall + 24px air (phones too) */ --sl-ftc-c1: var(--play-butter); --sl-ftc-c2: var(--play-mint); --sl-ftc-c3: var(--play-berry); --sl-ftc-c4: var(--play-periwinkle); --sl-ftc-cut: 28px; }
/* Stacked folders slide in but never fade: a half-faded folder sliding over a pinned one would show it through. */
#work[data-layout="stack"] .sl-ftc__item[data-reveal] { opacity: 1; }

/* Reviews: Tangerine stars (non-text graphic, 3.35:1 on Paper passes the 3:1 graphic minimum). */
#reviews { --sl-rvm-star: var(--tangerine); }

/* Final CTA: Berry Mid so the close reads as its own island above the Berry Ink footer. */
#final-cta { --sl-fcta-bg: var(--berry-mid); }

/* Footer logo: stacked wordmark in Light Paper (Yvad 2026-09-23), viewBox cropped, 2.44:1. */
#site-footer { --sl-ftr-logo-h: 88px; }

/* recipe: hero/2026-09_creohaus_editorial-split-hero (service pages; Mode F 2026-09-24: value-first facts + source line) */
/* ==== RECIPE CSS START: hero/2026-09_creohaus_editorial-split-hero ==== */
.sl-esh { background: var(--sl-bg); color: var(--sl-text); padding: var(--sl-esh-top, 104px) 0 56px; }
@media (min-width: 1024px) { .sl-esh { padding-bottom: 80px; } }

/* Phones: claim + actions, photo, supporting line, facts (measured order on the reference). */
.sl-esh__grid { display: grid; grid-template-columns: 1fr; grid-template-areas: "main" "visual" "note" "facts"; row-gap: 40px; }
.sl-esh__main { grid-area: main; display: flex; flex-direction: column; justify-content: center; }
.sl-esh__eyebrow { margin-bottom: 14px; }
.sl-esh__title { font-size: var(--sl-esh-title, clamp(40px, 4.2vw, 64px)); line-height: 1.1; letter-spacing: -0.03em; text-transform: var(--sl-esh-title-case, none); }
.sl-esh__actions { margin-top: 40px; display: flex; flex-direction: column; align-items: stretch; gap: 12px; }
@media (min-width: 640px) { .sl-esh__actions { flex-direction: row; align-items: center; gap: 16px; } }

/* Knob data-phone-order="photo-before-actions": under 1024px the photo sits between the claim and the buttons
   (claim, photo, actions, supporting line, facts). The main column dissolves so its children take their own rows. */
@media (max-width: 1023px) {
  .sl-esh[data-phone-order="photo-before-actions"] .sl-esh__grid { grid-template-areas: "title" "visual" "actions" "note" "facts"; }
  .sl-esh[data-phone-order="photo-before-actions"] .sl-esh__grid:has(.sl-esh__eyebrow) { grid-template-areas: "eyebrow" "title" "visual" "actions" "note" "facts"; }
  .sl-esh[data-phone-order="photo-before-actions"] .sl-esh__main { display: contents; }
  .sl-esh[data-phone-order="photo-before-actions"] .sl-esh__eyebrow { grid-area: eyebrow; justify-self: start; margin-bottom: -26px; } /* 14px under the eyebrow despite the 40px row gap */
  .sl-esh[data-phone-order="photo-before-actions"] .sl-esh__title { grid-area: title; }
  .sl-esh[data-phone-order="photo-before-actions"] .sl-esh__actions { grid-area: actions; margin-top: 0; }
}

.sl-esh__visual { grid-area: visual; }
.sl-esh__media { position: relative; aspect-ratio: var(--sl-esh-ratio, 1 / 1); border-radius: var(--sl-radius); overflow: hidden; background: var(--sl-surface-2); }
.sl-esh__media > img,
.sl-esh__media > video { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }

/* Under the split: a hairline, then the supporting line (left) and the fact bar (right). */
.sl-esh__note { grid-area: note; padding-top: 24px; border-top: 1px solid var(--sl-border); max-width: 48ch; }
.sl-esh__facts { grid-area: facts; list-style: none; padding-top: 24px; border-top: 1px solid var(--sl-border); display: grid; grid-template-columns: 1fr; gap: 20px; }
@media (min-width: 640px) { .sl-esh__facts { grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 24px; } }
.sl-esh__fact-label { font-size: 16px; color: var(--sl-muted); }
/* Knob data-fact-order="value-first": the value leads (a statistic), its sentence follows. */
.sl-esh[data-fact-order="value-first"] [data-sl-fact] { display: flex; flex-direction: column; }
.sl-esh[data-fact-order="value-first"] .sl-esh__fact-value { order: -1; margin: 0 0 8px; }
/* Optional source line under a fact: a sourced number always shows where it comes from. */
.sl-esh__fact-source { margin-top: 8px; font-size: 14px; line-height: 1.4; color: var(--sl-muted); }
.sl-esh__fact-source a { color: inherit; text-decoration: underline; text-underline-offset: 3px; }
.sl-esh__fact-source a:hover { color: var(--sl-text); }
.sl-esh__fact-source a:focus-visible { outline: 2px solid var(--sl-accent); outline-offset: 2px; }
.sl-esh__fact-value {
  margin-top: 8px;
  font-family: var(--sl-font-display);
  font-size: var(--sl-esh-value, clamp(26px, 2.4vw, 32px));
  font-weight: 600;
  line-height: 1.1;
  letter-spacing: -0.01em;
  font-variant-numeric: tabular-nums;
}

@media (min-width: 1024px) {
  /* Two equal columns, each framed by hairlines above and below. */
  .sl-esh__grid {
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
    grid-template-areas: "main visual" "note facts";
    column-gap: clamp(24px, 2.4vw, 34px);
    row-gap: 0;
  }
  .sl-esh__main { padding: 48px 0; border-top: 1px solid var(--sl-border); border-bottom: 1px solid var(--sl-border); }
  .sl-esh__visual { padding-bottom: 24px; border-top: 1px solid var(--sl-border); border-bottom: 1px solid var(--sl-border); }
  .sl-esh__note, .sl-esh__facts { border-top: 0; }
}
/* Knob data-layout="stack": one centred column at every width (eyebrow, claim, actions, supporting line, then the
   media below), for notice pages such as a 404. Don't combine with data-phone-order. Widths: --sl-esh-stack-w (text),
   --sl-esh-stack-media (media). */
.sl-esh[data-layout="stack"] .sl-esh__grid { grid-template-columns: minmax(0, 1fr); grid-template-areas: "main" "note" "visual" "facts"; row-gap: 24px; column-gap: 0; max-width: var(--sl-esh-stack-w, 760px); margin-inline: auto; text-align: center; }
.sl-esh[data-layout="stack"] .sl-esh__main { padding: 0; border: 0; align-items: center; }
.sl-esh[data-layout="stack"] .sl-esh__actions { justify-content: center; margin-top: 32px; }
.sl-esh[data-layout="stack"] .sl-esh__note { padding-top: 0; border-top: 0; margin-inline: auto; }
.sl-esh[data-layout="stack"] .sl-esh__visual { width: 100%; max-width: var(--sl-esh-stack-media, 560px); justify-self: center; margin-top: 16px; padding: 0; border: 0; }
/* ==== RECIPE CSS END ==== */

/* recipe: steps-process/2026-09_creohaus_scroll-lit-phase-track (service pages: How it works) */
/* ==== RECIPE CSS START: steps-process/2026-09_creohaus_scroll-lit-phase-track ==== */
.sl-slt {
  --sl-slt-badge: 56px;
  --sl-slt-line-w: 2px;
  --sl-slt-gap: 32px;
  --sl-slt-col-gap: 32px;
  --sl-slt-fill: var(--sl-accent);
  --sl-slt-lit-scale: 1.12;
  --sl-slt-lit-ms: 500ms;
  --sl-slt-glow: 0 0 16px color-mix(in srgb, var(--sl-accent) 38%, transparent);
  /* Scroll window (read by the JS on every refresh, wrapped in clamp() so it can always finish). */
  --sl-slt-start: top 85%;
  --sl-slt-end: bottom 50%;
  --sl-slt-scrub: 0.8;
  background: var(--sl-bg);
  color: var(--sl-text);
}
.sl-slt__head { max-width: 720px; margin: 0 auto 48px; text-align: center; }
.sl-slt__head h2 { margin-top: 14px; }

/* Phones: a vertical spine. Each connector runs from its badge's bottom edge to the next badge's top edge,
   so the line always touches both squares, however long each phase's copy runs. */
.sl-slt__track { list-style: none; display: flex; flex-direction: column; }
.sl-slt__item { position: relative; display: flex; gap: 16px; padding-bottom: var(--sl-slt-gap); }
.sl-slt__item:last-child { padding-bottom: 0; }
.sl-slt__link {
  position: absolute;
  z-index: 1;
  top: var(--sl-slt-badge);
  bottom: 0;
  left: calc(var(--sl-slt-badge) / 2 - var(--sl-slt-line-w) / 2);
  width: var(--sl-slt-line-w);
}
.sl-slt__item:last-child .sl-slt__link { display: none; }
.sl-slt__link-base { position: absolute; inset: 0; background: var(--sl-border); }
/* --sl-slt-p is set by the JS (0 to 1). Unset = 1, so the finished state shows without JS. */
.sl-slt__link-fill {
  position: absolute;
  inset: 0;
  background: var(--sl-slt-fill);
  transform-origin: 50% 0;
  transform: scaleY(var(--sl-slt-p, 1));
}

/* Badge: bordered square > muted square + icon. Opaque, so the line meets its edges cleanly. */
.sl-slt__badge {
  position: relative;
  z-index: 2;
  flex-shrink: 0;
  width: var(--sl-slt-badge);
  height: var(--sl-slt-badge);
  padding: 5px;
  border: 1px solid var(--sl-border);
  border-radius: max(0px, calc(var(--sl-radius) + 2px));
  background: var(--sl-surface);
  transition: transform var(--sl-slt-lit-ms) cubic-bezier(0.16, 1, 0.3, 1), border-color var(--sl-slt-lit-ms) ease, box-shadow var(--sl-slt-lit-ms) ease;
}
.sl-slt__badge-inner {
  width: 100%;
  height: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
  border: 1px solid var(--sl-border);
  border-radius: var(--sl-radius-sm);
  background: var(--sl-surface-2);
  color: var(--sl-text);
  transition: background-color var(--sl-slt-lit-ms) ease, border-color var(--sl-slt-lit-ms) ease, color var(--sl-slt-lit-ms) ease;
}
.sl-slt__badge-inner .material-symbols-outlined { font-size: 22px; }

/* Lit: the line has reached this phase. Without JS (or with reduced motion) every phase shows lit. */
.sl-slt__item.is-lit .sl-slt__badge,
.sl-slt:not(.is-armed) .sl-slt__badge {
  transform: scale(var(--sl-slt-lit-scale));
  border-color: var(--sl-accent);
  box-shadow: var(--sl-slt-glow);
}
.sl-slt__item.is-lit .sl-slt__badge-inner,
.sl-slt:not(.is-armed) .sl-slt__badge-inner {
  background: var(--sl-accent);
  border-color: var(--sl-accent);
  color: var(--sl-on-accent);
}

.sl-slt__content { padding-top: 4px; }
.sl-slt__label { display: block; margin-bottom: 4px; font-size: 13px; font-weight: 700; letter-spacing: 0.08em; text-transform: uppercase; color: var(--sl-muted); }
.sl-slt__content p { margin-top: 6px; color: var(--sl-muted); }
.sl-slt__cta { margin-top: 48px; display: flex; justify-content: center; }

@media (min-width: 768px) {
  .sl-slt { --sl-slt-badge: 64px; --sl-slt-end: top 30%; }
  /* One column per phase, however many phases there are. */
  .sl-slt__track { display: grid; grid-auto-flow: column; grid-auto-columns: 1fr; column-gap: var(--sl-slt-col-gap); }
  .sl-slt__item { flex-direction: column; gap: 0; padding: calc(var(--sl-slt-badge) + 24px) 0 0; }
  .sl-slt__badge { position: absolute; top: 0; left: 0; }
  /* Right edge of this badge to the left edge of the next one: across the column and its gap. */
  .sl-slt__link {
    top: calc(var(--sl-slt-badge) / 2 - var(--sl-slt-line-w) / 2);
    bottom: auto;
    left: var(--sl-slt-badge);
    width: calc(100% - var(--sl-slt-badge) + var(--sl-slt-col-gap));
    height: var(--sl-slt-line-w);
  }
  .sl-slt__link-fill { transform-origin: 0 50%; transform: scaleX(var(--sl-slt-p, 1)); }
  .sl-slt__content { padding-top: 0; }
}
@media (prefers-reduced-motion: reduce) {
  .sl-slt__badge, .sl-slt__badge-inner { transition: none; }
}
/* ==== RECIPE CSS END ==== */

/* recipe: comparison/2026-09_creohaus_honest-comparison-table (service pages, new 2026-09-24) */
/* ==== RECIPE CSS START: comparison/2026-09_creohaus_honest-comparison-table ==== */
.sl-hct { background: var(--sl-bg); color: var(--sl-text); }
.sl-hct__head { display: flex; flex-direction: column; gap: 14px; max-width: 760px; }
.sl-hct__sub { color: var(--sl-muted); }
.sl-hct__wrap { margin-top: 40px; }
.sl-hct__table { width: 100%; border-collapse: separate; border-spacing: 0; text-align: left; }
.sl-hct__table caption { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0, 0, 0, 0); white-space: nowrap; border: 0; }
.sl-hct__table th, .sl-hct__table td { padding: 18px 20px; vertical-align: top; line-height: 1.5; }
.sl-hct__table thead th { font-family: var(--sl-font-display); font-weight: 700; font-size: 18px; line-height: 1.25; padding-bottom: 16px; border-bottom: 1px solid var(--sl-border); }
.sl-hct__table tbody th { font-weight: 700; width: var(--sl-hct-label-w, 26%); }
.sl-hct__table tbody tr + tr > * { border-top: 1px solid var(--sl-border); }
.sl-hct__table td { color: var(--sl-muted); }
/* The pick column: one surface running the full height, the accent only as a thin top rule (one moment per section). */
.sl-hct__table [data-sl-pick] { background: var(--sl-surface); color: var(--sl-text); }
.sl-hct__table thead [data-sl-pick] { border-top: 4px solid var(--sl-accent); border-radius: var(--sl-radius-sm) var(--sl-radius-sm) 0 0; }
.sl-hct__table tbody tr:last-child [data-sl-pick] { border-radius: 0 0 var(--sl-radius-sm) var(--sl-radius-sm); }
.sl-hct[data-pick-style="outline"] .sl-hct__table [data-sl-pick] { background: transparent; box-shadow: inset 1px 0 0 var(--sl-text), inset -1px 0 0 var(--sl-text); }
.sl-hct[data-pick-style="outline"] .sl-hct__table tbody tr:last-child [data-sl-pick] { box-shadow: inset 1px 0 0 var(--sl-text), inset -1px 0 0 var(--sl-text), inset 0 -1px 0 var(--sl-text); }
/* Optional mark before an answer: yes / part / no, drawn in CSS so no icon font is needed. */
.sl-hct__mark { display: inline-block; width: 10px; height: 10px; margin-right: 10px; border: 2px solid currentColor; border-radius: 50%; vertical-align: 1px; }
.sl-hct__mark[data-mark="yes"] { background: currentColor; }
.sl-hct__mark[data-mark="part"] { background: linear-gradient(90deg, currentColor 50%, transparent 50%); }
.sl-hct__mark[data-mark="no"] { opacity: 0.5; }
.sl-hct__note { margin-top: 28px; max-width: 760px; color: var(--sl-muted); }
.sl-hct__cta { margin-top: 32px; }
/* Phones: each row becomes a card; every answer carries its column name (data-label), the pick answer sits on its surface. */
@media (max-width: 767px) {
  .sl-hct__table, .sl-hct__table tbody, .sl-hct__table tr, .sl-hct__table th, .sl-hct__table td { display: block; width: 100%; }
  .sl-hct__table thead { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0, 0, 0, 0); }
  .sl-hct__table tbody { display: flex; flex-direction: column; gap: 16px; }
  .sl-hct__table tbody tr { border: 1px solid var(--sl-border); border-radius: var(--sl-radius-sm); overflow: hidden; }
  .sl-hct__table tbody tr + tr > * { border-top: 0; }
  .sl-hct__table tbody th { width: 100%; padding: 16px 18px 8px; font-family: var(--sl-font-display); font-size: 18px; }
  .sl-hct__table td { padding: 10px 18px; }
  .sl-hct__table td::before { content: attr(data-label); display: block; font-size: 14px; font-weight: 700; letter-spacing: 0.04em; text-transform: uppercase; color: var(--sl-muted); margin-bottom: 2px; }
  .sl-hct__table td[data-sl-pick] { padding: 14px 18px 16px; border-top: 3px solid var(--sl-accent); border-radius: 0; }
  .sl-hct__table td[data-sl-pick]::before { color: var(--sl-text); }
  .sl-hct__table tbody tr:last-child [data-sl-pick] { border-radius: 0; }
  .sl-hct[data-pick-style="outline"] .sl-hct__table td[data-sl-pick], .sl-hct[data-pick-style="outline"] .sl-hct__table tbody tr:last-child [data-sl-pick] { box-shadow: none; }
}
/* ==== RECIPE CSS END ==== */

/* ==== CreoHaus service pages skin (/services/<slug>, board pick C 2026-09-24) ==== */
.sl-esh { --sl-esh-top: 136px; --sl-esh-title-case: uppercase; --sl-esh-ratio: 1 / 1; --sl-esh-value: clamp(34px, 3.2vw, 44px); }
.sl-esh .sl-esh__media { display: flex; align-items: center; justify-content: center; background: var(--paper-2); }
.sl-esh .ch-scene { height: 88%; }
.sl-esh .ch-scene--duo { transform: translateY(6.5%); }   /* laptop + phone scene: its phone close-up is top-anchored, so centre it in the square hero frame (measured 2026-09-25) */
.sl-esh__eyebrow { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.sl-esh__tag { display: inline-block; padding: 6px 10px 4px; background: var(--tangerine); color: var(--ink); font-family: var(--sl-font-display); font-weight: 800; font-size: 15px; letter-spacing: 0.04em; text-transform: uppercase; }
.ch-crumb { font-size: 14px; font-weight: 600; letter-spacing: 0.08em; text-transform: uppercase; color: var(--sl-muted); text-decoration: none; }
.ch-crumb:hover { color: var(--sl-text); text-decoration: underline; text-underline-offset: 3px; }
.ch-crumb:focus-visible { outline: 2px solid var(--tangerine); outline-offset: 3px; }
.ch-crumb__sep { color: var(--sl-muted); }
.sl-esh .sl-esh__fact-value { color: var(--sl-text); }
#how .ch-answer { max-width: 62ch; margin-inline: auto; }
.sl-slt__head, .sl-slt__head .eyebrow { text-align: center; }
.ch-cost { margin-top: 20px; padding: 18px 20px; border-left: 3px solid var(--tangerine); background: var(--sl-surface-2); }
.sl-acp[data-band="dark"] .ch-cost { background: rgba(255,255,255,0.06); }
.ch-cost__title { font-family: var(--sl-font-display); font-weight: 800; font-size: 22px; letter-spacing: 0.01em; text-transform: uppercase; margin-bottom: 6px; color: var(--sl-text); }
.sl-hct__table thead th { font-size: 22px; font-weight: 800; letter-spacing: 0.01em; text-transform: uppercase; }
@media (max-width: 767px) { .sl-hct__table tbody th { font-size: 20px; font-weight: 800; text-transform: uppercase; } }
.ch-cost p:not(.ch-cost__title) { color: var(--sl-muted); }
.sl-dcf__answer ul { margin: 10px 0 10px 20px; display: grid; gap: 6px; }
#familiar { --sl-toc-c1: var(--paper); --sl-toc-c2: var(--paper); --sl-toc-c3: var(--paper); --sl-toc-icon-bg: var(--play-periwinkle); }
#familiar .sl-toc__outcome { color: var(--sl-text); font-size: 18px; line-height: 1.55; margin-bottom: 0; }
#related .sl-toc__card { background: var(--ch-tone); border-color: transparent; }
#related { --sl-toc-icon-bg: var(--paper); }


/* ==== BUTTON SYSTEM: roll-slide v1 ===========================================================
   MASTER COPY: _agency-ops/section-library/_micro-elements/buttons/2026-09_creohaus_roll-slide/button-system.css
   Captured from https://agenflow.webflow.io/ (2026-09-21, frame-sampled). First installed on CreoHaus (Client 2).
   Install with _micro-elements/buttons/_tools/install-button-system.cjs, plus button-system.js (builds the second
   copy of each label and arrow). Per client, edit ONLY the TOKEN BRIDGE. Spec + role picking: BUTTON-SCALE.md

   INVARIANTS: one height (--btn-height) for every button at every breakpoint. One hover family, no colour change:
   the label rolls up out of the button while shrinking to 80%, an identical copy rises from below growing 80% to
   100%, and the arrow slides out to the right while a second arrow slides in from the left. 400ms on enter; on
   leave everything resets instantly, which is invisible because both copies are identical (measured on the
   reference: leave runs no animation, the next hover replays from the start). No lift, shadow or wipe.

   ROLES  .btn-primary / .btn-split-on-light / .btn-split-on-dark  -> accent shell, on-accent label (every band)
          .btn-call          dark shell on light bands, light shell on dark bands; phone controls never move:
                             label and icon stay still, hover is a tint (opacity only)
          .btn-ghost         2px keyline in the band's contrast neutral, label + arrow, no fill
          .btn-outline-rect  2px keyline in the band's contrast neutral, label only
          .btn-square        icon-only accent square, arrow slides through
   BANDS  light is the default. Dark: .on-dark on the button, or an ancestor .text-on-dark / [data-band="dark"] /
          .mobile-cta-bar. Accent-coloured band: .on-accent or ancestor [data-band="accent"].
   Markup is the shared class contract (.btn-split-label + .btn-split-icon). button-system.js wraps the label text in
   .btn-roll (two copies) and the icon svg in .btn-slide (two copies). Without JS the buttons render correctly and
   simply don't roll.
   ============================================================================================ */

/* ---- TOKEN BRIDGE: the only per-client edit. Point each at the client's own tokens. ---- */
:root {
  --btn-height: 56px;                                          /* THE height. Every button, every breakpoint (never under 48px) */
  --btn-font: "Big Shoulders Display", sans-serif;          /* roll-slide labels are uppercase display type (Agenflow look) */
  --btn-accent: var(--tangerine);                                /* brand accent: primary cell, call shell, primary wipe */
  --btn-on-accent: var(--ink);                                 /* text + icons sitting on the accent */
  --btn-dark: var(--ink);                                      /* dark neutral: dark shells, ghost/outline on light bands */
  --btn-on-dark: var(--light);                                    /* text + icons resting on a dark shell or dark cell */
  --btn-light: var(--paper);                                 /* light shell for primaries on dark bands */
  --btn-on-light: var(--ink);                                  /* text resting on the light shell */
  --btn-light-line: var(--light);                       /* light neutral over dark bands / dark floods: keylines, ghost cell, labels */
  --btn-band-dark: var(--ink);                             /* ink on light cells; outline-on-dark hover label */
  --btn-tint-light: rgba(58, 15, 34, 0.08);                    /* ghost hover fill, light bands (default: dark at ~5%) */
  --btn-tint-dark: rgba(255, 243, 228, 0.12);                  /* ghost hover fill, dark bands (default: light at ~8%) */
  /* Ghost hover label, one per band. Only needs changing when a client sets the ghost fill above to something
     opaque (e.g. the accent), where the resting label would no longer read on it. Defaults keep the label as-is. */
  --btn-ghost-label-hover-light: var(--btn-dark);
  --btn-ghost-label-hover-dark: var(--btn-light-line);
}
/* ---- END TOKEN BRIDGE ---- */

/* ---- SYSTEM CONSTANTS: what makes this system THIS system. Measured off the reference (frame-sampled at 60fps,
   fitted rmse 0.003). Change only by re-capturing it, never per client. ---- */
:root {
  --btn-motion: roll;                                          /* read by site-buttons.cjs to pick the right hover check */
  --btn-frame: 2px;                                            /* keyline weight (ghost, outline) */
  --btn-cell: 22px;                                            /* arrow box (the reference's 24px icon block, scaled to our 18px icon) */
  --btn-radius: 0px;                                           /* sharp */
  --btn-duration: 400ms;                                       /* enter; leave is instant (0ms), as measured */
  --btn-ease: cubic-bezier(0.46, 1, 0.9, 1);                   /* best fit to the sampled roll (power2-out family) */
  --btn-roll-scale: 0.8;                                       /* outgoing copy shrinks to, incoming copy grows from */
  --btn-gap: 10px;                                             /* label to arrow */
}

.btn {
  position: relative;
  isolation: isolate;
  overflow: hidden;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--btn-gap);
  height: var(--btn-height);
  min-height: var(--btn-height);
  padding: 0 20px;
  background: var(--btn-bg, transparent);
  border: var(--line-width, 0px) solid var(--line, transparent);
  border-radius: var(--btn-radius);
  color: var(--label, currentColor);
  font-family: var(--btn-font);
  font-size: 18px;
  font-weight: 800;
  line-height: 1;
  letter-spacing: 0.02em;
  text-transform: uppercase;
  text-decoration: none;
  white-space: nowrap;
  clip-path: none;
  cursor: pointer;
}
@media (min-width: 768px) {
  .btn { padding: 0 24px; font-size: 20px; }
}
/* Tint layer: only the call role (and reduced motion) uses it, so a hover is always visible. Opacity only. */
.btn::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  background: var(--btn-tint, transparent);
  opacity: 0;
  transition: opacity 200ms ease;
  pointer-events: none;
}
.btn:active { transform: translateY(1px); }
.btn:focus-visible { outline: 2px solid var(--focus-ring, var(--btn-dark)); outline-offset: 3px; }
.text-on-dark, [data-band="dark"], .mobile-cta-bar { --focus-ring: var(--btn-light-line); }

/* ---- Split structure: label + arrow, no cell in this system. ---- */
.btn-split { justify-content: center; }
.btn-split-label { display: inline-flex; align-items: center; }
.btn-split-icon {
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex: 0 0 var(--btn-cell);
  width: var(--btn-cell);
  height: var(--btn-cell);
  overflow: hidden;
  color: var(--icon, currentColor);
}
.btn-split-icon svg { width: 18px; height: 18px; display: block; flex: none; }
/* The shared markup carries a diagonal arrow; this system shows it pointing right, like the reference. */
.btn-split:not(.btn-call):not([data-motion-lock="phone"]) .btn-split-icon svg,
.btn-square svg { transform: rotate(45deg); }

/* ---- The roll (label) and the slide (arrow). Built by button-system.js. ---- */
.btn-roll { position: relative; display: inline-block; overflow: hidden; vertical-align: top; line-height: 1.2; }   /* no padding: the copy must land exactly where the first sat */
.btn-roll__a, .btn-roll__b { display: block; transform-origin: 50% 50%; transition: transform 0ms; }
.btn-roll__b { position: absolute; left: 0; right: 0; top: 100%; transform: scale(var(--btn-roll-scale)); }
.btn-slide__a, .btn-slide__b { display: flex; align-items: center; justify-content: center; width: 100%; height: 100%; transition: transform 0ms; }
.btn-slide__b { position: absolute; inset: 0; transform: translateX(-100%); }

.btn:not([data-motion-lock="phone"]):hover .btn-roll__a,
.btn:not([data-motion-lock="phone"]):focus-visible .btn-roll__a {
  transform: translateY(-100%) scale(var(--btn-roll-scale));
  transition: transform var(--btn-duration) var(--btn-ease);
}
.btn:not([data-motion-lock="phone"]):hover .btn-roll__b,
.btn:not([data-motion-lock="phone"]):focus-visible .btn-roll__b {
  transform: translateY(-100%) scale(1);
  transition: transform var(--btn-duration) var(--btn-ease);
}
.btn:not([data-motion-lock="phone"]):hover .btn-slide__a,
.btn:not([data-motion-lock="phone"]):focus-visible .btn-slide__a {
  transform: translateX(100%);
  transition: transform var(--btn-duration) var(--btn-ease);
}
.btn:not([data-motion-lock="phone"]):hover .btn-slide__b,
.btn:not([data-motion-lock="phone"]):focus-visible .btn-slide__b {
  transform: translateX(0);
  transition: transform var(--btn-duration) var(--btn-ease);
}
/* Phone controls never move (label, number and icon stay still): the tint shows the hover instead. */
.btn[data-motion-lock="phone"]:hover::after,
.btn[data-motion-lock="phone"]:focus-visible::after { opacity: 1; }

/* ---- Roles. Each sets colours only. ---- */

/* PRIMARY: accent shell, on-accent label and arrow, on every band (the accent reads on light and dark grounds). */
.btn-primary,
.btn-split-on-light,
.btn-split-on-dark {
  --btn-bg: var(--btn-accent);
  --label: var(--btn-on-accent);
  --btn-tint: var(--btn-tint-light);
}
/* On an accent-coloured band the accent shell would vanish: dark shell, light label (derived, not observed). */
.btn-primary.on-accent,
[data-band="accent"] .btn-primary {
  --btn-bg: var(--btn-dark);
  --label: var(--btn-on-dark);
  --btn-tint: var(--btn-tint-dark);
}

/* CALL: the dark neutral shell (observed as the reference's dark nav button); light shell on dark bands. */
.btn-call {
  --btn-bg: var(--btn-dark);
  --label: var(--btn-on-dark);
  --icon: var(--btn-accent);
  --btn-tint: var(--btn-tint-dark);
}
.btn-call.on-dark,
.text-on-dark .btn-call,
[data-band="dark"] .btn-call,
.mobile-cta-bar .btn-call {
  --btn-bg: var(--btn-light);
  --label: var(--btn-on-light);
  --icon: var(--btn-on-light);
  --btn-tint: var(--btn-tint-light);
}

/* GHOST: accent can't be spent here. 2px keyline in the contrast neutral, label + arrow. */
.btn-ghost {
  --line-width: var(--btn-frame);
  --line: var(--btn-dark);
  --label: var(--btn-dark);
  --btn-tint: var(--btn-tint-light);
}
.btn-ghost.on-dark,
.text-on-dark .btn-ghost,
[data-band="dark"] .btn-ghost,
.mobile-cta-bar .btn-ghost {
  --line: var(--btn-light-line);
  --label: var(--btn-light-line);
  --btn-tint: var(--btn-tint-dark);
}

/* OUTLINE secondary (no icon): the same keyline, label only. Never the accent. */
.btn-outline-rect {
  --line-width: var(--btn-frame);
  --line: var(--btn-dark);
  --label: var(--btn-dark);
  --btn-tint: var(--btn-tint-light);
}
.btn-outline-rect.on-dark,
.text-on-dark .btn-outline-rect,
[data-band="dark"] .btn-outline-rect,
.mobile-cta-bar .btn-outline-rect {
  --line: var(--btn-light-line);
  --label: var(--btn-light-line);
  --btn-tint: var(--btn-tint-dark);
}

/* SQUARE: icon-only accent square (back to top, carousel arrows). The arrow slides through. */
.btn-square {
  --btn-bg: var(--btn-accent);
  --label: var(--btn-on-accent);
  width: var(--btn-height);
  padding: 0;
}
.btn-square .btn-split-icon, .btn-square > .btn-slide-box { position: relative; width: var(--btn-cell); height: var(--btn-cell); overflow: hidden; display: inline-flex; }
.btn-square svg { width: 18px; height: 18px; display: block; }

/* Reduced motion: nothing moves; every role shows the tint instead, so a hover is still visible. */
@media (prefers-reduced-motion: reduce) {
  .btn-roll__a, .btn-roll__b, .btn-slide__a, .btn-slide__b { transition: none !important; }
  .btn:hover .btn-roll__a, .btn:focus-visible .btn-roll__a { transform: none; }
  .btn:hover .btn-roll__b, .btn:focus-visible .btn-roll__b { transform: scale(var(--btn-roll-scale)); }
  .btn:hover .btn-slide__a, .btn:focus-visible .btn-slide__a { transform: none; }
  .btn:hover .btn-slide__b, .btn:focus-visible .btn-slide__b { transform: translateX(-100%); }
  .btn:hover::after, .btn:focus-visible::after { opacity: 1; }
}
/* ==== END BUTTON SYSTEM ==== */


/* recipe: contact/2026-09_creohaus_info-card-form-split (installed 2026-09-25 for /contact) */
/* ==== RECIPE CSS START: contact/2026-09_creohaus_info-card-form-split ==== */
/* The agency contact-page baseline (values measured off the approved 2026-09-08 build). One section: a
   compact info card beside the form. DOM is info first, form second, so phones read eyebrow, heading,
   info, form; the desktop form-left swap is CSS order only. The card fills the row height and centres
   its content. */
.section.sl-icf { background: var(--sl-bg); color: var(--sl-text); padding-top: var(--sl-icf-top, 56px); }
.sl-icf__grid {
  display: grid;
  grid-template-columns: 0.75fr 1.25fr;
  gap: 56px;
  align-items: stretch;
}
/* Tracks may shrink below a long unbreakable row (an email address) instead of blowing out the grid. */
.sl-icf__grid > * { min-width: 0; }
@media (max-width: 900px) {
  .sl-icf__grid { grid-template-columns: 1fr; gap: 40px; }
}
@media (min-width: 901px) {
  .sl-icf[data-form-side="left"] .sl-icf__grid { grid-template-columns: 1.3fr 0.7fr; }
  .sl-icf[data-form-side="left"] .sl-icf__info { order: 2; }
  .sl-icf[data-form-side="left"] .sl-icf__form { order: 1; }
}
/* Knob data-phone-order="form-first": under 901px the form slot comes before the info card, for a step whose
   whole job is the embed (e.g. a booking calendar right after a form). Default: info first, as above. */
@media (max-width: 900px) {
  .sl-icf[data-phone-order="form-first"] .sl-icf__form { order: -1; }
}

.sl-icf__card {
  height: 100%;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  justify-content: center;
  padding: 40px;
  background: var(--sl-surface-2);
  border-radius: var(--sl-radius);
}
.sl-icf__title { margin-top: 14px; }
.sl-icf__sub { margin-top: 14px; font-size: 18px; color: var(--sl-muted); }

/* Sub-labels ("Information", "Follow Us"): the same job as footer column labels, not headings. */
.sl-icf__label {
  margin-bottom: 16px;
  font-family: var(--sl-font-body);
  font-size: 13px;
  font-weight: 600;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--sl-muted);
}
.sl-icf__rows { margin-top: 32px; width: 100%; }
.sl-icf__row {
  display: flex;
  align-items: center;
  gap: 14px;
  min-height: 48px;      /* tap target; same 50px row pitch as the baseline 36px icon + 14px gap */
  margin-bottom: 2px;
  color: var(--sl-text);
  font-size: 16px;
  font-weight: 600;
  text-decoration: none;
  overflow-wrap: anywhere;
}
.sl-icf__row:last-child { margin-bottom: 0; }
.sl-icf__icon {
  flex-shrink: 0;
  width: 36px;
  height: 36px;
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--sl-accent);
  color: var(--sl-on-accent);
  border-radius: var(--sl-radius-sm);
}
.sl-icf__icon .material-symbols-outlined { font-size: 20px; }
a.sl-icf__row:hover { text-decoration: underline; text-underline-offset: 4px; }
a.sl-icf__row:focus-visible { outline: 2px solid currentColor; outline-offset: 4px; }

.sl-icf__opt-social { width: 100%; }
.sl-icf__divider { height: 1px; margin: 22px 0; border: 0; background: var(--sl-border); }
.sl-icf__social { display: flex; gap: 12px; }
.sl-icf__social a {
  width: 40px;
  height: 40px;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 50%;
  background: var(--sl-text);
  color: var(--sl-bg);
  transition: background-color 0.3s var(--sl-ease), color 0.3s var(--sl-ease);
}
.sl-icf__social a:hover { background: var(--sl-accent); color: var(--sl-on-accent); }
.sl-icf__social a:focus-visible { outline: 2px solid var(--sl-text); outline-offset: 3px; }
.sl-icf__social svg { width: 16px; height: 16px; }

/* Form slot: the client's live embed (or native form) in a surface card. The slot is the anchor target.
   Third-party embeds style their own inside, so three knobs fix what the page can't reach:
   --sl-icf-form-pad (breathing room), --sl-icf-embed-trim (hides an embed's own bottom shadow strip) and
   data-form-bleed="phones" (the form runs to the screen edges under 641px, so fixed-width widgets such as a
   300px bot check aren't cropped). */
.sl-icf__form {
  position: relative;
  overflow: hidden;
  padding: var(--sl-icf-form-pad, 16px);
  background: var(--sl-surface);
  border: 1px solid var(--sl-border);
  border-radius: var(--sl-radius);
}
/* The trim clips the frame itself: the slot's overflow would only clip at its padding edge. */
.sl-icf__form iframe {
  display: block;
  width: 100%;
  border: 0;
  margin-bottom: calc(-1 * var(--sl-icf-embed-trim, 0px));
  clip-path: inset(0 0 var(--sl-icf-embed-trim, 0px) 0);
}
@media (max-width: 640px) {
  .sl-icf[data-form-bleed="phones"] .sl-icf__form {
    margin-inline: calc(-1 * var(--sl-icf-side, 24px));
    padding: var(--sl-icf-form-pad-sm, 0px);
    border-inline: 0;
    border-radius: 0;
  }
}
/* Loading veil (set by the recipe JS, so without JS the embed simply shows). While an embed boots it shows
   its own loading bar, a blank white page and a scrollbar before it sizes itself; the slot hides all of that
   behind a quiet field skeleton and fades the finished form in once. */
.sl-icf__form[data-embed-state] iframe { transition: opacity 450ms cubic-bezier(0.4, 0, 0.2, 1); }
.sl-icf__form[data-embed-state="loading"] iframe { opacity: 0; }
.sl-icf__form[data-embed-state="loading"]::before {
  content: "";
  position: absolute;
  inset: var(--sl-icf-form-pad, 16px);
  z-index: 1;
  pointer-events: none;
  background:
    linear-gradient(to bottom, var(--sl-surface-2) 0 12px, transparent 12px) left top / 30% 96px repeat-y,
    linear-gradient(to bottom, transparent 0 22px, var(--sl-surface-2) 22px 64px, transparent 64px) left top / 100% 96px repeat-y;
  animation: sl-icf-skeleton 1.4s ease-in-out infinite alternate;
}
@keyframes sl-icf-skeleton { from { opacity: 0.45; } to { opacity: 1; } }
@media (max-width: 640px) {
  .sl-icf[data-form-bleed="phones"] .sl-icf__form[data-embed-state="loading"]::before { inset: 16px 24px; }
}
@media (prefers-reduced-motion: reduce) {
  .sl-icf__form[data-embed-state] iframe { transition: none; }
  .sl-icf__form[data-embed-state="loading"]::before { animation: none; opacity: 0.7; }
}
/* ==== RECIPE CSS END ==== */

/* remix: cta/2026-09_creohaus_quote-card-close, the native form field rules only (the contact recipe ships an embed slot, no fields) */
/* ==== RECIPE CSS START (piece): cta/2026-09_creohaus_quote-card-close fields ==== */
.sl-qcc__form { margin-top: 24px; display: grid; grid-template-columns: 1fr; gap: 16px; }
@media (min-width: 640px) { .sl-qcc__form { grid-template-columns: 1fr 1fr; } }
.sl-qcc__field { display: flex; flex-direction: column; gap: 6px; font-size: 14px; font-weight: 600; }
.sl-qcc__field--full { grid-column: 1 / -1; }
.sl-qcc__field input,
.sl-qcc__field select,
.sl-qcc__field textarea {
  width: 100%;
  font: inherit;
  font-size: 16px;
  font-weight: 400;
  color: var(--sl-text);
  background: var(--sl-surface);
  border: 1px solid var(--sl-border);
  border-radius: var(--sl-radius-sm);
  padding: 12px 14px;
  min-height: 48px;
  transition: border-color 0.2s var(--sl-ease), box-shadow 0.2s var(--sl-ease);
}
.sl-qcc__field input:focus,
.sl-qcc__field select:focus,
.sl-qcc__field textarea:focus {
  outline: none;
  border-color: var(--sl-text);
  box-shadow: 0 0 0 3px rgba(0, 0, 0, 0.08);
}
.sl-qcc__submit { grid-column: 1 / -1; display: flex; flex-direction: column; align-items: stretch; gap: 10px; }
@media (min-width: 640px) { .sl-qcc__submit { flex-direction: row; align-items: center; justify-content: space-between; } }
.sl-qcc__fine { color: var(--sl-muted); font-size: 14px; }
/* ==== RECIPE CSS END ==== */


/* recipe: gallery-portfolio/2026-09_creohaus_video-hero-thumbnail-strip-case-study (installed 2026-09-25 for /case-studies) */
/* ==== RECIPE CSS START: gallery-portfolio/2026-09_creohaus_video-hero-thumbnail-strip-case-study ==== */
.sl-cs { background: var(--sl-bg); color: var(--sl-text); }
.sl-cs__grid {
  display: grid;
  grid-template-columns: 1fr;
  grid-template-areas: "eyebrow" "heading" "media" "body" "cta";
  row-gap: 20px;
}
.sl-cs__copy { display: contents; }
.sl-cs__eyebrow { grid-area: eyebrow; }
.sl-cs__heading { grid-area: heading; }
.sl-cs__body { grid-area: body; color: var(--sl-muted); }
.sl-cs__cta { grid-area: cta; }
.sl-cs__media { grid-area: media; min-width: 0; }
@media (min-width: 768px) {
  /* Media-dominant split: the media is the focal point, media on the right by default. */
  .sl-cs__grid { grid-template-columns: 5fr 7fr; grid-template-areas: "copy media"; column-gap: 3rem; align-items: center; }
  .sl-cs[data-media-side="left"] .sl-cs__grid { grid-template-columns: 7fr 5fr; grid-template-areas: "media copy"; }
  .sl-cs__copy { grid-area: copy; display: flex; flex-direction: column; row-gap: 20px; }
}

.sl-cs__facts {
  margin: 20px 0 0;
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 16px;
  padding-top: 16px;
  border-top: 1px solid var(--sl-border);
}
.sl-cs__facts dt { font-size: 12px; font-weight: 600; letter-spacing: 0.1em; text-transform: uppercase; color: var(--sl-muted); }
.sl-cs__facts dd { margin: 4px 0 0; font-weight: 600; color: var(--sl-text); }

/* Horizontal (default): 16:9 hero frame above a 4-up row of 4:3 thumbnails. One rule, every width. */
.sl-cs__row { display: flex; flex-direction: column; gap: 14px; }
.sl-cs__frame {
  position: relative;
  aspect-ratio: 16 / 9;
  border-radius: var(--sl-radius);
  overflow: hidden;
  background: var(--sl-surface-2);
}
.sl-cs__frame > img,
.sl-cs__frame > video { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
.sl-cs__thumbs { display: grid; grid-template-columns: repeat(4, 1fr); gap: 10px; }
.sl-cs__thumb {
  position: relative;
  aspect-ratio: 4 / 3;
  padding: 0;
  border: 0;
  border-radius: var(--sl-radius-sm);
  overflow: hidden;
  cursor: pointer;
  background: var(--sl-surface-2);
}
.sl-cs__thumb img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; transition: transform 0.4s var(--sl-ease); }
.sl-cs__thumb:hover img { transform: scale(1.06); }
.sl-cs__thumb:focus-visible { outline: 2px solid var(--sl-text); outline-offset: 2px; }
.sl-cs__caption { margin-top: 12px; font-size: 14px; color: var(--sl-muted); }

/* Vertical: portrait frame with the thumbnails stacked beside it. Container-query units make the whole
   composition scale as one rigid shape at every width; never gate these rules to a breakpoint. */
.sl-cs[data-orientation="vertical"] .sl-cs__media { container-type: inline-size; }
.sl-cs[data-orientation="vertical"] .sl-cs__row { flex-direction: row; align-items: flex-start; }
.sl-cs[data-orientation="vertical"] .sl-cs__frame { flex: 1; min-width: 0; aspect-ratio: auto; height: 100cqw; }
.sl-cs[data-orientation="vertical"] .sl-cs__thumbs {
  display: flex;
  flex-direction: column;
  gap: 10px;
  align-self: stretch;
  flex: 0 0 calc(var(--sl-cs-thumb-w, 22cqw) - 6.6px);
}
.sl-cs[data-orientation="vertical"] .sl-cs__thumb { aspect-ratio: auto; width: 100%; height: calc(25cqw - 7.5px); flex: 0 0 auto; }
/* ==== RECIPE CSS END ==== */

/* recipe piece: gallery-portfolio/2026-08_creohaus_hub-only-lightbox-portfolio, the shared lightbox rules only (the case-study recipe's dependency) */
/* ==== RECIPE CSS START (piece): shared lightbox ==== */
/* Shared lightbox (identical block in every recipe that opens it: install once per page). */
.sl-lightbox {
  position: fixed;
  inset: 0;
  z-index: 1000;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 24px;
  background: rgba(0, 0, 0, 0.9);
  opacity: 0;
  visibility: hidden;
  transition: opacity 0.3s var(--sl-ease), visibility 0.3s;
}
.sl-lightbox.is-open { opacity: 1; visibility: visible; }
.sl-lightbox__frame {
  position: relative;
  width: min(90vw, 1000px);
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 16px;
}
.sl-lightbox__img {
  width: 100%;
  max-height: 74vh;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: var(--sl-radius);
  overflow: hidden;
  background: rgba(0, 0, 0, 0.6);
}
.sl-lightbox__img img { width: 100%; max-height: 74vh; object-fit: contain; }
.sl-lightbox__nav { display: flex; align-items: center; gap: 24px; }
.sl-lightbox__count { color: rgba(255, 255, 255, 0.75); font-size: 14px; font-weight: 500; min-width: 48px; text-align: center; }
.sl-lightbox__ctrl {
  width: 48px;
  height: 48px;
  border-radius: 50%;
  border: 1px solid rgba(255, 255, 255, 0.28);
  background: rgba(255, 255, 255, 0.1);
  color: rgba(255, 255, 255, 0.96);
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  transition: background-color 0.25s var(--sl-ease), border-color 0.25s var(--sl-ease), color 0.25s var(--sl-ease);
}
.sl-lightbox__ctrl:hover { background: var(--sl-accent); border-color: var(--sl-accent); color: var(--sl-on-accent); }
.sl-lightbox__ctrl:focus-visible { outline: 2px solid rgba(255, 255, 255, 0.9); outline-offset: 2px; }
.sl-lightbox__ctrl svg { width: 20px; height: 20px; }
.sl-lightbox__close { position: absolute; top: -60px; right: 0; }
.sl-lightbox [hidden] { display: none; }
/* ==== RECIPE CSS END ==== */

/* recipe: gallery-portfolio/2026-09_creohaus_site-scroll-showcase (installed 2026-09-25 for the case study pages) */
/* ==== RECIPE CSS START: gallery-portfolio/2026-09_creohaus_site-scroll-showcase ==== */
/* A real website, shown working: a desktop browser frame and a phone frame, each scrolling a full-page capture top to
   bottom and back like a screen recording, beside a short story and the notes on what was built. Optional Before /
   After switch swaps both captures to the old site (only when a real capture of the old site exists).

   The scroll is one tall image moved with a transform (a fraction of a video's weight, no autoplay handling). Travel
   is computed: -100% of the image plus one screen height (cqh) lands its bottom edge on the screen's bottom edge at
   every size. Hovering a screen pauses it; nothing moves off screen; reduced motion shows the top of the page. */
.section.sl-sss { background: var(--sl-bg); color: var(--sl-text); }
.sl-sss__grid { display: grid; grid-template-columns: 1fr; gap: 48px; align-items: center; }
.sl-sss__grid > * { min-width: 0; }
@media (min-width: 1024px) {
  .sl-sss__grid { grid-template-columns: minmax(0, 5fr) minmax(0, 7fr); gap: 64px; }
  .sl-sss[data-stage-side="left"] .sl-sss__copy { order: 2; }
}
.sl-sss__copy { display: flex; flex-direction: column; align-items: flex-start; }
.sl-sss__copy h2 { margin-top: 14px; }
.sl-sss__lead { margin-top: 14px; color: var(--sl-muted); }
.sl-sss__notes { list-style: none; margin: 28px 0 0; padding: 0; width: 100%; border-top: 1px solid var(--sl-border); }
.sl-sss__notes li { padding: 14px 0; border-bottom: 1px solid var(--sl-border); }
.sl-sss__notes strong { font-weight: 700; }
.sl-sss__notes span { color: var(--sl-muted); }
.sl-sss__cta { margin-top: 28px; }

/* Before / After switch (optional). Tabs, not buttons: they swap what the frames show. */
.sl-sss__switch { display: inline-flex; margin-top: 24px; border: 1px solid var(--sl-text); border-radius: var(--sl-radius-sm); overflow: hidden; }
.sl-sss__switch button {
  min-height: 48px; padding: 0 22px; border: 0; background: transparent; color: var(--sl-text);
  font: 600 16px/1 var(--sl-font-body); letter-spacing: 0.04em; text-transform: uppercase; cursor: pointer;
  transition: background-color 0.3s var(--sl-ease), color 0.3s var(--sl-ease);
}
.sl-sss__switch button + button { border-left: 1px solid var(--sl-text); }
.sl-sss__switch button[aria-selected="true"] { background: var(--sl-text); color: var(--sl-bg); }
.sl-sss__switch button:hover:not([aria-selected="true"]) { background: var(--sl-surface-2); }
.sl-sss__switch button:focus-visible { outline: 2px solid var(--sl-text); outline-offset: 3px; }
.sl-sss__switch button:active { transform: translateY(1px); }

/* The stage: browser frame, phone overlapping its lower right corner. */
.sl-sss__stage { position: relative; padding-bottom: var(--sl-sss-phone-drop, 8%); padding-right: var(--sl-sss-phone-out, 6%); }
.sl-sss__browser {
  position: relative; border: 1px solid var(--sl-border); border-radius: var(--sl-radius); overflow: hidden;
  background: var(--sl-surface); box-shadow: 0 2px 4px rgba(0, 0, 0, 0.06), 0 24px 48px rgba(0, 0, 0, 0.14);
}
.sl-sss__bar { display: flex; align-items: center; gap: 7px; height: 36px; padding: 0 14px; background: var(--sl-surface-2); border-bottom: 1px solid var(--sl-border); }
.sl-sss__bar > span:not(.sl-sss__url) { width: 10px; height: 10px; border-radius: 50%; background: var(--sl-border); flex: none; }
.sl-sss__url { margin-left: 10px; flex: 1; max-width: 60%; padding: 3px 12px; border-radius: 999px; background: var(--sl-surface); color: var(--sl-muted); font-size: 13px; line-height: 1.4; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.sl-sss__screen, .sl-sss__phone-screen { position: relative; overflow: hidden; container-type: size; background: var(--sl-surface-2); }
.sl-sss__screen { aspect-ratio: var(--sl-sss-ratio, 16 / 10); }
.sl-sss__phone {
  position: absolute; right: 0; bottom: 0; width: var(--sl-sss-phone-w, 24%);
  padding: 2.2%; border-radius: 22px; background: var(--sl-text);
  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1), 0 28px 56px rgba(0, 0, 0, 0.28);
}
.sl-sss__phone-screen { aspect-ratio: 9 / 19.5; border-radius: 15px; }
.sl-sss img[data-sl-scroll] {
  position: absolute; top: 0; left: 0; width: 100%; height: auto; display: block;
  animation: sl-sss-scroll var(--sl-sss-dur, 18s) linear infinite alternate;
}
.sl-sss__phone img[data-sl-scroll] { animation-duration: var(--sl-sss-phone-dur, var(--sl-sss-dur, 18s)); }
@keyframes sl-sss-scroll {
  0%, 6% { transform: translateY(0); }
  94%, 100% { transform: translateY(calc(-100% + 100cqh)); }
}
.sl-sss__screen:hover img[data-sl-scroll], .sl-sss__phone:hover img[data-sl-scroll],
.sl-sss.is-offscreen img[data-sl-scroll] { animation-play-state: paused; }
/* Which capture set shows: data-show on the root (the switch sets it). Without the switch, only "after" exists. */
/* img in the selectors (2026-09-26 fix): .sl-sss img[data-sl-scroll] sets display: block and out-ranked the plain
   [data-set] rules, so both sets showed and Before sat on top. */
.sl-sss img[data-set="before"] { display: none; }
.sl-sss[data-show="before"] img[data-set="before"] { display: block; }
.sl-sss[data-show="before"] img[data-set="after"] { display: none; }
.sl-sss__label {
  position: absolute; left: 12px; top: 12px; z-index: 1; padding: 4px 10px; border-radius: var(--sl-radius-sm);
  background: var(--sl-text); color: var(--sl-bg); font-size: 13px; font-weight: 600; letter-spacing: 0.1em; text-transform: uppercase;
}
.sl-sss:not([data-show="before"]) .sl-sss__label--before, .sl-sss[data-show="before"] .sl-sss__label--after { display: none; }
@media (max-width: 640px) {
  .sl-sss__stage { padding-right: 0; padding-bottom: 14%; }
  .sl-sss__phone { width: var(--sl-sss-phone-w-sm, 32%); padding: 2.6%; border-radius: 16px; }
  .sl-sss__phone-screen { border-radius: 10px; }
  .sl-sss__bar { height: 28px; }
  .sl-sss__url { font-size: 13px; }
}
@media (prefers-reduced-motion: reduce) {
  .sl-sss img[data-sl-scroll] { animation: none; }
}
/* --- Mode F 2026-09-26: data-stage="scene". The stage holds a demo scene (the laptop + phone micro-element from
   _micro-elements/demo-scenes, which plays its own scroll, in sync) instead of the frames above, on a light panel so a
   dark device reads on either band. The frames block is optional (data-sl-opt-frames); delete it in a scene install. --- */
.sl-sss__scene { display: none; }
.sl-sss[data-stage="scene"] .sl-sss__scene {
  display: block;
  position: relative;
  aspect-ratio: var(--sl-sss-scene-ratio, 1 / 1);
  border-radius: var(--sl-radius);
  overflow: hidden;
  background: var(--sl-sss-scene-bg, var(--sl-light-surface, var(--sl-surface)));
}
.sl-sss[data-stage="scene"] .sl-sss__stage { padding: 0; }
.sl-sss[data-stage="scene"] .sl-sss__browser,
.sl-sss[data-stage="scene"] .sl-sss__phone { display: none; }
/* ==== RECIPE CSS END ==== */

/* recipe: gallery-portfolio/2026-09_creohaus_brand-kit-sheet (installed 2026-09-25 for the case study pages) */
/* ==== RECIPE CSS START: gallery-portfolio/2026-09_creohaus_brand-kit-sheet ==== */
/* A brand, laid out like a one-page brand sheet: the logo (optionally its old version beside it), the typefaces as
   specimens set in the real fonts, and the palette as swatches with names and values. For showing a brand that was
   actually made; every value is the brand's real one.

   The brand's own colours and fonts are CONTENT here, not theme: each swatch takes --sl-bks-sw and each specimen
   --sl-bks-font from a style attribute, and a logo tile can sit on the brand's own background with --sl-bks-mark-bg
   (the page must load those fonts). Everything else reads the band tokens. */
.section.sl-bks { background: var(--sl-bg); color: var(--sl-text); }
.sl-bks__head { max-width: 720px; margin-bottom: 40px; }
.sl-bks__head > * + * { margin-top: 14px; }
.sl-bks__head p:last-child { color: var(--sl-muted); }
.sl-bks__sheet { display: grid; grid-template-columns: 1fr; gap: 16px; }
@media (min-width: 900px) { .sl-bks__sheet { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); } .sl-bks__logo { grid-column: 1 / -1; } }
.sl-bks__panel { padding: 32px; border: 1px solid var(--sl-border); border-radius: var(--sl-radius); background: var(--sl-surface); }
@media (max-width: 640px) { .sl-bks__panel { padding: 24px 20px; } }
.sl-bks__label { margin-bottom: 20px; font-size: 13px; font-weight: 600; letter-spacing: 0.14em; text-transform: uppercase; color: var(--sl-muted); }

/* Logo: before -> after (before optional). */
.sl-bks__marks { display: grid; grid-template-columns: 1fr; gap: 16px; align-items: center; }
@media (min-width: 700px) { .sl-bks__marks { grid-template-columns: minmax(0, 1fr) auto minmax(0, 1fr); } }
.sl-bks__marks:not(:has([data-sl-opt-before])) { grid-template-columns: minmax(0, 1fr); }
.sl-bks__mark { margin: 0; display: flex; flex-direction: column; gap: 10px; }
.sl-bks__mark-art {
  position: relative; display: flex; align-items: center; justify-content: center; aspect-ratio: var(--sl-bks-mark-ratio, 16 / 9);
  padding: 8%; border-radius: var(--sl-radius-sm); background: var(--sl-bks-mark-bg, var(--sl-surface-2));
}
.sl-bks__mark-art img, .sl-bks__mark-art svg { position: absolute; inset: 10%; width: 80%; height: 80%; object-fit: contain; }   /* every logo fits the same tile */
.sl-bks__mark figcaption { font-size: 13px; font-weight: 600; letter-spacing: 0.14em; text-transform: uppercase; color: var(--sl-muted); }
.sl-bks__mark--after figcaption { color: var(--sl-text); }
.sl-bks__arrow { display: flex; justify-content: center; color: var(--sl-muted); }
.sl-bks__arrow svg { width: 28px; height: 28px; }
@media (max-width: 699px) { .sl-bks__arrow svg { transform: rotate(90deg); } }

/* From 700px, with an old logo: the tiles share one row and the captions sit in a second row, so the arrow centres on
   the tiles themselves, not on tile + caption. */
@media (min-width: 700px) {
  .sl-bks__marks:has([data-sl-opt-before]) { grid-template-rows: auto auto; row-gap: 10px; }
  .sl-bks__marks:has([data-sl-opt-before]) .sl-bks__mark { display: contents; }
  .sl-bks__marks:has([data-sl-opt-before]) .sl-bks__mark--before > * { grid-column: 1; }
  .sl-bks__marks:has([data-sl-opt-before]) .sl-bks__mark--after > * { grid-column: 3; }
  .sl-bks__marks:has([data-sl-opt-before]) .sl-bks__mark-art { grid-row: 1; }
  .sl-bks__marks:has([data-sl-opt-before]) figcaption { grid-row: 2; }
  .sl-bks__marks:has([data-sl-opt-before]) .sl-bks__arrow { grid-column: 2; grid-row: 1; align-self: center; }
}
/* Per tile: data-fit="fill" lets a logo that comes with its own background (an old image file) fill the tile, so both
   logos read at the same size. */
.sl-bks__mark-art[data-fit="fill"] { padding: 0; overflow: hidden; }
.sl-bks__mark-art[data-fit="fill"] img { inset: 0; width: 100%; height: 100%; object-fit: cover; }
/* Optional note under the logos (data-sl-opt-note), e.g. what changed about the file itself. */
.sl-bks__note { margin-top: 24px; max-width: 70ch; color: var(--sl-muted); }
/* Optional list under the note (data-sl-opt-changes): what changed in the design itself, one short point each,
   a bold lead-in then a plain line. For a refresh that looks the same at first glance. */
.sl-bks__changes { margin: 16px 0 0; padding: 0; list-style: none; display: grid; gap: 12px; max-width: 70ch; }
.sl-bks__changes li { position: relative; padding-left: 26px; color: var(--sl-muted); }
.sl-bks__changes li::before { content: ""; position: absolute; left: 0; top: 0.8em; width: 12px; height: 2px; background: var(--sl-text); }
.sl-bks__changes strong { color: var(--sl-text); }
/* data-logo-layout="stack": old logo on top, new logo under it (arrow pointing down), smaller, in a left column; the
   note and the changes list sit to the right, centred on the pair (the empty 1fr rows above and below do the centring).
   Phones stack everything as usual. */
.sl-bks[data-logo-layout="stack"] .sl-bks__marks { grid-template-columns: minmax(0, 1fr); grid-template-rows: none; row-gap: 12px; }
.sl-bks[data-logo-layout="stack"] .sl-bks__marks .sl-bks__mark { display: flex; }
.sl-bks[data-logo-layout="stack"] .sl-bks__marks .sl-bks__arrow { grid-column: auto; grid-row: auto; }
.sl-bks[data-logo-layout="stack"] .sl-bks__arrow svg { transform: rotate(90deg); }
@media (min-width: 900px) {
  .sl-bks[data-logo-layout="stack"] .sl-bks__logo {
    display: grid;
    grid-template-columns: minmax(0, var(--sl-bks-stack-w, 40%)) minmax(0, 1fr);
    grid-template-rows: auto 1fr auto auto 1fr auto;
    column-gap: var(--sl-bks-stack-gap, 56px);
  }
  .sl-bks[data-logo-layout="stack"] .sl-bks__logo > .sl-bks__label { grid-column: 1 / -1; grid-row: 1; }
  .sl-bks[data-logo-layout="stack"] .sl-bks__logo > .sl-bks__marks { grid-column: 1; grid-row: 2 / 6; }
  .sl-bks[data-logo-layout="stack"] .sl-bks__logo > .sl-bks__note { grid-column: 2; grid-row: 3; margin-top: 0; }
  .sl-bks[data-logo-layout="stack"] .sl-bks__logo > .sl-bks__changes { grid-column: 2; grid-row: 4; }
  .sl-bks[data-logo-layout="stack"] .sl-bks__logo > .sl-bks__variants { grid-column: 1 / -1; grid-row: 6; }
}
/* Optional icon row (data-sl-opt-solo): the new logo's icon on its own, in small square tiles under the After logo, one
   colour pairing per tile (the brand's own colours, per tile style: --sl-bks-mark-bg + color). Three by default. */
.sl-bks__solos { display: grid; grid-template-columns: repeat(var(--sl-bks-solo-count, 3), minmax(0, 1fr)); gap: 12px; }
.sl-bks__solos .sl-bks__mark { gap: 8px; }
.sl-bks__solos .sl-bks__mark-art { aspect-ratio: 1 / 1; padding: 0; }
.sl-bks__solos .sl-bks__mark-art img, .sl-bks__solos .sl-bks__mark-art svg { inset: var(--sl-bks-solo-inset, 16%); width: calc(100% - 2 * var(--sl-bks-solo-inset, 16%)); height: calc(100% - 2 * var(--sl-bks-solo-inset, 16%)); }
.sl-bks__solos figcaption { font-size: 12px; letter-spacing: 0.1em; }
.sl-bks:not([data-logo-layout="stack"]) .sl-bks__solos { grid-column: 1 / -1; }
/* Optional variations grid (data-sl-opt-variants): the new logo taken apart and recoloured, the way a vector file allows. */
.sl-bks__variants { margin-top: 28px; padding-top: 24px; border-top: 1px solid var(--sl-border); }
.sl-bks__variant-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 16px; }
@media (min-width: 900px) { .sl-bks__variant-grid { grid-template-columns: repeat(4, minmax(0, 1fr)); } }
.sl-bks__variant { margin: 0; display: flex; flex-direction: column; gap: 8px; }
.sl-bks__variant .sl-bks__mark-art { aspect-ratio: var(--sl-bks-variant-ratio, 4 / 3); }
.sl-bks__variant figcaption { font-size: 13px; font-weight: 600; letter-spacing: 0.14em; text-transform: uppercase; color: var(--sl-muted); }

/* Typography: one specimen per face, set in the face itself. */
.sl-bks__face { display: grid; grid-template-columns: auto minmax(0, 1fr); gap: 4px 20px; align-items: center; padding: 18px 0; border-top: 1px solid var(--sl-border); }
.sl-bks__face:last-child { padding-bottom: 0; }
.sl-bks__aa { grid-row: span 2; font-family: var(--sl-bks-font, var(--sl-font-display)); font-size: var(--sl-bks-aa, clamp(56px, 6vw, 88px)); line-height: 1; letter-spacing: 0; }
.sl-bks__name { font-family: var(--sl-bks-font, var(--sl-font-display)); font-size: 22px; line-height: 1.2; font-weight: 700; }
.sl-bks__role { font-size: 16px; color: var(--sl-muted); }
.sl-bks__sample { grid-column: 1 / -1; margin-top: 8px; font-family: var(--sl-bks-font, var(--sl-font-body)); font-size: 18px; line-height: 1.5; overflow-wrap: anywhere; }

/* Palette: swatch + name + value. */
.sl-bks__swatches { list-style: none; margin: 0; padding: 0; display: grid; grid-template-columns: repeat(auto-fill, minmax(118px, 1fr)); gap: 16px; }
.sl-bks__swatch { display: flex; flex-direction: column; gap: 6px; }
.sl-bks__chip { display: block; aspect-ratio: 1 / 1; border-radius: var(--sl-radius-sm); background: var(--sl-bks-sw); border: 1px solid var(--sl-border); }
.sl-bks__swatch strong { font-size: 16px; font-weight: 600; line-height: 1.3; }
.sl-bks__swatch code { font-family: var(--sl-font-body); font-size: 16px; color: var(--sl-muted); text-transform: uppercase; }
/* ==== RECIPE CSS END ==== */

/* recipe: testimonials/2026-09_creohaus_named-quote-stats (installed 2026-09-25 for the case study pages) */
/* ==== RECIPE CSS START: testimonials/2026-09_creohaus_named-quote-stats ==== */
.sl-nqs { background: var(--sl-bg); color: var(--sl-text); }
.sl-nqs__panel { padding: 28px 22px; background: var(--sl-surface); border: 1px solid var(--sl-border); border-radius: var(--sl-radius); }
@media (min-width: 640px) { .sl-nqs__panel { padding: 48px; } }
.sl-nqs__source { display: flex; flex-direction: column; gap: 12px; padding-bottom: 24px; border-bottom: 1px solid var(--sl-border); }
@media (min-width: 640px) { .sl-nqs__source { flex-direction: row; align-items: flex-end; justify-content: space-between; } }
.sl-nqs__source-head { display: flex; flex-direction: column; gap: 14px; }
/* Knob data-heading: "sr" keeps the heading for screen readers only (a quote carries the band);
   "visible" shows it under the eyebrow (a band of facts needs a headline). Size comes from the site's h2. */
.sl-nqs__title { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0, 0, 0, 0); white-space: nowrap; border: 0; }
.sl-nqs[data-heading="visible"] .sl-nqs__title { position: static; width: auto; height: auto; margin: 0; overflow: visible; clip: auto; white-space: normal; }
.sl-nqs__chips { list-style: none; display: flex; flex-wrap: wrap; gap: 8px; }
.sl-nqs__chips li { padding: 6px 12px; border-radius: var(--sl-radius-sm); background: var(--sl-surface-2); font-size: 14px; font-weight: 600; }
/* Attribution sits beside the quote and above the numbers, so every figure reads as someone's. */
.sl-nqs__quote-row { margin-top: 32px; display: grid; grid-template-columns: 1fr; gap: 24px; }
@media (min-width: 1024px) { .sl-nqs__quote-row { grid-template-columns: 8fr 4fr; gap: 40px; align-items: center; } }
.sl-nqs__quote { margin: 0; }
.sl-nqs__quote p { font-family: var(--sl-font-display); font-size: var(--sl-nqs-quote, clamp(24px, 3vw, 36px)); font-weight: 700; line-height: 1.25; letter-spacing: -0.01em; }
.sl-nqs__attr { display: flex; align-items: center; gap: 14px; padding: 16px; border-radius: var(--sl-radius-sm); background: var(--sl-surface-2); }
.sl-nqs__face { width: 56px; height: 56px; flex-shrink: 0; border-radius: 50%; overflow: hidden; background: var(--sl-border); }
.sl-nqs__face img { width: 100%; height: 100%; object-fit: cover; }
.sl-nqs__name { font-weight: 700; }
.sl-nqs__role, .sl-nqs__cite { font-size: 14px; color: var(--sl-muted); }
.sl-nqs__metrics { list-style: none; margin-top: 32px; display: grid; grid-template-columns: 1fr; gap: 16px; }
@media (min-width: 640px) { .sl-nqs__metrics { grid-template-columns: repeat(3, 1fr); } }
.sl-nqs__metric { display: flex; flex-direction: column; justify-content: space-between; padding: 20px; border: 1px solid var(--sl-border); border-radius: var(--sl-radius-sm); background: var(--sl-bg); }
.sl-nqs__label { font-size: 16px; color: var(--sl-muted); line-height: 1.45; }
/* Static values by default: no count-up unless the figure is real and the motion is measured. */
.sl-nqs__value { margin-top: 24px; font-family: var(--sl-font-display); font-size: var(--sl-nqs-value, clamp(40px, 5vw, 56px)); font-weight: 700; line-height: 1; letter-spacing: -0.02em; }
/* ==== RECIPE CSS END ==== */

/* ==== CreoHaus legal pages (/privacy, /terms): data-recipe="exempt:legal", generated by brand_assets/legal-pages-build.cjs ====
   A readable single column (~70ch) on the light linen band: real headings, a "Last updated" line, an "On this page"
   list, 17px body text. Headings are document headings (a different job from section H2s), so they sit smaller. */
.ch-legal__doc { max-width: 70ch; margin: 0 auto; font-size: 17px; line-height: 1.7; color: var(--ink); }
.ch-legal__updated { font-size: 13px; font-weight: 600; letter-spacing: 0.14em; text-transform: uppercase; color: var(--ink-soft); margin-bottom: 14px; }
.ch-legal__lead { font-size: 19px; margin-bottom: 40px; }
.ch-legal__toc { border-top: 2px solid var(--ink); border-bottom: 1px solid var(--line); padding: 20px 0 16px; margin-bottom: 56px; }
.ch-legal__toc-head { font-size: 13px; font-weight: 600; letter-spacing: 0.14em; text-transform: uppercase; margin-bottom: 8px; }
.ch-legal__toc ol { margin: 0; padding: 0; list-style: none; counter-reset: legal; columns: 2; column-gap: 32px; }
.ch-legal__toc li { counter-increment: legal; break-inside: avoid; }
.ch-legal__toc a { display: flex; gap: 10px; align-items: baseline; padding: 6px 0; color: var(--ink); text-decoration: none; transition: color 0.3s var(--sl-ease); }
.ch-legal__toc a::before { content: counter(legal, decimal-leading-zero); font-family: var(--sl-font-display); font-weight: 800; font-size: 15px; color: var(--ink-soft); min-width: 22px; }
.ch-legal__toc a:hover { color: var(--berry-mid); text-decoration: underline; text-underline-offset: 3px; }
.ch-legal__toc a:focus-visible { outline: 2px solid var(--ink); outline-offset: 2px; }
.ch-legal__toc a:active { transform: translateY(1px); }
.ch-legal__doc h2 { font-size: clamp(26px, 3vw, 34px); line-height: 1.05; margin: 48px 0 14px; scroll-margin-top: 110px; }
.ch-legal__doc h2:first-of-type { margin-top: 0; }
.ch-legal__doc p + p, .ch-legal__doc ul + p, .ch-legal__doc p + ul { margin-top: 14px; }
.ch-legal__doc ul { margin: 0; padding-left: 1.25em; }
.ch-legal__doc li { margin-top: 8px; }
.ch-legal__doc li::marker { color: var(--tangerine); }
.ch-legal__doc strong { font-weight: 700; }
.ch-legal__doc p a, .ch-legal__doc li a { color: var(--ink); text-decoration: underline; text-underline-offset: 3px; text-decoration-thickness: 1px; transition: color 0.3s var(--sl-ease); }
.ch-legal__doc p a:hover, .ch-legal__doc li a:hover { color: var(--berry-mid); text-decoration-thickness: 2px; }
.ch-legal__doc p a:focus-visible, .ch-legal__doc li a:focus-visible { outline: 2px solid var(--ink); outline-offset: 2px; }
/* Visible placeholder until Yvad supplies the detail (never ships: listed under "Needs Yvad" in task-log.md). */
.ch-legal__todo { background: var(--play-butter); color: var(--ink); padding: 0 4px; font-weight: 600; }
@media (max-width: 767px) {
  .ch-legal__lead { font-size: 18px; margin-bottom: 32px; }
  .ch-legal__toc ol { columns: 1; }
  .ch-legal__toc a { min-height: 48px; align-items: center; padding: 0; }
  .ch-legal__toc { margin-bottom: 44px; }
  .ch-legal__doc h2 { margin-top: 40px; }
}

/* ==== CreoHaus contact page skin (/contact; generator brand_assets/contact-build.cjs) ====
   Two installs of contact/2026-09_creohaus_info-card-form-split: #book (the calendar slot) and #message (the native
   form, fields from cta/2026-09_creohaus_quote-card-close). Skin only: colours, sizes, the placeholders. */
.sl-icf.ch-contactpage { --sl-icf-form-pad: 40px; }
@media (max-width: 640px) { .sl-icf.ch-contactpage { --sl-icf-form-pad: 24px; } }
.ch-contactpage .sl-icf__card { padding: 40px; }
@media (max-width: 640px) { .ch-contactpage .sl-icf__card { padding: 32px 24px; } }
/* Repeated rows never take the accent (design-doctrine: accent = the one Primary + the eyebrow). */
.ch-contactpage .sl-icf__icon { background: var(--play-periwinkle); color: var(--ink); }
.ch-contactpage .sl-icf__row { font-weight: 500; }
.ch-contactpage .sl-icf__row b { font-weight: 700; }
.ch-contactpage .sl-icf__sub { font-size: 18px; }

/* Calendar slot placeholder (until the HighLevel booking widget is pasted in). */
.ch-cal-ph { position: relative; min-height: 560px; height: 100%; display: flex; flex-direction: column; align-items: flex-start; justify-content: center; gap: 14px; padding: 40px;
  background: repeating-linear-gradient(135deg, rgba(255,243,228,.05) 0 2px, transparent 2px 22px); border: 1px dashed var(--sl-border); }
[data-band="light"] .ch-cal-ph { background: repeating-linear-gradient(135deg, rgba(58,15,34,.05) 0 2px, transparent 2px 22px); }
.ch-cal-ph__icon { width: 56px; height: 56px; display: flex; align-items: center; justify-content: center; background: var(--play-periwinkle); color: var(--ink); }
.ch-cal-ph__icon .material-symbols-outlined { font-size: 30px; }
.ch-cal-ph__tag { font-size: 13px; font-weight: 600; letter-spacing: 0.14em; text-transform: uppercase; color: var(--sl-muted); }
.ch-cal-ph__title { font-family: var(--sl-font-display); font-weight: 800; text-transform: uppercase; font-size: clamp(28px, 3vw, 36px); line-height: 1.02; letter-spacing: -0.02em; color: var(--sl-text); }
.ch-cal-ph p:not([class]) { max-width: 46ch; color: var(--sl-muted); }
.ch-cal-ph a { color: var(--sl-text); text-decoration: underline; text-underline-offset: 3px; transition: opacity 0.3s var(--sl-ease); }
.ch-cal-ph a:hover { opacity: 0.75; }
.ch-cal-ph a:focus-visible { outline: 2px solid var(--sl-text); outline-offset: 2px; }
@media (max-width: 640px) { .ch-cal-ph { min-height: 420px; padding: 28px 24px; } }

/* Native form: 16px labels (body text floor), fields on Paper inside the Paper 2 card. */
.ch-contactpage .sl-qcc__form { margin-top: 0; }
.ch-contactpage .sl-qcc__field { font-size: 16px; color: var(--sl-text); }
.ch-contactpage .sl-qcc__field input, .ch-contactpage .sl-qcc__field select { background: var(--paper); border-color: rgba(58, 15, 34, 0.28); }
.ch-contactpage .sl-qcc__field input:hover, .ch-contactpage .sl-qcc__field select:hover { border-color: rgba(58, 15, 34, 0.5); }
.ch-contactpage .sl-qcc__field input:focus, .ch-contactpage .sl-qcc__field select:focus { border-color: var(--ink); box-shadow: 0 0 0 3px rgba(58, 15, 34, 0.12); }
.ch-contactpage .sl-qcc__field select { appearance: none; -webkit-appearance: none; padding-right: 44px; cursor: pointer;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='none' stroke='%233A0F22' stroke-width='2.4' stroke-linecap='square'%3E%3Cpath d='M3 6l5 5 5-5'/%3E%3C/svg%3E");
  background-repeat: no-repeat; background-position: right 16px center; background-size: 14px; }
.ch-form__help { font-size: 16px; font-weight: 400; color: var(--sl-muted); }
.ch-form__head { grid-column: 1 / -1; margin-bottom: 4px; }
.ch-form__head h3 { font-size: 22px; }
/* SMS consent: optional, unticked. Small print is allowed here (consent line); the whole row is the tap target. */
.ch-consent { grid-column: 1 / -1; display: grid; grid-template-columns: 24px 1fr; gap: 12px; align-items: start; padding: 12px 0; cursor: pointer; font-size: 14px; line-height: 1.6; font-weight: 400; color: var(--sl-muted); }
.ch-consent input { width: 22px; height: 22px; margin: 2px 0 0; accent-color: var(--ink); cursor: pointer; }
.ch-consent input:focus-visible { outline: 2px solid var(--ink); outline-offset: 2px; }
.ch-consent a { color: var(--sl-text); text-decoration: underline; text-underline-offset: 2px; }
.ch-consent a:hover { color: var(--berry-mid); }
.ch-consent a:focus-visible { outline: 2px solid var(--ink); outline-offset: 2px; }
.ch-contactpage .sl-qcc__submit { margin-top: 4px; }
.ch-form__status { grid-column: 1 / -1; padding: 16px 18px; background: var(--play-butter); color: var(--ink); font-size: 16px; }
.ch-form__status[hidden] { display: none; }
.ch-form__status:focus { outline: 2px solid var(--ink); outline-offset: 2px; }

/* ==== CreoHaus case studies skin (/case-studies; generator brand_assets/case-studies-build.cjs) ==== */
/* The shared lightbox must sit above the sticky nav (1100000) or its close button hides under the bar. */
.sl-lightbox { z-index: 1200000; }
/* "Visit Their Site" under a centred story head (reel, demo rows). */
.ch-story__visit { margin-top: 24px; display: flex; justify-content: center; }
.sl-pdr__head .ch-story__visit, .sl-prm__head .ch-story__visit { margin-top: 24px; }
/* Brand kit: the new logo is the inline SVG from the homepage logo strip; its accent parts take the brand accent. */
.ch-mark .sl-mwm__accent { fill: var(--ch-mark-accent, currentColor); }
.ch-mark .sl-mwm__edge { display: none; }
/* More work (Yvad 2026-09-26): each client's real logo in one colour, Berry Ink, in the icon slot instead of a stock icon. */
.sl-toc__icon.ch-toc-logo { width: auto; height: 56px; justify-content: flex-start; background: none; color: var(--ink); --ch-mark-accent: currentColor; }
.ch-toc-logo svg { height: 100%; width: auto; max-width: 170px; }
/* The starting point as a brief (Yvad 2026-09-26): statement heading, labelled rows, the old logo with its old Google
   profile laid over it, a hand-drawn marker in the homepage Real Client Photos style. */
#starting-point.sl-sua {
  --sl-sua-media-w: min(470px, 40vw);
  --sl-sua-ratio: 4 / 5;
  --sl-sua-statement-size: clamp(26px, 2.6vw, 38px);
  --sl-sua-statement-max: 30ch;
  --sl-sua-rows-top: 24px;
  --sl-sua-marker-font: "Caveat", cursive;
  --sl-sua-marker-size: clamp(21px, 5.2vw, 31px);
  --sl-sua-marker-color: var(--tangerine);
  --sl-sua-marker-hang: clamp(16px, 2.65vw, 38px);
  --sl-sua-marker-arrow-w: clamp(42px, 7.2vw, 86px);
  --sl-sua-max: 1240px;
  --sl-sua-row-label-w: 170px;
}
@media (max-width: 767px) { #starting-point.sl-sua { --sl-sua-ratio: 3 / 4; --sl-sua-inset-w: 42%; --sl-sua-rows-top: -16px; } }   /* the empty body / cta grid rows already add 40px of gap */
#starting-point .sl-sua__marker { align-items: center; }
#starting-point .sl-sua__marker-arrow { --sl-sua-arrow-tilt: 64deg; --sl-sua-marker-arrow-x: 38px; }

/* ==== CreoHaus Who We Serve skin (/about/who-we-serve; generator brand_assets/who-we-serve-build.cjs, Yvad 2026-09-28) ==== */
/* What we believe: the same brief treatment as the case study starting point. */
#believe.sl-sua {
  --sl-sua-media-w: min(470px, 40vw); --sl-sua-ratio: 4 / 5;
  --sl-sua-statement-size: clamp(26px, 2.6vw, 38px); --sl-sua-statement-max: 30ch; --sl-sua-rows-top: 24px;
  --sl-sua-marker-font: "Caveat", cursive; --sl-sua-marker-size: clamp(21px, 5.2vw, 31px); --sl-sua-marker-color: var(--tangerine);
  --sl-sua-marker-hang: clamp(16px, 2.65vw, 38px); --sl-sua-marker-arrow-w: clamp(42px, 7.2vw, 86px);
  --sl-sua-max: 1240px; --sl-sua-row-label-w: 170px;
  --sl-sua-marker-scrim: 0.5;
}
@media (max-width: 767px) { #believe.sl-sua { --sl-sua-ratio: 3 / 4; --sl-sua-rows-top: -16px; } }
#believe .sl-sua__marker { align-items: center; }
#believe .sl-sua__marker-arrow { --sl-sua-arrow-tilt: 64deg; --sl-sua-marker-arrow-x: 38px; }
#believe .sl-sua__row dd strong { color: var(--sl-text); }
/* Who we serve: the three fit cards in the play colours, like the case study "more work" cards. */
#fit .sl-toc__card { background: var(--ch-tone); border-color: transparent; }
#fit { --sl-toc-icon-bg: var(--paper); }
#fit .sl-toc__outcome { margin-bottom: 0; }
#starting-point .sl-sua__row dd strong { color: var(--sl-text); }
/* Website: the site duo straight on the Berry band, no light panel (Yvad 2026-09-28); the stage never clips the device shadows. */
#website { --sl-sss-scene-bg: transparent; --sl-sss-scene-ratio: 100 / 67; }
#website .sl-sss__scene { overflow: visible; }
/* Brand: old logo above the new one, the story beside them (Yvad 2026-09-26). */
#brand { --sl-bks-stack-w: 36%; }
/* Story pages: the breadcrumb's current page reads brighter than the link back; photo thumbs keep heads in frame. */
.ch-crumb__here { font-size: 14px; font-weight: 600; letter-spacing: 0.08em; text-transform: uppercase; color: var(--sl-text); }
.sl-sss ~ * .sl-cs__thumb img, #photos .sl-cs__thumb img { object-position: 50% 20%; }

/* Hero welcome video: play bar (drag or tap to jump, incl. back to the start) + a proportional sound badge on phones.
   Picked 2026-10-10 (board https://claude.ai/artifact/2zZyzPrZN7i4Wv7TrVqVuf: no extra decoration, play bar only). */
#hero .sl-ppt__badge { width: 76px; height: 76px; right: 10px; bottom: 10px; }
#hero .sl-ppt__badge-core { width: 40px; height: 40px; }
#hero .sl-ppt__badge-core svg { width: 19px; height: 19px; }
@media (min-width: 640px) { #hero .sl-ppt__badge { width: 95px; height: 95px; right: 12px; bottom: 12px; } #hero .sl-ppt__badge-core { width: 50px; height: 50px; } #hero .sl-ppt__badge-core svg { width: 24px; height: 24px; } }
@media (min-width: 1024px) { #hero .sl-ppt__badge { width: 121px; height: 121px; right: 24px; bottom: 24px; } #hero .sl-ppt__badge-core { width: 64px; height: 64px; } }
.ch-vbar { position: absolute; z-index: 4; left: 12px; right: 96px; bottom: 12px; height: 28px; display: flex; align-items: center; }
@media (min-width: 640px) { .ch-vbar { right: 117px; } }
@media (min-width: 1024px) { .ch-vbar { left: 20px; right: 161px; bottom: 24px; } }
.ch-vbar__range { -webkit-appearance: none; appearance: none; width: 100%; height: 28px; margin: 0; background: transparent; cursor: pointer; --p: 0%; }
.ch-vbar__range::-webkit-slider-runnable-track { height: 4px; background: linear-gradient(90deg, var(--tangerine) var(--p), rgba(255, 248, 232, .45) var(--p)); }
.ch-vbar__range::-moz-range-track { height: 4px; background: rgba(255, 248, 232, .45); }
.ch-vbar__range::-moz-range-progress { height: 4px; background: var(--tangerine); }
.ch-vbar__range::-webkit-slider-thumb { -webkit-appearance: none; width: 14px; height: 14px; margin-top: -5px; border-radius: 50%; background: var(--paper); box-shadow: 0 0 0 3px var(--tangerine), 0 2px 6px rgba(30, 5, 15, .4); transition: transform .15s ease; }
.ch-vbar__range::-moz-range-thumb { width: 14px; height: 14px; border: 0; border-radius: 50%; background: var(--paper); box-shadow: 0 0 0 3px var(--tangerine); transition: transform .15s ease; }
.ch-vbar__range:hover::-webkit-slider-thumb, .ch-vbar__range:active::-webkit-slider-thumb { transform: scale(1.3); }
.ch-vbar__range:hover::-moz-range-thumb, .ch-vbar__range:active::-moz-range-thumb { transform: scale(1.3); }
.ch-vbar__range:focus-visible { outline: 2px solid var(--tangerine); outline-offset: 4px; }

/* Reality stat icons (LottieFiles line set, filled flat in brand colours; picked on the Reality Icons board 2026-10-10).
   The animation fills the recipe's media slot. Each file's empty margin is cropped by its data-lottie-box (the viewBox),
   so the icon scales to the slot with nothing spilling past it: right edge of the open bar on desktop, left edge above
   the text on phones (the script sets the alignment). */
.sl-nss__lottie { position: absolute; inset: 0; }
.sl-nss__lottie > svg { display: block; width: 100%; height: 100%; }

/* About, What makes us different: the same animated icon set in the column's art slot (the recipe's data-art padding
   frames it; the crop in data-lottie-box removes each file's built-in margin). */
.sl-spa__lottie { position: absolute; inset: 10%; display: block; }
.sl-spa__lottie > svg { display: block; width: 100%; height: 100%; }

/* 404 page (#nf-hero, editorial split hero): the animated icon fills the media panel, cropped to its drawing.
   Option b sets "4 [magnifier] 4" in the display face, the magnifier standing in for the zero. */
#nf-hero .ch-404-art { position: absolute; inset: 14%; display: block; }
#nf-hero .ch-404-art > svg { display: block; width: 100%; height: 100%; }
#nf-hero .ch-404-num { display: flex; align-items: center; justify-content: center; gap: 2%; width: 100%; padding: 0 8%; font-family: var(--sl-font-display); font-weight: 800; font-size: clamp(96px, 16vw, 220px); line-height: 1; color: var(--ink); }
#nf-hero .ch-404-zero { display: block; flex: 0 0 auto; width: 1.02em; height: 1.02em; }
#nf-hero .ch-404-zero > svg { display: block; width: 100%; height: 100%; }
#nf-hero .ch-404-stage { position: absolute; inset: 0; display: flex; flex-direction: column; align-items: center; justify-content: center; padding: 8% 6% 6%; }
#nf-hero .ch-404-big { display: block; font-family: var(--sl-font-display); font-weight: 900; font-size: clamp(120px, 15vw, 230px); line-height: .82; letter-spacing: -.01em; color: var(--ink); }
#nf-hero .ch-404-plug { display: block; width: 100%; flex: 1 1 auto; min-height: 0; margin-top: -4%; }
#nf-hero .ch-404-plug > svg { display: block; width: 100%; height: 100%; }
/* 404 skin: light band in Paper-2 (the illustration panel's own colour), so the scene sits on the page itself. */
#nf-hero { --sl-bg: var(--paper-2); --sl-esh-stack-media: 520px; }
#nf-hero .sl-esh__media { background: transparent; }
body:has(#nf-hero) { background: var(--paper-2); }   /* no lighter strip between the 404 band and the footer */
/* 404 scene (option d, assets/js/404-scene.js): the SVG fills the media square; hidden only until the timeline sets its start. */
#nf-hero .ns-scene { position: absolute; inset: 0; display: block; width: 100%; height: 100%; cursor: pointer; overflow: visible; }
#nf-hero .ns-sans { font-family: var(--sl-font-body); }
.ns-wait #nf-hero .ns-scene { visibility: hidden; }
