/* ---------- BRAND FONTS -------------------------------------------------
   Alterglam (display) and Articulat CF (body) are licensed fonts. Drop the
   web files into assets/fonts/ and uncomment this block. See the README there.

@font-face{font-family:"Alterglam";src:url("fonts/alterglam.woff2") format("woff2");
  font-weight:400 900;font-display:swap}
@font-face{font-family:"Articulat CF";src:url("fonts/articulat-cf-regular.woff2") format("woff2");
  font-weight:400;font-display:swap}
@font-face{font-family:"Articulat CF";src:url("fonts/articulat-cf-medium.woff2") format("woff2");
  font-weight:500 600;font-display:swap}
@font-face{font-family:"Articulat CF";src:url("fonts/articulat-cf-bold.woff2") format("woff2");
  font-weight:700 900;font-display:swap}
------------------------------------------------------------------------- */

/* ==========================================================================
   SOSIYO — Motion & Interaction Layer
   Loaded on every page after the inline <style> block.
   1. Cursor normalisation (kills the I-beam "text" cursor site-wide)
   2. Ambient atmosphere (aurora, grain, beam)
   3. Scroll choreography
   4. Micro-interactions
   ========================================================================== */

/* ---------- 1. CURSOR NORMALISATION ------------------------------------- */
/* Text on this site is display copy, not editable content. The default arrow
   reads as "designed surface"; the I-beam reads as "document". */
body, body * { cursor: default; }

a, a *,
button, button *,
summary,
[role="button"], [role="button"] *,
.btn, .btn *,
.nav-cta, .nav-cta *,
.service, .service *,
.project, .project *,
.faq-item, .faq-item *,
.faq-q, .faq-q *,
.client-logo-card, .client-logo-card *,
.to-top { cursor: pointer; }

input, textarea, select { cursor: text; }
a[href^="tel:"], a[href^="mailto:"] { cursor: pointer; }

/* Nothing on the page should show a selection I-beam on decorative type */
/* Everything stays selectable. The arrow cursor is set above; that is what
   stops the I-beam appearing, not blocking selection. */
h1, h2, h3, h4, h5, h6, .display, .metric, .stat b {
  -webkit-user-select: text; user-select: text;
}
/* Only decorative counters and glyphs opt out — copying "01" or "+" is noise */
.eyebrow, .mini, .num, .plus, .scroll { -webkit-user-select: none; user-select: none; }

/* Body copy stays selectable — people do copy phone numbers and emails */
p, .copy, address, .contact-value { -webkit-user-select: text; user-select: text; }


/* ---------- 2. AMBIENT ATMOSPHERE --------------------------------------- */

/* Scroll progress — the brand gradient as a loading bar for the whole page */
.progress-bar{
  position:fixed; top:0; left:0; height:3px; width:100%;
  transform:scaleX(0); transform-origin:0 50%;
  background:var(--grad); z-index:200; pointer-events:none;
  will-change:transform;
}

/* Fine film grain — stops the large flat fields from looking like flat CSS */
.grain{
  position:fixed; inset:-50%; z-index:150; pointer-events:none; opacity:.09;
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='140' height='140'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.85' numOctaves='3'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)' opacity='.55'/%3E%3C/svg%3E");
  animation:grainShift 1.1s steps(4) infinite;
  mix-blend-mode:overlay;
}
@keyframes grainShift{
  0%{transform:translate(0,0)}25%{transform:translate(-3%,2%)}
  50%{transform:translate(2%,-3%)}75%{transform:translate(-2%,-2%)}
  100%{transform:translate(3%,3%)}
}

