/* Pieces shared by every page of the hi-fi prototype. Components come from the design system;
   this file places them. Page files (home.css, service.css, growth-review.css) hold only what is unique to one page. */

/* Theme hooks: the dark centre behind hero text and the glass on hero buttons follow the theme (see the end of this file). */
:root { --sf-scrim: 9 11 20; --sf-scrim-k: 1; --sf-glass-hover: 26 31 50; }

/* ---------- Shared page pieces ---------- */
.site-footer { border-top: 1px solid var(--sf-border); }
.section-head { max-width: 760px; }
.section-head .sf-h2 { margin-top: 14px; }
.section-head .sf-lead { margin-top: 18px; }
@media print { .section-head { break-after: avoid; } }
.row-head { display: flex; flex-wrap: wrap; align-items: flex-end; justify-content: space-between; gap: 20px 32px; }
/* Every grid starts as one shrinkable column, so a scrolling card row inside can never widen the page. */
.split { display: grid; grid-template-columns: minmax(0, 1fr); gap: 40px; }
@media (min-width: 1024px) { .split { grid-template-columns: minmax(0, 5fr) minmax(0, 7fr); gap: 72px; align-items: start; } }
/* Copy beside a picture or sample, centred against each other. */
.media-split { display: grid; grid-template-columns: minmax(0, 1fr); gap: 40px; align-items: center; }
@media (min-width: 1024px) { .media-split { grid-template-columns: minmax(0, 5fr) minmax(0, 6fr); gap: 72px; } }
.mt-24 { margin-top: 24px; } .mt-32 { margin-top: 32px; } .mt-48 { margin-top: clamp(32px, 4vw, 48px); } .mt-64 { margin-top: clamp(40px, 5vw, 64px); }

