/* Cult Media, code we own.
   Framer drove its tickers from JavaScript. That JS is gone, so this file
   reimplements the two marquees in CSS. tools/snapshot.mjs duplicates each
   track exactly once, so translating by half its width loops seamlessly. */

.cm-marquee-wrap{
  overflow:hidden;
  /* fade the edges rather than cutting hard */
  -webkit-mask-image:linear-gradient(90deg,transparent,#000 6%,#000 94%,transparent);
          mask-image:linear-gradient(90deg,transparent,#000 6%,#000 94%,transparent);
}
.cm-marquee{
  display:flex;
  width:max-content!important;
  /* Framer also pins the track to max-width:100% inline, which capped the reel
     at its wrap's width while its cards ran eight times wider, so the loop
     travelled 580px and snapped. The track must be as wide as its contents. */
  max-width:none!important;
  /* Framer's ticker centres its row and lets the runtime reposition it every
     frame. Frozen, that left the first half of the track empty, so no logo was
     ever inside the viewport. Pack the items from the left. */
  justify-content:flex-start!important;
  padding:0!important;
  margin:0!important;
  animation:cm-scroll var(--cm-duration,48s) linear infinite;
  will-change:transform;
}
.cm-marquee > *{margin-left:0!important}
/* Each ticker item was captured with the inline translateX Framer's runtime
   was advancing every frame (3839px at the moment of capture), which pushed
   the whole row out of every viewport. The animation lives on the track, not
   the items, so the items need no transform at all. */
.cm-marquee > *{transform:none!important}
.cm-marquee-wrap:hover .cm-marquee{animation-play-state:paused}
@keyframes cm-scroll{
  from{transform:translate3d(0,0,0)}
  to{transform:translate3d(-50%,0,0)}
}

/* the logo row runs a little quicker than the card reel */
[data-framer-name="List"] .cm-marquee{--cm-duration:40s}

@media (prefers-reduced-motion:reduce){
  .cm-marquee{animation:none}
  .cm-marquee-wrap{overflow-x:auto;-webkit-overflow-scrolling:touch}
}

/* One client logo has only a 236px master on Framer's CDN, so the design's
   52px row stretches it to 267px. Cap it at native size: slightly smaller than
   its neighbours, but sharp. Replace the file and this rule can go. */
.cm-marquee img[src*="image-5b85e9bd"]{max-width:236px}

/* Touch targets.
   Framer's header and footer links render 17-32px tall, under the 44px minimum
   for a standalone control on a phone. There is no <nav> or <footer> to hook,
   and Framer wraps link text in divs, so the rule is a plain min-height on
   every link with prose links exempted (WCAG 2.5.5 exempts a link inside a
   block of text). min-height only ever raises, so nothing shrinks. */
@media (max-width:900px){
  a{min-height:44px}
  p a, li a, blockquote a, .framer-text a{min-height:0}
}

/* ── Booking modal ─────────────────────────────────────────────────────
   Replaces Framer's overlay component. Measured off the live site: white
   full-screen sheet, 1240px inner, 80px top padding, dark 1200x576 form panel,
   blue circular close button top-right. */
.cm-cta{cursor:pointer}
.cm-modal{
  position:fixed;inset:0;z-index:9999;display:none;
  background:#fff;overflow-y:auto;-webkit-overflow-scrolling:touch;
}
.cm-modal.is-open{display:block}
html.cm-modal-open{overflow:hidden}
.cm-modal__inner{
  max-width:1240px;margin:0 auto;padding:80px 20px 40px;text-align:center;
}
.cm-modal__title{
  font-family:Montserrat,"Montserrat Placeholder",sans-serif;font-weight:600;
  font-size:clamp(32px,2.2rem + 1.4vw,50px);letter-spacing:-1.1px;line-height:1.2;
  color:#282c5e;margin:0 0 .5rem;
}
.cm-modal__sub{
  font-family:Montserrat,"Montserrat Placeholder",sans-serif;font-weight:500;
  font-size:20px;color:#282c5e;margin:0 0 2rem;
}
.cm-modal__form{
  background:#111827;min-height:576px;width:100%;
  display:flex;align-items:stretch;justify-content:center;
}
.cm-modal__form > div{width:100%;min-height:576px}
.cm-modal__close{
  position:fixed;top:80px;right:40px;z-index:1;
  width:32px;height:32px;border-radius:50%;border:0;padding:0;
  background:#15aaff;display:grid;place-items:center;cursor:pointer;
}
.cm-modal__close:hover{background:#0b7fc4}
.cm-modal__close:focus-visible{outline:2px solid #05153d;outline-offset:3px}
@media (max-width:760px){
  .cm-modal__inner{padding:64px 12px 24px}
  .cm-modal__close{top:16px;right:16px;width:40px;height:40px}
  .cm-modal__form{min-height:520px}
}

/* Homepage "How We'd Grow You" card labels on phones.
   Framer positions each label absolutely at a different hard-coded left
   (151px, 195px…) that only lines up at desktop card widths; on a phone the
   labels wander and can clip. Centre every label under its card instead. The
   class is this component's instance name in the captured homepage; if the
   homepage is ever re-captured with a different one, this rule stops matching. */
@media (max-width:809.98px){
  .framer-awav4i-container{left:50%!important;right:auto!important;transform:translateX(-50%)!important;max-width:calc(100% - 16px)!important}
}

/* ── Mobile header ──────────────────────────────────────────────────────
   The capture was taken at desktop width after Framer's runtime had removed
   the phone-breakpoint variants from the DOM, so below 810px the page had no
   header at all once the desktop one was correctly hidden. This is ours: the
   same white pill, the logo, and a disclosure menu that needs no script.
   Framer's own header fits down to 600px (it clips at 560), so it is shown
   that far and this one takes over below, with the booking button kept
   beside the menu so the primary action never hides behind a tap. */
.cm-mobile{display:none}
@media (min-width:600px) and (max-width:809.98px){
  div.ssr-variant:has(> .framer-9jk72q-container){display:contents!important}
}
@media (max-width:599.98px){
  .cm-mobile{
    display:flex;align-items:center;justify-content:space-between;
    position:fixed;top:12px;left:12px;right:12px;z-index:60;
    height:64px;padding:0 10px 0 16px;border-radius:40px;background:#fff;
    box-shadow:0 2px 12px rgba(5,21,61,.08);
    font-family:Inter,-apple-system,system-ui,sans-serif;
  }
  .cm-mobile__logo{display:flex;align-items:center;min-height:44px}
  .cm-mobile__logo img{width:36px;height:36px}
  .cm-mobile__right{display:flex;align-items:center;gap:4px}
  .cm-mobile__book{
    min-height:44px;padding:0 16px;border:0;border-radius:40px;background:#05153d;color:#fff;
    font:600 13px/1 Montserrat,"Montserrat Placeholder",sans-serif;cursor:pointer;white-space:nowrap;
  }
  .cm-mobile__book:hover{background:#0a2560}
  .cm-mobile details{position:relative}
  .cm-mobile summary{
    list-style:none;cursor:pointer;width:44px;height:44px;border-radius:50%;
    display:grid;place-items:center;
  }
  .cm-mobile summary::-webkit-details-marker{display:none}
  .cm-mobile summary:hover,.cm-mobile details[open] summary{background:rgba(5,21,61,.06)}
  .cm-mobile__bars,.cm-mobile__bars::before,.cm-mobile__bars::after{
    content:"";display:block;width:18px;height:2px;border-radius:2px;background:#05153d;
  }
  .cm-mobile__bars{position:relative}
  .cm-mobile__bars::before{position:absolute;top:-6px}
  .cm-mobile__bars::after{position:absolute;top:6px}
  .cm-mobile__panel{
    position:absolute;right:0;top:calc(100% + 14px);min-width:min(80vw,280px);
    display:flex;flex-direction:column;gap:2px;padding:8px;
    background:#fff;border-radius:18px;box-shadow:0 18px 44px rgba(5,21,61,.16);
  }
  .cm-mobile__panel a,.cm-mobile__panel button{
    display:flex;align-items:center;min-height:46px;padding:0 14px;border-radius:10px;border:0;
    background:none;font:500 16px/1 Inter,-apple-system,system-ui,sans-serif;letter-spacing:-.32px;
    color:#05153d;text-decoration:none;cursor:pointer;text-align:left;
  }
  .cm-mobile__panel a:hover,.cm-mobile__panel button:hover{background:#edf3ff}
  .cm-mobile__panel .cm-mobile__cta{
    margin-top:6px;justify-content:center;background:#05153d;color:#fff;border-radius:40px;min-height:50px;
    font-family:Montserrat,"Montserrat Placeholder",sans-serif;font-weight:600;font-size:15px;
  }
  .cm-mobile__panel .cm-mobile__cta:hover{background:#0a2560}
}
@media (max-width:809.98px){
  /* hero eyebrow: the desktop pill holds its text on one line, which does not
     fit a phone. Allowing it to wrap inside a content-sized flex item collapses
     the item to its longest word, so size the container to the unwrapped text,
     cap it at the viewport, and let the paragraph fill it: two lines at 12px. */
  [data-framer-name^="🚨 Stop Struggling"]{
    width:max-content!important;max-width:calc(100vw - 64px)!important;height:auto!important;
  }
  [data-framer-name^="🚨 Stop Struggling"] > *,
  [data-framer-name^="📈 Growth on Autopilot"]{width:100%!important;max-width:100%!important;min-width:0!important}
  [data-framer-name^="📈 Growth on Autopilot"] p{
    white-space:normal!important;width:100%!important;text-align:center;
    font-size:12px!important;line-height:1.35!important;
  }
}
}

/* ── FAQ accordion ──────────────────────────────────────────────────────
   Items are captured in Framer's "Closed" variant: a fixed-height clipped box
   with the answer inside. site.js toggles .cm-open; the height is released. */
[data-framer-name="Closed"] > [data-framer-name="Top"]{cursor:pointer}
/* The captured item is a fixed 400px, 68px box whose question cannot wrap, so
   on phones the text ran under the +/- icon and the icon left the viewport.
   Size it to its container, let the question wrap, and hide the answer while
   closed instead of relying on the clipped fixed height. */
[data-framer-name="Closed"]{height:auto!important;max-height:none!important}
[data-framer-name="Closed"]:not(.cm-open) > [data-framer-name="Answer"]{display:none}
.framer-c0mIJ.framer-1dxjmo4{width:100%!important;max-width:100%}
.framer-c0mIJ .framer-1h4koq7{white-space:normal!important;flex:1 1 auto!important;min-width:0;padding-right:8px}
[data-framer-name="Closed"].cm-open{height:auto!important;max-height:none!important;overflow:visible!important}
[data-framer-name="Closed"] > [data-framer-name="Top"] > :last-child{transition:transform .2s ease}
[data-framer-name="Closed"].cm-open > [data-framer-name="Top"] > :last-child{transform:rotate(45deg)}
/* Answer: Framer left-aligns it under a centered question with lopsided
   padding and text-wrap:balance, so the paragraph looks stuck to one side. */
.framer-c0mIJ .framer-f30hqa{padding:0 20px 16px!important;justify-content:center}
.framer-c0mIJ .framer-f30hqa .framer-17j7m1m{--framer-text-wrap-override:pretty;max-width:640px;margin:0 auto}
.framer-c0mIJ .framer-f30hqa p{text-align:center!important}

/* ── Mobile overrides inherited from the mirror ────────────────────────
   The mirror's process.mjs injected these into every page, and the capture
   carried them along. They live here now so they are versioned with the rest
   and so the capture can drop the injected copy. The preset rules were
   written for the prev/next article links, but the same text preset styles
   the footer links, and display:block plus wrapping inside a min-content flex
   column collapsed "Blogs" to one letter per line; they are scoped now. */
@media (max-width:400px){
  /* let the eyebrow wrap instead of overflowing its fixed-width frame */
  [class*="framer-"]{max-width:100%!important}
  h1,h2,h3,h4,p{overflow-wrap:break-word;word-break:normal}
  /* Framer pins some text nodes to a fixed width; release them */
  [data-framer-component-type="RichTextContainer"]{width:auto!important;max-width:100%!important}
}
@media (max-width:340px){ html{font-size:15px} }

/* The prev/next article links at the foot of an insight render wider than the
   viewport on phones and get pushed off-screen. Let them wrap in place. */
@media (max-width:900px){
  [data-framer-name="Previous"] [class*="framer-styles-preset-19xa6xm"],
  [data-framer-name="Next"] [class*="framer-styles-preset-19xa6xm"],
  [data-framer-name="Previous"] [class*="framer-styles-preset-37hchy"],
  [data-framer-name="Next"] [class*="framer-styles-preset-37hchy"]{
    max-width:100%!important;width:auto!important;
    white-space:normal!important;overflow-wrap:anywhere;
  }
  [data-framer-name="Previous"] [class*="framer-styles-preset-19xa6xm"],
  [data-framer-name="Next"] [class*="framer-styles-preset-19xa6xm"]{display:block!important}

  /* Framer lays the pair out as two full-width columns in a single-width flex
     row, so the first is pushed to a negative offset. data-framer-name is a
     stable hook; the generated class names are not. */
  div:has(> [data-framer-name="Previous"]),
  div:has(> [data-framer-name="Next"]){
    flex-direction:column!important;flex-wrap:wrap!important;align-items:stretch!important;
  }
  [data-framer-name="Previous"],
  [data-framer-name="Next"]{width:100%!important;max-width:100%!important;left:auto!important}
}

/* ── Offer split (dual-offer homepage) ─────────────────────────────────
   Two cards under the logo ticker: paid UGC creative for ecommerce/SaaS,
   organic creator distribution for funded B2C apps. Ours, not Framer's;
   colours and radii match the captured design tokens. */
.cm-offers{width:100%;padding:24px 20px 0;font-family:Montserrat,"Montserrat Placeholder",sans-serif;color:#282c5e}
.cm-offers__inner{max-width:1200px;margin:0 auto;display:flex;flex-direction:column;align-items:center;gap:32px}
.cm-offers__title{margin:0;text-align:center;font-weight:600;font-size:clamp(28px,1.6rem + 1.6vw,44px);line-height:1.15;letter-spacing:-.02em;color:#05153d;text-wrap:balance}
.cm-offers__accent{color:#15aaff}
.cm-offers__grid{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:24px;width:100%}
.cm-offer{
  display:flex;flex-direction:column;align-items:flex-start;gap:14px;
  padding:40px;border-radius:32px;background:#fff;border:1px solid rgba(5,21,61,.08);
  box-shadow:0 10px 40px rgba(5,21,61,.06);
}
.cm-offer--apps{background:#05153d;color:#dbe7ff;border-color:#05153d}
.cm-offer__for{margin:0;font-size:13px;font-weight:600;letter-spacing:.06em;text-transform:uppercase;color:#15aaff}
.cm-offer__title{margin:0;font-size:clamp(24px,1.2rem + 1vw,30px);font-weight:600;line-height:1.2;letter-spacing:-.01em;color:#05153d}
.cm-offer--apps .cm-offer__title{color:#fff}
.cm-offer__body{margin:0;font-size:16px;font-weight:500;line-height:1.6;color:#282c5e}
.cm-offer--apps .cm-offer__body{color:#dbe7ff}
.cm-offer__cta{
  margin-top:auto;padding-top:6px;
  display:inline-flex;align-items:center;gap:8px;min-height:48px;padding:0 24px;border:0;border-radius:40px;
  background:#05153d;color:#fff;font:600 15px/1 Montserrat,"Montserrat Placeholder",sans-serif;cursor:pointer;
  transition:background .15s ease,transform .15s ease;
}
.cm-offer__cta:hover{background:#0a2560;transform:translateY(-1px)}
.cm-offer--apps .cm-offer__cta{background:#15aaff;color:#05153d}
.cm-offer--apps .cm-offer__cta:hover{background:#3fbaff}
.cm-offer__cta:focus-visible{outline:2px solid #15aaff;outline-offset:3px}
@media (max-width:809.98px){
  .cm-offers__grid{grid-template-columns:1fr}
  .cm-offer{padding:28px 24px;border-radius:24px}
}

/* ── Logo wall + track record (from get.cultmedia.io) ──────────────────
   Replaces Framer's "Client Logos" ticker. The rows reuse .cm-marquee, so
   each track holds its cards twice for the -50% loop. */
.cm-logos{width:100%;padding:8px 0 0;font-family:Montserrat,"Montserrat Placeholder",sans-serif}
.cm-logos__inner{max-width:1200px;margin:0 auto;padding:0 20px;display:flex;flex-direction:column;gap:16px}
.cm-logos__head{margin:0 0 4px;text-align:center;font-size:12px;font-weight:600;letter-spacing:.16em;text-transform:uppercase;color:#282c5e;opacity:.75}
.cm-logos__row .cm-marquee{gap:16px;--cm-duration:40s}
.cm-logos__row--reverse .cm-marquee{animation-direction:reverse;--cm-duration:26s} /* shorter track, same ~40px/s */
.cm-brand{
  flex:0 0 auto;width:clamp(144px,16vw,192px);height:82px;margin:0;
  display:flex;align-items:center;justify-content:center;padding:14px 18px;
  background:rgba(255,255,255,.92);border:1px solid #d6e4fb;border-radius:16px;
  box-shadow:0 1px 2px rgba(5,21,61,.05),0 10px 26px rgba(83,124,188,.08);
}
.cm-brand img{max-width:100%;max-height:48px;width:auto;height:auto;object-fit:contain;filter:brightness(0) opacity(.78)}
.cm-brand--icon img{max-height:38px}
.cm-brand--tone img{filter:grayscale(1) opacity(.85)}
.cm-stats{display:grid;grid-template-columns:repeat(3,1fr);gap:16px;max-width:820px;margin:28px auto 0;padding:0;text-align:center}
.cm-stat{display:flex;flex-direction:column-reverse;gap:6px}
.cm-stat dd{margin:0;font-size:clamp(28px,1.5rem + 1.4vw,40px);font-weight:600;line-height:1.1;letter-spacing:-.02em;color:#05153d}
.cm-stat dt{font-size:11px;font-weight:600;letter-spacing:.13em;text-transform:uppercase;color:#282c5e;opacity:.75}
@media (max-width:600px){
  .cm-stats{grid-template-columns:1fr;gap:22px}
  .cm-stat dd{font-size:34px}
}

/* ── Call-to-action buttons ─────────────────────────────────────────────
   Framer fixed each button's wrapper at a desktop width (246px) while the
   label cannot wrap, so a slightly wider font rendering pushed the arrow over
   the last word on phones. Let the wrapper size to its content. */
.framer-rhrj7 .framer-10ir7ao-container,.framer-rhrj7 .framer-1geyiad-container{width:auto!important;max-width:100%}
.cm-cta{width:auto!important;max-width:100%}
.framer-C9Y1G .framer-qe2x7w{white-space:nowrap!important}
.framer-C9Y1G .framer-19y53jx{flex:none!important}