/* Aurora — slow drifting colour fields behind dark sections */
.aurora{position:absolute;inset:0;overflow:hidden;pointer-events:none;z-index:0;
  -webkit-mask-image:radial-gradient(ellipse at center,#000 55%,transparent 92%);
  mask-image:radial-gradient(ellipse at center,#000 55%,transparent 92%)}
.aurora b{
  position:absolute;display:block;border-radius:50%;filter:blur(70px);opacity:.5;
  animation:drift 46s ease-in-out infinite;
}
.aurora b:nth-child(1){width:46vw;height:46vw;left:-10vw;top:-12vw;background:radial-gradient(circle,rgba(249,58,172,.55),transparent 68%)}
.aurora b:nth-child(2){width:38vw;height:38vw;right:-8vw;top:22vh;background:radial-gradient(circle,rgba(57,202,255,.45),transparent 68%);animation-delay:-15s}
.aurora b:nth-child(3){width:42vw;height:42vw;left:28vw;bottom:-18vw;background:radial-gradient(circle,rgba(139,79,216,.5),transparent 68%);animation-delay:-30s}
@keyframes drift{
  0%,100%{transform:translate3d(0,0,0) scale(1)}
  33%{transform:translate3d(6vw,-4vh,0) scale(1.14)}
  66%{transform:translate3d(-5vw,5vh,0) scale(.9)}
}
.hero > .container, .dark > .container, .final .inner, .page-hero .container{position:relative;z-index:2}

/* Scanning beam — a single sweep of brand light across dark sections */
.beam{
  position:absolute;top:0;bottom:0;width:38%;z-index:1;pointer-events:none;
  background:linear-gradient(100deg,transparent,rgba(255,255,255,.05),transparent);
  -webkit-mask-image:linear-gradient(to bottom,transparent,#000 22%,#000 78%,transparent);
  mask-image:linear-gradient(to bottom,transparent,#000 22%,#000 78%,transparent);
  animation:sweep 18s ease-in-out infinite;
}
@keyframes sweep{
  0%{transform:translateX(-120%) skewX(-14deg)}
  55%,100%{transform:translateX(360%) skewX(-14deg)}
}

/* Hairline gradient rule that draws itself in when a section arrives */
.rule{height:1px;background:var(--grad);transform:scaleX(0);transform-origin:0 50%;
  transition:transform 2.2s cubic-bezier(.16,.84,.24,1)}
.rule.visible{transform:scaleX(1)}


/* ---------- 3. SCROLL CHOREOGRAPHY -------------------------------------- */

/* Base reveal is already in the page; these are the extra variants */
.r-up,.r-left,.r-right,.r-clip,.r-scale,.r-blur{
  opacity:0; will-change:transform,opacity;
  transition:opacity 1.6s cubic-bezier(.16,.84,.24,1), transform 1.6s cubic-bezier(.16,.84,.24,1),
             clip-path 1.9s cubic-bezier(.16,.84,.24,1), filter 1.6s ease;
}
.r-up{transform:translateY(42px)}
.r-left{transform:translateX(-46px)}
.r-right{transform:translateX(46px)}
.r-scale{transform:scale(.93)}
.r-blur{filter:blur(14px);transform:translateY(20px)}
.r-clip{clip-path:inset(0 0 100% 0);opacity:1}
.r-up.visible,.r-left.visible,.r-right.visible,.r-scale.visible{opacity:1;transform:none}
.r-blur.visible{opacity:1;filter:blur(0);transform:none}
.r-clip.visible{clip-path:inset(0 0 0 0)}

/* Stagger — children arrive in sequence rather than all at once */
[data-stagger] > *{opacity:0;transform:translateY(38px);
  transition:opacity 1.5s cubic-bezier(.16,.84,.24,1),transform 1.5s cubic-bezier(.16,.84,.24,1)}
[data-stagger].visible > *{opacity:1;transform:none}
[data-stagger].visible > *:nth-child(1){transition-delay:0.10s}
[data-stagger].visible > *:nth-child(2){transition-delay:0.20s}
[data-stagger].visible > *:nth-child(3){transition-delay:0.30s}
[data-stagger].visible > *:nth-child(4){transition-delay:0.40s}
[data-stagger].visible > *:nth-child(5){transition-delay:0.50s}
[data-stagger].visible > *:nth-child(6){transition-delay:0.60s}
[data-stagger].visible > *:nth-child(7){transition-delay:0.70s}
[data-stagger].visible > *:nth-child(8){transition-delay:0.80s}
[data-stagger].visible > *:nth-child(n+9){transition-delay:.90s}

/* Headline words rise from their own baseline, one after another */
/* Headline words.
   Three attempts to tune a clip window all ended with something cropped,
   because any mask tight enough to hide the parked word is also tight enough
   to shave a glyph somewhere. So there is no mask at all now: words fade and
   rise into place. Nothing is ever clipped, on any axis, at any size.
   Text stays fully selectable — only the pointer is held to an arrow. */
.word-wrap{display:inline-block}
.word{display:inline-block;opacity:0;transform:translateY(.34em);
  transition:opacity 1.15s cubic-bezier(.16,.84,.24,1),
             transform 1.15s cubic-bezier(.16,.84,.24,1)}
.visible .word,.word.in{opacity:1;transform:none}

/* Parallax targets get their transform from JS */
[data-parallax]{will-change:transform}


/* ---------- 4. MICRO-INTERACTIONS --------------------------------------- */

/* Shine sweep across cards on hover */
.tilt,.client-logo-card,.creative,.step,.contact-tile{position:relative;overflow:hidden}
.tilt::after,.client-logo-card::after,.contact-tile::after{
  content:"";position:absolute;top:0;left:-70%;width:45%;height:100%;z-index:3;
  background:linear-gradient(100deg,transparent,rgba(255,255,255,.45),transparent);
  transform:skewX(-18deg);transition:left 1.4s cubic-bezier(.16,.84,.24,1);pointer-events:none;
}
.tilt:hover::after,.client-logo-card:hover::after,.contact-tile:hover::after{left:130%}

/* 3D tilt container */
.tilt-wrap{perspective:1000px}
.tilt{transition:transform .8s cubic-bezier(.16,.84,.24,1),box-shadow .8s ease;
  transform-style:preserve-3d;will-change:transform}

/* "Why" rows — a gradient bar grows in from the left instead of a colour swap */
.why{position:relative;overflow:hidden}
.why::before{
  content:"";position:absolute;left:0;top:0;bottom:0;width:3px;background:var(--grad);
  transform:scaleY(0);transition:transform .85s cubic-bezier(.16,.84,.24,1);
}
.why:hover::before{transform:scaleY(1)}   /* origin comes from --why-origin */
.why h3{transition:padding-left .8s cubic-bezier(.16,.84,.24,1),background .5s ease}

/* Service rows — number flips to gradient, arrow slides */
.service .num{transition:color .6s ease,transform .6s ease}
.service:hover .num{transform:translateX(4px)}
.service .plus{transition:transform .85s cubic-bezier(.16,.84,.24,1)}
.service:hover .plus{transform:rotate(90deg) scale(1.15)}

/* Buttons — brand-gradient fill wipes up from the bottom */
.btn,.nav-cta{position:relative;overflow:hidden;z-index:1}
.btn::before,.nav-cta::before{
  content:"";position:absolute;inset:0;z-index:-1;background:var(--grad);
  transform:translateY(101%);transition:transform .8s cubic-bezier(.16,.84,.24,1);
}
.btn:hover::before,.nav-cta:hover::before{transform:translateY(0)}
.btn:hover,.nav-cta:hover{color:var(--ink)}
.btn.alt:hover{border-color:transparent}

/* Counter digits are tabular so the layout doesn't jitter while counting */
.stat b,.metric{font-variant-numeric:tabular-nums;font-feature-settings:"tnum"}

/* Back to top */
.to-top{
  position:fixed;right:24px;bottom:24px;width:50px;height:50px;border-radius:50%;
  border:1px solid var(--line);background:var(--white);color:var(--ink);
  display:grid;place-items:center;z-index:120;font-size:1.1rem;
  opacity:0;transform:translateY(18px) scale(.85);pointer-events:none;
  transition:.8s cubic-bezier(.16,.84,.24,1);box-shadow:0 14px 34px rgba(41,37,106,.16);
}
.to-top.show{opacity:1;transform:none;pointer-events:auto}
.to-top:hover{background:var(--ink);color:#fff;transform:translateY(-3px)}

/* Marquee pauses so people can actually read a card */
.strip:hover{animation-play-state:paused}
.creative{transition:transform .8s cubic-bezier(.16,.84,.24,1)}
.creative:hover{transform:translateY(-10px)}

/* Page entrance */
.preloader{
  position:fixed;inset:0;z-index:300;background:var(--ink);color:#fff;
  display:grid;place-items:center;transition:opacity .5s ease,visibility .5s;
}
.preloader .pl-logo{width:min(280px,52vw);height:auto;animation:plPulse 1.5s ease-in-out infinite}
.preloader .pl-mark{
  font-family:var(--display);font-weight:900;font-size:clamp(2.5rem,9vw,6rem);
  letter-spacing:-.06em;background:var(--grad);-webkit-background-clip:text;
  background-clip:text;color:transparent;animation:plPulse 1.4s ease-in-out infinite;
}
.preloader.done{opacity:0;visibility:hidden}
@keyframes plPulse{50%{opacity:.45}}


/* ---------- CONTACT DETAILS (replaces the enquiry form) ------------------ */
.contact-details{display:grid;gap:16px}
.contact-tile{
  display:grid;grid-template-columns:54px 1fr auto;align-items:center;gap:20px;
  padding:26px 28px;background:var(--white);border:1px solid var(--line);border-radius:4px;
  transition:transform .8s cubic-bezier(.16,.84,.24,1),box-shadow .8s ease,border-color .8s ease;
}
.contact-tile:hover{transform:translateY(-4px);border-color:transparent;
  box-shadow:0 22px 50px rgba(41,37,106,.13)}
.contact-tile .ct-icon{
  width:54px;height:54px;border-radius:50%;display:grid;place-items:center;
  background:var(--grad);color:#fff;font-size:1.2rem;
}
.contact-tile > span:nth-child(2){display:block;min-width:0}
.contact-tile .ct-label{display:block;font-size:.68rem;letter-spacing:.16em;text-transform:uppercase;
  color:var(--muted);margin-bottom:6px}
.contact-tile .contact-value{display:block;font-family:var(--display);font-size:clamp(1.1rem,2.4vw,1.6rem);
  letter-spacing:-.03em;font-weight:800;word-break:break-word}
.contact-tile .ct-go{font-size:1.3rem;opacity:.3;transition:.7s}
.contact-tile:hover .ct-go{opacity:1;transform:translateX(5px)}
.contact-note{color:var(--muted);line-height:1.7;margin-top:26px;font-size:.95rem}
@media(max-width:560px){
  .contact-tile{grid-template-columns:44px 1fr;padding:20px;gap:14px}
  .contact-tile .ct-icon{width:44px;height:44px;font-size:1rem}
  .contact-tile .ct-go{display:none}
}


/* ---------- CASE STUDY / LEGAL PAGE HELPERS ----------------------------- */
.case-meta{display:grid;grid-template-columns:repeat(4,1fr);gap:1px;background:var(--line);
  border:1px solid var(--line)}
.case-meta div{background:var(--paper);padding:24px}
.case-meta small{display:block;font-size:.66rem;letter-spacing:.15em;text-transform:uppercase;
  color:var(--muted);margin-bottom:8px}
.case-meta b{font-family:var(--display);font-size:1.15rem;letter-spacing:-.03em}
.result-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:22px}
.result{border-top:1px solid var(--line);padding-top:20px}
.result b{font-family:var(--display);font-size:clamp(2.6rem,5vw,4rem);letter-spacing:-.06em;display:block}
.result span{color:var(--muted)}
.prose{max-width:760px}
.prose h2{font-family:var(--display);font-size:clamp(1.7rem,3.4vw,2.5rem);letter-spacing:-.04em;
  margin:52px 0 14px}
.prose h2:first-child{margin-top:0}
.prose p,.prose li{color:var(--muted);line-height:1.8}
.prose ul{padding-left:20px}
.prose li{margin-bottom:10px}
@media(max-width:850px){
  .case-meta{grid-template-columns:1fr 1fr}
  .result-grid{grid-template-columns:1fr}
}


/* ---------- ACCESSIBILITY FLOOR ----------------------------------------- */
a:focus-visible,button:focus-visible,.service:focus-visible,.project:focus-visible{
  outline:2px solid var(--pink);outline-offset:4px;border-radius:3px;
}

@media (prefers-reduced-motion: reduce){
  *,*::before,*::after{
    animation-duration:.001ms !important;animation-iteration-count:1 !important;
    transition-duration:.001ms !important;scroll-behavior:auto !important;
  }
  .grain,.beam,.aurora{display:none}
  .r-up,.r-left,.r-right,.r-clip,.r-scale,.r-blur,[data-stagger] > *{
    opacity:1 !important;transform:none !important;filter:none !important;clip-path:none !important}
  .word{opacity:1 !important;transform:none !important}
  .preloader{display:none}
}


/* ---------- NO-JS FAILSAFE ---------------------------------------------- */
/* The reveal classes start at opacity 0. If the motion script does not run,
   the page must still be fully readable. */
.no-js .reveal,.no-js .r-up,.no-js .r-left,.no-js .r-right,
.no-js .r-scale,.no-js .r-blur,.no-js [data-stagger] > *{
  opacity:1 !important;transform:none !important;filter:none !important}
.no-js .r-clip{clip-path:none !important}
.no-js .preloader{display:none}
.no-js .rule{transform:scaleX(1)}


/* ---------- BRAND LOGO --------------------------------------------------- */
/* Wordmark is part of the logo artwork, so the text label is hidden from
   sight but kept for screen readers and search engines. */
.brand{gap:0}
.brand .logo{height:38px;width:auto;max-width:none;display:block;transition:opacity .7s ease}
.brand .sr{position:absolute;width:1px;height:1px;padding:0;margin:-1px;
  overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap;border:0}
footer .brand .logo{height:44px}
@media(max-width:520px){.brand .logo{height:31px}}

/* The mark spins up on page load, then settles */
.brand .logo{animation:markIn 1.6s cubic-bezier(.16,.84,.24,1) both}
@keyframes markIn{from{opacity:0;transform:translateX(-14px) rotate(-12deg)}
  to{opacity:1;transform:none}}


/* Client name on hover.
   The old version was a hard navy bar that slid up and covered the logo, in
   the body font at a size too small to read. Now the card lifts, a gradient
   hairline draws across the base, and the name settles in underneath in the
   display face — part of the card rather than a label stuck over it. */
.client-logo-card{flex-direction:column;gap:0;padding-bottom:6px}
.client-logo-card .client-name{
  position:absolute;left:12px;right:12px;bottom:12px;z-index:4;
  font-family:var(--display);font-weight:700;
  font-size:clamp(.62rem,1.05vw,.78rem);letter-spacing:-.005em;line-height:1.2;
  text-align:center;color:var(--ink);
  opacity:0;transform:translateY(9px);
  transition:opacity .55s cubic-bezier(.16,.84,.24,1),transform .55s cubic-bezier(.16,.84,.24,1);
  white-space:normal;
}
.client-logo-card:hover .client-name{opacity:1;transform:none}
/* Gradient hairline drawing in along the base of the card */
.client-logo-card::before{
  content:"";position:absolute;left:14px;right:14px;bottom:6px;height:2px;z-index:4;
  background:var(--grad);border-radius:2px;
  transform:scaleX(0);transform-origin:50% 50%;
  transition:transform .6s cubic-bezier(.16,.84,.24,1);
}
.client-logo-card:hover::before{transform:scaleX(1)}
/* Logo lifts to make room instead of being covered */
.client-logo-card img{transition:transform .6s cubic-bezier(.16,.84,.24,1)}
.client-logo-card:hover img{transform:translateY(-13px) scale(.94)}
@media(max-width:850px){
  .client-logo-card .client-name{font-size:.56rem;left:6px;right:6px;bottom:8px}
  .client-logo-card:hover img{transform:translateY(-10px) scale(.95)}
}


/* ---------- RIBBON ------------------------------------------------------
   The brand cover art is a swirl of light ribbons around the mark. This is
   that motif rebuilt in CSS, sitting behind the hero. */
.ribbon{position:absolute;inset:0;overflow:hidden;pointer-events:none;z-index:1;
  opacity:.85;perspective:900px}
.ribbon i{
  position:absolute;left:50%;top:50%;display:block;border-radius:50%;
  border:1.5px solid transparent;transform-style:preserve-3d;
  animation:ribbonSpin 26s linear infinite;
}
.ribbon i:nth-child(1){width:120vw;height:52vw;margin:-26vw 0 0 -60vw;
  border-top-color:var(--pink);border-left-color:var(--purple);
  transform:rotateX(74deg) rotateZ(8deg)}
.ribbon i:nth-child(2){width:104vw;height:44vw;margin:-22vw 0 0 -52vw;
  border-top-color:var(--blue);border-right-color:var(--pink);
  transform:rotateX(72deg) rotateZ(-14deg);animation-duration:34s;animation-direction:reverse}
.ribbon i:nth-child(3){width:88vw;height:36vw;margin:-18vw 0 0 -44vw;
  border-bottom-color:var(--yellow);border-left-color:var(--red);
  transform:rotateX(70deg) rotateZ(22deg);animation-duration:42s}
.ribbon i:nth-child(4){width:70vw;height:28vw;margin:-14vw 0 0 -35vw;
  border-top-color:var(--blue);border-bottom-color:var(--purple);
  transform:rotateX(68deg) rotateZ(-30deg);animation-duration:30s;animation-direction:reverse}
@keyframes ribbonSpin{to{transform:rotateX(72deg) rotateZ(376deg)}}
@media(max-width:850px){.ribbon{opacity:.55}}



/* ==========================================================================
   PACING OVERRIDES for the original page animations
   These keyframes ship in each page's inline <style>. Nothing is removed —
   only slowed, so the ambient motion reads as drift rather than activity.
   ========================================================================== */
.reveal{transition:1.6s cubic-bezier(.16,.84,.24,1)}
.core{animation-duration:48s !important}
.ring{animation-duration:36s !important}
.r2{animation-duration:44s !important}
.float{animation-duration:9s !important}
.f2{animation-delay:-3.4s !important}
.f3{animation-delay:-6.2s !important}
.strip{animation-duration:64s !important}
.nav-cta{animation-duration:5.2s, 1.1s !important}
.links a{animation-duration:1.1s}
.links a:nth-child(1){animation-delay:.14s}.links a:nth-child(2){animation-delay:.24s}
.links a:nth-child(3){animation-delay:.34s}.links a:nth-child(4){animation-delay:.44s}
.links a:nth-child(5){animation-delay:.54s}.links a:nth-child(6){animation-delay:.64s}
.brand{animation-duration:1.2s}
.service{transition:.7s cubic-bezier(.16,.84,.24,1)}
.service p{transition:.65s cubic-bezier(.16,.84,.24,1)}
.art{transition:1.5s cubic-bezier(.16,.84,.24,1)}
.client{transition:.55s ease}
.client-logo-card{transition:transform .8s cubic-bezier(.16,.84,.24,1),box-shadow .8s ease}
.faq-a{transition:grid-template-rows .8s cubic-bezier(.16,.84,.24,1)}
.faq-icon{transition:transform .7s cubic-bezier(.16,.84,.24,1)}
.btn,.nav-cta{transition:.55s cubic-bezier(.16,.84,.24,1)}
nav{transition:.75s cubic-bezier(.16,.84,.24,1)}
.ribbon i{animation-duration:70s}
.ribbon i:nth-child(2){animation-duration:92s}
.ribbon i:nth-child(3){animation-duration:110s}
.ribbon i:nth-child(4){animation-duration:82s}


/* ==========================================================================
   VORTEX — the brand cover art, now the loading screen.
   It was competing with the hero's own orbit animation, so it moved to where
   it has the stage to itself. The canvas is drawn by sosiyo.js.
   ========================================================================== */
.preloader{position:fixed;inset:0;z-index:300;background:#0a0836;color:#fff;
  display:grid;place-items:center;overflow:hidden;
  transition:opacity .8s ease,visibility .8s}
.preloader.done{opacity:0;visibility:hidden}

.vortex{position:absolute;inset:0;z-index:1;pointer-events:none;overflow:hidden}
.vortex canvas{position:absolute;inset:0;width:100%;height:100%;display:block;
  opacity:0;transition:opacity .7s ease;filter:blur(.4px) saturate(1.15)}
.vortex.live canvas{opacity:1}
/* Deep navy pool the ribbons orbit inside, matching the cover */
.vortex::before{
  content:"";position:absolute;left:50%;top:50%;width:88%;height:62%;
  transform:translate(-50%,-50%);border-radius:50%;
  background:radial-gradient(ellipse at center,rgba(8,6,48,.9),rgba(41,37,106,.3) 55%,transparent 78%);
}
/* Bright core where the ribbons converge, right behind the wordmark */
.vortex::after{
  content:"";position:absolute;left:50%;top:50%;width:38%;height:26%;
  transform:translate(-50%,-50%);border-radius:50%;pointer-events:none;
  background:radial-gradient(ellipse at center,rgba(249,58,172,.4),rgba(139,79,216,.2) 45%,transparent 72%);
  filter:blur(30px);animation:coreBreathe 6s ease-in-out infinite;
}
@keyframes coreBreathe{50%{transform:translate(-50%,-50%) scale(1.25);opacity:.7}}

/* The wordmark rides in the eye of the swirl */
.preloader .pl-logo{
  position:relative;z-index:3;width:min(300px,54vw);height:auto;
  filter:drop-shadow(0 12px 44px rgba(0,0,0,.6));
  animation:plLogoIn 1.5s cubic-bezier(.16,.84,.24,1) both;
}
@keyframes plLogoIn{
  0%{opacity:0;transform:scale(.86);filter:blur(9px) drop-shadow(0 12px 44px rgba(0,0,0,.6))}
  60%{opacity:1;filter:blur(0) drop-shadow(0 12px 44px rgba(0,0,0,.6))}
  100%{opacity:1;transform:scale(1)}
}
/* Thin brand-gradient progress hairline along the bottom of the intro */
.preloader::after{
  content:"";position:absolute;left:0;bottom:0;height:2px;width:100%;z-index:4;
  background:var(--grad);transform:scaleX(0);transform-origin:0 50%;
  animation:plBar 2.1s cubic-bezier(.3,.7,.3,1) both;
}
@keyframes plBar{to{transform:scaleX(1)}}

@media (prefers-reduced-motion: reduce){
  .preloader .pl-logo{animation:none}
  .preloader::after{animation:none;transform:scaleX(1)}
  .vortex::after{animation:none}
}



/* ==========================================================================
   SECTION BALANCE
   The two-column sections paired a very large display heading against a short
   right column, and bottom-aligned them, so the columns started at wildly
   different heights and read as unrelated. Now: both columns start on the
   same line, the heading is capped so it breaks over fewer lines, and the
   ratio is closer to even.
   ========================================================================== */
.intro{grid-template-columns:1.05fr .95fr;gap:56px;align-items:start}
.intro h2{font-size:clamp(2.6rem,5vw,4.6rem);line-height:.94}
.intro .copy{font-size:1.02rem;max-width:none}
.intro .stats{margin-top:38px}
.intro .stat b{font-size:2.8rem}

.content-grid{grid-template-columns:1fr 1fr;gap:56px;align-items:start}
.content-grid h2.display{font-size:clamp(2.4rem,4.6vw,4.2rem);line-height:.94}
.content-grid .copy{font-size:1.02rem}

/* Heading + supporting line share a baseline instead of hanging apart */
.section-head{align-items:start;gap:48px}
.section-head h2{font-size:clamp(2.6rem,5.2vw,5rem);line-height:.94;max-width:16ch}
.section-head p{max-width:34ch;padding-top:.5em}

/* The closing panel headline was large enough to clip on narrow viewports */
.final h2{font-size:clamp(3.2rem,8.5vw,8rem);line-height:.92}
.page-hero h1{font-size:clamp(3rem,7.5vw,7.5rem);line-height:.94}
.hero h1{font-size:clamp(3rem,7.5vw,8rem);line-height:.94}

@media(max-width:850px){
  .intro,.content-grid{grid-template-columns:1fr;gap:34px}
  .section-head{gap:20px}
  .section-head h2,.intro h2,.content-grid h2.display{max-width:none}
  .section-head p{padding-top:0}
}


/* ---------- CONTACT ICONS ------------------------------------------------ */
.contact-tile .ct-icon{overflow:visible}
.contact-tile .ct-icon svg{width:23px;height:23px;display:block}
.contact-tile .ct-icon{transition:transform .7s cubic-bezier(.16,.84,.24,1)}
.contact-tile:hover .ct-icon{transform:scale(1.08) rotate(-6deg)}


/* ==========================================================================
   HEADER
   The bar now arrives as one object: it drops in, the pill widens, and the
   links resolve behind it.
   ========================================================================== */
nav{animation:navDrop 1.1s cubic-bezier(.16,.84,.24,1) both}
@keyframes navDrop{from{opacity:0;transform:translateY(-130%)}to{opacity:1;transform:none}}
.nav-inner{transition:background .7s ease,box-shadow .7s ease,border-color .7s ease,
  border-radius .7s ease,padding .7s ease}
/* Gradient hairline under the bar, drawn on scroll */
.nav-inner::after{
  content:"";position:absolute;left:20px;right:20px;bottom:0;height:1px;
  background:var(--grad);transform:scaleX(0);transform-origin:0 50%;
  transition:transform 1.1s cubic-bezier(.16,.84,.24,1);opacity:.85;
}
.scrolled .nav-inner{position:relative}
.scrolled .nav-inner::after{transform:scaleX(1)}
.nav-inner{position:relative}
.links a{padding:6px 0}
.brand:hover .logo{transform:scale(1.04)}
.brand .logo{transform-origin:left center}


/* ==========================================================================
   FOOTER
   Was static. Now it assembles: a gradient rule draws across the top, the
   columns lift in sequence, and the links carry the same underline sweep as
   the header so both ends of the page behave the same way.
   ========================================================================== */
footer{position:relative;overflow:hidden}
footer::before{
  content:"";position:absolute;top:0;left:0;right:0;height:2px;background:var(--grad);
  transform:scaleX(0);transform-origin:0 50%;
  transition:transform 1.8s cubic-bezier(.16,.84,.24,1);
}
footer.visible::before{transform:scaleX(1)}
/* Slow drifting colour field, same family as the section auroras */
footer::after{
  content:"";position:absolute;right:-14%;bottom:-55%;width:58%;height:150%;
  border-radius:50%;pointer-events:none;
  background:radial-gradient(circle,rgba(249,58,172,.16),transparent 66%);
  animation:drift 52s ease-in-out infinite;
}
footer .container{position:relative;z-index:2}

.foot > div{opacity:0;transform:translateY(34px);
  transition:opacity 1.3s cubic-bezier(.16,.84,.24,1),transform 1.3s cubic-bezier(.16,.84,.24,1)}
footer.visible .foot > div{opacity:1;transform:none}
footer.visible .foot > div:nth-child(1){transition-delay:.06s}
footer.visible .foot > div:nth-child(2){transition-delay:.18s}
footer.visible .foot > div:nth-child(3){transition-delay:.30s}
footer.visible .foot > div:nth-child(4){transition-delay:.42s}

.foot a{position:relative;display:block;width:-moz-fit-content;width:fit-content;
  transition:opacity .5s ease,transform .5s ease}
.foot a::after{
  content:"";position:absolute;left:0;bottom:-2px;width:100%;height:1px;
  background:var(--grad);transform:scaleX(0);transform-origin:right;
  transition:transform .6s cubic-bezier(.16,.84,.24,1);
}
.foot a:hover{opacity:1;transform:translateX(4px)}
.foot a:hover::after{transform:scaleX(1);transform-origin:left}
.foot h4{position:relative;padding-bottom:10px}
.foot h4::after{content:"";position:absolute;left:0;bottom:0;width:24px;height:1px;
  background:var(--grad);opacity:.7}

.copyright{opacity:0;transform:translateY(18px);
  transition:opacity 1.2s ease .55s,transform 1.2s cubic-bezier(.16,.84,.24,1) .55s}
footer.visible .copyright{opacity:.55;transform:none}

footer .brand .logo{transition:transform .8s cubic-bezier(.16,.84,.24,1)}
footer .brand:hover .logo{transform:translateY(-3px) scale(1.03)}

@media (prefers-reduced-motion: reduce){
  nav{animation:none}
  .foot > div,.copyright{opacity:1 !important;transform:none !important}
  footer::before{transform:scaleX(1)}
  footer::after{animation:none}
}


@media(max-width:850px){
  }

/* Slightly tighter clip box than the first pass — enough to clear the caps
   without letting neighbouring lines overlap during the rise. */





/* ==========================================================================
   SHOWCASE STRIP
   The loop only held four unique cards (~1208px) but translated by a whole
   set, so on any viewport wider than that a gap opened at the wrap point —
   which is what looked broken when zoomed out. Eight unique cards now carry
   the set, and colours are assigned by explicit index rather than nth-child
   so card N and card N+8 match and the seam is invisible.
   ========================================================================== */
.showcase .strip{gap:20px}
.creative{width:clamp(230px,20vw,300px);height:auto;min-height:380px;
  display:flex;flex-direction:column;justify-content:space-between;border-radius:14px}
.creative small{font-size:.62rem;letter-spacing:.15em;text-transform:uppercase;opacity:.72}
.creative h3{margin:0;font-size:clamp(1.5rem,2.2vw,2.1rem);line-height:1.02;letter-spacing:-.02em}

/* Colour cycle, period 8 — card N and card N+8 must match for a clean seam */
.creative{background:linear-gradient(150deg,#29256A,#1d1a4e)}
.creative.c1{background:linear-gradient(150deg,#29256A,#1d1a4e)}
.creative.c2{background:linear-gradient(150deg,#FF8A3D,#FF4444)}
.creative.c3{background:linear-gradient(150deg,#F93AAC,#8B4FD8)}
.creative.c4{background:linear-gradient(150deg,#8B4FD8,#39CAFF)}
.creative.c5{background:linear-gradient(150deg,#FFCE33,#FF8A3D)}
.creative.c6{background:linear-gradient(150deg,#39CAFF,#8B4FD8)}
.creative.c7{background:linear-gradient(150deg,#FF4444,#F93AAC)}
.creative.c8{background:linear-gradient(150deg,#29256A,#8B4FD8)}
/* The yellow card needs dark type to stay legible */
.creative.c5 small,.creative.c5 h3{color:#29256A}
.creative.c5::after{border-color:rgba(41,37,106,.28)}

/* Feather both ends so cards resolve out of the page instead of being sliced
   off by the viewport edge */
.showcase .strip{
  -webkit-mask-image:linear-gradient(90deg,transparent,#000 7%,#000 93%,transparent);
  mask-image:linear-gradient(90deg,transparent,#000 7%,#000 93%,transparent);
}
/* The heading sits in the same measure as every other section head */
.showcase .section-head{margin-bottom:48px}

@media(max-width:850px){
  .creative{min-height:300px;padding:20px}
  .showcase .strip{-webkit-mask-image:none;mask-image:none}
}


/* Intrinsic width/height attributes are there to reserve space and avoid
   layout shift; CSS still drives the rendered size. */
.brand .logo,.preloader .pl-logo{height:auto}
.brand .logo{height:38px}
footer .brand .logo{height:44px}
@media(max-width:520px){.brand .logo{height:31px}}
.client-logo-card img{width:auto;height:auto;max-width:100%;max-height:100%;object-fit:contain}


/* ==========================================================================
   CURSOR
   A real arrow so the pointer still reads as a pointer, with smoke lifting
   off its tail, a colour trail that lingers, and a spark on click. The
   particles live on a canvas (see sosiyo.js); this positions the pieces.
   ========================================================================== */
html.cursor-on, html.cursor-on *{cursor:none !important}
/* Text fields always keep a real caret */
html.cursor-on input, html.cursor-on textarea, html.cursor-on select,
html.cursor-on [contenteditable]{cursor:text !important}
html.cursor-on .cursor-field{cursor:text !important}

.cur-canvas{position:fixed;inset:0;pointer-events:none;z-index:9998;
  opacity:0;transition:opacity .4s ease}
.cursor-ready .cur-canvas{opacity:1}

.cur-arrow{position:fixed;top:0;left:0;width:26px;height:30px;pointer-events:none;
  z-index:9999;opacity:0;transition:opacity .35s ease;
  transform-origin:3px 2px;will-change:transform;
  filter:drop-shadow(0 2px 6px rgba(0,0,0,.35))}
.cursor-ready .cur-arrow{opacity:1}
.cur-arrow svg{display:block;overflow:visible;
  animation:curBreathe 2.6s ease-in-out infinite;transform-origin:3px 2px}
@keyframes curBreathe{50%{transform:scale(1.06) rotate(-2deg)}}

/* Over something clickable the arrow leans in and brightens */
.cursor-active .cur-arrow{filter:drop-shadow(0 0 9px rgba(249,58,172,.85))}
.cursor-active .cur-arrow svg{animation-duration:1.1s}
/* Held down */
.cursor-down .cur-arrow{transform-origin:3px 2px}
.cursor-down .cur-arrow svg{transform:scale(.86)}
/* Quick kick on click */
.cur-arrow.pop svg{animation:curPop .42s cubic-bezier(.2,.9,.25,1)}
@keyframes curPop{0%{transform:scale(.78)}55%{transform:scale(1.18)}100%{transform:scale(1)}}
/* Over a text field the arrow steps aside for the caret */
.cursor-field .cur-arrow{opacity:0}

@media (hover:none),(pointer:coarse){
  .cur-arrow,.cur-canvas{display:none !important}
  html.cursor-on,html.cursor-on *{cursor:auto !important}
}
@media (prefers-reduced-motion: reduce){
  .cur-arrow svg{animation:none}
}


/* ---------- WHY ROWS ------------------------------------------------------
   The bar grows from whichever edge the pointer entered by, and collapses
   toward the edge it leaves by, so it always travels with the mouse instead
   of always running downward. JS sets --why-origin.                        */
.why::before{transform-origin:50% var(--why-origin,100%)}
.why:hover::before{transform:scaleY(1)}


/* ---------- HEADER LOGO ---------------------------------------------------
   The white and colour lockups were swapped with display, which restarted
   the entrance keyframe and made the logo appear to slide in from the side.
   They are stacked and cross-faded instead, so only the colour changes as
   the hero scrolls past.                                                   */
.brand{position:relative;display:inline-flex;align-items:center}
.brand .logo{transition:opacity .55s ease}
.brand .logo-light{opacity:1}
.brand .logo-dark{position:absolute;left:0;top:50%;transform:translateY(-50%);
  opacity:0;display:block}
.scrolled .brand .logo-light{opacity:0}
.scrolled .brand .logo-dark{opacity:1}
/* The entrance animation belongs to the wrapper, not the swapping images,
   so it runs once on load and never again */
.brand .logo{animation:none}
.brand{animation:markIn 1.4s cubic-bezier(.16,.84,.24,1) both}


/* ---------- FOOTER BRAND ------------------------------------------------
   The horizontal lockup left a tall gap under it in the first column. The
   vertical lockup fills that space and gives the column a proper anchor. */
footer .brand{display:block}
footer .brand .logo{height:auto;width:min(210px,72%);max-width:210px;display:block}
footer .foot > div:first-child p{margin-top:20px}
@media(max-width:850px){footer .brand .logo{width:170px}}


/* ---------- LOADING SCREEN BREATHING ROOM -------------------------------
   The ribbons were running straight through the wordmark. The swirl now
   starts outside a clear centre, and a soft well sits behind the logo so the
   two never touch.                                                        */
.preloader .pl-logo{width:min(260px,48vw)}
.preloader::before{
  content:"";position:absolute;left:50%;top:50%;z-index:2;
  width:min(560px,86vw);height:min(360px,56vw);
  transform:translate(-50%,-50%);border-radius:50%;pointer-events:none;
  background:radial-gradient(ellipse at center,
    rgba(10,8,54,.96) 0%,rgba(10,8,54,.86) 34%,rgba(10,8,54,.42) 62%,transparent 82%);
}


/* ==========================================================================
   WORK GALLERY
   ========================================================================== */
.roster{display:grid;grid-template-columns:repeat(auto-fill,minmax(210px,1fr));gap:18px;margin-top:12px}
.roster-card{
  background:var(--white);border:1px solid var(--line);border-radius:12px;padding:22px 18px 18px;
  display:flex;flex-direction:column;align-items:center;gap:14px;text-align:center;
  transition:transform .7s cubic-bezier(.16,.84,.24,1),box-shadow .7s ease,border-color .7s ease;
}
.roster-card:hover{transform:translateY(-6px);border-color:transparent;
  box-shadow:0 26px 56px rgba(41,37,106,.14)}
.roster-card img{width:100%;max-width:150px;height:78px;object-fit:contain}
.roster-word{font-family:var(--display);font-size:1.15rem;letter-spacing:-.03em;
  height:78px;display:grid;place-items:center;color:var(--ink)}
.roster-info{display:block;line-height:1.35}
.roster-info b{display:block;font-family:var(--display);font-size:.98rem;letter-spacing:-.02em}
.roster-info i{display:block;font-style:normal;font-size:.72rem;color:var(--muted);margin-top:3px}
.roster-info em{display:inline-block;font-style:normal;font-size:.64rem;letter-spacing:.1em;
  text-transform:uppercase;margin-top:9px;padding:4px 10px;border-radius:99px;
  background:var(--grad);color:#fff}

.chips{display:flex;flex-wrap:wrap;gap:10px;margin:0 0 34px}
.chip{
  font:inherit;font-size:.8rem;padding:9px 17px;border-radius:99px;
  border:1px solid var(--line);background:transparent;color:var(--muted);
  transition:.5s cubic-bezier(.16,.84,.24,1);position:relative;overflow:hidden;
}
.chip:hover{color:var(--ink);border-color:var(--ink)}
.chip.is-on{color:#fff;border-color:transparent;background:var(--grad)}

.work-gallery{columns:4;column-gap:16px}
@media(max-width:1100px){.work-gallery{columns:3}}
@media(max-width:760px){.work-gallery{columns:2;column-gap:12px}}
@media(max-width:420px){.work-gallery{columns:1}}
.tile{
  display:block;width:100%;padding:0;border:0;background:none;position:relative;
  break-inside:avoid;margin:0 0 16px;border-radius:12px;overflow:hidden;
  opacity:0;transform:translateY(26px);
  transition:opacity .9s cubic-bezier(.16,.84,.24,1),transform .9s cubic-bezier(.16,.84,.24,1),
             box-shadow .6s ease;
}
.tile.in{opacity:1;transform:none}
.tile.hide{display:none}
.tile img{width:100%;height:auto;display:block;border-radius:12px;
  transition:transform 1.1s cubic-bezier(.16,.84,.24,1),filter .6s ease}
.tile:hover{box-shadow:0 24px 54px rgba(41,37,106,.22)}
.tile:hover img{transform:scale(1.05)}
.tile-meta{
  position:absolute;left:0;right:0;bottom:0;padding:34px 15px 13px;text-align:left;
  background:linear-gradient(to top,rgba(12,10,45,.9),transparent);
  color:#fff;opacity:0;transform:translateY(10px);transition:.6s cubic-bezier(.16,.84,.24,1);
}
.tile:hover .tile-meta{opacity:1;transform:none}
.tile-meta b{display:block;font-family:var(--display);font-size:.92rem;letter-spacing:-.02em}
.tile-meta i{font-style:normal;font-size:.68rem;opacity:.75}
.tile-video .play{
  position:absolute;top:50%;left:50%;transform:translate(-50%,-50%);
  width:62px;height:62px;border-radius:50%;display:grid;place-items:center;
  background:var(--grad);color:#fff;font-size:1.2rem;padding-left:4px;
  box-shadow:0 12px 34px rgba(12,10,45,.45);transition:transform .6s cubic-bezier(.16,.84,.24,1);
}
.tile-video:hover .play{transform:translate(-50%,-50%) scale(1.12)}
.gallery-empty{text-align:center;color:var(--muted);padding:60px 0}

/* ---- Lightbox ---- */
.lightbox{position:fixed;inset:0;z-index:400;background:rgba(8,6,34,.94);
  display:grid;place-items:center;padding:34px;
  opacity:0;transition:opacity .45s ease}
.lightbox.open{opacity:1}
.lightbox[hidden]{display:none}
.lb-stage{margin:0;max-width:min(1100px,92vw);max-height:86vh;display:flex;
  flex-direction:column;align-items:center;gap:14px}
.lb-stage img,.lb-stage video{max-width:100%;max-height:76vh;width:auto;height:auto;
  border-radius:10px;display:block;box-shadow:0 30px 90px rgba(0,0,0,.6)}
.lb-stage figcaption{color:#fff;text-align:center}
.lb-stage figcaption b{display:block;font-family:var(--display);font-size:1.05rem;letter-spacing:-.02em}
.lb-stage figcaption span{font-size:.78rem;opacity:.6}
.lb-close,.lb-prev,.lb-next{
  position:absolute;background:rgba(255,255,255,.1);border:1px solid rgba(255,255,255,.2);
  color:#fff;width:48px;height:48px;border-radius:50%;font-size:1.3rem;
  display:grid;place-items:center;transition:.4s;backdrop-filter:blur(8px)}
.lb-close:hover,.lb-prev:hover,.lb-next:hover{background:var(--grad);border-color:transparent}
.lb-close{top:24px;right:24px}
.lb-prev{left:24px;top:50%;transform:translateY(-50%)}
.lb-next{right:24px;top:50%;transform:translateY(-50%)}
@media(max-width:700px){
  .lb-prev{left:10px}.lb-next{right:10px}
  .lb-close{top:12px;right:12px}
  .lightbox{padding:14px}
}


/* ==========================================================================
   ABOUT PAGE
   The page was five near-identical stacked text blocks. These give it some
   rhythm: a stat band, an image collage, and card grids that break up the
   run of paragraphs.
   ========================================================================== */
.about-band{padding:0}
.band{display:grid;grid-template-columns:repeat(4,1fr);gap:1px;background:var(--line);
  border-top:1px solid var(--line);border-bottom:1px solid var(--line)}
.band-cell{background:var(--paper);padding:40px 26px;text-align:center}
.band-cell b{display:block;font-family:var(--display);font-weight:900;
  font-size:clamp(2.4rem,4.4vw,3.6rem);letter-spacing:-.05em;line-height:1;
  background:var(--grad);-webkit-background-clip:text;background-clip:text;color:transparent;
  font-variant-numeric:tabular-nums}
.band-cell span{display:block;margin-top:10px;font-size:.8rem;color:var(--muted);line-height:1.4}

.collage-sec{background:var(--paper)}
.collage{display:grid;grid-template-columns:repeat(6,1fr);gap:14px}
.cg-item{margin:0;border-radius:12px;overflow:hidden;aspect-ratio:4/5;
  box-shadow:0 16px 40px rgba(41,37,106,.10)}
.cg-item img{width:100%;height:100%;object-fit:cover;display:block;
  transition:transform 1.2s cubic-bezier(.16,.84,.24,1)}
.cg-item:hover img{transform:scale(1.06)}
/* First two run taller so the grid is not a flat row of equal boxes */
.cg-item:nth-child(1),.cg-item:nth-child(2){grid-column:span 2;aspect-ratio:1/1}
.cg-item:nth-child(3){grid-column:span 2;aspect-ratio:1/1}
.cg-item:nth-child(n+4){grid-column:span 2}
.collage-cta{margin-top:34px;display:inline-block}

.pgrid{display:grid;grid-template-columns:repeat(2,1fr);gap:18px}
.pcard{position:relative;padding:34px 30px 30px;border-radius:14px;
  background:rgba(255,255,255,.045);border:1px solid rgba(255,255,255,.11);
  transition:transform .7s cubic-bezier(.16,.84,.24,1),background .7s ease,border-color .7s ease;
  overflow:hidden}
.pcard::before{content:"";position:absolute;left:0;top:0;bottom:0;width:3px;
  background:var(--grad);transform:scaleY(0);transform-origin:50% 0;
  transition:transform .7s cubic-bezier(.16,.84,.24,1)}
.pcard:hover{transform:translateY(-5px);background:rgba(255,255,255,.075);
  border-color:rgba(255,255,255,.2)}
.pcard:hover::before{transform:scaleY(1)}
.pnum{display:block;font-family:var(--display);font-size:.82rem;letter-spacing:.14em;
  background:var(--grad);-webkit-background-clip:text;background-clip:text;color:transparent;
  margin-bottom:14px}
.pcard h3{font-family:var(--display);font-size:clamp(1.15rem,2vw,1.5rem);letter-spacing:-.03em;
  margin:0 0 10px;color:#fff}
.pcard p{color:rgba(255,255,255,.66);line-height:1.7;margin:0;font-size:.95rem}

.svc-pills{display:flex;flex-wrap:wrap;gap:12px}
.svc-pill{display:inline-flex;align-items:center;gap:10px;padding:14px 22px;border-radius:99px;
  border:1px solid var(--line);font-family:var(--display);font-weight:600;
  font-size:clamp(.86rem,1.4vw,1rem);letter-spacing:-.01em;color:var(--ink);
  transition:.55s cubic-bezier(.16,.84,.24,1);position:relative;overflow:hidden;z-index:1}
.svc-pill span{opacity:.35;transition:.55s cubic-bezier(.16,.84,.24,1)}
.svc-pill::before{content:"";position:absolute;inset:0;z-index:-1;background:var(--grad);
  transform:translateY(101%);transition:transform .55s cubic-bezier(.16,.84,.24,1)}
.svc-pill:hover{border-color:transparent;color:#fff}
.svc-pill:hover::before{transform:translateY(0)}
.svc-pill:hover span{opacity:1;transform:translateX(4px)}

@media(max-width:900px){
  .band{grid-template-columns:1fr 1fr}
  .pgrid{grid-template-columns:1fr}
  .collage{grid-template-columns:repeat(4,1fr)}
  .cg-item:nth-child(1),.cg-item:nth-child(2),.cg-item:nth-child(3){grid-column:span 2}
}
@media(max-width:560px){
  .collage{grid-template-columns:repeat(2,1fr);gap:10px}
  .cg-item,.cg-item:nth-child(n){grid-column:span 1;aspect-ratio:4/5}
  .band-cell{padding:28px 14px}
}


/* Homepage work tiles now hold real imagery rather than a flat gradient */
.work-grid .art{position:relative;overflow:hidden}
.work-grid .art img{width:100%;height:100%;object-fit:cover;display:block;
  transition:transform 1.3s cubic-bezier(.16,.84,.24,1)}
.work-grid .project:hover .art img{transform:scale(1.07)}
.work-grid .project-info{position:relative;z-index:2}

/* ============================================================
   SEO content components — service pages, breadcrumbs, lists
   ============================================================ */
nav.crumbs,.crumbs{position:static;inset:auto;z-index:auto;color:inherit;transition:none;margin:0 0 22px;font-size:.74rem;letter-spacing:.06em}
.crumbs ol{list-style:none;display:flex;flex-wrap:wrap;gap:8px;margin:0;padding:0}
.crumbs li{display:flex;align-items:center;gap:8px;opacity:.62}
.crumbs li+li:before{content:"/";opacity:.5}
.crumbs a{text-decoration:none;border-bottom:1px solid transparent;transition:.25s}
.crumbs a:hover{border-bottom-color:currentColor;opacity:1}
.crumbs li:last-child{opacity:.95}
.page-hero .crumbs{color:rgba(255,255,255,.9)}

.mini-h{font-family:var(--display);font-size:clamp(1.4rem,2.6vw,2.1rem);letter-spacing:-.035em;margin:14px 0 22px;line-height:1.05}
.tick-list{list-style:none;margin:0;padding:0;border-top:1px solid var(--line)}
.tick-list li{position:relative;padding:15px 0 15px 30px;border-bottom:1px solid var(--line);color:var(--muted);line-height:1.55}
.tick-list li:before{content:"";position:absolute;left:0;top:22px;width:12px;height:2px;border-radius:2px;background:var(--grad)}
.dark .tick-list,.dark .tick-list li{border-color:rgba(255,255,255,.14);color:rgba(255,255,255,.72)}

.ilink{border-bottom:1px solid rgba(41,37,106,.35);transition:.25s}
.ilink:hover{border-bottom-color:currentColor}
.section-head p .ilink,.copy .ilink{color:inherit}
.dark .ilink{border-bottom-color:rgba(255,255,255,.4)}

.step h3{font-size:1.05rem;margin:10px 0 8px;letter-spacing:-.01em}
.step b{display:block}

.rel-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:18px}
.rel-card{display:flex;flex-direction:column;justify-content:space-between;gap:26px;min-height:170px;padding:26px;border:1px solid var(--line);border-radius:14px;background:rgba(255,255,255,.55);transition:transform .35s cubic-bezier(.2,.8,.2,1),box-shadow .35s,border-color .35s}
.rel-card b{font-family:var(--display);font-size:clamp(1.2rem,2vw,1.7rem);letter-spacing:-.035em;line-height:1.05}
.rel-card span{font-size:.78rem;letter-spacing:.08em;text-transform:uppercase;color:var(--muted)}
.rel-card:hover{transform:translateY(-4px);border-color:transparent;box-shadow:0 18px 40px rgba(41,37,106,.13)}
.rel-card:focus-visible{outline:2px solid var(--ink);outline-offset:3px}

.cta-actions{display:flex;flex-wrap:wrap;gap:12px;margin-top:26px}
.dark .cta-actions .btn{background:#fff;color:var(--ink)}
.dark .cta-actions .btn.alt{background:transparent;color:#fff;border:1px solid rgba(255,255,255,.3)}

@media(max-width:900px){
  .rel-grid{grid-template-columns:1fr}
  .crumbs{font-size:.7rem}
}

@media(max-width:560px){
  .process{grid-template-columns:1fr}
  .step{border-right:0;min-height:0;padding:24px 0}
  .step:nth-child(2n){border-right:0}
}