/* Abstract art stands in for photos and project images until the real ones arrive. */
.art { position: relative; overflow: hidden; width: 100%; height: 100%; background: linear-gradient(135deg, #1B2242 0%, #0E1224 70%); }
.art::before { content: ""; position: absolute; inset: 0; background-image: linear-gradient(rgba(255,255,255,.05) 1px, transparent 1px), linear-gradient(90deg, rgba(255,255,255,.05) 1px, transparent 1px); background-size: 40px 40px; }
.art::after { content: ""; position: absolute; width: 70%; aspect-ratio: 1; right: -18%; top: -30%; border-radius: 50%; background: radial-gradient(closest-side, rgba(140,77,255,.45), transparent); }
/* The picture for this piece of content (made by tools/art.py). It is fitted whole inside the frame, above the frame's own grid and glow, so no frame shape cuts it. */
.art > .art__img { position: absolute; inset: 0; z-index: 1; width: 100%; height: 100%; object-fit: contain; }
.art__ribbon { position: absolute; inset: 0; width: 100%; height: 100%; z-index: 1; }
.art__ribbon path { fill: none; stroke: url(#art-grad); stroke-width: 2; vector-effect: non-scaling-stroke; }
.art__tag { position: absolute; left: 14px; bottom: 14px; z-index: 2; padding: 4px 8px; border-radius: var(--sf-radius-xs); background: rgba(9, 11, 20, 0.72); color: var(--sf-white); font-size: 12px; font-weight: 600; letter-spacing: .02em; }
.art--light { background: linear-gradient(135deg, #E6E2DA 0%, #F5F4F0 75%); }
.art--light::before { background-image: linear-gradient(rgba(9,11,20,.06) 1px, transparent 1px), linear-gradient(90deg, rgba(9,11,20,.06) 1px, transparent 1px); }
.art--light::after { background: radial-gradient(closest-side, rgba(70,119,255,.22), transparent); }
.art--mono { background: linear-gradient(160deg, #2B2F3A 0%, #121521 65%); }
.art--mono::after { background: radial-gradient(closest-side, rgba(255,255,255,.12), transparent); }

/* ---------- Header over the hero ---------- */
.site-header { margin-bottom: calc(-1 * var(--sf-header-height)); }
.site-header.sf-dark { background-color: transparent; }
.site-header.sf-dark.is-solid { background-color: color-mix(in srgb, var(--sf-bg) 88%, transparent); }

/* "All services" under the mega menu's featured card. */
.mega-all { margin-top: 14px; font-size: var(--sf-fs-small); }

/* ---------- Page hero: the aurora background shared by every dark hero ---------- */
.page-hero { position: relative; isolation: isolate; overflow: hidden; }
/* Background, far to near. Everything moves with transform only, slowly, and pauses while the hero is off screen.
   The blobs are the brand colours at low strength, blurred, and blended with screen so their overlaps glow. */
.hero__bg { position: absolute; inset: 0; z-index: -3; overflow: hidden; pointer-events: none;
  -webkit-mask-image: linear-gradient(to bottom, #000 72%, transparent); mask-image: linear-gradient(to bottom, #000 72%, transparent); }
.hero__aurora { position: absolute; inset: -12%; }
.hero__blob, .hero__beam { position: absolute; border-radius: 50%; mix-blend-mode: screen; will-change: transform; animation-timing-function: ease-in-out; animation-iteration-count: infinite; animation-direction: alternate; }
.hero__blob--blue { left: -14%; top: 28%; width: 56vmax; aspect-ratio: 1.35; background: radial-gradient(closest-side, rgba(70, 119, 255, 0.55), rgba(70, 119, 255, 0)); filter: blur(48px); animation-name: aurora-blue; animation-duration: 26s; }
.hero__blob--purple { right: -12%; top: -22%; width: 50vmax; aspect-ratio: 1.15; background: radial-gradient(closest-side, rgba(140, 77, 255, 0.6), rgba(140, 77, 255, 0)); filter: blur(48px); animation-name: aurora-purple; animation-duration: 31s; }
.hero__blob--violet { left: 28%; bottom: -30%; width: 44vmax; aspect-ratio: 1.7; background: radial-gradient(closest-side, rgba(140, 77, 255, 0.45), rgba(70, 119, 255, 0.14) 60%, rgba(70, 119, 255, 0)); filter: blur(56px); animation-name: aurora-violet; animation-duration: 23s; }
.hero__blob--lavender { right: 10%; bottom: 6%; width: 24vmax; aspect-ratio: 1; background: radial-gradient(closest-side, rgba(200, 183, 255, 0.22), rgba(200, 183, 255, 0)); filter: blur(40px); animation-name: aurora-lavender; animation-duration: 19s; }
/* A long, soft beam of light on the angle of the symbol's ribbons. */
.hero__beam { left: 50%; top: 64%; width: 96vmax; height: 15vmax; margin-left: -48vmax; background: linear-gradient(90deg, rgba(70, 119, 255, 0), rgba(70, 119, 255, 0.38) 32%, rgba(140, 77, 255, 0.42) 68%, rgba(140, 77, 255, 0)); filter: blur(56px); opacity: 0.75; animation-name: aurora-beam; animation-duration: 17s; }
@keyframes aurora-blue { from { transform: translate3d(0, 0, 0) scale(1); } to { transform: translate3d(16vmax, -7vmax, 0) scale(1.18) rotate(10deg); } }
@keyframes aurora-purple { from { transform: translate3d(0, 0, 0) scale(1); } to { transform: translate3d(-15vmax, 9vmax, 0) scale(1.12) rotate(-8deg); } }
@keyframes aurora-violet { from { transform: translate3d(0, 0, 0) scale(1); } to { transform: translate3d(-10vmax, -5vmax, 0) scale(1.2); } }
@keyframes aurora-lavender { from { transform: translate3d(0, 0, 0) scale(1); opacity: 1; } to { transform: translate3d(-9vmax, -9vmax, 0) scale(1.3); opacity: 0.55; } }
@keyframes aurora-beam { from { transform: rotate(-28deg) translateY(2vmax); } to { transform: rotate(-19deg) translateY(-3vmax); } }
/* A dark centre over the colour and under the text, so the headline reads the same wherever the colour drifts. */
.hero__scrim { position: absolute; inset: 0; background: radial-gradient(ellipse 64% 50% at 50% 40%, rgb(var(--sf-scrim) / calc(0.8 * var(--sf-scrim-k))), rgb(var(--sf-scrim) / calc(0.42 * var(--sf-scrim-k))) 55%, rgb(var(--sf-scrim) / 0) 86%); }
/* Below 1024px the text runs the full width, right over the colour, so the dark centre grows and the colour softens. */
@media (max-width: 1023px) {
  .hero__scrim { background: radial-gradient(ellipse 95% 62% at 50% 42%, rgb(var(--sf-scrim) / calc(0.84 * var(--sf-scrim-k))), rgb(var(--sf-scrim) / calc(0.55 * var(--sf-scrim-k))) 60%, rgb(var(--sf-scrim) / 0) 94%); }
  .hero__aurora { opacity: 0.8; }
}
.hero__grid { position: absolute; inset: 0;
  background-image: linear-gradient(rgba(255, 255, 255, 0.035) 1px, transparent 1px), linear-gradient(90deg, rgba(255, 255, 255, 0.035) 1px, transparent 1px);
  background-size: 72px 72px; background-position: center top; filter: blur(0.6px);
  -webkit-mask-image: radial-gradient(ellipse 60% 70% at 50% 42%, #000 10%, transparent 70%); mask-image: radial-gradient(ellipse 60% 70% at 50% 42%, #000 10%, transparent 70%); }
/* Fine grain against banding in the blur. It stays off the centre, where the text sits. */
.hero__grain { position: absolute; inset: 0; opacity: 0.07; background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='180' height='180'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.8' numOctaves='3' stitchTiles='stitch'/%3E%3CfeColorMatrix values='0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 0 0 0 1.2 -0.25'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E"); background-size: 180px 180px;
  -webkit-mask-image: radial-gradient(ellipse 52% 44% at 50% 40%, transparent 35%, #000 85%); mask-image: radial-gradient(ellipse 52% 44% at 50% 40%, transparent 35%, #000 85%); }
.page-hero.is-offscreen .hero__blob, .page-hero.is-offscreen .hero__beam { animation-play-state: paused; }

/* Artwork shows through the outline button, so in a hero it gets a glass fill. */
.page-hero .sf-btn--secondary { background-color: rgb(var(--sf-scrim) / 0.6); -webkit-backdrop-filter: blur(10px); backdrop-filter: blur(10px); }
.page-hero .sf-btn--secondary:hover { background-color: rgb(var(--sf-glass-hover) / 0.75); }

/* ---------- Split hero: copy on the left, a stack of glass cards in depth on the right (service pages, Growth Review) ---------- */
.split-hero { padding-top: calc(var(--sf-header-height) + clamp(40px, 6vw, 96px)); padding-bottom: clamp(64px, 8vw, 112px); }
/* The dark centre sits behind the copy on the left, not in the middle as on the homepage. */
.split-hero .hero__scrim { background: radial-gradient(ellipse 60% 72% at 26% 48%, rgb(var(--sf-scrim) / calc(0.82 * var(--sf-scrim-k))), rgb(var(--sf-scrim) / calc(0.45 * var(--sf-scrim-k))) 55%, rgb(var(--sf-scrim) / 0) 88%); }
@media (max-width: 1023px) {
  .split-hero .hero__scrim { background: radial-gradient(ellipse 100% 58% at 50% 34%, rgb(var(--sf-scrim) / calc(0.85 * var(--sf-scrim-k))), rgb(var(--sf-scrim) / calc(0.55 * var(--sf-scrim-k))) 60%, rgb(var(--sf-scrim) / 0) 94%); }
}
/* A hero with no picture is shorter, so the colour sits closer to the text: the dark centre grows to cover the whole copy. */
@media (min-width: 1024px) {
  .split-hero:not(:has(.split-hero__visual)) .hero__scrim { background: radial-gradient(ellipse 78% 120% at 22% 55%, rgb(var(--sf-scrim) / calc(0.88 * var(--sf-scrim-k))), rgb(var(--sf-scrim) / calc(0.55 * var(--sf-scrim-k))) 58%, rgb(var(--sf-scrim) / 0) 92%); }
}
@media (max-width: 1023px) {
  .split-hero:not(:has(.split-hero__visual)) .hero__scrim { background: radial-gradient(ellipse 130% 105% at 40% 50%, rgb(var(--sf-scrim) / calc(0.9 * var(--sf-scrim-k))), rgb(var(--sf-scrim) / calc(0.62 * var(--sf-scrim-k))) 60%, rgb(var(--sf-scrim) / 0) 98%); }
}
.split-hero__grid { position: relative; display: grid; grid-template-columns: minmax(0, 1fr); gap: clamp(48px, 7vw, 72px); align-items: center; }
@media (min-width: 1024px) { .split-hero__grid { grid-template-columns: minmax(0, 7fr) minmax(0, 5fr); gap: 48px; } }
.split-hero__layer { margin-top: 22px; }
/* Same rule as the homepage hero: one typeface, with the payoff word in the brand gradient. */
.split-hero__title { margin-top: 18px; max-width: 16ch; font-size: clamp(2.5rem, 1.9rem + 2vw, 3.5rem); }
/* From 1200px a title built from short sentences gives each its own line: "Every click costs money. / Every click should count." */
@media (min-width: 1200px) { .split-hero__title:has(.split-hero__line) { max-width: none; } .split-hero__line { display: block; } }
.split-hero__sub { margin-top: 22px; max-width: 46ch; }
.split-hero__ctas { margin-top: 32px; }
/* Phones: full-width buttons, and a long label wraps inside its button instead of pushing past the column (320px). */
@media (max-width: 559px) { .split-hero__ctas .sf-btn { flex: 1 1 100%; min-width: 0; white-space: normal; text-align: center; line-height: 1.25; padding-block: 10px; } }
.split-hero__proof { display: flex; align-items: flex-start; gap: 8px; margin-top: 18px; font-size: var(--sf-fs-small); color: var(--sf-fg-body); }
.split-hero__proof .sf-icon { flex: none; width: 18px; height: 18px; margin-top: 1px; color: var(--sf-fg-accent); }

/* The stack: glass cards at different depths. Each page places its own layers (.stack__layer--*).
   Each layer moves with the pointer by its data-sf-depth and bobs slowly. Illustrations only, never real client data. */
.split-hero__visual { position: relative; perspective: 1400px; }
.split-hero__visual::before { content: ""; position: absolute; inset: 6% 0; z-index: -1; border-radius: 50%; background: radial-gradient(closest-side, rgba(140, 77, 255, 0.28), rgba(70, 119, 255, 0.08) 60%, transparent); }
.stack { position: relative; width: min(460px, 100%); aspect-ratio: 1 / 0.96; margin-inline: auto; transform: rotateY(-16deg) rotateX(8deg); transform-style: preserve-3d; }
@media (max-width: 1023px) { .stack { width: min(400px, 100%); transform: rotateY(-8deg) rotateX(6deg); } }
.stack__layer { position: absolute; transform-style: preserve-3d; }
/* One-column hero (below 1024px): the stack sits under the copy, so the hero's scroll parallax (sarafi.js, measured from the top
   of the page) has already built up by the time the stack comes into view and would squeeze its cards together over their text.
   The layers stay where each page lays them out; the aurora behind keeps its parallax. */
@media (max-width: 1023px) { .stack__layer { translate: none !important; } }
.stack__card { padding: 16px 18px; border: 1px solid rgba(255, 255, 255, 0.12); border-radius: var(--sf-radius-md); color: var(--sf-white);
  background: linear-gradient(160deg, rgba(27, 34, 66, 0.86), rgba(14, 18, 36, 0.82)); -webkit-backdrop-filter: blur(14px); backdrop-filter: blur(14px);
  box-shadow: 0 32px 64px -28px rgba(0, 0, 0, 0.65), inset 0 1px 0 rgba(255, 255, 255, 0.07); animation: stack-bob 8s ease-in-out infinite; }
@keyframes stack-bob { 0%, 100% { translate: 0 0; } 50% { translate: 0 -8px; } }
.split-hero.is-offscreen .stack__card { animation-play-state: paused; }
/* The cards and the placeholder labels are light text on their own dark fill. Printers drop backgrounds by default,
   which would leave pale text on white paper, so these print their fill (as dark screens, which is what they show). */
@media print { .stack__card, .art__tag { print-color-adjust: exact; -webkit-print-color-adjust: exact; } }
/* Light theme: the cards are pictures of screens, so they stay dark, as solid Midnight instead of see-through slate,
   on the level-3 shadow (the portrait card on About and the plates on the services hub follow the same rule). */
:root[data-theme="light"] .stack__card { background: linear-gradient(160deg, #1A2142 0%, #0D1122 100%); border-color: rgba(255, 255, 255, 0.08);
  -webkit-backdrop-filter: none; backdrop-filter: none; box-shadow: var(--sf-shadow-3), inset 0 1px 0 rgba(255, 255, 255, 0.06); }

/* ---------- Platform and tool tiles ---------- */
/* Platforms we work with: the same tile as the client logos, eight across on wide screens.
   The marks are drawn in the text colour with a CSS mask, so every brand sits in one quiet tone and brightens on hover. */
.platforms { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 12px; margin: 16px 0 0; padding: 0; list-style: none; }
@media (min-width: 768px) { .platforms { grid-template-columns: repeat(4, minmax(0, 1fr)); } }
@media (min-width: 1200px) { .platforms { grid-template-columns: repeat(8, minmax(0, 1fr)); } }
.platform { gap: 10px; padding-inline: 12px; color: color-mix(in srgb, var(--sf-fg) 78%, transparent); font-size: 0.9375rem; font-weight: var(--sf-fw-semibold); letter-spacing: -0.01em; white-space: nowrap; }
.platform:hover { color: var(--sf-fg); border-color: var(--sf-border-strong); }
.platform__icon { flex: none; width: 22px; height: 22px; background-color: currentColor; -webkit-mask: var(--icon) center / contain no-repeat; mask: var(--icon) center / contain no-repeat; }
/* Light theme: platforms (home) and tools (service pages) are an unboxed monochrome row between two hairlines, set
   like press logos, in muted ink that turns Midnight on hover. */
:root[data-theme="light"] :is(.platforms, .tools) { box-shadow: inset 0 1px 0 var(--sf-hairline), inset 0 -1px 0 var(--sf-hairline); }
:root[data-theme="light"] .platform { border-color: transparent; color: var(--sf-ink-muted); }
:root[data-theme="light"] .platform:hover { border-color: transparent; color: var(--sf-fg); }
/* Phones: a ruled list, not four rows of boxes; rows are 52px instead of 72px tiles. */
@media (max-width: 767px) {
  :root[data-theme="light"] :is(.platforms, .tools) { gap: 0; box-shadow: inset 0 1px 0 var(--sf-hairline); }
  :root[data-theme="light"] .platform { height: 52px; border: 0; border-radius: 0; box-shadow: inset 0 -1px 0 var(--sf-hairline); }
}

/* ---------- Case study card ---------- */
.case .sf-card__media { aspect-ratio: 16 / 10; }
/* Side by side, the shorter card grows its image so both cards end together without a gap. */
@media (min-width: 1024px) {
  .case { display: flex; flex-direction: column; }
  .case .sf-card__media { flex: 1 0 auto; }
}
.case__title { margin-top: 8px; font-size: var(--sf-fs-h3); line-height: var(--sf-lh-h3); font-weight: var(--sf-fw-semibold); letter-spacing: -0.01em; }
.case__metrics { display: flex; flex-wrap: wrap; gap: 20px 36px; margin-top: 20px; }
.case__metrics .sf-stat__value { font-size: clamp(1.75rem, 1.4rem + 1.2vw, 2.5rem); }
.case .sf-cluster { --sf-cluster-gap: 6px; margin-top: 20px; }

/* ---------- Next case study: one wide card (case study, thank-you) ---------- */
.next-case { display: grid; grid-template-columns: minmax(0, 1fr); gap: 28px; align-items: center; text-decoration: none; color: inherit; }
@media (min-width: 768px) { .next-case { grid-template-columns: minmax(0, 5fr) minmax(0, 7fr); gap: 48px; } }
.next-case__title { margin-top: 12px; font-size: var(--sf-fs-h2); line-height: var(--sf-lh-h2); font-weight: var(--sf-fw-bold); letter-spacing: -0.02em; }
.next-case__text { margin-top: 12px; color: var(--sf-fg-body); }
.next-case .sf-link-arrow { margin-top: 24px; }
.next-case__media { aspect-ratio: 16 / 9; margin: 0; border-radius: var(--sf-radius-sm); }
@media (min-width: 768px) { .next-case__media { order: 2; } }

/* ---------- Steps ---------- */
.steps { list-style: none; padding: 0; position: relative; display: grid; grid-template-columns: minmax(0, 1fr); gap: 14px; margin-top: clamp(40px, 5vw, 64px); }
@media (min-width: 768px) { .steps { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (min-width: 1024px) { .steps { grid-template-columns: repeat(4, minmax(0, 1fr)); } }
.step__top { display: flex; align-items: center; justify-content: space-between; }
.step__n { font: 600 0.8125rem/1 var(--sf-font-sans); letter-spacing: .1em; color: var(--sf-fg-muted); }
.step__title { margin-top: 20px; font-size: 1.25rem; font-weight: var(--sf-fw-bold); }
.step__text { margin-top: 8px; color: var(--sf-fg-body); }
/* Print: Chrome moves a grid that does not fit to the next page whole, which left its heading alone on a nearly empty
   page. A flex column breaks between the steps instead and keeps each step whole (growth-review.css does the same). */
@media print { .steps { display: flex; flex-direction: column; } }

/* ---------- Checklist ---------- */
.checklist { display: grid; gap: 14px; margin: 26px 0 0; padding: 0; list-style: none; font-size: var(--sf-fs-body-lg); }
.checklist li { display: flex; align-items: flex-start; gap: 12px; }
.checklist .sf-icon { flex: none; width: 20px; height: 20px; margin-top: 4px; color: var(--sf-fg-accent); }

/* ---------- Sample report: a raised sheet for illustrative report layouts (labels and shapes only, no numbers) ---------- */
.report { position: relative; padding: clamp(18px, 3vw, 28px); border: 1px solid var(--sf-border); border-radius: var(--sf-radius-md); background: var(--sf-bg-raised); box-shadow: 0 40px 80px -44px rgba(9, 11, 20, 0.4); }
/* Light theme: a sample sheet is a raised sheet, on the level-3 shadow. */
:root[data-theme="light"] .report { box-shadow: var(--sf-shadow-3); }
/* Print flattens the soft shadow into a solid grey slab, so paper gets the border only (the light guard is at the end). */
@media print { .report { box-shadow: none; } }
.report__head { display: flex; align-items: center; justify-content: space-between; gap: 12px; }
.report__title { font-size: 1.125rem; font-weight: var(--sf-fw-bold); }
.report__tag { left: auto; right: 14px; bottom: auto; top: -12px; }

/* ---------- Quote card ---------- */
.quote-card { display: flex; flex-direction: column; justify-content: space-between; gap: 28px; }
.quote-card .sf-quote__text { font-size: clamp(1.375rem, 1.2rem + 0.6vw, 1.75rem); }
.quote-mark { display: block; height: 0.5em; font: 400 6rem/1 var(--sf-font-serif); color: var(--sf-fg-accent); opacity: 0.6; }
/* Light theme: at 0.6 the decorative mark was 2.4:1; at 0.85 it reaches about 4:1. */
:root[data-theme="light"] .quote-mark { opacity: 0.85; }
/* A single testimonial on its own dark band, centred and large. */
.quote-feature { max-width: 900px; margin: 0 auto; text-align: center; }
.quote-feature .sf-quote__text { font-size: clamp(1.75rem, 1.3rem + 1.8vw, 3rem); line-height: 1.15; }
.quote-feature .quote-mark { margin-bottom: 14px; }
.quote-feature .sf-quote__cite { justify-content: center; text-align: left; margin-top: 32px; }

/* ---------- Best for, and not for ---------- */
.fit-cards { display: grid; grid-template-columns: minmax(0, 1fr); gap: 16px; }
@media (min-width: 768px) { .fit-cards { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
.fit-card__head { display: flex; align-items: center; gap: 10px; }
.fit-card__head .sf-icon { width: 22px; height: 22px; }
.fit-card--yes .fit-card__head .sf-icon { color: var(--sf-fg-accent); }
.fit-card--no .fit-card__head .sf-icon { color: var(--sf-fg-muted); }
.fit-card__text { margin-top: 16px; font-size: clamp(1.125rem, 1rem + 0.4vw, 1.375rem); font-weight: var(--sf-fw-semibold); line-height: 1.4; }

/* ---------- FAQ ---------- */
.faq__aside .sf-lead { margin-top: 18px; }
.faq__aside .sf-link-arrow { margin-top: 24px; }

/* ---------- Final CTA ---------- */
.final { position: relative; isolation: isolate; overflow: hidden; text-align: center; }
.final::before { content: ""; position: absolute; left: 50%; top: 50%; z-index: -2; width: min(1100px, 140vw); height: 620px; transform: translate(-50%, -50%); background: radial-gradient(closest-side, rgba(140, 77, 255, 0.26), rgba(70, 119, 255, 0.10) 55%, transparent); }
.final__symbol { position: absolute; right: -6%; top: 50%; z-index: -1; width: min(560px, 80vw); height: auto; transform: translateY(-50%); overflow: visible; }
.final__bg { position: absolute; inset: 0; z-index: -3; overflow: hidden; pointer-events: none; }
.final__blob { position: absolute; border-radius: 50%; mix-blend-mode: screen; filter: blur(48px); will-change: transform; animation-timing-function: ease-in-out; animation-iteration-count: infinite; animation-direction: alternate; }
.final__blob--blue { left: -14%; bottom: -34%; width: 44vmax; aspect-ratio: 1.3; background: radial-gradient(closest-side, rgba(70, 119, 255, 0.42), rgba(70, 119, 255, 0)); animation-name: final-drift-a; animation-duration: 27s; }
.final__blob--purple { right: -12%; top: -34%; width: 40vmax; aspect-ratio: 1.1; background: radial-gradient(closest-side, rgba(140, 77, 255, 0.46), rgba(140, 77, 255, 0)); animation-name: final-drift-b; animation-duration: 33s; }
@keyframes final-drift-a { from { transform: translate3d(0, 0, 0) scale(1); } to { transform: translate3d(8vmax, -5vmax, 0) scale(1.12); } }
@keyframes final-drift-b { from { transform: translate3d(0, 0, 0) scale(1); } to { transform: translate3d(-8vmax, 5vmax, 0) scale(1.1); } }
.final.is-offscreen .final__blob { animation-play-state: paused; }
.final__symbol { color: var(--sf-fg); }
.final__symbol path { fill: none; stroke: color-mix(in srgb, currentColor 7%, transparent); stroke-width: 1.5px; vector-effect: non-scaling-stroke; }
.final .sf-h1 { max-width: 16ch; margin-inline: auto; }
/* The serif answer starts its own line, so "It" never hangs at the end of the first sentence. */
.final .sf-h1 .sf-serif { display: block; }
.final .sf-lead { margin: 22px auto 0; }
.final .sf-cluster { justify-content: center; margin-top: 36px; }
@media (max-width: 559px) { .final .sf-cluster .sf-btn { flex: 1 1 100%; min-width: 0; white-space: normal; text-align: center; line-height: 1.25; padding-block: 10px; } }

/* ---------- 3D motion shared by the sections ---------- */
/* Pictures inside cards drift a little slower than the page, like a view through a window. Scaled up so no edge shows. */
.art[data-sf-depth] { scale: 1.16; }
/* The placeholder label moves in by the scaled-off margin (about 7% each side) and scales back to its normal size. */
.art[data-sf-depth] .art__tag { left: calc(7% + 12px); bottom: calc(7% + 12px); scale: 0.86; transform-origin: 0 100%; }
/* Dark sections: a soft light follows the pointer (sarafi.js sets --sf-mx, --sf-my and .is-pointer on the scene).
   It sits behind the cards, so text on them keeps its contrast. */
.spotlight { position: relative; isolation: isolate; }
.spotlight::after { content: ""; position: absolute; inset: 0; z-index: -1; pointer-events: none; opacity: 0; transition: opacity 600ms var(--sf-ease-out);
  background: radial-gradient(640px circle at var(--sf-mx, 50%) var(--sf-my, 50%), rgba(140, 77, 255, 0.08), transparent 62%); }
.spotlight.is-pointer::after { opacity: 1; }

/* ---------- Footer ---------- */
.news { margin-top: 28px; max-width: 360px; }
/* The field keeps room for the whole placeholder: on a narrow row, Subscribe drops underneath. */
.news__row { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 10px; }
.news__row .sf-input { flex: 1 1 190px; min-width: 0; min-height: 44px; }
/* The newsletter forms' spam trap: off screen, so people never see it but simple bots fill it in. */
.hp-field { position: absolute; left: -9999px; width: 1px; height: 1px; overflow: hidden; }
.newsletter__form { position: relative; }
.newsletter__form [data-sf-news-status] { flex-basis: 100%; margin-top: 4px; }
/* A sign-up form does nothing on paper, and without it the footer's last line no longer spills onto a page of its own. */
@media print { .news { display: none; } }
/* Social profiles: round icon buttons in the site's own line-icon style; brand gradient on hover. */
.footer-social { display: flex; flex-wrap: wrap; gap: 8px; margin: 0; padding: 0; list-style: none; }
.footer-social .footer-social__link { display: grid; place-items: center; width: 40px; height: 40px; min-height: 0; border-radius: 50%;
  border: 1px solid color-mix(in srgb, var(--sf-fg) 16%, transparent); background: color-mix(in srgb, var(--sf-fg) 4%, transparent); color: var(--sf-fg);
  transition: background-color var(--sf-dur-base) var(--sf-ease-out), border-color var(--sf-dur-base) var(--sf-ease-out), color var(--sf-dur-fast) var(--sf-ease-out), transform var(--sf-dur-base) var(--sf-ease-out), box-shadow var(--sf-dur-base) var(--sf-ease-out); }
.footer-social__link .sf-icon { width: 18px; height: 18px; stroke-width: 1.75; }
.footer-social .footer-social__link:hover { border-color: transparent; background: var(--sf-gradient-brand); color: #FFFFFF; box-shadow: 0 10px 24px -10px rgba(140, 77, 255, 0.7); }
@media (prefers-reduced-motion: no-preference) { .footer-social .footer-social__link:hover { transform: translateY(-2px); } }
.footer-social__link:focus-visible { outline: 2px solid var(--sf-focus); outline-offset: 3px; }
@media (min-width: 768px) { .sf-footer__legal .footer-social { margin-left: auto; } }
@media (max-width: 767px) { .sf-footer__legal .footer-social { flex-basis: 100%; margin-top: 12px; } }

/* ---------- Light theme ("Paper, Cloud and Mist") ----------
   The surface tokens flip in tokens.css: paper for the chrome that is dark by default, Cloud for .sf-light, Mist for
   the Midnight feature bands, and the dark tokens restored inside the final box and the one chapter band (.sf-band).
   Here the pieces with their own colours follow. Illustration cards stay dark on purpose: they are screens and
   mockups, and read as images in both themes. */
/* The hero scrim turns into white "studio light". It is hidden on every .page-hero below; this only covers custom heroes. */
:root[data-theme="light"] { --sf-scrim: 255 255 255; --sf-scrim-k: 1.2; --sf-glass-hover: 247 248 252; }

/* Rhythm: a 1px hairline where two bands are close in tone (inset shadows, so nothing moves).
   Paper after paper, Cloud against Mist (1.04:1 apart), and a hero that runs straight into a paper section.
   The Midnight chapter band (.sf-band, below) has no seam on either side: the value change is the edge. */
:root[data-theme="light"] section.sf-white + section.sf-white:not(.hub-measure),
:root[data-theme="light"] .sf-light + .sf-section.sf-dark:not(.final, .sf-band),
:root[data-theme="light"] .sf-section.sf-dark:not(.final, .sf-band) + .sf-light,
:root[data-theme="light"] .page-hero + .sf-white { box-shadow: inset 0 1px 0 var(--sf-hairline); }

/* One Midnight chapter band per long page (.sf-band: home How we work, every service page's How it works, Growth
   Review Two ways to start, About Mission, Approach Process, case study What we built). A long white run breaks once,
   with Sarafi's own Midnight and Deep Blue: tokens.css gives it the Sarafi Box's token row and keeps the cards on it
   paper; here it takes its light (--sf-band: Growth Purple from the top right, Electric Blue from the lower left).
   Full-bleed, square, hard straight edges. Cards on the band are sheets on a stage: a soft drop shadow, black on
   purpose (a Midnight tint would not show on Midnight), and no hairline (the featured card keeps its gradient edge). */
:root[data-theme="light"] .sf-section.sf-dark.sf-band:not(.final) { background-image: var(--sf-band); }
:root[data-theme="light"] .sf-section.sf-dark.sf-band:not(.final) .sf-card:not(.sf-card--outline) { box-shadow: 0 24px 48px -24px rgb(0 0 0 / 0.55); }
:root[data-theme="light"] .sf-section.sf-dark.sf-band:not(.final) .sf-card:not(.sf-card--outline, .sf-card--featured) { border-color: transparent; }
/* The brand moment, for a page with no band (the services hub's "Start with a growth review", .sf-moment): visible
   corner light in the brand pair on its Mist, the copy in the calm middle, the featured card as the white sheet on it.
   Phones get corner-sized light, so it stays in the corners of the tall section. */
:root[data-theme="light"] .sf-section.sf-dark.sf-moment:not(.final) { background-image: var(--sf-moment); }
@media (max-width: 767px) {
  :root[data-theme="light"] .sf-section.sf-dark.sf-moment:not(.final) {
    background-image: radial-gradient(95% 22% at 0% 0%, rgb(70 119 255 / 0.18), rgb(70 119 255 / 0) 70%),
      radial-gradient(95% 22% at 100% 100%, rgb(140 77 255 / 0.22), rgb(140 77 255 / 0) 70%);
  }
}

/* Heroes: paper and one whisper glow (--sf-ambient: Electric Blue from the top left, Growth Purple from the top right),
   with no aurora and no scrim, so no lilac fog sits behind the copy. The grid lines and grain turn dark and faint. */
:root[data-theme="light"] .page-hero { background-image: var(--sf-ambient); }
:root[data-theme="light"] .page-hero :is(.hero__aurora, .hero__scrim) { display: none; }
:root[data-theme="light"] .hero__grid { background-image: linear-gradient(rgba(17, 23, 42, 0.045) 1px, transparent 1px), linear-gradient(90deg, rgba(17, 23, 42, 0.045) 1px, transparent 1px); }
:root[data-theme="light"] .hero__grain { opacity: 0.025; }
:root[data-theme="light"] .split-hero__visual::before { background: radial-gradient(closest-side, rgba(140, 77, 255, 0.14), rgba(70, 119, 255, 0.07) 58%, transparent); }

/* Eyebrows that sit outside an .sf-section (the home trust strip titles, the service pages' tools band) take the
   section eyebrows' short Electric Blue dash from sarafi.css. */
:root[data-theme="light"] :is(.trust__title, .tools-band .sf-eyebrow) { letter-spacing: 0.14em; }
:root[data-theme="light"] :is(.trust__title, .tools-band .sf-eyebrow)::before {
  content: ""; display: inline-block; width: 18px; height: 2px; margin: 0 10px 0 0; vertical-align: 0.28em;
  border-radius: 2px; background: var(--sf-electric-blue);
}

/* Placeholder art in the light theme: brand-lit stand-ins until the photography brief is shot. Project and article art
   is a blue-to-lavender duotone lit in purple, with a hairline edge, so it reads as a brand-lit picture, not a grey
   wireframe (grey-on-grey is a brand-book don't). */
:root[data-theme="light"] :is(.art, .art--light) {
  background: linear-gradient(150deg, color-mix(in srgb, var(--sf-electric-blue) 18%, var(--sf-white)) 0%,
    color-mix(in srgb, var(--sf-growth-purple) 12%, var(--sf-white)) 52%, color-mix(in srgb, var(--sf-growth-purple) 4%, var(--sf-white)) 100%);
  box-shadow: inset 0 0 0 1px rgba(17, 23, 42, 0.05);
}
:root[data-theme="light"] :is(.art, .art--light)::before { background-image: linear-gradient(rgba(17, 23, 42, 0.05) 1px, transparent 1px), linear-gradient(90deg, rgba(17, 23, 42, 0.05) 1px, transparent 1px); }
:root[data-theme="light"] .art::after { background: radial-gradient(closest-side, rgb(140 77 255 / 0.30), rgb(70 119 255 / 0.10) 60%, transparent); }
/* Portraits: the brand book's navy-purple monochrome, backlit in purple, with a glass label. */
:root[data-theme="light"] .art--mono {
  background: linear-gradient(160deg, color-mix(in srgb, var(--sf-growth-purple) 30%, var(--sf-deep-blue)) 0%,
    color-mix(in srgb, var(--sf-growth-purple) 14%, var(--sf-deep-blue)) 55%, var(--sf-deep-blue) 100%);
  box-shadow: none;
}
:root[data-theme="light"] .art--mono::before { background-image: linear-gradient(rgba(255, 255, 255, 0.045) 1px, transparent 1px), linear-gradient(90deg, rgba(255, 255, 255, 0.045) 1px, transparent 1px); }
:root[data-theme="light"] .art--mono::after { background: radial-gradient(closest-side, rgb(140 77 255 / 0.50), rgb(70 119 255 / 0.14) 60%, transparent); }
:root[data-theme="light"] .art--mono .art__tag { background: rgba(255, 255, 255, 0.14); }
/* Dark theme: light placeholder pictures switch to the dark placeholder, so they sit quietly on the dark sections. */
:root[data-theme="dark"] .art--light { background: linear-gradient(135deg, #1B2242 0%, #0E1224 70%); }
:root[data-theme="dark"] .art--light::before { background-image: linear-gradient(rgba(255,255,255,.05) 1px, transparent 1px), linear-gradient(90deg, rgba(255,255,255,.05) 1px, transparent 1px); }
:root[data-theme="dark"] .art--light::after { background: radial-gradient(closest-side, rgba(140,77,255,.45), transparent); }
/* A frame that holds a picture (.art--pic) is the same Midnight panel in both themes: the pictures are drawn for it,
   like the navy product cards in the light theme's heroes. */
:root[data-theme="light"] .art--pic { background: linear-gradient(135deg, #1B2242 0%, #0E1224 70%); border: 0; box-shadow: none; }
:root[data-theme="light"] .art--pic::before { background-image: linear-gradient(rgba(255,255,255,.05) 1px, transparent 1px), linear-gradient(90deg, rgba(255,255,255,.05) 1px, transparent 1px); }
:root[data-theme="light"] .art--pic::after { background: radial-gradient(closest-side, rgba(140,77,255,.45), transparent); }

/* The final CTA stays the one Midnight "Sarafi Box": tokens.css restores the dark theme's tokens inside it, so its
   glows, blobs (screen blend) and line art keep their dark-theme strength. Tablet and desktop: an inset box aligned
   to the content edges. Phones keep a full-bleed band, so the headline keeps its measure. */
@media (min-width: 768px) {
  :root[data-theme="light"] .final.sf-dark {
    margin: clamp(48px, 6vw, 88px) max(var(--sf-gutter-md), calc((100% - var(--sf-container)) / 2));
    border-radius: var(--sf-radius-md);
    box-shadow: 0 2px 6px rgba(9, 11, 20, 0.06), 0 32px 64px -36px rgba(9, 11, 20, 0.45);
  }
}
/* Inside the box, gradient text goes back to the brand pair (the on-light pair is for light surfaces only). */
:root[data-theme="light"] .final :is(.sf-gradient-text, .sf-stat__value--gradient) { background-image: var(--sf-gradient-brand); }
/* Outline buttons inside the box go back to the dark outline (the light paper-button rule in sarafi.css matches every
   secondary button). */
:root[data-theme="light"] .final :is(.sf-btn--secondary, .sf-btn--whatsapp) { background-color: transparent; border-color: var(--sf-border-strong); box-shadow: none; }
:root[data-theme="light"] .final :is(.sf-btn--secondary, .sf-btn--whatsapp):hover { background-color: var(--sf-hover); border-color: rgba(255, 255, 255, 0.5); }
:root[data-theme="light"] .final .sf-btn--primary { box-shadow: 0 12px 28px -12px rgba(140, 77, 255, 0.7); }

/* Footer: its own closing band. Mist with a hairline top (its --sf-border on paper, also under the Sarafi Box),
   Midnight column heads and ink links at full strength: the page ends on a base. */
:root[data-theme="light"] .site-footer { --sf-bg: var(--sf-mist); }
:root[data-theme="light"] .sf-footer__title { color: var(--sf-fg); }
:root[data-theme="light"] .sf-footer__list a { color: var(--sf-fg-body); opacity: 1; }
:root[data-theme="light"] .sf-footer__list a:hover { color: var(--sf-fg); }
:root[data-theme="light"] .footer-social .footer-social__link { border-color: var(--sf-hairline); background: var(--sf-white); color: var(--sf-fg-body); }
:root[data-theme="light"] .footer-social .footer-social__link:hover { border-color: transparent; background: var(--sf-gradient-brand); color: #FFFFFF; }

/* Print: sarafi.js prints in the light theme, with background graphics off by default. The Midnight box goes back to a
   paper surface (tokens.css swaps its tokens back to paper; here the box shape and art go), and the light-only shadows
   (which outrank the plain print resets) are removed. */
@media print {
  :root[data-theme="light"] .final.sf-dark { margin: 0; border-radius: 0; box-shadow: none; }
  :root[data-theme="light"] .final :is(.final__bg, .final__symbol) { display: none; }
  :root[data-theme="light"] .final::before { display: none; }
  :root[data-theme="light"] .report { box-shadow: none; }
  /* !important: the seam rules above reach 0,5,2. */
  :root[data-theme="light"] :is(.stack__card, section) { box-shadow: none !important; }
  /* The band and the brand moment go back to paper (tokens.css swaps the band's tokens), so the band's cards get
     their hairline back, and the portrait label keeps a dark plate. */
  :root[data-theme="light"] .sf-section.sf-dark.sf-band:not(.final) { background-image: none; }
  :root[data-theme="light"] .sf-section.sf-dark.sf-band:not(.final) .sf-card:not(.sf-card--outline, .sf-card--featured) { border-color: var(--sf-hairline); }
  :root[data-theme="light"] .sf-section.sf-dark.sf-moment:not(.final) { background-image: none; }
  :root[data-theme="light"] .art--mono .art__tag { background: rgba(9, 11, 20, 0.72); }
}
